[aseprite] 31/134: Fix ReplaceInkProcessing to work correctly with transparent colors (fix #435)
Tobias Hansen
thansen at moszumanska.debian.org
Sat Mar 14 17:09:58 UTC 2015
This is an automated email from the git hooks/post-receive script.
thansen pushed a commit to branch master
in repository aseprite.
commit 8a9ea2681171fa5bc2ff8eed05831c25deffb350
Author: David Capello <davidcapello at gmail.com>
Date: Sat Nov 1 23:14:48 2014 -0300
Fix ReplaceInkProcessing to work correctly with transparent colors (fix #435)
Now we can replace a solid color with transparent in RGBA and Grayscale
images.
---
src/app/color_utils.cpp | 51 ++++++++++++++++++++++++++----------------
src/app/tools/ink_processing.h | 22 ++++++++++++++----
src/raster/blend.cpp | 18 ++++++++++-----
3 files changed, 62 insertions(+), 29 deletions(-)
diff --git a/src/app/color_utils.cpp b/src/app/color_utils.cpp
index 67c8f0f..d7867e9 100644
--- a/src/app/color_utils.cpp
+++ b/src/app/color_utils.cpp
@@ -119,31 +119,44 @@ raster::color_t color_utils::color_for_layer(const app::Color& color, Layer* lay
raster::color_t color_utils::color_for_target(const app::Color& color, const ColorTarget& colorTarget)
{
- if (color.getType() == app::Color::MaskType)
- return colorTarget.maskColor();
-
raster::color_t c = -1;
+ if (color.getType() == app::Color::MaskType) {
+ c = colorTarget.maskColor();
+ }
+ else {
+ switch (colorTarget.pixelFormat()) {
+ case IMAGE_RGB:
+ c = raster::rgba(color.getRed(), color.getGreen(), color.getBlue(), 255);
+ break;
+ case IMAGE_GRAYSCALE:
+ c = raster::graya(color.getGray(), 255);
+ break;
+ case IMAGE_INDEXED:
+ if (color.getType() == app::Color::IndexType) {
+ c = color.getIndex();
+ }
+ else {
+ c = get_current_palette()->findBestfit(
+ color.getRed(),
+ color.getGreen(),
+ color.getBlue(),
+ colorTarget.isTransparent() ?
+ colorTarget.maskColor(): // Don't return the mask color
+ -1); // Return any color, we are in a background layer.
+ }
+ break;
+ }
+ }
+
switch (colorTarget.pixelFormat()) {
case IMAGE_RGB:
- c = raster::rgba(color.getRed(), color.getGreen(), color.getBlue(), 255);
+ if (colorTarget.isBackground())
+ c |= raster::rgba(0, 0, 0, 255);
break;
case IMAGE_GRAYSCALE:
- c = raster::graya(color.getGray(), 255);
- break;
- case IMAGE_INDEXED:
- if (color.getType() == app::Color::IndexType) {
- c = color.getIndex();
- }
- else {
- c = get_current_palette()->findBestfit(
- color.getRed(),
- color.getGreen(),
- color.getBlue(),
- colorTarget.isTransparent() ?
- colorTarget.maskColor(): // Don't return the mask color
- -1); // Return any color, we are in a background layer.
- }
+ if (colorTarget.isBackground())
+ c |= raster::graya(0, 255);
break;
}
diff --git a/src/app/tools/ink_processing.h b/src/app/tools/ink_processing.h
index a18d4dc..4909a94 100644
--- a/src/app/tools/ink_processing.h
+++ b/src/app/tools/ink_processing.h
@@ -22,6 +22,7 @@
#include "app/tools/shading_options.h"
#include "filters/neighboring_pixels.h"
#include "raster/palette.h"
+#include "raster/raster.h"
#include "raster/rgbmap.h"
#include "raster/sprite.h"
@@ -475,14 +476,27 @@ private:
template<>
void ReplaceInkProcessing<RgbTraits>::processPixel(int x, int y) {
- if (*m_srcAddress == m_color1)
- *m_dstAddress = rgba_blend_normal(*m_srcAddress, m_color2, m_opacity);
+ color_t src = (*m_srcAddress);
+
+ // Colors (m_srcAddress and m_color1) match if:
+ // * They are both completelly transparent (alpha == 0)
+ // * Or they are not transparent and the RGB values are the same
+ if ((rgba_geta(src) == 0 && rgba_geta(m_color1) == 0) ||
+ (rgba_geta(src) > 0 && rgba_geta(m_color1) > 0 &&
+ ((src & rgba_rgb_mask) == (m_color1 & rgba_rgb_mask)))) {
+ *m_dstAddress = rgba_blend_merge(src, m_color2, m_opacity);
+ }
}
template<>
void ReplaceInkProcessing<GrayscaleTraits>::processPixel(int x, int y) {
- if (*m_srcAddress == m_color1)
- *m_dstAddress = graya_blend_normal(*m_srcAddress, m_color2, m_opacity);
+ color_t src = (*m_srcAddress);
+
+ if ((graya_geta(src) == 0 && graya_geta(m_color1) == 0) ||
+ (graya_geta(src) > 0 && graya_geta(m_color1) > 0 &&
+ ((src & graya_v_mask) == (m_color1 & graya_v_mask)))) {
+ *m_dstAddress = graya_blend_merge(src, m_color2, m_opacity);
+ }
}
template<>
diff --git a/src/raster/blend.cpp b/src/raster/blend.cpp
index 2399bab..8dc2a1d 100644
--- a/src/raster/blend.cpp
+++ b/src/raster/blend.cpp
@@ -109,6 +109,7 @@ int rgba_blend_merge(int back, int front, int opacity)
int B_r, B_g, B_b, B_a;
int F_r, F_g, F_b, F_a;
int D_r, D_g, D_b, D_a;
+ int t;
B_r = rgba_getr(back);
B_g = rgba_getg(back);
@@ -131,11 +132,13 @@ int rgba_blend_merge(int back, int front, int opacity)
D_b = B_b;
}
else {
- D_r = B_r + (F_r-B_r) * opacity / 255;
- D_g = B_g + (F_g-B_g) * opacity / 255;
- D_b = B_b + (F_b-B_b) * opacity / 255;
+ D_r = B_r + INT_MULT((F_r - B_r), opacity, t);
+ D_g = B_g + INT_MULT((F_g - B_g), opacity, t);
+ D_b = B_b + INT_MULT((F_b - B_b), opacity, t);
}
- D_a = B_a + (F_a-B_a) * opacity / 255;
+ D_a = B_a + INT_MULT((F_a - B_a), opacity, t);
+ if (D_a == 0)
+ D_r = D_g = D_b = 0;
return rgba(D_r, D_g, D_b, D_a);
}
@@ -274,6 +277,7 @@ int graya_blend_merge(int back, int front, int opacity)
int B_k, B_a;
int F_k, F_a;
int D_k, D_a;
+ int t;
B_k = graya_getv(back);
B_a = graya_geta(back);
@@ -288,9 +292,11 @@ int graya_blend_merge(int back, int front, int opacity)
D_k = B_k;
}
else {
- D_k = B_k + (F_k-B_k) * opacity / 255;
+ D_k = B_k + INT_MULT((F_k-B_k), opacity, t);
}
- D_a = B_a + (F_a-B_a) * opacity / 255;
+ D_a = B_a + INT_MULT((F_a-B_a), opacity, t);
+ if (D_a == 0)
+ D_k = 0;
return graya(D_k, D_a);
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/aseprite.git
More information about the Pkg-games-commits
mailing list