]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkcairoblur.c
filechooserbutton: In SELECT_FOLDER, when the selection is empty, show (None) in...
[~andy/gtk] / gtk / gtkcairoblur.c
index c85e2e2ee62b32b7e9d7def123c47c8a5c67d72d..3f944e24297d39e42a50ed7b0bedca0085821f34 100644 (file)
@@ -64,6 +64,7 @@ static inline void
 _blurrow (guchar* pixels,
           gint    width,
           gint    height,
+          gint    rowstride,
           gint    channels,
           gint    line,
           gint    alpha,
@@ -77,7 +78,7 @@ _blurrow (guchar* pixels,
   gint    index;
   guchar* scanline;
 
-  scanline = &(pixels[line * width * channels]);
+  scanline = &pixels[line * rowstride];
 
   zR = *scanline << zprec;
   zG = *(scanline + 1) << zprec;
@@ -109,6 +110,7 @@ static inline void
 _blurcol (guchar* pixels,
           gint    width,
           gint    height,
+          gint    rowstride,
           gint    channels,
           gint    x,
           gint    alpha,
@@ -131,8 +133,8 @@ _blurcol (guchar* pixels,
   zB = *((guchar*) ptr + 2) << zprec;
   zA = *((guchar*) ptr + 3) << zprec;
 
-  for (index = width; index < (height - 1) * width; index += width)
-    _blurinner ((guchar*) &ptr[index * channels],
+  for (index = 0; index < height; index++)
+    _blurinner (&ptr[index * rowstride],
                 &zR,
                 &zG,
                 &zB,
@@ -141,8 +143,8 @@ _blurcol (guchar* pixels,
                 aprec,
                 zprec);
 
-  for (index = (height - 2) * width; index >= 0; index -= width)
-    _blurinner ((guchar*) &ptr[index * channels],
+  for (index = height - 2; index >= 0; index--)
+    _blurinner (&ptr[index * rowstride],
                 &zR,
                 &zG,
                 &zB,
@@ -157,6 +159,7 @@ _blurcol (guchar* pixels,
  * @pixels: image data
  * @width: image width
  * @height: image height
+ * @rowstride: image rowstride
  * @channels: image channels
  * @radius: kernel radius
  * @aprec: precision of alpha parameter in fixed-point format 0.aprec
@@ -172,37 +175,36 @@ static void
 _expblur (guchar* pixels,
           gint    width,
           gint    height,
+          gint    rowstride,
           gint    channels,
-          gint    radius,
+          double  radius,
           gint    aprec,
           gint    zprec)
 {
   gint alpha;
-  gint row = 0;
-  gint col = 0;
-
-  if (radius < 1)
-    return;
+  int row, col;
 
   /* Calculate the alpha such that 90% of 
    * the kernel is within the radius.
    * (Kernel extends to infinity) */
   alpha = (gint) ((1 << aprec) * (1.0f - expf (-2.3f / (radius + 1.f))));
 
-  for (; row < height; row++)
+  for (row = 0; row < height; row++)
     _blurrow (pixels,
               width,
               height,
+              rowstride,
               channels,
               row,
               alpha,
               aprec,
               zprec);
 
-  for(; col < width; col++)
+  for(col = 0; col < width; col++)
     _blurcol (pixels,
               width,
               height,
+              rowstride,
               channels,
               col,
               alpha,
@@ -217,23 +219,18 @@ _expblur (guchar* pixels,
  * @radius: the blur radius.
  *
  * Blurs the cairo image surface at the given radius.
- *
  */
 void
 _gtk_cairo_blur_surface (cairo_surface_t* surface,
-                         guint            radius)
+                         double           radius)
 {
   cairo_format_t format;
-  guchar*        pixels;
-  guint          width;
-  guint          height;
 
   g_return_if_fail (surface != NULL);
   g_return_if_fail (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_IMAGE);
 
   format = cairo_image_surface_get_format (surface);
-  g_return_if_fail (format == CAIRO_FORMAT_A8 ||
-                    format == CAIRO_FORMAT_RGB24 ||
+  g_return_if_fail (format == CAIRO_FORMAT_RGB24 ||
                     format == CAIRO_FORMAT_ARGB32);
 
   if (radius == 0)
@@ -242,25 +239,14 @@ _gtk_cairo_blur_surface (cairo_surface_t* surface,
   /* Before we mess with the surface execute any pending drawing. */
   cairo_surface_flush (surface);
 
-  pixels = cairo_image_surface_get_data (surface);
-  width  = cairo_image_surface_get_width (surface);
-  height = cairo_image_surface_get_height (surface);
-  format = cairo_image_surface_get_format (surface);
-
-  switch (format)
-  {
-    case CAIRO_FORMAT_ARGB32:
-      _expblur (pixels, width, height, 4, radius, 16, 7);
-      break;
-    case CAIRO_FORMAT_RGB24:
-      _expblur (pixels, width, height, 3, radius, 16, 7);
-      break;
-    case CAIRO_FORMAT_A8:
-      _expblur (pixels, width, height, 1, radius, 16, 7);
-      break;
-    default:
-      break;
-  }
+  _expblur (cairo_image_surface_get_data (surface),
+            cairo_image_surface_get_width (surface),
+            cairo_image_surface_get_height (surface),
+            cairo_image_surface_get_stride (surface),
+            4,
+            radius,
+            16,
+            7);
 
   /* Inform cairo we altered the surfaces contents. */
   cairo_surface_mark_dirty (surface);