aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Tkachev2016-06-30 23:34:25 +0600
committerEugene Sandulenko2016-07-03 12:23:57 +0200
commit4b87563792163d5fd538092b340500bccd20aa7b (patch)
treebc64bedf5aef5686c82a1d16cf870b0fc7a1bc35
parent916c86e68941cb1a752566ac9c0346263970b366 (diff)
downloadscummvm-rg350-4b87563792163d5fd538092b340500bccd20aa7b.tar.gz
scummvm-rg350-4b87563792163d5fd538092b340500bccd20aa7b.tar.bz2
scummvm-rg350-4b87563792163d5fd538092b340500bccd20aa7b.zip
GUI: Add blipClip()
-rw-r--r--graphics/nine_patch.cpp35
-rw-r--r--graphics/nine_patch.h1
-rw-r--r--graphics/transparent_surface.cpp133
-rw-r--r--graphics/transparent_surface.h8
-rw-r--r--gui/ThemeEngine.cpp7
5 files changed, 177 insertions, 7 deletions
diff --git a/graphics/nine_patch.cpp b/graphics/nine_patch.cpp
index a193200208..8ac6977eed 100644
--- a/graphics/nine_patch.cpp
+++ b/graphics/nine_patch.cpp
@@ -236,6 +236,41 @@ void NinePatchBitmap::blit(Graphics::Surface &target, int dx, int dy, int dw, in
}
}
+void NinePatchBitmap::blitClip(Graphics::Surface &target, Common::Rect clip, int dx, int dy, int dw, int dh) {
+ /* don't draw bitmaps that are smaller than the fixed area */
+ if (dw < _h._fix || dh < _v._fix)
+ return;
+
+ /* if the bitmap is the same size as the origin, then draw it as-is */
+ if (dw == _width && dh == _height) {
+ Common::Rect r(1, 1, dw, dh);
+
+ _bmp->blitClip(target, clip, dx, dy, Graphics::FLIP_NONE, &r);
+ return;
+ }
+
+ /* only recalculate the offsets if they have changed since the last draw */
+ if (_cached_dw != dw || _cached_dh != dh) {
+ _h.calcOffsets(dw);
+ _v.calcOffsets(dh);
+
+ _cached_dw = dw;
+ _cached_dh = dh;
+ }
+
+ /* draw each region */
+ for (uint i = 0; i < _v._m.size(); ++i) {
+ for (uint j = 0; j < _h._m.size(); ++j) {
+ Common::Rect r(_h._m[j]->offset, _v._m[i]->offset,
+ _h._m[j]->offset + _h._m[j]->length, _v._m[i]->offset + _v._m[i]->length);
+
+ _bmp->blitClip(target, clip, dx + _h._m[j]->dest_offset, dy + _v._m[i]->dest_offset,
+ Graphics::FLIP_NONE, &r, TS_ARGB(255, 255, 255, 255),
+ _h._m[j]->dest_length, _v._m[i]->dest_length);
+ }
+ }
+}
+
NinePatchBitmap::~NinePatchBitmap() {
if (_destroy_bmp)
delete _bmp;
diff --git a/graphics/nine_patch.h b/graphics/nine_patch.h
index c62de3f6e2..45e4e0918a 100644
--- a/graphics/nine_patch.h
+++ b/graphics/nine_patch.h
@@ -83,6 +83,7 @@ public:
~NinePatchBitmap();
void blit(Graphics::Surface &target, int dx, int dy, int dw, int dh);
+ void blitClip(Graphics::Surface &target, Common::Rect clip, int dx, int dy, int dw, int dh);
int getWidth() { return _width; }
int getHeight() { return _height; }
diff --git a/graphics/transparent_surface.cpp b/graphics/transparent_surface.cpp
index 19e7655a93..c2903d42c3 100644
--- a/graphics/transparent_surface.cpp
+++ b/graphics/transparent_surface.cpp
@@ -462,6 +462,139 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
return retSize;
}
+Common::Rect TransparentSurface::blitClip(Graphics::Surface &target, Common::Rect clippingArea, int posX, int posY, int flipping, Common::Rect *pPartRect, uint color, int width, int height, TSpriteBlendMode blendMode) {
+ Common::Rect retSize;
+ retSize.top = 0;
+ retSize.left = 0;
+ retSize.setWidth(0);
+ retSize.setHeight(0);
+ // Check if we need to draw anything at all
+ int ca = (color >> kAModShift) & 0xff;
+
+ if (ca == 0) {
+ return retSize;
+ }
+
+ // Create an encapsulating surface for the data
+ TransparentSurface srcImage(*this, false);
+ // TODO: Is the data really in the screen format?
+ if (format.bytesPerPixel != 4) {
+ warning("TransparentSurface can only blit 32bpp images, but got %d", format.bytesPerPixel * 8);
+ return retSize;
+ }
+
+ if (pPartRect) {
+
+ int xOffset = pPartRect->left;
+ int yOffset = pPartRect->top;
+
+ if (flipping & FLIP_V) {
+ yOffset = srcImage.h - pPartRect->bottom;
+ }
+
+ if (flipping & FLIP_H) {
+ xOffset = srcImage.w - pPartRect->right;
+ }
+
+ srcImage.pixels = getBasePtr(xOffset, yOffset);
+ srcImage.w = pPartRect->width();
+ srcImage.h = pPartRect->height();
+
+ debug(6, "Blit(%d, %d, %d, [%d, %d, %d, %d], %08x, %d, %d)", posX, posY, flipping,
+ pPartRect->left, pPartRect->top, pPartRect->width(), pPartRect->height(), color, width, height);
+ } else {
+
+ debug(6, "Blit(%d, %d, %d, [%d, %d, %d, %d], %08x, %d, %d)", posX, posY, flipping, 0, 0,
+ srcImage.w, srcImage.h, color, width, height);
+ }
+
+ if (width == -1) {
+ width = srcImage.w;
+ }
+ if (height == -1) {
+ height = srcImage.h;
+ }
+
+#ifdef SCALING_TESTING
+ // Hardcode scaling to 66% to test scaling
+ width = width * 2 / 3;
+ height = height * 2 / 3;
+#endif
+
+ Graphics::Surface *img = nullptr;
+ Graphics::Surface *imgScaled = nullptr;
+ byte *savedPixels = nullptr;
+ if ((width != srcImage.w) || (height != srcImage.h)) {
+ // Scale the image
+ img = imgScaled = srcImage.scale(width, height);
+ savedPixels = (byte *)img->getPixels();
+ } else {
+ img = &srcImage;
+ }
+
+ // Handle off-screen clipping
+ if (posY < clippingArea.top) {
+ img->h = MAX(0, (int)img->h - (clippingArea.top - posY));
+ img->setPixels((byte *)img->getBasePtr(0, clippingArea.top - posY));
+ posY = clippingArea.top;
+ }
+
+ if (posX < clippingArea.left) {
+ img->w = MAX(0, (int)img->w - (clippingArea.left - posX));
+ img->setPixels((byte *)img->getBasePtr(clippingArea.left - posX, 0));
+ posX = clippingArea.left;
+ }
+
+ img->w = CLIP((int)img->w, 0, (int)MAX((int)clippingArea.right - posX, 0));
+ img->h = CLIP((int)img->h, 0, (int)MAX((int)clippingArea.bottom - posY, 0));
+
+ if ((img->w > 0) && (img->h > 0)) {
+ int xp = 0, yp = 0;
+
+ int inStep = 4;
+ int inoStep = img->pitch;
+ if (flipping & FLIP_H) {
+ inStep = -inStep;
+ xp = img->w - 1;
+ }
+
+ if (flipping & FLIP_V) {
+ inoStep = -inoStep;
+ yp = img->h - 1;
+ }
+
+ byte *ino = (byte *)img->getBasePtr(xp, yp);
+ byte *outo = (byte *)target.getBasePtr(posX, posY);
+
+ if (color == 0xFFFFFFFF && blendMode == BLEND_NORMAL && _alphaMode == ALPHA_OPAQUE) {
+ doBlitOpaqueFast(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
+ } else if (color == 0xFFFFFFFF && blendMode == BLEND_NORMAL && _alphaMode == ALPHA_BINARY) {
+ doBlitBinaryFast(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
+ } else {
+ if (blendMode == BLEND_ADDITIVE) {
+ doBlitAdditiveBlend(ino, outo, img->w, img->h, target.pitch, inStep, inoStep, color);
+ } else if (blendMode == BLEND_SUBTRACTIVE) {
+ doBlitSubtractiveBlend(ino, outo, img->w, img->h, target.pitch, inStep, inoStep, color);
+ } else {
+ assert(blendMode == BLEND_NORMAL);
+ doBlitAlphaBlend(ino, outo, img->w, img->h, target.pitch, inStep, inoStep, color);
+ }
+ }
+
+ }
+
+ retSize.setWidth(img->w);
+ retSize.setHeight(img->h);
+
+ if (imgScaled) {
+ imgScaled->setPixels(savedPixels);
+ imgScaled->free();
+ delete imgScaled;
+ }
+
+ return retSize;
+}
+
/**
* Writes a color key to the alpha channel of the surface
* @param rKey the red component of the color key
diff --git a/graphics/transparent_surface.h b/graphics/transparent_surface.h
index 0cd7d5b2e9..c0d3d26e52 100644
--- a/graphics/transparent_surface.h
+++ b/graphics/transparent_surface.h
@@ -123,6 +123,14 @@ struct TransparentSurface : public Graphics::Surface {
uint color = TS_ARGB(255, 255, 255, 255),
int width = -1, int height = -1,
TSpriteBlendMode blend = BLEND_NORMAL);
+ Common::Rect blitClip(Graphics::Surface &target, Common::Rect clippingArea,
+ int posX = 0, int posY = 0,
+ int flipping = FLIP_NONE,
+ Common::Rect *pPartRect = nullptr,
+ uint color = TS_ARGB(255, 255, 255, 255),
+ int width = -1, int height = -1,
+ TSpriteBlendMode blend = BLEND_NORMAL);
+
void applyColorKey(uint8 r, uint8 g, uint8 b, bool overwriteAlpha = false);
/**
diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp
index 08245380a8..b16a42806c 100644
--- a/gui/ThemeEngine.cpp
+++ b/gui/ThemeEngine.cpp
@@ -168,8 +168,6 @@ protected:
bool _alpha;
};
-
-
/**********************************************************
* Data definitions for theme engine elements
*********************************************************/
@@ -306,7 +304,6 @@ void ThemeItemBitmap::drawSelf(bool draw, bool restore) {
}
-
/**********************************************************
* ThemeEngine class
*********************************************************/
@@ -979,8 +976,6 @@ void ThemeEngine::queueBitmap(const Graphics::Surface *bitmap, const Common::Rec
}
}
-
-
/**********************************************************
* Widget drawing functions
*********************************************************/
@@ -1201,8 +1196,6 @@ void ThemeEngine::drawDialogBackgroundClip(const Common::Rect &r, const Common::
case kDialogBackgroundDefault:
queueDDClip(kDDDefaultBackground, r, clip);
break;
- case kDialogBackgroundNone:
- break;
}
}