Fix Eraser tool to handle opacity values correctly

This commit is contained in:
David Capello 2015-09-30 08:59:59 -03:00
parent 3d4fdb62b4
commit 30b257a8f5
2 changed files with 92 additions and 4 deletions

View File

@ -264,6 +264,72 @@ private:
const int m_maskIndex;
};
//////////////////////////////////////////////////////////////////////
// Merge Ink
//////////////////////////////////////////////////////////////////////
template<typename ImageTraits>
class MergeInkProcessing : public DoubleInkProcessing<MergeInkProcessing<ImageTraits>, ImageTraits> {
public:
MergeInkProcessing(ToolLoop* loop) {
m_color = loop->getPrimaryColor();
m_opacity = loop->getOpacity();
}
void processPixel(int x, int y) {
// Do nothing
}
private:
color_t m_color;
int m_opacity;
};
template<>
void MergeInkProcessing<RgbTraits>::processPixel(int x, int y) {
*m_dstAddress = rgba_blender_merge(*m_srcAddress, m_color, m_opacity);
}
template<>
void MergeInkProcessing<GrayscaleTraits>::processPixel(int x, int y) {
*m_dstAddress = graya_blender_merge(*m_srcAddress, m_color, m_opacity);
}
template<>
class MergeInkProcessing<IndexedTraits> : public DoubleInkProcessing<MergeInkProcessing<IndexedTraits>, IndexedTraits> {
public:
MergeInkProcessing(ToolLoop* loop) :
m_palette(get_current_palette()),
m_rgbmap(loop->getRgbMap()),
m_opacity(loop->getOpacity()),
m_maskIndex(loop->getLayer()->isBackground() ? -1: loop->sprite()->transparentColor()),
m_color(loop->getPrimaryColor() == m_maskIndex ?
(m_palette->getEntry(loop->getPrimaryColor()) & rgba_rgb_mask):
(m_palette->getEntry(loop->getPrimaryColor()))) {
}
void processPixel(int x, int y) {
color_t c = *m_srcAddress;
if (c == m_maskIndex)
c = m_palette->getEntry(c) & rgba_rgb_mask; // Alpha = 0
else
c = m_palette->getEntry(c);
c = rgba_blender_merge(c, m_color, m_opacity);
*m_dstAddress = m_rgbmap->mapColor(rgba_getr(c),
rgba_getg(c),
rgba_getb(c),
rgba_geta(c));
}
private:
const Palette* m_palette;
const RgbMap* m_rgbmap;
const int m_opacity;
const int m_maskIndex;
const color_t m_color;
};
//////////////////////////////////////////////////////////////////////
// Blur Ink
//////////////////////////////////////////////////////////////////////
@ -973,6 +1039,7 @@ enum {
INK_COPY,
INK_LOCKALPHA,
INK_TRANSPARENT,
INK_MERGE,
INK_BLUR,
INK_REPLACE,
INK_JUMBLE,
@ -1000,6 +1067,7 @@ AlgoHLine ink_processing[][3] =
DEFINE_INK(CopyInkProcessing),
DEFINE_INK(LockAlphaInkProcessing),
DEFINE_INK(TransparentInkProcessing),
DEFINE_INK(MergeInkProcessing),
DEFINE_INK(BlurInkProcessing),
DEFINE_INK(ReplaceInkProcessing),
DEFINE_INK(JumbleInkProcessing),

View File

@ -207,13 +207,33 @@ public:
{
switch (m_type) {
case Eraser:
m_proc = ink_processing[INK_COPY][MID(0, loop->sprite()->pixelFormat(), 2)];
case Eraser: {
color_t primary = app_get_color_to_clear_layer(loop->getLayer());
color_t secondary = app_get_color_to_clear_layer(loop->getLayer());
if (loop->getOpacity() == 255) {
m_proc = ink_processing[INK_COPY][MID(0, loop->sprite()->pixelFormat(), 2)];
}
else {
// For opaque layers
if (loop->getLayer()->isBackground()) {
m_proc = ink_processing[INK_TRANSPARENT][MID(0, loop->sprite()->pixelFormat(), 2)];
}
// For transparent layers
else {
m_proc = ink_processing[INK_MERGE][MID(0, loop->sprite()->pixelFormat(), 2)];
if (loop->sprite()->pixelFormat() == IMAGE_INDEXED) {
primary = loop->sprite()->transparentColor();
}
}
}
// TODO app_get_color_to_clear_layer should receive the context as parameter
loop->setPrimaryColor(app_get_color_to_clear_layer(loop->getLayer()));
loop->setSecondaryColor(app_get_color_to_clear_layer(loop->getLayer()));
loop->setPrimaryColor(primary);
loop->setSecondaryColor(secondary);
break;
}
case ReplaceFgWithBg:
m_proc = ink_processing[INK_REPLACE][MID(0, loop->sprite()->pixelFormat(), 2)];