aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--graphics/VectorRenderer.h1
-rw-r--r--graphics/VectorRendererSpec.cpp54
-rw-r--r--graphics/VectorRendererSpec.h1
-rw-r--r--gui/ThemeEngine.cpp50
-rw-r--r--gui/ThemeEngine.h6
-rw-r--r--gui/widget.cpp2
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);
}
}