diff options
author | Eugene Sandulenko | 2014-05-02 23:36:03 +0300 |
---|---|---|
committer | Alexander Tkachev | 2016-08-24 16:07:55 +0600 |
commit | 53a42ececfff48b93cef414bc2762806786da8d5 (patch) | |
tree | 5e48090f4a3db077562b5223a1d2001ed087f4bd | |
parent | 762671ccd841c5f54e4cf241a5372c26210b5865 (diff) | |
download | scummvm-rg350-53a42ececfff48b93cef414bc2762806786da8d5.tar.gz scummvm-rg350-53a42ececfff48b93cef414bc2762806786da8d5.tar.bz2 scummvm-rg350-53a42ececfff48b93cef414bc2762806786da8d5.zip |
GUI: Added new alphabitmap image type
-rw-r--r-- | graphics/VectorRenderer.h | 16 | ||||
-rw-r--r-- | graphics/VectorRendererSpec.cpp | 13 | ||||
-rw-r--r-- | graphics/VectorRendererSpec.h | 5 | ||||
-rw-r--r-- | graphics/transparent_surface.cpp | 80 | ||||
-rw-r--r-- | graphics/transparent_surface.h | 3 | ||||
-rw-r--r-- | gui/ThemeEngine.cpp | 65 | ||||
-rw-r--r-- | gui/ThemeEngine.h | 15 | ||||
-rw-r--r-- | gui/ThemeParser.cpp | 24 | ||||
-rw-r--r-- | gui/ThemeParser.h | 5 |
9 files changed, 215 insertions, 11 deletions
diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h index 0352808706..3c042a3c40 100644 --- a/graphics/VectorRenderer.h +++ b/graphics/VectorRenderer.h @@ -28,6 +28,7 @@ #include "common/str.h" #include "graphics/surface.h" +#include "graphics/transparent_surface.h" #include "gui/ThemeEngine.h" @@ -81,6 +82,7 @@ struct DrawStep { DrawingFunctionCallback drawingCall; /**< Pointer to drawing function */ Graphics::Surface *blitSrc; + Graphics::TransparentSurface *blitAlphaSrc; }; VectorRenderer *createRenderer(int mode); @@ -420,7 +422,13 @@ public: void drawCallback_BITMAP(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) { uint16 x, y, w, h; stepGetPositions(step, area, x, y, w, h); - blitAlphaBitmapClip(step.blitSrc, Common::Rect(x, y, x + w, y + h), clip); + blitKeyBitmapClip(step.blitSrc, Common::Rect(x, y, x + w, y + h), clip); + } + + void drawCallback_ALPHABITMAP(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) { + uint16 x, y, w, h; + stepGetPositions(step, area, x, y, w, h); + blitAlphaBitmap(step.blitAlphaSrc, Common::Rect(x, y, x + w, y + h)); //TODO } void drawCallback_CROSS(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) { @@ -482,8 +490,10 @@ public: virtual void blitSubSurface(const Graphics::Surface *source, const Common::Rect &r) = 0; virtual void blitSubSurfaceClip(const Graphics::Surface *source, const Common::Rect &r, const Common::Rect &clipping) = 0; - virtual void blitAlphaBitmap(const Graphics::Surface *source, const Common::Rect &r) = 0; - virtual void blitAlphaBitmapClip(const Graphics::Surface *source, const Common::Rect &r, const Common::Rect &clipping) = 0; + virtual void blitKeyBitmap(const Graphics::Surface *source, const Common::Rect &r) = 0; + virtual void blitKeyBitmapClip(const Graphics::Surface *source, const Common::Rect &r, const Common::Rect &clipping) = 0; + + virtual void blitAlphaBitmap(Graphics::TransparentSurface *source, const Common::Rect &r) = 0; /** * Draws a string into the screen. Wrapper for the Graphics::Font string drawing diff --git a/graphics/VectorRendererSpec.cpp b/graphics/VectorRendererSpec.cpp index fc741f6e77..a50bb27c1a 100644 --- a/graphics/VectorRendererSpec.cpp +++ b/graphics/VectorRendererSpec.cpp @@ -25,6 +25,7 @@ #include "common/frac.h" #include "graphics/surface.h" +#include "graphics/transparent_surface.h" #include "graphics/colormasks.h" #include "gui/ThemeEngine.h" @@ -848,8 +849,8 @@ blitSubSurfaceClip(const Graphics::Surface *source, const Common::Rect &r, const } template<typename PixelType> -void VectorRendererSpec<PixelType>:: -blitAlphaBitmap(const Graphics::Surface *source, const Common::Rect &r) { +void VectorRendererSpec<PixelType>:: +blitKeyBitmap(const Graphics::Surface *source, const Common::Rect &r) { int16 x = r.left; int16 y = r.top; @@ -885,7 +886,7 @@ blitAlphaBitmap(const Graphics::Surface *source, const Common::Rect &r) { template<typename PixelType> void VectorRendererSpec<PixelType>:: -blitAlphaBitmapClip(const Graphics::Surface *source, const Common::Rect &r, const Common::Rect &clipping) { +blitKeyBitmapClip(const Graphics::Surface *source, const Common::Rect &r, const Common::Rect &clipping) { if (clipping.isEmpty() || clipping.contains(r)) { blitAlphaBitmap(source, r); return; @@ -944,6 +945,12 @@ blitAlphaBitmapClip(const Graphics::Surface *source, const Common::Rect &r, cons template<typename PixelType> void VectorRendererSpec<PixelType>:: +blitAlphaBitmap(Graphics::TransparentSurface *source, const Common::Rect &r) { + source->blit(*_activeSurface, r.left, r.top); +} + +template<typename PixelType> +void VectorRendererSpec<PixelType>:: applyScreenShading(GUI::ThemeEngine::ShadingStyle shadingStyle) { int pixels = _activeSurface->w * _activeSurface->h; PixelType *ptr = (PixelType *)_activeSurface->getPixels(); diff --git a/graphics/VectorRendererSpec.h b/graphics/VectorRendererSpec.h index bee6d4c425..658c70948f 100644 --- a/graphics/VectorRendererSpec.h +++ b/graphics/VectorRendererSpec.h @@ -93,8 +93,9 @@ public: void blitSurface(const Graphics::Surface *source, const Common::Rect &r); void blitSubSurface(const Graphics::Surface *source, const Common::Rect &r); void blitSubSurfaceClip(const Graphics::Surface *source, const Common::Rect &r, const Common::Rect &clipping); - void blitAlphaBitmap(const Graphics::Surface *source, const Common::Rect &r); - void blitAlphaBitmapClip(const Graphics::Surface *source, const Common::Rect &r, const Common::Rect &clipping); + void blitKeyBitmap(const Graphics::Surface *source, const Common::Rect &r); + void blitKeyBitmapClip(const Graphics::Surface *source, const Common::Rect &r, const Common::Rect &clipping); + void blitAlphaBitmap(Graphics::TransparentSurface *source, const Common::Rect &r); void applyScreenShading(GUI::ThemeEngine::ShadingStyle shadingStyle); diff --git a/graphics/transparent_surface.cpp b/graphics/transparent_surface.cpp index c2903d42c3..81b7f3d647 100644 --- a/graphics/transparent_surface.cpp +++ b/graphics/transparent_surface.cpp @@ -346,7 +346,7 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p TransparentSurface srcImage(*this, false); // TODO: Is the data really in the screen format? if (format.bytesPerPixel != 4) { - warning("TransparentSurface can only blit 32bpp images, but got %d", format.bytesPerPixel * 8); + warning("TransparentSurface can only blit 32bpp images, but got %d", format.bytesPerPixel * 8); return retSize; } @@ -979,4 +979,82 @@ TransparentSurface *TransparentSurface::scale(uint16 newWidth, uint16 newHeight) } +TransparentSurface *TransparentSurface::convertTo(const PixelFormat &dstFormat, const byte *palette) const { + assert(pixels); + + TransparentSurface *surface = new TransparentSurface(); + + // If the target format is the same, just copy + if (format == dstFormat) { + surface->copyFrom(*this); + return surface; + } + + if (format.bytesPerPixel == 0 || format.bytesPerPixel > 4) + error("Surface::convertTo(): Can only convert from 1Bpp, 2Bpp, 3Bpp, and 4Bpp"); + + if (dstFormat.bytesPerPixel != 2 && dstFormat.bytesPerPixel != 4) + error("Surface::convertTo(): Can only convert to 2Bpp and 4Bpp"); + + surface->create(w, h, dstFormat); + + if (format.bytesPerPixel == 1) { + // Converting from paletted to high color + assert(palette); + + for (int y = 0; y < h; y++) { + const byte *srcRow = (const byte *)getBasePtr(0, y); + byte *dstRow = (byte *)surface->getBasePtr(0, y); + + for (int x = 0; x < w; x++) { + byte index = *srcRow++; + byte r = palette[index * 3]; + byte g = palette[index * 3 + 1]; + byte b = palette[index * 3 + 2]; + + uint32 color = dstFormat.RGBToColor(r, g, b); + + if (dstFormat.bytesPerPixel == 2) + *((uint16 *)dstRow) = color; + else + *((uint32 *)dstRow) = color; + + dstRow += dstFormat.bytesPerPixel; + } + } + } else { + // Converting from high color to high color + for (int y = 0; y < h; y++) { + const byte *srcRow = (const byte *)getBasePtr(0, y); + byte *dstRow = (byte *)surface->getBasePtr(0, y); + + for (int x = 0; x < w; x++) { + uint32 srcColor; + if (format.bytesPerPixel == 2) + srcColor = READ_UINT16(srcRow); + else if (format.bytesPerPixel == 3) + srcColor = READ_UINT24(srcRow); + else + srcColor = READ_UINT32(srcRow); + + srcRow += format.bytesPerPixel; + + // Convert that color to the new format + byte r, g, b, a; + format.colorToARGB(srcColor, a, r, g, b); + uint32 color = dstFormat.ARGBToColor(a, r, g, b); + + if (dstFormat.bytesPerPixel == 2) + *((uint16 *)dstRow) = color; + else + *((uint32 *)dstRow) = color; + + dstRow += dstFormat.bytesPerPixel; + } + } + } + + return surface; +} + } // End of namespace Graphics diff --git a/graphics/transparent_surface.h b/graphics/transparent_surface.h index c0d3d26e52..461d7a6e4b 100644 --- a/graphics/transparent_surface.h +++ b/graphics/transparent_surface.h @@ -151,6 +151,9 @@ struct TransparentSurface : public Graphics::Surface { * */ TransparentSurface *rotoscale(const TransformStruct &transform) const; + + TransparentSurface *convertTo(const PixelFormat &dstFormat, const byte *palette = 0) const; + AlphaType getAlphaMode() const; void setAlphaMode(AlphaType); private: diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index 70ce07b211..1a648b44a0 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -31,6 +31,7 @@ #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" @@ -309,7 +310,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); } @@ -323,7 +324,7 @@ void ThemeItemBitmapClip::drawSelf(bool draw, bool restore) { if (draw) { if (_alpha) - _engine->renderer()->blitAlphaBitmapClip(_bitmap, _area, _clip); + _engine->renderer()->blitKeyBitmapClip(_bitmap, _area, _clip); else _engine->renderer()->blitSubSurfaceClip(_bitmap, _area, _clip); } @@ -402,6 +403,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; @@ -526,6 +536,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(); @@ -759,6 +778,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); diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h index 3c259b4f9d..92aafc8975 100644 --- a/gui/ThemeEngine.h +++ b/gui/ThemeEngine.h @@ -32,6 +32,7 @@ #include "common/rect.h" #include "graphics/surface.h" +#include "graphics/transparent_surface.h" #include "graphics/font.h" #include "graphics/pixelformat.h" @@ -140,6 +141,7 @@ enum TextColor { class ThemeEngine { protected: typedef Common::HashMap<Common::String, Graphics::Surface *> ImagesMap; + typedef Common::HashMap<Common::String, Graphics::TransparentSurface *> AImagesMap; friend class GUI::Dialog; friend class GUI::GuiObject; @@ -483,6 +485,14 @@ public: bool addBitmap(const Common::String &filename); /** + * Interface for the ThemeParser class: Loads a bitmap with transparency file to use on the GUI. + * The filename is also used as its identifier. + * + * @param filename Name of the bitmap file. + */ + bool addAlphaBitmap(const Common::String &filename); + + /** * Adds a new TextStep from the ThemeParser. This will be deprecated/removed once the * new Font API is in place. FIXME: Is that so ??? */ @@ -526,6 +536,10 @@ public: return _bitmaps.contains(name) ? _bitmaps[name] : 0; } + Graphics::TransparentSurface *getAlphaBitmap(const Common::String &name) { + return _abitmaps.contains(name) ? _abitmaps[name] : 0; + } + const Graphics::Surface *getImageSurface(const Common::String &name) const { return _bitmaps.contains(name) ? _bitmaps[name] : 0; } @@ -688,6 +702,7 @@ protected: TextColorData *_textColors[kTextColorMAX]; ImagesMap _bitmaps; + AImagesMap _abitmaps; Graphics::PixelFormat _overlayFormat; #ifdef USE_RGB_COLOR Graphics::PixelFormat _cursorFormat; diff --git a/gui/ThemeParser.cpp b/gui/ThemeParser.cpp index bd5b406ca8..8d917f29e0 100644 --- a/gui/ThemeParser.cpp +++ b/gui/ThemeParser.cpp @@ -241,6 +241,18 @@ bool ThemeParser::parserCallback_bitmap(ParserNode *node) { return true; } +bool ThemeParser::parserCallback_alphabitmap(ParserNode *node) { + if (resolutionCheck(node->values["resolution"]) == false) { + node->ignore = true; + return true; + } + + if (!_theme->addAlphaBitmap(node->values["filename"])) + return parserError("Error loading Bitmap file '" + node->values["filename"] + "'"); + + return true; +} + bool ThemeParser::parserCallback_text(ParserNode *node) { Graphics::TextAlign alignH; GUI::ThemeEngine::TextAlignVertical alignV; @@ -323,6 +335,8 @@ static Graphics::DrawingFunctionCallback getDrawingFunctionCallback(const Common return &Graphics::VectorRenderer::drawCallback_BITMAP; if (name == "cross") return &Graphics::VectorRenderer::drawCallback_CROSS; + if (name == "alphabitmap") + return &Graphics::VectorRenderer::drawCallback_ALPHABITMAP; return 0; } @@ -448,6 +462,16 @@ bool ThemeParser::parseDrawStep(ParserNode *stepNode, Graphics::DrawStep *drawst return parserError("The given filename hasn't been loaded into the GUI."); } + if (functionName == "alphabitmap") { + if (!stepNode->values.contains("file")) + return parserError("Need to specify a filename for AlphaBitmap blitting."); + + drawstep->blitAlphaSrc = _theme->getAlphaBitmap(stepNode->values["file"]); + + if (!drawstep->blitAlphaSrc) + return parserError("The given filename hasn't been loaded into the GUI."); + } + if (functionName == "roundedsq" || functionName == "circle" || functionName == "tab") { if (stepNode->values.contains("radius") && stepNode->values["radius"] == "auto") { drawstep->radius = 0xFF; diff --git a/gui/ThemeParser.h b/gui/ThemeParser.h index 360e3da009..14305af80d 100644 --- a/gui/ThemeParser.h +++ b/gui/ThemeParser.h @@ -80,6 +80,10 @@ protected: XML_PROP(filename, true) XML_PROP(resolution, false) KEY_END() + XML_KEY(alphabitmap) + XML_PROP(filename, true) + XML_PROP(resolution, false) + KEY_END() KEY_END() XML_KEY(cursor) @@ -224,6 +228,7 @@ protected: bool parserCallback_drawdata(ParserNode *node); bool parserCallback_bitmaps(ParserNode *node) { return true; } bool parserCallback_bitmap(ParserNode *node); + bool parserCallback_alphabitmap(ParserNode *node); bool parserCallback_cursor(ParserNode *node); |