Index: app/paint-funcs/paint-funcs.c
===================================================================
--- app/paint-funcs/paint-funcs.c	(revision 26353)
+++ app/paint-funcs/paint-funcs.c	(working copy)
@@ -1402,54 +1402,38 @@
                       guint           bytes1,
                       guint           bytes2)
 {
-  const guint has_alpha1 = HAS_ALPHA (bytes1);
-  const guint has_alpha2 = HAS_ALPHA (bytes2);
-  const guint bytes      = MIN (bytes1, bytes2);
-  guint b;
-  gint  tmp;
+  const guint   has_alpha1 = HAS_ALPHA (bytes1);
+  const guint   has_alpha2 = HAS_ALPHA (bytes2);
+  const guint   alpha      = bytes1 - has_alpha1;
+  const guint   alpha2     = bytes2 - has_alpha2;
+  const guchar *m          = mask ? mask : &no_mask;
+  guint         b;
+  gint          tmp;
 
-  if (mask)
+  while (length --)
     {
-      const guchar *m = mask;
+      guchar mask_alpha  = INT_MULT (*m, opacity, tmp);
+      guchar src1_alpha  = has_alpha1 ? src1[alpha]  : 255;
+      guchar src2_alpha  = has_alpha2 ? src2[alpha2] : 255;
+      guchar new_alpha   = INT_BLEND (src2_alpha, src1_alpha, mask_alpha, tmp);
 
-      while (length --)
-        {
-          guchar mask_alpha = INT_MULT (*m, opacity, tmp);
+      gfloat ratio       = new_alpha ? (float) INT_MULT (src2_alpha, mask_alpha, tmp) / new_alpha : 0.0;
+      gfloat compl_ratio = 1.0 - ratio;
 
-          for (b = 0; b < bytes; b++)
-            dest[b] = (affect[b] ?
-                       INT_BLEND (src2[b], src1[b], mask_alpha, tmp) :
-                       src1[b]);
+      for (b = 0; b < alpha; b++)
+          dest[b] = affect[b] ?
+            (guchar) (src2[b] * ratio + src1[b] * compl_ratio + EPSILON) : src1[b];
 
-          if (has_alpha1 && !has_alpha2)
-            dest[b] = src1[b];
+      if (has_alpha1)
+        dest[alpha] = affect[alpha] ? new_alpha : src1[alpha];
 
-          m++;
+      if (mask)
+        m++;
 
-          src1 += bytes1;
-          src2 += bytes2;
-          dest += bytes1;
-        }
-    }
-  else
-    {
-      const guchar mask_alpha = opacity;
-
-      while (length --)
-        {
-          for (b = 0; b < bytes; b++)
-            dest[b] = (affect[b] ?
-                       INT_BLEND (src2[b], src1[b], mask_alpha, tmp) :
-                       src1[b]);
-
-          if (has_alpha1 && !has_alpha2)
-            dest[b] = src1[b];
-
-          src1 += bytes1;
-          src2 += bytes2;
-          dest += bytes1;
-        }
-    }
+      src1 += bytes1;
+      src2 += bytes2;
+      dest += bytes1;
+   }
 }
 
 /*  replace the contents of one pixel row with the other
