[Scummvm-git-logs] scummvm master -> 96f9569790fadc8d21068e63e3ed4b0afb5d74ed

sev- noreply at scummvm.org
Wed Jun 19 00:36:21 UTC 2024


This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
49ca5c3a0e GRAPHICS: Add simplified blitting routines to ManagedSurface
3da558fc96 GRAPHICS: Add a common function for detecting transparent surfaces
96f9569790 GUI: Make use of simple blitting routines where possible


Commit: 49ca5c3a0e2904d02a7e0519e7a6898475b9531a
    https://github.com/scummvm/scummvm/commit/49ca5c3a0e2904d02a7e0519e7a6898475b9531a
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2024-06-19T02:36:17+02:00

Commit Message:
GRAPHICS: Add simplified blitting routines to ManagedSurface

Changed paths:
    graphics/managed_surface.cpp
    graphics/managed_surface.h


diff --git a/graphics/managed_surface.cpp b/graphics/managed_surface.cpp
index 32a63e3b738..4b6c6d1dfe5 100644
--- a/graphics/managed_surface.cpp
+++ b/graphics/managed_surface.cpp
@@ -233,6 +233,73 @@ void ManagedSurface::copyFrom(const Surface &surf) {
 	}
 }
 
+void ManagedSurface::simpleBlitFrom(const Surface &src, const Palette *srcPalette) {
+	simpleBlitFrom(src, Common::Rect(0, 0, src.w, src.h), Common::Point(0, 0), srcPalette);
+}
+
+void ManagedSurface::simpleBlitFrom(const Surface &src, const Common::Point &destPos, const Palette *srcPalette) {
+	simpleBlitFrom(src, Common::Rect(0, 0, src.w, src.h), destPos, srcPalette);
+}
+
+void ManagedSurface::simpleBlitFrom(const Surface &src, const Common::Rect &srcRect,
+		const Common::Point &destPos, const Palette *srcPalette) {
+	simpleBlitFromInner(src, srcRect, destPos, srcPalette, false, 0);
+}
+
+void ManagedSurface::simpleBlitFrom(const ManagedSurface &src) {
+	simpleBlitFrom(src, Common::Rect(0, 0, src.w, src.h), Common::Point(0, 0));
+}
+
+void ManagedSurface::simpleBlitFrom(const ManagedSurface &src, const Common::Point &destPos) {
+	simpleBlitFrom(src, Common::Rect(0, 0, src.w, src.h), destPos);
+}
+
+void ManagedSurface::simpleBlitFrom(const ManagedSurface &src, const Common::Rect &srcRect,
+		const Common::Point &destPos) {
+	simpleBlitFromInner(src._innerSurface, srcRect, destPos, src._palette,
+		src._transparentColorSet, src._transparentColor);
+}
+
+void ManagedSurface::simpleBlitFromInner(const Surface &src, const Common::Rect &srcRect,
+		const Common::Point &destPos, const Palette *srcPalette,
+		bool transparentColorSet, uint transparentColor) {
+
+	Common::Rect srcRectC = srcRect;
+	Common::Rect dstRectC = srcRect;
+
+	dstRectC.moveTo(destPos.x, destPos.y);
+	clip(srcRectC, dstRectC);
+
+	const byte *srcPtr = (const byte *)src.getBasePtr(srcRectC.left, srcRectC.top);
+	byte *dstPtr = (byte *)getBasePtr(dstRectC.left, dstRectC.top);
+
+	if (src.format.isCLUT8()) {
+		assert(srcPalette);
+		assert(format.isCLUT8());
+
+		uint32 map[256];
+		convertPaletteToMap(map, srcPalette->data(), srcPalette->size(), format);
+
+		if (transparentColorSet) {
+			crossKeyBlitMap(dstPtr, srcPtr, pitch, src.pitch, srcRectC.width(), srcRectC.height(),
+				format.bytesPerPixel, map, transparentColor);
+		} else {
+			crossBlitMap(dstPtr, srcPtr, pitch, src.pitch, srcRectC.width(), srcRectC.height(),
+				format.bytesPerPixel, map);
+		}
+	} else {
+		if (transparentColorSet) {
+			crossKeyBlit(dstPtr, srcPtr, pitch, src.pitch, srcRectC.width(), srcRectC.height(),
+				format, src.format, transparentColor);
+		} else {
+			crossBlit(dstPtr, srcPtr, pitch, src.pitch, srcRectC.width(), srcRectC.height(),
+				format, src.format);
+		}
+	}
+
+	addDirtyRect(dstRectC);
+}
+
 void ManagedSurface::blitFrom(const Surface &src, const Palette *srcPalette) {
 	blitFrom(src, Common::Rect(0, 0, src.w, src.h), Common::Point(0, 0), srcPalette);
 }
diff --git a/graphics/managed_surface.h b/graphics/managed_surface.h
index fee443dc666..94e11b02f31 100644
--- a/graphics/managed_surface.h
+++ b/graphics/managed_surface.h
@@ -85,6 +85,13 @@ private:
 	 */
 	Palette *_palette;
 protected:
+	/**
+	 * Inner method for blitting.
+	 */
+	void simpleBlitFromInner(const Surface &src, const Common::Rect &srcRect,
+		const Common::Point &destPos, const Palette *srcPalette,
+		bool transparentColorSet, uint transparentColor);
+
 	/**
 	 * Inner method for blitting.
 	 */
@@ -306,6 +313,38 @@ public:
 		return Common::Rect(0, 0, this->w, this->h);
 	}
 
+	/**
+	 * Copy another surface into this one.
+	 */
+	void simpleBlitFrom(const Surface &src, const Palette *srcPalette = nullptr);
+
+	/**
+	 * Copy another surface into this one at a given destination position.
+	 */
+	void simpleBlitFrom(const Surface &src, const Common::Point &destPos, const Palette *srcPalette = nullptr);
+
+	/**
+	 * Copy another surface into this one at a given destination position.
+	 */
+	void simpleBlitFrom(const Surface &src, const Common::Rect &srcRect,
+		const Common::Point &destPos, const Palette *srcPalette = nullptr);
+
+	/**
+	 * Copy another surface into this one.
+	 */
+	void simpleBlitFrom(const ManagedSurface &src);
+
+	/**
+	 * Copy another surface into this one at a given destination position.
+	 */
+	void simpleBlitFrom(const ManagedSurface &src, const Common::Point &destPos);
+
+	/**
+	 * Copy another surface into this one at a given destination position.
+	 */
+	void simpleBlitFrom(const ManagedSurface &src, const Common::Rect &srcRect,
+		const Common::Point &destPos);
+
 	/**
 	 * Copy another surface into this one.
 	 */


Commit: 3da558fc964b619f7d1ab0f878a63f7469dc6575
    https://github.com/scummvm/scummvm/commit/3da558fc964b619f7d1ab0f878a63f7469dc6575
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2024-06-19T02:36:17+02:00

Commit Message:
GRAPHICS: Add a common function for detecting transparent surfaces

Changed paths:
    engines/sword25/gfx/image/renderedimage.cpp
    engines/sword25/gfx/image/renderedimage.h
    engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
    graphics/managed_surface.h
    graphics/surface.cpp
    graphics/surface.h


diff --git a/engines/sword25/gfx/image/renderedimage.cpp b/engines/sword25/gfx/image/renderedimage.cpp
index b3f9bbdb07f..6a00d2edfd6 100644
--- a/engines/sword25/gfx/image/renderedimage.cpp
+++ b/engines/sword25/gfx/image/renderedimage.cpp
@@ -140,7 +140,7 @@ RenderedImage::RenderedImage(const Common::String &filename, bool &result) :
 	delete[] pFileData;
 
 	_doCleanup = true;
-	_alphaType = checkForTransparency();
+	_alphaType = _surface.detectAlpha();
 
 	return;
 }
@@ -260,24 +260,4 @@ void RenderedImage::copyDirectly(int posX, int posY) {
 	g_system->copyRectToScreen(data, _backSurface->pitch, posX, posY, w, h);
 }
 
-Graphics::AlphaType RenderedImage::checkForTransparency() const {
-	// Check if the source bitmap has any transparent pixels at all
-	Graphics::AlphaType alphaType = Graphics::ALPHA_OPAQUE;
-	uint32 mask = _surface.format.ARGBToColor(0xff, 0, 0, 0);
-	const uint32 *data = (const uint32 *)_surface.getPixels();
-
-	for (int i = 0; i < _surface.h; i++) {
-		for (int j = 0; j < _surface.w; j++) {
-			if ((*data & mask) != mask) {
-				if ((*data & mask) != 0)
-					return Graphics::ALPHA_FULL;
-				else
-					alphaType = Graphics::ALPHA_BINARY;
-			}
-			data++;
-		}
-	}
-	return alphaType;
-}
-
 } // End of namespace Sword25
diff --git a/engines/sword25/gfx/image/renderedimage.h b/engines/sword25/gfx/image/renderedimage.h
index 719645071fe..6d286c8ea67 100644
--- a/engines/sword25/gfx/image/renderedimage.h
+++ b/engines/sword25/gfx/image/renderedimage.h
@@ -113,8 +113,6 @@ private:
 	bool _doCleanup;
 
 	Graphics::ManagedSurface *_backSurface;
-
-	Graphics::AlphaType checkForTransparency() const;
 };
 
 } // End of namespace Sword25
diff --git a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
index d66ead7a69e..e270ca0acad 100644
--- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
@@ -73,39 +73,6 @@ BaseSurfaceOSystem::~BaseSurfaceOSystem() {
 	renderer->invalidateTicketsFromSurface(this);
 }
 
-Graphics::AlphaType hasTransparencyType(const Graphics::Surface *surf) {
-	if (surf->format.bytesPerPixel != 4) {
-		warning("hasTransparencyType:: non 32 bpp surface passed as argument");
-		return Graphics::ALPHA_OPAQUE;
-	}
-	uint8 r, g, b, a;
-	bool seenAlpha = false;
-	bool seenFullAlpha = false;
-	for (int i = 0; i < surf->h; i++) {
-		if (seenFullAlpha) {
-			break;
-		}
-		for (int j = 0; j < surf->w; j++) {
-			uint32 pix = *(const uint32 *)surf->getBasePtr(j, i);
-			surf->format.colorToARGB(pix, a, r, g, b);
-			if (a != 255) {
-				seenAlpha = true;
-				if (a != 0) {
-					seenFullAlpha = true;
-					break;
-				}
-			}
-		}
-	}
-	if (seenFullAlpha) {
-		return Graphics::ALPHA_FULL;
-	} else if (seenAlpha) {
-		return Graphics::ALPHA_BINARY;
-	} else {
-		return Graphics::ALPHA_OPAQUE;
-	}
-}
-
 //////////////////////////////////////////////////////////////////////////
 bool BaseSurfaceOSystem::create(const Common::String &filename, bool defaultCK, byte ckRed, byte ckGreen, byte ckBlue, int lifeTime, bool keepLoaded) {
 	/*  BaseRenderOSystem *renderer = static_cast<BaseRenderOSystem *>(_gameRef->_renderer); */
@@ -188,7 +155,7 @@ bool BaseSurfaceOSystem::finishLoad() {
 		_surface->applyColorKey(_ckRed, _ckGreen, _ckBlue, replaceAlpha);
 	}
 
-	_alphaType = hasTransparencyType(_surface);
+	_alphaType = _surface->detectAlpha();
 	_valid = true;
 
 	_gameRef->addMem(_width * _height * 4);
diff --git a/graphics/managed_surface.h b/graphics/managed_surface.h
index 94e11b02f31..1f323feaea5 100644
--- a/graphics/managed_surface.h
+++ b/graphics/managed_surface.h
@@ -713,6 +713,13 @@ public:
 		addDirtyRect(r);
 	}
 
+	/**
+	 * Checks if the given surface contains alpha transparency
+	 */
+	AlphaType detectAlpha() const {
+		return _innerSurface.detectAlpha();
+	}
+
 	/**
 	 * Return a sub-area of the screen, but only add a single initial dirty rect
 	 * for the retrieved area.
diff --git a/graphics/surface.cpp b/graphics/surface.cpp
index d2eb754999f..955c2d2db9d 100644
--- a/graphics/surface.cpp
+++ b/graphics/surface.cpp
@@ -443,6 +443,28 @@ bool Surface::setAlpha(uint8 alpha, bool skipTransparent) {
 	                          skipTransparent, alpha);
 }
 
+AlphaType Surface::detectAlpha() const {
+	if (format.isCLUT8() || format.aBits() == 0)
+		return ALPHA_OPAQUE;
+
+	const uint32 mask = format.ARGBToColor(0xff, 0, 0, 0);
+	AlphaType alphaType = ALPHA_OPAQUE;
+
+	for (int y = 0; y < h; y++) {
+		for (int x = 0; x < w; x++) {
+			uint32 pixel = getPixel(x, y);
+			if ((pixel & mask) != mask) {
+				if ((pixel & mask) == 0)
+					alphaType = ALPHA_BINARY;
+				else
+					return ALPHA_FULL;
+			}
+		}
+	}
+
+	return alphaType;
+}
+
 Graphics::Surface *Surface::scale(int16 newWidth, int16 newHeight, bool filtering) const {
 	Graphics::Surface *target = new Graphics::Surface();
 
diff --git a/graphics/surface.h b/graphics/surface.h
index 3eb5280e4d5..51df73f11e2 100644
--- a/graphics/surface.h
+++ b/graphics/surface.h
@@ -32,6 +32,7 @@ struct Point;
 }
 
 #include "graphics/pixelformat.h"
+#include "graphics/transform_struct.h"
 
 namespace Graphics {
 
@@ -512,6 +513,11 @@ public:
 	 */
 	bool setAlpha(uint8 alpha, bool skipTransparent = false);
 
+	/**
+	 * Checks if the given surface contains alpha transparency
+	 */
+	AlphaType detectAlpha() const;
+
 	/**
 	 * Scale the data to the given size.
 	 *


Commit: 96f9569790fadc8d21068e63e3ed4b0afb5d74ed
    https://github.com/scummvm/scummvm/commit/96f9569790fadc8d21068e63e3ed4b0afb5d74ed
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2024-06-19T02:36:17+02:00

Commit Message:
GUI: Make use of simple blitting routines where possible

Changed paths:
    graphics/VectorRenderer.h
    graphics/VectorRendererSpec.cpp
    graphics/VectorRendererSpec.h
    gui/ThemeEngine.cpp
    gui/ThemeEngine.h
    gui/ThemeParser.cpp
    gui/widget.cpp
    gui/widget.h
    gui/widgets/grid.cpp
    gui/widgets/grid.h
    gui/widgets/richtext.cpp


diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h
index 04e052edfb0..beaf13e0ad6 100644
--- a/graphics/VectorRenderer.h
+++ b/graphics/VectorRenderer.h
@@ -51,6 +51,7 @@ typedef void (VectorRenderer::*DrawingFunctionCallback)(const Common::Rect &, co
 struct DrawStep {
 	DrawingFunctionCallback drawingCall; /**< Pointer to drawing function */
 	Graphics::ManagedSurface *blitSrc;
+	Graphics::AlphaType alphaType;
 
 	struct Color {
 		uint8 r, g, b;
@@ -99,6 +100,7 @@ struct DrawStep {
 	DrawStep() {
 		drawingCall = nullptr;
 		blitSrc = nullptr;
+		alphaType = Graphics::ALPHA_OPAQUE;
 		// fgColor, bgColor, gradColor1, gradColor2, bevelColor initialized by Color default constructor
 		autoWidth = autoHeight = false;
 		x = y = w = h = 0;
@@ -472,7 +474,7 @@ public:
 	void drawCallback_BITMAP(const Common::Rect &area, const DrawStep &step) {
 		uint16 x, y, w, h;
 		stepGetPositions(step, area, x, y, w, h);
-		blitManagedSurface(step.blitSrc, Common::Point(x, y));
+		blitManagedSurface(step.blitSrc, Common::Point(x, y), step.alphaType);
 	}
 
 	void drawCallback_CROSS(const Common::Rect &area, const DrawStep &step) {
@@ -523,7 +525,7 @@ public:
 	 */
 	virtual void blitSurface(const Graphics::ManagedSurface *source, const Common::Rect &r) = 0;
 
-	virtual void blitManagedSurface(const Graphics::ManagedSurface *source, const Common::Point &p) = 0;
+	virtual void blitManagedSurface(const Graphics::ManagedSurface *source, const Common::Point &p, Graphics::AlphaType alphaType) = 0;
 
 	/**
 	 * Draws a string into the screen. Wrapper for the Graphics::Font string drawing
diff --git a/graphics/VectorRendererSpec.cpp b/graphics/VectorRendererSpec.cpp
index 3482c6fc984..c8d841bdcfc 100644
--- a/graphics/VectorRendererSpec.cpp
+++ b/graphics/VectorRendererSpec.cpp
@@ -785,7 +785,7 @@ blitSurface(const Graphics::ManagedSurface *source, const Common::Rect &r) {
 
 template<typename PixelType>
 void VectorRendererSpec<PixelType>::
-blitManagedSurface(const Graphics::ManagedSurface *source, const Common::Point &p) {
+blitManagedSurface(const Graphics::ManagedSurface *source, const Common::Point &p, Graphics::AlphaType alphaType) {
 	Common::Rect drawRect(p.x, p.y, p.x + source->w, p.y + source->h);
 	drawRect.clip(_clippingArea);
 	drawRect.translate(-p.x, -p.y);
@@ -803,7 +803,11 @@ blitManagedSurface(const Graphics::ManagedSurface *source, const Common::Point &
 		np = p;
 	}
 
-	_activeSurface->blitFrom(*source, drawRect, np);
+	if (alphaType != Graphics::ALPHA_OPAQUE) {
+		_activeSurface->transBlitFrom(*source, drawRect, np);
+	} else {
+		_activeSurface->simpleBlitFrom(*source, drawRect, np);
+	}
 }
 
 template<typename PixelType>
diff --git a/graphics/VectorRendererSpec.h b/graphics/VectorRendererSpec.h
index 50372706770..c8d39514b54 100644
--- a/graphics/VectorRendererSpec.h
+++ b/graphics/VectorRendererSpec.h
@@ -88,7 +88,7 @@ public:
 
 	void fillSurface() override;
 	void blitSurface(const Graphics::ManagedSurface *source, const Common::Rect &r) override;
-	void blitManagedSurface(const Graphics::ManagedSurface *source, const Common::Point &p) override;
+	void blitManagedSurface(const Graphics::ManagedSurface *source, const Common::Point &p, Graphics::AlphaType alphaType) override;
 
 	void applyScreenShading(GUI::ThemeEngine::ShadingStyle shadingStyle) override;
 
diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp
index c4be030462d..47e0e28f1da 100644
--- a/gui/ThemeEngine.cpp
+++ b/gui/ThemeEngine.cpp
@@ -1240,7 +1240,7 @@ void ThemeEngine::drawPopUpWidget(const Common::Rect &r, const Common::U32String
 	}
 }
 
-void ThemeEngine::drawManagedSurface(const Common::Point &p, const Graphics::ManagedSurface &surface) {
+void ThemeEngine::drawManagedSurface(const Common::Point &p, const Graphics::ManagedSurface &surface, Graphics::AlphaType alphaType) {
 	if (!ready())
 		return;
 
@@ -1248,7 +1248,7 @@ void ThemeEngine::drawManagedSurface(const Common::Point &p, const Graphics::Man
 		return;
 
 	_vectorRenderer->setClippingRect(_clip);
-	_vectorRenderer->blitManagedSurface(&surface, p);
+	_vectorRenderer->blitManagedSurface(&surface, p, alphaType);
 
 	Common::Rect dirtyRect = Common::Rect(p.x, p.y, p.x + surface.w, p.y + surface.h);
 	dirtyRect.clip(_clip);
diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h
index 2c3159f8195..b0c11e4a018 100644
--- a/gui/ThemeEngine.h
+++ b/gui/ThemeEngine.h
@@ -469,7 +469,7 @@ public:
 	void drawDropDownButton(const Common::Rect &r, uint32 dropdownWidth, const Common::U32String &str,
 	                        WidgetStateInfo buttonState, bool inButton, bool inDropdown, bool rtl = false);
 
-	void drawManagedSurface(const Common::Point &p, const Graphics::ManagedSurface &surface);
+	void drawManagedSurface(const Common::Point &p, const Graphics::ManagedSurface &surface, Graphics::AlphaType alphaType);
 
 	void drawSlider(const Common::Rect &r, int width, WidgetStateInfo state = kStateEnabled, bool rtl = false);
 
diff --git a/gui/ThemeParser.cpp b/gui/ThemeParser.cpp
index beca53bd703..d7f83e8f49e 100644
--- a/gui/ThemeParser.cpp
+++ b/gui/ThemeParser.cpp
@@ -537,6 +537,8 @@ bool ThemeParser::parseDrawStep(ParserNode *stepNode, Graphics::DrawStep *drawst
 
 			if (!drawstep->blitSrc)
 				return parserError("The given filename hasn't been loaded into the GUI.");
+
+			drawstep->alphaType = drawstep->blitSrc->detectAlpha();
 		}
 
 		if (functionName == "roundedsq" || functionName == "circle" || functionName == "tab") {
diff --git a/gui/widget.cpp b/gui/widget.cpp
index 6e2984bd94f..dff323ac977 100644
--- a/gui/widget.cpp
+++ b/gui/widget.cpp
@@ -646,6 +646,8 @@ void PicButtonWidget::setGfx(const Graphics::ManagedSurface *gfx, int statenum,
 	if (!isVisible() || !_boss->isVisible())
 		return;
 
+	_alphaType[statenum] = gfx->detectAlpha();
+
 	float sf = g_gui.getScaleFactor();
 	if (scale && sf != 1.0) {
 		Graphics::Surface *tmp2 = gfx->rawSurface().scale(gfx->w * sf, gfx->h * sf, false);
@@ -686,6 +688,7 @@ void PicButtonWidget::setGfx(int w, int h, int r, int g, int b, int statenum) {
 
 	_gfx[statenum].create(w, h, requiredFormat);
 	_gfx[statenum].fillRect(Common::Rect(0, 0, w, h), _gfx[statenum].format.RGBToColor(r, g, b));
+	_alphaType[statenum] = Graphics::ALPHA_OPAQUE;
 }
 
 void PicButtonWidget::drawWidget() {
@@ -693,24 +696,31 @@ void PicButtonWidget::drawWidget() {
 		g_gui.theme()->drawButton(Common::Rect(_x, _y, _x + _w, _y + _h), Common::U32String(), _state, getFlags());
 
 	Graphics::ManagedSurface *gfx;
+	Graphics::AlphaType alphaType;
 
-	if (_state == ThemeEngine::kStateHighlight)
+	if (_state == ThemeEngine::kStateHighlight) {
 		gfx = &_gfx[kPicButtonHighlight];
-	else if (_state == ThemeEngine::kStateDisabled)
+		alphaType = _alphaType[kPicButtonHighlight];
+	} else if (_state == ThemeEngine::kStateDisabled) {
 		gfx = &_gfx[kPicButtonStateDisabled];
-	else if (_state == ThemeEngine::kStatePressed)
+		alphaType = _alphaType[kPicButtonStateDisabled];
+	} else if (_state == ThemeEngine::kStatePressed) {
 		gfx = &_gfx[kPicButtonStatePressed];
-	else
+		alphaType = _alphaType[kPicButtonStatePressed];
+	} else {
 		gfx = &_gfx[kPicButtonStateEnabled];
-
-	if (!gfx->getPixels())
+		alphaType = _alphaType[kPicButtonStateEnabled];
+	}
+	if (!gfx->getPixels()) {
 		gfx = &_gfx[kPicButtonStateEnabled];
+		alphaType= _alphaType[kPicButtonStateEnabled];
+	}
 
 	if (gfx->getPixels()) {
 		const int x = _x + (_w - gfx->w) / 2;
 		const int y = _y + (_h - gfx->h) / 2;
 
-		g_gui.theme()->drawManagedSurface(Common::Point(x, y), *gfx);
+		g_gui.theme()->drawManagedSurface(Common::Point(x, y), *gfx, alphaType);
 	}
 }
 
@@ -928,7 +938,7 @@ int SliderWidget::posToValue(int pos) {
 #pragma mark -
 
 GraphicsWidget::GraphicsWidget(GuiObject *boss, int x, int y, int w, int h, bool scale, const Common::U32String &tooltip)
-	: Widget(boss, x, y, w, h, scale, tooltip), _gfx() {
+	: Widget(boss, x, y, w, h, scale, tooltip), _gfx(), _alphaType(Graphics::ALPHA_OPAQUE) {
 	setFlags(WIDGET_ENABLED | WIDGET_CLEARBG);
 	_type = kGraphicsWidget;
 }
@@ -938,7 +948,7 @@ GraphicsWidget::GraphicsWidget(GuiObject *boss, int x, int y, int w, int h, cons
 }
 
 GraphicsWidget::GraphicsWidget(GuiObject *boss, const Common::String &name, const Common::U32String &tooltip)
-	: Widget(boss, name, tooltip), _gfx() {
+	: Widget(boss, name, tooltip), _gfx(), _alphaType(Graphics::ALPHA_OPAQUE) {
 	setFlags(WIDGET_ENABLED | WIDGET_CLEARBG);
 	_type = kGraphicsWidget;
 }
@@ -970,6 +980,8 @@ void GraphicsWidget::setGfx(const Graphics::ManagedSurface *gfx, bool scale) {
 		_h = gfx->h;
 	}
 
+	_alphaType = gfx->detectAlpha();
+
 	if ((_w != gfx->w || _h != gfx->h) && _w && _h) {
 		Graphics::Surface *tmp2 = gfx->rawSurface().scale(_w, _h, false);
 		_gfx.copyFrom(*tmp2);
@@ -1001,6 +1013,7 @@ void GraphicsWidget::setGfx(int w, int h, int r, int g, int b) {
 
 	_gfx.create(w, h, requiredFormat);
 	_gfx.fillRect(Common::Rect(0, 0, w, h), _gfx.format.RGBToColor(r, g, b));
+	_alphaType = Graphics::ALPHA_OPAQUE;
 }
 
 void GraphicsWidget::setGfxFromTheme(const char *name) {
@@ -1014,7 +1027,7 @@ void GraphicsWidget::drawWidget() {
 		const int x = _x + (_w - _gfx.w) / 2;
 		const int y = _y + (_h - _gfx.h) / 2;
 
-		g_gui.theme()->drawManagedSurface(Common::Point(x, y), _gfx);
+		g_gui.theme()->drawManagedSurface(Common::Point(x, y), _gfx, _alphaType);
 	}
 }
 
diff --git a/gui/widget.h b/gui/widget.h
index c575cbf2f2a..0cf9f9cbc8d 100644
--- a/gui/widget.h
+++ b/gui/widget.h
@@ -319,6 +319,7 @@ protected:
 	void drawWidget() override;
 
 	Graphics::ManagedSurface _gfx[kPicButtonStateMax + 1];
+	Graphics::AlphaType _alphaType[kPicButtonStateMax + 1];
 	bool _showButton;
 };
 
@@ -454,6 +455,7 @@ protected:
 	void drawWidget() override;
 
 	Graphics::ManagedSurface _gfx;
+	Graphics::AlphaType _alphaType;
 };
 
 class PathWidget : public StaticTextWidget {
diff --git a/gui/widgets/grid.cpp b/gui/widgets/grid.cpp
index 99b05c23915..631e2f1e063 100644
--- a/gui/widgets/grid.cpp
+++ b/gui/widgets/grid.cpp
@@ -49,8 +49,10 @@ void GridItemWidget::setActiveEntry(GridItemInfo &entry) {
 void GridItemWidget::updateThumb() {
 	const Graphics::ManagedSurface *gfx = _grid->filenameToSurface(_activeEntry->thumbPath);
 	_thumbGfx.free();
-	if (gfx)
+	if (gfx) {
 		_thumbGfx.copyFrom(*gfx);
+		_thumbAlpha = _thumbGfx.detectAlpha();
+	}
 }
 
 void GridItemWidget::update() {
@@ -119,30 +121,32 @@ void GridItemWidget::drawWidget() {
 			r.translate(0, kLineHeight);
 		}
 	} else {
-		g_gui.theme()->drawManagedSurface(Common::Point(_x + _grid->_thumbnailMargin, _y + _grid->_thumbnailMargin), _thumbGfx);
+		g_gui.theme()->drawManagedSurface(Common::Point(_x + _grid->_thumbnailMargin, _y + _grid->_thumbnailMargin), _thumbGfx, _thumbAlpha);
 	}
 
+	Graphics::AlphaType alphaType;
+
 	// Draw Platform Icon
-	const Graphics::ManagedSurface *platGfx = _grid->platformToSurface(_activeEntry->platform);
+	const Graphics::ManagedSurface *platGfx = _grid->platformToSurface(_activeEntry->platform, alphaType);
 	if (platGfx) {
 		Common::Point p(_x + thumbWidth - platGfx->w, _y + thumbHeight - platGfx->h);
-		g_gui.theme()->drawManagedSurface(p, *platGfx);
+		g_gui.theme()->drawManagedSurface(p, *platGfx, alphaType);
 	}
 
 	// Draw Flag
-	const Graphics::ManagedSurface *flagGfx = _grid->languageToSurface(_activeEntry->language);
+	const Graphics::ManagedSurface *flagGfx = _grid->languageToSurface(_activeEntry->language, alphaType);
 	if (flagGfx) {
 		// SVG and PNG can resize differently so it's better to use thumbWidth as reference to
 		// ensure all flags are aligned
 		Common::Point p(_x + thumbWidth - (thumbWidth / 5), _y + 5);
-		g_gui.theme()->drawManagedSurface(p, *flagGfx);
+		g_gui.theme()->drawManagedSurface(p, *flagGfx, alphaType);
 	}
 
 	// Draw Demo Overlay
-	const Graphics::ManagedSurface *demoGfx = _grid->demoToSurface(_activeEntry->extra);
+	const Graphics::ManagedSurface *demoGfx = _grid->demoToSurface(_activeEntry->extra, alphaType);
 	if (demoGfx) {
 		Common::Point p(_x, _y);
-		g_gui.theme()->drawManagedSurface(p, *demoGfx);
+		g_gui.theme()->drawManagedSurface(p, *demoGfx, alphaType);
 	}
 
 	bool validEntry = _activeEntry->validEntry;
@@ -152,7 +156,7 @@ void GridItemWidget::drawWidget() {
 		const Graphics::ManagedSurface *darkenGfx = _grid->disabledThumbnail();
 		if (darkenGfx) {
 			Common::Point p(_x, _y);
-			g_gui.theme()->drawManagedSurface(p, *darkenGfx);
+			g_gui.theme()->drawManagedSurface(p, *darkenGfx, Graphics::ALPHA_FULL);
 		}
 	}
 
@@ -452,6 +456,9 @@ GridWidget::~GridWidget() {
 	_headerEntryList.clear();
 	_sortedEntryList.clear();
 	_visibleEntryList.clear();
+	_platformIconsAlpha.clear();
+	_languageIconsAlpha.clear();
+	_extraIconsAlpha.clear();
 }
 
 template<typename T>
@@ -468,21 +475,24 @@ const Graphics::ManagedSurface *GridWidget::filenameToSurface(const Common::Stri
 	return _loadedSurfaces[name];
 }
 
-const Graphics::ManagedSurface *GridWidget::languageToSurface(Common::Language languageCode) {
+const Graphics::ManagedSurface *GridWidget::languageToSurface(Common::Language languageCode, Graphics::AlphaType &alphaType) {
 	if (languageCode == Common::UNK_LANG)
 		return nullptr;
+	alphaType = _languageIconsAlpha[languageCode];
 	return _languageIcons[languageCode];
 }
 
-const Graphics::ManagedSurface *GridWidget::platformToSurface(Common::Platform platformCode) {
+const Graphics::ManagedSurface *GridWidget::platformToSurface(Common::Platform platformCode, Graphics::AlphaType &alphaType) {
 	if (platformCode == Common::kPlatformUnknown)
 		return nullptr;
+	alphaType = _platformIconsAlpha[platformCode];
 	return _platformIcons[platformCode];
 }
 
-const Graphics::ManagedSurface *GridWidget::demoToSurface(const Common::String extraString) {
+const Graphics::ManagedSurface *GridWidget::demoToSurface(const Common::String extraString, Graphics::AlphaType &alphaType) {
 	if (! extraString.contains("Demo") )
 		return nullptr;
+	alphaType = _extraIconsAlpha[0];
 	return _extraIcons[0];
 }
 
@@ -731,6 +741,7 @@ void GridWidget::loadFlagIcons() {
 		Graphics::ManagedSurface *gfx = loadSurfaceFromFile(path, _flagIconWidth, _flagIconHeight);
 		if (gfx) {
 			_languageIcons[l->id] = gfx;
+			_languageIconsAlpha[l->id] = gfx->detectAlpha();
 			continue;
 		} // if no .svg flag is available, search for a .png
 		path = Common::String::format("icons/flags/%s.png", l->code);
@@ -738,6 +749,7 @@ void GridWidget::loadFlagIcons() {
 		if (gfx) {
 			const Graphics::ManagedSurface *scGfx = scaleGfx(gfx, _flagIconWidth, _flagIconHeight, true);
 			_languageIcons[l->id] = scGfx;
+			_languageIconsAlpha[l->id] = gfx->detectAlpha();
 			if (gfx != scGfx) {
 				gfx->free();
 				delete gfx;
@@ -756,6 +768,7 @@ void GridWidget::loadPlatformIcons() {
 		if (gfx) {
 			const Graphics::ManagedSurface *scGfx = scaleGfx(gfx, _platformIconWidth, _platformIconHeight, true);
 			_platformIcons[l->id] = scGfx;
+			_platformIconsAlpha[l->id] = scGfx->detectAlpha();
 			if (gfx != scGfx) {
 				gfx->free();
 				delete gfx;
@@ -770,12 +783,14 @@ void GridWidget::loadExtraIcons() {  // for now only the demo icon is available
 	Graphics::ManagedSurface *gfx = loadSurfaceFromFile("icons/extra/demo.svg", _extraIconWidth, _extraIconHeight);
 	if (gfx) {
 		_extraIcons[0] = gfx;
+		_extraIconsAlpha[0] = gfx->detectAlpha();
 		return;
 	} // if no .svg file is available, search for a .png
 	gfx = loadSurfaceFromFile("icons/extra/demo.png");
 	if (gfx) {
 		const Graphics::ManagedSurface *scGfx = scaleGfx(gfx, _extraIconWidth, _extraIconHeight, true);
 		_extraIcons[0] = scGfx;
+		_extraIconsAlpha[0] = scGfx->detectAlpha();
 		if (gfx != scGfx) {
 			gfx->free();
 			delete gfx;
@@ -1051,6 +1066,9 @@ void GridWidget::reflowLayout() {
 		unloadSurfaces(_platformIcons);
 		unloadSurfaces(_languageIcons);
 		unloadSurfaces(_loadedSurfaces);
+		_platformIconsAlpha.clear();
+		_languageIconsAlpha.clear();
+		_extraIconsAlpha.clear();
 		if (_disabledIconOverlay)
 			_disabledIconOverlay->free();
 		reloadThumbnails();
diff --git a/gui/widgets/grid.h b/gui/widgets/grid.h
index f2d693c1201..15e68249dbd 100644
--- a/gui/widgets/grid.h
+++ b/gui/widgets/grid.h
@@ -102,6 +102,9 @@ protected:
 	Common::HashMap<int, const Graphics::ManagedSurface *> _platformIcons;
 	Common::HashMap<int, const Graphics::ManagedSurface *> _languageIcons;
 	Common::HashMap<int, const Graphics::ManagedSurface *> _extraIcons;
+	Common::HashMap<int, Graphics::AlphaType> _platformIconsAlpha;
+	Common::HashMap<int, Graphics::AlphaType> _languageIconsAlpha;
+	Common::HashMap<int, Graphics::AlphaType> _extraIconsAlpha;
 	Graphics::ManagedSurface *_disabledIconOverlay;
 	// Images are mapped by filename -> surface.
 	Common::HashMap<Common::String, const Graphics::ManagedSurface *> _loadedSurfaces;
@@ -173,9 +176,9 @@ public:
 	void unloadSurfaces(Common::HashMap<T, const Graphics::ManagedSurface *> &surfaces);
 
 	const Graphics::ManagedSurface *filenameToSurface(const Common::String &name);
-	const Graphics::ManagedSurface *languageToSurface(Common::Language languageCode);
-	const Graphics::ManagedSurface *platformToSurface(Common::Platform platformCode);
-	const Graphics::ManagedSurface *demoToSurface(const Common::String extraString);
+	const Graphics::ManagedSurface *languageToSurface(Common::Language languageCode, Graphics::AlphaType &alphaType);
+	const Graphics::ManagedSurface *platformToSurface(Common::Platform platformCode, Graphics::AlphaType &alphaType);
+	const Graphics::ManagedSurface *demoToSurface(const Common::String extraString, Graphics::AlphaType &alphaType);
 	const Graphics::ManagedSurface *disabledThumbnail();
 
 	/// Update _visibleEntries from _allEntries and returns true if reload is required.
@@ -232,6 +235,7 @@ public:
 class GridItemWidget : public ContainerWidget, public CommandSender {
 protected:
 	Graphics::ManagedSurface _thumbGfx;
+	Graphics::AlphaType _thumbAlpha;
 
 	GridItemInfo	*_activeEntry;
 	GridWidget		*_grid;
diff --git a/gui/widgets/richtext.cpp b/gui/widgets/richtext.cpp
index 3e388448f71..c942216eabe 100644
--- a/gui/widgets/richtext.cpp
+++ b/gui/widgets/richtext.cpp
@@ -237,7 +237,7 @@ void RichTextWidget::drawWidget() {
 
 	_txtWnd->draw(_surface, 0, _scrolledY, _textWidth, _textHeight, 0, 0);
 
-	g_gui.theme()->drawManagedSurface(Common::Point(_x + _innerMargin, _y + _innerMargin), *_surface);
+	g_gui.theme()->drawManagedSurface(Common::Point(_x + _innerMargin, _y + _innerMargin), *_surface, Graphics::ALPHA_FULL);
 }
 
 void RichTextWidget::draw() {




More information about the Scummvm-git-logs mailing list