[Scummvm-git-logs] scummvm master -> 382df658c42b01cccdba5347b9045def8bc6113f
bluegr
noreply at scummvm.org
Fri Sep 13 11:45:27 UTC 2024
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
382df658c4 XEEN: Support rendering Traditional Chinese characters
Commit: 382df658c42b01cccdba5347b9045def8bc6113f
https://github.com/scummvm/scummvm/commit/382df658c42b01cccdba5347b9045def8bc6113f
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2024-09-13T14:45:24+03:00
Commit Message:
XEEN: Support rendering Traditional Chinese characters
Note: this isn't full Chinese support, only font rendering
Tested with "Darkside of Xeen" and "Clouds of Xeen"
Signed-off-by: Vladimir Serbinenko <phcoder at gmail.com>
Changed paths:
engines/mm/xeen/font.cpp
engines/mm/xeen/font.h
engines/mm/xeen/window.cpp
diff --git a/engines/mm/xeen/font.cpp b/engines/mm/xeen/font.cpp
index 0cba4f54bb3..6a25f90fb53 100644
--- a/engines/mm/xeen/font.cpp
+++ b/engines/mm/xeen/font.cpp
@@ -27,13 +27,19 @@
namespace MM {
namespace Xeen {
+namespace {
+const int kBig5Width = 16;
+const int kBig5Height = 14;
+}
+
const byte *FontData::_fontData;
Common::Point *FontData::_fontWritePos;
byte FontData::_textColors[4];
byte FontData::_bgColor;
bool FontData::_fontReduced;
Justify FontData::_fontJustify;
-
+Graphics::Big5Font *FontData::_big5Font;
+
FontSurface::FontSurface() : XSurface(), _msgWraps(false), _displayString(nullptr),
_writePos(*FontData::_fontWritePos) {
setTextColor(0);
@@ -54,6 +60,7 @@ FontSurface::FontSurface() : XSurface(), _msgWraps(false), _displayString(nullpt
_fntEnWOffset = 0x1000;
_fntEnReducedWOffset = 0x1080;
}
+ _isBig5 = Common::ZH_TWN == lang;
}
FontSurface::FontSurface(int wv, int hv) : XSurface(wv, hv),
@@ -77,6 +84,7 @@ FontSurface::FontSurface(int wv, int hv) : XSurface(wv, hv),
_fntEnWOffset = 0x1000;
_fntEnReducedWOffset = 0x1080;
}
+ _isBig5 = Common::ZH_TWN == lang;
}
void FontSurface::writeSymbol(int symbolId) {
@@ -183,7 +191,7 @@ const char *FontSurface::writeString(const Common::String &s, const Common::Rect
// Main character display loop
while (_displayString <= displayEnd) {
- char c = getNextChar();
+ uint16_t c = getNextChar();
if (c == ' ') {
_writePos.x += _fontReduced ? 3 : 4;
@@ -233,7 +241,7 @@ const char *FontSurface::writeString(const Common::String &s, const Common::Rect
} else {
if (c == 6)
c = ' ';
- int offset_charW = c < 0 ?
+ int offset_charW = c & 0x80 ?
(_fontReduced ? _fntNonEnReducedWOffset : _fntNonEnWOffset) + (int)(c & 0x7F) :
(_fontReduced ? _fntEnReducedWOffset : _fntEnWOffset) + (int)c;
byte charSize = _fontData[offset_charW];
@@ -273,14 +281,12 @@ const char *FontSurface::writeString(const Common::String &s, const Common::Rect
if (idx < 0)
idx = 0;
setTextColor(idx);
+ } else if (Common::RU_RUS == lang && (c & 0x80)) {
+ writeChar(c, bounds);
} else if (c < ' ') {
- if (Common::RU_RUS == lang && c < 0) {
- writeChar(c, bounds);
- } else {
- // End of string or invalid command
- _displayString = nullptr;
- break;
- }
+ // End of string or invalid command
+ _displayString = nullptr;
+ break;
} else {
// Standard character - write it out
writeChar(c, bounds);
@@ -297,24 +303,35 @@ const char *FontSurface::writeString(const Common::String &s, const Common::Rect
return _displayString;
}
-void FontSurface::writeCharacter(char c, const Common::Rect &clipRect) {
+void FontSurface::writeCharacter(uint16_t c, const Common::Rect &clipRect) {
Justify justify = _fontJustify;
_fontJustify = JUSTIFY_NONE;
- writeString(Common::String::format("%c", c), clipRect);
+ if (_isBig5 && c >= 0x100)
+ writeString(Common::String::format("%c%c", c >> 8, c & 0xff), clipRect);
+ else
+ writeString(Common::String::format("%c", c), clipRect);
_fontJustify = justify;
}
-char FontSurface::getNextChar() {
- if (Common::RU_RUS == lang)
- return *_displayString++;
+uint16_t FontSurface::getNextChar() {
+ if (_isBig5) {
+ uint8_t lead = *_displayString++;
+ if (!(lead & 0x80))
+ return lead;
+ return (lead << 8) | (*_displayString++ & 0xff);
+ } else if (Common::RU_RUS == lang)
+ return *_displayString++ & 0xff;
else
return *_displayString++ & 0x7f;
}
bool FontSurface::getNextCharWidth(int &total) {
- char c = getNextChar();
+ uint16_t c = getNextChar();
- if (c > ' ') {
+ if (_isBig5 && c > 0xff) {
+ total += kBig5Width;
+ return false;
+ } if (c > ' ') {
total += _fontData[(_fontReduced ? _fntEnReducedWOffset : _fntEnWOffset) + (int)c];
return false;
} else if (c == ' ') {
@@ -334,7 +351,7 @@ bool FontSurface::getNextCharWidth(int &total) {
if (c != 'd')
getNextChar();
return false;
- } else if (Common::RU_RUS == lang && c < 0) {
+ } else if (Common::RU_RUS == lang && (c & 0x80)) {
total += _fontData[(_fontReduced ? _fntNonEnReducedWOffset : _fntNonEnWOffset) + (int)(c & 0x7F)];
return false;
} else {
@@ -360,7 +377,7 @@ bool FontSurface::newLine(const Common::Rect &bounds) {
int FontSurface::fontAtoi(int len) {
int total = 0;
for (int i = 0; i < len; ++i) {
- char c = getNextChar();
+ uint16_t c = getNextChar();
if (c == ' ')
c = '0';
@@ -379,9 +396,17 @@ void FontSurface::setTextColor(int idx) {
Common::copy(colP, colP + 4, &_textColors[0]);
}
-void FontSurface::writeChar(char c, const Common::Rect &clipRect) {
+void FontSurface::writeChar(uint16_t c, const Common::Rect &clipRect) {
// Get y position, handling kerning
int y = _writePos.y;
+ if (_isBig5 && c > 0xff) {
+ _big5Font->drawBig5Char(surfacePtr(), c, _writePos, _textColors[0]);
+ _writePos.x += kBig5Width;
+ addDirtyRect(Common::Rect(_writePos.x, _writePos.y, _writePos.x + kBig5Width,
+ _writePos.y + kBig5Height));
+
+ return;
+ }
if (c == 'g' || c == 'p' || c == 'q' || c == 'y')
++y;
int yStart = y;
@@ -389,7 +414,7 @@ void FontSurface::writeChar(char c, const Common::Rect &clipRect) {
// Get pointers into font data and surface to write pixels to
int offset_charData;
int offset_charW;
- if (Common::RU_RUS == lang && c < 0) {
+ if (Common::RU_RUS == lang && (c & 0x80)) {
offset_charData = (_fontReduced ? _fntNonEnReducedOffset : _fntNonEnOffset) + (int)(c & 0x7F) * 16;
offset_charW = (_fontReduced ? _fntNonEnReducedWOffset : _fntNonEnWOffset) + (int)(c & 0x7F);
} else {
diff --git a/engines/mm/xeen/font.h b/engines/mm/xeen/font.h
index 6767c4bc2c7..b8b33605c2e 100644
--- a/engines/mm/xeen/font.h
+++ b/engines/mm/xeen/font.h
@@ -24,6 +24,7 @@
#include "common/language.h"
#include "mm/shared/xeen/xsurface.h"
+#include "graphics/big5.h"
namespace MM {
namespace Xeen {
@@ -41,12 +42,14 @@ struct FontData {
static byte _bgColor;
static bool _fontReduced;
static Justify _fontJustify;
+ static Graphics::Big5Font *_big5Font;
};
class FontSurface: public Shared::Xeen::XSurface, public FontData {
private:
const char *_displayString;
bool _msgWraps;
+ bool _isBig5;
Common::Language lang;
/**
@@ -64,7 +67,7 @@ private:
/**
* Return the next pending character to display
*/
- char getNextChar();
+ uint16_t getNextChar();
/**
* Return the width of a given character
@@ -89,7 +92,7 @@ private:
/**
* Wrie a character to the surface
*/
- void writeChar(char c, const Common::Rect &clipRect);
+ void writeChar(uint16_t c, const Common::Rect &clipRect);
public:
Common::Point &_writePos;
public:
@@ -118,7 +121,7 @@ public:
* @param c Character
* @param clipRect Window bounds to display string within
*/
- void writeCharacter(char c, const Common::Rect &clipRect);
+ void writeCharacter(uint16_t c, const Common::Rect &clipRect);
};
} // End of namespace Xeen
diff --git a/engines/mm/xeen/window.cpp b/engines/mm/xeen/window.cpp
index f9f32588d7e..d3f8d43a30a 100644
--- a/engines/mm/xeen/window.cpp
+++ b/engines/mm/xeen/window.cpp
@@ -84,6 +84,18 @@ Windows::Windows() {
};
_windows = Common::Array<Window>(windows, 42);
+
+ Common::File pat;
+ if (pat.open("TEXTPAT.FNT")) {
+ _big5Font = new Graphics::Big5Font();
+ _big5Font->loadPrefixedRaw(pat, 14);
+ } else if (pat.open("CMM4.PAT")) {
+ _big5Font = new Graphics::Big5Font();
+ _big5Font->loadPrefixedRaw(pat, 15);
+ } else if (g_vm->getLanguage() == Common::ZH_TWN) {
+ error("Unable to find TEXTPAT.FNT or CMM4.PAT for Chinese version");
+ }
+
}
Windows::~Windows() {
More information about the Scummvm-git-logs
mailing list