diff options
author | Filippos Karapetis | 2011-10-08 17:16:58 +0300 |
---|---|---|
committer | Filippos Karapetis | 2011-10-08 17:19:00 +0300 |
commit | 4ad2ebd9959a8413c0d00cd7498ac4166edfe886 (patch) | |
tree | a663c3cae3cdecd205b38c950cb888a3b24e6db5 /engines/sci/graphics | |
parent | 2ffdd0d3b7d06d072c11db06cb4017d9948b205b (diff) | |
download | scummvm-rg350-4ad2ebd9959a8413c0d00cd7498ac4166edfe886.tar.gz scummvm-rg350-4ad2ebd9959a8413c0d00cd7498ac4166edfe886.tar.bz2 scummvm-rg350-4ad2ebd9959a8413c0d00cd7498ac4166edfe886.zip |
SCI2+: Some groundwork for kTextSize()
The old behavior is currently hacked in inside kernelTextSize(), as the
top of the subtitles frame is wrong if kTextWidth() is properly working...
Diffstat (limited to 'engines/sci/graphics')
-rw-r--r-- | engines/sci/graphics/frameout.cpp | 10 | ||||
-rw-r--r-- | engines/sci/graphics/text32.cpp | 94 | ||||
-rw-r--r-- | engines/sci/graphics/text32.h | 7 |
3 files changed, 97 insertions, 14 deletions
diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp index fcd22de7e1..e4d921a129 100644 --- a/engines/sci/graphics/frameout.cpp +++ b/engines/sci/graphics/frameout.cpp @@ -554,21 +554,13 @@ void GfxFrameout::kernelFrameout() { TextEntry *textEntry = g_sci->_gfxText32->getTextEntry(itemEntry->object); uint16 startX = ((textEntry->x * _screen->getWidth()) / scriptsRunningWidth) + it->planeRect.left; uint16 startY = ((textEntry->y * _screen->getHeight()) / scriptsRunningHeight) + it->planeRect.top; - // HACK. The plane sometimes doesn't contain the correct width. This - // hack breaks the dialog options when speaking with Grace, but it's - // the best we got up to now. This happens because of the unimplemented - // kTextWidth function in SCI32. - // TODO: Remove this once kTextWidth has been implemented. - uint16 w = it->planeRect.width() >= 20 ? it->planeRect.width() : _screen->getWidth() - 10; - // Upscale the coordinates/width if the fonts are already upscaled if (_screen->fontIsUpscaled()) { startX = startX * _screen->getDisplayWidth() / _screen->getWidth(); startY = startY * _screen->getDisplayHeight() / _screen->getHeight(); - w = w * _screen->getDisplayWidth() / _screen->getWidth(); } - g_sci->_gfxText32->drawTextBitmap(itemEntry->object, startX, startY, w); + g_sci->_gfxText32->drawTextBitmap(itemEntry->object, startX, startY, it->planeRect.width()); } } } diff --git a/engines/sci/graphics/text32.cpp b/engines/sci/graphics/text32.cpp index 21372f1502..f13a56fa17 100644 --- a/engines/sci/graphics/text32.cpp +++ b/engines/sci/graphics/text32.cpp @@ -74,7 +74,7 @@ void GfxText32::createTextBitmap(reg_t textObject) { } // TODO: Finish this! -void GfxText32::drawTextBitmap(reg_t textObject, uint16 textX, uint16 textY, uint16 w) { +void GfxText32::drawTextBitmap(reg_t textObject, uint16 textX, uint16 textY, uint16 planeWidth) { uint32 textId = (textObject.segment << 16) | textObject.offset; if (!_textCache.contains(textId)) @@ -90,11 +90,19 @@ void GfxText32::drawTextBitmap(reg_t textObject, uint16 textX, uint16 textY, uin const char *txt = entry->text.c_str(); int16 charCount; + uint16 maxWidth = (planeWidth > 0) ? planeWidth : _screen->getWidth() - textX; while (*txt) { - charCount = GetLongest(txt, w, font); - if (charCount == 0) - break; + charCount = GetLongest(txt, maxWidth, font); + if (charCount == 0) { + // If the text does not fit inside the given plane, use the + // whole screen. + // TODO/FIXME: Is this really needed? Perhaps some other + // functionality is missing instead? + charCount = GetLongest(txt, _screen->getWidth() - textX, font); + if (charCount == 0) + break; + } uint16 curX = textX; @@ -235,4 +243,82 @@ int16 GfxText32::GetLongest(const char *text, int16 maxWidth, GfxFont *font) { return maxChars; } +void GfxText32::kernelTextSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight) { + Common::Rect rect(0, 0, 0, 0); + Size(rect, text, font, maxWidth); + *textWidth = rect.width(); + *textHeight = rect.height(); + + // TODO: Setting textWidth properly changes the subtitle plane top to 0. + // I have no idea why, so we currently hack in the old behavior here. + *textWidth = 0; + *textHeight = 0; +} + +void GfxText32::StringWidth(const char *str, GuiResourceId fontId, int16 &textWidth, int16 &textHeight) { + Width(str, 0, (int16)strlen(str), fontId, textWidth, textHeight, true); +} + +void GfxText32::Width(const char *text, int16 from, int16 len, GuiResourceId fontId, int16 &textWidth, int16 &textHeight, bool restoreFont) { + uint16 curChar; + textWidth = 0; textHeight = 0; + + GfxFont *font = _cache->getFont(fontId); + + if (font) { + text += from; + while (len--) { + curChar = (*(const byte *)text++); + switch (curChar) { + case 0x0A: + case 0x0D: + case 0x9781: // this one is used by SQ4/japanese as line break as well + textHeight = MAX<int16> (textHeight, font->getHeight()); + break; + case 0x7C: + warning("Code processing isn't implemented in SCI32"); + break; + default: + textHeight = MAX<int16> (textHeight, font->getHeight()); + textWidth += font->getCharWidth(curChar); + break; + } + } + } +} + +int16 GfxText32::Size(Common::Rect &rect, const char *text, GuiResourceId fontId, int16 maxWidth) { + int16 charCount; + int16 maxTextWidth = 0, textWidth; + int16 totalHeight = 0, textHeight; + + rect.top = rect.left = 0; + GfxFont *font = _cache->getFont(fontId); + + if (maxWidth < 0) { // force output as single line + StringWidth(text, fontId, textWidth, textHeight); + rect.bottom = textHeight; + rect.right = textWidth; + } else { + // rect.right=found widest line with RTextWidth and GetLongest + // rect.bottom=num. lines * GetPointSize + rect.right = (maxWidth ? maxWidth : 192); + const char *curPos = text; + while (*curPos) { + charCount = GetLongest(curPos, rect.right, font); + if (charCount == 0) + break; + Width(curPos, 0, charCount, fontId, textWidth, textHeight, false); + maxTextWidth = MAX(textWidth, maxTextWidth); + totalHeight += textHeight; + curPos += charCount; + while (*curPos == ' ') + curPos++; // skip over breaking spaces + } + rect.bottom = totalHeight; + rect.right = maxWidth ? maxWidth : MIN(rect.right, maxTextWidth); + } + return rect.right; +} + } // End of namespace Sci diff --git a/engines/sci/graphics/text32.h b/engines/sci/graphics/text32.h index 39fe710a86..7f70afc880 100644 --- a/engines/sci/graphics/text32.h +++ b/engines/sci/graphics/text32.h @@ -52,12 +52,17 @@ public: GfxText32(SegManager *segMan, GfxCache *fonts, GfxScreen *screen); ~GfxText32(); void createTextBitmap(reg_t textObject); - void drawTextBitmap(reg_t textObject, uint16 textX, uint16 textY, uint16 w); + void drawTextBitmap(reg_t textObject, uint16 textX, uint16 textY, uint16 planeWidth); int16 GetLongest(const char *text, int16 maxWidth, GfxFont *font); TextEntry *getTextEntry(reg_t textObject); + void kernelTextSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight); + private: TextEntry *createTextEntry(reg_t textObject); + int16 Size(Common::Rect &rect, const char *text, GuiResourceId fontId, int16 maxWidth); + void Width(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight, bool restoreFont); + void StringWidth(const char *str, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight); void purgeCache(); SegManager *_segMan; |