diff options
Diffstat (limited to 'graphics/VectorRenderer.cpp')
-rw-r--r-- | graphics/VectorRenderer.cpp | 293 |
1 files changed, 187 insertions, 106 deletions
diff --git a/graphics/VectorRenderer.cpp b/graphics/VectorRenderer.cpp index 67a60bbde1..d840b5d35a 100644 --- a/graphics/VectorRenderer.cpp +++ b/graphics/VectorRenderer.cpp @@ -62,10 +62,11 @@ void vector_renderer_test(OSystem *_system) { vr->setFgColor(255, 255, 255); vr->fillSurface(); - vr->setFgColor(255, 0, 0 ); - vr->setBgColor(25, 25, 175 ); - vr->setFillMode( VectorRenderer::kBackgroundFill ); - vr->shadowEnable( 5, 5 ); + vr->setFgColor(255, 0, 0); + vr->setBgColor(25, 25, 175); + vr->setFillMode(VectorRenderer::kBackgroundFill); + vr->setStrokeWidth(3); + vr->shadowEnable(1, 1); vr->drawLine(25, 25, 125, 300); vr->drawCircle(250, 250, 100); @@ -87,7 +88,86 @@ void vector_renderer_test(OSystem *_system) { template<typename PixelType, typename PixelFormat> void VectorRendererSpec<PixelType, PixelFormat>:: +drawCircle(int x, int y, int r) { + if (Base::_fillMode != kNoFill && Base::_shadows) { + drawCircleAlg(x + Base::_shadowXOffset + 1, y + Base::_shadowYOffset + 1, r, 0, true); + } + + switch(Base::_fillMode) { + case kNoFill: + drawCircleAlg(x, y, r, _fgColor, false); + break; + + case kForegroundFill: + drawCircleAlg(x, y, r, _fgColor, true); + break; + + case kBackgroundFill: + VectorRendererSpec::drawCircleAlg(x, y, r - 1, _bgColor, true); + drawCircleAlg(x, y, r, _fgColor, false); + break; + + case kGradientFill: + break; + } +} + +template<typename PixelType, typename PixelFormat> +void VectorRendererSpec<PixelType, PixelFormat>:: +drawSquare(int x, int y, int w, int h) { + if (Base::_fillMode != kNoFill && Base::_shadows) { + drawSquareAlg(x + Base::_shadowXOffset + 1, y + Base::_shadowYOffset + 1, w, h, 0, true); + } + + switch(Base::_fillMode) { + case kNoFill: + drawSquareAlg(x, y, w, h, _fgColor, false); + break; + + case kForegroundFill: + drawSquareAlg(x, y, w, h, _fgColor, true); + break; + + case kBackgroundFill: + drawSquareAlg(x, y, w, h, _bgColor, true); + drawSquareAlg(x, y, w, h, _fgColor, false); + break; + + case kGradientFill: + break; + } +} + +template<typename PixelType, typename PixelFormat> +void VectorRendererSpec<PixelType, PixelFormat>:: +drawRoundedSquare(int x, int y, int r, int w, int h) { + if (Base::_fillMode != kNoFill && Base::_shadows) { + drawRoundedSquareAlg(x + Base::_shadowXOffset + 1, y + Base::_shadowYOffset + 1, r, w, h, 0, true); + } + + switch(Base::_fillMode) { + case kNoFill: + drawRoundedSquareAlg(x, y, r, w, h, _fgColor, false); + break; + + case kForegroundFill: + drawRoundedSquareAlg(x, y, r, w, h, _fgColor, true); + break; + + case kBackgroundFill: + VectorRendererSpec::drawRoundedSquareAlg(x + 1, y + 1, r, w - 1, h - 1, _bgColor, true); + drawRoundedSquareAlg(x, y, r, w, h, _fgColor, false); + break; + + case kGradientFill: + break; + } +} + +template<typename PixelType, typename PixelFormat> +void VectorRendererSpec<PixelType, PixelFormat>:: drawSquareAlg(int x, int y, int w, int h, PixelType color, bool fill) { + PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(x, y); int pitch = Base::surfacePitch(); @@ -97,12 +177,17 @@ drawSquareAlg(int x, int y, int w, int h, PixelType color, bool fill) { ptr += pitch; } } else { - Common::set_to(ptr, ptr + w, color); - Common::set_to(ptr + pitch * h, ptr + w + pitch * h, color); + int sw = _strokeWidth, sp = 0, hp = pitch * (h - 1); + + while(sw--) { + Common::set_to(ptr + sp, ptr + w + sp, color); + Common::set_to(ptr + hp - sp, ptr + w + hp - sp, color); + sp += pitch; + } while (h--) { - *ptr = color; - *(ptr + w) = color; + Common::set_to(ptr, ptr + _strokeWidth, color); + Common::set_to(ptr + w - _strokeWidth, ptr + w, color); ptr += pitch; } } @@ -159,6 +244,11 @@ drawLineAlg(int x1, int y1, int x2, int y2, int dx, int dy, PixelType color) { template<typename PixelType, typename PixelFormat> void VectorRendererAA<PixelType, PixelFormat>:: blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha) { + if (alpha == 255) { + *ptr = color; + return; + } + register int idst = *ptr; register int isrc = color; @@ -283,7 +373,7 @@ inline uint32 fp_sqroot(uint32 x) { remHI = (remHI << 2) | (remLO >> 30); remLO <<= 2; root <<= 1; - testDIV = (root << 1 ) + 1; + testDIV = (root << 1) + 1; if (remHI >= testDIV) { remHI -= testDIV; @@ -343,12 +433,35 @@ drawCircleAlg(int x1, int y1, int r, PixelType color, bool fill) { } } +#define __WU_DRAWCIRCLE(ptr1,ptr2,ptr3,ptr4,x,y,px,py,a) { \ + blendPixelPtr(ptr1 + (y) - (px), color, a); \ + blendPixelPtr(ptr1 + (x) - (py), color, a); \ + blendPixelPtr(ptr2 - (x) - (py), color, a); \ + blendPixelPtr(ptr2 - (y) - (px), color, a); \ + blendPixelPtr(ptr3 - (y) + (px), color, a); \ + blendPixelPtr(ptr3 - (x) + (py), color, a); \ + blendPixelPtr(ptr4 + (x) + (py), color, a); \ + blendPixelPtr(ptr4 + (y) + (px), color, a); \ +} + +#define __WU_ALGORITHM() { \ + oldT = T; \ + T = fp_sqroot(rsq - ((y * y) << 16)) ^ 0xFFFF; \ + py += p; \ + if (T < oldT) { \ + x--; px -= p; \ + } \ + a2 = (T >> 8); \ + a1 = ~a2; \ +} + template<typename PixelType, typename PixelFormat> void VectorRendererAA<PixelType, PixelFormat>:: drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, bool fill) { - int x = r; - int y = 0; + int x, y; int p = Base::surfacePitch(), px, py; + int sw = 0, sp = 0, hp = h * p; + uint32 rsq = (r * r) << 16; uint32 T = 0, oldT; uint8 a1, a2; @@ -359,137 +472,105 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, bool PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r); PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1); - Common::set_to(ptr_fill + r, ptr_fill + w - r + 1, color); - Common::set_to(ptr_fill + r + h*p, ptr_fill + w - r + 1 + h*p, color); - - h -= 2*r; - ptr_fill += p*r; - - if (!fill) { - while (h-- >= 0) { - *(ptr_fill) = (PixelType)color; - *(ptr_fill + w) = (PixelType)color; - ptr_fill += p; - } - } else { - while (h-- >= 0) { - Common::set_to(ptr_fill, ptr_fill + w + 1, color); - ptr_fill += p; - } - } + int short_h = h - 2 * r; - px = p * x; - py = 0; + if (fill == false) { + while (sw++ < Base::_strokeWidth) { + Common::set_to(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color); + Common::set_to(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color); + sp += p; - while (x > y++) - { - oldT = T; - T = fp_sqroot(rsq - ((y * y) << 16)) ^ 0xFFFF; + x = r - (sw - 1); y = 0; T = 0; + px = p * x; py = 0; + + while (x > y++) { + __WU_ALGORITHM(); - py += p; + if (sw != 1 && sw != Base::_strokeWidth) + a2 = a1 = 255; - if (T < oldT) { - x--; - px -= p; + __WU_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, (x - 1), y, (px - p), py, a2); + __WU_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1); + } } - a2 = (T >> 8); - a1 = ~a2; + ptr_fill += p * r; + while (short_h-- >= 0) { + Common::set_to(ptr_fill, ptr_fill + _strokeWidth, color); + Common::set_to(ptr_fill + w - _strokeWidth + 1, ptr_fill + w + 1, color); + ptr_fill += p; + } + } else { + x = r; y = 0; T = 0; + px = p * x; py = 0; + + while (x > y++) { + __WU_ALGORITHM(); - if (fill) { Common::set_to(ptr_tl - x - py, ptr_tr + x - py, color); Common::set_to(ptr_tl - y - px, ptr_tr + y - px, color); Common::set_to(ptr_bl - x + py, ptr_br + x + py, color); Common::set_to(ptr_bl - y + px, ptr_br + y + px, color); - } else { - blendPixelPtr(ptr_tr + y - (px-p), color, a2); - blendPixelPtr(ptr_tr + x - 1 - py, color, a2); - blendPixelPtr(ptr_tl - x + 1 - py, color, a2); - blendPixelPtr(ptr_tl - y - (px-p), color, a2); - - blendPixelPtr(ptr_bl - y + (px-p), color, a2); - blendPixelPtr(ptr_bl - x + 1 + py, color, a2); - - blendPixelPtr(ptr_br + x - 1 + py, color, a2); - blendPixelPtr(ptr_br + y + (px-p), color, a2); - } - - blendPixelPtr(ptr_tr + y - px, color, a1); - blendPixelPtr(ptr_tr + x - py, color, a1); - - blendPixelPtr(ptr_tl - x - py, color, a1); - blendPixelPtr(ptr_tl - y - px, color, a1); - - blendPixelPtr(ptr_bl - y + px, color, a1); - blendPixelPtr(ptr_bl - x + py, color, a1); + __WU_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1); + } - blendPixelPtr(ptr_br + x + py, color, a1); - blendPixelPtr(ptr_br + y + px, color, a1); + ptr_fill += p * r; + while (short_h-- >= 0) { + Common::set_to(ptr_fill, ptr_fill + w + 1, color); + ptr_fill += p; + } } } template<typename PixelType, typename PixelFormat> void VectorRendererAA<PixelType, PixelFormat>:: drawCircleAlg(int x1, int y1, int r, PixelType color, bool fill) { - int x = r; - int y = 0; - int p = Base::surfacePitch(), px = 0, py = 0; + int x, y, sw = 0; + int p = Base::surfacePitch(), px, py; + uint32 rsq = (r * r) << 16; uint32 T = 0, oldT; uint8 a1, a2; PixelType *ptr = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1); - px = p * x; - py = p * y; - *(ptr + x) = (PixelType)color; - *(ptr - x) = (PixelType)color; - *(ptr + px) = (PixelType)color; - *(ptr - px) = (PixelType)color; - - if (fill) Common::set_to(ptr - x, ptr + x, color); + if (fill == false) { + while (sw++ < Base::_strokeWidth) { + x = r - (sw - 1); y = 0; T = 0; + px = p * x; py = 0; - while (x > y++) - { - oldT = T; - T = fp_sqroot(rsq - ((y * y) << 16)) ^ 0xFFFF; + *(ptr + x) = (PixelType)color; + *(ptr - x) = (PixelType)color; + *(ptr + px) = (PixelType)color; + *(ptr - px) = (PixelType)color; - py += p; + while (x > y++) { + __WU_ALGORITHM(); - if (T < oldT) { - x--; - px -= p; + if (sw != 1 && sw != Base::_strokeWidth) + a2 = a1 = 255; + + __WU_DRAWCIRCLE(ptr, ptr, ptr, ptr, (x - 1), y, (px - p), py, a2); + __WU_DRAWCIRCLE(ptr, ptr, ptr, ptr, x, y, px, py, a1); + } } + } else { + Common::set_to(ptr - r, ptr + r + 1, color); + x = r; y = 0; T = 0; + px = p * x; py = 0; - a2 = (T >> 8); - a1 = ~a2; + while (x > y++) { + __WU_ALGORITHM(); - if (fill) { Common::set_to(ptr - x + py, ptr + x + py, color); Common::set_to(ptr - x - py, ptr + x - py, color); Common::set_to(ptr - y + px, ptr + y + px, color); Common::set_to(ptr - y - px, ptr + y - px, color); - } else { - blendPixelPtr(ptr + x - 1 + py, color, a2); - blendPixelPtr(ptr + y - (px-p), color, a2); - blendPixelPtr(ptr - x + 1 - py, color, a2); - blendPixelPtr(ptr - y - (px-p), color, a2); - blendPixelPtr(ptr - y + (px-p), color, a2); - blendPixelPtr(ptr - x + 1 + py, color, a2); - blendPixelPtr(ptr + y + (px-p), color, a2); - blendPixelPtr(ptr + x - 1 - py, color, a2); - } - - blendPixelPtr(ptr + x + py, color, a1); - blendPixelPtr(ptr + y - px, color, a1); - blendPixelPtr(ptr - x - py, color, a1); - blendPixelPtr(ptr - y - px, color, a1); - blendPixelPtr(ptr - y + px, color, a1); - blendPixelPtr(ptr - x + py, color, a1); - blendPixelPtr(ptr + y + px, color, a1); - blendPixelPtr(ptr + x - py, color, a1); + + __WU_DRAWCIRCLE(ptr, ptr, ptr, ptr, x, y, px, py, a1); + } } } |