diff options
-rw-r--r-- | graphics/VectorRenderer.h | 1 | ||||
-rw-r--r-- | graphics/VectorRendererSpec.cpp | 54 | ||||
-rw-r--r-- | graphics/VectorRendererSpec.h | 1 | ||||
-rw-r--r-- | gui/ThemeEngine.cpp | 50 | ||||
-rw-r--r-- | gui/ThemeEngine.h | 6 | ||||
-rw-r--r-- | gui/widget.cpp | 2 |
6 files changed, 111 insertions, 3 deletions
diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h index 78133b0e04..0352808706 100644 --- a/graphics/VectorRenderer.h +++ b/graphics/VectorRenderer.h @@ -480,6 +480,7 @@ public: * blitted into the active surface, at the position specified by "r". */ virtual void blitSubSurface(const Graphics::Surface *source, const Common::Rect &r) = 0; + virtual void blitSubSurfaceClip(const Graphics::Surface *source, const Common::Rect &r, const Common::Rect &clipping) = 0; virtual void blitAlphaBitmap(const Graphics::Surface *source, const Common::Rect &r) = 0; virtual void blitAlphaBitmapClip(const Graphics::Surface *source, const Common::Rect &r, const Common::Rect &clipping) = 0; diff --git a/graphics/VectorRendererSpec.cpp b/graphics/VectorRendererSpec.cpp index 32c2f06cc8..43ca2c40ad 100644 --- a/graphics/VectorRendererSpec.cpp +++ b/graphics/VectorRendererSpec.cpp @@ -797,6 +797,58 @@ blitSubSurface(const Graphics::Surface *source, const Common::Rect &r) { template<typename PixelType> void VectorRendererSpec<PixelType>:: +blitSubSurfaceClip(const Graphics::Surface *source, const Common::Rect &r, const Common::Rect &clipping) { + if (clipping.isEmpty() || clipping.contains(r)) { + blitSubSurface(source, r); + return; + } + + int16 x = r.left; + int16 y = r.top; + + if (r.width() > source->w) + x = x + (r.width() >> 1) - (source->w >> 1); + + if (r.height() > source->h) + y = y + (r.height() >> 1) - (source->h >> 1); + + int w = source->w, h = source->h; + int usedW = w, usedH = h; + int offsetX = 0, offsetY = 0; + + if (x > clipping.right || x + w < clipping.left) return; + if (y > clipping.bottom || y + h < clipping.top) return; + if (x < clipping.left) { + offsetX = clipping.left - x; + usedW -= offsetX; + x = clipping.left; + } + if (y < clipping.top) { + offsetY = clipping.top - y; + usedH -= offsetY; + y = clipping.top; + } + if (usedW > clipping.width()) usedW = clipping.width(); + if (usedH > clipping.width()) usedH = clipping.height(); + + byte *dst_ptr = (byte *)_activeSurface->getBasePtr(x, y); + const byte *src_ptr = (const byte *)source->getBasePtr(offsetX, offsetY); + + const int dst_pitch = _activeSurface->pitch; + const int src_pitch = source->pitch; + + int lines = usedH; + const int sz = usedW * sizeof(PixelType); + + while (lines--) { + memcpy(dst_ptr, src_ptr, sz); + dst_ptr += dst_pitch; + src_ptr += src_pitch; + } +} + +template<typename PixelType> +void VectorRendererSpec<PixelType>:: blitAlphaBitmap(const Graphics::Surface *source, const Common::Rect &r) { int16 x = r.left; int16 y = r.top; @@ -886,7 +938,7 @@ blitAlphaBitmapClip(const Graphics::Surface *source, const Common::Rect &r, cons } dst_ptr = dst_ptr - usedW + dst_pitch; - src_ptr = src_ptr - usedH + src_pitch; + src_ptr = src_ptr - usedW + src_pitch; } } diff --git a/graphics/VectorRendererSpec.h b/graphics/VectorRendererSpec.h index 5517555ede..bee6d4c425 100644 --- a/graphics/VectorRendererSpec.h +++ b/graphics/VectorRendererSpec.h @@ -92,6 +92,7 @@ public: void fillSurfaceClip(Common::Rect clipping); void blitSurface(const Graphics::Surface *source, const Common::Rect &r); void blitSubSurface(const Graphics::Surface *source, const Common::Rect &r); + void blitSubSurfaceClip(const Graphics::Surface *source, const Common::Rect &r, const Common::Rect &clipping); void blitAlphaBitmap(const Graphics::Surface *source, const Common::Rect &r); void blitAlphaBitmapClip(const Graphics::Surface *source, const Common::Rect &r, const Common::Rect &clipping); diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index b16a42806c..6174d41ddd 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -168,6 +168,19 @@ protected: bool _alpha; }; +class ThemeItemBitmapClip : public ThemeItem { +public: + ThemeItemBitmapClip(ThemeEngine *engine, const Common::Rect &area, const Common::Rect &clip, const Graphics::Surface *bitmap, bool alpha) : + ThemeItem(engine, area), _bitmap(bitmap), _alpha(alpha), _clip(clip) {} + + void drawSelf(bool draw, bool restore); + +protected: + const Graphics::Surface *_bitmap; + bool _alpha; + const Common::Rect _clip; +}; + /********************************************************** * Data definitions for theme engine elements *********************************************************/ @@ -303,6 +316,21 @@ void ThemeItemBitmap::drawSelf(bool draw, bool restore) { _engine->addDirtyRect(_area); } +void ThemeItemBitmapClip::drawSelf(bool draw, bool restore) { + if (restore) + _engine->restoreBackground(_area); + + if (draw) { + if (_alpha) + _engine->renderer()->blitAlphaBitmapClip(_bitmap, _area, _clip); + else + _engine->renderer()->blitSubSurfaceClip(_bitmap, _area, _clip); + } + + Common::Rect dirtyRect = _area; + dirtyRect.clip(_clip); + _engine->addDirtyRect(dirtyRect); +} /********************************************************** * ThemeEngine class @@ -976,6 +1004,21 @@ void ThemeEngine::queueBitmap(const Graphics::Surface *bitmap, const Common::Rec } } +void ThemeEngine::queueBitmapClip(const Graphics::Surface *bitmap, const Common::Rect &r, const Common::Rect &clip, bool alpha) { + + Common::Rect area = r; + area.clip(_screen.w, _screen.h); + + ThemeItemBitmapClip *q = new ThemeItemBitmapClip(this, area, clip, bitmap, alpha); + + if (_buffering) { + _screenQueue.push_back(q); + } else { + q->drawSelf(true, false); + delete q; + } +} + /********************************************************** * Widget drawing functions *********************************************************/ @@ -1270,6 +1313,13 @@ void ThemeEngine::drawSurface(const Common::Rect &r, const Graphics::Surface &su queueBitmap(&surface, r, themeTrans); } +void ThemeEngine::drawSurfaceClip(const Common::Rect &r, const Common::Rect &clip, const Graphics::Surface &surface, WidgetStateInfo state, int alpha, bool themeTrans) { + if (!ready()) + return; + + queueBitmapClip(&surface, r, clip, themeTrans); +} + void ThemeEngine::drawWidgetBackground(const Common::Rect &r, uint16 hints, WidgetBackground background, WidgetStateInfo state) { if (!ready()) return; diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h index d88890d39e..b8ceeda39b 100644 --- a/gui/ThemeEngine.h +++ b/gui/ThemeEngine.h @@ -351,7 +351,10 @@ public: WidgetStateInfo state = kStateEnabled, uint16 hints = 0); void drawSurface(const Common::Rect &r, const Graphics::Surface &surface, - WidgetStateInfo state = kStateEnabled, int alpha = 256, bool themeTrans = false); + WidgetStateInfo state = kStateEnabled, int alpha = 255, bool themeTrans = false); + + void drawSurfaceClip(const Common::Rect &r, const Common::Rect &clippingRect, const Graphics::Surface &surface, + WidgetStateInfo state = kStateEnabled, int alpha = 255, bool themeTrans = false); void drawSlider(const Common::Rect &r, int width, WidgetStateInfo state = kStateEnabled); @@ -609,6 +612,7 @@ protected: void queueDDTextClip(TextData type, TextColor color, const Common::Rect &r, const Common::Rect &clippingRect, const Common::String &text, bool restoreBg, 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); + void queueBitmapClip(const Graphics::Surface *bitmap, const Common::Rect &clippingRect, const Common::Rect &r, bool alpha); /** * DEBUG: Draws a white square and writes some text next to it. diff --git a/gui/widget.cpp b/gui/widget.cpp index ed7cf93d7b..13be22f142 100644 --- a/gui/widget.cpp +++ b/gui/widget.cpp @@ -686,7 +686,7 @@ void GraphicsWidget::drawWidget() { const int x = _x + (_w - _gfx.w) / 2; const int y = _y + (_h - _gfx.h) / 2; - g_gui.theme()->drawSurface(Common::Rect(x, y, x + _gfx.w, y + _gfx.h), _gfx, _state, _alpha, _transparency); + g_gui.theme()->drawSurfaceClip(Common::Rect(x, y, x + _gfx.w, y + _gfx.h), getBossClipRect(), _gfx, _state, _alpha, _transparency); } } |