diff options
| author | Johannes Schickel | 2011-07-01 04:13:37 +0200 | 
|---|---|---|
| committer | Johannes Schickel | 2011-07-01 05:42:54 +0200 | 
| commit | c047f871d646e89ccaacedb83136112244eb1b44 (patch) | |
| tree | 8fe988c9425a0c79061fa004c9b329e27e8284ea | |
| parent | 173db53e4b89dfafe9582a48d28a3450c888e200 (diff) | |
| download | scummvm-rg350-c047f871d646e89ccaacedb83136112244eb1b44.tar.gz scummvm-rg350-c047f871d646e89ccaacedb83136112244eb1b44.tar.bz2 scummvm-rg350-c047f871d646e89ccaacedb83136112244eb1b44.zip | |
GRAPHICS: Cleanup SJIS font code a bit.
| -rw-r--r-- | graphics/sjis.cpp | 306 | ||||
| -rw-r--r-- | graphics/sjis.h | 27 | 
2 files changed, 187 insertions, 146 deletions
| diff --git a/graphics/sjis.cpp b/graphics/sjis.cpp index 09e1746df4..e3925f99c4 100644 --- a/graphics/sjis.cpp +++ b/graphics/sjis.cpp @@ -58,6 +58,43 @@ void FontSJIS::drawChar(Graphics::Surface &dst, uint16 ch, int x, int y, uint32  	drawChar(dst.getBasePtr(x, y), ch, dst.pitch, dst.format.bytesPerPixel, c1, c2, dst.w - x, dst.h - y);  } +FontSJISBase::FontSJISBase() : _drawMode(kDefaultMode), _flippedMode(false) { +} + +void FontSJISBase::setDrawingMode(DrawingMode mode) { +	_drawMode = mode; +} + +void FontSJISBase::toggleFlippedMode(bool enable) { +	_flippedMode = enable; +} + +uint FontSJISBase::getFontHeight() const { +	switch (_drawMode) { +	case kOutlineMode: +		return 18; + +	case kDefaultMode: +		return 16; + +	default: +		return 17; +	} +} + +uint FontSJISBase::getMaxFontWidth() const { +	switch (_drawMode) { +	case kOutlineMode: +		return 18; + +	case kDefaultMode: +		return 16; + +	default: +		return 17; +	} +} +  template<typename Color>  void FontSJISBase::blitCharacter(const uint8 *glyph, const int w, const int h, uint8 *dst, int pitch, Color c) const {  	for (int y = 0; y < h; ++y) { @@ -131,6 +168,9 @@ const uint8 *FontSJISBase::flipCharacter(const uint8 *glyph, const int w) const  		0x0F, 0x8F, 0x4F, 0xC7, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x97, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF  	}; +	// TODO: This code looks like it will only work with 16 pixel wide +	// characters we should really take care that we only call it on these +	// or we fix this to support a generic width.  	for (int i = 0; i < w; i++) {  		_tempGlyph[i] = flipData[glyph[(w * 2 - 1) - i]];  		_tempGlyph[(w * 2 - 1) - i] = flipData[glyph[i]]; @@ -146,8 +186,8 @@ void FontSJISBase::drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1,  	int outlineExtraWidth = 2, outlineExtraHeight = 2;  	int outlineXOffset = 0, outlineYOffset = 0; -	if (is8x16(ch)) { -		glyphSource = getCharData8x16(ch); +	if (isASCII(ch)) { +		glyphSource = getCharData(ch);  		width = 8;  		height = 16;  	} else { @@ -177,6 +217,9 @@ void FontSJISBase::drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1,  	}  #ifndef DISABLE_FLIPPED_MODE +	// TODO: This code inside flopCharater looks like it will only work with +	// 16 pixel wide characters we should really take care that we only call +	// it on these or we fix it to support a generic width.  	if (_flippedMode)  		glyphSource = flipCharacter(glyphSource, width);  #endif @@ -221,13 +264,13 @@ void FontSJISBase::drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1,  }  uint FontSJISBase::getCharWidth(uint16 ch) const { -	if (is8x16(ch)) +	if (isASCII(ch))  		return (_drawMode == kOutlineMode) ? 10 : (_drawMode == kDefaultMode ? 8 : 9);  	else  		return getMaxFontWidth();  } -bool FontSJISBase::is8x16(uint16 ch) const { +bool FontSJISBase::isASCII(uint16 ch) const {  	if (ch >= 0xFF)  		return false;  	else if (ch <= 0x7F || (ch >= 0xA1 && ch <= 0xDF)) @@ -253,105 +296,112 @@ bool FontTowns::loadData() {  }  const uint8 *FontTowns::getCharData(uint16 ch) const { -	uint8 f = ch & 0xFF; -	uint8 s = ch >> 8; - -	// copied from scumm\charset.cpp -	enum { -		KANA = 0, -		KANJI = 1, -		EKANJI = 2 -	}; - -	int base = s - ((s + 1) % 32); -	int c = 0, p = 0, chunk_f = 0, chunk = 0, cr = 0, kanjiType = KANA; +	if (ch < kFont8x16Chars) { +		return _fontData8x16 + ch * 16; +	} else { +		uint8 f = ch & 0xFF; +		uint8 s = ch >> 8; + +		// copied from scumm\charset.cpp +		enum { +			KANA = 0, +			KANJI = 1, +			EKANJI = 2 +		}; + +		int base = s - ((s + 1) % 32); +		int c = 0, p = 0, chunk_f = 0, chunk = 0, cr = 0, kanjiType = KANA; + +		if (f >= 0x81 && f <= 0x84) kanjiType = KANA; +		if (f >= 0x88 && f <= 0x9f) kanjiType = KANJI; +		if (f >= 0xe0 && f <= 0xea) kanjiType = EKANJI; + +		if ((f > 0xe8 || (f == 0xe8 && base >= 0x9f)) || (f > 0x90 || (f == 0x90 && base >= 0x9f))) { +			c = 48; //correction +			p = -8; //correction +		} -	if (f >= 0x81 && f <= 0x84) kanjiType = KANA; -	if (f >= 0x88 && f <= 0x9f) kanjiType = KANJI; -	if (f >= 0xe0 && f <= 0xea) kanjiType = EKANJI; +		if (kanjiType == KANA) {//Kana +			chunk_f = (f - 0x81) * 2; +		} else if (kanjiType == KANJI) {//Standard Kanji +			p += f - 0x88; +			chunk_f = c + 2 * p; +		} else if (kanjiType == EKANJI) {//Enhanced Kanji +			p += f - 0xe0; +			chunk_f = c + 2 * p; +		} -	if ((f > 0xe8 || (f == 0xe8 && base >= 0x9f)) || (f > 0x90 || (f == 0x90 && base >= 0x9f))) { -		c = 48; //correction -		p = -8; //correction -	} +		// Base corrections +		if (base == 0x7f && s == 0x7f) +			base -= 0x20; +		if (base == 0x9f && s == 0xbe) +			base += 0x20; +		if (base == 0xbf && s == 0xde) +			base += 0x20; +		//if (base == 0x7f && s == 0x9e) +		//	base += 0x20; + +		switch (base) { +		case 0x3f: +			cr = 0; //3f +			if (kanjiType == KANA) chunk = 1; +			else if (kanjiType == KANJI) chunk = 31; +			else if (kanjiType == EKANJI) chunk = 111; +			break; +		case 0x5f: +			cr = 0; //5f +			if (kanjiType == KANA) chunk = 17; +			else if (kanjiType == KANJI) chunk = 47; +			else if (kanjiType == EKANJI) chunk = 127; +			break; +		case 0x7f: +			cr = -1; //80 +			if (kanjiType == KANA) chunk = 9; +			else if (kanjiType == KANJI) chunk = 63; +			else if (kanjiType == EKANJI) chunk = 143; +			break; +		case 0x9f: +			cr = 1; //9e +			if (kanjiType == KANA) chunk = 2; +			else if (kanjiType == KANJI) chunk = 32; +			else if (kanjiType == EKANJI) chunk = 112; +			break; +		case 0xbf: +			cr = 1; //be +			if (kanjiType == KANA) chunk = 18; +			else if (kanjiType == KANJI) chunk = 48; +			else if (kanjiType == EKANJI) chunk = 128; +			break; +		case 0xdf: +			cr = 1; //de +			if (kanjiType == KANA) chunk = 10; +			else if (kanjiType == KANJI) chunk = 64; +			else if (kanjiType == EKANJI) chunk = 144; +			break; +		default: +			debug(4, "Invalid Char! f %x s %x base %x c %d p %d", f, s, base, c, p); +		} -	if (kanjiType == KANA) {//Kana -		chunk_f = (f - 0x81) * 2; -	} else if (kanjiType == KANJI) {//Standard Kanji -		p += f - 0x88; -		chunk_f = c + 2 * p; -	} else if (kanjiType == EKANJI) {//Enhanced Kanji -		p += f - 0xe0; -		chunk_f = c + 2 * p; +		debug(6, "Kanji: %c%c f 0x%x s 0x%x base 0x%x c %d p %d chunk %d cr %d index %d", f, s, f, s, base, c, p, chunk, cr, ((chunk_f + chunk) * 32 + (s - base)) + cr); +		const int chunkNum = (((chunk_f + chunk) * 32 + (s - base)) + cr); +		if (chunkNum < 0 || chunkNum >= kFont16x16Chars) +			return 0; +		else +			return _fontData16x16 + chunkNum * 32;  	} +} -	// Base corrections -	if (base == 0x7f && s == 0x7f) -		base -= 0x20; -	if (base == 0x9f && s == 0xbe) -		base += 0x20; -	if (base == 0xbf && s == 0xde) -		base += 0x20; -	//if (base == 0x7f && s == 0x9e) -	//	base += 0x20; - -	switch (base) { -	case 0x3f: -		cr = 0; //3f -		if (kanjiType == KANA) chunk = 1; -		else if (kanjiType == KANJI) chunk = 31; -		else if (kanjiType == EKANJI) chunk = 111; -		break; -	case 0x5f: -		cr = 0; //5f -		if (kanjiType == KANA) chunk = 17; -		else if (kanjiType == KANJI) chunk = 47; -		else if (kanjiType == EKANJI) chunk = 127; -		break; -	case 0x7f: -		cr = -1; //80 -		if (kanjiType == KANA) chunk = 9; -		else if (kanjiType == KANJI) chunk = 63; -		else if (kanjiType == EKANJI) chunk = 143; -		break; -	case 0x9f: -		cr = 1; //9e -		if (kanjiType == KANA) chunk = 2; -		else if (kanjiType == KANJI) chunk = 32; -		else if (kanjiType == EKANJI) chunk = 112; -		break; -	case 0xbf: -		cr = 1; //be -		if (kanjiType == KANA) chunk = 18; -		else if (kanjiType == KANJI) chunk = 48; -		else if (kanjiType == EKANJI) chunk = 128; -		break; -	case 0xdf: -		cr = 1; //de -		if (kanjiType == KANA) chunk = 10; -		else if (kanjiType == KANJI) chunk = 64; -		else if (kanjiType == EKANJI) chunk = 144; -		break; -	default: -		debug(4, "Invalid Char! f %x s %x base %x c %d p %d", f, s, base, c, p); -	} +// ScummVM SJIS font -	debug(6, "Kanji: %c%c f 0x%x s 0x%x base 0x%x c %d p %d chunk %d cr %d index %d", f, s, f, s, base, c, p, chunk, cr, ((chunk_f + chunk) * 32 + (s - base)) + cr); -	const int chunkNum = (((chunk_f + chunk) * 32 + (s - base)) + cr); -	if (chunkNum < 0 || chunkNum >= kFont16x16Chars) -		return 0; -	else -		return _fontData16x16 + chunkNum * 32; +FontSjisSVM::FontSjisSVM() +	: _fontData16x16(0), _fontData16x16Size(0), _fontData8x16(0), _fontData8x16Size(0) {  } -const uint8 *FontTowns::getCharData8x16(uint16 c) const { -	if (c >= kFont8x16Chars) -		return 0; -	return _fontData8x16 + c * 16; +FontSjisSVM::~FontSjisSVM() { +	delete[] _fontData16x16; +	delete[] _fontData8x16;  } -// ScummVM SJIS font -  bool FontSjisSVM::loadData() {  	Common::SeekableReadStream *data = SearchMan.createReadStreamForMember("SJIS.FNT");  	if (!data) @@ -393,46 +443,40 @@ const uint8 *FontSjisSVM::getCharData(uint16 c) const {  	const uint8 fB = c & 0xFF;  	const uint8 sB = c >> 8; -	// We only allow 2 byte SJIS characters. -	if (fB <= 0x80 || fB >= 0xF0 || (fB >= 0xA0 && fB <= 0xDF) || sB == 0x7F) -		return 0; - -	int base = fB; -	base -= 0x81; -	if (base >= 0x5F) -		base -= 0x40; - -	int index = sB; -	index -= 0x40; -	if (index >= 0x3F) -		--index; - -	// Another check if the passed character was an -	// correctly encoded SJIS character. -	if (index < 0 || index >= 0xBC || base < 0) -		return 0; - -	const uint offset = (base * 0xBC + index) * 32; -	assert(offset + 16 <= _fontData16x16Size); -	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; +	if (isASCII(c)) { +		int index = fB; -	// half-width katakana -	if (fB >= 0xA1 && fB <= 0xDF) -		index -= 0x21; +		// half-width katakana +		if (fB >= 0xA1 && fB <= 0xDF) +			index -= 0x21; -	const uint offset = index * 16; -	assert(offset <= _fontData8x16Size); -	return _fontData8x16 + offset; +		const uint offset = index * 16; +		assert(offset <= _fontData8x16Size); +		return _fontData8x16 + offset; +	} else { +		// We only allow 2 byte SJIS characters. +		if (fB <= 0x80 || fB >= 0xF0 || (fB >= 0xA0 && fB <= 0xDF) || sB == 0x7F) +			return 0; + +		int base = fB; +		base -= 0x81; +		if (base >= 0x5F) +			base -= 0x40; + +		int index = sB; +		index -= 0x40; +		if (index >= 0x3F) +			--index; + +		// Another check if the passed character was an +		// correctly encoded SJIS character. +		if (index < 0 || index >= 0xBC || base < 0) +			return 0; + +		const uint offset = (base * 0xBC + index) * 32; +		assert(offset + 16 <= _fontData16x16Size); +		return _fontData16x16 + offset; +	}  }  } // End of namespace Graphics diff --git a/graphics/sjis.h b/graphics/sjis.h index 0c3b057cc4..d455a96e64 100644 --- a/graphics/sjis.h +++ b/graphics/sjis.h @@ -134,19 +134,19 @@ public:   */  class FontSJISBase : public FontSJIS {  public: -	FontSJISBase() : _drawMode(kDefaultMode), _flippedMode(false) {} +	FontSJISBase(); -	void setDrawingMode(DrawingMode mode) { _drawMode = mode; } +	virtual void setDrawingMode(DrawingMode mode); -	void toggleFlippedMode(bool enable) { _flippedMode = enable; } +	virtual void toggleFlippedMode(bool enable); -	uint getFontHeight() const { return (_drawMode == kOutlineMode) ? 18 : (_drawMode == kDefaultMode ? 16 : 17); } +	virtual uint getFontHeight() const; -	uint getMaxFontWidth() const { return (_drawMode == kOutlineMode) ? 18 : (_drawMode == kDefaultMode ? 16 : 17); } +	virtual uint getMaxFontWidth() const; -	uint getCharWidth(uint16 ch) const; +	virtual uint getCharWidth(uint16 ch) const; -	void drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, uint32 c2, int maxW = -1, int maxH = -1) const; +	virtual void drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, uint32 c2, int maxW = -1, int maxH = -1) const;  private:  	template<typename Color>  	void blitCharacter(const uint8 *glyph, const int w, const int h, uint8 *dst, int pitch, Color c) const; @@ -162,10 +162,9 @@ protected:  	DrawingMode _drawMode;  	bool _flippedMode; -	bool is8x16(uint16 ch) const; +	bool isASCII(uint16 ch) const;  	virtual const uint8 *getCharData(uint16 c) const = 0; -	virtual const uint8 *getCharData8x16(uint16 c) const = 0;  };  /** @@ -188,8 +187,7 @@ private:  	uint8 _fontData16x16[kFont16x16Chars * 32];  	uint8 _fontData8x16[kFont8x16Chars * 32]; -	const uint8 *getCharData(uint16 c) const; -	const uint8 *getCharData8x16(uint16 c) const; +	virtual const uint8 *getCharData(uint16 c) const;  };  /** @@ -197,8 +195,8 @@ private:   */  class FontSjisSVM : public FontSJISBase {  public: -	FontSjisSVM() : _fontData16x16(0), _fontData16x16Size(0), _fontData8x16(0), _fontData8x16Size(0) {} -	~FontSjisSVM() { delete[] _fontData16x16; delete[] _fontData8x16; } +	FontSjisSVM(); +	~FontSjisSVM();  	/**  	 * Load the font data from "SJIS.FNT". @@ -211,8 +209,7 @@ private:  	uint8 *_fontData8x16;  	uint _fontData8x16Size; -	const uint8 *getCharData(uint16 c) const; -	const uint8 *getCharData8x16(uint16 c) const; +	virtual const uint8 *getCharData(uint16 c) const;  };  // TODO: Consider adding support for PC98 ROM | 
