From d280862a75f7949bff88b418d4addcc5ed091628 Mon Sep 17 00:00:00 2001 From: Gaspar Capello Date: Fri, 25 Oct 2024 19:30:21 -0300 Subject: [PATCH] Implementation of dacap suggestions --- src/app/tools/ink.h | 2 +- src/app/tools/ink_processing.h | 180 +++++++++++++++++---------------- src/app/tools/point_shapes.h | 15 +-- src/app/tools/symmetry.cpp | 10 +- src/app/tools/symmetry.h | 7 ++ src/app/ui/context_bar.cpp | 1 - src/doc/brush.cpp | 25 ++--- src/doc/brush.h | 4 +- tests/scripts/tools.lua | 8 +- 9 files changed, 126 insertions(+), 126 deletions(-) diff --git a/src/app/tools/ink.h b/src/app/tools/ink.h index 0fe21f5a83..570c39fff3 100644 --- a/src/app/tools/ink.h +++ b/src/app/tools/ink.h @@ -105,7 +105,7 @@ namespace app { // Called for each point shape. virtual void prepareForPointShape(ToolLoop* loop, bool firstPoint, int x, int y, - doc::SymmetryIndex summetry) { } + doc::SymmetryIndex symmetry) { } virtual void prepareVForPointShape(ToolLoop* loop, int y) { } virtual void prepareUForPointShapeWholeScanline(ToolLoop* loop, int x1) { } virtual void prepareUForPointShapeSlicedScanline(ToolLoop* loop, bool leftSlice, int x1) { } diff --git a/src/app/tools/ink_processing.h b/src/app/tools/ink_processing.h index e921b57820..5abb9c431f 100644 --- a/src/app/tools/ink_processing.h +++ b/src/app/tools/ink_processing.h @@ -6,6 +6,7 @@ // the End-User License Agreement for Aseprite. #include "app/color_utils.h" +#include "app/tools/symmetry.h" #include "app/util/wrap_point.h" #include "app/util/wrap_value.h" #include "doc/blend_funcs.h" @@ -1145,26 +1146,22 @@ class BrushInkProcessingBase : public DoubleInkProcessingpattern() != BrushPattern::ALIGNED_TO_SRC) { + m_isBoundsRotated = does_symmetry_rotate_image(index); + m_brushImage = m_brush->getSymmetryImage(index); + m_brushMask = m_brush->getSymmetryMask(index); + m_patternAlign = m_brush->pattern(); + if (m_patternAlign != BrushPattern::ALIGNED_TO_SRC) { + const int brushW = brushWidth(); + const int brushH = brushHeight(); // Case: during painting process with PaintBucket Tool if (loop->getPointShape()->isFloodFill()) { - m_u = x - bSize.w / 2; - m_v = y - bSize.h / 2; + m_u = x - brushW / 2; + m_v = y - brushH / 2; } // Case: during brush preview of PaintBucket Tool else if (loop->getController()->isOnePoint()) { @@ -1172,54 +1169,54 @@ class BrushInkProcessingBase : public DoubleInkProcessingpatternOrigin().x % loop->sprite()->width()) - loop->getCelOrigin().x) % bSize.w; - m_v = ((m_brush->patternOrigin().y % loop->sprite()->height()) - loop->getCelOrigin().y) % bSize.h; + m_u = ((m_brush->patternOrigin().x % loop->sprite()->width()) - loop->getCelOrigin().x) % brushW; + m_v = ((m_brush->patternOrigin().y % loop->sprite()->height()) - loop->getCelOrigin().y) % brushH; } } } void prepareVForPointShape(ToolLoop* loop, int y) override { - int height = (m_isBoundsRotated ? m_width : m_height); - if (m_brush->pattern() == doc::BrushPattern::ALIGNED_TO_SRC) { - m_v = (m_brush->patternOrigin().y - loop->getCelOrigin().y) % height; - if (m_v < 0) m_v += height; + const int brushH(brushHeight()); + if (m_patternAlign == doc::BrushPattern::ALIGNED_TO_SRC) { + m_v = (m_brush->patternOrigin().y - loop->getCelOrigin().y) % brushH; + if (m_v < 0) m_v += brushH; } else { int spriteH = loop->sprite()->height(); if (y/spriteH > 0) // 'y' is outside of the center tile. - m_v = (m_brush->patternOrigin().y + height - (y/spriteH) * spriteH) % height; + m_v = (m_brush->patternOrigin().y + brushH - (y/spriteH) * spriteH) % brushH; else // 'y' is inside of the center tile. - m_v = ((m_brush->patternOrigin().y % spriteH) - loop->getCelOrigin().y) % height; + m_v = ((m_brush->patternOrigin().y % spriteH) - loop->getCelOrigin().y) % brushH; } } void prepareUForPointShapeWholeScanline(ToolLoop* loop, int x1) override { - int width = (m_isBoundsRotated ? m_height : m_width); - if (m_brush->pattern() == doc::BrushPattern::ALIGNED_TO_SRC) { - m_u = (m_brush->patternOrigin().x - loop->getCelOrigin().x) % width; - if (m_u < 0) m_u += (m_isBoundsRotated ? m_width : m_height); + const int brushW(brushWidth()); + if (m_patternAlign == doc::BrushPattern::ALIGNED_TO_SRC) { // ultimo corregido + m_u = (m_brush->patternOrigin().x - loop->getCelOrigin().x) % brushW; + if (m_u < 0) m_u += brushHeight(); } else { - m_u = ((m_brush->patternOrigin().x % loop->sprite()->width()) - loop->getCelOrigin().x ) % width; + m_u = ((m_brush->patternOrigin().x % loop->sprite()->width()) - loop->getCelOrigin().x ) % brushW; if (x1/loop->sprite()->width() > 0) - m_u = (m_brush->patternOrigin().x + width - (x1/loop->sprite()->width()) * loop->sprite()->width()) % width; + m_u = (m_brush->patternOrigin().x + brushW - (x1/loop->sprite()->width()) * loop->sprite()->width()) % brushW; } } void prepareUForPointShapeSlicedScanline(ToolLoop* loop, bool leftSlice, int x1) override { - int width = (m_isBoundsRotated ? m_height : m_width); - if (m_brush->pattern() == doc::BrushPattern::ALIGNED_TO_SRC) { - m_u = (m_brush->patternOrigin().x - loop->getCelOrigin().x) % width; - if (m_u < 0) m_u += (m_isBoundsRotated ? m_width : m_height); + const int brushW(brushWidth()); + if (m_patternAlign == doc::BrushPattern::ALIGNED_TO_SRC) { + m_u = (m_brush->patternOrigin().x - loop->getCelOrigin().x) % brushW; + if (m_u < 0) m_u += brushHeight(); return; } else { if (leftSlice) - m_u = ((m_brush->patternOrigin().x % loop->sprite()->width()) - loop->getCelOrigin().x ) % width; + m_u = ((m_brush->patternOrigin().x % loop->sprite()->width()) - loop->getCelOrigin().x ) % brushW; else - m_u = (m_brush->patternOrigin().x + width - (x1/loop->sprite()->width() + 1) * loop->sprite()->width()) % width; + m_u = (m_brush->patternOrigin().x + brushW - (x1/loop->sprite()->width() + 1) * loop->sprite()->width()) % brushW; } } @@ -1238,15 +1235,15 @@ class BrushInkProcessingBase : public DoubleInkProcessinggetSymmetryMask(m_symmetryIndex) && - !get_pixel_fast(m_brush->getSymmetryMask(m_symmetryIndex), x, y)) + if (m_brushMask && + !get_pixel_fast(m_brushMask, x, y)) return false; if (m_brush->patternImage()) { @@ -1263,17 +1260,26 @@ class BrushInkProcessingBase : public DoubleInkProcessing::preProcessPixel(int x, int y, color_t* r color_t c; switch (m_brush->image()->pixelFormat()) { case IMAGE_RGB: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); // We blend the previous image brush pixel with a pixel from the // image preview (*m_dstAddress). Yes, dstImage, in that way we @@ -1296,7 +1302,7 @@ bool BrushInkProcessingBase::preProcessPixel(int x, int y, color_t* r break; } case IMAGE_INDEXED: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); if (m_transparentColor == c) c = 0; else @@ -1305,14 +1311,14 @@ bool BrushInkProcessingBase::preProcessPixel(int x, int y, color_t* r break; } case IMAGE_GRAYSCALE: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); c = doc::rgba(graya_getv(c), graya_getv(c), graya_getv(c), graya_geta(c)); c = rgba_blender_normal(*m_dstAddress, c, m_opacity); break; } case IMAGE_BITMAP: { // TODO In which circuntance is possible this case? - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); c = c ? m_fgColor: m_bgColor; break; } @@ -1332,13 +1338,13 @@ bool BrushInkProcessingBase::preProcessPixel(int x, int y, colo color_t c; switch (m_brush->image()->pixelFormat()) { case IMAGE_RGB: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); c = graya(rgba_luma(c), rgba_geta(c)); c = graya_blender_normal(*m_dstAddress, c, m_opacity); break; } case IMAGE_INDEXED: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); if (m_transparentColor == c) c = 0; else @@ -1348,13 +1354,13 @@ bool BrushInkProcessingBase::preProcessPixel(int x, int y, colo break; } case IMAGE_GRAYSCALE: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); c = graya_blender_normal(*m_dstAddress, c, m_opacity); break; } case IMAGE_BITMAP: { // TODO In which circuntance is possible this case? - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); c = c ? m_fgColor: m_bgColor; break; } @@ -1374,7 +1380,7 @@ bool BrushInkProcessingBase::preProcessPixel(int x, int y, color_ color_t c; switch (m_brush->image()->pixelFormat()) { case IMAGE_RGB: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); color_t d = m_palette->getEntry(*m_dstAddress); c = rgba_blender_normal(d, c, m_opacity); c = m_palette->findBestfit(rgba_getr(c), @@ -1384,7 +1390,7 @@ bool BrushInkProcessingBase::preProcessPixel(int x, int y, color_ break; } case IMAGE_INDEXED: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); if (c == m_transparentColor) return false; @@ -1403,7 +1409,7 @@ bool BrushInkProcessingBase::preProcessPixel(int x, int y, color_ break; } case IMAGE_GRAYSCALE: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); color_t b = m_palette->getEntry(*m_dstAddress); b = graya(rgba_luma(b), rgba_geta(b)); @@ -1416,7 +1422,7 @@ bool BrushInkProcessingBase::preProcessPixel(int x, int y, color_ } case IMAGE_BITMAP: { // TODO In which circuntance is possible this case? - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); c = c ? m_fgColor: m_bgColor; break; } @@ -1528,7 +1534,7 @@ void BrushEraserInkProcessing::processPixel(int x, int y) { color_t c; switch (m_brush->image()->pixelFormat()) { case IMAGE_RGB: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); int t; c = doc::rgba(rgba_getr(*m_srcAddress), rgba_getg(*m_srcAddress), @@ -1537,7 +1543,7 @@ void BrushEraserInkProcessing::processPixel(int x, int y) { break; } case IMAGE_INDEXED: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); if (m_transparentColor == c) c = 0; else @@ -1550,7 +1556,7 @@ void BrushEraserInkProcessing::processPixel(int x, int y) { break; } case IMAGE_GRAYSCALE: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); int t; c = doc::rgba(rgba_getr(*m_srcAddress), rgba_getg(*m_srcAddress), @@ -1560,7 +1566,7 @@ void BrushEraserInkProcessing::processPixel(int x, int y) { } case IMAGE_BITMAP: { // TODO In which circuntance is possible this case? - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); c = c ? m_bgColor : *m_srcAddress; break; } @@ -1579,14 +1585,14 @@ void BrushEraserInkProcessing::processPixel(int x, int y) { color_t c; switch (m_brush->image()->pixelFormat()) { case IMAGE_RGB: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); int t; c = graya(graya_getv(*m_srcAddress), MUL_UN8(graya_geta(*m_dstAddress), 255 - rgba_geta(c), t)); break; } case IMAGE_INDEXED: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); if (m_transparentColor == c) c = 0; else { @@ -1598,7 +1604,7 @@ void BrushEraserInkProcessing::processPixel(int x, int y) { break; } case IMAGE_GRAYSCALE: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); int t; c = graya(graya_getv(*m_srcAddress), MUL_UN8(graya_geta(*m_dstAddress), 255 - graya_geta(c), t)); @@ -1606,7 +1612,7 @@ void BrushEraserInkProcessing::processPixel(int x, int y) { } case IMAGE_BITMAP: { // TODO In which circuntance is possible this case? - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); c = c ? m_bgColor : *m_srcAddress; break; } @@ -1625,7 +1631,7 @@ void BrushEraserInkProcessing::processPixel(int x, int y) { color_t c; switch (m_brush->image()->pixelFormat()) { case IMAGE_RGB: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); c = m_palette->findBestfit(rgba_getr(c), rgba_getg(c), rgba_getb(c), @@ -1633,11 +1639,11 @@ void BrushEraserInkProcessing::processPixel(int x, int y) { break; } case IMAGE_INDEXED: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); break; } case IMAGE_GRAYSCALE: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); c = m_palette->findBestfit(graya_getv(c), graya_getv(c), graya_getv(c), @@ -1646,7 +1652,7 @@ void BrushEraserInkProcessing::processPixel(int x, int y) { } case IMAGE_BITMAP: { // TODO In which circuntance is possible this case? - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); c = c ? m_fgColor: m_bgColor; break; } @@ -1688,7 +1694,7 @@ void BrushShadingInkProcessing::processPixel(int x, int y) { switch (m_brush->image()->pixelFormat()) { case IMAGE_RGB: { - auto c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + auto c = get_pixel_fast(m_brushImage, x, y); int iBrush = m_shading.findIndex(rgba_getr(c), rgba_getg(c), rgba_getb(c), @@ -1698,13 +1704,13 @@ void BrushShadingInkProcessing::processPixel(int x, int y) { break; } case IMAGE_INDEXED: { - auto c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + auto c = get_pixel_fast(m_brushImage, x, y); if (m_transparentColor != c) *m_dstAddress = m_shading(*m_srcAddress); break; } case IMAGE_GRAYSCALE: { - auto c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + auto c = get_pixel_fast(m_brushImage, x, y); if (graya_geta(c) != 0) *m_dstAddress = m_shading(*m_srcAddress); break; @@ -1722,7 +1728,7 @@ void BrushShadingInkProcessing::processPixel(int x, int y) { switch (m_brush->image()->pixelFormat()) { case IMAGE_RGB: { - auto c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + auto c = get_pixel_fast(m_brushImage, x, y); int iBrush = m_shading.findIndex(rgba_getr(c), rgba_getg(c), rgba_getb(c), @@ -1732,13 +1738,13 @@ void BrushShadingInkProcessing::processPixel(int x, int y) { break; } case IMAGE_INDEXED: { - auto c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + auto c = get_pixel_fast(m_brushImage, x, y); if (m_transparentColor != c) *m_dstAddress = m_shading(*m_srcAddress); break; } case IMAGE_GRAYSCALE: { - auto c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + auto c = get_pixel_fast(m_brushImage, x, y); if (graya_geta(c) != 0) *m_dstAddress = m_shading(*m_srcAddress); break; @@ -1756,7 +1762,7 @@ void BrushShadingInkProcessing::processPixel(int x, int y) { switch (m_brush->image()->pixelFormat()) { case IMAGE_RGB: { - auto c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + auto c = get_pixel_fast(m_brushImage, x, y); int iBrush = m_shading.findIndex(rgba_getr(c), rgba_getg(c), rgba_getb(c), @@ -1766,13 +1772,13 @@ void BrushShadingInkProcessing::processPixel(int x, int y) { break; } case IMAGE_INDEXED: { - auto c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + auto c = get_pixel_fast(m_brushImage, x, y); if (m_transparentColor != c) *m_dstAddress = m_shading(*m_srcAddress); break; } case IMAGE_GRAYSCALE: { - auto c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + auto c = get_pixel_fast(m_brushImage, x, y); if (graya_geta(c) != 0) *m_dstAddress = m_shading(*m_srcAddress); break; @@ -1806,13 +1812,13 @@ void BrushCopyInkProcessing::processPixel(int x, int y) { color_t c; switch (m_brush->image()->pixelFormat()) { case IMAGE_RGB: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); if (rgba_geta(c) == 0) return; break; } case IMAGE_INDEXED: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); if (c == m_transparentColor) { *m_dstAddress = *m_srcAddress; return; @@ -1821,7 +1827,7 @@ void BrushCopyInkProcessing::processPixel(int x, int y) { break; } case IMAGE_GRAYSCALE: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); if (graya_geta(c) == 0) return; c = doc::rgba(graya_getv(c), graya_getv(c), graya_getv(c), graya_geta(c)); @@ -1829,7 +1835,7 @@ void BrushCopyInkProcessing::processPixel(int x, int y) { } case IMAGE_BITMAP: { // TODO In which circuntance is possible this case? - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); c = c ? m_fgColor: m_bgColor; break; } @@ -1848,7 +1854,7 @@ void BrushCopyInkProcessing::processPixel(int x, int y) { color_t c; switch (m_brush->image()->pixelFormat()) { case IMAGE_RGB: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); if (rgba_geta(c) == 0) return; c = m_palette->findBestfit(rgba_getr(c), @@ -1860,13 +1866,13 @@ void BrushCopyInkProcessing::processPixel(int x, int y) { break; } case IMAGE_INDEXED: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); if (c == m_transparentColor) c = *m_srcAddress; break; } case IMAGE_GRAYSCALE: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); if (graya_geta(c) == 0) return; c = m_palette->findBestfit(graya_getv(c), @@ -1877,7 +1883,7 @@ void BrushCopyInkProcessing::processPixel(int x, int y) { } case IMAGE_BITMAP: { // TODO In which circuntance is possible this case? - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); c = c ? m_fgColor: m_bgColor; break; } @@ -1896,14 +1902,14 @@ void BrushCopyInkProcessing::processPixel(int x, int y) { color_t c; switch (m_brush->image()->pixelFormat()) { case IMAGE_RGB: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); if (rgba_geta(c) == 0) return; c = graya(rgba_luma(c), rgba_geta(c)); break; } case IMAGE_INDEXED: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); if (c == m_transparentColor) { *m_dstAddress = *m_srcAddress; return; @@ -1913,14 +1919,14 @@ void BrushCopyInkProcessing::processPixel(int x, int y) { break; } case IMAGE_GRAYSCALE: { - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); if (graya_geta(c) == 0) return; break; } case IMAGE_BITMAP: { // TODO In which circuntance is possible this case? - c = get_pixel_fast(m_brush->getSymmetryImage(m_symmetryIndex), x, y); + c = get_pixel_fast(m_brushImage, x, y); c = c ? m_fgColor: m_bgColor; break; } diff --git a/src/app/tools/point_shapes.h b/src/app/tools/point_shapes.h index a9e08d765d..adb8501a2e 100644 --- a/src/app/tools/point_shapes.h +++ b/src/app/tools/point_shapes.h @@ -8,6 +8,7 @@ #include "app/util/wrap_point.h" #include "app/tools/ink.h" +#include "app/tools/symmetry.h" #include "doc/algorithm/flip_image.h" #include "doc/primitives.h" #include "render/gradient.h" @@ -218,10 +219,7 @@ class BrushPointShape : public PointShape { } if (brush->type() == kImageBrushType && - (pt.symmetry == doc::SymmetryIndex::ROTATED_90 || - pt.symmetry == doc::SymmetryIndex::ROTATED_270 || - pt.symmetry == doc::SymmetryIndex::ROT_FLIP_90 || - pt.symmetry == doc::SymmetryIndex::ROT_FLIP_270)) { + does_symmetry_rotate_image(pt.symmetry)) { x += brush->bounds().y; y += brush->bounds().x; } @@ -268,10 +266,7 @@ class BrushPointShape : public PointShape { void getModifiedArea(ToolLoop* loop, int x, int y, doc::SymmetryIndex symmetry, Rect& area) override { auto bounds = loop->getBrush()->bounds(); - if (symmetry == doc::SymmetryIndex::ROTATED_90 || - symmetry == doc::SymmetryIndex::ROTATED_270 || - symmetry == doc::SymmetryIndex::ROT_FLIP_90 || - symmetry == doc::SymmetryIndex::ROT_FLIP_270) + if (does_symmetry_rotate_image(symmetry)) area = gfx::Rect(bounds.y, bounds.x, bounds.h, bounds.w); else area = bounds; @@ -280,8 +275,8 @@ class BrushPointShape : public PointShape { } private: - CompressedImage& getCompressedImage(doc::SymmetryIndex index) {//symmetryMode - auto& compressPtr = m_compressedImages[index]; + CompressedImage& getCompressedImage(doc::SymmetryIndex index) { + auto& compressPtr = m_compressedImages[int(index)]; if (!compressPtr) { compressPtr.reset(new CompressedImage(m_lastBrush->getSymmetryImage(index), m_lastBrush->getSymmetryMask(index), diff --git a/src/app/tools/symmetry.cpp b/src/app/tools/symmetry.cpp index 17282cf3ea..7750318c59 100644 --- a/src/app/tools/symmetry.cpp +++ b/src/app/tools/symmetry.cpp @@ -119,16 +119,13 @@ void Symmetry::calculateSymmetricalStroke(const Stroke& refStroke, gfx::Point brushCenter(0, 0); auto brush = loop->getBrush(); if (!loop->getPointShape()->isFloodFill()) { - if (symmetry == doc::SymmetryIndex::ORIGINAL || - symmetry == doc::SymmetryIndex::FLIPPED_X || - symmetry == doc::SymmetryIndex::FLIPPED_Y || - symmetry == doc::SymmetryIndex::FLIPPED_XY) { + if (!does_symmetry_rotate_image(symmetry)) { brushSize = brush->bounds().size(); brushCenter = brush->center(); } else { - brushSize = gfx::Size(brush->bounds().size().h, - brush->bounds().size().w); + brushSize = gfx::Size(brush->bounds().h, + brush->bounds().w); brushCenter = gfx::Point(brush->center().y, brush->center().x); } @@ -171,6 +168,7 @@ void Symmetry::calculateSymmetricalStroke(const Stroke& refStroke, } default: pt2.y = 2 * (m_y + brushCenter.y) - pt.y - brushSize.h; + break; } stroke.addPoint(pt2); } diff --git a/src/app/tools/symmetry.h b/src/app/tools/symmetry.h index 3c5e7130d1..a58719dda8 100644 --- a/src/app/tools/symmetry.h +++ b/src/app/tools/symmetry.h @@ -18,6 +18,13 @@ namespace tools { class ToolLoop; +static inline bool does_symmetry_rotate_image(doc::SymmetryIndex symmetry) { + return symmetry == doc::SymmetryIndex::ROTATED_90 || + symmetry == doc::SymmetryIndex::ROTATED_270 || + symmetry == doc::SymmetryIndex::ROT_FLIP_90 || + symmetry == doc::SymmetryIndex::ROT_FLIP_270; +} + class Symmetry { public: Symmetry(gen::SymmetryMode symmetryMode, double x, double y) diff --git a/src/app/ui/context_bar.cpp b/src/app/ui/context_bar.cpp index c392b397f2..cb8ab20332 100644 --- a/src/app/ui/context_bar.cpp +++ b/src/app/ui/context_bar.cpp @@ -2475,7 +2475,6 @@ void ContextBar::setActiveBrushBySlot(tools::Tool* tool, int slot) // the slot. if (brush.hasFlag(BrushSlot::Flags::ImageColor)) brush.brush()->resetImageColors(); - brush.brush()->resetSymmetries(); setActiveBrush(brush.brush()); } else { diff --git a/src/doc/brush.cpp b/src/doc/brush.cpp index 05d9985ff0..bdf1f3942c 100644 --- a/src/doc/brush.cpp +++ b/src/doc/brush.cpp @@ -113,7 +113,6 @@ void Brush::setImage(const Image* image, m_backupImage.reset(); m_mainColor.reset(); m_bgColor.reset(); - resetSymmetries(); resetBounds(); } @@ -297,7 +296,6 @@ void Brush::resetImageColors() m_image.reset(Image::createCopy(m_backupImage.get())); m_mainColor.reset(); m_bgColor.reset(); - resetSymmetries(); } } @@ -316,7 +314,6 @@ void Brush::clean() m_image.reset(); m_maskBitmap.reset(); m_backupImage.reset(); - resetSymmetries(); } static void algo_hline(int x1, int y, int x2, void *data) @@ -326,18 +323,14 @@ static void algo_hline(int x1, int y, int x2, void *data) void Brush::resetSymmetries() { - if (m_symmetryImages.empty()) { - for (int i=0; i<8; i++) { - m_symmetryImages.push_back(ImageRef()); - m_symmetryMasks.push_back(ImageRef()); - } - } - else { - for (int i=0; i<8; i++) { - m_symmetryImages[i].reset(); - m_symmetryMasks[i].reset(); - } - } + m_symmetryImages.resize(0); + m_symmetryMasks.resize(0); +} + +void Brush::reserveSymmetries() +{ + m_symmetryImages.resize(int(SymmetryIndex::ELEMENTS)); + m_symmetryMasks.resize(int(SymmetryIndex::ELEMENTS)); } Image* Brush::getSymmetryImage(const SymmetryIndex index) @@ -346,7 +339,7 @@ Image* Brush::getSymmetryImage(const SymmetryIndex index) return m_image.get(); if (m_symmetryImages.empty()) - resetSymmetries(); + reserveSymmetries(); if (!m_symmetryImages[index]) { switch (index) { diff --git a/src/doc/brush.h b/src/doc/brush.h index f464c12c2f..498e4d66f2 100644 --- a/src/doc/brush.h +++ b/src/doc/brush.h @@ -30,7 +30,8 @@ namespace doc { ROTATED_270 = 4, ROT_FLIP_90 = 5, ROTATED_90 = 6, - ROT_FLIP_270 = 7 + ROT_FLIP_270 = 7, + ELEMENTS = 8 }; class Brush; @@ -105,6 +106,7 @@ namespace doc { } void resetSymmetries(); + void reserveSymmetries(); Image* getSymmetryImage(const SymmetryIndex index); Image* getSymmetryMask(const SymmetryIndex index); diff --git a/tests/scripts/tools.lua b/tests/scripts/tools.lua index 1d308f1956..e5c40951eb 100644 --- a/tests/scripts/tools.lua +++ b/tests/scripts/tools.lua @@ -412,8 +412,8 @@ function drawing_with_symmetry(imageColorMode, colorInImage, expect_eq(cel.bounds, Rectangle(0, 0, 8, 3)) expect_img(cel.image, { 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 }) + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }) local b = Brush { size=1 } app.fgColor = c @@ -457,7 +457,7 @@ function drawing_with_symmetry(imageColorMode, colorInImage, expect_eq(cel.bounds, Rectangle(0, 0, 8, 3)) expect_img(cel.image, { 0, c, 0, 0, 0, 0, c, 0, - c, c, c, 0, 0, c, c, c, + c, c, c, 0, 0, c, c, c, 0, c, 0, 0, 0, 0, c, 0 }) app.undo() @@ -467,7 +467,7 @@ function drawing_with_symmetry(imageColorMode, colorInImage, expect_eq(cel.bounds, Rectangle(1, 0, 6, 3)) expect_img(cel.image, { 0, c, 0, 0, c, 0, - c, c, c, c, c, c, + c, c, c, c, c, c, 0, c, 0, 0, c, 0 }) app.undo()