mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-24 05:01:43 +00:00
GRAPHICS: Remove use of TransparentSurface in NinePatch code
This commit is contained in:
parent
5f90959608
commit
6ee5aad258
@ -53,6 +53,8 @@ namespace Wage {
|
||||
// to print out similar pictures, use
|
||||
// bmpDecoder.getSurface()->debugPrint(0, 0, 0, 0, 0, 1);
|
||||
// in MacWindowBorder::loadBorder()
|
||||
//
|
||||
// TODO: Store these as XPM files?
|
||||
|
||||
static const char *wage_border_inact_title[] = {
|
||||
"...................................... .. .. ......................................",
|
||||
@ -230,6 +232,12 @@ static const char *wage_border_act[] = {
|
||||
".. .. ..",
|
||||
".................................. .................................."};
|
||||
|
||||
static const byte wage_border_palette[] = {
|
||||
0, 0, 0,
|
||||
255, 255, 255,
|
||||
255, 0, 255
|
||||
};
|
||||
|
||||
void Gui::loadBorders() {
|
||||
_consoleWindow->enableScrollbar(true);
|
||||
loadBorder(_sceneWindow, wage_border_inact_title, ARRAYSIZE(wage_border_inact_title), Graphics::kWindowBorderTitle, 22);
|
||||
@ -241,25 +249,26 @@ void Gui::loadBorders() {
|
||||
void Gui::loadBorder(Graphics::MacWindow *target, const char *border[], uint height, uint32 flags, int titlePos) {
|
||||
uint width = strlen(border[0]) / 2;
|
||||
|
||||
Graphics::Surface source;
|
||||
|
||||
source.create(width, height, Graphics::TransparentSurface::getSupportedPixelFormat());
|
||||
Graphics::ManagedSurface *surface = new Graphics::ManagedSurface();
|
||||
surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
|
||||
surface->setPalette(wage_border_palette, 0, 3);
|
||||
surface->setTransparentColor(2);
|
||||
|
||||
for (uint y = 0; y < height; y++) {
|
||||
uint32 *dst = (uint32 *)source.getBasePtr(0, y);
|
||||
byte *dst = (byte *)surface->getBasePtr(0, y);
|
||||
|
||||
for (uint x = 0; x < width; x++) {
|
||||
switch(border[y][x * 2]) {
|
||||
case ' ':
|
||||
*dst = MS_RGB(0, 0, 0);
|
||||
*dst = 0;
|
||||
break;
|
||||
|
||||
case '#':
|
||||
*dst = MS_RGB(0xff, 0xff, 0xff);
|
||||
*dst = 1;
|
||||
break;
|
||||
|
||||
case '.':
|
||||
*dst = MS_RGB(0xff, 0, 0xff);
|
||||
*dst = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -270,10 +279,6 @@ void Gui::loadBorder(Graphics::MacWindow *target, const char *border[], uint hei
|
||||
}
|
||||
}
|
||||
|
||||
Graphics::TransparentSurface *surface = new Graphics::TransparentSurface(source, true);
|
||||
|
||||
source.free();
|
||||
|
||||
Graphics::BorderOffsets offsets;
|
||||
offsets.left = 16;
|
||||
offsets.right = 16;
|
||||
|
@ -359,7 +359,7 @@ void MacWindow::loadBorder(Common::SeekableReadStream &file, uint32 flags, Borde
|
||||
_macBorder.loadBorder(file, flags, offsets);
|
||||
}
|
||||
|
||||
void MacWindow::setBorder(Graphics::TransparentSurface *surface, uint32 flags, BorderOffsets offsets) {
|
||||
void MacWindow::setBorder(Graphics::ManagedSurface *surface, uint32 flags, BorderOffsets offsets) {
|
||||
_macBorder.setBorder(surface, flags, offsets);
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "common/stream.h"
|
||||
|
||||
#include "graphics/managed_surface.h"
|
||||
#include "graphics/transparent_surface.h"
|
||||
#include "graphics/nine_patch.h"
|
||||
#include "graphics/palette.h"
|
||||
#include "graphics/font.h"
|
||||
@ -332,7 +331,7 @@ public:
|
||||
*/
|
||||
void loadBorder(Common::SeekableReadStream &file, uint32 flags, int lo = -1, int ro = -1, int to = -1, int bo = -1);
|
||||
void loadBorder(Common::SeekableReadStream &file, uint32 flags, BorderOffsets offsets);
|
||||
void setBorder(Graphics::TransparentSurface *surface, uint32 flags, BorderOffsets offsets);
|
||||
void setBorder(Graphics::ManagedSurface *surface, uint32 flags, BorderOffsets offsets);
|
||||
void disableBorder();
|
||||
void loadInternalBorder(uint32 flags);
|
||||
/**
|
||||
|
@ -80,22 +80,28 @@ bool MacWindowBorder::hasBorder(uint32 flags) {
|
||||
}
|
||||
|
||||
void MacWindowBorder::disableBorder() {
|
||||
Graphics::TransparentSurface *noborder = new Graphics::TransparentSurface();
|
||||
noborder->create(3, 3, noborder->getSupportedPixelFormat());
|
||||
uint32 colorBlack = noborder->getSupportedPixelFormat().RGBToColor(0, 0, 0);
|
||||
uint32 colorPink = noborder->getSupportedPixelFormat().RGBToColor(255, 0, 255);
|
||||
const byte palette[] = {
|
||||
255, 0, 255,
|
||||
0, 0, 0
|
||||
};
|
||||
|
||||
Graphics::ManagedSurface *noborder = new Graphics::ManagedSurface();
|
||||
noborder->create(3, 3, Graphics::PixelFormat::createFormatCLUT8());
|
||||
noborder->setPalette(palette, 0, 2);
|
||||
noborder->setTransparentColor(0);
|
||||
|
||||
for (int y = 0; y < 3; y++)
|
||||
for (int x = 0; x < 3; x++)
|
||||
*((uint32 *)noborder->getBasePtr(x, y)) = noborderData[y][x] ? colorBlack : colorPink;
|
||||
*((byte *)noborder->getBasePtr(x, y)) = noborderData[y][x];
|
||||
|
||||
setBorder(noborder, kWindowBorderActive);
|
||||
|
||||
Graphics::TransparentSurface *noborder2 = new Graphics::TransparentSurface(*noborder, true);
|
||||
Graphics::ManagedSurface *noborder2 = new Graphics::ManagedSurface();
|
||||
noborder2->copyFrom(*noborder);
|
||||
setBorder(noborder2, 0);
|
||||
}
|
||||
|
||||
void MacWindowBorder::addBorder(TransparentSurface *source, uint32 flags, int titlePos) {
|
||||
void MacWindowBorder::addBorder(ManagedSurface *source, uint32 flags, int titlePos) {
|
||||
if (flags >= kWindowBorderMaxFlag) {
|
||||
warning("Accessing non-existed border type");
|
||||
return;
|
||||
@ -216,22 +222,32 @@ void MacWindowBorder::loadBorder(Common::SeekableReadStream &file, uint32 flags,
|
||||
|
||||
void MacWindowBorder::loadBorder(Common::SeekableReadStream &file, uint32 flags, BorderOffsets offsets) {
|
||||
Image::BitmapDecoder bmpDecoder;
|
||||
Graphics::Surface *source;
|
||||
Graphics::TransparentSurface *surface = new Graphics::TransparentSurface();
|
||||
|
||||
bmpDecoder.loadStream(file);
|
||||
source = bmpDecoder.getSurface()->convertTo(surface->getSupportedPixelFormat(), bmpDecoder.getPalette());
|
||||
|
||||
surface->create(source->w, source->h, _window->_wm->_pixelformat);
|
||||
surface->copyFrom(*source);
|
||||
Graphics::ManagedSurface *surface = new Graphics::ManagedSurface();
|
||||
surface->copyFrom(*bmpDecoder.getSurface());
|
||||
surface->setPalette(bmpDecoder.getPalette(), bmpDecoder.getPaletteStartIndex(),
|
||||
bmpDecoder.getPaletteColorCount());
|
||||
|
||||
source->free();
|
||||
delete source;
|
||||
if (surface->format.isCLUT8()) {
|
||||
const byte *palette = bmpDecoder.getPalette();
|
||||
for (int i = 0; i < bmpDecoder.getPaletteColorCount(); i++) {
|
||||
if (palette[0] == 255 && palette[1] == 0 && palette[2] == 255) {
|
||||
surface->setTransparentColor(bmpDecoder.getPaletteStartIndex() + i);
|
||||
break;
|
||||
}
|
||||
palette += 3;
|
||||
}
|
||||
} else {
|
||||
const Graphics::PixelFormat requiredFormat_4byte(4, 8, 8, 8, 8, 24, 16, 8, 0);
|
||||
surface->convertToInPlace(requiredFormat_4byte);
|
||||
surface->setTransparentColor(surface->format.RGBToColor(255, 0, 255));
|
||||
}
|
||||
|
||||
setBorder(surface, flags, offsets);
|
||||
}
|
||||
|
||||
void MacWindowBorder::setBorder(Graphics::TransparentSurface *surface, uint32 flags, int lo, int ro, int to, int bo) {
|
||||
void MacWindowBorder::setBorder(Graphics::ManagedSurface *surface, uint32 flags, int lo, int ro, int to, int bo) {
|
||||
BorderOffsets offsets;
|
||||
offsets.left = lo;
|
||||
offsets.right = ro;
|
||||
@ -244,8 +260,7 @@ void MacWindowBorder::setBorder(Graphics::TransparentSurface *surface, uint32 fl
|
||||
setBorder(surface, flags, offsets);
|
||||
}
|
||||
|
||||
void MacWindowBorder::setBorder(Graphics::TransparentSurface *surface, uint32 flags, BorderOffsets offsets) {
|
||||
surface->applyColorKey(255, 0, 255, false);
|
||||
void MacWindowBorder::setBorder(Graphics::ManagedSurface *surface, uint32 flags, BorderOffsets offsets) {
|
||||
addBorder(surface, flags, offsets.titlePos);
|
||||
|
||||
if ((flags & kWindowBorderActive) && offsets.left + offsets.right + offsets.top + offsets.bottom > -4) { // Checking against default -1
|
||||
@ -276,7 +291,6 @@ void MacWindowBorder::blitBorderInto(ManagedSurface &destination, uint32 flags,
|
||||
return;
|
||||
}
|
||||
|
||||
TransparentSurface srf;
|
||||
NinePatchBitmap *src = _border[flags];
|
||||
|
||||
if (!src) {
|
||||
@ -294,12 +308,7 @@ void MacWindowBorder::blitBorderInto(ManagedSurface &destination, uint32 flags,
|
||||
setTitle(_title, destination.w, wm);
|
||||
}
|
||||
|
||||
srf.create(destination.w, destination.h, destination.format);
|
||||
srf.fillRect(Common::Rect(srf.w, srf.h), wm->_colorGreen2);
|
||||
|
||||
src->blit(srf, 0, 0, srf.w, srf.h, NULL, 0, wm);
|
||||
destination.transBlitFrom(srf, wm->_colorGreen2);
|
||||
srf.free();
|
||||
src->blit(destination, 0, 0, destination.w, destination.h, wm);
|
||||
|
||||
if (flags & kWindowBorderTitle)
|
||||
drawTitle(&destination, wm, src->getTitleOffset());
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include "common/list.h"
|
||||
|
||||
#include "graphics/managed_surface.h"
|
||||
#include "graphics/transparent_surface.h"
|
||||
#include "graphics/primitives.h"
|
||||
|
||||
#include "image/bmp.h"
|
||||
@ -92,7 +91,7 @@ public:
|
||||
* @param The border type indicated by flag
|
||||
* @param The title position of bmp image
|
||||
*/
|
||||
void addBorder(TransparentSurface *source, uint32 flags, int titlePos = 0);
|
||||
void addBorder(ManagedSurface *source, uint32 flags, int titlePos = 0);
|
||||
|
||||
/**
|
||||
* Accessor function for the custom offsets.
|
||||
@ -154,8 +153,8 @@ public:
|
||||
void loadBorder(Common::SeekableReadStream &file, uint32 flags, BorderOffsets offsets);
|
||||
void loadInternalBorder(uint32 flags);
|
||||
|
||||
void setBorder(Graphics::TransparentSurface *surface, uint32 flags, int lo = -1, int ro = -1, int to = -1, int bo = -1);
|
||||
void setBorder(Graphics::TransparentSurface *surface, uint32 flags, BorderOffsets offsets);
|
||||
void setBorder(Graphics::ManagedSurface *surface, uint32 flags, int lo = -1, int ro = -1, int to = -1, int bo = -1);
|
||||
void setBorder(Graphics::ManagedSurface *surface, uint32 flags, BorderOffsets offsets);
|
||||
private:
|
||||
int _scrollPos, _scrollSize;
|
||||
Common::String _title;
|
||||
|
@ -63,7 +63,8 @@ NinePatchSide::~NinePatchSide() {
|
||||
}
|
||||
|
||||
|
||||
bool NinePatchSide::init(Graphics::TransparentSurface *bmp, bool vertical, int titlePos, int *titleIndex) {
|
||||
bool NinePatchSide::init(Graphics::ManagedSurface *bmp, bool vertical, uint32 black, uint32 white, int titlePos, int *titleIndex) {
|
||||
const uint32 key = bmp->getTransparentColor();
|
||||
const uint len = vertical ? bmp->h : bmp->w;
|
||||
uint i;
|
||||
int s, t, z;
|
||||
@ -74,15 +75,13 @@ bool NinePatchSide::init(Graphics::TransparentSurface *bmp, bool vertical, int t
|
||||
|
||||
for (i = 1, s = -1, t = 0, z = -1; i < len; ++i) {
|
||||
int zz;
|
||||
uint8 r, g, b, a;
|
||||
uint32 *color = vertical ? (uint32 *)bmp->getBasePtr(0, i) : (uint32 *)bmp->getBasePtr(i, 0);
|
||||
bmp->format.colorToARGB(*color, a, r, g, b);
|
||||
uint32 color = vertical ? bmp->getPixel(0, i) : bmp->getPixel(i, 0);
|
||||
|
||||
if (i == len - 1) {
|
||||
zz = -1;
|
||||
} else if (r == 0 && g == 0 && b == 0 && a == 255) {
|
||||
} else if (color == black) {
|
||||
zz = 0;
|
||||
} else if (a == 0 || r + g + b + a == 255 * 4) {
|
||||
} else if (color == key || color == white) {
|
||||
zz = 1;
|
||||
} else {
|
||||
warning("NinePatchSide::init(): Bad pixel at %d,%d", (vertical ? 0 : i), (vertical ? i : 0));
|
||||
@ -170,9 +169,8 @@ int NinePatchBitmap::getTitleOffset() {
|
||||
return _h._m[_titleIndex]->dest_offset;
|
||||
}
|
||||
|
||||
NinePatchBitmap::NinePatchBitmap(Graphics::TransparentSurface *bmp, bool owns_bitmap, int titlePos) {
|
||||
NinePatchBitmap::NinePatchBitmap(Graphics::ManagedSurface *bmp, bool owns_bitmap, int titlePos) {
|
||||
int i;
|
||||
uint8 r, g, b, a;
|
||||
|
||||
_bmp = bmp;
|
||||
_destroy_bmp = owns_bitmap;
|
||||
@ -186,13 +184,43 @@ NinePatchBitmap::NinePatchBitmap(Graphics::TransparentSurface *bmp, bool owns_bi
|
||||
_titleWidth = 0;
|
||||
_titlePos = titlePos;
|
||||
|
||||
const uint32 key = bmp->getTransparentColor();
|
||||
uint32 black, white;
|
||||
|
||||
if (bmp->format.isCLUT8()) {
|
||||
byte palette[256 * 3];
|
||||
bmp->grabPalette(palette, 0, 256);
|
||||
|
||||
black = -1;
|
||||
white = -1;
|
||||
|
||||
for (int j = 0; j < 256; j++) {
|
||||
byte r = palette[(j * 3) + 0];
|
||||
byte g = palette[(j * 3) + 1];
|
||||
byte b = palette[(j * 3) + 2];
|
||||
|
||||
if (black == uint32(-1) && r == 0 && g == 0 && b == 0)
|
||||
black = j;
|
||||
else if (white == uint32(-1) && r == 255 && g == 255 && b == 255)
|
||||
white = j;
|
||||
}
|
||||
|
||||
if (black == uint32(-1) || white == uint32(-1))
|
||||
goto bad_bitmap;
|
||||
} else {
|
||||
black = bmp->format.RGBToColor(0, 0, 0);
|
||||
white = bmp->format.RGBToColor(255, 255, 255);
|
||||
}
|
||||
|
||||
if (_width <= 0 || _height <= 0)
|
||||
goto bad_bitmap;
|
||||
|
||||
if (!bmp->hasTransparentColor())
|
||||
goto bad_bitmap;
|
||||
|
||||
/* make sure all four corners are transparent */
|
||||
#define _check_pixel(x, y) \
|
||||
bmp->format.colorToARGB(*(uint32 *)bmp->getBasePtr(x, y), a, r, g, b); \
|
||||
if (a != 0 && r + g + b + a != 4) goto bad_bitmap;
|
||||
if (bmp->getPixel(x, y) != key) goto bad_bitmap;
|
||||
|
||||
_check_pixel(0, 0);
|
||||
_check_pixel(bmp->w - 1, 0);
|
||||
@ -204,14 +232,14 @@ NinePatchBitmap::NinePatchBitmap(Graphics::TransparentSurface *bmp, bool owns_bi
|
||||
|
||||
i = 1;
|
||||
while (i < bmp->w) {
|
||||
bmp->format.colorToARGB(*(uint32 *)bmp->getBasePtr(i, bmp->h - 1), a, r, g, b);
|
||||
uint32 color = bmp->getPixel(i, bmp->h - 1);
|
||||
|
||||
if (r + g + b == 0 && a == 255) {
|
||||
if (color == black) {
|
||||
if (_padding.left == -1)
|
||||
_padding.left = i - 1;
|
||||
else if (_padding.right != -1)
|
||||
goto bad_bitmap;
|
||||
} else if (a == 0 || r + g + b == 0) {
|
||||
} else if (color == key) {
|
||||
if (_padding.left != -1 && _padding.right == -1)
|
||||
_padding.right = bmp->w - i - 1;
|
||||
}
|
||||
@ -220,21 +248,21 @@ NinePatchBitmap::NinePatchBitmap(Graphics::TransparentSurface *bmp, bool owns_bi
|
||||
|
||||
i = 1;
|
||||
while (i < bmp->h) {
|
||||
bmp->format.colorToARGB(*(uint32 *)bmp->getBasePtr(bmp->w - 1, i), a, r, g, b);
|
||||
uint32 color = bmp->getPixel(bmp->w - 1, i);
|
||||
|
||||
if (r + g + b == 0 && a == 255) {
|
||||
if (color == black) {
|
||||
if (_padding.top == -1)
|
||||
_padding.top = i - 1;
|
||||
else if (_padding.bottom != -1)
|
||||
goto bad_bitmap;
|
||||
} else if (a == 0 || r + g + b == 0) {
|
||||
} else if (color == key) {
|
||||
if (_padding.top != -1 && _padding.bottom == -1)
|
||||
_padding.bottom = bmp->h - i - 1;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
if (!_h.init(bmp, false, titlePos, &_titleIndex) || !_v.init(bmp, true)) {
|
||||
if (!_h.init(bmp, false, black, white, titlePos, &_titleIndex) || !_v.init(bmp, true, black, white)) {
|
||||
bad_bitmap:
|
||||
warning("NinePatchBitmap::NinePatchBitmap(): Bad bitmap");
|
||||
|
||||
@ -249,20 +277,13 @@ void NinePatchBitmap::modifyTitleWidth(int titleWidth) {
|
||||
_h.calcOffsets(_cached_dw, _titleIndex, _titleWidth);
|
||||
}
|
||||
|
||||
void NinePatchBitmap::blit(Graphics::Surface &target, int dx, int dy, int dw, int dh, byte *palette, int numColors, MacWindowManager *wm, uint32 transColor) {
|
||||
void NinePatchBitmap::blit(Graphics::ManagedSurface &target, int dx, int dy, int dw, int dh, MacWindowManager *wm) {
|
||||
/* don't draw bitmaps that are smaller than the fixed area */
|
||||
if (dw < _h._fix || dh < _v._fix)
|
||||
return;
|
||||
|
||||
if (dw < _h._fix + _titleWidth)
|
||||
dw = _h._fix + _titleWidth;
|
||||
/* if the bitmap is the same size as the origin, then draw it as-is */
|
||||
if (dw == _width && dh == _height) {
|
||||
Common::Rect r(1, 1, dw, dh);
|
||||
|
||||
_bmp->blit(target, dx, dy, Graphics::FLIP_NONE, &r);
|
||||
return;
|
||||
}
|
||||
|
||||
/* only recalculate the offsets if they have changed since the last draw */
|
||||
if (_cached_dw != dw || _cached_dh != dh) {
|
||||
@ -275,35 +296,38 @@ void NinePatchBitmap::blit(Graphics::Surface &target, int dx, int dy, int dw, in
|
||||
|
||||
/* Handle CLUT8 */
|
||||
if (target.format.bytesPerPixel == 1) {
|
||||
if (!palette && !wm)
|
||||
if (!wm)
|
||||
error("NinePatchBitmap::blit(): Trying to blit into a surface with 8bpp, you need a palette.");
|
||||
|
||||
Surface *srf = new Surface();
|
||||
uint32 transColor = _bmp->getTransparentColor();
|
||||
ManagedSurface *srf = new ManagedSurface();
|
||||
srf->create(target.w, target.h, _bmp->format);
|
||||
srf->fillRect(Common::Rect(srf->w, srf->h), transColor);
|
||||
|
||||
drawRegions(*srf, dx, dy, dw, dh);
|
||||
|
||||
//TODO: This can be further optimized by keeping the data between draws,
|
||||
// and using a unique identifier for each palette, so that it only gets
|
||||
// recalculated when the palette changes.
|
||||
_cached_colors.clear();
|
||||
if (srf->format.isCLUT8()) {
|
||||
uint8 palette[256 * 3];
|
||||
_bmp->grabPalette(palette, 0, 256);
|
||||
|
||||
if (palette) {
|
||||
for (int i = 0; i < srf->w; ++i) {
|
||||
for (int j = 0; j < srf->h; ++j) {
|
||||
uint32 color = *(uint32*)srf->getBasePtr(i, j);
|
||||
byte color = *(byte*)srf->getBasePtr(i, j);
|
||||
if (color != transColor) {
|
||||
*((byte *)target.getBasePtr(i, j)) = closestGrayscale(color, palette, numColors);
|
||||
byte r = palette[(color * 3) + 0];
|
||||
byte g = palette[(color * 3) + 1];
|
||||
byte b = palette[(color * 3) + 2];
|
||||
*((byte *)target.getBasePtr(i, j)) = wm->findBestColor(r, g, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < srf->w; ++i) {
|
||||
for (int j = 0; j < srf->h; ++j) {
|
||||
uint32 color = *(uint32*)srf->getBasePtr(i, j);
|
||||
byte a, r, g, b;
|
||||
_bmp->format.colorToARGB(color, a, r, g, b);
|
||||
if (a > 0 && color != transColor) {
|
||||
uint32 color = srf->getPixel(i, j);
|
||||
if (color != transColor) {
|
||||
byte a, r, g, b;
|
||||
srf->format.colorToARGB(color, a, r, g, b);
|
||||
*((byte *)target.getBasePtr(i, j)) = wm->findBestColor(r, g, b);
|
||||
}
|
||||
}
|
||||
@ -316,6 +340,14 @@ void NinePatchBitmap::blit(Graphics::Surface &target, int dx, int dy, int dw, in
|
||||
return;
|
||||
}
|
||||
|
||||
/* if the bitmap is the same size as the origin, then draw it as-is */
|
||||
if (dw == _width && dh == _height) {
|
||||
Common::Rect r(1, 1, dw, dh);
|
||||
|
||||
target.blitFrom(*_bmp, r, Common::Point(dx, dy));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Else, draw regions normally */
|
||||
drawRegions(target, dx, dy, dw, dh);
|
||||
}
|
||||
@ -327,99 +359,20 @@ NinePatchBitmap::~NinePatchBitmap() {
|
||||
}
|
||||
}
|
||||
|
||||
void NinePatchBitmap::drawRegions(Graphics::Surface &target, int dx, int dy, int dw, int dh) {
|
||||
void NinePatchBitmap::drawRegions(Graphics::ManagedSurface &target, int dx, int dy, int dw, int dh) {
|
||||
/* draw each region */
|
||||
for (uint i = 0; i < _v._m.size(); ++i) {
|
||||
for (uint j = 0; j < _h._m.size(); ++j) {
|
||||
Common::Rect r(_h._m[j]->offset, _v._m[i]->offset,
|
||||
_h._m[j]->offset + _h._m[j]->length, _v._m[i]->offset + _v._m[i]->length);
|
||||
Common::Rect srcRect(_h._m[j]->offset, _v._m[i]->offset,
|
||||
_h._m[j]->offset + _h._m[j]->length,
|
||||
_v._m[i]->offset + _v._m[i]->length);
|
||||
Common::Rect dstRect(dx + _h._m[j]->dest_offset, dy + _v._m[i]->dest_offset,
|
||||
dx + _h._m[j]->dest_offset + _h._m[j]->dest_length,
|
||||
dy + _v._m[i]->dest_offset + _v._m[i]->dest_length);
|
||||
|
||||
_bmp->blit(target, dx + _h._m[j]->dest_offset, dy + _v._m[i]->dest_offset,
|
||||
Graphics::FLIP_NONE, &r, MS_ARGB((uint)255, (uint)255, (uint)255, (uint)255),
|
||||
_h._m[j]->dest_length, _v._m[i]->dest_length);
|
||||
target.blitFrom(*_bmp, srcRect, dstRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NinePatchBitmap::blitClip(Graphics::Surface &target, Common::Rect clip, int dx, int dy, int dw, int dh) {
|
||||
/* don't draw bitmaps that are smaller than the fixed area */
|
||||
if (dw < _h._fix || dh < _v._fix)
|
||||
return;
|
||||
|
||||
/* if the bitmap is the same size as the origin, then draw it as-is */
|
||||
if (dw == _width && dh == _height) {
|
||||
Common::Rect r(1, 1, dw, dh);
|
||||
|
||||
_bmp->blitClip(target, clip, dx, dy, Graphics::FLIP_NONE, &r);
|
||||
return;
|
||||
}
|
||||
|
||||
/* only recalculate the offsets if they have changed since the last draw */
|
||||
if (_cached_dw != dw || _cached_dh != dh) {
|
||||
_h.calcOffsets(dw);
|
||||
_v.calcOffsets(dh);
|
||||
|
||||
_cached_dw = dw;
|
||||
_cached_dh = dh;
|
||||
}
|
||||
|
||||
/* draw each region */
|
||||
for (uint i = 0; i < _v._m.size(); ++i) {
|
||||
for (uint j = 0; j < _h._m.size(); ++j) {
|
||||
Common::Rect r(_h._m[j]->offset, _v._m[i]->offset,
|
||||
_h._m[j]->offset + _h._m[j]->length, _v._m[i]->offset + _v._m[i]->length);
|
||||
|
||||
_bmp->blitClip(target, clip, dx + _h._m[j]->dest_offset, dy + _v._m[i]->dest_offset,
|
||||
Graphics::FLIP_NONE, &r, MS_ARGB((uint)255, (uint)255, (uint)255, (uint)255),
|
||||
_h._m[j]->dest_length, _v._m[i]->dest_length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byte NinePatchBitmap::getColorIndex(uint32 target, byte* palette) {
|
||||
byte *pal = palette;
|
||||
uint i = 0;
|
||||
uint32 color = MS_RGB(pal[0], pal[1], pal[2]);
|
||||
while (color != target) {
|
||||
i += 3;
|
||||
color = MS_RGB(pal[i], pal[i + 1], pal[i + 2]);
|
||||
}
|
||||
return (i / 3);
|
||||
}
|
||||
|
||||
uint32 NinePatchBitmap::grayscale(uint32 color) {
|
||||
byte r, g, b;
|
||||
_bmp->format.colorToRGB(color, r, g, b);
|
||||
return grayscale(r, g, b);
|
||||
}
|
||||
|
||||
uint32 NinePatchBitmap::grayscale(byte r, byte g, byte b) {
|
||||
return (0.29 * r + 0.58 * g + 0.11 * b) / 3;
|
||||
}
|
||||
|
||||
static inline uint32 dist(uint32 a, uint32 b) {
|
||||
if (a > b)
|
||||
return (a - b);
|
||||
|
||||
return b - a;
|
||||
}
|
||||
|
||||
byte NinePatchBitmap::closestGrayscale(uint32 color, byte* palette, int paletteLength) {
|
||||
if (!_cached_colors.contains(color)) {
|
||||
byte target = grayscale(color);
|
||||
byte bestNdx = 0;
|
||||
byte bestColor = grayscale(palette[0], palette[1], palette[2]);
|
||||
for (int i = 1; i < paletteLength; ++i) {
|
||||
byte current = grayscale(palette[i * 3], palette[(i * 3) + 1], palette[(i * 3) + 2]);
|
||||
if (dist(target, bestColor) >= dist(target, current)) {
|
||||
bestColor = current;
|
||||
bestNdx = i;
|
||||
}
|
||||
}
|
||||
_cached_colors[color] = bestNdx;
|
||||
}
|
||||
|
||||
return _cached_colors[color];
|
||||
}
|
||||
|
||||
} // end of namespace Graphics
|
||||
|
@ -51,8 +51,7 @@
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
struct TransparentSurface;
|
||||
struct Surface;
|
||||
class ManagedSurface;
|
||||
class MacWindowManager;
|
||||
|
||||
struct NinePatchMark {
|
||||
@ -71,27 +70,25 @@ public:
|
||||
NinePatchSide() : _fix(0) { _m.clear(); }
|
||||
~NinePatchSide();
|
||||
|
||||
bool init(Graphics::TransparentSurface *bmp, bool vertical, int titlePos = 0, int *titleIndex = nullptr);
|
||||
bool init(Graphics::ManagedSurface *bmp, bool vertical, uint32 black, uint32 white, int titlePos = 0, int *titleIndex = nullptr);
|
||||
|
||||
void calcOffsets(int len, int titleIndex = 0, int titleWidth = 0);
|
||||
};
|
||||
|
||||
class NinePatchBitmap {
|
||||
Graphics::TransparentSurface *_bmp;
|
||||
Graphics::ManagedSurface *_bmp;
|
||||
NinePatchSide _h, _v;
|
||||
Common::Rect _padding;
|
||||
bool _destroy_bmp;
|
||||
int _width, _height;
|
||||
int _cached_dw, _cached_dh;
|
||||
int _titleIndex, _titleWidth, _titlePos;
|
||||
Common::HashMap<uint32, int> _cached_colors;
|
||||
|
||||
public:
|
||||
NinePatchBitmap(Graphics::TransparentSurface *bmp, bool owns_bitmap, int titlePos = 0);
|
||||
NinePatchBitmap(Graphics::ManagedSurface *bmp, bool owns_bitmap, int titlePos = 0);
|
||||
~NinePatchBitmap();
|
||||
|
||||
void blit(Graphics::Surface &target, int dx, int dy, int dw, int dh, byte *palette = NULL, int numColors = 0, MacWindowManager *wm = NULL, uint32 transColor = 0);
|
||||
void blitClip(Graphics::Surface &target, Common::Rect clip, int dx, int dy, int dw, int dh);
|
||||
void blit(Graphics::ManagedSurface &target, int dx, int dy, int dw, int dh, MacWindowManager *wm = NULL);
|
||||
void modifyTitleWidth(int titleWidth);
|
||||
|
||||
int getWidth() { return _width; }
|
||||
@ -101,18 +98,12 @@ public:
|
||||
int getTitleWidth() { return _titleWidth; }
|
||||
// always call it after you calc the offset, such as after you call blit, then you will get the right offset
|
||||
int getTitleOffset();
|
||||
Graphics::TransparentSurface *getSource() { return _bmp; }
|
||||
Graphics::ManagedSurface *getSource() { return _bmp; }
|
||||
Common::Rect &getPadding() { return _padding; }
|
||||
|
||||
private:
|
||||
|
||||
void drawRegions(Graphics::Surface &target, int dx, int dy, int dw, int dh);
|
||||
|
||||
// Assumes color is in the palette
|
||||
byte getColorIndex(uint32 target, byte *palette);
|
||||
uint32 grayscale(uint32 color);
|
||||
uint32 grayscale(byte r, byte g, byte b);
|
||||
byte closestGrayscale(uint32 color, byte* palette, int paletteLength);
|
||||
void drawRegions(Graphics::ManagedSurface &target, int dx, int dy, int dw, int dh);
|
||||
};
|
||||
|
||||
} // end of namespace Graphics
|
||||
|
Loading…
x
Reference in New Issue
Block a user