aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--graphics/VectorRenderer.h16
-rw-r--r--graphics/VectorRendererSpec.cpp13
-rw-r--r--graphics/VectorRendererSpec.h5
-rw-r--r--graphics/transparent_surface.cpp80
-rw-r--r--graphics/transparent_surface.h3
-rw-r--r--gui/ThemeEngine.cpp65
-rw-r--r--gui/ThemeEngine.h15
-rw-r--r--gui/ThemeParser.cpp24
-rw-r--r--gui/ThemeParser.h5
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);