diff --git a/graphics/VectorRenderer.cpp b/graphics/VectorRenderer.cpp index a95564789e2..aa0fad36c80 100644 --- a/graphics/VectorRenderer.cpp +++ b/graphics/VectorRenderer.cpp @@ -402,8 +402,13 @@ drawTab(int x, int y, int r, int w, int h) { return; case kFillGradient: - case kFillForeground: case kFillBackground: + drawTabAlg(x, y, w, h, r, (Base::_fillMode == kFillBackground) ? _bgColor : _fgColor, Base::_fillMode); + if (Base::_strokeWidth) + drawTabAlg(x, y, w, h, r, _fgColor, kFillDisabled); + break; + + case kFillForeground: drawTabAlg(x, y, w, h, r, (Base::_fillMode == kFillBackground) ? _bgColor : _fgColor, Base::_fillMode); break; } @@ -471,44 +476,82 @@ drawTabAlg(int x1, int y1, int w, int h, int r, PixelType color, VectorRenderer: int f, ddF_x, ddF_y; int x, y, px, py; int pitch = Base::surfacePitch(); + int sw = 0, sp = 0, hp = 0; PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r); PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r); PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1); int real_radius = r; - int short_h = h - (r) + 2; + int short_h = h - r + 2; int long_h = h; - - __BE_RESET(); PixelType color1, color2; if (fill_m == kFillForeground || fill_m == kFillBackground) color1 = color2 = color; - - while (x++ < y) { - __BE_ALGORITHM(); - if (fill_m == kFillGradient) { - color1 = calcGradient(real_radius - x, long_h); - color2 = calcGradient(real_radius - y, long_h); + if (fill_m == kFillDisabled) { + while (sw++ < Base::_strokeWidth) { + colorFill(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color); + colorFill(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color); + sp += pitch; + + __BE_RESET(); + r--; + + while (x++ < y) { + __BE_ALGORITHM(); + *(ptr_tr + (y) - (px)) = color; + *(ptr_tr + (x) - (py)) = color; + *(ptr_tl - (x) - (py)) = color; + *(ptr_tl - (y) - (px)) = color; + + if (Base::_strokeWidth > 1) { + *(ptr_tr + (y) - (px)) = color; + *(ptr_tr + (x - 1) - (py)) = color; + *(ptr_tl - (x - 1) - (py)) = color; + *(ptr_tl - (y) - (px)) = color; + *(ptr_tr + (y) - (px - pitch)) = color; + *(ptr_tr + (x) - (py)) = color; + *(ptr_tl - (x) - (py)) = color; + *(ptr_tl - (y) - (px - pitch)) = color; + } + } } + + ptr_fill += pitch * real_radius; + while (short_h--) { + colorFill(ptr_fill, ptr_fill + Base::_strokeWidth, color); + colorFill(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color); + ptr_fill += pitch; + } + } else { + __BE_RESET(); - colorFill(ptr_tl - x - py, ptr_tr + x - py, color2); - colorFill(ptr_tl - y - px, ptr_tr + y - px, color1); - - *(ptr_tr + (y) - (px)) = color; - *(ptr_tr + (x) - (py)) = color; - *(ptr_tl - (x) - (py)) = color; - *(ptr_tl - (y) - (px)) = color; - } - - ptr_fill += pitch * r; - while (short_h--) { - if (fill_m == kFillGradient) - color = calcGradient(real_radius++, long_h); - colorFill(ptr_fill, ptr_fill + w + 1, color); - ptr_fill += pitch; + while (x++ < y) { + __BE_ALGORITHM(); + + if (fill_m == kFillGradient) { + color1 = calcGradient(real_radius - x, long_h); + color2 = calcGradient(real_radius - y, long_h); + } + + colorFill(ptr_tl - x - py, ptr_tr + x - py, color2); + colorFill(ptr_tl - y - px, ptr_tr + y - px, color1); + + *(ptr_tr + (y) - (px)) = color1; + *(ptr_tr + (x) - (py)) = color2; + *(ptr_tl - (x) - (py)) = color2; + *(ptr_tl - (y) - (px)) = color1; + } + + ptr_fill += pitch * r; + while (short_h--) { + if (fill_m == kFillGradient) + color = calcGradient(real_radius++, long_h); + colorFill(ptr_fill, ptr_fill + w + 1, color); + ptr_fill += pitch; + } } } diff --git a/gui/ThemeDefaultXML.cpp b/gui/ThemeDefaultXML.cpp index 0561f4b8d1c..bbd18fce5ce 100644 --- a/gui/ThemeDefaultXML.cpp +++ b/gui/ThemeDefaultXML.cpp @@ -63,7 +63,7 @@ bool ThemeRenderer::loadDefaultXML() { "" "" - "" + "" "" "" diff --git a/gui/ThemeRenderer.cpp b/gui/ThemeRenderer.cpp index 7995c34a40d..4b56eba4a2f 100644 --- a/gui/ThemeRenderer.cpp +++ b/gui/ThemeRenderer.cpp @@ -76,7 +76,7 @@ const char *ThemeRenderer::kDrawDataStrings[] = { ThemeRenderer::ThemeRenderer(Common::String themeName, GraphicsMode mode) : _vectorRenderer(0), _system(0), _graphicsMode(kGfxDisabled), - _screen(0), _bytesPerPixel(0), _initOk(false), _themeOk(false), _enabled(false) { + _screen(0), _backBuffer(0), _bytesPerPixel(0), _initOk(false), _themeOk(false), _enabled(false) { _system = g_system; _parser = new ThemeParser(this); @@ -153,9 +153,15 @@ void ThemeRenderer::disable() { } template -void ThemeRenderer::screenInit() { +void ThemeRenderer::screenInit(bool backBuffer) { freeScreen(); - + freeBackbuffer(); + + if (backBuffer) { + _backBuffer = new Surface; + _backBuffer->create(_system->getOverlayWidth(), _system->getOverlayHeight(), sizeof(PixelType)); + } + _screen = new Surface; _screen->create(_system->getOverlayWidth(), _system->getOverlayHeight(), sizeof(PixelType)); _system->clearOverlay(); @@ -166,7 +172,7 @@ void ThemeRenderer::setGraphicsMode(GraphicsMode mode) { case kGfxStandard16bit: case kGfxAntialias16bit: _bytesPerPixel = sizeof(uint16); - screenInit(); + screenInit(kEnableBackCaching); break; default: diff --git a/gui/ThemeRenderer.h b/gui/ThemeRenderer.h index 3addda17a76..e7e320d0481 100644 --- a/gui/ThemeRenderer.h +++ b/gui/ThemeRenderer.h @@ -73,6 +73,9 @@ class ThemeRenderer : public Theme { /** Constant value to expand dirty rectangles, to make sure they are fully copied */ static const int kDirtyRectangleThreshold = 2; + + /** Sets whether backcaching is enabled */ + static const bool kEnableBackCaching = true; public: enum GraphicsMode { @@ -204,7 +207,7 @@ public: void setGraphicsMode(GraphicsMode mode); protected: - template void screenInit(); + template void screenInit(bool backBuffer); bool loadThemeXML(Common::String themeName); bool loadDefaultXML(); @@ -228,6 +231,14 @@ protected: delete _vectorRenderer; _vectorRenderer = 0; } + + void freeBackbuffer() { + if (_backBuffer != 0) { + _backBuffer->free(); + delete _backBuffer; + _backBuffer = 0; + } + } void freeScreen() { if (_screen != 0) { @@ -283,6 +294,7 @@ protected: GUI::ThemeParser *_parser; Graphics::Surface *_screen; + Graphics::Surface *_backBuffer; int _bytesPerPixel; GraphicsMode _graphicsMode;