From ee00156d5450b01508894013dc446ef3d928d781 Mon Sep 17 00:00:00 2001 From: Alexander Tkachev Date: Wed, 29 Jun 2016 19:47:32 +0600 Subject: GUI: Add drawBeveledSquareClip() --- graphics/VectorRenderer.h | 5 ++- graphics/VectorRendererSpec.cpp | 96 +++++++++++++++++++++++++++++++++++++++++ graphics/VectorRendererSpec.h | 17 +++++++- 3 files changed, 115 insertions(+), 3 deletions(-) (limited to 'graphics') diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h index d180d87217..bedc8a3a8f 100644 --- a/graphics/VectorRenderer.h +++ b/graphics/VectorRenderer.h @@ -204,6 +204,7 @@ public: * @param bevel Amount of bevel. Must be positive. */ virtual void drawBeveledSquare(int x, int y, int w, int h, int bevel) = 0; + virtual void drawBeveledSquareClip(int x, int y, int w, int h, int bevel, Common::Rect clipping) = 0; /** * Draws a tab-like shape, specially thought for the Tab widget. @@ -397,10 +398,10 @@ public: drawTriangleClip(x, y, w, h, (TriangleOrientation)step.extraData, clip); } - void drawCallback_BEVELSQ(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) { //TODO + void drawCallback_BEVELSQ(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) { uint16 x, y, w, h; stepGetPositions(step, area, x, y, w, h); - drawBeveledSquare(x, y, w, h, _bevel); + drawBeveledSquareClip(x, y, w, h, _bevel, clip); } void drawCallback_TAB(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) { //TODO diff --git a/graphics/VectorRendererSpec.cpp b/graphics/VectorRendererSpec.cpp index 3011601168..607b9a37b1 100644 --- a/graphics/VectorRendererSpec.cpp +++ b/graphics/VectorRendererSpec.cpp @@ -922,6 +922,36 @@ darkenFill(PixelType *ptr, PixelType *end) { } } +template +inline void VectorRendererSpec:: +darkenFillClip(PixelType *ptr, PixelType *end, int x, int y) { + PixelType mask = (PixelType)((3 << _format.rShift) | (3 << _format.gShift) | (3 << _format.bShift)); + + if (!g_system->hasFeature(OSystem::kFeatureOverlaySupportsAlpha)) { + // !kFeatureOverlaySupportsAlpha (but might have alpha bits) + + while (ptr != end) { + if (IS_IN_CLIP(x, y)) *ptr = ((*ptr & ~mask) >> 2) | _alphaMask; + ++ptr; + ++x; + } + } else { + // kFeatureOverlaySupportsAlpha + // assuming at least 3 alpha bits + + mask |= 3 << _format.aShift; + PixelType addA = (PixelType)(3 << (_format.aShift + 6 - _format.aLoss)); + + while (ptr != end) { + // Darken the color, and increase the alpha + // (0% -> 75%, 100% -> 100%) + if (IS_IN_CLIP(x, y)) *ptr = (PixelType)(((*ptr & ~mask) >> 2) + addA); + ++ptr; + ++x; + } + } +} + /******************************************************************** ******************************************************************** * Primitive shapes drawing - Public API calls - VectorRendererSpec * @@ -1895,6 +1925,72 @@ drawBevelSquareAlg(int x, int y, int w, int h, int bevel, PixelType top_color, P } } +template +void VectorRendererSpec:: +drawBevelSquareAlgClip(int x, int y, int w, int h, int bevel, PixelType top_color, PixelType bottom_color, bool fill) { + int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel; + int i, j; + PixelType *ptr_left; + int ptr_x, ptr_y; + + // Fill Background + ptr_left = (PixelType *)_activeSurface->getBasePtr(x, y); + ptr_x = x; ptr_y = y; + i = h; + if (fill) { + assert((_bgColor & ~_alphaMask) == 0); // only support black + while (i--) { + darkenFillClip(ptr_left, ptr_left + w, ptr_x, ptr_y); + ptr_left += pitch; + ++ptr_y; + } + } + + x = MAX(x - bevel, 0); + y = MAX(y - bevel, 0); + + w = MIN(w + (bevel * 2), (int)_activeSurface->w); + h = MIN(h + (bevel * 2), (int)_activeSurface->h); + + ptr_left = (PixelType *)_activeSurface->getBasePtr(x, y); + ptr_x = x; ptr_y = y; + i = bevel; + while (i--) { + colorFillClip(ptr_left, ptr_left + w, top_color, ptr_x, ptr_y, _clippingArea); + ptr_left += pitch; + ++ptr_y; + } + + ptr_left = (PixelType *)_activeSurface->getBasePtr(x, y + bevel); + ptr_x = x; ptr_y = y + bevel; + i = h - bevel; + while (i--) { + colorFillClip(ptr_left, ptr_left + bevel, top_color, ptr_x, ptr_y, _clippingArea); + ptr_left += pitch; + ++ptr_y; + } + + ptr_left = (PixelType *)_activeSurface->getBasePtr(x, y + h - bevel); + ptr_x = x; ptr_y = y + h - bevel; + i = bevel; + while (i--) { + colorFillClip(ptr_left + i, ptr_left + w, bottom_color, ptr_x + i, ptr_y, _clippingArea); + ptr_left += pitch; + ++ptr_y; + } + + ptr_left = (PixelType *)_activeSurface->getBasePtr(x + w - bevel, y); + ptr_x = x + w - bevel; ptr_y = y; + i = h - bevel; + j = bevel - 1; + while (i--) { + colorFillClip(ptr_left + j, ptr_left + bevel, bottom_color, ptr_x + j, ptr_y, _clippingArea); + if (j > 0) j--; + ptr_left += pitch; + ++ptr_y; + } +} + /** GENERIC LINE ALGORITHM **/ template void VectorRendererSpec:: diff --git a/graphics/VectorRendererSpec.h b/graphics/VectorRendererSpec.h index dcef88e082..b69ab87bdd 100644 --- a/graphics/VectorRendererSpec.h +++ b/graphics/VectorRendererSpec.h @@ -61,9 +61,20 @@ public: void drawTriangle(int x, int y, int base, int height, TriangleOrientation orient); void drawTriangleClip(int x, int y, int base, int height, TriangleOrientation orient, Common::Rect clipping); void drawTab(int x, int y, int r, int w, int h); //TODO - void drawBeveledSquare(int x, int y, int w, int h, int bevel) { //TODO + void drawBeveledSquare(int x, int y, int w, int h, int bevel) { drawBevelSquareAlg(x, y, w, h, bevel, _bevelColor, _fgColor, Base::_fillMode != kFillDisabled); } + void drawBeveledSquareClip(int x, int y, int w, int h, int bevel, Common::Rect clipping) { + bool useClippingVersions = !(clipping.isEmpty() || clipping.contains(Common::Rect(x, y, x + w, y + h))); + if (useClippingVersions) { + Common::Rect backup = _clippingArea; + _clippingArea = clipping; + drawBevelSquareAlgClip(x, y, w, h, bevel, _bevelColor, _fgColor, Base::_fillMode != kFillDisabled); + _clippingArea = backup; + } else { + drawBevelSquareAlg(x, y, w, h, bevel, _bevelColor, _fgColor, Base::_fillMode != kFillDisabled); + } + } void drawString(const Graphics::Font *font, const Common::String &text, const Common::Rect &area, Graphics::TextAlign alignH, GUI::ThemeEngine::TextAlignVertical alignV, int deltax, bool elipsis, const Common::Rect &textDrawableArea = Common::Rect(0, 0, 0, 0)); @@ -205,6 +216,9 @@ protected: virtual void drawBevelSquareAlg(int x, int y, int w, int h, int bevel, PixelType top_color, PixelType bottom_color, bool fill); + virtual void drawBevelSquareAlgClip(int x, int y, int w, int h, + int bevel, PixelType top_color, PixelType bottom_color, bool fill); + 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); @@ -272,6 +286,7 @@ protected: } void darkenFill(PixelType *first, PixelType *last); + void darkenFillClip(PixelType *first, PixelType *last, int x, int y); const PixelFormat _format; const PixelType _redMask, _greenMask, _blueMask, _alphaMask; -- cgit v1.2.3