mirror of https://github.com/OpenRCT2/OpenRCT2.git
implement utf8, part 6
This commit is contained in:
parent
795c01cab5
commit
d6a7025a3a
|
@ -58,6 +58,7 @@
|
|||
<ClCompile Include="..\src\interface\widget.c" />
|
||||
<ClCompile Include="..\src\interface\window.c" />
|
||||
<ClCompile Include="..\src\intro.c" />
|
||||
<ClCompile Include="..\src\localisation\convert.c" />
|
||||
<ClCompile Include="..\src\localisation\currency.c" />
|
||||
<ClCompile Include="..\src\localisation\date.c" />
|
||||
<ClCompile Include="..\src\localisation\language.c" />
|
||||
|
|
|
@ -495,6 +495,9 @@
|
|||
<ClCompile Include="..\src\cheats.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\localisation\convert.c">
|
||||
<Filter>Source\Localisation</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\management\award.h">
|
||||
|
|
|
@ -4,15 +4,13 @@
|
|||
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerCommand>$(TargetDir)\openrct2.exe</LocalDebuggerCommand>
|
||||
<LocalDebuggerCommandArguments>
|
||||
</LocalDebuggerCommandArguments>
|
||||
<LocalDebuggerCommandArguments>"C:\Program Files (x86)\Infogrames\RollerCoaster Tycoon 2\Scenarios\Electric Fields.SC6"</LocalDebuggerCommandArguments>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release with Tests|Win32'">
|
||||
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerCommand>$(TargetDir)\openrct2.exe</LocalDebuggerCommand>
|
||||
<LocalDebuggerCommandArguments>
|
||||
</LocalDebuggerCommandArguments>
|
||||
<LocalDebuggerCommandArguments>"C:\Program Files (x86)\Infogrames\RollerCoaster Tycoon 2\Scenarios\Electric Fields.SC6"</LocalDebuggerCommandArguments>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ShowAllFiles>false</ShowAllFiles>
|
||||
|
@ -21,5 +19,6 @@
|
|||
<LocalDebuggerCommand>$(TargetDir)\openrct2.exe</LocalDebuggerCommand>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
|
||||
<LocalDebuggerCommandArguments>"C:\Program Files (x86)\Infogrames\RollerCoaster Tycoon 2\Scenarios\Electric Fields.SC6"</LocalDebuggerCommandArguments>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -299,121 +299,109 @@ int gfx_clip_string(utf8 *text, int width)
|
|||
* num_lines (edi) - out
|
||||
* font_height (ebx) - out
|
||||
*/
|
||||
int gfx_wrap_string(char* buffer, int width, int* num_lines, int* font_height)
|
||||
int gfx_wrap_string(utf8 *text, int width, int *num_lines, int *font_height)
|
||||
{
|
||||
unsigned int line_width = 0;
|
||||
unsigned int max_width = 0;
|
||||
rct_g1_element g1_element;
|
||||
int lineWidth = 0;
|
||||
int maxWidth = 0;
|
||||
rct_g1_element g1Element;
|
||||
|
||||
*num_lines = 0;
|
||||
*font_height = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16);
|
||||
|
||||
// Pointer to the start of the current word
|
||||
unsigned char* curr_word = NULL;
|
||||
utf8 *currentWord = NULL;
|
||||
// Width of line up to current word
|
||||
unsigned int curr_width;
|
||||
|
||||
for (unsigned char* curr_char = buffer; *curr_char != (uint8)0; curr_char++) {
|
||||
int currentWidth;
|
||||
|
||||
utf8 *ch = text;
|
||||
utf8 *lastCh;
|
||||
int codepoint;
|
||||
while ((codepoint = utf8_get_next(ch, &lastCh)) != 0) {
|
||||
// Remember start of current word and line width up to this word
|
||||
if (*curr_char == ' ') {
|
||||
curr_word = curr_char;
|
||||
curr_width = line_width;
|
||||
}
|
||||
|
||||
// 5 is RCT2 new line?
|
||||
if (*curr_char != 5) {
|
||||
if (*curr_char < ' ') {
|
||||
switch(*curr_char) {
|
||||
case FORMAT_MOVE_X:
|
||||
case FORMAT_ADJUST_PALETTE:
|
||||
case 3:
|
||||
case 4:
|
||||
curr_char++;
|
||||
continue;
|
||||
case FORMAT_NEWLINE:
|
||||
case FORMAT_NEWLINE_SMALLER:
|
||||
continue;
|
||||
case FORMAT_TINYFONT:
|
||||
*font_height = 0x1C0;
|
||||
continue;
|
||||
case FORMAT_BIGFONT:
|
||||
*font_height = 0x2A0;
|
||||
continue;
|
||||
case FORMAT_MEDIUMFONT:
|
||||
*font_height = 0xE0;
|
||||
continue;
|
||||
case FORMAT_SMALLFONT:
|
||||
*font_height = 0;
|
||||
continue;
|
||||
case FORMAT_OUTLINE:
|
||||
case FORMAT_OUTLINE_OFF:
|
||||
case FORMAT_WINDOW_COLOUR_1:
|
||||
case FORMAT_WINDOW_COLOUR_2:
|
||||
case FORMAT_WINDOW_COLOUR_3:
|
||||
case 0x10:
|
||||
continue;
|
||||
case FORMAT_INLINE_SPRITE:
|
||||
g1_element = g1Elements[*((uint32*)(curr_char + 1)) & 0x7FFFF];
|
||||
line_width += g1_element.width;
|
||||
curr_char += 4;
|
||||
break;
|
||||
default:
|
||||
if (*curr_char <= 0x16) {
|
||||
curr_char += 2;
|
||||
continue;
|
||||
}
|
||||
curr_char += 4;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
line_width += _spriteFontCharacterWidths[*font_height + (*curr_char - 0x20)];
|
||||
|
||||
if ((int)line_width <= width) {
|
||||
continue;
|
||||
}
|
||||
if (curr_word == 0) {
|
||||
curr_char--;
|
||||
unsigned char* old_char = curr_char;
|
||||
unsigned char swap_char = 0;
|
||||
unsigned char temp;
|
||||
// Insert NULL at current character
|
||||
// Aboslutely no guarantee that this won't overrun!
|
||||
do {
|
||||
temp = swap_char;
|
||||
swap_char = *curr_char;
|
||||
*curr_char = temp;
|
||||
curr_char++;
|
||||
} while(swap_char != 0);
|
||||
|
||||
*curr_char = swap_char;
|
||||
curr_char = old_char;
|
||||
curr_char++;
|
||||
*num_lines += 1;
|
||||
|
||||
if (line_width > max_width) {
|
||||
max_width = line_width;
|
||||
}
|
||||
line_width = 0;
|
||||
curr_word = 0;
|
||||
continue;
|
||||
}
|
||||
curr_char = curr_word;
|
||||
line_width = curr_width;
|
||||
}
|
||||
|
||||
*num_lines += 1;
|
||||
*curr_char = 0;
|
||||
|
||||
if (line_width > max_width) {
|
||||
max_width = line_width;
|
||||
if (codepoint == ' ') {
|
||||
currentWord = ch;
|
||||
currentWidth = lineWidth;
|
||||
}
|
||||
|
||||
if (utf8_is_format_code(codepoint)) {
|
||||
switch (codepoint) {
|
||||
case FORMAT_MOVE_X:
|
||||
case FORMAT_ADJUST_PALETTE:
|
||||
case 3:
|
||||
case 4:
|
||||
ch++;
|
||||
break;
|
||||
case FORMAT_NEWLINE:
|
||||
case FORMAT_NEWLINE_SMALLER:
|
||||
*num_lines += 1;
|
||||
*ch = 0;
|
||||
if (lineWidth > maxWidth) {
|
||||
maxWidth = lineWidth;
|
||||
}
|
||||
lineWidth = 0;
|
||||
currentWord = 0;
|
||||
break;
|
||||
case FORMAT_TINYFONT:
|
||||
*font_height = FONT_SPRITE_BASE_TINY;
|
||||
break;
|
||||
case FORMAT_SMALLFONT:
|
||||
*font_height = FONT_SPRITE_BASE_SMALL;
|
||||
break;
|
||||
case FORMAT_MEDIUMFONT:
|
||||
*font_height = FONT_SPRITE_BASE_MEDIUM;
|
||||
break;
|
||||
case FORMAT_BIGFONT:
|
||||
*font_height = FONT_SPRITE_BASE_BIG;
|
||||
break;
|
||||
case FORMAT_OUTLINE:
|
||||
case FORMAT_OUTLINE_OFF:
|
||||
case FORMAT_WINDOW_COLOUR_1:
|
||||
case FORMAT_WINDOW_COLOUR_2:
|
||||
case FORMAT_WINDOW_COLOUR_3:
|
||||
case 0x10:
|
||||
break;
|
||||
case FORMAT_INLINE_SPRITE:
|
||||
g1Element = g1Elements[*((uint32*)(ch + 1)) & 0x7FFFF];
|
||||
lineWidth += g1Element.width;
|
||||
lastCh += 4;
|
||||
break;
|
||||
default:
|
||||
if (codepoint < FORMAT_COLOUR_CODE_START || codepoint > FORMAT_COLOUR_CODE_END) {
|
||||
if (codepoint <= 0x16) {
|
||||
lastCh += 2;
|
||||
} else {
|
||||
lastCh += 4;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
ch = lastCh;
|
||||
} else {
|
||||
lineWidth += _spriteFontCharacterWidths[*font_height + utf8_get_sprite_offset_for_codepoint(codepoint)];
|
||||
if ((int)lineWidth <= width) {
|
||||
ch = lastCh;
|
||||
} else if (currentWord == NULL) {
|
||||
// Single word is longer than line, insert null terminator
|
||||
utf8 *end = get_string_end(ch);
|
||||
memmove(ch + 1, ch, end - ch + 1);
|
||||
*ch++ = 0;
|
||||
|
||||
maxWidth = max(maxWidth, lineWidth);
|
||||
*num_lines += 1;
|
||||
lineWidth = 0;
|
||||
currentWord = NULL;
|
||||
} else {
|
||||
ch = currentWord;
|
||||
*ch++ = 0;
|
||||
|
||||
maxWidth = max(maxWidth, currentWidth);
|
||||
*num_lines += 1;
|
||||
lineWidth = 0;
|
||||
currentWord = NULL;
|
||||
}
|
||||
}
|
||||
line_width = 0;
|
||||
curr_word = 0;
|
||||
}
|
||||
if (max_width == 0)return line_width;
|
||||
return max_width;
|
||||
return maxWidth == 0 ? lineWidth : maxWidth;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1018,15 +1006,6 @@ static void ttf_draw_string_raw_ttf(rct_drawpixelinfo *dpi, const utf8 *text, te
|
|||
break;
|
||||
}
|
||||
|
||||
int fontStyle = TTF_GetFontStyle(font);
|
||||
int newFontStyle = 0;
|
||||
if (info->flags & TEXT_DRAW_FLAG_OUTLINE) {
|
||||
newFontStyle |= TTF_STYLE_BOLD;
|
||||
}
|
||||
if (fontStyle != newFontStyle) {
|
||||
TTF_SetFontStyle(font, newFontStyle);
|
||||
}
|
||||
|
||||
if (info->flags & TEXT_DRAW_FLAG_NO_DRAW) {
|
||||
int width, height;
|
||||
|
||||
|
@ -1079,7 +1058,12 @@ static void ttf_draw_string_raw_ttf(rct_drawpixelinfo *dpi, const utf8 *text, te
|
|||
int dstScanSkip = dpi->width + dpi->pitch - width;
|
||||
for (int yy = 0; yy < height; yy++) {
|
||||
for (int xx = 0; xx < width; xx++) {
|
||||
if (*src != 0) *dst = colour;
|
||||
if (*src != 0) {
|
||||
*dst = colour;
|
||||
if (info->flags & TEXT_DRAW_FLAG_OUTLINE) {
|
||||
*(dst + width + dstScanSkip + 1) = 0;
|
||||
}
|
||||
}
|
||||
src++;
|
||||
dst++;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -99,6 +99,9 @@ uint32 utf8_get_next(const utf8 *char_ptr, const utf8 **nextchar_ptr)
|
|||
} else if ((char_ptr[0] & 0xF0) == 0xE0) {
|
||||
result = ((char_ptr[0] & 0x0F) << 12) | ((char_ptr[1] & 0x3F) << 6) | (char_ptr[2] & 0x3F);
|
||||
numBytes = 3;
|
||||
} else if ((char_ptr[0] & 0xF8) == 0xF0) {
|
||||
result = ((char_ptr[0] & 0x07) << 18) | ((char_ptr[1] & 0x3F) << 12) | ((char_ptr[1] & 0x3F) << 6) | (char_ptr[2] & 0x3F);
|
||||
numBytes = 4;
|
||||
} else {
|
||||
// TODO 4 bytes
|
||||
result = ' ';
|
||||
|
@ -384,6 +387,8 @@ static utf8 *convert_multibyte_charset(const char *src)
|
|||
uint8 a = *ch++;
|
||||
uint8 b = *ch++;
|
||||
uint16 codepoint = (a << 8) | b;
|
||||
|
||||
codepoint = encoding_convert_gb2312_to_unicode(codepoint - 0x8080);
|
||||
dst = utf8_write_codepoint(dst, codepoint);
|
||||
} else {
|
||||
*dst++ = *ch++;
|
||||
|
@ -391,7 +396,8 @@ static utf8 *convert_multibyte_charset(const char *src)
|
|||
}
|
||||
*dst++ = 0;
|
||||
int actualLength = dst - buffer;
|
||||
return realloc(buffer, actualLength);
|
||||
buffer = realloc(buffer, actualLength);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static bool rct2_language_is_multibyte_charset(int languageId)
|
||||
|
|
|
@ -180,7 +180,7 @@ int utf8_get_sprite_offset_for_codepoint(int codepoint)
|
|||
case FORMAT_TICK: return 172 - 32;
|
||||
case FORMAT_CROSS: return 173 - 32;
|
||||
default:
|
||||
if (codepoint > 224) codepoint = ' ';
|
||||
if (codepoint > 224) codepoint = 'W';
|
||||
return codepoint - 32;
|
||||
}
|
||||
}
|
||||
|
@ -797,6 +797,36 @@ void generate_string_file()
|
|||
fclose(f);
|
||||
}
|
||||
|
||||
utf8 *get_string_end(utf8 *text)
|
||||
{
|
||||
int codepoint;
|
||||
const utf8 *ch = text;
|
||||
|
||||
while ((codepoint = utf8_get_next(ch, &ch)) != 0) {
|
||||
if (utf8_is_format_code(codepoint)) {
|
||||
switch (codepoint) {
|
||||
case FORMAT_MOVE_X:
|
||||
case FORMAT_ADJUST_PALETTE:
|
||||
case 3:
|
||||
case 4:
|
||||
ch++;
|
||||
break;
|
||||
case FORMAT_INLINE_SPRITE:
|
||||
ch += 4;
|
||||
break;
|
||||
default:
|
||||
if (codepoint <= 22) {
|
||||
ch += 2;
|
||||
} else {
|
||||
ch += 4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ch - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the length of the string in buffer.
|
||||
* note you can't use strlen as there can be inline sprites!
|
||||
|
|
|
@ -35,6 +35,7 @@ void format_string_raw(char *dest, char *src, void *args);
|
|||
void format_string_to_upper(char *dest, rct_string_id format, void *args);
|
||||
void generate_string_file();
|
||||
void error_string_quit(int error, rct_string_id format);
|
||||
utf8 *get_string_end(utf8 *text);
|
||||
int get_string_length(const utf8* buffer);
|
||||
|
||||
void user_string_clear_all();
|
||||
|
@ -45,6 +46,8 @@ bool is_user_string_id(rct_string_id stringId);
|
|||
utf8 *win1252_to_utf8_alloc(const char *src);
|
||||
int win1252_to_utf8(utf8string dst, const char *src, int maxBufferLength);
|
||||
|
||||
wchar_t encoding_convert_gb2312_to_unicode(wchar_t gb2312);
|
||||
|
||||
#define MAX_USER_STRINGS 1024
|
||||
#define USER_STRING_MAX_LENGTH 32
|
||||
|
||||
|
|
Loading…
Reference in New Issue