[Scummvm-git-logs] scummvm master -> 583ebb114726c60900ca2339aaa9e564a1b7215a

bluegr noreply at scummvm.org
Tue Apr 14 15:46:19 UTC 2026


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

Summary:
70050f9d0c GRAPHICS: Remove duplicate scaling function
8a01c2a0b0 GUI: Use Common::SharedPtr for reusing surfaces
583ebb1147 GRAPHICS: Always use simpleBlitFrom in VectorRendererSpec


Commit: 70050f9d0ce31da2c0fe21ce972a8775ff1868bd
    https://github.com/scummvm/scummvm/commit/70050f9d0ce31da2c0fe21ce972a8775ff1868bd
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2026-04-14T18:46:14+03:00

Commit Message:
GRAPHICS: Remove duplicate scaling function

Changed paths:
    engines/colony/metaengine.cpp
    engines/freescape/metaengine.cpp
    graphics/thumbnail.cpp
    graphics/thumbnail.h
    gui/recorderdialog.cpp


diff --git a/engines/colony/metaengine.cpp b/engines/colony/metaengine.cpp
index 1754c24a0e3..4b88aca2400 100644
--- a/engines/colony/metaengine.cpp
+++ b/engines/colony/metaengine.cpp
@@ -32,7 +32,6 @@
 #include "common/system.h"
 #include "common/translation.h"
 #include "graphics/scaler.h"
-#include "graphics/thumbnail.h"
 
 #include "colony/colony.h"
 #include "colony/detection.h"
@@ -84,7 +83,7 @@ void ColonyMetaEngine::getSavegameThumbnail(Graphics::Surface &thumb) {
 	if (!engine || !engine->getSavedScreen())
 		return;
 
-	Graphics::Surface *scaledSavedScreen = scale(*engine->getSavedScreen(), kThumbnailWidth, kThumbnailHeight2);
+	Graphics::Surface *scaledSavedScreen = engine->getSavedScreen()->scale(kThumbnailWidth, kThumbnailHeight2);
 	if (!scaledSavedScreen)
 		return;
 
diff --git a/engines/freescape/metaengine.cpp b/engines/freescape/metaengine.cpp
index 5970768aad1..a3927d4b81f 100644
--- a/engines/freescape/metaengine.cpp
+++ b/engines/freescape/metaengine.cpp
@@ -23,7 +23,6 @@
 #include "backends/keymapper/action.h"
 #include "backends/keymapper/keymap.h"
 #include "backends/keymapper/standard-actions.h"
-#include "graphics/thumbnail.h"
 #include "graphics/scaler.h"
 
 
@@ -235,7 +234,7 @@ Common::KeymapArray FreescapeMetaEngine::initKeymaps(const char *target) const {
 void FreescapeMetaEngine::getSavegameThumbnail(Graphics::Surface &thumb) {
 	Freescape::FreescapeEngine *engine = (Freescape::FreescapeEngine *)g_engine;
 	assert(engine->_savedScreen);
-	Graphics::Surface *scaledSavedScreen = scale(*engine->_savedScreen, kThumbnailWidth, kThumbnailHeight2);
+	Graphics::Surface *scaledSavedScreen = engine->_savedScreen->scale(kThumbnailWidth, kThumbnailHeight2);
 	assert(scaledSavedScreen);
 	thumb.copyFrom(*scaledSavedScreen);
 
diff --git a/graphics/thumbnail.cpp b/graphics/thumbnail.cpp
index 00677b39ff4..393985cff4f 100644
--- a/graphics/thumbnail.cpp
+++ b/graphics/thumbnail.cpp
@@ -282,55 +282,4 @@ bool saveThumbnail(Common::WriteStream &out, const Graphics::Surface &thumb) {
 	return true;
 }
 
-
-/**
- * Returns an array indicating which pixels of a source image horizontally or vertically get
- * included in a scaled image
- */
-int *scaleLine(int size, int srcSize) {
-	int scale = 100 * size / srcSize;
-	assert(scale > 0);
-	int *v = new int[size];
-	Common::fill(v, v + size, 0);
-
-	int distCtr = 0;
-	int *destP = v;
-	for (int distIndex = 0; distIndex < srcSize; ++distIndex) {
-		distCtr += scale;
-		while (distCtr >= 100) {
-			assert(destP < &v[size]);
-			*destP++ = distIndex;
-			distCtr -= 100;
-		}
-	}
-
-	return v;
-}
-
-Graphics::Surface *scale(const Graphics::Surface &srcImage, int xSize, int ySize) {
-	Graphics::Surface *s = new Graphics::Surface();
-	s->create(xSize, ySize, srcImage.format);
-
-	int *horizUsage = scaleLine(xSize, srcImage.w);
-	int *vertUsage = scaleLine(ySize, srcImage.h);
-
-	// Loop to create scaled version
-	for (int yp = 0; yp < ySize; ++yp) {
-		const byte *srcP = (const byte *)srcImage.getBasePtr(0, vertUsage[yp]);
-		byte *destP = (byte *)s->getBasePtr(0, yp);
-
-		for (int xp = 0; xp < xSize; ++xp) {
-			const byte *tempSrcP = srcP + (horizUsage[xp] * srcImage.format.bytesPerPixel);
-			for (int byteCtr = 0; byteCtr < srcImage.format.bytesPerPixel; ++byteCtr) {
-				*destP++ = *tempSrcP++;
-			}
-		}
-	}
-
-	// Delete arrays and return surface
-	delete[] horizUsage;
-	delete[] vertUsage;
-	return s;
-}
-
 } // End of namespace Graphics
diff --git a/graphics/thumbnail.h b/graphics/thumbnail.h
index 37c96f9e139..a61088cff73 100644
--- a/graphics/thumbnail.h
+++ b/graphics/thumbnail.h
@@ -86,15 +86,6 @@ bool saveThumbnail(Common::WriteStream &out, const Graphics::Surface &thumb);
  */
 bool createScreenShot(Graphics::Surface &surf);
 
-/**
- * Scales a passed surface, creating a new surface with the result
- * @param srcImage		Source image to scale
- * @param xSize			New surface width
- * @param ySize			New surface height
- * @remarks Caller is responsible for freeing the returned surface
- */
-Graphics::Surface *scale(const Graphics::Surface &srcImage, int xSize, int ySize);
-
 /** @} */
 } // End of namespace Graphics
 
diff --git a/gui/recorderdialog.cpp b/gui/recorderdialog.cpp
index fa3616eb019..cf20883cb80 100644
--- a/gui/recorderdialog.cpp
+++ b/gui/recorderdialog.cpp
@@ -25,7 +25,6 @@
 #include "common/system.h"
 #include "graphics/palette.h"
 #include "graphics/scaler.h"
-#include "graphics/thumbnail.h"
 #include "common/translation.h"
 #include "gui/widgets/list.h"
 #include "gui/editrecorddialog.h"
@@ -349,7 +348,7 @@ void RecorderDialog::updateScreenshot() {
 	Graphics::Surface *srcsf = _playbackFile.getScreenShot(_currentScreenshot);
 	Common::SharedPtr<Graphics::Surface> srcsfSptr = Common::SharedPtr<Graphics::Surface>(srcsf, Graphics::SurfaceDeleter());
 	if (srcsfSptr) {
-		Graphics::Surface *destsf = Graphics::scale(*srcsfSptr, _gfxWidget->getWidth(), _gfxWidget->getHeight());
+		Graphics::Surface *destsf = srcsfSptr->scale(_gfxWidget->getWidth(), _gfxWidget->getHeight());
 		Common::SharedPtr<Graphics::Surface> destsfSptr = Common::SharedPtr<Graphics::Surface>(destsf, Graphics::SurfaceDeleter());
 		if (destsfSptr && _gfxWidget->isVisible())
 			_gfxWidget->setGfx(destsf, false);


Commit: 8a01c2a0b06409fb6e8c6b71834aac15f56bb286
    https://github.com/scummvm/scummvm/commit/8a01c2a0b06409fb6e8c6b71834aac15f56bb286
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2026-04-14T18:46:14+03:00

Commit Message:
GUI: Use Common::SharedPtr for reusing surfaces

Changed paths:
    common/recorderfile.cpp
    common/recorderfile.h
    engines/testbed/printing.cpp
    graphics/VectorRenderer.h
    graphics/thumbnail.cpp
    graphics/thumbnail.h
    gui/ThemeEngine.cpp
    gui/ThemeEngine.h
    gui/imagealbum-dialog.cpp
    gui/launcher.cpp
    gui/printing-dialog.cpp
    gui/recorderdialog.cpp
    gui/saveload-dialog.cpp
    gui/widget.cpp
    gui/widget.h
    gui/widgets/grid.cpp
    gui/widgets/grid.h


diff --git a/common/recorderfile.cpp b/common/recorderfile.cpp
index 7bce79baaff..bad8f862fd9 100644
--- a/common/recorderfile.cpp
+++ b/common/recorderfile.cpp
@@ -26,7 +26,7 @@
 #include "common/savefile.h"
 #include "common/bufferedstream.h"
 #include "graphics/thumbnail.h"
-#include "graphics/surface.h"
+#include "graphics/managed_surface.h"
 #include "graphics/scaler.h"
 
 #define RECORD_VERSION 1
@@ -455,7 +455,11 @@ void PlaybackFile::readEventsToBuffer(uint32 size) {
 	_eventsSize = size;
 }
 
-void PlaybackFile::saveScreenShot(Graphics::Surface &screen, byte md5[16]) {
+void PlaybackFile::saveScreenShot(const Graphics::ManagedSurface &screen, const byte md5[16]) {
+	saveScreenShot(screen.rawSurface(), md5);
+}
+
+void PlaybackFile::saveScreenShot(const Graphics::Surface &screen, const byte md5[16]) {
 	dumpRecordsToFile();
 	_writeStream->writeUint32BE(kMD5Tag);
 	_writeStream->writeUint32BE(16);
@@ -689,7 +693,7 @@ bool PlaybackFile::skipToNextScreenshot() {
 	return false;
 }
 
-Graphics::Surface *PlaybackFile::getScreenShot(int number) {
+Graphics::ManagedSurface *PlaybackFile::getScreenShot(int number) {
 	if (_mode != kRead) {
 		return NULL;
 	}
@@ -699,7 +703,7 @@ Graphics::Surface *PlaybackFile::getScreenShot(int number) {
 		if (screenCount == number) {
 			screenCount++;
 			_readStream->seek(-4, SEEK_CUR);
-			Graphics::Surface *thumbnail = nullptr;
+			Graphics::ManagedSurface *thumbnail = nullptr;
 			return Graphics::loadThumbnail(*_readStream, thumbnail) ? thumbnail : NULL;
 		} else {
 			uint32 size = _readStream->readUint32BE();
diff --git a/common/recorderfile.h b/common/recorderfile.h
index b9f36036409..73349194f3c 100644
--- a/common/recorderfile.h
+++ b/common/recorderfile.h
@@ -33,6 +33,10 @@
 #define kMaxBufferedRecords 10000
 #define kRecordBuffSize sizeof(RecorderEvent) * kMaxBufferedRecords
 
+namespace Graphics {
+class ManagedSurface;
+}
+
 namespace Common {
 
 enum RecorderEventType {
@@ -149,8 +153,9 @@ public:
 	RecorderEvent getNextEvent();
 	void writeEvent(const RecorderEvent &event);
 
-	void saveScreenShot(Graphics::Surface &screen, byte md5[16]);
-	Graphics::Surface *getScreenShot(int number);
+	void saveScreenShot(const Graphics::ManagedSurface &screen, const byte md5[16]);
+	void saveScreenShot(const Graphics::Surface &screen, const byte md5[16]);
+	Graphics::ManagedSurface *getScreenShot(int number);
 	int getScreensCount();
 
 	bool isEventsBufferEmpty() const;
@@ -204,7 +209,6 @@ private:
 	bool skipToNextScreenshot();
 	void readEvent(RecorderEvent& event);
 	void readEventsToBuffer(uint32 size);
-	bool grabScreenAndComputeMD5(Graphics::Surface &screen, uint8 md5[16]);
 };
 
 } // End of namespace Common
diff --git a/engines/testbed/printing.cpp b/engines/testbed/printing.cpp
index 191874c8312..52343da57c6 100644
--- a/engines/testbed/printing.cpp
+++ b/engines/testbed/printing.cpp
@@ -56,7 +56,7 @@ TestExitStatus PrintingTests::printTestPage() {
 	}
 
 	// Print ScummVM logo
-	const Graphics::ManagedSurface *logo = g_gui.theme()->getImageSurface("logo.bmp");
+	Common::SharedPtr<Graphics::ManagedSurface> logo = g_gui.theme()->getImageSurface("logo.bmp");
 	if (!logo) {
 		warning("Failed to load the ScummVM logo.");
 		return kTestFailed;
diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h
index beaf13e0ad6..de3f1699a1f 100644
--- a/graphics/VectorRenderer.h
+++ b/graphics/VectorRenderer.h
@@ -50,7 +50,7 @@ typedef void (VectorRenderer::*DrawingFunctionCallback)(const Common::Rect &, co
 
 struct DrawStep {
 	DrawingFunctionCallback drawingCall; /**< Pointer to drawing function */
-	Graphics::ManagedSurface *blitSrc;
+	Common::SharedPtr<Graphics::ManagedSurface> blitSrc;
 	Graphics::AlphaType alphaType;
 
 	struct Color {
@@ -99,7 +99,6 @@ struct DrawStep {
 
 	DrawStep() {
 		drawingCall = nullptr;
-		blitSrc = nullptr;
 		alphaType = Graphics::ALPHA_OPAQUE;
 		// fgColor, bgColor, gradColor1, gradColor2, bevelColor initialized by Color default constructor
 		autoWidth = autoHeight = false;
@@ -474,7 +473,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), step.alphaType);
+		blitManagedSurface(step.blitSrc.get(), Common::Point(x, y), step.alphaType);
 	}
 
 	void drawCallback_CROSS(const Common::Rect &area, const DrawStep &step) {
diff --git a/graphics/thumbnail.cpp b/graphics/thumbnail.cpp
index 393985cff4f..0d173be78e4 100644
--- a/graphics/thumbnail.cpp
+++ b/graphics/thumbnail.cpp
@@ -22,6 +22,7 @@
 #include "graphics/thumbnail.h"
 #include "graphics/scaler.h"
 #include "graphics/pixelformat.h"
+#include "graphics/managed_surface.h"
 #include "common/endian.h"
 #include "common/algorithm.h"
 #include "common/system.h"
@@ -146,7 +147,8 @@ bool skipThumbnail(Common::SeekableReadStream &in) {
 	return true;
 }
 
-bool loadThumbnail(Common::SeekableReadStream &in, Graphics::Surface *&thumbnail, bool skipThumbnail) {
+template<class T>
+bool loadThumbnailImpl(Common::SeekableReadStream &in, T *&thumbnail, bool skipThumbnail) {
 	if (skipThumbnail) {
 		thumbnail = nullptr;
 		return Graphics::skipThumbnail(in);
@@ -175,7 +177,7 @@ bool loadThumbnail(Common::SeekableReadStream &in, Graphics::Surface *&thumbnail
 		return false;
 	}
 
-	thumbnail = new Graphics::Surface();
+	thumbnail = new T();
 	thumbnail->create(header.width, header.height, header.format);
 
 	for (int y = 0; y < thumbnail->h; ++y) {
@@ -201,6 +203,14 @@ bool loadThumbnail(Common::SeekableReadStream &in, Graphics::Surface *&thumbnail
 	return true;
 }
 
+bool loadThumbnail(Common::SeekableReadStream &in, Graphics::Surface *&thumbnail, bool skipThumbnail) {
+	return loadThumbnailImpl(in, thumbnail, skipThumbnail);
+}
+
+bool loadThumbnail(Common::SeekableReadStream &in, Graphics::ManagedSurface *&thumbnail, bool skipThumbnail) {
+	return loadThumbnailImpl(in, thumbnail, skipThumbnail);
+}
+
 bool createThumbnail(Graphics::Surface &thumb) {
 	if (thumb.getPixels())
 		thumb.free();
diff --git a/graphics/thumbnail.h b/graphics/thumbnail.h
index a61088cff73..e35e3423664 100644
--- a/graphics/thumbnail.h
+++ b/graphics/thumbnail.h
@@ -41,6 +41,7 @@ namespace Graphics {
  */
 
 struct Surface;
+class ManagedSurface;
 
 /**
  * Checks for presence of the thumbnail save header.
@@ -62,6 +63,11 @@ bool skipThumbnail(Common::SeekableReadStream &in);
  */
 bool loadThumbnail(Common::SeekableReadStream &in, Graphics::Surface *&thumbnail, bool skipThumbnail = false);
 
+/**
+ * Loads a thumbnail from the given input stream.
+ */
+bool loadThumbnail(Common::SeekableReadStream &in, Graphics::ManagedSurface *&thumbnail, bool skipThumbnail = false);
+
 /**
  * Creates a thumbnail from screen contents.
  */
diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp
index bfb97cdd425..67a2b3c3621 100644
--- a/gui/ThemeEngine.cpp
+++ b/gui/ThemeEngine.cpp
@@ -241,20 +241,10 @@ ThemeEngine::~ThemeEngine() {
 	unloadExtraFont();
 
 	// Release all graphics surfaces
-	for (auto &bitmap : _bitmaps) {
-		Graphics::ManagedSurface *surf = bitmap._value;
-		if (surf) {
-			surf->free();
-			delete surf;
-		}
-	}
 	_bitmaps.clear();
 
 	delete _parser;
 	delete _themeEval;
-	for (int i = 0; i < kCursorMax; i++) {
-        delete[] _cursors[i].data;
-    }
 }
 
 
@@ -379,15 +369,11 @@ void ThemeEngine::refresh() {
 
 	// Flush all bitmaps if the overlay pixel format changed.
 	if (_overlayFormat != _system->getOverlayFormat() || _needScaleRefresh) {
-		for (auto &bitmap : _bitmaps) {
-			Graphics::ManagedSurface *surf = bitmap._value;
-			if (surf) {
-				surf->free();
-				delete surf;
-			}
-		}
 		_bitmaps.clear();
-
+		for (int i = 0; i < kCursorMax; i++) {
+			_cursors[i].surface.reset();
+		}
+		_useCursor = false;
 		_needScaleRefresh = false;
 	}
 
@@ -398,9 +384,12 @@ void ThemeEngine::refresh() {
 
 		if (_useCursor) {
 			CursorData &cur = _cursors[_activeCursorType];
-			if (cur.palSize)
-				CursorMan.replaceCursorPalette(cur.pal, 0, cur.palSize);
-			CursorMan.replaceCursor(cur.data, cur.width, cur.height, cur.hotspotX, cur.hotspotY, cur.transparent, true, &cur.format);
+			if (cur.surface->hasPalette()) {
+				const Graphics::Palette *pal = cur.surface->grabPalette();
+				CursorMan.replaceCursorPalette(pal->data(), 0, pal->size());
+			}
+			CursorMan.replaceCursor(cur.surface->rawSurface(), cur.hotspotX, cur.hotspotY,
+			                        cur.surface->getTransparentColor(), true);
 		}
 	}
 }
@@ -645,7 +634,7 @@ bool ThemeEngine::addTextColor(TextColor colorId, int r, int g, int b) {
 
 bool ThemeEngine::addBitmap(const Common::String &filename, const Common::String &scalablefile, int width, int height) {
 	// Nothing has to be done if the bitmap already has been loaded.
-	Graphics::ManagedSurface *surf = _bitmaps[filename];
+	Common::SharedPtr<Graphics::ManagedSurface> surf = _bitmaps[filename];
 	if (surf) {
 		return true;
 	}
@@ -656,7 +645,7 @@ bool ThemeEngine::addBitmap(const Common::String &filename, const Common::String
 		for (Common::ArchiveMemberList::const_iterator i = members.begin(), end = members.end(); i != end; ++i) {
 			Common::SeekableReadStream *stream = (*i)->createReadStream();
 			if (stream) {
-				_bitmaps[filename] = new Graphics::SVGBitmap(stream, width * _scaleFactor, height * _scaleFactor);
+				_bitmaps[filename].reset(new Graphics::SVGBitmap(stream, width * _scaleFactor, height * _scaleFactor));
 				delete stream;
 				return true;
 			}
@@ -687,7 +676,7 @@ bool ThemeEngine::addBitmap(const Common::String &filename, const Common::String
 		}
 
 		if (srcSurface && srcSurface->format.bytesPerPixel != 1) {
-			surf = new Graphics::ManagedSurface();
+			surf.reset(new Graphics::ManagedSurface());
 			surf->convertFrom(*srcSurface, _overlayFormat);
 		}
 #else
@@ -710,7 +699,7 @@ bool ThemeEngine::addBitmap(const Common::String &filename, const Common::String
 		}
 
 		if (srcSurface && srcSurface->format.bytesPerPixel != 1) {
-			surf = new Graphics::ManagedSurface();
+			surf.reset(new Graphics::ManagedSurface());
 			surf->convertFrom(*srcSurface, _overlayFormat);
 		}
 
@@ -719,16 +708,9 @@ bool ThemeEngine::addBitmap(const Common::String &filename, const Common::String
 	}
 
 	if (_scaleFactor != 1.0 && surf) {
-		Graphics::ManagedSurface *surf2 = surf->scale(surf->w * _scaleFactor, surf->h * _scaleFactor, false);
-
-		if (surf->hasTransparentColor())
-			surf2->setTransparentColor(surf->getTransparentColor());
-
-		surf->free();
-		delete surf;
-
-		surf = surf2;
+		surf.reset(surf->scale(surf->w * _scaleFactor, surf->h * _scaleFactor, false));
 	}
+
 	// Store the surface into our hashmap (attention, may store NULL entries!)
 	_bitmaps[filename] = surf;
 
@@ -1582,7 +1564,7 @@ void ThemeEngine::applyScreenShading(ShadingStyle style) {
 
 bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int hotspotY, CursorType type) {
 	// Try to locate the specified file among all loaded bitmaps
-	const Graphics::ManagedSurface *cursor = _bitmaps[filename];
+	Common::SharedPtr<Graphics::ManagedSurface> cursor = _bitmaps[filename];
 	if (!cursor)
 	    //warning("createCursor: Bitmap '%s' not found in _bitmaps! (type=%d)", filename.c_str(), type);
 		return false;
@@ -1593,25 +1575,9 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int
 	cur.hotspotX = hotspotX;
 	cur.hotspotY = hotspotY;
 
-	cur.width = cursor->w;
-	cur.height = cursor->h;
-
-	cur.transparent = 255;
-	cur.format = Graphics::PixelFormat::createFormatCLUT8();
-	cur.palSize = 0;
-
 	if (_system->hasFeature(OSystem::kFeatureCursorAlpha)) {
-		cur.format = cursor->format;
-		cur.transparent = cur.format.RGBToColor(0xFF, 0, 0xFF);
-
-		// Allocate a new buffer for the cursor
-		delete[] cur.data;
-		cur.data = new byte[cur.width * cur.height * cur.format.bytesPerPixel];
-		assert(cur.data);
-		Graphics::copyBlit(cur.data, (const byte *)cursor->getPixels(),
-		                   cur.width * cur.format.bytesPerPixel, cursor->pitch,
-		                   cur.width, cur.height, cur.format.bytesPerPixel);
-
+		// Use the bitmap as-is
+		cur.surface.reset(cursor);
 		_useCursor = true;
 		return true;
 	}
@@ -1620,35 +1586,27 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int
 		return true;
 
 	// Allocate a new buffer for the cursor
-	delete[] cur.data;
-	cur.data = new byte[cur.width * cur.height];
-	assert(cur.data);
-	memset(cur.data, 0xFF, sizeof(byte) * cur.width * cur.height);
+	Common::SharedPtr<Graphics::ManagedSurface> cursor8(new Graphics::ManagedSurface());
+	cursor8->create(cursor->w, cursor->h, Graphics::PixelFormat::createFormatCLUT8());
+	cursor8->setTransparentColor(0xFF);
+	cursor8->clear(0xFF);
 
 	// the transparent color is 0xFF00FF
-	const uint32 colTransparent = cursor->format.RGBToColor(0xFF, 0, 0xFF);
+	const bool hasTransparent = cursor->hasTransparentColor();
+	const uint32 colTransparent = cursor->getTransparentColor();
 	const uint32 alphaMask = cursor->format.ARGBToColor(0x80, 0, 0, 0);
 
 	// Now, scan the bitmap. We have to convert it from 16 bit color mode
 	// to 8 bit mode, and have to create a suitable palette on the fly.
 	uint colorsFound = 0;
 	Common::HashMap<int, int> colorToIndex;
-	const byte *src = (const byte *)cursor->getPixels();
-	for (uint y = 0; y < cur.height; ++y) {
-		for (uint x = 0; x < cur.width; ++x) {
-			uint32 color = colTransparent;
+	for (int y = 0; y < cursor->h; ++y) {
+		for (int x = 0; x < cursor->w; ++x) {
+			uint32 color = cursor->getPixel(x, y);
 			byte r, g, b;
 
-			if (cursor->format.bytesPerPixel == 2) {
-				color = READ_UINT16(src);
-			} else if (cursor->format.bytesPerPixel == 4) {
-				color = READ_UINT32(src);
-			}
-
-			src += cursor->format.bytesPerPixel;
-
 			// Skip transparency
-			if (color == colTransparent
+			if ((hasTransparent && color == colTransparent)
 			    // Replace with transparent is alpha is present and < 50%
 			    || (alphaMask != 0 && (color & alphaMask) == 0))
 				continue;
@@ -1666,28 +1624,25 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int
 				const int index = colorsFound++;
 				colorToIndex[col] = index;
 
-				cur.pal[index * 3 + 0] = r;
-				cur.pal[index * 3 + 1] = g;
-				cur.pal[index * 3 + 2] = b;
+				byte pal[3] = { r, g, b };
+				cursor8->setPalette(pal, index, 1);
 			}
 
 			// Copy pixel from the 16 bit source surface to the 8bit target surface
 			const int index = colorToIndex[col];
-			cur.data[y * cur.width + x] = index;
+			cursor8->setPixel(x, y, index);
 		}
-
-		src += cursor->pitch - cursor->w * cursor->format.bytesPerPixel;
 	}
 
+	cur.surface.reset(cursor8);
 	_useCursor = true;
-	cur.palSize = colorsFound;
 
 	return true;
 }
 
 void ThemeEngine::setActiveCursor(CursorType type) {
-    if (type < 0 || type >= kCursorMax || !_cursors[type].data) {
-        if (type == kCursorIndex && _cursors[kCursorNormal].data) {
+    if (type < 0 || type >= kCursorMax || !_cursors[type].surface) {
+        if (type == kCursorIndex && _cursors[kCursorNormal].surface) {
         	type = kCursorNormal;  // Fallback to normal cursor
         } else {
             return;
@@ -1698,13 +1653,12 @@ void ThemeEngine::setActiveCursor(CursorType type) {
     
     if (_useCursor) {
         CursorData &cur = _cursors[_activeCursorType];
-		if (cur.palSize) {
-			CursorMan.replaceCursorPalette(cur.pal, 0, cur.palSize);
-		}
-
-        CursorMan.replaceCursor(cur.data, cur.width, cur.height, 
-                                cur.hotspotX, cur.hotspotY, 
-                                cur.transparent, true, &cur.format);
+        if (cur.surface->hasPalette()) {
+            const Graphics::Palette *pal = cur.surface->grabPalette();
+            CursorMan.replaceCursorPalette(pal->data(), 0, pal->size());
+        }
+        CursorMan.replaceCursor(cur.surface->rawSurface(), cur.hotspotX, cur.hotspotY,
+                                cur.surface->getTransparentColor(), true);
     }
 }
 
@@ -2273,19 +2227,20 @@ void ThemeEngine::showCursor() {
 
     CursorData &cur = _cursors[_activeCursorType];
 
-	if (cur.palSize)
-        CursorMan.pushCursorPalette(cur.pal, 0, cur.palSize);
+    if (cur.surface->hasPalette()) {
+        const Graphics::Palette *pal = cur.surface->grabPalette();
+        CursorMan.pushCursorPalette(pal->data(), 0, pal->size());
+    }
 
-    CursorMan.pushCursor(cur.data, cur.width, cur.height, 
-                         cur.hotspotX, cur.hotspotY, 
-                         cur.transparent, true, &cur.format);
+    CursorMan.pushCursor(cur.surface->rawSurface(), cur.hotspotX, cur.hotspotY,
+                         cur.surface->getTransparentColor(), true);
     CursorMan.showMouse(true);
 }
 
 void ThemeEngine::hideCursor() {
 	if (_useCursor) {
 		CursorData &cur = _cursors[_activeCursorType];
-		if (cur.palSize)
+		if (cur.surface->hasPalette())
 			CursorMan.popCursorPalette();
 		CursorMan.popCursor();
 	}
diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h
index eba9e29cf04..3b989eb3a68 100644
--- a/gui/ThemeEngine.h
+++ b/gui/ThemeEngine.h
@@ -208,7 +208,7 @@ private:
 
 class ThemeEngine {
 protected:
-	typedef Common::HashMap<Common::String, Graphics::ManagedSurface *> ImagesMap;
+	typedef Common::HashMap<Common::String, Common::SharedPtr<Graphics::ManagedSurface> > ImagesMap;
 
 	friend class GUI::Dialog;
 	friend class GUI::GuiObject;
@@ -648,15 +648,9 @@ protected:
 	void setGraphicsMode(GraphicsMode mode);
 
 	struct CursorData {
-		byte *data = nullptr;
-		uint width = 0;
-		uint height = 0;
+		Common::SharedPtr<Graphics::ManagedSurface> surface;
 		int hotspotX = 0;
 		int hotspotY = 0;
-		uint32 transparent = 255;
-		Graphics::PixelFormat format;
-		byte palSize = 0;
-		byte pal[3 * 256];
 	};
 
 	CursorData _cursors[kCursorMax];
@@ -670,7 +664,7 @@ public:
 	inline bool supportsImages() const { return true; }
 	inline bool ownCursor() const { return _useCursor; }
 
-	Graphics::ManagedSurface *getImageSurface(const Common::String &name) const {
+	Common::SharedPtr<Graphics::ManagedSurface> getImageSurface(const Common::String &name) const {
 		return _bitmaps.contains(name) ? _bitmaps[name] : 0;
 	}
 
diff --git a/gui/imagealbum-dialog.cpp b/gui/imagealbum-dialog.cpp
index 3f865258a6c..a4dd272f146 100644
--- a/gui/imagealbum-dialog.cpp
+++ b/gui/imagealbum-dialog.cpp
@@ -211,10 +211,10 @@ void ImageAlbumDialog::changeToSlot(uint slot) {
 			if (scaledHeight < 1)
 				scaledHeight = 1;
 
-			Graphics::ManagedSurface rescaledGraphic;
-			rescaledGraphic.create(scaledWidth, scaledHeight, surf->format);
+			Common::SharedPtr<Graphics::ManagedSurface> rescaledGraphic(new Graphics::ManagedSurface());
+			rescaledGraphic->create(scaledWidth, scaledHeight, surf->format);
 			if (hasPalette)
-				rescaledGraphic.setPalette(palette.data(), 0, 256);
+				rescaledGraphic->setPalette(palette.data(), 0, 256);
 
 			if (needs90Rotate) {
 				bool isClockwise = metadata._viewTransformation == kImageAlbumViewTransformationRotate90CW;
@@ -230,7 +230,7 @@ void ImageAlbumDialog::changeToSlot(uint slot) {
 						if (!isClockwise)
 							srcX = imageWidth - 1 - srcX;
 
-						rescaledGraphic.setPixel(destX, destY, surf->getPixel(srcX, srcY));
+						rescaledGraphic->setPixel(destX, destY, surf->getPixel(srcX, srcY));
 					}
 				}
 			} else if (metadata._viewTransformation == kImageAlbumViewTransformationRotate180) {
@@ -240,11 +240,11 @@ void ImageAlbumDialog::changeToSlot(uint slot) {
 					for (uint32 destY = 0; destY < scaledHeight; destY++) {
 						uint32 srcY = (imageHeight - 1 - (destY * imageHeight / scaledHeight));
 
-						rescaledGraphic.setPixel(destX, destY, surf->getPixel(srcX, srcY));
+						rescaledGraphic->setPixel(destX, destY, surf->getPixel(srcX, srcY));
 					}
 				}
 			} else {
-				rescaledGraphic.blitFrom(*surf, Common::Rect(0, 0, imageWidth, imageHeight), Common::Rect(0, 0, scaledWidth, scaledHeight));
+				rescaledGraphic->blitFrom(*surf, Common::Rect(0, 0, imageWidth, imageHeight), Common::Rect(0, 0, scaledWidth, scaledHeight));
 			}
 
 			_imageSupplier->releaseImageSlot(slot);
@@ -254,7 +254,7 @@ void ImageAlbumDialog::changeToSlot(uint slot) {
 
 			_imageGraphic = new GraphicsWidget(_imageContainer, xCoord, yCoord, xCoord + static_cast<int32>(scaledWidth), yCoord + static_cast<int32>(scaledHeight));
 
-			_imageGraphic->setGfx(&rescaledGraphic, false);
+			_imageGraphic->setGfx(rescaledGraphic);
 
 			if (_numSlots > 1) {
 				_imageNumberLabel->setLabel(Common::U32String::format(_("%u of %u"), static_cast<uint>(slot + 1u), _numSlots));
diff --git a/gui/launcher.cpp b/gui/launcher.cpp
index 5adf5b3bc7d..e0b5157e3b0 100644
--- a/gui/launcher.cpp
+++ b/gui/launcher.cpp
@@ -1001,7 +1001,7 @@ ButtonWidget *LauncherDialog::createSwitchButton(const Common::String &name, con
 #ifndef DISABLE_FANCY_THEMES
 	if (g_gui.xmlEval()->getVar("Globals.ShowChooserPics") == 1 && g_gui.theme()->supportsImages()) {
 		button = new PicButtonWidget(this, name, tooltip, cmd);
-		((PicButtonWidget *)button)->setGfxFromTheme(image, kPicButtonStateEnabled, false);
+		((PicButtonWidget *)button)->setGfxFromTheme(image);
 	} else
 #endif
 		button = new ButtonWidget(this, name, desc, tooltip, cmd);
diff --git a/gui/printing-dialog.cpp b/gui/printing-dialog.cpp
index 10c0890e928..bd62c022e1d 100644
--- a/gui/printing-dialog.cpp
+++ b/gui/printing-dialog.cpp
@@ -149,14 +149,14 @@ void PrintingDialog::updatePreview() {
 		// In this mode, there is no "page", just fit the image exactly in the preview area
 		Common::Rect destRect = computePlacementInContainer(_surface.w, _surface.h, previewW, previewH, true, false);
 
-		Graphics::ManagedSurface fittedImage(destRect.width(), destRect.height(), g_gui.theme()->getPixelFormat());
-		fittedImage.blitFrom(_surface, _surface.getBounds(), destRect);
+		Common::SharedPtr<Graphics::ManagedSurface> fittedImage(new Graphics::ManagedSurface(destRect.width(), destRect.height(), g_gui.theme()->getPixelFormat()));
+		fittedImage->blitFrom(_surface, _surface.getBounds(), destRect);
 
 		int16 deltaX = (previewW - destRect.width()) / 2;
 		int16 deltaY = (previewH - destRect.height()) / 2;
 
 		_preview->resize(previewX + deltaX, destRect.top + deltaY, destRect.width(), destRect.height(), false);
-		_preview->setGfx(&fittedImage, false);
+		_preview->setGfx(fittedImage);
 		g_gui.scheduleTopDialogRedraw();
 		return;
 	}
@@ -182,8 +182,8 @@ void PrintingDialog::updatePreview() {
 
 	// Draw a white rectangle representing the page
 	Common::Rect pageInPreviewDims = computePlacementInContainer(paperDim.width(), paperDim.height(), previewW, previewH, true, true);
-	Graphics::ManagedSurface page(pageInPreviewDims.width(), pageInPreviewDims.height(), g_gui.theme()->getPixelFormat());
-	page.fillRect(page.getBounds(), page.format.RGBToColor(255, 255, 255));
+	Common::SharedPtr<Graphics::ManagedSurface> page(new Graphics::ManagedSurface(pageInPreviewDims.width(), pageInPreviewDims.height(), g_gui.theme()->getPixelFormat()));
+	page->fillRect(page->getBounds(), page->format.RGBToColor(255, 255, 255));
 
 	// Blit the image to the page surface, taking into account the printable area offset and the "fit to page" and "center" options.
 	double pageToPreviewScale = (double)pageInPreviewDims.width() / paperDim.width();
@@ -198,14 +198,14 @@ void PrintingDialog::updatePreview() {
 	imageInPagePreview.bottom = (int16)round(imageOnPageDims.bottom * pageToPreviewScale);
 
 	if (!imageInPagePreview.isEmpty())
-		page.blitFrom(_surface, _surface.getBounds(), imageInPagePreview);
+		page->blitFrom(_surface, _surface.getBounds(), imageInPagePreview);
 
 	// Update the preview widget
 	int16 deltaX = (previewW - pageInPreviewDims.width()) / 2;
 	int16 deltaY = (previewH - pageInPreviewDims.height()) / 2;
 
 	_preview->resize(previewX + deltaX, previewY + deltaY, pageInPreviewDims.width(), pageInPreviewDims.height(), false);
-	_preview->setGfx(&page, false);
+	_preview->setGfx(page);
 	g_gui.scheduleTopDialogRedraw();
 }
 
diff --git a/gui/recorderdialog.cpp b/gui/recorderdialog.cpp
index cf20883cb80..611bcc6549b 100644
--- a/gui/recorderdialog.cpp
+++ b/gui/recorderdialog.cpp
@@ -273,7 +273,7 @@ void RecorderDialog::updateList() {
 int RecorderDialog::runModal(Common::String &target) {
 	_target = target;
 	if (_gfxWidget)
-		_gfxWidget->setGfx((Graphics::ManagedSurface *)nullptr);
+		_gfxWidget->clearGfx();
 
 	reflowLayout();
 	updateList();
@@ -345,13 +345,11 @@ void RecorderDialog::updateScreenshot() {
 		_currentScreenshot = 1;
 	}
 
-	Graphics::Surface *srcsf = _playbackFile.getScreenShot(_currentScreenshot);
-	Common::SharedPtr<Graphics::Surface> srcsfSptr = Common::SharedPtr<Graphics::Surface>(srcsf, Graphics::SurfaceDeleter());
-	if (srcsfSptr) {
-		Graphics::Surface *destsf = srcsfSptr->scale(_gfxWidget->getWidth(), _gfxWidget->getHeight());
-		Common::SharedPtr<Graphics::Surface> destsfSptr = Common::SharedPtr<Graphics::Surface>(destsf, Graphics::SurfaceDeleter());
-		if (destsfSptr && _gfxWidget->isVisible())
-			_gfxWidget->setGfx(destsf, false);
+	Common::SharedPtr<Graphics::ManagedSurface> srcsf(_playbackFile.getScreenShot(_currentScreenshot));
+	if (srcsf) {
+		Common::SharedPtr<Graphics::ManagedSurface> destsf(srcsf->scale(_gfxWidget->getWidth(), _gfxWidget->getHeight()));
+		if (destsf && _gfxWidget->isVisible())
+			_gfxWidget->setGfx(destsf);
 	} else {
 		_gfxWidget->setGfx(-1, -1, 0, 0, 0);
 	}
diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp
index bed72781737..abfe10e1a66 100644
--- a/gui/saveload-dialog.cpp
+++ b/gui/saveload-dialog.cpp
@@ -392,7 +392,7 @@ ButtonWidget *SaveLoadChooserDialog::createSwitchButton(const Common::String &na
 #ifndef DISABLE_FANCY_THEMES
 	if (g_gui.xmlEval()->getVar("Globals.ShowChooserPics") == 1 && g_gui.theme()->supportsImages()) {
 		button = new PicButtonWidget(this, name, tooltip, cmd);
-		((PicButtonWidget *)button)->setGfxFromTheme(image, kPicButtonStateEnabled, false);
+		((PicButtonWidget *)button)->setGfxFromTheme(image);
 	} else
 #endif
 		button = new ButtonWidget(this, name, desc, tooltip, cmd);
@@ -478,7 +478,7 @@ void SaveLoadChooserSimple::addThumbnailContainer() {
 
 int SaveLoadChooserSimple::runIntern() {
 	if (_gfxWidget)
-		_gfxWidget->setGfx((Graphics::ManagedSurface *)nullptr);
+		_gfxWidget->clearGfx();
 
 	_resultString.clear();
 	reflowLayout();
@@ -1156,7 +1156,7 @@ void SaveLoadChooserGrid::destroyButtons() {
 
 void SaveLoadChooserGrid::hideButtons() {
 	for (ButtonArray::iterator i = _buttons.begin(), end = _buttons.end(); i != end; ++i) {
-		i->button->setGfx((Graphics::ManagedSurface *)nullptr);
+		i->button->clearGfx();
 		i->setVisible(false);
 	}
 }
diff --git a/gui/widget.cpp b/gui/widget.cpp
index cb639b4fce5..c5f3a116f37 100644
--- a/gui/widget.cpp
+++ b/gui/widget.cpp
@@ -466,7 +466,7 @@ ButtonWidget *addClearButton(GuiObject *boss, const Common::String &name, uint32
 			button = new PicButtonWidget(boss, name, _("Clear value"), cmd);
 		else
 			button = new PicButtonWidget(boss, x, y, w, h, scale, _("Clear value"), cmd);
-		((PicButtonWidget *)button)->setGfxFromTheme(ThemeEngine::kImageEraser, kPicButtonStateEnabled, false);
+		((PicButtonWidget *)button)->setGfxFromTheme(ThemeEngine::kImageEraser);
 	} else
 #endif
 		if (!name.empty())
@@ -605,30 +605,9 @@ void DropdownButtonWidget::drawWidget() {
 
 #pragma mark -
 
-const Graphics::ManagedSurface *scaleGfx(const Graphics::ManagedSurface *gfx, int w, int h, bool filtering) {
-	int nw = w, nh = h;
-
-	// Maintain aspect ratio
-	float xRatio = 1.0f * w / gfx->w;
-	float yRatio = 1.0f * h / gfx->h;
-
-	if (xRatio < yRatio)
-		nh = gfx->h * xRatio;
-	else
-		nw = gfx->w * yRatio;
-
-	if (nw == gfx->w && nh == gfx->h)
-		return gfx;
-
-	w = nw;
-	h = nh;
-
-	return gfx->scale(w, h, filtering);
-}
-
 PicButtonWidget::PicButtonWidget(GuiObject *boss, int x, int y, int w, int h, bool scale, const Common::U32String &tooltip, uint32 cmd, uint8 hotkey)
 	: ButtonWidget(boss, x, y, w, h, scale, Common::U32String(), tooltip, cmd, hotkey),
-	  _showButton(true), _gfx{} {
+	  _showButton(true) {
 	Common::fill(_alphaType, _alphaType + ARRAYSIZE(_alphaType), Graphics::ALPHA_OPAQUE);
 	setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG);
 	_type = kButtonWidget;
@@ -640,21 +619,17 @@ PicButtonWidget::PicButtonWidget(GuiObject *boss, int x, int y, int w, int h, co
 
 PicButtonWidget::PicButtonWidget(GuiObject *boss, const Common::String &name, const Common::U32String &tooltip, uint32 cmd, uint8 hotkey)
 	: ButtonWidget(boss, name, Common::U32String(), tooltip, cmd, hotkey),
-	  _showButton(true), _gfx{} {
+	  _showButton(true) {
 	Common::fill(_alphaType, _alphaType + ARRAYSIZE(_alphaType), Graphics::ALPHA_OPAQUE);
 	setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG);
 	_type = kButtonWidget;
 }
 
 PicButtonWidget::~PicButtonWidget() {
-	for (int i = 0; i < kPicButtonStateMax + 1; i++) {
-		delete _gfx[i];
-	}
 }
 
-void PicButtonWidget::setGfx(const Graphics::ManagedSurface *gfx, int statenum, bool scale) {
-	delete _gfx[statenum];
-	_gfx[statenum] = nullptr;
+void PicButtonWidget::setGfx(Common::SharedPtr<Graphics::ManagedSurface> &gfx, int statenum) {
+	_gfx[statenum].reset();
 
 	if (!gfx || !gfx->getPixels())
 		return;
@@ -663,14 +638,7 @@ void PicButtonWidget::setGfx(const Graphics::ManagedSurface *gfx, int statenum,
 		return;
 
 	_alphaType[statenum] = gfx->detectAlpha();
-
-	float sf = g_gui.getScaleFactor();
-	if (scale && sf != 1.0) {
-		_gfx[statenum] = gfx->scale(gfx->w * sf, gfx->h * sf, false);
-	} else {
-		_gfx[statenum] = new Graphics::ManagedSurface();
-		_gfx[statenum]->copyFrom(*gfx);
-	}
+	_gfx[statenum] = gfx;
 }
 
 void PicButtonWidget::setGfx(const Graphics::Surface *gfx, int statenum, bool scale) {
@@ -679,23 +647,31 @@ void PicButtonWidget::setGfx(const Graphics::Surface *gfx, int statenum, bool sc
 		return;
 	}
 
-	Graphics::ManagedSurface *tmpGfx = new Graphics::ManagedSurface();
-	tmpGfx->copyFrom(*gfx);
-	setGfx(tmpGfx, statenum, scale);
-	delete tmpGfx;
+	Common::SharedPtr<Graphics::ManagedSurface> tmpGfx(new Graphics::ManagedSurface());
+
+	float sf = g_gui.getScaleFactor();
+	if (scale && sf != 1.0) {
+		Graphics::Surface *scaled = gfx->scale(gfx->w * sf, gfx->h * sf, false);
+		tmpGfx->copyFrom(*scaled);
+		scaled->free();
+		delete scaled;
+	} else {
+		tmpGfx->copyFrom(*gfx);
+	}
+
+	setGfx(tmpGfx, statenum);
 }
 
-void PicButtonWidget::setGfxFromTheme(const char *name, int statenum, bool scale) {
-	const Graphics::ManagedSurface *gfx = g_gui.theme()->getImageSurface(name);
+void PicButtonWidget::setGfxFromTheme(const char *name, int statenum) {
+	Common::SharedPtr<Graphics::ManagedSurface> gfx = g_gui.theme()->getImageSurface(name);
 
-	setGfx(gfx, statenum, scale);
+	setGfx(gfx, statenum);
 
 	return;
 }
 
 void PicButtonWidget::setGfx(int w, int h, int r, int g, int b, int statenum) {
-	delete _gfx[statenum];
-	_gfx[statenum] = nullptr;
+	_gfx[statenum].reset();
 
 	if (!isVisible() || !_boss->isVisible())
 		return;
@@ -707,7 +683,7 @@ void PicButtonWidget::setGfx(int w, int h, int r, int g, int b, int statenum) {
 
 	const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat();
 
-	_gfx[statenum] = new Graphics::ManagedSurface();
+	_gfx[statenum].reset(new Graphics::ManagedSurface());
 	_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;
@@ -717,7 +693,7 @@ void PicButtonWidget::drawWidget() {
 	if (_showButton)
 		g_gui.theme()->drawButton(Common::Rect(_x, _y, _x + _w, _y + _h), Common::U32String(), _state, getFlags());
 
-	Graphics::ManagedSurface *gfx;
+	Common::SharedPtr<Graphics::ManagedSurface> gfx;
 	Graphics::AlphaType alphaType;
 
 	if (_state == ThemeEngine::kStateHighlight) {
@@ -960,7 +936,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(nullptr), _alphaType(Graphics::ALPHA_OPAQUE) {
+	: Widget(boss, x, y, w, h, scale, tooltip), _alphaType(Graphics::ALPHA_OPAQUE) {
 	setFlags(WIDGET_ENABLED | WIDGET_CLEARBG);
 	_type = kGraphicsWidget;
 }
@@ -970,18 +946,16 @@ 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(nullptr), _alphaType(Graphics::ALPHA_OPAQUE) {
+	: Widget(boss, name, tooltip), _alphaType(Graphics::ALPHA_OPAQUE) {
 	setFlags(WIDGET_ENABLED | WIDGET_CLEARBG);
 	_type = kGraphicsWidget;
 }
 
 GraphicsWidget::~GraphicsWidget() {
-	delete _gfx;
 }
 
-void GraphicsWidget::setGfx(const Graphics::ManagedSurface *gfx, bool scale) {
-	delete _gfx;
-	_gfx = nullptr;
+void GraphicsWidget::setGfx(Common::SharedPtr<Graphics::ManagedSurface> &gfx) {
+	_gfx.reset();
 
 	if (!gfx || !gfx->getPixels())
 		return;
@@ -989,23 +963,11 @@ void GraphicsWidget::setGfx(const Graphics::ManagedSurface *gfx, bool scale) {
 	if (!isVisible())
 		return;
 
-	float sf = g_gui.getScaleFactor();
-	if (scale && sf != 1.0) {
-		_w = gfx->w * sf;
-		_h = gfx->h * sf;
-	} else {
-		_w = gfx->w;
-		_h = gfx->h;
-	}
+	_w = gfx->w;
+	_h = gfx->h;
 
 	_alphaType = gfx->detectAlpha();
-
-	if ((_w != gfx->w || _h != gfx->h) && _w && _h) {
-		_gfx = gfx->scale(_w, _h, false);
-	} else {
-		_gfx = new Graphics::ManagedSurface();
-		_gfx->copyFrom(*gfx);
-	}
+	_gfx = gfx;
 }
 
 void GraphicsWidget::setGfx(const Graphics::Surface *gfx, bool scale) {
@@ -1014,15 +976,23 @@ void GraphicsWidget::setGfx(const Graphics::Surface *gfx, bool scale) {
 		return;
 	}
 
-	Graphics::ManagedSurface *tmpGfx = new Graphics::ManagedSurface();
-	tmpGfx->copyFrom(*gfx);
-	setGfx(tmpGfx, scale);
-	delete tmpGfx;
+	Common::SharedPtr<Graphics::ManagedSurface> tmpGfx(new Graphics::ManagedSurface());
+
+	float sf = g_gui.getScaleFactor();
+	if (scale && sf != 1.0) {
+		Graphics::Surface *scaled = gfx->scale(gfx->w * sf, gfx->h * sf, false);
+		tmpGfx->copyFrom(*scaled);
+		scaled->free();
+		delete scaled;
+	} else {
+		tmpGfx->copyFrom(*gfx);
+	}
+
+	setGfx(tmpGfx);
 }
 
 void GraphicsWidget::setGfx(int w, int h, int r, int g, int b) {
-	delete _gfx;
-	_gfx = nullptr;
+	_gfx.reset();
 
 	if (!isVisible())
 		return;
@@ -1034,16 +1004,16 @@ void GraphicsWidget::setGfx(int w, int h, int r, int g, int b) {
 
 	const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat();
 
-	_gfx = new Graphics::ManagedSurface();
+	_gfx.reset(new Graphics::ManagedSurface());
 	_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) {
-	const Graphics::ManagedSurface *gfx = g_gui.theme()->getImageSurface(name);
+	Common::SharedPtr<Graphics::ManagedSurface> gfx = g_gui.theme()->getImageSurface(name);
 
-	setGfx(gfx, false);
+	setGfx(gfx);
 }
 
 void GraphicsWidget::drawWidget() {
diff --git a/gui/widget.h b/gui/widget.h
index 4be4d344fba..7f1dd5364f8 100644
--- a/gui/widget.h
+++ b/gui/widget.h
@@ -311,17 +311,18 @@ public:
 	PicButtonWidget(GuiObject *boss, const Common::String &name, const Common::U32String &tooltip = Common::U32String(), uint32 cmd = 0, uint8 hotkey = 0);
 	~PicButtonWidget() override;
 
-	void setGfx(const Graphics::ManagedSurface *gfx, int statenum = kPicButtonStateEnabled, bool scale = true);
+	void setGfx(Common::SharedPtr<Graphics::ManagedSurface> &gfx, int statenum = kPicButtonStateEnabled);
 	void setGfx(const Graphics::Surface *gfx, int statenum = kPicButtonStateEnabled, bool scale = true);
-	void setGfxFromTheme(const char *name, int statenum = kPicButtonStateEnabled, bool scale = true);
+	void setGfxFromTheme(const char *name, int statenum = kPicButtonStateEnabled);
 	void setGfx(int w, int h, int r, int g, int b, int statenum = kPicButtonStateEnabled);
+	void clearGfx(int statenum = kPicButtonStateEnabled) { _gfx[statenum].reset(); }
 
 	void setButtonDisplay(bool enable) {_showButton = enable; }
 
 protected:
 	void drawWidget() override;
 
-	Graphics::ManagedSurface *_gfx[kPicButtonStateMax + 1];
+	Common::SharedPtr<Graphics::ManagedSurface> _gfx[kPicButtonStateMax + 1];
 	Graphics::AlphaType _alphaType[kPicButtonStateMax + 1];
 	bool _showButton;
 };
@@ -449,15 +450,16 @@ public:
 	GraphicsWidget(GuiObject *boss, const Common::String &name, const Common::U32String &tooltip = Common::U32String());
 	~GraphicsWidget() override;
 
-	void setGfx(const Graphics::ManagedSurface *gfx, bool scale = false);
+	void setGfx(Common::SharedPtr<Graphics::ManagedSurface> &gfx);
 	void setGfx(const Graphics::Surface *gfx, bool scale = false);
 	void setGfx(int w, int h, int r, int g, int b);
 	void setGfxFromTheme(const char *name);
+	void clearGfx() { _gfx.reset(); }
 
 protected:
 	void drawWidget() override;
 
-	Graphics::ManagedSurface *_gfx;
+	Common::SharedPtr<Graphics::ManagedSurface> _gfx;
 	Graphics::AlphaType _alphaType;
 };
 
@@ -590,7 +592,6 @@ protected:
 };
 
 ButtonWidget *addClearButton(GuiObject *boss, const Common::String &name, uint32 cmd, int x=0, int y=0, int w=0, int h=0, bool scale = false);
-const Graphics::ManagedSurface *scaleGfx(const Graphics::ManagedSurface *gfx, int w, int h, bool filtering = false);
 
 } // End of namespace GUI
 
diff --git a/gui/widgets/grid.cpp b/gui/widgets/grid.cpp
index ab34f6e94fb..8b8ab8a27a6 100644
--- a/gui/widgets/grid.cpp
+++ b/gui/widgets/grid.cpp
@@ -51,13 +51,9 @@ void GridItemWidget::setActiveEntry(GridItemInfo &entry) {
 }
 
 void GridItemWidget::updateThumb() {
-	const Graphics::ManagedSurface *gfx = _grid->filenameToSurface(_activeEntry->thumbPath);
-	_thumbGfx.free();
-	if (gfx) {
-		// TODO: Use a reference instead of copying the surface
-		_thumbGfx.copyFrom(*gfx);
-		_thumbAlpha = _thumbGfx.detectAlpha();
-	}
+	_thumbGfx = _grid->filenameToSurface(_activeEntry->thumbPath);
+	if (_thumbGfx)
+		_thumbAlpha = _thumbGfx->detectAlpha();
 }
 
 void GridItemWidget::update() {
@@ -117,7 +113,7 @@ void GridItemWidget::drawWidget() {
 										ThemeEngine::kThumbnailBackground);
 
 	// Draw Thumbnail
-	if (_thumbGfx.empty()) {
+	if (!_thumbGfx) {
 		// Draw Title when thumbnail is missing
 		int linesInThumb = MIN(thumbHeight / kLineHeight, (int)titleLines.size());
 		Common::Rect r(_x, _y + (thumbHeight - linesInThumb * kLineHeight) / 2,
@@ -130,20 +126,20 @@ void GridItemWidget::drawWidget() {
 			r.translate(0, kLineHeight);
 		}
 	} else {
-		g_gui.theme()->drawManagedSurface(Common::Point(_x + _grid->_thumbnailMargin, _y + _grid->_thumbnailMargin), _thumbGfx, _thumbAlpha);
+		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, alphaType);
+	Common::SharedPtr<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, alphaType);
 	}
 
 	// Draw Flag
-	const Graphics::ManagedSurface *flagGfx = _grid->languageToSurface(_activeEntry->language, alphaType);
+	Common::SharedPtr<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
@@ -152,7 +148,7 @@ void GridItemWidget::drawWidget() {
 	}
 
 	// Draw Demo Overlay
-	const Graphics::ManagedSurface *demoGfx = _grid->demoToSurface(_activeEntry->extra, alphaType);
+	Common::SharedPtr<Graphics::ManagedSurface> demoGfx = _grid->demoToSurface(_activeEntry->extra, alphaType);
 	if (demoGfx) {
 		Common::Point p(_x, _y);
 		g_gui.theme()->drawManagedSurface(p, *demoGfx, alphaType);
@@ -162,7 +158,7 @@ void GridItemWidget::drawWidget() {
 
 	// Darken thumbnail if path is unreachable
 	if (!validEntry) {
-		const Graphics::ManagedSurface *darkenGfx = _grid->disabledThumbnail();
+		Common::SharedPtr<Graphics::ManagedSurface> darkenGfx = _grid->disabledThumbnail();
 		if (darkenGfx) {
 			Common::Point p(_x, _y);
 			g_gui.theme()->drawManagedSurface(p, *darkenGfx, Graphics::ALPHA_FULL);
@@ -341,9 +337,9 @@ GridItemTray::GridItemTray(GuiObject *boss, int x, int y, int w, int h, int entr
 }
 
 void GridItemTray::reflowLayout() {
-	_playButton->setGfxFromTheme("button_play.bmp", 0, false);
-	_loadButton->setGfxFromTheme("button_load.bmp", 0, false);
-	_editButton->setGfxFromTheme("button_options.bmp", 0, false);
+	_playButton->setGfxFromTheme("button_play.bmp");
+	_loadButton->setGfxFromTheme("button_load.bmp");
+	_editButton->setGfxFromTheme("button_options.bmp");
 }
 
 void GridItemTray::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
@@ -402,9 +398,9 @@ void GridItemTray::handleMouseMoved(int x, int y, int button) {
 
 // Load an image file by String name, provide additional render dimensions for SVG images.
 // TODO: Add BMP support, and add scaling of non-vector images.
-Graphics::ManagedSurface *loadSurfaceFromFile(const Common::String &name, int renderWidth = 0, int renderHeight = 0) {
+Common::SharedPtr<Graphics::ManagedSurface> loadSurfaceFromFile(const Common::String &name, int renderWidth = 0, int renderHeight = 0) {
 	Common::Path path(name);
-	Graphics::ManagedSurface *surf = nullptr;
+	Common::SharedPtr<Graphics::ManagedSurface> surf;
 	if (name.hasSuffix(".png")) {
 #ifdef USE_PNG
 		const Graphics::Surface *srcSurface = nullptr;
@@ -423,7 +419,7 @@ Graphics::ManagedSurface *loadSurfaceFromFile(const Common::String &name, int re
 			if (!srcSurface) {
 				warning("Failed to load surface : %s", name.c_str());
 			} else if (srcSurface->format.bytesPerPixel != 1) {
-				surf = new Graphics::ManagedSurface();
+				surf.reset(new Graphics::ManagedSurface());
 				surf->copyFrom(*srcSurface);
 			}
 		} else {
@@ -437,7 +433,7 @@ Graphics::ManagedSurface *loadSurfaceFromFile(const Common::String &name, int re
 		g_gui.lockIconsSet();
 		if (g_gui.getIconsSet().hasFile(path)) {
 			Common::SeekableReadStream *stream = g_gui.getIconsSet().createReadStreamForMember(path);
-			surf = new Graphics::SVGBitmap(stream, renderWidth, renderHeight);
+			surf.reset(new Graphics::SVGBitmap(stream, renderWidth, renderHeight));
 			delete stream;
 		} else {
 			debug(5, "GridWidget: Cannot read file '%s'", name.c_str());
@@ -447,6 +443,27 @@ Graphics::ManagedSurface *loadSurfaceFromFile(const Common::String &name, int re
 	return surf;
 }
 
+Common::SharedPtr<Graphics::ManagedSurface> scaleGfx(Common::SharedPtr<Graphics::ManagedSurface> &gfx, int w, int h, bool filtering) {
+	int nw = w, nh = h;
+
+	// Maintain aspect ratio
+	float xRatio = 1.0f * w / gfx->w;
+	float yRatio = 1.0f * h / gfx->h;
+
+	if (xRatio < yRatio)
+		nh = gfx->h * xRatio;
+	else
+		nw = gfx->w * yRatio;
+
+	if (nw == gfx->w && nh == gfx->h)
+		return gfx;
+
+	w = nw;
+	h = nh;
+
+	return Common::SharedPtr<Graphics::ManagedSurface>(gfx->scale(w, h, filtering));
+}
+
 #pragma mark -
 
 GridWidget::GridWidget(GuiObject *boss, const Common::String &name)
@@ -460,7 +477,6 @@ GridWidget::GridWidget(GuiObject *boss, const Common::String &name)
 	_platformIconWidth = 0;
 	_extraIconHeight = 0;
 	_extraIconWidth = 0;
-	_disabledIconOverlay = nullptr;
 
 	_minGridXSpacing = 0;
 	_minGridYSpacing = 0;
@@ -503,11 +519,11 @@ GridWidget::GridWidget(GuiObject *boss, const Common::String &name)
 }
 
 GridWidget::~GridWidget() {
-	unloadSurfaces(_platformIcons);
-	unloadSurfaces(_languageIcons);
-	unloadSurfaces(_extraIcons);
-	unloadSurfaces(_loadedSurfaces);
-	delete _disabledIconOverlay;
+	_platformIcons.clear();
+	_languageIcons.clear();
+	_extraIcons.clear();
+	_loadedSurfaces.clear();
+	_disabledIconOverlay.reset();
 	_gridItems.clear();
 	_dataEntryList.clear();
 	_headerEntryList.clear();
@@ -518,42 +534,34 @@ GridWidget::~GridWidget() {
 	_extraIconsAlpha.clear();
 }
 
-template<typename T>
-void GridWidget::unloadSurfaces(Common::HashMap<T, const Graphics::ManagedSurface *> &surfaces) {
-	for (typename Common::HashMap<T, const Graphics::ManagedSurface *>::iterator i = surfaces.begin(); i != surfaces.end(); ++i) {
-		delete i->_value;
-	}
-	surfaces.clear();
-}
-
-const Graphics::ManagedSurface *GridWidget::filenameToSurface(const Common::String &name) {
+Common::SharedPtr<Graphics::ManagedSurface> GridWidget::filenameToSurface(const Common::String &name) {
 	if (name.empty())
 		return nullptr;
 	return _loadedSurfaces[name];
 }
 
-const Graphics::ManagedSurface *GridWidget::languageToSurface(Common::Language languageCode, Graphics::AlphaType &alphaType) {
+Common::SharedPtr<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, Graphics::AlphaType &alphaType) {
+Common::SharedPtr<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, Graphics::AlphaType &alphaType) {
+Common::SharedPtr<Graphics::ManagedSurface> GridWidget::demoToSurface(const Common::String &extraString, Graphics::AlphaType &alphaType) {
 	if (! extraString.contains("Demo") )
 		return nullptr;
 	alphaType = _extraIconsAlpha[0];
 	return _extraIcons[0];
 }
 
-const Graphics::ManagedSurface *GridWidget::disabledThumbnail() {
+Common::SharedPtr<Graphics::ManagedSurface> GridWidget::disabledThumbnail() {
 	return _disabledIconOverlay;
 }
 
@@ -763,36 +771,24 @@ void GridWidget::reloadThumbnails() {
 			continue;
 
 		if (!_loadedSurfaces.contains(entry->thumbPath)) {
-			_loadedSurfaces[entry->thumbPath] = nullptr;
+			_loadedSurfaces[entry->thumbPath].reset();
 			Common::String path = Common::String::format("icons/%s-%s.png", entry->engineid.c_str(), entry->gameid.c_str());
-			Graphics::ManagedSurface *surf = loadSurfaceFromFile(path);
+			Common::SharedPtr<Graphics::ManagedSurface> surf = loadSurfaceFromFile(path);
 			if (!surf) {
 				path = Common::String::format("icons/%s.png", entry->engineid.c_str());
 				if (!_loadedSurfaces.contains(path)) {
 					surf = loadSurfaceFromFile(path);
 				} else {
-					const Graphics::ManagedSurface *scSurf = _loadedSurfaces[path];
-					// TODO: Use SharedPtr instead of duplicating the surface
-					Graphics::ManagedSurface *thSurf = new Graphics::ManagedSurface();
-					thSurf->copyFrom(*scSurf);
-					_loadedSurfaces[entry->thumbPath] = thSurf;
+					_loadedSurfaces[entry->thumbPath] = _loadedSurfaces[path];
 				}
 			}
 
 			if (surf) {
-				const Graphics::ManagedSurface *scSurf(scaleGfx(surf, thumbnailWidth, thumbnailHeight, true));
+				Common::SharedPtr<Graphics::ManagedSurface> scSurf = scaleGfx(surf, thumbnailWidth, thumbnailHeight, true);
 				_loadedSurfaces[entry->thumbPath] = scSurf;
 
 				if (path != entry->thumbPath) {
-					// TODO: Use SharedPtr instead of duplicating the surface
-					Graphics::ManagedSurface *thSurf = new Graphics::ManagedSurface();
-					thSurf->copyFrom(*scSurf);
-					_loadedSurfaces[path] = thSurf;
-				}
-
-				if (surf != scSurf) {
-					surf->free();
-					delete surf;
+					_loadedSurfaces[path] = scSurf;
 				}
 			}
 		}
@@ -803,7 +799,7 @@ void GridWidget::loadFlagIcons() {
 	const Common::LanguageDescription *l = Common::g_languages;
 	for (; l->code; ++l) {
 		Common::String path = Common::String::format("icons/flags/%s.svg", l->code);
-		Graphics::ManagedSurface *gfx = loadSurfaceFromFile(path, _flagIconWidth, _flagIconHeight);
+		Common::SharedPtr<Graphics::ManagedSurface> gfx = loadSurfaceFromFile(path, _flagIconWidth, _flagIconHeight);
 		if (gfx) {
 			_languageIcons[l->id] = gfx;
 			_languageIconsAlpha[l->id] = gfx->detectAlpha();
@@ -812,15 +808,11 @@ void GridWidget::loadFlagIcons() {
 		path = Common::String::format("icons/flags/%s.png", l->code);
 		gfx = loadSurfaceFromFile(path);
 		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;
-			}
+			Common::SharedPtr<Graphics::ManagedSurface> scSurf = scaleGfx(gfx, _flagIconWidth, _flagIconHeight, true);
+			_languageIcons[l->id] = scSurf;
+			_languageIconsAlpha[l->id] = scSurf->detectAlpha();
 		} else {
-			_languageIcons[l->id] = nullptr; // nothing found, set to nullptr
+			_languageIcons[l->id].reset(); // nothing found
 		}
 	}
 }
@@ -829,39 +821,31 @@ void GridWidget::loadPlatformIcons() {
 	const Common::PlatformDescription *l = Common::g_platforms;
 	for (; l->code; ++l) {
 		Common::String path = Common::String::format("icons/platforms/%s.png", l->code);
-		Graphics::ManagedSurface *gfx = loadSurfaceFromFile(path);
+		Common::SharedPtr<Graphics::ManagedSurface> gfx = loadSurfaceFromFile(path);
 		if (gfx) {
-			const Graphics::ManagedSurface *scGfx = scaleGfx(gfx, _platformIconWidth, _platformIconHeight, true);
+			Common::SharedPtr<Graphics::ManagedSurface> scGfx = scaleGfx(gfx, _platformIconWidth, _platformIconHeight, true);
 			_platformIcons[l->id] = scGfx;
 			_platformIconsAlpha[l->id] = scGfx->detectAlpha();
-			if (gfx != scGfx) {
-				gfx->free();
-				delete gfx;
-			}
 		} else {
-			_platformIcons[l->id] = nullptr;
+			_platformIcons[l->id].reset();
 		}
 	}
 }
 
 void GridWidget::loadExtraIcons() {  // for now only the demo icon is available
-	Graphics::ManagedSurface *gfx = loadSurfaceFromFile("icons/extra/demo.svg", _extraIconWidth, _extraIconHeight);
+	Common::SharedPtr<Graphics::ManagedSurface> gfx = loadSurfaceFromFile("icons/extra/demo.svg", _extraIconWidth, _extraIconHeight);
 	if (gfx) {
-		_extraIcons[0] = gfx;
+		_extraIcons[0].reset(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);
+		Common::SharedPtr<Graphics::ManagedSurface> scGfx = scaleGfx(gfx, _extraIconWidth, _extraIconHeight, true);
 		_extraIcons[0] = scGfx;
 		_extraIconsAlpha[0] = scGfx->detectAlpha();
-		if (gfx != scGfx) {
-			gfx->free();
-			delete gfx;
-		}
 	} else {
-		_extraIcons[0] = nullptr;
+		_extraIcons[0].reset();
 	}
 }
 
@@ -1166,20 +1150,20 @@ void GridWidget::reflowLayout() {
 	if ((oldThumbnailHeight != _thumbnailHeight) ||
 		(oldThumbnailWidth != _thumbnailWidth) ||
 		(oldThumbnailMargin != _thumbnailMargin)) {
-		unloadSurfaces(_extraIcons);
-		unloadSurfaces(_platformIcons);
-		unloadSurfaces(_languageIcons);
-		unloadSurfaces(_loadedSurfaces);
+		_extraIcons.clear();
+		_platformIcons.clear();
+		_languageIcons.clear();
+		_loadedSurfaces.clear();
 		_platformIconsAlpha.clear();
 		_languageIconsAlpha.clear();
 		_extraIconsAlpha.clear();
-		delete _disabledIconOverlay;
+		_disabledIconOverlay.reset();
 		reloadThumbnails();
 		loadFlagIcons();
 		loadPlatformIcons();
 		loadExtraIcons();
 
-		Graphics::ManagedSurface *gfx = new Graphics::ManagedSurface(_thumbnailWidth, _thumbnailHeight, g_system->getOverlayFormat());
+		Common::SharedPtr<Graphics::ManagedSurface> gfx(new Graphics::ManagedSurface(_thumbnailWidth, _thumbnailHeight, g_system->getOverlayFormat()));
 		uint32 disabledThumbnailColor = gfx->format.ARGBToColor(153, 0, 0, 0);  // 60% opacity black
 		gfx->fillRect(Common::Rect(0, 0, _thumbnailWidth, _thumbnailHeight), disabledThumbnailColor);
 		_disabledIconOverlay = gfx;
diff --git a/gui/widgets/grid.h b/gui/widgets/grid.h
index fd0c81b785a..7dd709ebdcb 100644
--- a/gui/widgets/grid.h
+++ b/gui/widgets/grid.h
@@ -104,15 +104,15 @@ public:
 	typedef bool (*FilterMatcher)(void *arg, int idx, const Common::U32String &item, const Common::U32String &token);
 
 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, Common::SharedPtr<Graphics::ManagedSurface> > _platformIcons;
+	Common::HashMap<int, Common::SharedPtr<Graphics::ManagedSurface> > _languageIcons;
+	Common::HashMap<int, Common::SharedPtr<Graphics::ManagedSurface> > _extraIcons;
 	Common::HashMap<int, Graphics::AlphaType> _platformIconsAlpha;
 	Common::HashMap<int, Graphics::AlphaType> _languageIconsAlpha;
 	Common::HashMap<int, Graphics::AlphaType> _extraIconsAlpha;
-	Graphics::ManagedSurface *_disabledIconOverlay;
+	Common::SharedPtr<Graphics::ManagedSurface> _disabledIconOverlay;
 	// Images are mapped by filename -> surface.
-	Common::HashMap<Common::String, const Graphics::ManagedSurface *> _loadedSurfaces;
+	Common::HashMap<Common::String, Common::SharedPtr<Graphics::ManagedSurface> > _loadedSurfaces;
 
 	Common::Array<GridItemInfo>			_dataEntryList;
 	Common::Array<GridItemInfo>			_headerEntryList;
@@ -182,14 +182,11 @@ public:
 	GridWidget(GuiObject *boss, const Common::String &name);
 	~GridWidget();
 
-	template<typename T>
-	void unloadSurfaces(Common::HashMap<T, const Graphics::ManagedSurface *> &surfaces);
-
-	const Graphics::ManagedSurface *filenameToSurface(const Common::String &name);
-	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();
+	Common::SharedPtr<Graphics::ManagedSurface> filenameToSurface(const Common::String &name);
+	Common::SharedPtr<Graphics::ManagedSurface> languageToSurface(Common::Language languageCode, Graphics::AlphaType &alphaType);
+	Common::SharedPtr<Graphics::ManagedSurface> platformToSurface(Common::Platform platformCode, Graphics::AlphaType &alphaType);
+	Common::SharedPtr<Graphics::ManagedSurface> demoToSurface(const Common::String &extraString, Graphics::AlphaType &alphaType);
+	Common::SharedPtr<Graphics::ManagedSurface> disabledThumbnail();
 
 	/// Update _visibleEntries from _allEntries and returns true if reload is required.
 	bool calcVisibleEntries();
@@ -258,7 +255,7 @@ public:
 /* GridItemWidget */
 class GridItemWidget : public ContainerWidget, public CommandSender {
 protected:
-	Graphics::ManagedSurface _thumbGfx;
+	Common::SharedPtr<Graphics::ManagedSurface> _thumbGfx;
 	Graphics::AlphaType _thumbAlpha;
 
 	GridItemInfo	*_activeEntry;


Commit: 583ebb114726c60900ca2339aaa9e564a1b7215a
    https://github.com/scummvm/scummvm/commit/583ebb114726c60900ca2339aaa9e564a1b7215a
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2026-04-14T18:46:14+03:00

Commit Message:
GRAPHICS: Always use simpleBlitFrom in VectorRendererSpec

Changed paths:
    graphics/VectorRendererSpec.cpp


diff --git a/graphics/VectorRendererSpec.cpp b/graphics/VectorRendererSpec.cpp
index 2ff494ce14b..bbdcbe585fe 100644
--- a/graphics/VectorRendererSpec.cpp
+++ b/graphics/VectorRendererSpec.cpp
@@ -803,11 +803,7 @@ blitManagedSurface(const Graphics::ManagedSurface *source, const Common::Point &
 		np = p;
 	}
 
-	if (alphaType != Graphics::ALPHA_OPAQUE) {
-		_activeSurface->transBlitFrom(*source, drawRect, np);
-	} else {
-		_activeSurface->simpleBlitFrom(*source, drawRect, np);
-	}
+	_activeSurface->simpleBlitFrom(*source, drawRect, np, Graphics::FLIP_NONE, alphaType != Graphics::ALPHA_OPAQUE);
 }
 
 template<typename PixelType>




More information about the Scummvm-git-logs mailing list