mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-29 15:22:08 +00:00
- let the 3 relevant text functions handle UTF-8 strings
These functions are: DCanvas::DrawTextCommon, V_BreakLines and FFont::StringWidth. This will allow strings from UTF-8 encoded assets to display properly, but also handle the OpenAL device name on international systems, as this will be returned as an UTF-8 string. Due to backwards compatibility needs the decoding function is rather lax to allow both UTF-8 and ISO 8859-1 to pass through correctly - and this also implies that it will allow mixed encodings which may happen if strings from different sources get concatenated.
This commit is contained in:
parent
7cbcbe66c0
commit
cc54db6e6d
3 changed files with 81 additions and 7 deletions
|
@ -890,9 +890,10 @@ int FFont::StringWidth(const uint8_t *string) const
|
||||||
|
|
||||||
while (*string)
|
while (*string)
|
||||||
{
|
{
|
||||||
if (*string == TEXTCOLOR_ESCAPE)
|
auto chr = GetCharFromString(string);
|
||||||
|
if (chr == TEXTCOLOR_ESCAPE)
|
||||||
{
|
{
|
||||||
++string;
|
// We do not need to check for UTF-8 in here.
|
||||||
if (*string == '[')
|
if (*string == '[')
|
||||||
{
|
{
|
||||||
while (*string != '\0' && *string != ']')
|
while (*string != '\0' && *string != ']')
|
||||||
|
@ -906,16 +907,15 @@ int FFont::StringWidth(const uint8_t *string) const
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (*string == '\n')
|
else if (chr == '\n')
|
||||||
{
|
{
|
||||||
if (w > maxw)
|
if (w > maxw)
|
||||||
maxw = w;
|
maxw = w;
|
||||||
w = 0;
|
w = 0;
|
||||||
++string;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
w += GetCharWidth(*string++) + GlobalKerning;
|
w += GetCharWidth(chr) + GlobalKerning;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,78 @@
|
||||||
|
|
||||||
int ListGetInt(VMVa_List &tags);
|
int ListGetInt(VMVa_List &tags);
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// reads one character from the string.
|
||||||
|
// This can handle both ISO 8859-1 and UTF-8, as well as mixed strings
|
||||||
|
// between both encodings, which may happen if inconsistent encoding is
|
||||||
|
// used between different files in a mod.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
int GetCharFromString(const uint8_t *&string)
|
||||||
|
{
|
||||||
|
int z, y, x;
|
||||||
|
|
||||||
|
z = *string++;
|
||||||
|
|
||||||
|
if (z < 192)
|
||||||
|
{
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
else if (z <= 223)
|
||||||
|
{
|
||||||
|
y = *string++;
|
||||||
|
if (y < 128 || y >= 192)
|
||||||
|
{
|
||||||
|
// not an UTF-8 sequence so return the first byte unchanged
|
||||||
|
string--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
z = (z - 192) * 64 + (y - 128);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (z >= 224 && z <= 239)
|
||||||
|
{
|
||||||
|
y = *string++;
|
||||||
|
if (y < 128 || y >= 192)
|
||||||
|
{
|
||||||
|
// not an UTF-8 sequence so return the first byte unchanged
|
||||||
|
string--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x = *string++;
|
||||||
|
if (x < 128 || x >= 192)
|
||||||
|
{
|
||||||
|
// not an UTF-8 sequence so return the first byte unchanged
|
||||||
|
string -= 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
z = (z - 224) * 4096 + (y - 128) * 64 + (x - 128);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (z >= 240)
|
||||||
|
{
|
||||||
|
y = *string++;
|
||||||
|
if (y < 128 || y >= 192)
|
||||||
|
{
|
||||||
|
// not an UTF-8 sequence so return the first byte unchanged
|
||||||
|
string--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we do not support 4-Byte UTF-8 here
|
||||||
|
string += 2;
|
||||||
|
return '?';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// DrawChar
|
// DrawChar
|
||||||
|
@ -170,7 +242,7 @@ void DCanvas::DrawTextCommon(FFont *font, int normalcolor, double x, double y, c
|
||||||
|
|
||||||
while ((const char *)ch - string < parms.maxstrlen)
|
while ((const char *)ch - string < parms.maxstrlen)
|
||||||
{
|
{
|
||||||
c = *ch++;
|
c = GetCharFromString(ch);
|
||||||
if (!c)
|
if (!c)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -288,7 +360,7 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const uint8_t *string, bo
|
||||||
|
|
||||||
w = 0;
|
w = 0;
|
||||||
|
|
||||||
while ( (c = *string++) )
|
while ( (c = GetCharFromString(string)) )
|
||||||
{
|
{
|
||||||
if (c == TEXTCOLOR_ESCAPE)
|
if (c == TEXTCOLOR_ESCAPE)
|
||||||
{
|
{
|
||||||
|
|
|
@ -86,4 +86,6 @@ inline FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const char *str, b
|
||||||
inline FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const FString &str, bool preservecolor = false, unsigned int *count = nullptr)
|
inline FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const FString &str, bool preservecolor = false, unsigned int *count = nullptr)
|
||||||
{ return V_BreakLines (font, maxwidth, (const uint8_t *)str.GetChars(), preservecolor, count); }
|
{ return V_BreakLines (font, maxwidth, (const uint8_t *)str.GetChars(), preservecolor, count); }
|
||||||
|
|
||||||
|
int GetCharFromString(const uint8_t *&string);
|
||||||
|
|
||||||
#endif //__V_TEXT_H__
|
#endif //__V_TEXT_H__
|
||||||
|
|
Loading…
Reference in a new issue