[gimp] Bug 631609 - [regression] no transparency on antialiased fonts



commit db72c72c1f057ee3f1f096c5d7a43a9633bd4d9e
Author: Sven Neumann <sven gimp org>
Date:   Thu Oct 7 22:21:49 2010 +0200

    Bug 631609 - [regression] no transparency on antialiased fonts
    
    Render the layout into an ARGB32 surface and convert the text layer
    pixel format from that.

 app/text/gimptextlayer.c         |   72 +++++++++++++++-----------------------
 libgimpwidgets/gimpcairo-utils.h |   38 ++++++++++++++++++++
 2 files changed, 66 insertions(+), 44 deletions(-)
---
diff --git a/app/text/gimptextlayer.c b/app/text/gimptextlayer.c
index 365f003..f5072ce 100644
--- a/app/text/gimptextlayer.c
+++ b/app/text/gimptextlayer.c
@@ -641,15 +641,12 @@ gimp_text_layer_render_layout (GimpTextLayer  *layer,
   GimpItem        *item     = GIMP_ITEM (layer);
   GimpImage       *image    = gimp_item_get_image (item);
   cairo_t         *cr;
-  cairo_surface_t *rgb_surface;
-  cairo_surface_t *alpha_surface;
+  cairo_surface_t *surface;
   PixelRegion      layerPR;
-  const guchar    *rgb_data;
-  const guchar    *alpha_data;
+  const guchar    *data;
   GimpImageType    layer_type;
   gint             layer_alpha_byte;
-  gint             rgb_rowstride;
-  gint             alpha_rowstride;
+  gint             rowstride;
   gint             width;
   gint             height;
   gpointer         pr;
@@ -659,73 +656,60 @@ gimp_text_layer_render_layout (GimpTextLayer  *layer,
   width  = gimp_item_get_width  (item);
   height = gimp_item_get_height (item);
 
-  rgb_surface   = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
-  alpha_surface = cairo_image_surface_create (CAIRO_FORMAT_A8,    width, height);
+  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
 
-  cr = cairo_create (rgb_surface);
-  gimp_text_layout_render (layout, cr, layer->text->base_dir, FALSE);
-  cairo_destroy (cr);
-
-  cr = cairo_create (alpha_surface);
+  cr = cairo_create (surface);
   gimp_text_layout_render (layout, cr, layer->text->base_dir, FALSE);
   cairo_destroy (cr);
 
   pixel_region_init (&layerPR, gimp_drawable_get_tiles (drawable),
                      0, 0, width, height, TRUE);
 
-  layer_type       = gimp_drawable_type (drawable);
+  layer_type = gimp_drawable_type (drawable);
   layer_alpha_byte = layerPR.bytes - 1;
 
-  cairo_surface_flush (rgb_surface);
-  rgb_data      = cairo_image_surface_get_data (rgb_surface);
-  rgb_rowstride = cairo_image_surface_get_stride (rgb_surface);
-
-  cairo_surface_flush (alpha_surface);
-  alpha_data      = cairo_image_surface_get_data (alpha_surface);
-  alpha_rowstride = cairo_image_surface_get_stride (alpha_surface);
+  cairo_surface_flush (surface);
+  data      = cairo_image_surface_get_data (surface);
+  rowstride = cairo_image_surface_get_stride (surface);
 
   for (pr = pixel_regions_register (1, &layerPR);
        pr != NULL;
        pr = pixel_regions_process (pr))
     {
-      const guchar *rgb_src;
-      const guchar *alpha_src;
+      const guchar *src  = data + layerPR.y * rowstride + layerPR.x * 4;
       guchar       *dest = layerPR.data;
       gint          rows = layerPR.h;
 
-      rgb_src   = rgb_data   + layerPR.x * 4 + layerPR.y * rgb_rowstride;
-      alpha_src = alpha_data + layerPR.x     + layerPR.y * alpha_rowstride;
-
       while (rows--)
         {
-          const guchar *rgb   = rgb_src;
-          const guchar *alpha = alpha_src;
-          guchar       *d     = dest;
-          gint          i;
+          const guchar *s = src;
+          guchar       *d = dest;
+          gint          w = layerPR.w;
 
-          for (i = 0; i < layerPR.w; i++)
+          while (w--)
             {
-              guchar color[3];
+              guchar color[4];
 
-              GIMP_CAIRO_RGB24_GET_PIXEL (rgb, color[0], color[1], color[2]);
+              GIMP_CAIRO_ARGB32_GET_PIXEL (s,
+                                           color[0],
+                                           color[1],
+                                           color[2],
+                                           color[3]);
 
-              gimp_image_transform_color (image, layer_type, d,
-                                          GIMP_RGB, color);
-              d[layer_alpha_byte] = *alpha;
+              gimp_image_transform_color (image,
+                                          layer_type, d, GIMP_RGB, color);
+              d[layer_alpha_byte] = color[3];
 
-              rgb   += 4;
-              alpha += 1;
-              d     += layerPR.bytes;
+              s += 4;
+              d += layerPR.bytes;
             }
 
-          rgb_src   += rgb_rowstride;
-          alpha_src += alpha_rowstride;
-          dest      += layerPR.rowstride;
+          src  += rowstride;
+          dest += layerPR.rowstride;
         }
     }
 
-  cairo_surface_destroy (rgb_surface);
-  cairo_surface_destroy (alpha_surface);
+  cairo_surface_destroy (surface);
 
   gimp_drawable_update (drawable, 0, 0, width, height);
 }
diff --git a/libgimpwidgets/gimpcairo-utils.h b/libgimpwidgets/gimpcairo-utils.h
index 7ccf27d..6d614a0 100644
--- a/libgimpwidgets/gimpcairo-utils.h
+++ b/libgimpwidgets/gimpcairo-utils.h
@@ -123,5 +123,43 @@ cairo_surface_t * gimp_cairo_surface_create_from_pixbuf (GdkPixbuf     *pixbuf);
   } G_STMT_END
 #endif
 
+/**
+ * GIMP_CAIRO_ARGB32_GET_PIXEL:
+ * @s: pointer to the source buffer
+ * @r: red component, not pre-multiplied
+ * @g: green component, not pre-multiplied
+ * @b: blue component, not pre-multiplied
+ * @a: alpha component
+ *
+ * Gets a single pixel from a Cairo image surface in %CAIRO_FORMAT_ARGB32.
+ *
+ * Since: GIMP 2.8
+ **/
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+#define GIMP_CAIRO_ARGB32_GET_PIXEL(s, r, g, b, a) \
+  G_STMT_START {                                   \
+    const guint tb = s[0];                         \
+    const guint tg = s[1];                         \
+    const guint tr = s[2];                         \
+    const guint ta = s[3];                         \
+    (r) = (tr << 8) / (ta + 1);                    \
+    (g) = (tg << 8) / (ta + 1);                    \
+    (b) = (tb << 8) / (ta + 1);                    \
+    (a) = ta;                                      \
+  } G_STMT_END
+#else
+#define GIMP_CAIRO_ARGB32_GET_PIXEL(s, r, g, b, a) \
+  G_STMT_START {                                   \
+    const guint ta = s[0];                         \
+    const guint tr = s[1];                         \
+    const guint tg = s[2];                         \
+    const guint tb = s[3];                         \
+    (r) = (tr << 8) / (ta + 1);                    \
+    (g) = (tg << 8) / (ta + 1);                    \
+    (b) = (tb << 8) / (ta + 1);                    \
+    (a) = ta;                                      \
+  } G_STMT_END
+#endif
+
 
 #endif /* __GIMP_CAIRO_UTILS_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]