Use fg/bg color alpha to modify custom brush alpha

Bug reported here: https://twitter.com/dovker/status/880137802142429184
This commit is contained in:
David Capello 2017-06-29 14:24:28 -03:00
parent cc8337fa84
commit 91c9cc29b0
2 changed files with 44 additions and 23 deletions

View File

@ -1524,11 +1524,13 @@ void ContextBar::onFgOrBgColorChange(doc::Brush::ImageColor imageColor)
auto& pref = Preferences::instance();
m_activeBrush->setImageColor(
imageColor,
color_utils::color_for_image(
color_utils::color_for_target_mask(
(imageColor == doc::Brush::ImageColor::MainColor ?
pref.colorBar.fgColor():
pref.colorBar.bgColor()),
m_activeBrush->image()->pixelFormat()));
ColorTarget(ColorTarget::TransparentLayer,
m_activeBrush->image()->pixelFormat(),
-1)));
}
}
@ -1822,13 +1824,19 @@ void ContextBar::setActiveBrushBySlot(tools::Tool* tool, int slot)
brush.brush()->setImageColor(
Brush::ImageColor::MainColor,
color_utils::color_for_image(pref.colorBar.fgColor(),
pixelFormat));
color_utils::color_for_target_mask(
pref.colorBar.fgColor(),
ColorTarget(ColorTarget::TransparentLayer,
pixelFormat,
-1)));
brush.brush()->setImageColor(
Brush::ImageColor::BackgroundColor,
color_utils::color_for_image(pref.colorBar.bgColor(),
pixelFormat));
color_utils::color_for_target_mask(
pref.colorBar.bgColor(),
ColorTarget(ColorTarget::TransparentLayer,
pixelFormat,
-1)));
}
if (brush.hasFlag(BrushSlot::Flags::InkType))

View File

@ -13,6 +13,7 @@
#include "base/pi.h"
#include "doc/algo.h"
#include "doc/algorithm/polygon.h"
#include "doc/blend_internals.h"
#include "doc/image.h"
#include "doc/image_impl.h"
#include "doc/primitives.h"
@ -114,7 +115,8 @@ void Brush::setImage(const Image* image,
template<class ImageTraits,
color_t color_mask,
color_t alpha_mask>
color_t alpha_mask,
color_t alpha_shift>
static void replace_image_colors(
Image* image,
Image* maskBitmap,
@ -145,25 +147,36 @@ static void replace_image_colors(
++mask_it;
}
mainColor &= color_mask;
bgColor &= color_mask;
int t;
if (hasAlpha) {
for (auto& pixel : bits) {
if (useMain)
pixel = (pixel & alpha_mask) | mainColor;
else if (useBg)
pixel = (pixel & alpha_mask) | bgColor;
if (useMain || useBg) {
const color_t color = (useMain ? mainColor: useBg);
for (auto& pixel : bits) {
color_t a1 = (pixel & alpha_mask) >> alpha_shift;
const color_t a2 = (color & alpha_mask) >> alpha_shift;
a1 = MUL_UN8(a1, a2, t);
pixel =
(a1 << alpha_shift) |
(color & color_mask);
}
}
}
else {
for (auto& pixel : bits) {
if (useMain && ((pixel != srcBgColor) || (srcMainColor == srcBgColor))) {
pixel = (pixel & alpha_mask) | mainColor;
}
else if (useBg && (pixel == srcBgColor)) {
pixel = (pixel & alpha_mask) | bgColor;
}
color_t color;
if (useMain && ((pixel != srcBgColor) || (srcMainColor == srcBgColor)))
color = mainColor;
else if (useBg && (pixel == srcBgColor))
color = bgColor;
else
continue;
color_t a1 = (pixel & alpha_mask) >> alpha_shift;
color_t a2 = (color & alpha_mask) >> alpha_shift;
a1 = MUL_UN8(a1, a2, t);
pixel =
(a1 << alpha_shift) |
(color & color_mask);
}
}
}
@ -246,14 +259,14 @@ void Brush::setImageColor(ImageColor imageColor, color_t color)
switch (m_image->pixelFormat()) {
case IMAGE_RGB:
replace_image_colors<RgbTraits, rgba_rgb_mask, rgba_a_mask>(
replace_image_colors<RgbTraits, rgba_rgb_mask, rgba_a_mask, rgba_a_shift>(
m_image.get(), m_maskBitmap.get(),
(m_mainColor ? true: false), (m_mainColor ? *m_mainColor: 0),
(m_bgColor ? true: false), (m_bgColor ? *m_bgColor: 0));
break;
case IMAGE_GRAYSCALE:
replace_image_colors<GrayscaleTraits, graya_v_mask, graya_a_mask>(
replace_image_colors<GrayscaleTraits, graya_v_mask, graya_a_mask, graya_a_shift>(
m_image.get(), m_maskBitmap.get(),
(m_mainColor ? true: false), (m_mainColor ? *m_mainColor: 0),
(m_bgColor ? true: false), (m_bgColor ? *m_bgColor: 0));