From a3516483587b736922901ae74305dcf6f043987c Mon Sep 17 00:00:00 2001 From: Max Horn Date: Fri, 13 Feb 2009 00:03:13 +0000 Subject: Rewrote VectorRendererSpec & VectorRendererAA to use a Graphics::PixelFormat, instead of relying on color masks -> should fix bug #2537212, possibly at a slow down on low-end systems (a regression which we certainly could resolve, though). Note: I left the PixelType template param in on purpose, in case we want one day to compile in both 16 and 32 bit pixel support simultaneously svn-id: r36288 --- graphics/VectorRenderer.h | 2 +- graphics/VectorRendererSpec.cpp | 206 ++++++++++++++++++++-------------------- graphics/VectorRendererSpec.h | 28 +++--- 3 files changed, 121 insertions(+), 115 deletions(-) diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h index 7905c43940..3579ae8383 100644 --- a/graphics/VectorRenderer.h +++ b/graphics/VectorRenderer.h @@ -30,7 +30,7 @@ #include "common/system.h" #include "graphics/surface.h" -#include "graphics/colormasks.h" +#include "graphics/pixelformat.h" #include "gui/ThemeEngine.h" diff --git a/graphics/VectorRendererSpec.cpp b/graphics/VectorRendererSpec.cpp index 3fffca0426..d7d1b20e2d 100644 --- a/graphics/VectorRendererSpec.cpp +++ b/graphics/VectorRendererSpec.cpp @@ -230,16 +230,11 @@ VectorRenderer *createRenderer(int mode) { // so it could maybe be handled via DISABLE_FANCY_THEMES, // same goes for 4444, which is only used by DC port. PixelFormat format = g_system->getOverlayFormat(); - if (format == createPixelFormat<1555>()) { - CREATE_RENDERER_16(1555) - } else if (format == createPixelFormat<4444>()) { - CREATE_RENDERER_16(4444) - } else if (format == createPixelFormat<555>()) { - CREATE_RENDERER_16(555) - } else if (format == createPixelFormat<565>()) { - CREATE_RENDERER_16(565) - } else { - error("createRenderer(): PixelFormat not supported"); + switch (mode) { + case GUI::ThemeEngine::kGfxStandard16bit: + return new VectorRendererSpec(format); + case GUI::ThemeEngine::kGfxAntialias16bit: + return new VectorRendererAA(format); } return 0; @@ -248,19 +243,31 @@ VectorRenderer *createRenderer(int mode) { #endif } -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: setGradientColors(uint8 r1, uint8 g1, uint8 b1, uint8 r2, uint8 g2, uint8 b2) { - _gradientEnd = RGBToColor(r2, g2, b2); - _gradientStart = RGBToColor(r1, g1, b1); + _gradientEnd = _format.RGBToColor(r2, g2, b2); + _gradientStart = _format.RGBToColor(r1, g1, b1); + + Base::_gradientBytes[0] = (_gradientEnd & _redMask) - (_gradientStart & _redMask); + Base::_gradientBytes[1] = (_gradientEnd & _greenMask) - (_gradientStart & _greenMask); + Base::_gradientBytes[2] = (_gradientEnd & _blueMask) - (_gradientStart & _blueMask); +} - Base::_gradientBytes[0] = (_gradientEnd & PixelFormat::kRedMask) - (_gradientStart & PixelFormat::kRedMask); - Base::_gradientBytes[1] = (_gradientEnd & PixelFormat::kGreenMask) - (_gradientStart & PixelFormat::kGreenMask); - Base::_gradientBytes[2] = (_gradientEnd & PixelFormat::kBlueMask) - (_gradientStart & PixelFormat::kBlueMask); +template +VectorRendererSpec:: +VectorRendererSpec(PixelFormat format) : + _format(format), + _redMask((0xFF >> format.rLoss) << format.rShift), + _greenMask((0xFF >> format.gLoss) << format.gShift), + _blueMask((0xFF >> format.bLoss) << format.bShift), + _alphaMask((0xFF >> format.aLoss) << format.aShift) { + + _bitmapAlphaColor = _format.RGBToColor(255, 0, 255); } -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: fillSurface() { byte *ptr = (byte *)_activeSurface->getBasePtr(0, 0); @@ -280,8 +287,8 @@ fillSurface() { } } -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: copyFrame(OSystem *sys, const Common::Rect &r) { sys->copyRectToOverlay( @@ -291,8 +298,8 @@ copyFrame(OSystem *sys, const Common::Rect &r) { ); } -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: blitSurface(const Graphics::Surface *source, const Common::Rect &r) { assert(source->w == _activeSurface->w && source->h == _activeSurface->h); @@ -312,8 +319,8 @@ blitSurface(const Graphics::Surface *source, const Common::Rect &r) { } } -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: blitSubSurface(const Graphics::Surface *source, const Common::Rect &r) { byte *dst_ptr = (byte *)_activeSurface->getBasePtr(r.left, r.top); byte *src_ptr = (byte *)source->getBasePtr(0, 0); @@ -331,8 +338,8 @@ blitSubSurface(const Graphics::Surface *source, const Common::Rect &r) { } } -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: blitAlphaBitmap(const Graphics::Surface *source, const Common::Rect &r) { int16 x = r.left; int16 y = r.top; @@ -367,8 +374,8 @@ blitAlphaBitmap(const Graphics::Surface *source, const Common::Rect &r) { } } -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: applyScreenShading(GUI::ThemeEngine::ShadingStyle shadingStyle) { int pixels = _activeSurface->w * _activeSurface->h; PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(0, 0); @@ -376,9 +383,7 @@ applyScreenShading(GUI::ThemeEngine::ShadingStyle shadingStyle) { uint lum; const uint32 shiftMask = (uint32)~( - (1 << PixelFormat::kGreenShift) | - (1 << PixelFormat::kRedShift) | - (1 << PixelFormat::kBlueShift)) >> 1; + (1 << _format.rShift) | (1 << _format.gShift) | (1 << _format.bShift)) >> 1; if (shadingStyle == GUI::ThemeEngine::kShadingDim) { @@ -398,45 +403,44 @@ applyScreenShading(GUI::ThemeEngine::ShadingStyle shadingStyle) { } else if (shadingStyle == GUI::ThemeEngine::kShadingLuminance) { while (pixels--) { - colorToRGB(*ptr, r, g, b); + _format.colorToRGB(*ptr, r, g, b); lum = (r >> 2) + (g >> 1) + (b >> 3); - *ptr++ = RGBToColor(lum, lum, lum); + *ptr++ = _format.RGBToColor(lum, lum, lum); } } } -template -inline void VectorRendererSpec:: +template +inline void VectorRendererSpec:: blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha) { register int idst = *ptr; register int isrc = color; - int rightShift = 8 - PixelFormat::kAlphaBits; - + *ptr = (PixelType)( - (PixelFormat::kRedMask & ((idst & PixelFormat::kRedMask) + - ((int)(((int)(isrc & PixelFormat::kRedMask) - - (int)(idst & PixelFormat::kRedMask)) * alpha) >> 8))) | - (PixelFormat::kGreenMask & ((idst & PixelFormat::kGreenMask) + - ((int)(((int)(isrc & PixelFormat::kGreenMask) - - (int)(idst & PixelFormat::kGreenMask)) * alpha) >> 8))) | - (PixelFormat::kBlueMask & ((idst & PixelFormat::kBlueMask) + - ((int)(((int)(isrc & PixelFormat::kBlueMask) - - (int)(idst & PixelFormat::kBlueMask)) * alpha) >> 8))) | - (PixelFormat::kAlphaMask & ((idst & PixelFormat::kAlphaMask) + - ((alpha >> rightShift) << PixelFormat::kAlphaShift) - - (((int)(idst & PixelFormat::kAlphaMask) * alpha) >> 8)))); + (_redMask & ((idst & _redMask) + + ((int)(((int)(isrc & _redMask) - + (int)(idst & _redMask)) * alpha) >> 8))) | + (_greenMask & ((idst & _greenMask) + + ((int)(((int)(isrc & _greenMask) - + (int)(idst & _greenMask)) * alpha) >> 8))) | + (_blueMask & ((idst & _blueMask) + + ((int)(((int)(isrc & _blueMask) - + (int)(idst & _blueMask)) * alpha) >> 8))) | + (_alphaMask & ((idst & _alphaMask) + + ((alpha >> _format.aLoss) << _format.aShift) - + (((int)(idst & _alphaMask) * alpha) >> 8)))); } -template -inline PixelType VectorRendererSpec:: +template +inline PixelType VectorRendererSpec:: calcGradient(uint32 pos, uint32 max) { PixelType output = 0; pos = (MIN(pos * Base::_gradientFactor, max) << 12) / max; - output |= (_gradientStart + ((Base::_gradientBytes[0] * pos) >> 12)) & PixelFormat::kRedMask; - output |= (_gradientStart + ((Base::_gradientBytes[1] * pos) >> 12)) & PixelFormat::kGreenMask; - output |= (_gradientStart + ((Base::_gradientBytes[2] * pos) >> 12)) & PixelFormat::kBlueMask; - output |= ~(PixelFormat::kRedMask | PixelFormat::kGreenMask | PixelFormat::kBlueMask); + output |= (_gradientStart + ((Base::_gradientBytes[0] * pos) >> 12)) & _redMask; + output |= (_gradientStart + ((Base::_gradientBytes[1] * pos) >> 12)) & _greenMask; + output |= (_gradientStart + ((Base::_gradientBytes[2] * pos) >> 12)) & _blueMask; + output |= ~(_redMask | _greenMask | _blueMask); return output; } @@ -446,8 +450,8 @@ calcGradient(uint32 pos, uint32 max) { * Primitive shapes drawing - Public API calls - VectorRendererSpec * ******************************************************************** ********************************************************************/ -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: drawString(const Graphics::Font *font, const Common::String &text, const Common::Rect &area, Graphics::TextAlign alignH, GUI::ThemeEngine::TextAlignVertical alignV, int deltax, bool ellipsis) { @@ -470,8 +474,8 @@ drawString(const Graphics::Font *font, const Common::String &text, const Common: } /** LINES **/ -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: drawLine(int x1, int y1, int x2, int y2) { x1 = CLIP(x1, 0, (int)Base::_activeSurface->w); x2 = CLIP(x2, 0, (int)Base::_activeSurface->w); @@ -529,8 +533,8 @@ drawLine(int x1, int y1, int x2, int y2) { } /** CIRCLES **/ -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: drawCircle(int x, int y, int r) { if (x + r > Base::_activeSurface->w || y + r > Base::_activeSurface->h || x - r < 0 || y - r < 0 || x == 0 || y == 0 || r <= 0) @@ -568,8 +572,8 @@ drawCircle(int x, int y, int r) { } /** SQUARES **/ -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: drawSquare(int x, int y, int w, int h) { if (x + w > Base::_activeSurface->w || y + h > Base::_activeSurface->h || w <= 0 || h <= 0 || x < 0 || y < 0) @@ -605,8 +609,8 @@ drawSquare(int x, int y, int w, int h) { } /** ROUNDED SQUARES **/ -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: drawRoundedSquare(int x, int y, int r, int w, int h) { if (x + w > Base::_activeSurface->w || y + h > Base::_activeSurface->h || w <= 0 || h <= 0 || x < 0 || y < 0 || r <= 0) @@ -653,8 +657,8 @@ drawRoundedSquare(int x, int y, int r, int w, int h) { drawRoundedSquareFakeBevel(x, y, r, w, h, Base::_bevel); } -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: drawTab(int x, int y, int r, int w, int h) { if (x + w > Base::_activeSurface->w || y + h > Base::_activeSurface->h || w <= 0 || h <= 0 || x < 0 || y < 0 || r > w || r > h) @@ -684,8 +688,8 @@ drawTab(int x, int y, int r, int w, int h) { } } -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: drawTriangle(int x, int y, int w, int h, TriangleOrientation orient) { if (x + w > Base::_activeSurface->w || y + h > Base::_activeSurface->h) @@ -738,8 +742,8 @@ drawTriangle(int x, int y, int w, int h, TriangleOrientation orient) { ******************************************************************** ********************************************************************/ /** TAB ALGORITHM - NON AA */ -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: drawTabAlg(int x1, int y1, int w, int h, int r, PixelType color, VectorRenderer::FillMode fill_m, int baseLeft, int baseRight) { int f, ddF_x, ddF_y; int x, y, px, py; @@ -838,8 +842,8 @@ drawTabAlg(int x1, int y1, int w, int h, int r, PixelType color, VectorRenderer: /** BEVELED TABS FOR CLASSIC THEME **/ -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: drawBevelTabAlg(int x, int y, int w, int h, int bevel, PixelType top_color, PixelType bottom_color, int baseLeft, int baseRight) { int pitch = _activeSurface->pitch / _activeSurface->bytesPerPixel; int i, j; @@ -882,8 +886,8 @@ drawBevelTabAlg(int x, int y, int w, int h, int bevel, PixelType top_color, Pixe } /** SQUARE ALGORITHM **/ -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: drawSquareAlg(int x, int y, int w, int h, PixelType color, VectorRenderer::FillMode fill_m) { PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(x, y); int pitch = _activeSurface->pitch / _activeSurface->bytesPerPixel; @@ -915,8 +919,8 @@ drawSquareAlg(int x, int y, int w, int h, PixelType color, VectorRenderer::FillM } /** SQUARE ALGORITHM **/ -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: drawBevelSquareAlg(int x, int y, int w, int h, int bevel, PixelType top_color, PixelType bottom_color, bool fill) { int pitch = _activeSurface->pitch / _activeSurface->bytesPerPixel; @@ -969,8 +973,8 @@ drawBevelSquareAlg(int x, int y, int w, int h, int bevel, PixelType top_color, P } /** GENERIC LINE ALGORITHM **/ -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: drawLineAlg(int x1, int y1, int x2, int y2, int dx, int dy, PixelType color) { PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(x1, y1); int pitch = _activeSurface->pitch / _activeSurface->bytesPerPixel; @@ -1017,8 +1021,8 @@ drawLineAlg(int x1, int y1, int x2, int y2, int dx, int dy, PixelType color) { } /** VERTICAL TRIANGLE DRAWING ALGORITHM **/ -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: drawTriangleVertAlg(int x1, int y1, int w, int h, bool inverted, PixelType color, VectorRenderer::FillMode fill_m) { int dx = w >> 1, dy = h, gradient_h = 0; int pitch = _activeSurface->pitch / _activeSurface->bytesPerPixel; @@ -1099,8 +1103,8 @@ drawTriangleVertAlg(int x1, int y1, int w, int h, bool inverted, PixelType color /** VERTICAL TRIANGLE DRAWING - FAST VERSION FOR SQUARED TRIANGLES */ -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: drawTriangleFast(int x1, int y1, int size, bool inverted, PixelType color, VectorRenderer::FillMode fill_m) { int pitch = _activeSurface->pitch / _activeSurface->bytesPerPixel; int hstep = 0, dy = size; @@ -1142,8 +1146,8 @@ drawTriangleFast(int x1, int y1, int size, bool inverted, PixelType color, Vecto } /** ROUNDED SQUARE ALGORITHM **/ -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m) { int f, ddF_x, ddF_y; int x, y, px, py; @@ -1233,8 +1237,8 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, Vecto } /** CIRCLE ALGORITHM **/ -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: drawCircleAlg(int x1, int y1, int r, PixelType color, VectorRenderer::FillMode fill_m) { int f, ddF_x, ddF_y; int x, y, px, py, sw = 0; @@ -1284,8 +1288,8 @@ drawCircleAlg(int x1, int y1, int r, PixelType color, VectorRenderer::FillMode f * SHADOW drawing algorithms - VectorRendererSpec ******************* ******************************************************************** ********************************************************************/ -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: drawSquareShadow(int x, int y, int w, int h, int blur) { PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(x + w - 1, y + blur); int pitch = _activeSurface->pitch / _activeSurface->bytesPerPixel; @@ -1320,8 +1324,8 @@ drawSquareShadow(int x, int y, int w, int h, int blur) { } } -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: drawRoundedSquareShadow(int x1, int y1, int r, int w, int h, int blur) { int f, ddF_x, ddF_y; int x, y, px, py; @@ -1368,8 +1372,8 @@ drawRoundedSquareShadow(int x1, int y1, int r, int w, int h, int blur) { } } -template -void VectorRendererSpec:: +template +void VectorRendererSpec:: drawRoundedSquareFakeBevel(int x1, int y1, int r, int w, int h, int amount) { int x, y; const int pitch = _activeSurface->pitch / _activeSurface->bytesPerPixel; @@ -1380,7 +1384,7 @@ drawRoundedSquareFakeBevel(int x1, int y1, int r, int w, int h, int amount) { frac_t T = 0, oldT; uint8 a1, a2; - PixelType color = _bevelColor; //RGBToColor(63, 60, 17); + PixelType color = _bevelColor; //_format.RGBToColor(63, 60, 17); PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r); PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r); @@ -1437,8 +1441,8 @@ drawRoundedSquareFakeBevel(int x1, int y1, int r, int w, int h, int amount) { * ANTIALIASED PRIMITIVES drawing algorithms - VectorRendererAA ********************************************************************/ /** LINES **/ -template -void VectorRendererAA:: +template +void VectorRendererAA:: drawLineAlg(int x1, int y1, int x2, int y2, int dx, int dy, PixelType color) { PixelType *ptr = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1); @@ -1489,8 +1493,8 @@ drawLineAlg(int x1, int y1, int x2, int y2, int dx, int dy, PixelType color) { } /** ROUNDED SQUARES **/ -template -void VectorRendererAA:: +template +void VectorRendererAA:: drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m) { int x, y; const int pitch = Base::_activeSurface->pitch / Base::_activeSurface->bytesPerPixel; @@ -1566,8 +1570,8 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, Vecto } /** CIRCLES **/ -template -void VectorRendererAA:: +template +void VectorRendererAA:: drawCircleAlg(int x1, int y1, int r, PixelType color, VectorRenderer::FillMode fill_m) { int x, y, sw = 0; const int pitch = Base::_activeSurface->pitch / Base::_activeSurface->bytesPerPixel; diff --git a/graphics/VectorRendererSpec.h b/graphics/VectorRendererSpec.h index 045882c955..07d37e1847 100644 --- a/graphics/VectorRendererSpec.h +++ b/graphics/VectorRendererSpec.h @@ -42,21 +42,16 @@ namespace Graphics { * @param PixelType Defines a type which may hold the color value of a single * pixel, such as "byte" or "uint16" for 8 and 16 BPP respectively. * - * @param PixelFormat Defines the type of the PixelFormat struct which contains all - * the actual information of the pixels being used, as declared in "graphics/colormasks.h" - * * TODO: Expand documentation. * * @see VectorRenderer */ -template +template class VectorRendererSpec : public VectorRenderer { typedef VectorRenderer Base; public: - VectorRendererSpec() { - _bitmapAlphaColor = RGBToColor(255, 0, 255); - } + VectorRendererSpec(PixelFormat format); void drawLine(int x1, int y1, int x2, int y2); void drawCircle(int x, int y, int r); @@ -71,9 +66,9 @@ public: const Common::Rect &area, Graphics::TextAlign alignH, GUI::ThemeEngine::TextAlignVertical alignV, int deltax, bool elipsis); - void setFgColor(uint8 r, uint8 g, uint8 b) { _fgColor = RGBToColor(r, g, b); } - void setBgColor(uint8 r, uint8 g, uint8 b) { _bgColor = RGBToColor(r, g, b); } - void setBevelColor(uint8 r, uint8 g, uint8 b) { _bevelColor = RGBToColor(r, g, b); } + void setFgColor(uint8 r, uint8 g, uint8 b) { _fgColor = _format.RGBToColor(r, g, b); } + void setBgColor(uint8 r, uint8 g, uint8 b) { _bgColor = _format.RGBToColor(r, g, b); } + void setBevelColor(uint8 r, uint8 g, uint8 b) { _bevelColor = _format.RGBToColor(r, g, b); } void setGradientColors(uint8 r1, uint8 g1, uint8 b1, uint8 r2, uint8 g2, uint8 b2); void copyFrame(OSystem *sys, const Common::Rect &r); @@ -207,6 +202,9 @@ protected: while (first != last) blendPixelPtr(first++, color, alpha); } + const PixelFormat _format; + const PixelType _redMask, _greenMask, _blueMask, _alphaMask; + PixelType _fgColor; /**< Foreground color currently being used to draw on the renderer */ PixelType _bgColor; /**< Background color currently being used to draw on the renderer */ @@ -231,9 +229,13 @@ protected: * @see VectorRenderer * @see VectorRendererSpec */ -template -class VectorRendererAA : public VectorRendererSpec { - typedef VectorRendererSpec Base; +template +class VectorRendererAA : public VectorRendererSpec { + typedef VectorRendererSpec Base; +public: + VectorRendererAA(PixelFormat format) : VectorRendererSpec(format) { + } + protected: /** * "Wu's Line Antialiasing Algorithm" as published by Xiaolin Wu, July 1991 -- cgit v1.2.3