Index: gimp/app/paint-funcs/paint-funcs.c
===================================================================
RCS file: /cvs/gnome/gimp/app/paint-funcs/paint-funcs.c,v
retrieving revision 1.159
diff -u -p -r1.159 paint-funcs.c
--- a/gimp/app/paint-funcs/paint-funcs.c	15 Apr 2004 12:38:54 -0000	1.159
+++ b/gimp/app/paint-funcs/paint-funcs.c	29 May 2004 10:13:32 -0000
@@ -2372,13 +2372,15 @@ convolve_region (PixelRegion            
   gint   *m;
   gint    total [4];
   gint    b, bytes;
+  gint    alpha, a_byte;
   gint    length;
   gint    wraparound;
   gint    margin;      /*  margin imposed by size of conv. matrix  */
   gint    i, j;
   gint    x, y;
   gint    offset;
-
+  gdouble weighted_divisor, dalpha;
+  
   /*  If the mode is NEGATIVE_CONVOL, the offset should be 128  */
   if (mode == GIMP_NEGATIVE_CONVOL)
     {
@@ -2394,6 +2396,7 @@ convolve_region (PixelRegion            
 
   /*  Initialize some values  */
   bytes = srcR->bytes;
+  a_byte = bytes - 1;
   length = bytes * srcR->w;
   margin = size / 2;
   src = srcR->data;
@@ -2425,41 +2428,109 @@ convolve_region (PixelRegion            
 
       /* now, handle the center pixels */
       x = srcR->w - margin*2;
-      while (x--)
-        {
-          s = s_row;
 
-          m = matrix;
-          total [0] = total [1] = total [2] = total [3] = 0;
-          i = size;
-          while (i --)
+      if (HAS_ALPHA (bytes))
+        {
+          while (x--)
             {
-              j = size;
-              while (j --)
+              s = s_row;
+
+              m = matrix;
+              total [0] = total [1] = total [2] = total [3] = 0;
+              weighted_divisor = 0.0;
+              
+              i = size;
+              while (i --)
                 {
-                  for (b = 0; b < bytes; b++)
-                    total [b] += *m * *s++;
-                  m ++;
+                  j = size;
+                  while (j --)
+                    {
+                      alpha = s [a_byte];
+
+                      if (alpha && *m)
+                        {
+                          if (alpha == 255)
+                            {
+                              for (b = 0; b < bytes; b++)
+                                total [b] += *m * *s++;
+                              
+                              weighted_divisor += *m;
+                            }
+                          else
+                            {
+                              dalpha = *m * (alpha / 255.0);
+                              
+                              for (b = 0; b < bytes; b++)
+                                total [b] += (gint)(dalpha * *s++);
+                              
+                              weighted_divisor += dalpha;
+                            }
+                        }
+                      else
+                        s += bytes;
+                      
+                      m ++;
+                    }
+
+                  s += wraparound;
                 }
 
-              s += wraparound;
-            }
+              if (weighted_divisor == 0.0)
+                weighted_divisor = 1.0;
 
-          for (b = 0; b < bytes; b++)
-            {
-              total [b] = total [b] / divisor + offset;
+              for (b = 0; b < bytes; b++)
+                {
+                  total [b] = (gint)(total [b] / weighted_divisor) + offset;
 
-              if (total [b] < 0 && mode != GIMP_NORMAL_CONVOL)
-                total [b] = - total [b];
+                  if (total [b] < 0 && mode != GIMP_NORMAL_CONVOL)
+                    total [b] = - total [b];
 
-              if (total [b] < 0)
-                *d++ = 0;
-              else
-                *d++ = (total [b] > 255) ? 255 : (guchar) total [b];
+                  if (total [b] < 0)
+                    *d++ = 0;
+                  else
+                    *d++ = (total [b] > 255) ? 255 : (guchar) total [b];
+                }
+
+              s_row += bytes;
             }
+        }
+      else
+        {
+          while (x--)
+            {
+              s = s_row;
+
+              m = matrix;
+              total [0] = total [1] = total [2] = total [3] = 0;
+              i = size;
+              while (i --)
+                {
+                  j = size;
+                  while (j --)
+                    {
+                      for (b = 0; b < bytes; b++)
+                        total [b] += *m * *s++;
+                      m ++;
+                    }
+
+                  s += wraparound;
+                }
 
-          s_row += bytes;
+              for (b = 0; b < bytes; b++)
+                {
+                  total [b] = total [b] / divisor + offset;
+
+                  if (total [b] < 0 && mode != GIMP_NORMAL_CONVOL)
+                    total [b] = - total [b];
+
+                  if (total [b] < 0)
+                    *d++ = 0;
+                  else
+                    *d++ = (total [b] > 255) ? 255 : (guchar) total [b];
+                }
 
+              s_row += bytes;
+            }
         }
 
       /* handle the last pixel... */
