[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