mirror of
https://github.com/libretro/scummvm.git
synced 2025-04-02 14:51:40 +00:00
SCUMM/FM-TOWNS JAPANESE: fix out of bounds text drawing
(could cause invalid memory access in MI1) svn-id: r54079
This commit is contained in:
parent
8c997e2608
commit
206971d16b
@ -773,13 +773,13 @@ void CharsetRendererV3::printChar(int chr, bool ignoreCharsetMask) {
|
||||
if (charPtr)
|
||||
drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight, vs->bytesPerPixel);
|
||||
else if (_vm->_cjkFont)
|
||||
_vm->_cjkFont->drawChar(dst, chr, vs->pitch, vs->bytesPerPixel, _color, _shadowColor);
|
||||
_vm->_cjkFont->drawChar(vs, chr, _left, drawTop, _color, _shadowColor);
|
||||
} else {
|
||||
dst = (byte *)_vm->_textSurface.getBasePtr(_left * _vm->_textSurfaceMultiplier, _top * _vm->_textSurfaceMultiplier);
|
||||
if (charPtr)
|
||||
drawBits1(_vm->_textSurface, dst, charPtr, drawTop, origWidth, origHeight, _vm->_textSurface.bytesPerPixel, (_vm->_textSurfaceMultiplier == 2 && !is2byte));
|
||||
else if (_vm->_cjkFont)
|
||||
_vm->_cjkFont->drawChar(dst, chr, _vm->_textSurface.pitch, vs->bytesPerPixel, _color, _shadowColor);
|
||||
_vm->_cjkFont->drawChar(_vm->_textSurface, chr, _left * _vm->_textSurfaceMultiplier, _top * _vm->_textSurfaceMultiplier, _color, _shadowColor);
|
||||
if (is2byte)
|
||||
origWidth /= _vm->_textSurfaceMultiplier;
|
||||
}
|
||||
@ -799,17 +799,14 @@ void CharsetRendererV3::printChar(int chr, bool ignoreCharsetMask) {
|
||||
_str.bottom = _top + height / _vm->_textSurfaceMultiplier;
|
||||
}
|
||||
|
||||
void CharsetRendererV3::drawChar(int chr, const Graphics::Surface &s, int x, int y) {
|
||||
void CharsetRendererV3::drawChar(int chr, Graphics::Surface &s, int x, int y) {
|
||||
const byte *charPtr;
|
||||
byte *dst;
|
||||
int width, height;
|
||||
int is2byte = (chr >= 0x80 && _vm->_useCJKMode) ? 1 : 0;
|
||||
if (is2byte) {
|
||||
if (_vm->_game.platform == Common::kPlatformFMTowns) {
|
||||
width = _vm->_cjkFont->getCharWidth(chr);
|
||||
height = _vm->_cjkFont->getFontHeight();
|
||||
dst = (byte *)s.pixels + y * s.pitch + x;
|
||||
_vm->_cjkFont->drawChar(dst, chr, s.pitch, s.bytesPerPixel, _color, _shadowColor);
|
||||
_vm->_cjkFont->drawChar(s, chr, x * _vm->_textSurfaceMultiplier, y * _vm->_textSurfaceMultiplier, _color, _shadowColor);
|
||||
return;
|
||||
} else {
|
||||
charPtr = _vm->get2byteCharPtr(chr);
|
||||
@ -1079,9 +1076,9 @@ void CharsetRendererClassic::printCharIntern(bool is2byte, const byte *charPtr,
|
||||
drawTop = _top - _vm->_screenTop;
|
||||
}
|
||||
|
||||
if (!charPtr && _vm->_cjkFont)
|
||||
_vm->_cjkFont->drawChar(dstPtr, _vm->_cjkChar, dstSurface.pitch, dstSurface.bytesPerPixel, _vm->_townsCharsetColorMap[1], _shadowColor);
|
||||
else if (is2byte) {
|
||||
if (!charPtr && _vm->_cjkFont) {
|
||||
_vm->_cjkFont->drawChar(dstSurface, _vm->_cjkChar, _left * _vm->_textSurfaceMultiplier, (_top - _vm->_screenTop) * _vm->_textSurfaceMultiplier, _vm->_townsCharsetColorMap[1], _shadowColor);
|
||||
} else if (is2byte) {
|
||||
drawBits1(dstSurface, dstPtr, charPtr, drawTop, origWidth, origHeight, dstSurface.bytesPerPixel);
|
||||
} else {
|
||||
drawBitsN(dstSurface, dstPtr, charPtr, *_fontPtr, drawTop, origWidth, origHeight, _vm->_textSurfaceMultiplier == 2);
|
||||
@ -1124,7 +1121,7 @@ void CharsetRendererClassic::printCharIntern(bool is2byte, const byte *charPtr,
|
||||
}
|
||||
}
|
||||
|
||||
void CharsetRendererClassic::drawChar(int chr, const Graphics::Surface &s, int x, int y) {
|
||||
void CharsetRendererClassic::drawChar(int chr, Graphics::Surface &s, int x, int y) {
|
||||
const byte *charPtr;
|
||||
byte *dst;
|
||||
int width, height;
|
||||
@ -1133,10 +1130,7 @@ void CharsetRendererClassic::drawChar(int chr, const Graphics::Surface &s, int x
|
||||
if (is2byte) {
|
||||
enableShadow(true);
|
||||
if (_vm->_game.platform == Common::kPlatformFMTowns) {
|
||||
width = _vm->_cjkFont->getCharWidth(chr);
|
||||
height = _vm->_cjkFont->getFontHeight();
|
||||
dst = (byte *)s.pixels + y * s.pitch + x;
|
||||
_vm->_cjkFont->drawChar(dst, chr, s.pitch, s.bytesPerPixel, _color, _shadowColor);
|
||||
_vm->_cjkFont->drawChar(s, chr, x * _vm->_textSurfaceMultiplier, y * _vm->_textSurfaceMultiplier, _color, _shadowColor);
|
||||
return;
|
||||
} else {
|
||||
charPtr = _vm->get2byteCharPtr(chr);
|
||||
@ -1525,7 +1519,7 @@ void CharsetRendererNES::printChar(int chr, bool ignoreCharsetMask) {
|
||||
_str.bottom = _top + height;
|
||||
}
|
||||
|
||||
void CharsetRendererNES::drawChar(int chr, const Graphics::Surface &s, int x, int y) {
|
||||
void CharsetRendererNES::drawChar(int chr, Graphics::Surface &s, int x, int y) {
|
||||
byte *charPtr, *dst;
|
||||
int width, height;
|
||||
|
||||
|
@ -75,7 +75,7 @@ public:
|
||||
virtual ~CharsetRenderer();
|
||||
|
||||
virtual void printChar(int chr, bool ignoreCharsetMask) = 0;
|
||||
virtual void drawChar(int chr, const Graphics::Surface &s, int x, int y) {}
|
||||
virtual void drawChar(int chr, Graphics::Surface &s, int x, int y) {}
|
||||
|
||||
int getStringWidth(int a, const byte *str);
|
||||
void addLinebreaks(int a, byte *str, int pos, int maxwidth);
|
||||
@ -134,7 +134,7 @@ public:
|
||||
CharsetRendererClassic(ScummEngine *vm) : CharsetRendererCommon(vm) {}
|
||||
|
||||
void printChar(int chr, bool ignoreCharsetMask);
|
||||
void drawChar(int chr, const Graphics::Surface &s, int x, int y);
|
||||
void drawChar(int chr, Graphics::Surface &s, int x, int y);
|
||||
|
||||
int getCharWidth(uint16 chr);
|
||||
|
||||
@ -155,7 +155,7 @@ public:
|
||||
|
||||
void setCurID(int32 id) {}
|
||||
void printChar(int chr, bool ignoreCharsetMask);
|
||||
void drawChar(int chr, const Graphics::Surface &s, int x, int y);
|
||||
void drawChar(int chr, Graphics::Surface &s, int x, int y);
|
||||
|
||||
int getFontHeight() { return 8; }
|
||||
int getCharWidth(uint16 chr) { return 8; }
|
||||
@ -169,7 +169,7 @@ public:
|
||||
CharsetRendererV3(ScummEngine *vm) : CharsetRendererCommon(vm) {}
|
||||
|
||||
void printChar(int chr, bool ignoreCharsetMask);
|
||||
void drawChar(int chr, const Graphics::Surface &s, int x, int y);
|
||||
void drawChar(int chr, Graphics::Surface &s, int x, int y);
|
||||
void setCurID(int32 id);
|
||||
void setColor(byte color);
|
||||
int getCharWidth(uint16 chr);
|
||||
|
@ -1025,7 +1025,7 @@ void ScummEngine::restoreBackground(Common::Rect rect, byte backColor) {
|
||||
|
||||
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
|
||||
if (_game.platform == Common::kPlatformFMTowns && _game.id == GID_MONKEY && vs->number == kVerbVirtScreen && rect.bottom <= 154)
|
||||
rect.right = 320;
|
||||
rect.right = 319;
|
||||
#endif
|
||||
|
||||
markRectAsDirty(vs->number, rect, USAGE_BIT_RESTORED);
|
||||
|
@ -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<uint8>(outline, width + 2, height + 2, (uint8 *)dst, pitch, c2);
|
||||
blitCharacter<uint8>(glyphSource, width, height, (uint8 *)dst + pitch + 1, pitch, c1);
|
||||
blitCharacter<uint8>(outline, width + outlineExtraWidth, height + outlineExtraHeight, (uint8 *)dst, pitch, c2);
|
||||
blitCharacter<uint8>(glyphSource, width - outlineXOffset, height - outlineYOffset, (uint8 *)dst + pitch + 1, pitch, c1);
|
||||
} else {
|
||||
blitCharacter<uint8>(glyphSource, width, height, (uint8 *)dst, pitch, c1, c2);
|
||||
}
|
||||
} else if (bpp == 2) {
|
||||
if (_drawMode == kOutlineMode) {
|
||||
blitCharacter<uint16>(outline, width + 2, height + 2, (uint8 *)dst, pitch, c2);
|
||||
blitCharacter<uint16>(glyphSource, width, height, (uint8 *)dst + pitch + 2, pitch, c1);
|
||||
blitCharacter<uint16>(outline, width + outlineExtraWidth, height + outlineExtraHeight, (uint8 *)dst, pitch, c2);
|
||||
blitCharacter<uint16>(glyphSource, width - outlineXOffset, height - outlineYOffset, (uint8 *)dst + pitch + 2, pitch, c1);
|
||||
} else {
|
||||
blitCharacter<uint16>(glyphSource, width, height, (uint8 *)dst, pitch, c1, c2);
|
||||
}
|
||||
|
@ -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<typename Color>
|
||||
void blitCharacter(const uint8 *glyph, const int w, const int h, uint8 *dst, int pitch, Color c1, Color c2 = 0) const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user