[Scummvm-cvs-logs] SF.net SVN: scummvm:[44486] scummvm/trunk

lordhoto at users.sourceforge.net lordhoto at users.sourceforge.net
Wed Sep 30 16:53:07 CEST 2009


Revision: 44486
          http://scummvm.svn.sourceforge.net/scummvm/?rev=44486&view=rev
Author:   lordhoto
Date:     2009-09-30 14:53:07 +0000 (Wed, 30 Sep 2009)

Log Message:
-----------
Implemented support for drawing 8x16 chars from our custom SJIS font.

Modified Paths:
--------------
    scummvm/trunk/engines/kyra/screen.cpp
    scummvm/trunk/graphics/sjis.cpp
    scummvm/trunk/graphics/sjis.h

Modified: scummvm/trunk/engines/kyra/screen.cpp
===================================================================
--- scummvm/trunk/engines/kyra/screen.cpp	2009-09-30 13:41:19 UTC (rev 44485)
+++ scummvm/trunk/engines/kyra/screen.cpp	2009-09-30 14:53:07 UTC (rev 44486)
@@ -1136,7 +1136,7 @@
 
 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 @@
 	}
 
 	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;

Modified: scummvm/trunk/graphics/sjis.cpp
===================================================================
--- scummvm/trunk/graphics/sjis.cpp	2009-09-30 13:41:19 UTC (rev 44485)
+++ scummvm/trunk/graphics/sjis.cpp	2009-09-30 14:53:07 UTC (rev 44486)
@@ -122,7 +122,7 @@
 		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,20 +250,118 @@
 		return false;
 	}
 	uint numChars16x16 = data->readUint16BE();
-	/*uint numChars8x16 = */data->readUint16BE();
+	uint numChars8x16 = data->readUint16BE();
 
-	_fontData16x16 = new uint16[numChars16x16 * 16];
+	_fontData16x16Size = numChars16x16 * 16;
+	_fontData16x16 = new uint16[_fontData16x16Size];
 	assert(_fontData16x16);
-	_fontData16x16Size = numChars16x16 * 16;
 
 	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;
 	const uint8 sB = c >> 8;
@@ -292,6 +390,24 @@
 	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)

Modified: scummvm/trunk/graphics/sjis.h
===================================================================
--- scummvm/trunk/graphics/sjis.h	2009-09-30 13:41:19 UTC (rev 44485)
+++ scummvm/trunk/graphics/sjis.h	2009-09-30 14:53:07 UTC (rev 44486)
@@ -47,8 +47,6 @@
 
 /**
  * A font that is able to draw SJIS encoded characters.
- *
- * The font is always monospaced.
  */
 class FontSJIS {
 public:
@@ -75,7 +73,7 @@
 	/**
 	 * 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,11 +84,16 @@
 	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.
 	 *
 	 * TODO: Currently there is no assurance, that this method will only draw within
@@ -104,12 +107,12 @@
 	/**
 	 * 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 @@
 	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 @@
 	template<typename Color>
 	void drawCharIntern(const uint16 *glyph, uint8 *dst, int pitch, Color c1) const;
 
+protected:
 	bool _outlineEnabled;
-protected:
 
 	virtual const uint16 *getCharData(uint16 c) const = 0;
 };
@@ -145,6 +148,8 @@
  * 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 @@
  */
 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


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list