diff --git a/engines/zvision/text/truetype_font.cpp b/engines/zvision/text/truetype_font.cpp index 9f4fbe7..f7580fb 100644 --- a/engines/zvision/text/truetype_font.cpp +++ b/engines/zvision/text/truetype_font.cpp @@ -26,6 +26,7 @@ #include "common/file.h" #include "common/system.h" #include "common/unzip.h" +#include "common/ustr.h" #include "graphics/font.h" #include "graphics/fonts/ttf.h" #include "graphics/surface.h" @@ -168,6 +169,36 @@ int StyledTTFont::getKerningOffset(byte left, byte right) { return 0; } +Common::U32String StyledTTFont::convertUtf8ToUtf32(const Common::String &str) { + // The String class, and therefore the Font class as well, assume one + // character is one byte, but in this case it's actually an UTF-8 + // string with up to 4 bytes per character. To work around this, + // convert it to an U32String before drawing it, because our Font class + // can handle that. + Common::U32String u32str; + uint i = 0; + while (i < str.size()) { + uint32 chr = 0; + if ((str[i] & 0xF8) == 0xF0) { + chr |= (str[i++] & 0x07) << 18; + chr |= (str[i++] & 0x3F) << 12; + chr |= (str[i++] & 0x3F) << 6; + chr |= (str[i++] & 0x3F); + } else if ((str[i] & 0xF0) == 0xE0) { + chr |= (str[i++] & 0x0F) << 12; + chr |= (str[i++] & 0x3F) << 6; + chr |= (str[i++] & 0x3F); + } else if ((str[i] & 0xE0) == 0xC0) { + chr |= (str[i++] & 0x1F) << 6; + chr |= (str[i++] & 0x3F); + } else { + chr = (str[i++] & 0x7F); + } + u32str += chr; + } + return u32str; +} + void StyledTTFont::drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) { if (_font) { _font->drawChar(dst, chr, x, y, color); @@ -186,10 +217,11 @@ void StyledTTFont::drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint void StyledTTFont::drawString(Graphics::Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, Graphics::TextAlign align) { if (_font) { - _font->drawString(dst, str, x, y, w, color, align); + Common::U32String u32str = convertUtf8ToUtf32(str); + _font->drawString(dst, u32str, x, y, w, color, align); if (_style & STTF_UNDERLINE) { int16 pos = floor(_font->getFontHeight() * 0.87); - int16 wd = MIN(_font->getStringWidth(str), w); + int16 wd = MIN(_font->getStringWidth(u32str), w); int16 stX = x; if (align == Graphics::kTextAlignCenter) stX += (w - wd) / 2; @@ -202,7 +234,7 @@ void StyledTTFont::drawString(Graphics::Surface *dst, const Common::String &str, } if (_style & STTF_STRIKEOUT) { int16 pos = floor(_font->getFontHeight() * 0.60); - int16 wd = MIN(_font->getStringWidth(str), w); + int16 wd = MIN(_font->getStringWidth(u32str), w); int16 stX = x; if (align == Graphics::kTextAlignCenter) stX += (w - wd) / 2; diff --git a/engines/zvision/text/truetype_font.h b/engines/zvision/text/truetype_font.h index 6fbb1f0..caa9c09 100644 --- a/engines/zvision/text/truetype_font.h +++ b/engines/zvision/text/truetype_font.h @@ -77,6 +77,8 @@ public: int getCharWidth(byte chr); int getKerningOffset(byte left, byte right); + Common::U32String convertUtf8ToUtf32(const Common::String &str); + void drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color); void drawString(Graphics::Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, Graphics::TextAlign align = Graphics::kTextAlignLeft);