From e7f6ccbecec6a20fe2969b962bc73e4aee725249 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 29 Aug 2016 19:28:58 -0400 Subject: TITANIC: Implement variant font writing used by credits --- engines/titanic/support/font.cpp | 61 ++++++++++++++++++++++++++++++ engines/titanic/support/font.h | 6 +++ engines/titanic/support/screen_manager.cpp | 20 +++++++++- engines/titanic/support/screen_manager.h | 4 +- 4 files changed, 87 insertions(+), 4 deletions(-) (limited to 'engines/titanic') diff --git a/engines/titanic/support/font.cpp b/engines/titanic/support/font.cpp index 69c0efe504..6501bdca54 100644 --- a/engines/titanic/support/font.cpp +++ b/engines/titanic/support/font.cpp @@ -179,6 +179,67 @@ int STFont::writeString(CVideoSurface *surface, const Rect &rect1, const Rect &d return endP ? endP - str.c_str() : 0; } +void STFont::writeString(CVideoSurface *surface, const Point &destPos, Rect &clipRect, + const CString &str, int lineWidth) { + if (!_fontHeight || !_dataPtr || str.empty()) + return; + if (!lineWidth) + // No line width specified, so get in the width + lineWidth = stringWidth(str); + + Rect textRect(0, 0, lineWidth, _fontHeight); + Point textPt = destPos; + + // Perform clipping as necessary if the text will fall outside clipping area + if (textPt.y > clipRect.bottom) + return; + + if ((textPt.y + textRect.height()) > clipRect.bottom) + textRect.bottom = textRect.top - textPt.y + clipRect.bottom; + + if (textPt.y < clipRect.top) { + if ((textPt.y + textRect.height()) < clipRect.top) + return; + + textRect.top += clipRect.top - textPt.y; + textPt.y = clipRect.top; + } + + // Iterate through each character of the string + for (const byte *srcP = (byte *)str.c_str(); *srcP; ++srcP) { + byte c = *srcP; + if (c == 0xE9) + c = '$'; + + // Form a rect of the area of the next character to draw + Rect charRect(_chars[c]._offset, textRect.top, + _chars[c]._offset + _chars[c]._width, textRect.bottom); + + if (textPt.x < clipRect.left) { + // Character is either partially or entirely left off-screen + if ((textPt.x + charRect.width()) < clipRect.left) { + textPt.x += _chars[c]._width; + continue; + } + + // Partially clipped on left-hand side + charRect.left = clipRect.left - textPt.x; + textPt.x = clipRect.left; + } else if ((textPt.x + charRect.width()) > clipRect.right) { + if (textPt.x > clipRect.right) + // Now entirely off right-hand side, so stop drawing + break; + + // Partially clipped on right-hand side + charRect.right += clipRect.right - textPt.x - charRect.width(); + } + + // At this point, we know we've got to draw at least part of a character, + // and have figured out the area of the character to draw + copyRect(surface, textPt, charRect); + } +} + WriteCharacterResult STFont::writeChar(CVideoSurface *surface, unsigned char c, const Point &pt, const Rect &destRect, const Rect *srcRect) { if (c == 233) diff --git a/engines/titanic/support/font.h b/engines/titanic/support/font.h index 591fb4661c..6c4fe8e9c3 100644 --- a/engines/titanic/support/font.h +++ b/engines/titanic/support/font.h @@ -98,6 +98,12 @@ public: int writeString(CVideoSurface *surface, const Rect &rect1, const Rect &destRect, int yOffset, const CString &str, CTextCursor *textCursor); + /** + * Write a string to the specified surface + */ + void writeString(CVideoSurface *surface, const Point &destPos, Rect &clipRect, + const CString &str, int lineWidth = 0); + /** * Get the text area a string will fit into * @param str String diff --git a/engines/titanic/support/screen_manager.cpp b/engines/titanic/support/screen_manager.cpp index aa72200056..bcf43fc8cb 100644 --- a/engines/titanic/support/screen_manager.cpp +++ b/engines/titanic/support/screen_manager.cpp @@ -240,8 +240,24 @@ int OSScreenManager::writeString(int surfaceNum, const Rect &destRect, } void OSScreenManager::writeString(int surfaceNum, const Point &destPos, - const Rect &clipRect, const CString &str, int maxWidth) { - // TODO + const Rect &clipRect, const CString &str, int lineWidth) { + CVideoSurface *surface; + Rect bounds; + + if (surfaceNum >= 0 && surfaceNum < (int)_backSurfaces.size()) { + surface = _backSurfaces[surfaceNum]._surface; + bounds = _backSurfaces[surfaceNum]._bounds; + } else if (surfaceNum == -1) { + surface = _frontRenderSurface; + bounds = Rect(0, 0, surface->getWidth(), surface->getHeight()); + } else { + return; + } + + Rect destRect = clipRect; + destRect.constrain(bounds); + + _fonts[_fontNumber].writeString(surface, destPos, destRect, str, lineWidth); } void OSScreenManager::setFontColor(byte r, byte g, byte b) { diff --git a/engines/titanic/support/screen_manager.h b/engines/titanic/support/screen_manager.h index a47b6a174b..cad6901b02 100644 --- a/engines/titanic/support/screen_manager.h +++ b/engines/titanic/support/screen_manager.h @@ -325,10 +325,10 @@ public: * @param destPos Position to start writing text at * @param clipRect Clipping area to constrain text to * @param str Line or lines to write - * @param maxWidth Maximum allowed line width + * @param lineWidth Width in pixels of the string, if known. */ virtual void writeString(int surfaceNum, const Point &destPos, - const Rect &clipRect, const CString &str, int maxWidth); + const Rect &clipRect, const CString &str, int lineWidth = 0); /** * Set the font color -- cgit v1.2.3