mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-02-12 01:24:54 +00:00
(svn r24885) -Fix: Pass proper UTF-16 strings instead of UCS-2 to ICU in order to preserve characters outside the BMP.
This commit is contained in:
parent
eb5149622e
commit
534837ace5
63
src/gfx.cpp
63
src/gfx.cpp
@ -297,11 +297,11 @@ static void SetColourRemap(TextColour colour)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(WITH_ICU)
|
#if !defined(WITH_ICU)
|
||||||
typedef WChar UChar;
|
static WChar *HandleBiDiAndArabicShapes(WChar *text) { return text; }
|
||||||
static UChar *HandleBiDiAndArabicShapes(UChar *text) { return text; }
|
|
||||||
#else
|
#else
|
||||||
#include <unicode/ubidi.h>
|
#include <unicode/ubidi.h>
|
||||||
#include <unicode/ushape.h>
|
#include <unicode/ushape.h>
|
||||||
|
#include <unicode/ustring.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to be able to handle right-to-left text and Arabic chars properly.
|
* Function to be able to handle right-to-left text and Arabic chars properly.
|
||||||
@ -332,31 +332,34 @@ static UChar *HandleBiDiAndArabicShapes(UChar *text) { return text; }
|
|||||||
* @param lastof the end of the buffer
|
* @param lastof the end of the buffer
|
||||||
* @return the buffer to draw from
|
* @return the buffer to draw from
|
||||||
*/
|
*/
|
||||||
static UChar *HandleBiDiAndArabicShapes(UChar *buffer)
|
static WChar *HandleBiDiAndArabicShapes(WChar *buffer)
|
||||||
{
|
{
|
||||||
static UChar input_output[DRAW_STRING_BUFFER];
|
UChar input[DRAW_STRING_BUFFER];
|
||||||
UChar intermediate[DRAW_STRING_BUFFER];
|
UChar intermediate[DRAW_STRING_BUFFER];
|
||||||
|
static WChar output[DRAW_STRING_BUFFER];
|
||||||
|
|
||||||
UChar *t = buffer;
|
/* Transform from UTF-32 to internal ICU format of UTF-16. */
|
||||||
size_t length = 0;
|
|
||||||
while (*t != '\0' && length < lengthof(input_output) - 1) {
|
|
||||||
input_output[length++] = *t++;
|
|
||||||
}
|
|
||||||
input_output[length] = 0;
|
|
||||||
|
|
||||||
UErrorCode err = U_ZERO_ERROR;
|
UErrorCode err = U_ZERO_ERROR;
|
||||||
UBiDi *para = ubidi_openSized((int32_t)length, 0, &err);
|
int32_t length = 0;
|
||||||
if (para == NULL) return buffer;
|
u_strFromUTF32(input, lengthof(input), &length, (UChar32 *)buffer, -1, &err);
|
||||||
|
|
||||||
ubidi_setPara(para, input_output, (int32_t)length, _current_text_dir == TD_RTL ? UBIDI_DEFAULT_RTL : UBIDI_DEFAULT_LTR, NULL, &err);
|
|
||||||
ubidi_writeReordered(para, intermediate, (int32_t)length, UBIDI_REMOVE_BIDI_CONTROLS, &err);
|
|
||||||
length = u_shapeArabic(intermediate, (int32_t)length, input_output, lengthof(input_output), U_SHAPE_TEXT_DIRECTION_VISUAL_LTR | U_SHAPE_LETTERS_SHAPE, &err);
|
|
||||||
ubidi_close(para);
|
|
||||||
|
|
||||||
if (U_FAILURE(err)) return buffer;
|
if (U_FAILURE(err)) return buffer;
|
||||||
|
|
||||||
input_output[length] = '\0';
|
UBiDi *para = ubidi_openSized(length, 0, &err);
|
||||||
return input_output;
|
if (para == NULL) return buffer;
|
||||||
|
|
||||||
|
ubidi_setPara(para, input, length, _current_text_dir == TD_RTL ? UBIDI_DEFAULT_RTL : UBIDI_DEFAULT_LTR, NULL, &err);
|
||||||
|
length = ubidi_writeReordered(para, intermediate, lengthof(intermediate), UBIDI_REMOVE_BIDI_CONTROLS, &err);
|
||||||
|
length = u_shapeArabic(intermediate, length, input, lengthof(input), U_SHAPE_TEXT_DIRECTION_VISUAL_LTR | U_SHAPE_LETTERS_SHAPE, &err);
|
||||||
|
ubidi_close(para);
|
||||||
|
if (U_FAILURE(err)) return buffer;
|
||||||
|
|
||||||
|
/* Transform back to UTF-32. */
|
||||||
|
u_strToUTF32((UChar32 *)output, lengthof(output), NULL, input, length, &err);
|
||||||
|
if (U_FAILURE(err)) return buffer;
|
||||||
|
|
||||||
|
/* u_strToUTF32 doesn't add a NUL charcter if the buffer is too small, be safe. */
|
||||||
|
output[lengthof(output) - 1] = '\0';
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
#endif /* WITH_ICU */
|
#endif /* WITH_ICU */
|
||||||
|
|
||||||
@ -420,7 +423,7 @@ static int TruncateString(char *str, int maxw, bool ignore_setxy, FontSize start
|
|||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ReallyDoDrawString(const UChar *string, int x, int y, DrawStringParams ¶ms, bool parse_string_also_when_clipped = false);
|
static int ReallyDoDrawString(const WChar *string, int x, int y, DrawStringParams ¶ms, bool parse_string_also_when_clipped = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the real width of the string.
|
* Get the real width of the string.
|
||||||
@ -428,7 +431,7 @@ static int ReallyDoDrawString(const UChar *string, int x, int y, DrawStringParam
|
|||||||
* @param start_fontsize Fontsize to start the text with
|
* @param start_fontsize Fontsize to start the text with
|
||||||
* @return the width.
|
* @return the width.
|
||||||
*/
|
*/
|
||||||
static int GetStringWidth(const UChar *str, FontSize start_fontsize)
|
static int GetStringWidth(const WChar *str, FontSize start_fontsize)
|
||||||
{
|
{
|
||||||
FontSize size = start_fontsize;
|
FontSize size = start_fontsize;
|
||||||
int max_width;
|
int max_width;
|
||||||
@ -496,11 +499,11 @@ static int DrawString(int left, int right, int top, char *str, const char *last,
|
|||||||
* the string and draw the parts separated by SETX(Y).
|
* the string and draw the parts separated by SETX(Y).
|
||||||
* So here we split
|
* So here we split
|
||||||
*/
|
*/
|
||||||
static SmallVector<UChar *, 4> setx_offsets;
|
static SmallVector<WChar *, 4> setx_offsets;
|
||||||
setx_offsets.Clear();
|
setx_offsets.Clear();
|
||||||
|
|
||||||
UChar draw_buffer[DRAW_STRING_BUFFER];
|
WChar draw_buffer[DRAW_STRING_BUFFER];
|
||||||
UChar *p = draw_buffer;
|
WChar *p = draw_buffer;
|
||||||
|
|
||||||
*setx_offsets.Append() = p;
|
*setx_offsets.Append() = p;
|
||||||
|
|
||||||
@ -559,8 +562,8 @@ static int DrawString(int left, int right, int top, char *str, const char *last,
|
|||||||
/* In case we have a RTL language we swap the alignment. */
|
/* In case we have a RTL language we swap the alignment. */
|
||||||
if (!(align & SA_FORCE) && _current_text_dir == TD_RTL && !(align & SA_STRIP) && (align & SA_HOR_MASK) != SA_HOR_CENTER) align ^= SA_RIGHT;
|
if (!(align & SA_FORCE) && _current_text_dir == TD_RTL && !(align & SA_STRIP) && (align & SA_HOR_MASK) != SA_HOR_CENTER) align ^= SA_RIGHT;
|
||||||
|
|
||||||
for (UChar **iter = setx_offsets.Begin(); iter != setx_offsets.End(); iter++) {
|
for (WChar **iter = setx_offsets.Begin(); iter != setx_offsets.End(); iter++) {
|
||||||
UChar *to_draw = *iter;
|
WChar *to_draw = *iter;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
/* Skip the SETX(Y) and set the appropriate offsets. */
|
/* Skip the SETX(Y) and set the appropriate offsets. */
|
||||||
@ -1088,11 +1091,11 @@ void DrawCharCentered(WChar c, int x, int y, TextColour colour)
|
|||||||
* @return the x-coordinates where the drawing has finished.
|
* @return the x-coordinates where the drawing has finished.
|
||||||
* If nothing is drawn, the originally passed x-coordinate is returned
|
* If nothing is drawn, the originally passed x-coordinate is returned
|
||||||
*/
|
*/
|
||||||
static int ReallyDoDrawString(const UChar *string, int x, int y, DrawStringParams ¶ms, bool parse_string_also_when_clipped)
|
static int ReallyDoDrawString(const WChar *string, int x, int y, DrawStringParams ¶ms, bool parse_string_also_when_clipped)
|
||||||
{
|
{
|
||||||
DrawPixelInfo *dpi = _cur_dpi;
|
DrawPixelInfo *dpi = _cur_dpi;
|
||||||
bool draw_shadow = GetDrawGlyphShadow();
|
bool draw_shadow = GetDrawGlyphShadow();
|
||||||
UChar c;
|
WChar c;
|
||||||
int xo = x;
|
int xo = x;
|
||||||
|
|
||||||
if (!parse_string_also_when_clipped) {
|
if (!parse_string_also_when_clipped) {
|
||||||
|
Loading…
Reference in New Issue
Block a user