[Scummvm-cvs-logs] scummvm master -> 4ad2ebd9959a8413c0d00cd7498ac4166edfe886

bluegr md5 at scummvm.org
Sat Oct 8 16:28:09 CEST 2011


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
4ad2ebd995 SCI2+: Some groundwork for kTextSize()


Commit: 4ad2ebd9959a8413c0d00cd7498ac4166edfe886
    https://github.com/scummvm/scummvm/commit/4ad2ebd9959a8413c0d00cd7498ac4166edfe886
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-10-08T07:19:00-07:00

Commit Message:
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...

Changed paths:
    engines/sci/engine/kgraphics.cpp
    engines/sci/graphics/frameout.cpp
    engines/sci/graphics/text32.cpp
    engines/sci/graphics/text32.h



diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index 2bf3f25..83eb941 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -354,11 +354,9 @@ reg_t kTextSize(EngineState *s, int argc, reg_t *argv) {
 	textWidth = dest[3].toUint16(); textHeight = dest[2].toUint16();
 
 #ifdef ENABLE_SCI32
-	if (!g_sci->_gfxText16) {
-		// TODO: Implement this
-		textWidth = 0; textHeight = 0;
-		warning("TODO: implement kTextSize for SCI32");
-	} else
+	if (g_sci->_gfxText32)
+		g_sci->_gfxText32->kernelTextSize(g_sci->strSplit(text.c_str(), sep).c_str(), font_nr, maxwidth, &textWidth, &textHeight);
+	else
 #endif
 		g_sci->_gfxText16->kernelTextSize(g_sci->strSplit(text.c_str(), sep).c_str(), font_nr, maxwidth, &textWidth, &textHeight);
 
diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp
index fcd22de..e4d921a 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 21372f1..f13a56f 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 39fe710..7f70afc 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;






More information about the Scummvm-git-logs mailing list