[gtk+/wip/matthiasc/gskpango: 2/2] Make the text node do the rendering
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/matthiasc/gskpango: 2/2] Make the text node do the rendering
- Date: Fri, 1 Sep 2017 01:38:22 +0000 (UTC)
commit eb598c9c3a22192a4bae375b9050a08f607287bf
Author: Matthias Clasen <mclasen redhat com>
Date: Thu Aug 31 14:34:52 2017 -0400
Make the text node do the rendering
For now, this is just the fallback implementation
using cairo.
gsk/gskrendernode.h | 9 ++-
gsk/gskrendernodeimpl.c | 129 ++++++++++++++++++++++++++++++++++++----------
gtk/gskpango.c | 87 +++++---------------------------
3 files changed, 120 insertions(+), 105 deletions(-)
---
diff --git a/gsk/gskrendernode.h b/gsk/gskrendernode.h
index a550272..4c94f8d 100644
--- a/gsk/gskrendernode.h
+++ b/gsk/gskrendernode.h
@@ -176,9 +176,12 @@ GskRenderNode * gsk_cross_fade_node_new (GskRenderNode
GDK_AVAILABLE_IN_3_92
GskRenderNode * gsk_text_node_new (PangoFont *font,
- int x,
- int y,
- PangoGlyphString *glyphs);
+ PangoGlyphString *glyphs,
+ const GdkRGBA *color,
+ int x_offset,
+ int y_offset,
+ double base_x,
+ double base_y);
GDK_AVAILABLE_IN_3_90
void gsk_render_node_set_scaling_filters (GskRenderNode *node,
diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c
index 16ac7a1..0eca7cc 100644
--- a/gsk/gskrendernodeimpl.c
+++ b/gsk/gskrendernodeimpl.c
@@ -3811,8 +3811,11 @@ struct _GskTextNode
PangoFont *font;
PangoGlyphString *glyphs;
- int x;
- int y;
+ GdkRGBA color;
+ int x_offset;
+ int y_offset;
+ double base_x;
+ double base_y;
};
static void
@@ -3824,35 +3827,71 @@ gsk_text_node_finalize (GskRenderNode *node)
pango_glyph_string_free (self->glyphs);
}
+static gboolean
+_pango_cairo_font_install (PangoFont *font,
+ cairo_t *cr)
+{
+ cairo_scaled_font_t *scaled_font = pango_cairo_font_get_scaled_font ((PangoCairoFont *)font);
+
+ if (G_UNLIKELY (scaled_font == NULL || cairo_scaled_font_status (scaled_font) != CAIRO_STATUS_SUCCESS))
+ return FALSE;
+
+ cairo_set_scaled_font (cr, scaled_font);
+
+ return TRUE;
+}
+
+
static void
gsk_text_node_draw (GskRenderNode *node,
cairo_t *cr)
{
GskTextNode *self = (GskTextNode *) node;
- int i;
+ int i, count;
+ int x_position = 0;
+ cairo_glyph_t *cairo_glyphs;
PangoFontDescription *desc;
- char *s;
+ char *s, *c;
- desc = pango_font_describe (self->font);
- s = pango_font_description_to_string (desc);
- g_print ("draw gyphs: font %s, x %d y %d\n", s, self->x, self->y);
- g_free (s);
- pango_font_description_free (desc);
+ cairo_save (cr);
+ cairo_translate (cr, self->x_offset, self->y_offset);
+
+ gdk_cairo_set_source_rgba (cr, &self->color);
+ if (!_pango_cairo_font_install (self->font, cr))
+ goto done;
+
+ cairo_glyphs = g_new (cairo_glyph_t, self->glyphs->num_glyphs);
+ count = 0;
for (i = 0; i < self->glyphs->num_glyphs; i++)
{
- PangoGlyphInfo *glyph = &self->glyphs->glyphs[i];
- g_print (" glyph %u width %d x %d y %d cs %d\n",
- glyph->glyph,
- glyph->geometry.width,
- glyph->geometry.x_offset,
- glyph->geometry.y_offset,
- glyph->attr.is_cluster_start);
+ PangoGlyphInfo *gi = &self->glyphs->glyphs[i];
+
+ if (gi->glyph != PANGO_GLYPH_EMPTY)
+ {
+ double cx = self->base_x + (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
+ double cy = gi->geometry.y_offset == 0 ? self->base_y : self->base_y +
(double)(gi->geometry.y_offset) / PANGO_SCALE;
+
+ if (!(gi->glyph & PANGO_GLYPH_UNKNOWN_FLAG))
+ {
+ cairo_glyphs[count].index = gi->glyph;
+ cairo_glyphs[count].x = cx;
+ cairo_glyphs[count].y = cy;
+ count++;
+ }
+ }
+ x_position += gi->geometry.width;
}
- g_print ("\n");
+
+ cairo_show_glyphs (cr, cairo_glyphs, count);
+
+ g_free (cairo_glyphs);
+
+done:
+ cairo_restore (cr);
}
-#define GSK_TEXT_NODE_VARIANT_TYPE "(siia(uiiii))"
+#define GSK_TEXT_NODE_VARIANT_TYPE "(sddddiidda(uiiii))"
static GVariant *
gsk_text_node_serialize (GskRenderNode *node)
@@ -3878,7 +3917,17 @@ gsk_text_node_serialize (GskRenderNode *node)
}
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(uiiii)"));
- v = g_variant_new (GSK_TEXT_NODE_VARIANT_TYPE, s, self->x, self->y, &builder);
+ v = g_variant_new (GSK_TEXT_NODE_VARIANT_TYPE,
+ s,
+ self->color.red,
+ self->color.green,
+ self->color.blue,
+ self->color.alpha,
+ self->x_offset,
+ self->y_offset,
+ self->base_x,
+ self->base_y,
+ &builder);
g_free (s);
pango_font_description_free (desc);
@@ -3891,7 +3940,6 @@ gsk_text_node_deserialize (GVariant *variant,
GError **error)
{
PangoFont *font;
- int x, y;
PangoGlyphString *glyphs;
GVariantIter iter;
GskRenderNode *result;
@@ -3899,12 +3947,19 @@ gsk_text_node_deserialize (GVariant *variant,
PangoFontDescription *desc;
int cluster_start;
char *s;
+ GdkRGBA color;
+ int x_offset, y_offset;
+ double base_x, base_y;
int i;
if (!check_variant_type (variant, GSK_TEXT_NODE_VARIANT_TYPE, error))
return NULL;
- g_variant_get (variant, "(&siia(uiiii))", &s, &x, &y, &iter);
+ g_variant_get (variant, "(&sddddiidda(uiiii))",
+ &color.red, &color.green, &color.blue, &color.alpha,
+ &x_offset, &y_offset,
+ &base_x, &base_y,
+ &s, &iter);
desc = pango_font_description_from_string (s);
font = NULL; /* FIXME: need a fontmap and context */
@@ -3919,7 +3974,9 @@ gsk_text_node_deserialize (GVariant *variant,
i++;
}
- result = gsk_text_node_new (font, x, y, glyphs);
+ result = gsk_text_node_new (font, glyphs, &color, /* FIXME: Avoid copying glyphs */
+ x_offset, y_offset,
+ base_x, base_y);
pango_glyph_string_free (glyphs);
pango_font_description_free (desc);
@@ -3939,18 +3996,34 @@ static const GskRenderNodeClass GSK_TEXT_NODE_CLASS = {
GskRenderNode *
gsk_text_node_new (PangoFont *font,
- int x,
- int y,
- PangoGlyphString *glyphs)
+ PangoGlyphString *glyphs,
+ const GdkRGBA *color,
+ int x_offset,
+ int y_offset,
+ double base_x,
+ double base_y)
{
GskTextNode *self;
+ PangoRectangle ink_rect;
self = (GskTextNode *) gsk_render_node_new (&GSK_TEXT_NODE_CLASS, 0);
- self->font = font ? g_object_ref (font) : NULL;
- self->x = x;
- self->y = y;
+ self->font = g_object_ref (font);
self->glyphs = pango_glyph_string_copy (glyphs);
+ self->color = *color;
+ self->x_offset = x_offset;
+ self->y_offset = y_offset;
+ self->base_x = base_x;
+ self->base_y = base_y;
+
+ pango_glyph_string_extents (glyphs, font, &ink_rect, NULL);
+ pango_extents_to_pixels (&ink_rect, NULL);
+
+ graphene_rect_init (&self->render_node.bounds,
+ x_offset + base_x + ink_rect.x,
+ y_offset + base_y + ink_rect.y,
+ ink_rect.width,
+ ink_rect.height);
return &self->render_node;
}
diff --git a/gtk/gskpango.c b/gtk/gskpango.c
index 1cff71e..278d58a 100644
--- a/gtk/gskpango.c
+++ b/gtk/gskpango.c
@@ -156,84 +156,23 @@ gsk_pango_renderer_show_text_glyphs (PangoRenderer *renderer,
int y)
{
GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
-
- cairo_t *cr;
- int i, count;
- int x_position = 0;
- cairo_glyph_t *cairo_glyphs;
- cairo_glyph_t stack_glyphs[STACK_ARRAY_LENGTH (cairo_glyph_t)];
double base_x = crenderer->x_offset + (double)x / PANGO_SCALE;
double base_y = crenderer->y_offset + (double)y / PANGO_SCALE;
+ char name[64];
+ GskRenderNode *node;
+ int x_offset, y_offset;
- cr = gtk_snapshot_append_cairo (crenderer->snapshot, &crenderer->bounds, "Text<%dglyphs>",
glyphs->num_glyphs);
-
- set_color (crenderer, PANGO_RENDER_PART_FOREGROUND, cr);
+ gtk_snapshot_get_offset (crenderer->snapshot, &x_offset, &y_offset);
+ gtk_snapshot_offset (crenderer->snapshot, base_x, base_y);
- if (!_pango_cairo_font_install (font, cr))
- {
- for (i = 0; i < glyphs->num_glyphs; i++)
- {
- PangoGlyphInfo *gi = &glyphs->glyphs[i];
-
- if (gi->glyph != PANGO_GLYPH_EMPTY)
- {
- double cx = base_x + (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
- double cy = gi->geometry.y_offset == 0 ?
- base_y :
- base_y + (double)(gi->geometry.y_offset) / PANGO_SCALE;
-
- gsk_pango_renderer_draw_unknown_glyph (crenderer, font, gi, cx, cy);
- }
- x_position += gi->geometry.width;
- }
-
- goto done;
- }
-
- if (glyphs->num_glyphs > (int) G_N_ELEMENTS (stack_glyphs))
- cairo_glyphs = g_new (cairo_glyph_t, glyphs->num_glyphs);
- else
- cairo_glyphs = stack_glyphs;
+ /* FIXME: need to filter out unknown glyphs */
+ node = gsk_text_node_new (font, glyphs, crenderer->fg_color, x_offset, y_offset, base_x, base_y);
+ snprintf (name, sizeof (name), "Glyphs<%d>", glyphs->num_glyphs);
+ gsk_render_node_set_name (node, name);
+ gtk_snapshot_append_node (crenderer->snapshot, node);
+ gsk_render_node_unref (node);
- count = 0;
- for (i = 0; i < glyphs->num_glyphs; i++)
- {
- PangoGlyphInfo *gi = &glyphs->glyphs[i];
-
- if (gi->glyph != PANGO_GLYPH_EMPTY)
- {
- double cx = base_x + (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
- double cy = gi->geometry.y_offset == 0 ?
- base_y :
- base_y + (double)(gi->geometry.y_offset) / PANGO_SCALE;
-
- if (gi->glyph & PANGO_GLYPH_UNKNOWN_FLAG)
- gsk_pango_renderer_draw_unknown_glyph (crenderer, font, gi, cx, cy);
- else
- {
- cairo_glyphs[count].index = gi->glyph;
- cairo_glyphs[count].x = cx;
- cairo_glyphs[count].y = cy;
- count++;
- }
- }
- x_position += gi->geometry.width;
- }
-
- if (G_UNLIKELY (clusters))
- cairo_show_text_glyphs (cr,
- text, text_len,
- cairo_glyphs, count,
- clusters, num_clusters,
- backward ? CAIRO_TEXT_CLUSTER_FLAG_BACKWARD : 0);
- else
- cairo_show_glyphs (cr, cairo_glyphs, count);
-
- if (cairo_glyphs != stack_glyphs)
- g_free (cairo_glyphs);
-
-done:
- cairo_destroy (cr);
+ gtk_snapshot_offset (crenderer->snapshot, -base_x, -base_y);
}
static void
@@ -577,7 +516,7 @@ release_renderer (GskPangoRenderer *renderer)
g_object_unref (renderer);
}
-/* convenience wrappers using the default renderer */
+/* convenience wrappers using the default rcenderer */
void
gsk_pango_show_layout (GtkSnapshot *snapshot,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]