GUI: Use Common::SharedPtr for reusing surfaces

This commit is contained in:
Cameron Cawley
2026-04-09 20:10:06 +01:00
committed by Filippos Karapetis
parent 70050f9d0c
commit 8a01c2a0b0
17 changed files with 248 additions and 326 deletions
+8 -4
View File
@@ -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();
+7 -3
View File
@@ -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
+1 -1
View File
@@ -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;
+2 -3
View File
@@ -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) {
+12 -2
View File
@@ -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();
+6
View File
@@ -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.
*/
+48 -93
View File
@@ -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();
}
+3 -9
View File
@@ -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;
}
+7 -7
View File
@@ -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));
+1 -1
View File
@@ -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);
+7 -7
View File
@@ -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();
}
+6 -8
View File
@@ -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);
}
+3 -3
View File
@@ -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);
}
}
+49 -79
View File
@@ -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() {
+7 -6
View File
@@ -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
+70 -86
View File
@@ -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;
+11 -14
View File
@@ -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;