From 206971d16b56ff37a6a81ff85a1b488fdc60c627 Mon Sep 17 00:00:00 2001 From: Florian Kagerer Date: Fri, 5 Nov 2010 00:36:23 +0000 Subject: SCUMM/FM-TOWNS JAPANESE: fix out of bounds text drawing (could cause invalid memory access in MI1) svn-id: r54079 --- graphics/sjis.cpp | 28 +++++++++++++++++++++++----- graphics/sjis.h | 12 +++++------- 2 files changed, 28 insertions(+), 12 deletions(-) (limited to 'graphics') diff --git a/graphics/sjis.cpp b/graphics/sjis.cpp index b9d0d8332f..6e758051a3 100644 --- a/graphics/sjis.cpp +++ b/graphics/sjis.cpp @@ -138,9 +138,12 @@ const uint8 *FontSJISBase::flipCharacter(const uint8 *glyph, const int w) const } #endif -void FontSJISBase::drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, uint32 c2) const { +void FontSJISBase::drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, uint32 c2, int maxW, int maxH) const { const uint8 *glyphSource = 0; int width = 0, height = 0; + int outlineExtraWidth = 2, outlineExtraHeight = 2; + int outlineXOffset = 0, outlineYOffset = 0; + if (is8x16(ch)) { glyphSource = getCharData8x16(ch); width = 8; @@ -151,6 +154,21 @@ void FontSJISBase::drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, height = 16; } + if (maxW != -1 && maxW < width) { + width = maxW; + outlineExtraWidth = 0; + outlineXOffset = 1; + } + + if (maxH != -1 && maxH < height) { + height = maxH; + outlineExtraHeight = 0; + outlineYOffset = 1; + } + + if (width <= 0 || height <= 0) + return; + if (!glyphSource) { warning("FontSJISBase::drawChar: Font does not offer data for %02X %02X", ch & 0xFF, ch >> 8); return; @@ -169,15 +187,15 @@ void FontSJISBase::drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, if (bpp == 1) { if (_drawMode == kOutlineMode) { - blitCharacter(outline, width + 2, height + 2, (uint8 *)dst, pitch, c2); - blitCharacter(glyphSource, width, height, (uint8 *)dst + pitch + 1, pitch, c1); + blitCharacter(outline, width + outlineExtraWidth, height + outlineExtraHeight, (uint8 *)dst, pitch, c2); + blitCharacter(glyphSource, width - outlineXOffset, height - outlineYOffset, (uint8 *)dst + pitch + 1, pitch, c1); } else { blitCharacter(glyphSource, width, height, (uint8 *)dst, pitch, c1, c2); } } else if (bpp == 2) { if (_drawMode == kOutlineMode) { - blitCharacter(outline, width + 2, height + 2, (uint8 *)dst, pitch, c2); - blitCharacter(glyphSource, width, height, (uint8 *)dst + pitch + 2, pitch, c1); + blitCharacter(outline, width + outlineExtraWidth, height + outlineExtraHeight, (uint8 *)dst, pitch, c2); + blitCharacter(glyphSource, width - outlineXOffset, height - outlineYOffset, (uint8 *)dst + pitch + 2, pitch, c1); } else { blitCharacter(glyphSource, width, height, (uint8 *)dst, pitch, c1, c2); } diff --git a/graphics/sjis.h b/graphics/sjis.h index 4ade2f5278..3ba07230da 100644 --- a/graphics/sjis.h +++ b/graphics/sjis.h @@ -115,13 +115,9 @@ public: /** * Draws a SJIS encoded character on the given surface. - * - * TODO: Currently there is no assurance, that this method will only draw within - * the surface boundaries. Thus the caller has to assure the glyph will fit at - * the specified position. */ void drawChar(Graphics::Surface &dst, uint16 ch, int x, int y, uint32 c1, uint32 c2) const { - drawChar(dst.getBasePtr(x, y), ch, c1, c2, dst.pitch, dst.bytesPerPixel); + drawChar(dst.getBasePtr(x, y), ch, dst.pitch, dst.bytesPerPixel, c1, c2, dst.w - x, dst.h - y); } /** @@ -133,8 +129,10 @@ public: * @param bpp bytes per pixel of the destination buffer * @param c1 forground color * @param c2 outline color + * @param maxW max draw width (to ensure that character drawing takes place within surface boundaries) + * @param maxH max draw height (to ensure that character drawing takes place within surface boundaries) */ - 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, int maxW = -1, int maxH = -1) const = 0; }; /** @@ -154,7 +152,7 @@ public: uint getCharWidth(uint16 ch) const; - void drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, uint32 c2) const; + void drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, uint32 c2, int maxW = -1, int maxH = -1) const; private: template void blitCharacter(const uint8 *glyph, const int w, const int h, uint8 *dst, int pitch, Color c1, Color c2 = 0) const; -- cgit v1.2.3