diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h index 5afdd546aea6..38185f1a7bd4 100644 --- a/graphics/VectorRenderer.h +++ b/graphics/VectorRenderer.h @@ -151,6 +151,7 @@ class VectorRenderer { * @param r Radius of the circle. */ virtual void drawCircle(int x, int y, int r) = 0; + virtual void drawCircleClip(int x, int y, int r, Common::Rect clipping) = 0; /** * Draws a square starting at (x,y) with the given width and height. @@ -358,16 +359,16 @@ class VectorRenderer { /** * DrawStep callback functions for each drawing feature */ - void drawCallback_CIRCLE(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) { //TODO + void drawCallback_CIRCLE(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) { uint16 x, y, w, h, radius; radius = stepGetRadius(step, area); stepGetPositions(step, area, x, y, w, h); - drawCircle(x + radius, y + radius, radius); + drawCircleClip(x + radius, y + radius, radius, clip); } - void drawCallback_SQUARE(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) { //TODO + void drawCallback_SQUARE(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) { uint16 x, y, w, h; stepGetPositions(step, area, x, y, w, h); drawSquareClip(x, y, w, h, clip); @@ -389,7 +390,7 @@ class VectorRenderer { fillSurface(); } - void drawCallback_TRIANGLE(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) { //TODO + void drawCallback_TRIANGLE(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) { uint16 x, y, w, h; stepGetPositions(step, area, x, y, w, h); drawTriangleClip(x, y, w, h, (TriangleOrientation)step.extraData, clip); diff --git a/graphics/VectorRendererSpec.cpp b/graphics/VectorRendererSpec.cpp index a0091a6f38d5..cbabdc7caf59 100644 --- a/graphics/VectorRendererSpec.cpp +++ b/graphics/VectorRendererSpec.cpp @@ -1069,6 +1069,69 @@ drawCircle(int x, int y, int r) { } } +template +void VectorRendererSpec:: +drawCircleClip(int x, int y, int r, Common::Rect clipping) { + if (x + r > Base::_activeSurface->w || y + r > Base::_activeSurface->h || + x - r < 0 || y - r < 0 || x == 0 || y == 0 || r <= 0) + return; + + Common::Rect backup = _clippingArea; + _clippingArea = clipping; + bool useClippingVersions = !(_clippingArea.isEmpty() || _clippingArea.contains(Common::Rect(x - r, y - r, x + r, y + r))); + + if (Base::_fillMode != kFillDisabled && Base::_shadowOffset + && x + r + Base::_shadowOffset < Base::_activeSurface->w + && y + r + Base::_shadowOffset < Base::_activeSurface->h) { + if (useClippingVersions) + drawCircleAlgClip(x + Base::_shadowOffset + 1, y + Base::_shadowOffset + 1, r, 0, kFillForeground); + else + drawCircleAlg(x + Base::_shadowOffset + 1, y + Base::_shadowOffset + 1, r, 0, kFillForeground); + } + + switch (Base::_fillMode) { + case kFillDisabled: + if (Base::_strokeWidth) + if (useClippingVersions) + drawCircleAlgClip(x, y, r, _fgColor, kFillDisabled); + else + drawCircleAlg(x, y, r, _fgColor, kFillDisabled); + break; + + case kFillForeground: + if (useClippingVersions) + drawCircleAlgClip(x, y, r, _fgColor, kFillForeground); + else + drawCircleAlg(x, y, r, _fgColor, kFillForeground); + break; + + case kFillBackground: + if (Base::_strokeWidth > 1) { + if (useClippingVersions) { + drawCircleAlgClip(x, y, r, _fgColor, kFillForeground); + drawCircleAlgClip(x, y, r - Base::_strokeWidth, _bgColor, kFillBackground); + } else { + drawCircleAlg(x, y, r, _fgColor, kFillForeground); + drawCircleAlg(x, y, r - Base::_strokeWidth, _bgColor, kFillBackground); + } + } else { + if (useClippingVersions) { + drawCircleAlgClip(x, y, r, _bgColor, kFillBackground); + drawCircleAlgClip(x, y, r, _fgColor, kFillDisabled); + } else { + drawCircleAlg(x, y, r, _bgColor, kFillBackground); + drawCircleAlg(x, y, r, _fgColor, kFillDisabled); + } + } + break; + + case kFillGradient: + break; + } + + _clippingArea = backup; +} + /** SQUARES **/ template void VectorRendererSpec:: @@ -2677,7 +2740,47 @@ drawCircleAlg(int x1, int y1, int r, PixelType color, VectorRenderer::FillMode f } +template +void VectorRendererSpec:: +drawCircleAlgClip(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; + int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel; + PixelType *ptr = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1); + + if (fill_m == kFillDisabled) { + while (sw++ < Base::_strokeWidth) { + BE_RESET(); + r--; + + if (IS_IN_CLIP(x1 + y, y1)) *(ptr + y) = color; + if (IS_IN_CLIP(x1 - y, y1)) *(ptr - y) = color; + if (IS_IN_CLIP(x1, y1 + y)) *(ptr + py) = color; + if (IS_IN_CLIP(x1, y1 - y)) *(ptr - py) = color; + + while (x++ < y) { + BE_ALGORITHM(); + BE_DRAWCIRCLE_CLIP(ptr, ptr, ptr, ptr, x, y, px, py, x1, y1, x1, y1, x1, y1, x1, y1); + + if (Base::_strokeWidth > 1) { + BE_DRAWCIRCLE_CLIP(ptr, ptr, ptr, ptr, x - 1, y, px, py, x1, y1, x1, y1, x1, y1, x1, y1); + BE_DRAWCIRCLE_CLIP(ptr, ptr, ptr, ptr, x, y, px - pitch, py, x1, y1, x1, y1, x1, y1, x1, y1); + } + } + } + } else { + colorFillClip(ptr - r, ptr + r, color, x1 - r, y1 + r, _clippingArea); + BE_RESET(); + while (x++ < y) { + BE_ALGORITHM(); + colorFillClip(ptr - x + py, ptr + x + py, color, x1 - x, y1 + y, _clippingArea); + colorFillClip(ptr - x - py, ptr + x - py, color, x1 - x, y1 - y, _clippingArea); + colorFillClip(ptr - y + px, ptr + y + px, color, x1 - y, y1 + x, _clippingArea); + colorFillClip(ptr - y - px, ptr + y - px, color, x1 - y, y1 - x, _clippingArea); + } + } +} /******************************************************************** diff --git a/graphics/VectorRendererSpec.h b/graphics/VectorRendererSpec.h index 1961e18f816f..01910004d25a 100644 --- a/graphics/VectorRendererSpec.h +++ b/graphics/VectorRendererSpec.h @@ -51,7 +51,8 @@ class VectorRendererSpec : public VectorRenderer { VectorRendererSpec(PixelFormat format); void drawLine(int x1, int y1, int x2, int y2); //TODO - void drawCircle(int x, int y, int r); //TODO + void drawCircle(int x, int y, int r); + void drawCircleClip(int x, int y, int r, Common::Rect clipping); void drawSquare(int x, int y, int w, int h); void drawSquareClip(int x, int y, int w, int h, Common::Rect clipping); void drawRoundedSquare(int x, int y, int r, int w, int h); @@ -161,6 +162,9 @@ class VectorRendererSpec : public VectorRenderer { virtual void drawCircleAlg(int x, int y, int r, PixelType color, FillMode fill_m); + virtual void drawCircleAlgClip(int x, int y, int r, + PixelType color, FillMode fill_m); + virtual void drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, FillMode fill_m);