diff options
Diffstat (limited to 'gui/ThemeEngine.cpp')
-rw-r--r-- | gui/ThemeEngine.cpp | 185 |
1 files changed, 165 insertions, 20 deletions
diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index c850a6a02e..96108bccce 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -31,11 +31,13 @@ #include "graphics/cursorman.h" #include "graphics/fontman.h" #include "graphics/surface.h" +#include "graphics/transparent_surface.h" #include "graphics/VectorRenderer.h" #include "graphics/fonts/bdf.h" #include "graphics/fonts/ttf.h" #include "image/bmp.h" +#include "image/png.h" #include "gui/widget.h" #include "gui/ThemeEngine.h" @@ -59,6 +61,10 @@ const char *const ThemeEngine::kImageStopSmallButton = "stopbtn_small.bmp"; const char *const ThemeEngine::kImageEditSmallButton = "editbtn_small.bmp"; const char *const ThemeEngine::kImageSwitchModeSmallButton = "switchbtn_small.bmp"; const char *const ThemeEngine::kImageFastReplaySmallButton = "fastreplay_small.bmp"; +const char *const ThemeEngine::kImageDropboxLogo = "dropbox.bmp"; +const char *const ThemeEngine::kImageOneDriveLogo = "onedrive.bmp"; +const char *const ThemeEngine::kImageGoogleDriveLogo = "googledrive.bmp"; +const char *const ThemeEngine::kImageBoxLogo = "box.bmp"; struct TextDrawData { const Graphics::Font *_fontPtr; @@ -168,11 +174,23 @@ protected: bool _alpha; }; +class ThemeItemABitmap : public ThemeItem { +public: + ThemeItemABitmap(ThemeEngine *engine, const Common::Rect &area, Graphics::TransparentSurface *bitmap, ThemeEngine::AutoScaleMode autoscale, int alpha) : + ThemeItem(engine, area), _bitmap(bitmap), _autoscale(autoscale), _alpha(alpha) {} + + void drawSelf(bool draw, bool restore); + +protected: + Graphics::TransparentSurface *_bitmap; + ThemeEngine::AutoScaleMode _autoscale; + int _alpha; +}; + class ThemeItemBitmapClip : public ThemeItem { public: ThemeItemBitmapClip(ThemeEngine *engine, const Common::Rect &area, const Common::Rect &clip, const Graphics::Surface *bitmap, bool alpha) : ThemeItem(engine, area), _bitmap(bitmap), _alpha(alpha), _clip(clip) {} - void drawSelf(bool draw, bool restore); protected: @@ -308,7 +326,7 @@ void ThemeItemBitmap::drawSelf(bool draw, bool restore) { if (draw) { if (_alpha) - _engine->renderer()->blitAlphaBitmap(_bitmap, _area); + _engine->renderer()->blitKeyBitmap(_bitmap, _area); else _engine->renderer()->blitSubSurface(_bitmap, _area); } @@ -316,13 +334,23 @@ void ThemeItemBitmap::drawSelf(bool draw, bool restore) { _engine->addDirtyRect(_area); } -void ThemeItemBitmapClip::drawSelf(bool draw, bool restore) { +void ThemeItemABitmap::drawSelf(bool draw, bool restore) { if (restore) _engine->restoreBackground(_area); + if (draw) + _engine->renderer()->blitAlphaBitmap(_bitmap, _area, _autoscale, Graphics::DrawStep::kVectorAlignManual, Graphics::DrawStep::kVectorAlignManual, _alpha); + + _engine->addDirtyRect(_area); +} + +void ThemeItemBitmapClip::drawSelf(bool draw, bool restore) { + if (restore) + _engine->restoreBackground(_area); + if (draw) { if (_alpha) - _engine->renderer()->blitAlphaBitmapClip(_bitmap, _area, _clip); + _engine->renderer()->blitKeyBitmapClip(_bitmap, _area, _clip); else _engine->renderer()->blitSubSurfaceClip(_bitmap, _area, _clip); } @@ -401,6 +429,15 @@ ThemeEngine::~ThemeEngine() { } _bitmaps.clear(); + for (AImagesMap::iterator i = _abitmaps.begin(); i != _abitmaps.end(); ++i) { + Graphics::TransparentSurface *surf = i->_value; + if (surf) { + surf->free(); + delete surf; + } + } + _abitmaps.clear(); + delete _parser; delete _themeEval; delete[] _cursor; @@ -525,6 +562,15 @@ void ThemeEngine::refresh() { } } _bitmaps.clear(); + + for (AImagesMap::iterator i = _abitmaps.begin(); i != _abitmaps.end(); ++i) { + Graphics::TransparentSurface *surf = i->_value; + if (surf) { + surf->free(); + delete surf; + } + } + _abitmaps.clear(); } init(); @@ -706,24 +752,51 @@ bool ThemeEngine::addBitmap(const Common::String &filename) { if (surf) return true; - // If not, try to load the bitmap via the BitmapDecoder class. - Image::BitmapDecoder bitmapDecoder; const Graphics::Surface *srcSurface = 0; - Common::ArchiveMemberList members; - _themeFiles.listMatchingMembers(members, filename); - for (Common::ArchiveMemberList::const_iterator i = members.begin(), end = members.end(); i != end; ++i) { - Common::SeekableReadStream *stream = (*i)->createReadStream(); - if (stream) { - bitmapDecoder.loadStream(*stream); - srcSurface = bitmapDecoder.getSurface(); - delete stream; - if (srcSurface) - break; + + if (filename.hasSuffix(".png")) { + // Maybe it is PNG? +#ifdef USE_PNG + Image::PNGDecoder decoder; + Common::ArchiveMemberList members; + _themeFiles.listMatchingMembers(members, filename); + for (Common::ArchiveMemberList::const_iterator i = members.begin(), end = members.end(); i != end; ++i) { + Common::SeekableReadStream *stream = (*i)->createReadStream(); + if (stream) { + if (!decoder.loadStream(*stream)) + error("Error decoding PNG"); + + srcSurface = decoder.getSurface(); + delete stream; + if (srcSurface) + break; + } } - } - if (srcSurface && srcSurface->format.bytesPerPixel != 1) - surf = srcSurface->convertTo(_overlayFormat); + if (srcSurface && srcSurface->format.bytesPerPixel != 1) + surf = srcSurface->convertTo(_overlayFormat); +#else + error("No PNG support compiled in"); +#endif + } else { + // If not, try to load the bitmap via the BitmapDecoder class. + Image::BitmapDecoder bitmapDecoder; + Common::ArchiveMemberList members; + _themeFiles.listMatchingMembers(members, filename); + for (Common::ArchiveMemberList::const_iterator i = members.begin(), end = members.end(); i != end; ++i) { + Common::SeekableReadStream *stream = (*i)->createReadStream(); + if (stream) { + bitmapDecoder.loadStream(*stream); + srcSurface = bitmapDecoder.getSurface(); + delete stream; + if (srcSurface) + break; + } + } + + if (srcSurface && srcSurface->format.bytesPerPixel != 1) + surf = srcSurface->convertTo(_overlayFormat); + } // Store the surface into our hashmap (attention, may store NULL entries!) _bitmaps[filename] = surf; @@ -731,6 +804,48 @@ bool ThemeEngine::addBitmap(const Common::String &filename) { return surf != 0; } +bool ThemeEngine::addAlphaBitmap(const Common::String &filename) { + // Nothing has to be done if the bitmap already has been loaded. + Graphics::TransparentSurface *surf = _abitmaps[filename]; + if (surf) + return true; + + const Graphics::TransparentSurface *srcSurface = 0; + + if (filename.hasSuffix(".png")) { + // Maybe it is PNG? +#ifdef USE_PNG + Image::PNGDecoder decoder; + Common::ArchiveMemberList members; + _themeFiles.listMatchingMembers(members, filename); + for (Common::ArchiveMemberList::const_iterator i = members.begin(), end = members.end(); i != end; ++i) { + Common::SeekableReadStream *stream = (*i)->createReadStream(); + if (stream) { + if (!decoder.loadStream(*stream)) + error("Error decoding PNG"); + + srcSurface = new Graphics::TransparentSurface(*decoder.getSurface(), true); + delete stream; + if (srcSurface) + break; + } + } + + if (srcSurface && srcSurface->format.bytesPerPixel != 1) + surf = srcSurface->convertTo(_overlayFormat); +#else + error("No PNG support compiled in"); +#endif + } else { + error("Only PNG is supported as alphabitmap"); + } + + // Store the surface into our hashmap (attention, may store NULL entries!) + _abitmaps[filename] = surf; + + return surf != 0; +} + bool ThemeEngine::addDrawData(const Common::String &data, bool cached) { DrawData id = parseDrawDataId(data); @@ -977,7 +1092,10 @@ void ThemeEngine::queueDDTextClip(TextData type, TextColor color, const Common:: area.clip(_screen.w, _screen.h); Common::Rect textArea = drawableTextArea; if (textArea.isEmpty()) textArea = clippingArea; - else textArea.clip(clippingArea); + else { + textArea.clip(clippingArea); + if (textArea.isEmpty()) textArea = Common::Rect(0, 0, 1, 1); // one small pixel should be invisible enough + } ThemeItemTextData *q = new ThemeItemTextData(this, _texts[type], _textColors[color], area, textArea, text, alignH, alignV, ellipsis, restoreBg, deltax); @@ -1004,6 +1122,21 @@ void ThemeEngine::queueBitmap(const Graphics::Surface *bitmap, const Common::Rec } } +void ThemeEngine::queueABitmap(Graphics::TransparentSurface *bitmap, const Common::Rect &r, AutoScaleMode autoscale, int alpha) { + + Common::Rect area = r; + area.clip(_screen.w, _screen.h); + + ThemeItemABitmap *q = new ThemeItemABitmap(this, area, bitmap, autoscale, alpha); + + if (_buffering) { + _screenQueue.push_back(q); + } else { + q->drawSelf(true, false); + delete q; + } +} + void ThemeEngine::queueBitmapClip(const Graphics::Surface *bitmap, const Common::Rect &r, const Common::Rect &clip, bool alpha) { Common::Rect area = r; @@ -1291,6 +1424,8 @@ void ThemeEngine::drawDialogBackground(const Common::Rect &r, DialogBackground b case kDialogBackgroundDefault: queueDD(kDDDefaultBackground, r); break; + case kDialogBackgroundNone: + break; } } @@ -1318,6 +1453,9 @@ void ThemeEngine::drawDialogBackgroundClip(const Common::Rect &r, const Common:: case kDialogBackgroundDefault: queueDDClip(kDDDefaultBackground, r, clip); break; + case kDialogBackgroundNone: + // no op + break; } } @@ -1392,6 +1530,13 @@ void ThemeEngine::drawSurface(const Common::Rect &r, const Graphics::Surface &su queueBitmap(&surface, r, themeTrans); } +void ThemeEngine::drawASurface(const Common::Rect &r, Graphics::TransparentSurface &surface, AutoScaleMode autoscale, int alpha) { + if (!ready()) + return; + + queueABitmap(&surface, r, autoscale, alpha); +} + void ThemeEngine::drawSurfaceClip(const Common::Rect &r, const Common::Rect &clip, const Graphics::Surface &surface, WidgetStateInfo state, int alpha, bool themeTrans) { if (!ready()) return; |