diff options
author | Willem Jan Palenstijn | 2012-02-20 21:53:17 +0100 |
---|---|---|
committer | Willem Jan Palenstijn | 2012-02-20 22:17:33 +0100 |
commit | 66d3def0e5aa62b1dafe9927682acf3ebc537b6a (patch) | |
tree | 9dfa09682345d58a563e6ba54eecabdcd09487a2 /graphics | |
parent | 19cb2dc7e719ded9b773417627f5475e49baf98a (diff) | |
download | scummvm-rg350-66d3def0e5aa62b1dafe9927682acf3ebc537b6a.tar.gz scummvm-rg350-66d3def0e5aa62b1dafe9927682acf3ebc537b6a.tar.bz2 scummvm-rg350-66d3def0e5aa62b1dafe9927682acf3ebc537b6a.zip |
GUI: Implement AAed tabs
The stroke effect isn't properly implemented yet since it isn't used
in the modern theme.
There are slight bleeding colours around the corners of the
tab_background when its corners overlap with the corners of the
underlying dialog. These are hard to avoid because the underlying dialog
destroys the background that we should be blending these corners with.
Diffstat (limited to 'graphics')
-rw-r--r-- | graphics/VectorRendererSpec.cpp | 193 | ||||
-rw-r--r-- | graphics/VectorRendererSpec.h | 4 |
2 files changed, 175 insertions, 22 deletions
diff --git a/graphics/VectorRendererSpec.cpp b/graphics/VectorRendererSpec.cpp index 5220beec5c..cd012f5f31 100644 --- a/graphics/VectorRendererSpec.cpp +++ b/graphics/VectorRendererSpec.cpp @@ -89,17 +89,25 @@ inline frac_t fp_sqroot(uint32 x) { f += ddF_x + 1; \ } while(0) -#define BE_DRAWCIRCLE(ptr1,ptr2,ptr3,ptr4,x,y,px,py) do { \ +#define BE_DRAWCIRCLE_TOP(ptr1,ptr2,x,y,px,py) do { \ *(ptr1 + (y) - (px)) = color; \ *(ptr1 + (x) - (py)) = color; \ *(ptr2 - (x) - (py)) = color; \ *(ptr2 - (y) - (px)) = color; \ +} while (0) + +#define BE_DRAWCIRCLE_BOTTOM(ptr3,ptr4,x,y,px,py) do { \ *(ptr3 - (y) + (px)) = color; \ *(ptr3 - (x) + (py)) = color; \ *(ptr4 + (x) + (py)) = color; \ *(ptr4 + (y) + (px)) = color; \ } while (0) +#define BE_DRAWCIRCLE(ptr1,ptr2,ptr3,ptr4,x,y,px,py) do { \ + BE_DRAWCIRCLE_TOP(ptr1,ptr2,x,y,px,py); \ + BE_DRAWCIRCLE_BOTTOM(ptr3,ptr4,x,y,px,py); \ +} while (0) + #define BE_DRAWCIRCLE_BCOLOR(ptr1,ptr2,ptr3,ptr4,x,y,px,py) do { \ *(ptr1 + (y) - (px)) = color1; \ *(ptr1 + (x) - (py)) = color1; \ @@ -111,17 +119,26 @@ inline frac_t fp_sqroot(uint32 x) { *(ptr4 + (y) + (px)) = color2; \ } while (0) -#define BE_DRAWCIRCLE_XCOLOR(ptr1,ptr2,ptr3,ptr4,x,y,px,py) do { \ +#define BE_DRAWCIRCLE_XCOLOR_TOP(ptr1,ptr2,x,y,px,py) do { \ *(ptr1 + (y) - (px)) = color1; \ *(ptr1 + (x) - (py)) = color2; \ *(ptr2 - (x) - (py)) = color2; \ *(ptr2 - (y) - (px)) = color1; \ +} while (0) + +#define BE_DRAWCIRCLE_XCOLOR_BOTTOM(ptr3,ptr4,x,y,px,py) do { \ *(ptr3 - (y) + (px)) = color3; \ *(ptr3 - (x) + (py)) = color4; \ *(ptr4 + (x) + (py)) = color4; \ *(ptr4 + (y) + (px)) = color3; \ } while (0) +#define BE_DRAWCIRCLE_XCOLOR(ptr1,ptr2,ptr3,ptr4,x,y,px,py) do { \ + BE_DRAWCIRCLE_XCOLOR_TOP(ptr1,ptr2,x,y,px,py); \ + BE_DRAWCIRCLE_XCOLOR_BOTTOM(ptr3,ptr4,x,y,px,py); \ +} while (0) + + #define BE_RESET() do { \ f = 1 - r; \ ddF_x = 0; ddF_y = -2 * r; \ @@ -151,30 +168,47 @@ inline frac_t fp_sqroot(uint32 x) { ptr_left += pitch; /** HELPER MACROS for WU's circle drawing algorithm **/ -#define WU_DRAWCIRCLE(ptr1,ptr2,ptr3,ptr4,x,y,px,py,a) do { \ +#define WU_DRAWCIRCLE_TOP(ptr1,ptr2,x,y,px,py,a) do { \ this->blendPixelPtr(ptr1 + (y) - (px), color, a); \ this->blendPixelPtr(ptr1 + (x) - (py), color, a); \ this->blendPixelPtr(ptr2 - (x) - (py), color, a); \ this->blendPixelPtr(ptr2 - (y) - (px), color, a); \ +} while (0) + +#define WU_DRAWCIRCLE_BOTTOM(ptr3,ptr4,x,y,px,py,a) do { \ this->blendPixelPtr(ptr3 - (y) + (px), color, a); \ this->blendPixelPtr(ptr3 - (x) + (py), color, a); \ this->blendPixelPtr(ptr4 + (x) + (py), color, a); \ this->blendPixelPtr(ptr4 + (y) + (px), color, a); \ } while (0) +#define WU_DRAWCIRCLE(ptr1,ptr2,ptr3,ptr4,x,y,px,py,a) do { \ + WU_DRAWCIRCLE_TOP(ptr1,ptr2,x,y,px,py,a); \ + WU_DRAWCIRCLE_BOTTOM(ptr3,ptr4,x,y,px,py,a); \ +} while (0) + + // Color depending on y // Note: this is only for the outer pixels -#define WU_DRAWCIRCLE_XCOLOR(ptr1,ptr2,ptr3,ptr4,x,y,px,py,a,func) do { \ +#define WU_DRAWCIRCLE_XCOLOR_TOP(ptr1,ptr2,x,y,px,py,a,func) do { \ this->func(ptr1 + (y) - (px), color1, a); \ this->func(ptr1 + (x) - (py), color2, a); \ this->func(ptr2 - (x) - (py), color2, a); \ this->func(ptr2 - (y) - (px), color1, a); \ +} while (0) + +#define WU_DRAWCIRCLE_XCOLOR_BOTTOM(ptr3,ptr4,x,y,px,py,a,func) do { \ this->func(ptr3 - (y) + (px), color3, a); \ this->func(ptr3 - (x) + (py), color4, a); \ this->func(ptr4 + (x) + (py), color4, a); \ this->func(ptr4 + (y) + (px), color3, a); \ } while (0) +#define WU_DRAWCIRCLE_XCOLOR(ptr1,ptr2,ptr3,ptr4,x,y,px,py,a,func) do { \ + WU_DRAWCIRCLE_XCOLOR_TOP(ptr1,ptr2,x,y,px,py,a,func); \ + WU_DRAWCIRCLE_XCOLOR_BOTTOM(ptr3,ptr4,x,y,px,py,a,func); \ +} while (0) + // Color depending on corner (tl,tr,bl: color1, br: color2) // Note: this is only for the outer pixels #define WU_DRAWCIRCLE_BCOLOR(ptr1,ptr2,ptr3,ptr4,x,y,px,py,a) do { \ @@ -767,10 +801,14 @@ drawTab(int x, int y, int r, int w, int h) { switch (Base::_fillMode) { case kFillDisabled: + // FIXME: Implement this return; case kFillGradient: case kFillBackground: + // FIXME: This is broken for the AA renderer. + // See the rounded rect alg for how to fix it. (The border should + // be drawn before the interior, both inside drawTabAlg.) drawTabAlg(x, y, w, h, r, (Base::_fillMode == kFillBackground) ? _bgColor : _fgColor, Base::_fillMode); if (Base::_strokeWidth) drawTabAlg(x, y, w, h, r, _fgColor, kFillDisabled, (Base::_dynamicData >> 16), (Base::_dynamicData & 0xFFFF)); @@ -887,17 +925,10 @@ drawTabAlg(int x1, int y1, int w, int h, int r, PixelType color, VectorRenderer: 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; + BE_DRAWCIRCLE_TOP(ptr_tr, ptr_tl, x, y, px, py); - if (Base::_strokeWidth > 1) { - *(ptr_tr + (y) - (px - pitch)) = color; - *(ptr_tr + (x) - (py)) = color; - *(ptr_tl - (x) - (py)) = color; - *(ptr_tl - (y) - (px - pitch)) = color; - } + if (Base::_strokeWidth > 1) + BE_DRAWCIRCLE_TOP(ptr_tr, ptr_tl, x, y, px - pitch, py); } } @@ -943,18 +974,12 @@ drawTabAlg(int x1, int y1, int w, int h, int r, PixelType color, VectorRenderer: gradientFill(ptr_tl - x - py, w - 2 * r + 2 * x, x1 + r - x - y, real_radius - y); gradientFill(ptr_tl - y - px, w - 2 * r + 2 * y, x1 + r - y - x, real_radius - x); - *(ptr_tr + (y) - (px)) = color1; - *(ptr_tr + (x) - (py)) = color2; - *(ptr_tl - (x) - (py)) = color2; - *(ptr_tl - (y) - (px)) = color1; + BE_DRAWCIRCLE_XCOLOR_TOP(ptr_tr, ptr_tl, x, y, px, py); } else { colorFill<PixelType>(ptr_tl - x - py, ptr_tr + x - py, color); colorFill<PixelType>(ptr_tl - y - px, ptr_tr + y - px, color); - *(ptr_tr + (y) - (px)) = color; - *(ptr_tr + (x) - (py)) = color; - *(ptr_tl - (x) - (py)) = color; - *(ptr_tl - (y) - (px)) = color; + BE_DRAWCIRCLE_TOP(ptr_tr, ptr_tl, x, y, px, py); } } @@ -1718,6 +1743,130 @@ drawLineAlg(int x1, int y1, int x2, int y2, int dx, int dy, PixelType color) { Base::putPixel(x2, y2, color); } +/** TAB ALGORITHM */ +template<typename PixelType> +void VectorRendererAA<PixelType>:: +drawTabAlg(int x1, int y1, int w, int h, int r, PixelType color, VectorRenderer::FillMode fill_m, int baseLeft, int baseRight) { + int x, y, px, py; + int pitch = Base::_activeSurface->pitch / Base::_activeSurface->format.bytesPerPixel; + int sw = 0, sp = 0, hp = 0; + + frac_t T = 0, oldT; + uint8 a1, a2; + uint32 rsq = r*r; + + 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; + + if (fill_m == Base::kFillDisabled) { + color = 0; + while (sw++ < Base::_strokeWidth) { + colorFill<PixelType>(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color); + colorFill<PixelType>(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color); + sp += pitch; + + x = r - (sw - 1); + y = 0; + T = 0; + px = pitch * x; + py = 0; + + + while (x > y++) { + WU_ALGORITHM(); + + // sw == 1: outside, sw = _strokeWidth: inside + if (sw != Base::_strokeWidth) + a2 = 255; + + // inner arc + WU_DRAWCIRCLE_TOP(ptr_tr, ptr_tl, x, y, px, py, a2); + + if (sw == 1) // outer arc + WU_DRAWCIRCLE_TOP(ptr_tr, ptr_tl, x, y, px - pitch, py, a1); + } + } + + int short_h = h - r + 2; + + ptr_fill += pitch * real_radius; + while (short_h--) { + colorFill<PixelType>(ptr_fill, ptr_fill + Base::_strokeWidth, color); + colorFill<PixelType>(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color); + ptr_fill += pitch; + } + + if (baseLeft) { + sw = 0; + ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1 + h + 1); + while (sw++ < Base::_strokeWidth) { + colorFill<PixelType>(ptr_fill - baseLeft, ptr_fill, color); + ptr_fill += pitch; + } + } + + if (baseRight) { + sw = 0; + ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w, y1 + h + 1); + while (sw++ < Base::_strokeWidth) { + colorFill<PixelType>(ptr_fill, ptr_fill + baseRight, color); + ptr_fill += pitch; + } + } + } else { + PixelType color1, color2; + color1 = color2 = color; + + int long_h = h; + int short_h = h - real_radius + 2; + x = real_radius; + y = 0; + T = 0; + px = pitch * x; + py = 0; + + Base::precalcGradient(long_h); + + while (x > y++) { + WU_ALGORITHM(); + + if (fill_m == Base::kFillGradient) { + color1 = Base::calcGradient(real_radius - x, long_h); + color2 = Base::calcGradient(real_radius - y, long_h); + + gradientFill(ptr_tl - x - py + 1, w - 2 * r + 2 * x - 1, x1 + r - x - y + 1, real_radius - y); + + // Only fill each horizontal line once (or we destroy + // the gradient effect at the edges) + if (T < oldT || y == 1) + gradientFill(ptr_tl - y - px + 1, w - 2 * r + 2 * y - 1, x1 + r - y - x + 1, real_radius - x); + + WU_DRAWCIRCLE_XCOLOR_TOP(ptr_tr, ptr_tl, x, y, px, py, a1, Base::blendPixelPtr); + } else { + colorFill<PixelType>(ptr_tl - x - py + 1, ptr_tr + x - py, color); + if (T < oldT || y == 1) + colorFill<PixelType>(ptr_tl - y - px + 1, ptr_tr + y - px, color); + + WU_DRAWCIRCLE_TOP(ptr_tr, ptr_tl, x, y, px, py, a1); + } + } + + ptr_fill += pitch * r; + while (short_h--) { + if (fill_m == Base::kFillGradient) { + gradientFill(ptr_fill, w + 1, x1, real_radius++); + } else { + colorFill<PixelType>(ptr_fill, ptr_fill + w + 1, color); + } + ptr_fill += pitch; + } + } +} + + /** ROUNDED SQUARES **/ template<typename PixelType> void VectorRendererAA<PixelType>:: diff --git a/graphics/VectorRendererSpec.h b/graphics/VectorRendererSpec.h index d8fc82a6f1..4ed80cb55f 100644 --- a/graphics/VectorRendererSpec.h +++ b/graphics/VectorRendererSpec.h @@ -297,6 +297,10 @@ protected: // VectorRenderer::applyConvolutionMatrix(VectorRenderer::kConvolutionHardBlur, // Common::Rect(x, y, x + w + blur * 2, y + h + blur * 2)); } + + virtual void drawTabAlg(int x, int y, int w, int h, int r, + PixelType color, VectorRenderer::FillMode fill_m, + int baseLeft = 0, int baseRight = 0); }; #endif |