From 887a99e211c25fd16e4cf3b7505ae17678c2f997 Mon Sep 17 00:00:00 2001 From: Narek Mailian Date: Thu, 13 Jun 2013 12:32:36 +0000 Subject: GRAPHICS: Added changes and improved code from inisider/scummvm (partial text) Includes code from https://github.com/inisider/scummvm/ , which has been squashed and bugfixed --- graphics/VectorRenderer.h | 2 +- graphics/VectorRendererSpec.cpp | 86 ++++++++++++++++++++++++++++++++++++----- graphics/VectorRendererSpec.h | 2 +- graphics/font.cpp | 2 +- gui/ThemeEngine.cpp | 17 ++++---- gui/ThemeEngine.h | 9 ++--- gui/about.cpp | 7 ++-- gui/object.cpp | 2 +- gui/object.h | 7 +++- gui/widgets/editable.cpp | 2 +- gui/widgets/edittext.cpp | 8 +++- 11 files changed, 109 insertions(+), 35 deletions(-) diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h index 5d6369c08f..4ca76224e1 100644 --- a/graphics/VectorRenderer.h +++ b/graphics/VectorRenderer.h @@ -466,7 +466,7 @@ public: */ virtual void drawString(const Graphics::Font *font, const Common::String &text, const Common::Rect &area, Graphics::TextAlign alignH, - GUI::ThemeEngine::TextAlignVertical alignV, int deltax, bool useEllipsis) = 0; + GUI::ThemeEngine::TextAlignVertical alignV, int deltax, bool useEllipsis, const Common::Rect &textDrawableArea) = 0; /** * Allows to temporarily enable/disable all shadows drawing. diff --git a/graphics/VectorRendererSpec.cpp b/graphics/VectorRendererSpec.cpp index e4843ba78b..f9041fc8ff 100644 --- a/graphics/VectorRendererSpec.cpp +++ b/graphics/VectorRendererSpec.cpp @@ -646,24 +646,90 @@ darkenFill(PixelType *ptr, PixelType *end) { template void VectorRendererSpec:: drawString(const Graphics::Font *font, const Common::String &text, const Common::Rect &area, - Graphics::TextAlign alignH, GUI::ThemeEngine::TextAlignVertical alignV, int deltax, bool ellipsis) { + Graphics::TextAlign alignH, GUI::ThemeEngine::TextAlignVertical alignV, int deltax, bool ellipsis, const Common::Rect &textDrawableArea) { int offset = area.top; if (font->getFontHeight() < area.height()) { switch (alignV) { - case GUI::ThemeEngine::kTextAlignVCenter: - offset = area.top + ((area.height() - font->getFontHeight()) >> 1); - break; - case GUI::ThemeEngine::kTextAlignVBottom: - offset = area.bottom - font->getFontHeight(); - break; - default: - break; + case GUI::ThemeEngine::kTextAlignVCenter: + offset = area.top + ((area.height() - font->getFontHeight()) >> 1); + break; + case GUI::ThemeEngine::kTextAlignVBottom: + offset = area.bottom - font->getFontHeight(); + break; + default: + break; } } - font->drawString(_activeSurface, text, area.left, offset, area.width() - deltax, _fgColor, alignH, deltax, ellipsis); + if (textDrawableArea.isEmpty()) { + font->drawString(_activeSurface, text, area.left, offset, area.width() - deltax, _fgColor, alignH, deltax, ellipsis); + // warning("there is no text drawable area. Please set this area for clipping"); + return; + } + + int textWidth = font->getStringWidth(text); + + int emptySpace = 0; + + switch (alignH) { + case Graphics::kTextAlignLeft: + // Let emptyspace = 0 + break; + case Graphics::kTextAlignCenter: + emptySpace = (area.width() - textWidth) / 2; + break; + case Graphics::kTextAlignRight: + emptySpace = area.right - textWidth; + break; + case Graphics::kTextAlignInvalid: + // warning("VectorRendererSpec::drawString(...) invalid text align"); + // return; + default: + break; + } + + // if text drawable area don't have any text for clipping + if ((textDrawableArea.right < (area.left + emptySpace)) || (textDrawableArea.left > (area.right - emptySpace))) + return; + + Surface backSurface; + backSurface.create(area.width(), font->getFontHeight() + 4, _activeSurface->format); + + byte *activeSurfacePtr = (byte *)_activeSurface->getBasePtr(area.left, area.top); + byte *backSurfacePtr = (byte *)backSurface.getBasePtr(0, 0); + + // copy background... + for (int i = 0; i < backSurface.h; i++) { + memcpy(backSurfacePtr, activeSurfacePtr, backSurface.w * backSurface.format.bytesPerPixel); + + activeSurfacePtr += _activeSurface->pitch; + backSurfacePtr += backSurface.pitch; + } + + font->drawString(&backSurface, text, 0, 0, area.width() - deltax, _fgColor, alignH, deltax, ellipsis); + + int fromX = ((area.left + emptySpace) < textDrawableArea.left) ? textDrawableArea.left : area.left + emptySpace; + int toX = ((area.right - emptySpace) > textDrawableArea.right) ? textDrawableArea.right : area.right - emptySpace; + + int bytesX = toX - fromX; + + int fromY = (area.top < textDrawableArea.top) ? textDrawableArea.top : area.top; + int toY = (textDrawableArea.bottom < area.bottom) ? textDrawableArea.bottom : area.bottom; + + // copy text from backSurface to activeSurface + activeSurfacePtr = (byte *)_activeSurface->getBasePtr(fromX, fromY); + backSurfacePtr = (byte *)backSurface.getBasePtr(fromX - area.left, fromY - area.top); + + for (int i = fromY; i < toY; i++) { + memcpy(activeSurfacePtr, backSurfacePtr, bytesX * backSurface.format.bytesPerPixel); + + activeSurfacePtr += _activeSurface->pitch; + backSurfacePtr += backSurface.pitch; + } + + backSurface.free(); } /** LINES **/ diff --git a/graphics/VectorRendererSpec.h b/graphics/VectorRendererSpec.h index 4ed80cb55f..08d00dd569 100644 --- a/graphics/VectorRendererSpec.h +++ b/graphics/VectorRendererSpec.h @@ -61,7 +61,7 @@ public: } void drawString(const Graphics::Font *font, const Common::String &text, const Common::Rect &area, Graphics::TextAlign alignH, - GUI::ThemeEngine::TextAlignVertical alignV, int deltax, bool elipsis); + GUI::ThemeEngine::TextAlignVertical alignV, int deltax, bool elipsis, const Common::Rect &textDrawableArea = Common::Rect(0, 0, 0, 0)); void setFgColor(uint8 r, uint8 g, uint8 b) { _fgColor = _format.RGBToColor(r, g, b); } void setBgColor(uint8 r, uint8 g, uint8 b) { _bgColor = _format.RGBToColor(r, g, b); } diff --git a/graphics/font.cpp b/graphics/font.cpp index 3b00cd8568..a852274b06 100644 --- a/graphics/font.cpp +++ b/graphics/font.cpp @@ -128,7 +128,7 @@ void Font::drawString(Surface *dst, const Common::String &sOld, int x, int y, in w = getCharWidth(cur); if (x+w > rightX) break; - if (x >= leftX) + if (x+w >= leftX) drawChar(dst, str[i], x, y, color); x += w; } diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index 561c0244a2..a6e61e8f41 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -122,15 +122,16 @@ protected: class ThemeItemTextData : public ThemeItem { public: - ThemeItemTextData(ThemeEngine *engine, const TextDrawData *data, const TextColorData *color, const Common::Rect &area, const Common::String &text, - Graphics::TextAlign alignH, GUI::ThemeEngine::TextAlignVertical alignV, + ThemeItemTextData(ThemeEngine *engine, const TextDrawData *data, const TextColorData *color, const Common::Rect &area, const Common::Rect &textDrawableArea, + const Common::String &text, Graphics::TextAlign alignH, GUI::ThemeEngine::TextAlignVertical alignV, bool ellipsis, bool restoreBg, int deltaX) : ThemeItem(engine, area), _data(data), _color(color), _text(text), _alignH(alignH), _alignV(alignV), - _ellipsis(ellipsis), _restoreBg(restoreBg), _deltax(deltaX) {} + _ellipsis(ellipsis), _restoreBg(restoreBg), _deltax(deltaX), _textDrawableArea(textDrawableArea) {} void drawSelf(bool draw, bool restore); protected: + Common::Rect _textDrawableArea; const TextDrawData *_data; const TextColorData *_color; Common::String _text; @@ -246,7 +247,7 @@ void ThemeItemTextData::drawSelf(bool draw, bool restore) { if (draw) { _engine->renderer()->setFgColor(_color->r, _color->g, _color->b); - _engine->renderer()->drawString(_data->_fontPtr, _text, _area, _alignH, _alignV, _deltax, _ellipsis); + _engine->renderer()->drawString(_data->_fontPtr, _text, _area, _alignH, _alignV, _deltax, _ellipsis, _textDrawableArea); } _engine->addDirtyRect(_area); @@ -836,7 +837,7 @@ void ThemeEngine::queueDD(DrawData type, const Common::Rect &r, uint32 dynamic, } void ThemeEngine::queueDDText(TextData type, TextColor color, const Common::Rect &r, const Common::String &text, bool restoreBg, - bool ellipsis, Graphics::TextAlign alignH, TextAlignVertical alignV, int deltax) { + bool ellipsis, Graphics::TextAlign alignH, TextAlignVertical alignV, int deltax, const Common::Rect &drawableTextArea) { if (_texts[type] == 0) return; @@ -844,7 +845,7 @@ void ThemeEngine::queueDDText(TextData type, TextColor color, const Common::Rect Common::Rect area = r; area.clip(_screen.w, _screen.h); - ThemeItemTextData *q = new ThemeItemTextData(this, _texts[type], _textColors[color], area, text, alignH, alignV, ellipsis, restoreBg, deltax); + ThemeItemTextData *q = new ThemeItemTextData(this, _texts[type], _textColors[color], area, drawableTextArea, text, alignH, alignV, ellipsis, restoreBg, deltax); if (_buffering) { _screenQueue.push_back(q); @@ -1115,7 +1116,7 @@ void ThemeEngine::drawTab(const Common::Rect &r, int tabHeight, int tabWidth, co } } -void ThemeEngine::drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state, Graphics::TextAlign align, TextInversionState inverted, int deltax, bool useEllipsis, FontStyle font, FontColor color, bool restore) { +void ThemeEngine::drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state, Graphics::TextAlign align, TextInversionState inverted, int deltax, bool useEllipsis, FontStyle font, FontColor color, bool restore, const Common::Rect &drawableTextArea) { if (!ready()) return; @@ -1185,7 +1186,7 @@ void ThemeEngine::drawText(const Common::Rect &r, const Common::String &str, Wid break; } - queueDDText(textId, colorId, r, str, restore, useEllipsis, align, kTextAlignVCenter, deltax); + queueDDText(textId, colorId, r, str, restore, useEllipsis, align, kTextAlignVCenter, deltax, drawableTextArea); } void ThemeEngine::drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, WidgetStateInfo state, FontColor color) { diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h index c0e47a19e6..4dffb13e71 100644 --- a/gui/ThemeEngine.h +++ b/gui/ThemeEngine.h @@ -29,6 +29,7 @@ #include "common/hashmap.h" #include "common/list.h" #include "common/str.h" +#include "common/rect.h" #include "graphics/surface.h" #include "graphics/font.h" @@ -39,10 +40,6 @@ class OSystem; -namespace Common { -struct Rect; -} - namespace Graphics { struct DrawStep; class VectorRenderer; @@ -376,7 +373,7 @@ public: void drawDialogBackground(const Common::Rect &r, DialogBackground type, WidgetStateInfo state = kStateEnabled); - void drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state = kStateEnabled, Graphics::TextAlign align = Graphics::kTextAlignCenter, TextInversionState inverted = kTextInversionNone, int deltax = 0, bool useEllipsis = true, FontStyle font = kFontStyleBold, FontColor color = kFontColorNormal, bool restore = true); + void drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state = kStateEnabled, Graphics::TextAlign align = Graphics::kTextAlignCenter, TextInversionState inverted = kTextInversionNone, int deltax = 0, bool useEllipsis = true, FontStyle font = kFontStyleBold, FontColor color = kFontColorNormal, bool restore = true, const Common::Rect &drawableTextArea = Common::Rect(0, 0, 0, 0)); void drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, WidgetStateInfo state = kStateEnabled, FontColor color = kFontColorNormal); @@ -588,7 +585,7 @@ protected: */ void queueDD(DrawData type, const Common::Rect &r, uint32 dynamic = 0, bool restore = false); void queueDDText(TextData type, TextColor color, const Common::Rect &r, const Common::String &text, bool restoreBg, - bool elipsis, Graphics::TextAlign alignH = Graphics::kTextAlignLeft, TextAlignVertical alignV = kTextAlignVTop, int deltax = 0); + bool elipsis, Graphics::TextAlign alignH = Graphics::kTextAlignLeft, TextAlignVertical alignV = kTextAlignVTop, int deltax = 0, const Common::Rect &drawableTextArea = Common::Rect(0, 0, 0, 0)); void queueBitmap(const Graphics::Surface *bitmap, const Common::Rect &r, bool alpha); /** diff --git a/gui/about.cpp b/gui/about.cpp index 20145886c6..3bb1934e28 100644 --- a/gui/about.cpp +++ b/gui/about.cpp @@ -180,9 +180,10 @@ void AboutDialog::close() { } void AboutDialog::drawDialog() { -// g_gui.theme()->setDrawArea(Common::Rect(_x, _y, _x+_w, _y+_h)); Dialog::drawDialog(); + setTextDrawableArea(Common::Rect(_x, _y, _x + _w, _y + _h)); + // Draw text // TODO: Add a "fade" effect for the top/bottom text lines // TODO: Maybe prerender all of the text into another surface, @@ -239,8 +240,8 @@ void AboutDialog::drawDialog() { while (*str && *str == ' ') str++; - if (*str && y > _y && y + g_gui.theme()->getFontHeight() < _y + _h) - g_gui.theme()->drawText(Common::Rect(_x + _xOff, y, _x + _w - _xOff, y + g_gui.theme()->getFontHeight()), str, state, align, ThemeEngine::kTextInversionNone, 0, false); + if (*str) + g_gui.theme()->drawText(Common::Rect(_x + _xOff, y, _x + _w - _xOff, y + g_gui.theme()->getFontHeight()), str, state, align, ThemeEngine::kTextInversionNone, 0, false, ThemeEngine::kFontStyleBold, ThemeEngine::kFontColorNormal, true, _textDrawableArea); y += _lineHeight; } } diff --git a/gui/object.cpp b/gui/object.cpp index 73c4f74d6c..189a286ead 100644 --- a/gui/object.cpp +++ b/gui/object.cpp @@ -29,7 +29,7 @@ namespace GUI { GuiObject::GuiObject(const Common::String &name) - : _x(-1000), _y(-1000), _w(0), _h(0), _name(name), _firstWidget(0) { + : _x(-1000), _y(-1000), _w(0), _h(0), _name(name), _firstWidget(0), _textDrawableArea(Common::Rect(0, 0, 0, 0)) { reflowLayout(); } diff --git a/gui/object.h b/gui/object.h index bce3cd7846..dac3341b5a 100644 --- a/gui/object.h +++ b/gui/object.h @@ -24,6 +24,7 @@ #include "common/scummsys.h" #include "common/str.h" +#include "common/rect.h" namespace GUI { @@ -59,6 +60,8 @@ class Widget; class GuiObject : public CommandReceiver { friend class Widget; protected: + Common::Rect _textDrawableArea; + int16 _x, _y; uint16 _w, _h; const Common::String _name; @@ -66,10 +69,12 @@ protected: Widget *_firstWidget; public: - GuiObject(int x, int y, int w, int h) : _x(x), _y(y), _w(w), _h(h), _firstWidget(0) { } + GuiObject(int x, int y, int w, int h) : _x(x), _y(y), _w(w), _h(h), _firstWidget(0), _textDrawableArea(Common::Rect(0, 0, 0, 0)) { } GuiObject(const Common::String &name); ~GuiObject(); + virtual void setTextDrawableArea(const Common::Rect &r) { _textDrawableArea = r; } + virtual int16 getAbsX() const { return _x; } virtual int16 getAbsY() const { return _y; } virtual int16 getChildX() const { return getAbsX(); } diff --git a/gui/widgets/editable.cpp b/gui/widgets/editable.cpp index 6fae9346b2..667850d6cc 100644 --- a/gui/widgets/editable.cpp +++ b/gui/widgets/editable.cpp @@ -277,7 +277,7 @@ void EditableWidget::drawCaret(bool erase) { int chrWidth = g_gui.getCharWidth(_editString[_caretPos], _font); const uint last = (_caretPos > 0) ? _editString[_caretPos - 1] : 0; x += g_gui.getKerningOffset(last, _editString[_caretPos], _font); - g_gui.theme()->drawText(Common::Rect(x, y, x + chrWidth, y + editRect.height() - 2), chr, _state, Graphics::kTextAlignLeft, _inversion, 0, false, _font); + g_gui.theme()->drawText(Common::Rect(x, y, x + chrWidth, y + editRect.height() - 2), chr, _state, Graphics::kTextAlignLeft, _inversion, 0, false, _font, ThemeEngine::kFontColorNormal, true, _textDrawableArea); } } diff --git a/gui/widgets/edittext.cpp b/gui/widgets/edittext.cpp index 3677f02e47..52527effd8 100644 --- a/gui/widgets/edittext.cpp +++ b/gui/widgets/edittext.cpp @@ -93,11 +93,15 @@ void EditTextWidget::drawWidget() { // Draw the text adjustOffset(); - g_gui.theme()->drawText(Common::Rect(_x+2+ _leftPadding,_y+2, _x+_leftPadding+getEditRect().width()+2, _y+_h-2), _editString, _state, Graphics::kTextAlignLeft, ThemeEngine::kTextInversionNone, -_editScrollOffset, false, _font); + + const Common::Rect &r = Common::Rect(_x + 2 + _leftPadding, _y + 2, _x + _leftPadding + getEditRect().width() + 8, _y + _h); + setTextDrawableArea(r); + + g_gui.theme()->drawText(Common::Rect(_x + 2 + _leftPadding, _y + 2, _x + _leftPadding + getEditRect().width() + 2, _y + _h), _editString, _state, Graphics::kTextAlignLeft, ThemeEngine::kTextInversionNone, -_editScrollOffset, false, _font, ThemeEngine::kFontColorNormal, true, _textDrawableArea); } Common::Rect EditTextWidget::getEditRect() const { - Common::Rect r(2 + _leftPadding, 2, _w - 2 - _leftPadding - _rightPadding, _h-1); + Common::Rect r(2 + _leftPadding, 2, _w - 2 - _leftPadding - _rightPadding, _h - 1); return r; } -- cgit v1.2.3