[gimp] app: render the text layout directly into the layer's pixels
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: render the text layout directly into the layer's pixels
- Date: Wed, 1 Sep 2010 21:32:56 +0000 (UTC)
commit 3759b3f0d1ba128eee9d6c3195b9b891aa75b582
Author: Michael Natterer <mitch gimp org>
Date: Wed Sep 1 23:30:40 2010 +0200
app: render the text layout directly into the layer's pixels
instead of using a mask. Enables color tags. Set the default color
from the text object using a pango color attibute and factor out
GimpTextLayout attribute setting into a utility function.
app/text/gimptextlayer.c | 97 +++++++++++++++++++++++++++++----------------
app/text/gimptextlayout.c | 59 +++++++++++++++++----------
2 files changed, 101 insertions(+), 55 deletions(-)
---
diff --git a/app/text/gimptextlayer.c b/app/text/gimptextlayer.c
index 779af21..4feca03 100644
--- a/app/text/gimptextlayer.c
+++ b/app/text/gimptextlayer.c
@@ -23,10 +23,12 @@
#include <string.h>
#include <gegl.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
#include <pango/pangocairo.h>
#include "libgimpbase/gimpbase.h"
#include "libgimpconfig/gimpconfig.h"
+#include "libgimpwidgets/gimpcairo-utils.h"
#include "text-types.h"
@@ -637,66 +639,93 @@ gimp_text_layer_render_layout (GimpTextLayer *layer,
{
GimpDrawable *drawable = GIMP_DRAWABLE (layer);
GimpItem *item = GIMP_ITEM (layer);
- TileManager *mask;
+ GimpImage *image = gimp_item_get_image (item);
cairo_t *cr;
- cairo_surface_t *surface;
- PixelRegion textPR;
- PixelRegion maskPR;
- const guchar *data;
- gint rowstride;
+ cairo_surface_t *rgb_surface;
+ cairo_surface_t *alpha_surface;
+ PixelRegion layerPR;
+ const guchar *rgb_data;
+ const guchar *alpha_data;
+ GimpImageType layer_type;
+ gint layer_alpha_byte;
+ gint rgb_rowstride;
+ gint alpha_rowstride;
gint width;
gint height;
gpointer pr;
- gimp_drawable_fill (drawable, &layer->text->color, NULL);
+ g_return_if_fail (gimp_drawable_has_alpha (drawable));
width = gimp_item_get_width (item);
height = gimp_item_get_height (item);
- surface = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
+ rgb_surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
+ alpha_surface = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
- cr = cairo_create (surface);
+ cr = cairo_create (rgb_surface);
+ gimp_text_layout_render (layout, cr, layer->text->base_dir, FALSE);
+ cairo_destroy (cr);
+ cr = cairo_create (alpha_surface);
gimp_text_layout_render (layout, cr, layer->text->base_dir, FALSE);
+ cairo_destroy (cr);
- mask = tile_manager_new ( width, height, 1);
- pixel_region_init (&maskPR, mask, 0, 0, width, height, TRUE);
+ pixel_region_init (&layerPR, gimp_drawable_get_tiles (drawable),
+ 0, 0, width, height, TRUE);
- cairo_surface_flush (surface);
+ layer_type = gimp_drawable_type (drawable);
+ layer_alpha_byte = layerPR.bytes - 1;
- data = cairo_image_surface_get_data (surface);
- rowstride = cairo_image_surface_get_stride (surface);
+ cairo_surface_flush (rgb_surface);
+ rgb_data = cairo_image_surface_get_data (rgb_surface);
+ rgb_rowstride = cairo_image_surface_get_stride (rgb_surface);
- for (pr = pixel_regions_register (1, &maskPR);
+ cairo_surface_flush (alpha_surface);
+ alpha_data = cairo_image_surface_get_data (alpha_surface);
+ alpha_rowstride = cairo_image_surface_get_stride (alpha_surface);
+
+ for (pr = pixel_regions_register (1, &layerPR);
pr != NULL;
pr = pixel_regions_process (pr))
{
- const guchar *src = data + maskPR.x + maskPR.y * rowstride;
- guchar *dest = maskPR.data;
- gint rows = maskPR.h;
+ const guchar *rgb_src;
+ const guchar *alpha_src;
+ 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--)
{
- memcpy (dest, src, maskPR.w);
+ const guchar *rgb = rgb_src;
+ const guchar *alpha = alpha_src;
+ guchar *d = dest;
+ gint i;
- src += rowstride;
- dest += maskPR.rowstride;
- }
- }
+ for (i = 0; i < layerPR.w; i++)
+ {
+ guchar color[3];
- cairo_destroy (cr);
- cairo_surface_destroy (surface);
+ GIMP_CAIRO_RGB24_GET_PIXEL (rgb, color[0], color[1], color[2]);
- pixel_region_init (&textPR, gimp_drawable_get_tiles (drawable),
- 0, 0, width, height, TRUE);
- pixel_region_init (&maskPR, mask,
- 0, 0, width, height, FALSE);
+ gimp_image_transform_color (image, layer_type, d,
+ GIMP_RGB, color);
+ d[layer_alpha_byte] = *alpha;
- apply_mask_to_region (&textPR, &maskPR, OPAQUE_OPACITY);
+ rgb += 4;
+ alpha += 1;
+ d += layerPR.bytes;
+ }
- tile_manager_unref (mask);
+ rgb_src += rgb_rowstride;
+ alpha_src += alpha_rowstride;
+ dest += layerPR.rowstride;
+ }
+ }
- /* no need to gimp_drawable_update() since gimp_drawable_fill()
- * did that for us.
- */
+ cairo_surface_destroy (rgb_surface);
+ cairo_surface_destroy (alpha_surface);
+
+ gimp_drawable_update (drawable, 0, 0, width, height);
}
diff --git a/app/text/gimptextlayout.c b/app/text/gimptextlayout.c
index c1968d1..f107098 100644
--- a/app/text/gimptextlayout.c
+++ b/app/text/gimptextlayout.c
@@ -49,6 +49,7 @@ struct _GimpTextLayout
static void gimp_text_layout_finalize (GObject *object);
static void gimp_text_layout_position (GimpTextLayout *layout);
+static void gimp_text_layout_set_attrs (GimpTextLayout *layout);
static PangoContext * gimp_text_get_pango_context (GimpText *text,
gdouble xres,
@@ -189,28 +190,8 @@ gimp_text_layout_new (GimpText *text,
gimp_text_layout_pixel_size (text->line_spacing,
text->unit,
yres));
- if (fabs (text->letter_spacing) > 0.1)
- {
- PangoAttrList *attrs;
- PangoAttribute *attr;
-
- attrs = pango_layout_get_attributes (layout->layout);
- if (attrs)
- pango_attr_list_ref (attrs);
- else
- attrs = pango_attr_list_new ();
-
- attr = pango_attr_letter_spacing_new (text->letter_spacing * PANGO_SCALE);
-
- attr->start_index = 0;
- attr->end_index = -1;
-
- pango_attr_list_insert (attrs, attr);
-
- pango_layout_set_attributes (layout->layout, attrs);
- pango_attr_list_unref (attrs);
- }
+ gimp_text_layout_set_attrs (layout);
gimp_text_layout_position (layout);
switch (text->box_mode)
@@ -477,6 +458,42 @@ gimp_text_layout_untransform_distance (GimpTextLayout *layout,
}
static void
+gimp_text_layout_set_attrs (GimpTextLayout *layout)
+{
+ GimpText *text = layout->text;
+ PangoAttrList *attrs;
+ PangoAttribute *attr;
+
+ attrs = pango_layout_get_attributes (layout->layout);
+ if (attrs)
+ pango_attr_list_ref (attrs);
+ else
+ attrs = pango_attr_list_new ();
+
+ attr = pango_attr_foreground_new (text->color.r * 65535,
+ text->color.g * 65535,
+ text->color.b * 65535);
+
+ attr->start_index = 0;
+ attr->end_index = -1;
+
+ pango_attr_list_insert (attrs, attr);
+
+ if (fabs (text->letter_spacing) > 0.1)
+ {
+ attr = pango_attr_letter_spacing_new (text->letter_spacing * PANGO_SCALE);
+
+ attr->start_index = 0;
+ attr->end_index = -1;
+
+ pango_attr_list_insert (attrs, attr);
+ }
+
+ pango_layout_set_attributes (layout->layout, attrs);
+ pango_attr_list_unref (attrs);
+}
+
+static void
gimp_text_layout_position (GimpTextLayout *layout)
{
PangoRectangle ink;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]