Implemented support for drawing 8x16 chars from our custom SJIS font.
svn-id: r44486
This commit is contained in:
parent
9be8a6e4f6
commit
03a26923c9
3 changed files with 158 additions and 22 deletions
|
@ -1136,7 +1136,7 @@ int Screen::getFontWidth() const {
|
||||||
|
|
||||||
int Screen::getCharWidth(uint16 c) const {
|
int Screen::getCharWidth(uint16 c) const {
|
||||||
if ((c & 0xFF00) && _sjisFont)
|
if ((c & 0xFF00) && _sjisFont)
|
||||||
return _sjisFont->getFontWidth() >> 1;
|
return _sjisFont->getMaxFontWidth() >> 1;
|
||||||
|
|
||||||
return _fonts[_currentFont]->getCharWidth(c) + _charWidth;
|
return _fonts[_currentFont]->getCharWidth(c) + _charWidth;
|
||||||
}
|
}
|
||||||
|
@ -3092,7 +3092,7 @@ void Screen::drawCharSJIS(uint16 c, int x, int y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_curPage == 0 || _curPage == 1)
|
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;
|
x <<= 1;
|
||||||
y <<= 1;
|
y <<= 1;
|
||||||
|
|
|
@ -122,7 +122,7 @@ void FontSJIS16x16::drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1
|
||||||
else
|
else
|
||||||
drawCharInternOutline<uint16>(glyphSource, (uint8 *)dst, pitch, c1, c2);
|
drawCharInternOutline<uint16>(glyphSource, (uint8 *)dst, pitch, c1, c2);
|
||||||
} else {
|
} else {
|
||||||
error("FontTowns::drawChar: unsupported bpp: %d", bpp);
|
error("FontSJIS16x16::drawChar: unsupported bpp: %d", bpp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,19 +250,117 @@ bool FontSjisSVM::loadData() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
uint numChars16x16 = data->readUint16BE();
|
uint numChars16x16 = data->readUint16BE();
|
||||||
/*uint numChars8x16 = */data->readUint16BE();
|
uint numChars8x16 = data->readUint16BE();
|
||||||
|
|
||||||
_fontData16x16 = new uint16[numChars16x16 * 16];
|
|
||||||
assert(_fontData16x16);
|
|
||||||
_fontData16x16Size = numChars16x16 * 16;
|
_fontData16x16Size = numChars16x16 * 16;
|
||||||
|
_fontData16x16 = new uint16[_fontData16x16Size];
|
||||||
|
assert(_fontData16x16);
|
||||||
|
|
||||||
for (uint i = 0; i < _fontData16x16Size; ++i)
|
for (uint i = 0; i < _fontData16x16Size; ++i)
|
||||||
_fontData16x16[i] = data->readUint16BE();
|
_fontData16x16[i] = data->readUint16BE();
|
||||||
|
|
||||||
|
_fontData8x16Size = numChars8x16 * 16;
|
||||||
|
_fontData8x16 = new uint8[numChars8x16 * 16];
|
||||||
|
assert(_fontData8x16);
|
||||||
|
|
||||||
|
data->read(_fontData8x16, _fontData8x16Size);
|
||||||
|
|
||||||
bool retValue = !data->err();
|
bool retValue = !data->err();
|
||||||
delete data;
|
delete data;
|
||||||
return retValue;
|
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 uint16 *FontSjisSVM::getCharData(uint16 c) const {
|
||||||
const uint8 fB = c & 0xFF;
|
const uint8 fB = c & 0xFF;
|
||||||
|
@ -292,6 +390,24 @@ const uint16 *FontSjisSVM::getCharData(uint16 c) const {
|
||||||
return _fontData16x16 + offset;
|
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
|
} // end of namespace Graphics
|
||||||
|
|
||||||
#endif // defined(GRAPHICS_SJIS_H)
|
#endif // defined(GRAPHICS_SJIS_H)
|
||||||
|
|
|
@ -47,8 +47,6 @@ namespace Graphics {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A font that is able to draw SJIS encoded characters.
|
* A font that is able to draw SJIS encoded characters.
|
||||||
*
|
|
||||||
* The font is always monospaced.
|
|
||||||
*/
|
*/
|
||||||
class FontSJIS {
|
class FontSJIS {
|
||||||
public:
|
public:
|
||||||
|
@ -75,7 +73,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Enable outline drawing.
|
* Enable outline drawing.
|
||||||
*
|
*
|
||||||
* After changing outline state, getFontHeight and getFontWidth might return
|
* After changing outline state, getFontHeight and getMaxFontWidth / getCharWidth might return
|
||||||
* different values!
|
* different values!
|
||||||
*/
|
*/
|
||||||
virtual void enableOutline(bool enable) {}
|
virtual void enableOutline(bool enable) {}
|
||||||
|
@ -86,9 +84,14 @@ public:
|
||||||
virtual uint getFontHeight() const = 0;
|
virtual uint getFontHeight() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the width of the font.
|
* Returns the max. width of the font.
|
||||||
*/
|
*/
|
||||||
virtual uint getFontWidth() const = 0;
|
virtual uint getMaxFontWidth() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the width of a specific character.
|
||||||
|
*/
|
||||||
|
virtual uint getCharWidth(uint16 ch) const { return getMaxFontWidth(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws a SJIS encoded character on the given surface.
|
* Draws a SJIS encoded character on the given surface.
|
||||||
|
@ -104,12 +107,12 @@ public:
|
||||||
/**
|
/**
|
||||||
* Draws a SJIS char on the given raw buffer.
|
* Draws a SJIS char on the given raw buffer.
|
||||||
*
|
*
|
||||||
* @param dst pointer to the destination
|
* @param dst pointer to the destination
|
||||||
* @param ch character to draw (in little endian)
|
* @param ch character to draw (in little endian)
|
||||||
* @param pitch pitch of the destination buffer (size in *bytes*)
|
* @param pitch pitch of the destination buffer (size in *bytes*)
|
||||||
* @param bpp bytes per pixel of the destination buffer
|
* @param bpp bytes per pixel of the destination buffer
|
||||||
* @param c1 forground color
|
* @param c1 forground color
|
||||||
* @param c2 outline color
|
* @param c2 outline color
|
||||||
*/
|
*/
|
||||||
virtual void drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, uint32 c2) const = 0;
|
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; }
|
void enableOutline(bool enable) { _outlineEnabled = enable; }
|
||||||
|
|
||||||
uint getFontHeight() const { return _outlineEnabled ? 18 : 16; }
|
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:
|
private:
|
||||||
template<typename Color>
|
template<typename Color>
|
||||||
|
@ -135,8 +138,8 @@ private:
|
||||||
template<typename Color>
|
template<typename Color>
|
||||||
void drawCharIntern(const uint16 *glyph, uint8 *dst, int pitch, Color c1) const;
|
void drawCharIntern(const uint16 *glyph, uint8 *dst, int pitch, Color c1) const;
|
||||||
|
|
||||||
bool _outlineEnabled;
|
|
||||||
protected:
|
protected:
|
||||||
|
bool _outlineEnabled;
|
||||||
|
|
||||||
virtual const uint16 *getCharData(uint16 c) const = 0;
|
virtual const uint16 *getCharData(uint16 c) const = 0;
|
||||||
};
|
};
|
||||||
|
@ -145,6 +148,8 @@ protected:
|
||||||
* FM-TOWNS ROM based SJIS compatible font.
|
* FM-TOWNS ROM based SJIS compatible font.
|
||||||
*
|
*
|
||||||
* This is used in KYRA and SCI.
|
* 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 {
|
class FontTowns : public FontSJIS16x16 {
|
||||||
public:
|
public:
|
||||||
|
@ -168,19 +173,34 @@ private:
|
||||||
*/
|
*/
|
||||||
class FontSjisSVM : public FontSJIS16x16 {
|
class FontSjisSVM : public FontSJIS16x16 {
|
||||||
public:
|
public:
|
||||||
FontSjisSVM() : _fontData16x16(0), _fontData16x16Size(0) {}
|
FontSjisSVM() : _fontData16x16(0), _fontData16x16Size(0), _fontData8x16(0), _fontData8x16Size(0) {}
|
||||||
~FontSjisSVM() { delete[] _fontData16x16; }
|
~FontSjisSVM() { delete[] _fontData16x16; delete[] _fontData8x16; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the font data from "SJIS.FNT".
|
* Load the font data from "SJIS.FNT".
|
||||||
*/
|
*/
|
||||||
bool loadData();
|
bool loadData();
|
||||||
|
|
||||||
|
void drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, uint32 c2) const;
|
||||||
|
|
||||||
|
uint getCharWidth(uint16 ch) const;
|
||||||
private:
|
private:
|
||||||
uint16 *_fontData16x16;
|
uint16 *_fontData16x16;
|
||||||
uint _fontData16x16Size;
|
uint _fontData16x16Size;
|
||||||
|
|
||||||
|
uint8 *_fontData8x16;
|
||||||
|
uint _fontData8x16Size;
|
||||||
|
|
||||||
|
bool is8x16(uint16 ch) const;
|
||||||
|
|
||||||
const uint16 *getCharData(uint16 c) 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
|
// TODO: Consider adding support for PC98 ROM
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue