Merge pull request #257 from lordhoto/graphics-conversion
Extend crossBlit for abitrary (in-place) conversions and add a in-place conversion to Surface
This commit is contained in:
commit
c2971374cd
6 changed files with 233 additions and 137 deletions
|
@ -22,123 +22,143 @@
|
||||||
#include "graphics/conversion.h"
|
#include "graphics/conversion.h"
|
||||||
#include "graphics/pixelformat.h"
|
#include "graphics/pixelformat.h"
|
||||||
|
|
||||||
|
#include "common/endian.h"
|
||||||
|
|
||||||
namespace Graphics {
|
namespace Graphics {
|
||||||
|
|
||||||
// TODO: YUV to RGB conversion function
|
// TODO: YUV to RGB conversion function
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
template<typename SrcColor, typename DstColor, bool backward>
|
||||||
|
FORCEINLINE void crossBlitLogic(byte *dst, const byte *src, const uint w, const uint h,
|
||||||
|
const PixelFormat &srcFmt, const PixelFormat &dstFmt,
|
||||||
|
const uint srcDelta, const uint dstDelta) {
|
||||||
|
for (uint y = 0; y < h; ++y) {
|
||||||
|
for (uint x = 0; x < w; ++x) {
|
||||||
|
const uint32 color = *(const SrcColor *)src;
|
||||||
|
byte a, r, g, b;
|
||||||
|
srcFmt.colorToARGB(color, a, r, g, b);
|
||||||
|
*(DstColor *)dst = dstFmt.ARGBToColor(a, r, g, b);
|
||||||
|
|
||||||
|
if (backward) {
|
||||||
|
src -= sizeof(SrcColor);
|
||||||
|
dst -= sizeof(DstColor);
|
||||||
|
} else {
|
||||||
|
src += sizeof(SrcColor);
|
||||||
|
dst += sizeof(DstColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (backward) {
|
||||||
|
src -= srcDelta;
|
||||||
|
dst -= dstDelta;
|
||||||
|
} else {
|
||||||
|
src += srcDelta;
|
||||||
|
dst += dstDelta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DstColor, bool backward>
|
||||||
|
FORCEINLINE void crossBlitLogic3BppSource(byte *dst, const byte *src, const uint w, const uint h,
|
||||||
|
const PixelFormat &srcFmt, const PixelFormat &dstFmt,
|
||||||
|
const uint srcDelta, const uint dstDelta) {
|
||||||
|
uint32 color;
|
||||||
|
byte r, g, b, a;
|
||||||
|
uint8 *col = (uint8 *)&color;
|
||||||
|
#ifdef SCUMM_BIG_ENDIAN
|
||||||
|
col++;
|
||||||
|
#endif
|
||||||
|
for (uint y = 0; y < h; ++y) {
|
||||||
|
for (uint x = 0; x < w; ++x) {
|
||||||
|
memcpy(col, src, 3);
|
||||||
|
srcFmt.colorToARGB(color, a, r, g, b);
|
||||||
|
*(DstColor *)dst = dstFmt.ARGBToColor(a, r, g, b);
|
||||||
|
|
||||||
|
if (backward) {
|
||||||
|
src -= 3;
|
||||||
|
dst -= sizeof(DstColor);
|
||||||
|
} else {
|
||||||
|
src += 3;
|
||||||
|
dst += sizeof(DstColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (backward) {
|
||||||
|
src -= srcDelta;
|
||||||
|
dst -= dstDelta;
|
||||||
|
} else {
|
||||||
|
src += srcDelta;
|
||||||
|
dst += dstDelta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of anonymous namespace
|
||||||
|
|
||||||
// Function to blit a rect from one color format to another
|
// Function to blit a rect from one color format to another
|
||||||
bool crossBlit(byte *dst, const byte *src, int dstpitch, int srcpitch,
|
bool crossBlit(byte *dst, const byte *src,
|
||||||
int w, int h, const Graphics::PixelFormat &dstFmt, const Graphics::PixelFormat &srcFmt) {
|
const uint dstPitch, const uint srcPitch,
|
||||||
|
const uint w, const uint h,
|
||||||
|
const Graphics::PixelFormat &dstFmt, const Graphics::PixelFormat &srcFmt) {
|
||||||
// Error out if conversion is impossible
|
// Error out if conversion is impossible
|
||||||
if ((srcFmt.bytesPerPixel == 1) || (dstFmt.bytesPerPixel == 1)
|
if ((srcFmt.bytesPerPixel == 1) || (dstFmt.bytesPerPixel == 1)
|
||||||
|| (!srcFmt.bytesPerPixel) || (!dstFmt.bytesPerPixel)
|
|| (dstFmt.bytesPerPixel == 3)
|
||||||
|| (srcFmt.bytesPerPixel > dstFmt.bytesPerPixel))
|
|| (!srcFmt.bytesPerPixel) || (!dstFmt.bytesPerPixel))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Don't perform unnecessary conversion
|
// Don't perform unnecessary conversion
|
||||||
if (srcFmt == dstFmt) {
|
if (srcFmt == dstFmt) {
|
||||||
if (dst == src)
|
if (dst != src) {
|
||||||
return true;
|
if (dstPitch == srcPitch && ((w * dstFmt.bytesPerPixel) == dstPitch)) {
|
||||||
if (dstpitch == srcpitch && ((w * dstFmt.bytesPerPixel) == dstpitch)) {
|
memcpy(dst, src, dstPitch * h);
|
||||||
memcpy(dst,src,dstpitch * h);
|
} else {
|
||||||
return true;
|
for (uint i = 0; i < h; ++i) {
|
||||||
} else {
|
memcpy(dst, src, w * dstFmt.bytesPerPixel);
|
||||||
for (int i = 0; i < h; i++) {
|
dst += dstPitch;
|
||||||
memcpy(dst,src,w * dstFmt.bytesPerPixel);
|
src += srcPitch;
|
||||||
dst += dstpitch;
|
}
|
||||||
src += srcpitch;
|
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Faster, but larger, to provide optimized handling for each case.
|
// Faster, but larger, to provide optimized handling for each case.
|
||||||
int srcDelta, dstDelta;
|
const uint srcDelta = (srcPitch - w * srcFmt.bytesPerPixel);
|
||||||
srcDelta = (srcpitch - w * srcFmt.bytesPerPixel);
|
const uint dstDelta = (dstPitch - w * dstFmt.bytesPerPixel);
|
||||||
dstDelta = (dstpitch - w * dstFmt.bytesPerPixel);
|
|
||||||
|
|
||||||
// TODO: optimized cases for dstDelta of 0
|
// TODO: optimized cases for dstDelta of 0
|
||||||
uint8 r, g, b, a;
|
|
||||||
if (dstFmt.bytesPerPixel == 2) {
|
if (dstFmt.bytesPerPixel == 2) {
|
||||||
uint16 color;
|
|
||||||
for (int y = 0; y < h; y++) {
|
|
||||||
for (int x = 0; x < w; x++, src += 2, dst += 2) {
|
|
||||||
color = *(const uint16 *)src;
|
|
||||||
srcFmt.colorToARGB(color, a, r, g, b);
|
|
||||||
color = dstFmt.ARGBToColor(a, r, g, b);
|
|
||||||
*(uint16 *)dst = color;
|
|
||||||
}
|
|
||||||
src += srcDelta;
|
|
||||||
dst += dstDelta;
|
|
||||||
}
|
|
||||||
} else if (dstFmt.bytesPerPixel == 3) {
|
|
||||||
uint32 color;
|
|
||||||
uint8 *col = (uint8 *) &color;
|
|
||||||
#ifdef SCUMM_BIG_ENDIAN
|
|
||||||
col++;
|
|
||||||
#endif
|
|
||||||
if (srcFmt.bytesPerPixel == 2) {
|
if (srcFmt.bytesPerPixel == 2) {
|
||||||
for (int y = 0; y < h; y++) {
|
crossBlitLogic<uint16, uint16, false>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta);
|
||||||
for (int x = 0; x < w; x++, src += 2, dst += 3) {
|
} else if (srcFmt.bytesPerPixel == 3) {
|
||||||
color = *(const uint16 *)src;
|
crossBlitLogic3BppSource<uint16, false>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta);
|
||||||
srcFmt.colorToARGB(color, a, r, g, b);
|
|
||||||
color = dstFmt.ARGBToColor(a, r, g, b);
|
|
||||||
memcpy(dst, col, 3);
|
|
||||||
}
|
|
||||||
src += srcDelta;
|
|
||||||
dst += dstDelta;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
for (int y = 0; y < h; y++) {
|
crossBlitLogic<uint32, uint16, false>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta);
|
||||||
for (int x = 0; x < w; x++, src += 3, dst += 3) {
|
|
||||||
memcpy(col, src, 3);
|
|
||||||
srcFmt.colorToARGB(color, a, r, g, b);
|
|
||||||
color = dstFmt.ARGBToColor(a, r, g, b);
|
|
||||||
memcpy(dst, col, 3);
|
|
||||||
}
|
|
||||||
src += srcDelta;
|
|
||||||
dst += dstDelta;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (dstFmt.bytesPerPixel == 4) {
|
} else if (dstFmt.bytesPerPixel == 4) {
|
||||||
uint32 color;
|
|
||||||
if (srcFmt.bytesPerPixel == 2) {
|
if (srcFmt.bytesPerPixel == 2) {
|
||||||
for (int y = 0; y < h; y++) {
|
// We need to blit the surface from bottom right to top left here.
|
||||||
for (int x = 0; x < w; x++, src += 2, dst += 4) {
|
// This is neeeded, because when we convert to the same memory
|
||||||
color = *(const uint16 *)src;
|
// buffer copying the surface from top left to bottom right would
|
||||||
srcFmt.colorToARGB(color, a, r, g, b);
|
// overwrite the source, since we have more bits per destination
|
||||||
color = dstFmt.ARGBToColor(a, r, g, b);
|
// color than per source color.
|
||||||
*(uint32 *)dst = color;
|
dst += h * dstPitch - dstDelta - dstFmt.bytesPerPixel;
|
||||||
}
|
src += h * srcPitch - srcDelta - srcFmt.bytesPerPixel;
|
||||||
src += srcDelta;
|
crossBlitLogic<uint16, uint32, true>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta);
|
||||||
dst += dstDelta;
|
|
||||||
}
|
|
||||||
} else if (srcFmt.bytesPerPixel == 3) {
|
} else if (srcFmt.bytesPerPixel == 3) {
|
||||||
uint8 *col = (uint8 *)&color;
|
// We need to blit the surface from bottom right to top left here.
|
||||||
#ifdef SCUMM_BIG_ENDIAN
|
// This is neeeded, because when we convert to the same memory
|
||||||
col++;
|
// buffer copying the surface from top left to bottom right would
|
||||||
#endif
|
// overwrite the source, since we have more bits per destination
|
||||||
for (int y = 0; y < h; y++) {
|
// color than per source color.
|
||||||
for (int x = 0; x < w; x++, src += 2, dst += 4) {
|
dst += h * dstPitch - dstDelta - dstFmt.bytesPerPixel;
|
||||||
memcpy(col, src, 3);
|
src += h * srcPitch - srcDelta - srcFmt.bytesPerPixel;
|
||||||
srcFmt.colorToARGB(color, a, r, g, b);
|
crossBlitLogic3BppSource<uint32, true>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta);
|
||||||
color = dstFmt.ARGBToColor(a, r, g, b);
|
|
||||||
*(uint32 *)dst = color;
|
|
||||||
}
|
|
||||||
src += srcDelta;
|
|
||||||
dst += dstDelta;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
for (int y = 0; y < h; y++) {
|
crossBlitLogic<uint32, uint32, false>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta);
|
||||||
for (int x = 0; x < w; x++, src += 4, dst += 4) {
|
|
||||||
color = *(const uint32 *)src;
|
|
||||||
srcFmt.colorToARGB(color, a, r, g, b);
|
|
||||||
color = dstFmt.ARGBToColor(a, r, g, b);
|
|
||||||
*(uint32 *)dst = color;
|
|
||||||
}
|
|
||||||
src += srcDelta;
|
|
||||||
dst += dstDelta;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -59,15 +59,18 @@ inline static void RGB2YUV(byte r, byte g, byte b, byte &y, byte &u, byte &v) {
|
||||||
* @return true if conversion completes successfully,
|
* @return true if conversion completes successfully,
|
||||||
* false if there is an error.
|
* false if there is an error.
|
||||||
*
|
*
|
||||||
* @note This implementation currently arbitrarily requires that the
|
* @note Blitting to a 3Bpp destination is not supported
|
||||||
* destination's format have at least as high a bytedepth as
|
* @note This can convert a surface in place, regardless of the
|
||||||
* the source's.
|
* source and destination format, as long as there is enough
|
||||||
* @note This can convert a rectangle in place, if the source and
|
* space for the destination. The dstPitch / srcPitch ratio
|
||||||
* destination format have the same bytedepth.
|
* must at least equal the dstBpp / srcBpp ratio for
|
||||||
*
|
* dstPitch >= srcPitch and at most dstBpp / srcBpp for
|
||||||
|
* dstPitch < srcPitch though.
|
||||||
*/
|
*/
|
||||||
bool crossBlit(byte *dst, const byte *src, int dstpitch, int srcpitch,
|
bool crossBlit(byte *dst, const byte *src,
|
||||||
int w, int h, const Graphics::PixelFormat &dstFmt, const Graphics::PixelFormat &srcFmt);
|
const uint dstPitch, const uint srcPitch,
|
||||||
|
const uint w, const uint h,
|
||||||
|
const Graphics::PixelFormat &dstFmt, const Graphics::PixelFormat &srcFmt);
|
||||||
|
|
||||||
} // End of namespace Graphics
|
} // End of namespace Graphics
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "common/textconsole.h"
|
#include "common/textconsole.h"
|
||||||
#include "graphics/primitives.h"
|
#include "graphics/primitives.h"
|
||||||
#include "graphics/surface.h"
|
#include "graphics/surface.h"
|
||||||
|
#include "graphics/conversion.h"
|
||||||
|
|
||||||
namespace Graphics {
|
namespace Graphics {
|
||||||
|
|
||||||
|
@ -282,6 +283,72 @@ void Surface::move(int dx, int dy, int height) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Surface::convertToInPlace(const PixelFormat &dstFormat, const byte *palette) {
|
||||||
|
// Do not convert to the same format and ignore empty surfaces.
|
||||||
|
if (format == dstFormat || pixels == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format.bytesPerPixel == 0 || format.bytesPerPixel > 4)
|
||||||
|
error("Surface::convertToInPlace(): Can only convert from 1Bpp, 2Bpp, 3Bpp, and 4Bpp");
|
||||||
|
|
||||||
|
if (dstFormat.bytesPerPixel != 2 && dstFormat.bytesPerPixel != 4)
|
||||||
|
error("Surface::convertToInPlace(): Can only convert to 2Bpp and 4Bpp");
|
||||||
|
|
||||||
|
// In case the surface data needs more space allocate it.
|
||||||
|
if (dstFormat.bytesPerPixel > format.bytesPerPixel) {
|
||||||
|
void *const newPixels = realloc(pixels, w * h * dstFormat.bytesPerPixel);
|
||||||
|
if (!newPixels) {
|
||||||
|
error("Surface::convertToInPlace(): Out of memory");
|
||||||
|
}
|
||||||
|
pixels = newPixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We take advantage of the fact that pitch is always w * format.bytesPerPixel.
|
||||||
|
// This is assured by the logic of Surface::create.
|
||||||
|
|
||||||
|
// We need to handle 1 Bpp surfaces special here.
|
||||||
|
if (format.bytesPerPixel == 1) {
|
||||||
|
assert(palette);
|
||||||
|
|
||||||
|
for (int y = h; y > 0; --y) {
|
||||||
|
const byte *srcRow = (const byte *)pixels + y * pitch - 1;
|
||||||
|
byte *dstRow = (byte *)pixels + y * w * dstFormat.bytesPerPixel - dstFormat.bytesPerPixel;
|
||||||
|
|
||||||
|
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 {
|
||||||
|
crossBlit((byte *)pixels, (const byte *)pixels, w * dstFormat.bytesPerPixel, pitch, w, h, dstFormat, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
// In case the surface data got smaller, free up some memory.
|
||||||
|
if (dstFormat.bytesPerPixel < format.bytesPerPixel) {
|
||||||
|
void *const newPixels = realloc(pixels, w * h * dstFormat.bytesPerPixel);
|
||||||
|
if (!newPixels) {
|
||||||
|
error("Surface::convertToInPlace(): Freeing memory failed");
|
||||||
|
}
|
||||||
|
pixels = newPixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the surface specific data.
|
||||||
|
format = dstFormat;
|
||||||
|
pitch = w * dstFormat.bytesPerPixel;
|
||||||
|
}
|
||||||
|
|
||||||
Graphics::Surface *Surface::convertTo(const PixelFormat &dstFormat, const byte *palette) const {
|
Graphics::Surface *Surface::convertTo(const PixelFormat &dstFormat, const byte *palette) const {
|
||||||
assert(pixels);
|
assert(pixels);
|
||||||
|
|
||||||
|
|
|
@ -134,6 +134,20 @@ struct Surface {
|
||||||
*/
|
*/
|
||||||
void copyFrom(const Surface &surf);
|
void copyFrom(const Surface &surf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the data to another pixel format.
|
||||||
|
*
|
||||||
|
* This works in-place. This means it will not create an additional buffer
|
||||||
|
* for the conversion process. The value of pixels might change though.
|
||||||
|
*
|
||||||
|
* Note that you should only use this, when you created the Surface data via
|
||||||
|
* create! Otherwise this function has undefined behavior.
|
||||||
|
*
|
||||||
|
* @param dstFormat The desired format
|
||||||
|
* @param palette The palette (in RGB888), if the source format has a Bpp of 1
|
||||||
|
*/
|
||||||
|
void convertToInPlace(const PixelFormat &dstFormat, const byte *palette = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the data to another pixel format.
|
* Convert the data to another pixel format.
|
||||||
*
|
*
|
||||||
|
|
|
@ -376,7 +376,7 @@ void ButtonWidget::wantTickle(bool tickled) {
|
||||||
|
|
||||||
PicButtonWidget::PicButtonWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip, uint32 cmd, uint8 hotkey)
|
PicButtonWidget::PicButtonWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip, uint32 cmd, uint8 hotkey)
|
||||||
: ButtonWidget(boss, x, y, w, h, "", tooltip, cmd, hotkey),
|
: ButtonWidget(boss, x, y, w, h, "", tooltip, cmd, hotkey),
|
||||||
_gfx(new Graphics::Surface()), _alpha(256), _transparency(false) {
|
_gfx(), _alpha(256), _transparency(false) {
|
||||||
|
|
||||||
setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG);
|
setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG);
|
||||||
_type = kButtonWidget;
|
_type = kButtonWidget;
|
||||||
|
@ -384,18 +384,17 @@ PicButtonWidget::PicButtonWidget(GuiObject *boss, int x, int y, int w, int h, co
|
||||||
|
|
||||||
PicButtonWidget::PicButtonWidget(GuiObject *boss, const Common::String &name, const char *tooltip, uint32 cmd, uint8 hotkey)
|
PicButtonWidget::PicButtonWidget(GuiObject *boss, const Common::String &name, const char *tooltip, uint32 cmd, uint8 hotkey)
|
||||||
: ButtonWidget(boss, name, "", tooltip, cmd, hotkey),
|
: ButtonWidget(boss, name, "", tooltip, cmd, hotkey),
|
||||||
_gfx(new Graphics::Surface()), _alpha(256), _transparency(false) {
|
_gfx(), _alpha(256), _transparency(false) {
|
||||||
setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG);
|
setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG);
|
||||||
_type = kButtonWidget;
|
_type = kButtonWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
PicButtonWidget::~PicButtonWidget() {
|
PicButtonWidget::~PicButtonWidget() {
|
||||||
_gfx->free();
|
_gfx.free();
|
||||||
delete _gfx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PicButtonWidget::setGfx(const Graphics::Surface *gfx) {
|
void PicButtonWidget::setGfx(const Graphics::Surface *gfx) {
|
||||||
_gfx->free();
|
_gfx.free();
|
||||||
|
|
||||||
if (!gfx || !gfx->pixels)
|
if (!gfx || !gfx->pixels)
|
||||||
return;
|
return;
|
||||||
|
@ -411,7 +410,7 @@ void PicButtonWidget::setGfx(const Graphics::Surface *gfx) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_gfx->copyFrom(*gfx);
|
_gfx.copyFrom(*gfx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PicButtonWidget::setGfx(int w, int h, int r, int g, int b) {
|
void PicButtonWidget::setGfx(int w, int h, int r, int g, int b) {
|
||||||
|
@ -422,29 +421,26 @@ void PicButtonWidget::setGfx(int w, int h, int r, int g, int b) {
|
||||||
|
|
||||||
const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat();
|
const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat();
|
||||||
|
|
||||||
_gfx->free();
|
_gfx.free();
|
||||||
_gfx->create(w, h, requiredFormat);
|
_gfx.create(w, h, requiredFormat);
|
||||||
_gfx->fillRect(Common::Rect(0, 0, w, h), _gfx->format.RGBToColor(r, g, b));
|
_gfx.fillRect(Common::Rect(0, 0, w, h), _gfx.format.RGBToColor(r, g, b));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PicButtonWidget::drawWidget() {
|
void PicButtonWidget::drawWidget() {
|
||||||
g_gui.theme()->drawButton(Common::Rect(_x, _y, _x+_w, _y+_h), "", _state, getFlags());
|
g_gui.theme()->drawButton(Common::Rect(_x, _y, _x+_w, _y+_h), "", _state, getFlags());
|
||||||
|
|
||||||
if (_gfx->pixels) {
|
if (_gfx.pixels) {
|
||||||
// Check whether the set up surface needs to be converted to the GUI
|
// Check whether the set up surface needs to be converted to the GUI
|
||||||
// color format.
|
// color format.
|
||||||
const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat();
|
const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat();
|
||||||
if (_gfx->format != requiredFormat) {
|
if (_gfx.format != requiredFormat) {
|
||||||
Graphics::Surface *converted = _gfx->convertTo(requiredFormat);
|
_gfx.convertToInPlace(requiredFormat);
|
||||||
_gfx->free();
|
|
||||||
delete _gfx;
|
|
||||||
_gfx = converted;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const int x = _x + (_w - _gfx->w) / 2;
|
const int x = _x + (_w - _gfx.w) / 2;
|
||||||
const int y = _y + (_h - _gfx->h) / 2;
|
const int y = _y + (_h - _gfx.h) / 2;
|
||||||
|
|
||||||
g_gui.theme()->drawSurface(Common::Rect(x, y, x + _gfx->w, y + _gfx->h), *_gfx, _state, _alpha, _transparency);
|
g_gui.theme()->drawSurface(Common::Rect(x, y, x + _gfx.w, y + _gfx.h), _gfx, _state, _alpha, _transparency);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -632,24 +628,23 @@ int SliderWidget::posToValue(int pos) {
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
|
|
||||||
GraphicsWidget::GraphicsWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip)
|
GraphicsWidget::GraphicsWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip)
|
||||||
: Widget(boss, x, y, w, h, tooltip), _gfx(new Graphics::Surface()), _alpha(256), _transparency(false) {
|
: Widget(boss, x, y, w, h, tooltip), _gfx(), _alpha(256), _transparency(false) {
|
||||||
setFlags(WIDGET_ENABLED | WIDGET_CLEARBG);
|
setFlags(WIDGET_ENABLED | WIDGET_CLEARBG);
|
||||||
_type = kGraphicsWidget;
|
_type = kGraphicsWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphicsWidget::GraphicsWidget(GuiObject *boss, const Common::String &name, const char *tooltip)
|
GraphicsWidget::GraphicsWidget(GuiObject *boss, const Common::String &name, const char *tooltip)
|
||||||
: Widget(boss, name, tooltip), _gfx(new Graphics::Surface()), _alpha(256), _transparency(false) {
|
: Widget(boss, name, tooltip), _gfx(), _alpha(256), _transparency(false) {
|
||||||
setFlags(WIDGET_ENABLED | WIDGET_CLEARBG);
|
setFlags(WIDGET_ENABLED | WIDGET_CLEARBG);
|
||||||
_type = kGraphicsWidget;
|
_type = kGraphicsWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphicsWidget::~GraphicsWidget() {
|
GraphicsWidget::~GraphicsWidget() {
|
||||||
_gfx->free();
|
_gfx.free();
|
||||||
delete _gfx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsWidget::setGfx(const Graphics::Surface *gfx) {
|
void GraphicsWidget::setGfx(const Graphics::Surface *gfx) {
|
||||||
_gfx->free();
|
_gfx.free();
|
||||||
|
|
||||||
if (!gfx || !gfx->pixels)
|
if (!gfx || !gfx->pixels)
|
||||||
return;
|
return;
|
||||||
|
@ -664,7 +659,7 @@ void GraphicsWidget::setGfx(const Graphics::Surface *gfx) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_gfx->copyFrom(*gfx);
|
_gfx.copyFrom(*gfx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsWidget::setGfx(int w, int h, int r, int g, int b) {
|
void GraphicsWidget::setGfx(int w, int h, int r, int g, int b) {
|
||||||
|
@ -675,27 +670,24 @@ void GraphicsWidget::setGfx(int w, int h, int r, int g, int b) {
|
||||||
|
|
||||||
const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat();
|
const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat();
|
||||||
|
|
||||||
_gfx->free();
|
_gfx.free();
|
||||||
_gfx->create(w, h, requiredFormat);
|
_gfx.create(w, h, requiredFormat);
|
||||||
_gfx->fillRect(Common::Rect(0, 0, w, h), _gfx->format.RGBToColor(r, g, b));
|
_gfx.fillRect(Common::Rect(0, 0, w, h), _gfx.format.RGBToColor(r, g, b));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsWidget::drawWidget() {
|
void GraphicsWidget::drawWidget() {
|
||||||
if (_gfx->pixels) {
|
if (_gfx.pixels) {
|
||||||
// Check whether the set up surface needs to be converted to the GUI
|
// Check whether the set up surface needs to be converted to the GUI
|
||||||
// color format.
|
// color format.
|
||||||
const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat();
|
const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat();
|
||||||
if (_gfx->format != requiredFormat) {
|
if (_gfx.format != requiredFormat) {
|
||||||
Graphics::Surface *converted = _gfx->convertTo(requiredFormat);
|
_gfx.convertToInPlace(requiredFormat);
|
||||||
_gfx->free();
|
|
||||||
delete _gfx;
|
|
||||||
_gfx = converted;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const int x = _x + (_w - _gfx->w) / 2;
|
const int x = _x + (_w - _gfx.w) / 2;
|
||||||
const int y = _y + (_h - _gfx->h) / 2;
|
const int y = _y + (_h - _gfx.h) / 2;
|
||||||
|
|
||||||
g_gui.theme()->drawSurface(Common::Rect(x, y, x + _gfx->w, y + _gfx->h), *_gfx, _state, _alpha, _transparency);
|
g_gui.theme()->drawSurface(Common::Rect(x, y, x + _gfx.w, y + _gfx.h), _gfx, _state, _alpha, _transparency);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -230,7 +230,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void drawWidget();
|
void drawWidget();
|
||||||
|
|
||||||
Graphics::Surface *_gfx;
|
Graphics::Surface _gfx;
|
||||||
int _alpha;
|
int _alpha;
|
||||||
bool _transparency;
|
bool _transparency;
|
||||||
};
|
};
|
||||||
|
@ -358,7 +358,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void drawWidget();
|
void drawWidget();
|
||||||
|
|
||||||
Graphics::Surface *_gfx;
|
Graphics::Surface _gfx;
|
||||||
int _alpha;
|
int _alpha;
|
||||||
bool _transparency;
|
bool _transparency;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue