aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/kyra/screen.cpp4
-rw-r--r--graphics/sjis.cpp124
-rw-r--r--graphics/sjis.h52
3 files changed, 158 insertions, 22 deletions
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index f2221d0c3c..5a7bbc4f9a 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -1136,7 +1136,7 @@ int Screen::getFontWidth() const {
int Screen::getCharWidth(uint16 c) const {
if ((c & 0xFF00) && _sjisFont)
- return _sjisFont->getFontWidth() >> 1;
+ return _sjisFont->getMaxFontWidth() >> 1;
return _fonts[_currentFont]->getCharWidth(c) + _charWidth;
}
@@ -3092,7 +3092,7 @@ void Screen::drawCharSJIS(uint16 c, int x, int y) {
}
if (_curPage == 0 || _curPage == 1)
- addDirtyRect(x, y, _sjisFont->getFontWidth() >> 1, _sjisFont->getFontHeight() >> 1);
+ addDirtyRect(x, y, _sjisFont->getMaxFontWidth() >> 1, _sjisFont->getFontHeight() >> 1);
x <<= 1;
y <<= 1;
diff --git a/graphics/sjis.cpp b/graphics/sjis.cpp
index e6ad08e14c..a3460d04e5 100644
--- a/graphics/sjis.cpp
+++ b/graphics/sjis.cpp
@@ -122,7 +122,7 @@ void FontSJIS16x16::drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1
else
drawCharInternOutline<uint16>(glyphSource, (uint8 *)dst, pitch, c1, c2);
} else {
- error("FontTowns::drawChar: unsupported bpp: %d", bpp);
+ error("FontSJIS16x16::drawChar: unsupported bpp: %d", bpp);
}
}
@@ -250,19 +250,117 @@ bool FontSjisSVM::loadData() {
return false;
}
uint numChars16x16 = data->readUint16BE();
- /*uint numChars8x16 = */data->readUint16BE();
+ uint numChars8x16 = data->readUint16BE();
- _fontData16x16 = new uint16[numChars16x16 * 16];
- assert(_fontData16x16);
_fontData16x16Size = numChars16x16 * 16;
+ _fontData16x16 = new uint16[_fontData16x16Size];
+ assert(_fontData16x16);
for (uint i = 0; i < _fontData16x16Size; ++i)
_fontData16x16[i] = data->readUint16BE();
+ _fontData8x16Size = numChars8x16 * 16;
+ _fontData8x16 = new uint8[numChars8x16 * 16];
+ assert(_fontData8x16);
+
+ data->read(_fontData8x16, _fontData8x16Size);
+
bool retValue = !data->err();
delete data;
return retValue;
}
+
+void FontSjisSVM::drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, uint32 c2) const {
+ if (!is8x16(ch))
+ return FontSJIS16x16::drawChar(dst, ch, pitch, bpp, c1, c2);
+
+ const uint8 *glyphSource = getCharData8x16(ch);
+ if (!glyphSource)
+ return;
+
+ if (bpp == 1) {
+ if (!_outlineEnabled)
+ drawCharIntern<uint8>(glyphSource, (uint8 *)dst, pitch, c1);
+ else
+ drawCharInternOutline<uint8>(glyphSource, (uint8 *)dst, pitch, c1, c2);
+ } else if (bpp == 2) {
+ if (!_outlineEnabled)
+ drawCharIntern<uint16>(glyphSource, (uint8 *)dst, pitch, c1);
+ else
+ drawCharInternOutline<uint16>(glyphSource, (uint8 *)dst, pitch, c1, c2);
+ } else {
+ error("FontSjisSVM::drawChar: unsupported bpp: %d", bpp);
+ }
+}
+
+// TODO: Consider merging these with FontSjis16x16
+template<typename Color>
+void FontSjisSVM::drawCharInternOutline(const uint8 *glyph, uint8 *dst, int pitch, Color c1, Color c2) const {
+ uint16 outlineGlyph[18];
+ memset(outlineGlyph, 0, sizeof(outlineGlyph));
+
+ // Create an outline map including the original character
+ const uint8 *src = glyph;
+ for (int i = 0; i < 16; ++i) {
+ uint16 line = *src++;
+ line = (line << 2) | (line << 1) | (line << 0);
+
+ outlineGlyph[i + 0] |= line;
+ outlineGlyph[i + 1] |= line;
+ outlineGlyph[i + 2] |= line;
+ }
+
+ uint8 *dstLine = dst;
+ for (int y = 0; y < 18; ++y) {
+ Color *lineBuf = (Color *)dstLine;
+ uint16 line = outlineGlyph[y];
+
+ for (int x = 0; x < 10; ++x) {
+ if (line & 0x200)
+ *lineBuf = c2;
+ line <<= 1;
+ ++lineBuf;
+ }
+
+ dstLine += pitch;
+ }
+
+ // draw the original char
+ drawCharIntern<Color>(glyph, dst + pitch + 1, pitch, c1);
+}
+
+template<typename Color>
+void FontSjisSVM::drawCharIntern(const uint8 *glyph, uint8 *dst, int pitch, Color c1) const {
+ for (int y = 0; y < 16; ++y) {
+ Color *lineBuf = (Color *)dst;
+ uint8 line = *glyph++;
+
+ for (int x = 0; x < 8; ++x) {
+ if (line & 0x80)
+ *lineBuf = c1;
+ line <<= 1;
+ ++lineBuf;
+ }
+
+ dst += pitch;
+ }
+}
+
+uint FontSjisSVM::getCharWidth(uint16 ch) const {
+ if (is8x16(ch))
+ return _outlineEnabled ? 10 : 8;
+ else
+ return FontSJIS16x16::getMaxFontWidth();
+}
+
+bool FontSjisSVM::is8x16(uint16 ch) const {
+ if (ch >= 0xFF)
+ return false;
+ else if (ch <= 0x7F || (ch >= 0xA1 && ch <= 0xDF))
+ return true;
+ else
+ return false;
+}
const uint16 *FontSjisSVM::getCharData(uint16 c) const {
const uint8 fB = c & 0xFF;
@@ -292,6 +390,24 @@ const uint16 *FontSjisSVM::getCharData(uint16 c) const {
return _fontData16x16 + offset;
}
+const uint8 *FontSjisSVM::getCharData8x16(uint16 c) const {
+ const uint8 fB = c & 0xFF;
+ const uint8 sB = c >> 8;
+
+ if (!is8x16(c) || sB)
+ return 0;
+
+ int index = fB;
+
+ // half-width katakana
+ if (fB >= 0xA1 && fB <= 0xDF)
+ index -= 0x21;
+
+ const uint offset = index * 16;
+ assert(offset <= _fontData8x16Size);
+ return _fontData8x16 + offset;
+}
+
} // end of namespace Graphics
#endif // defined(GRAPHICS_SJIS_H)
diff --git a/graphics/sjis.h b/graphics/sjis.h
index 6e975b5afd..b819cffba3 100644
--- a/graphics/sjis.h
+++ b/graphics/sjis.h
@@ -47,8 +47,6 @@ namespace Graphics {
/**
* A font that is able to draw SJIS encoded characters.
- *
- * The font is always monospaced.
*/
class FontSJIS {
public:
@@ -75,7 +73,7 @@ public:
/**
* Enable outline drawing.
*
- * After changing outline state, getFontHeight and getFontWidth might return
+ * After changing outline state, getFontHeight and getMaxFontWidth / getCharWidth might return
* different values!
*/
virtual void enableOutline(bool enable) {}
@@ -86,9 +84,14 @@ public:
virtual uint getFontHeight() const = 0;
/**
- * Returns the width of the font.
+ * Returns the max. width of the font.
+ */
+ virtual uint getMaxFontWidth() const = 0;
+
+ /**
+ * Returns the width of a specific character.
*/
- virtual uint getFontWidth() const = 0;
+ virtual uint getCharWidth(uint16 ch) const { return getMaxFontWidth(); }
/**
* Draws a SJIS encoded character on the given surface.
@@ -104,12 +107,12 @@ public:
/**
* Draws a SJIS char on the given raw buffer.
*
- * @param dst pointer to the destination
- * @param ch character to draw (in little endian)
- * @param pitch pitch of the destination buffer (size in *bytes*)
- * @param bpp bytes per pixel of the destination buffer
- * @param c1 forground color
- * @param c2 outline color
+ * @param dst pointer to the destination
+ * @param ch character to draw (in little endian)
+ * @param pitch pitch of the destination buffer (size in *bytes*)
+ * @param bpp bytes per pixel of the destination buffer
+ * @param c1 forground color
+ * @param c2 outline color
*/
virtual void drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, uint32 c2) const = 0;
};
@@ -124,9 +127,9 @@ public:
void enableOutline(bool enable) { _outlineEnabled = enable; }
uint getFontHeight() const { return _outlineEnabled ? 18 : 16; }
- uint getFontWidth() const { return _outlineEnabled ? 18 : 16; }
+ uint getMaxFontWidth() const { return _outlineEnabled ? 18 : 16; }
- void drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, uint32 c2) const;
+ virtual void drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, uint32 c2) const;
private:
template<typename Color>
@@ -135,8 +138,8 @@ private:
template<typename Color>
void drawCharIntern(const uint16 *glyph, uint8 *dst, int pitch, Color c1) const;
- bool _outlineEnabled;
protected:
+ bool _outlineEnabled;
virtual const uint16 *getCharData(uint16 c) const = 0;
};
@@ -145,6 +148,8 @@ protected:
* FM-TOWNS ROM based SJIS compatible font.
*
* This is used in KYRA and SCI.
+ *
+ * TODO: This implementation does not support any 8x16 ASCII or half-width katakana chars.
*/
class FontTowns : public FontSJIS16x16 {
public:
@@ -168,19 +173,34 @@ private:
*/
class FontSjisSVM : public FontSJIS16x16 {
public:
- FontSjisSVM() : _fontData16x16(0), _fontData16x16Size(0) {}
- ~FontSjisSVM() { delete[] _fontData16x16; }
+ FontSjisSVM() : _fontData16x16(0), _fontData16x16Size(0), _fontData8x16(0), _fontData8x16Size(0) {}
+ ~FontSjisSVM() { delete[] _fontData16x16; delete[] _fontData8x16; }
/**
* Load the font data from "SJIS.FNT".
*/
bool loadData();
+ void drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, uint32 c2) const;
+
+ uint getCharWidth(uint16 ch) const;
private:
uint16 *_fontData16x16;
uint _fontData16x16Size;
+ uint8 *_fontData8x16;
+ uint _fontData8x16Size;
+
+ bool is8x16(uint16 ch) const;
+
const uint16 *getCharData(uint16 c) const;
+ const uint8 *getCharData8x16(uint16 c) const;
+
+ template<typename Color>
+ void drawCharInternOutline(const uint8 *glyph, uint8 *dst, int pitch, Color c1, Color c2) const;
+
+ template<typename Color>
+ void drawCharIntern(const uint8 *glyph, uint8 *dst, int pitch, Color c1) const;
};
// TODO: Consider adding support for PC98 ROM