From 5d151264f883dffb87ad3915992364871cc20c2e Mon Sep 17 00:00:00 2001 From: Gaspar Capello Date: Wed, 9 Oct 2019 10:02:40 -0300 Subject: [PATCH] Fix Custom brushes + Pen + Shading Ink breaks pattern alignment (fix #1615) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Additionally, to avoid code repetition, we reuse ShadingInkProceessing functions to process the new added BrushShadingInkProcessing. To accomplish it, we did nest a code portion from original ShadingInkProcess::processPixel. This codee portion was named: shadingProcessPixel(…) --- src/app/tools/ink_processing.h | 202 +++++++++++++-------------------- 1 file changed, 78 insertions(+), 124 deletions(-) diff --git a/src/app/tools/ink_processing.h b/src/app/tools/ink_processing.h index d972e6a5eb..72f00afa3f 100644 --- a/src/app/tools/ink_processing.h +++ b/src/app/tools/ink_processing.h @@ -706,6 +706,16 @@ class ShadingInkProcessing : public DoubleInkProcessing : public DoubleInkProcessinggetMouseButton() == ToolLoop::Left) { } - void processPixel(int x, int y) { - color_t src = *m_srcAddress; - - // We cannot use the m_rgbmap->mapColor() function because RgbMaps - // are created with findBestfit(), and findBestfit() limits the - // returned indexes to [0,255] range (it's mainly used for RGBA -> - // Indexed image conversion). - int i = m_palette->findExactMatch(rgba_getr(src), - rgba_getg(src), - rgba_getb(src), - rgba_geta(src), - -1); - + RgbTraits::pixel_t shadindProcess(int i, RgbTraits::pixel_t src) { // If we didn't find the exact match. - if (i < 0) { - *m_dstAddress = src; - return; - } + if (i < 0) + return src; if (m_remap) { i = (*m_remap)[i]; @@ -755,10 +751,28 @@ class ShadingInkProcessing : public DoubleInkProcessinggetEntry(i); + } + + void processPixel(int x, int y) { + color_t src = *m_srcAddress; - *m_dstAddress = m_palette->getEntry(i); + // We cannot use the m_rgbmap->mapColor() function because RgbMaps + // are created with findBestfit(), and findBestfit() limits the + // returned indexes to [0,255] range (it's mainly used for RGBA -> + // Indexed image conversion). + int i = m_palette->findExactMatch(rgba_getr(src), + rgba_getg(src), + rgba_getb(src), + rgba_geta(src), + -1); + // If i < 0 we tell to shadingProcess function: + // 'We didn't find the exact match, then shadingProcess + // shouldn't process the current pixel, instead that, + // it has to return src' + *m_dstAddress = shadindProcess(i, src); } - + private: const Palette* m_palette; const RgbMap* m_rgbmap; @@ -776,19 +790,9 @@ class ShadingInkProcessing : public DoubleInkProcessinggetMouseButton() == ToolLoop::Left) { } - // Works as the RGBA version - void processPixel(int x, int y) { - color_t src = *m_srcAddress; - - int i = m_palette->findExactMatch(graya_getv(src), - graya_getv(src), - graya_getv(src), - graya_geta(src), - -1); - + typename GrayscaleTraits::pixel_t shadindProcess(int i, typename GrayscaleTraits::pixel_t src) { if (i < 0) { - *m_dstAddress = src; - return; + return src; } if (m_remap) { @@ -806,13 +810,23 @@ class ShadingInkProcessing : public DoubleInkProcessinggetEntry(i); - *m_dstAddress = graya( - int(255.0 * Hsv(Rgb(rgba_getr(rgba), - rgba_getg(rgba), - rgba_getb(rgba))).value()), - rgba_geta(rgba)); + return graya(int(255.0 * Hsv(Rgb(rgba_getr(rgba), + rgba_getg(rgba), + rgba_getb(rgba))).value()), + rgba_geta(rgba)); + } + + // Works as the RGBA version + void processPixel(int x, int y) { + color_t src = *m_srcAddress; + + int i = m_palette->findExactMatch(graya_getv(src), + graya_getv(src), + graya_getv(src), + graya_geta(src), + -1); + *m_dstAddress = shadindProcess(i, src); } private: @@ -831,10 +845,7 @@ class ShadingInkProcessing : public DoubleInkProcessinggetMouseButton() == ToolLoop::Left) { } - void processPixel(int x, int y) { - color_t src = *m_srcAddress; - int i = src; - + typename IndexedTraits::pixel_t shadindProcess(int i, typename IndexedTraits::pixel_t src) { if (m_remap) { i = (*m_remap)[i]; } @@ -850,8 +861,13 @@ class ShadingInkProcessing : public DoubleInkProcessing::processPixel(int x, int y) { template class BrushShadingInkProcessing : public BrushInkProcessingBase { public: - BrushShadingInkProcessing(ToolLoop* loop) : - BrushInkProcessingBase(loop), - m_rgbmap(loop->getRgbMap()), - m_remap(loop->getShadingRemap()), - m_left(loop->getMouseButton() == ToolLoop::Left) { + BrushShadingInkProcessing(ToolLoop* loop) : BrushInkProcessingBase(loop), m_shading(loop) { } - typename ImageTraits::pixel_t shadingProcessPixel(int iSrc, int iBrush, color_t initialSrc) { + typename ImageTraits::pixel_t shadingProcessPixel(int iSrc, int iBrush, color_t initialSrc) { // Do nothing } @@ -1386,39 +1398,20 @@ class BrushShadingInkProcessing : public BrushInkProcessingBase { } private: - const RgbMap* m_rgbmap; - const Remap* m_remap; - bool m_left; + ShadingInkProcessing m_shading; }; template<> RgbTraits::pixel_t BrushShadingInkProcessing::shadingProcessPixel(int iSrc, int iBrush, color_t initialSrc) { - // We cannot use the m_rgbmap->mapColor() function because RgbMaps - // are created with findBestfit(), and findBestfit() limits the - // returned indexes to [0,255] range (it's mainly used for RGBA -> - // Indexed image conversion). - - // If we didn't find the exact match. - if (iSrc < 0 || iBrush < 0) { + // If iSrc < 0 , it means: + // 'The current pixel, from visible pixel on sprite src, not belongs to the palette, + // then we shouldn't process the current pixel, instead that, it has to return src' + // If iBrush < 0 , it means: + // 'The current pixel, from the custom brush, not belongs to the palette, + // then we shouldn't process the current pixel, instead that, it has to return src' + if (iSrc < 0 || iBrush < 0) return initialSrc; - } - - if (m_remap) { - iSrc = (*(m_remap))[iSrc]; - } - else { - if (m_left) { - --iSrc; - if (iSrc < 0) - iSrc = m_palette->size()-1; - } - else { - ++iSrc; - if (iSrc >= m_palette->size()) - iSrc = 0; - } - } - return m_palette->getEntry(iSrc); + return m_shading.shadindProcess(iSrc, initialSrc); } template <> @@ -1475,26 +1468,7 @@ void BrushShadingInkProcessing::processPixel(int x, int y) { template<> IndexedTraits::pixel_t BrushShadingInkProcessing::shadingProcessPixel(int iSrc, int iBrush, color_t initialSrc) { - // We cannot use the m_rgbmap->mapColor() function because RgbMaps - // are created with findBestfit(), and findBestfit() limits the - // returned indexes to [0,255] range (it's mainly used for RGBA -> - // Indexed image conversion). - if (m_remap) { - iSrc = (*m_remap)[iSrc]; - } - else { - if (m_left) { - --iSrc; - if (iSrc < 0) - iSrc = m_palette->size()-1; - } - else { - ++iSrc; - if (iSrc >= m_palette->size()) - iSrc = 0; - } - } - return iSrc; + return m_shading.shadindProcess(iSrc, initialSrc); } template <> @@ -1547,35 +1521,15 @@ void BrushShadingInkProcessing::processPixel(int x, int y) { template<> GrayscaleTraits::pixel_t BrushShadingInkProcessing::shadingProcessPixel(int iSrc, int iBrush, color_t initialSrc) { - // We cannot use the m_rgbmap->mapColor() function because RgbMaps - // are created with findBestfit(), and findBestfit() limits the - // returned indexes to [0,255] range (it's mainly used for RGBA -> - // Indexed image conversion). - - if (iSrc < 0 || iBrush < 0) { + // If iSrc < 0 , it means: + // 'The current pixel, from visible pixel on sprite src, not belongs to the palette, + // then we shouldn't process the current pixel, instead that, it has to return src' + // If iBrush < 0 , it means: + // 'The current pixel, from the custom brush, not belongs to the palette, + // then we shouldn't process the current pixel, instead that, it has to return src' + if (iSrc < 0 || iBrush < 0) return initialSrc; - } - - if (m_remap) { - iSrc = (*m_remap)[iSrc]; - } - else { - if (m_left) { - --iSrc; - if (iSrc < 0) - iSrc = 255; - } - else { - ++iSrc; - if (iSrc > 255) - iSrc = 0; - } - } - color_t rgba = m_palette->getEntry(iSrc); - return graya(int(255.0 * Hsv(Rgb(rgba_getr(iSrc), - rgba_getg(rgba), - rgba_getb(rgba))).value()), - rgba_geta(rgba)); + return m_shading.shadindProcess(iSrc, initialSrc); } template <>