diff --git a/src/app/tools/ink_processing.h b/src/app/tools/ink_processing.h index 1b6fc6859..862ae69d1 100644 --- a/src/app/tools/ink_processing.h +++ b/src/app/tools/ink_processing.h @@ -1083,13 +1083,13 @@ private: }; ////////////////////////////////////////////////////////////////////// -// Brush Ink +// Brush Ink - Base ////////////////////////////////////////////////////////////////////// template -class BrushInkProcessing : public DoubleInkProcessing, ImageTraits> { +class BrushInkProcessingBase : public DoubleInkProcessing, ImageTraits> { public: - BrushInkProcessing(ToolLoop* loop) { + BrushInkProcessingBase(ToolLoop* loop) { m_fgColor = loop->getPrimaryColor(); m_bgColor = loop->getSecondaryColor(); m_palette = get_current_palette(); @@ -1112,10 +1112,19 @@ public: } } - void processPixel(int x, int y) { + bool preProcessPixel(int x, int y, color_t* result) { // Do nothing } + // TODO Remove this virtual function in some way. At the moment we + // need it because InkProcessing expects that its Derived + // template parameter has a processPixel() member function. + virtual void processPixel(int x, int y) { + // Do nothing + } + + color_t getTransparentColor() { return m_transparentColor; } + private: void alignPixelPoint(int& x, int& y) { x = (x - m_u) % m_width; @@ -1132,7 +1141,6 @@ private: const Image* m_brushMask; int m_opacity; int m_u, m_v, m_width, m_height; - // When we have a image brush from an INDEXED sprite, we need to know // which is the background color in order to translate to transparent color // in a RGBA sprite. @@ -1140,10 +1148,10 @@ private: }; template<> -void BrushInkProcessing::processPixel(int x, int y) { +bool BrushInkProcessingBase::preProcessPixel(int x, int y, color_t* result) { alignPixelPoint(x, y); if (m_brushMask && !get_pixel_fast(m_brushMask, x, y)) - return; + return false; color_t c; switch (m_brushImage->pixelFormat()) { @@ -1185,16 +1193,17 @@ void BrushInkProcessing::processPixel(int x, int y) { } default: ASSERT(false); - return; + return false; } - *m_dstAddress = c; + *result = c; + return true; } template<> -void BrushInkProcessing::processPixel(int x, int y) { +bool BrushInkProcessingBase::preProcessPixel(int x, int y, color_t* result) { alignPixelPoint(x, y); if (m_brushMask && !get_pixel_fast(m_brushMask, x, y)) - return; + return false; color_t c; switch (m_brushImage->pixelFormat()) { @@ -1233,16 +1242,17 @@ void BrushInkProcessing::processPixel(int x, int y) { } default: ASSERT(false); - return; + return false; } - *m_dstAddress = c; + *result = c; + return true; } template<> -void BrushInkProcessing::processPixel(int x, int y) { +bool BrushInkProcessingBase::preProcessPixel(int x, int y, color_t* result) { alignPixelPoint(x, y); if (m_brushMask && !get_pixel_fast(m_brushMask, x, y)) - return; + return false; color_t c; switch (m_brushImage->pixelFormat()) { @@ -1271,12 +1281,88 @@ void BrushInkProcessing::processPixel(int x, int y) { } default: ASSERT(false); - return; + return false; } - if (c != m_transparentColor) + if (c != m_transparentColor) { + *result = c; + return true; + } + return false; +} + +////////////////////////////////////////////////////////////////////// +// Brush Ink - Simple ink type +////////////////////////////////////////////////////////////////////// + +template +class BrushSimpleInkProcessing : public BrushInkProcessingBase { +public: + BrushSimpleInkProcessing(ToolLoop* loop) : BrushInkProcessingBase(loop) { + } + + void processPixel(int x, int y) override { + // Do nothing + } +}; + +template<> +void BrushSimpleInkProcessing::processPixel(int x, int y) { + color_t c; + if (preProcessPixel(x, y, &c)) *m_dstAddress = c; } +template<> +void BrushSimpleInkProcessing::processPixel(int x, int y) { + color_t c; + if (preProcessPixel(x, y, &c)) + *m_dstAddress = c; +} + +template<> +void BrushSimpleInkProcessing::processPixel(int x, int y) { + color_t c; + if (preProcessPixel(x, y, &c)) + *m_dstAddress = c; +} + +////////////////////////////////////////////////////////////////////// +// Brush Ink - Lock Alpha ink type +////////////////////////////////////////////////////////////////////// + +template +class BrushLockAlphaInkProcessing : public BrushInkProcessingBase { +public: + BrushLockAlphaInkProcessing(ToolLoop* loop) : BrushInkProcessingBase(loop) { + } + + void processPixel(int x, int y) override { + //Do nothing + } +}; + +template<> +void BrushLockAlphaInkProcessing::processPixel(int x, int y) { + color_t c; + if (preProcessPixel(x, y, &c)) + *m_dstAddress = rgba(rgba_getr(c), rgba_getg(c), rgba_getb(c), rgba_geta(*m_srcAddress)); +} + +template<> +void BrushLockAlphaInkProcessing::processPixel(int x, int y) { + color_t c; + if (preProcessPixel(x, y, &c)) + if (*m_srcAddress != getTransparentColor()) + *m_dstAddress = c; +} + +template<> +void BrushLockAlphaInkProcessing::processPixel(int x, int y) { + color_t c; + if (preProcessPixel(x, y, &c)) + *m_dstAddress = graya(graya_getv(c), graya_geta(*m_srcAddress)); +} + ////////////////////////////////////////////////////////////////////// template class T> diff --git a/src/app/tools/inks.h b/src/app/tools/inks.h index 5f3c9cdcd..cc8a2420a 100644 --- a/src/app/tools/inks.h +++ b/src/app/tools/inks.h @@ -82,7 +82,17 @@ public: } if (loop->getBrush()->type() == doc::kImageBrushType) - setProc(get_ink_proc(loop)); + switch (m_type) { + case Simple: + setProc(get_ink_proc(loop)); + break; + case LockAlpha: + setProc(get_ink_proc(loop)); + break; + default: + setProc(get_ink_proc(loop)); + break; + } else { switch (m_type) { case Simple: {