[gtk+/wip/matthiasc/gskpango] wip: Add a render node for text
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/matthiasc/gskpango] wip: Add a render node for text
- Date: Thu, 31 Aug 2017 18:35:50 +0000 (UTC)
commit 4b390a318677a1085f5511598882dfc465efb9b1
Author: Matthias Clasen <mclasen redhat com>
Date: Tue Aug 29 17:28:10 2017 -0400
wip: Add a render node for text
This is just a wrapper around a PangoGlyphString + PangoFont.
Basically, the arguments that are passed to pango_renderer_draw_glyphs.
gsk/gskenums.h | 4 +-
gsk/gskrendernode.h | 6 ++
gsk/gskrendernodeimpl.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 165 insertions(+), 2 deletions(-)
---
diff --git a/gsk/gskenums.h b/gsk/gskenums.h
index bc828b0..d52b458 100644
--- a/gsk/gskenums.h
+++ b/gsk/gskenums.h
@@ -45,6 +45,7 @@
* @GSK_SHADOW_NODE: A node that draws a shadow below its child
* @GSK_BLEND_NODE: A node the blends two children together
* @GSK_CROSS_FADE_NODE: A node the cross-fades between two children
+ * @GSK_TEXT_NODE: A node containing a glyph string
*
* The type of a node determines what the node is rendering.
*
@@ -69,7 +70,8 @@ typedef enum {
GSK_ROUNDED_CLIP_NODE,
GSK_SHADOW_NODE,
GSK_BLEND_NODE,
- GSK_CROSS_FADE_NODE
+ GSK_CROSS_FADE_NODE,
+ GSK_TEXT_NODE
} GskRenderNodeType;
/**
diff --git a/gsk/gskrendernode.h b/gsk/gskrendernode.h
index 0bbeed6..a550272 100644
--- a/gsk/gskrendernode.h
+++ b/gsk/gskrendernode.h
@@ -174,6 +174,12 @@ GskRenderNode * gsk_cross_fade_node_new (GskRenderNode
GskRenderNode *end,
double progress);
+GDK_AVAILABLE_IN_3_92
+GskRenderNode * gsk_text_node_new (PangoFont *font,
+ int x,
+ int y,
+ PangoGlyphString *glyphs);
+
GDK_AVAILABLE_IN_3_90
void gsk_render_node_set_scaling_filters (GskRenderNode *node,
GskScalingFilter min_filter,
diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c
index 214025b..16ac7a1 100644
--- a/gsk/gskrendernodeimpl.c
+++ b/gsk/gskrendernodeimpl.c
@@ -3801,6 +3801,160 @@ gsk_cross_fade_node_get_progress (GskRenderNode *node)
return self->progress;
}
+/*** GSK_TEXT_NODE ***/
+
+typedef struct _GskTextNode GskTextNode;
+
+struct _GskTextNode
+{
+ GskRenderNode render_node;
+
+ PangoFont *font;
+ PangoGlyphString *glyphs;
+ int x;
+ int y;
+};
+
+static void
+gsk_text_node_finalize (GskRenderNode *node)
+{
+ GskTextNode *self = (GskTextNode *) node;
+
+ g_object_unref (self->font);
+ pango_glyph_string_free (self->glyphs);
+}
+
+static void
+gsk_text_node_draw (GskRenderNode *node,
+ cairo_t *cr)
+{
+ GskTextNode *self = (GskTextNode *) node;
+ int i;
+ PangoFontDescription *desc;
+ char *s;
+
+ 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);
+
+ 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);
+ }
+ g_print ("\n");
+}
+
+#define GSK_TEXT_NODE_VARIANT_TYPE "(siia(uiiii))"
+
+static GVariant *
+gsk_text_node_serialize (GskRenderNode *node)
+{
+ GskTextNode *self = (GskTextNode *) node;
+ GVariant *v;
+ GVariantBuilder builder;
+ int i;
+ PangoFontDescription *desc;
+ char *s;
+
+ desc = pango_font_describe (self->font);
+ s = pango_font_description_to_string (desc);
+ for (i = 0; i < self->glyphs->num_glyphs; i++)
+ {
+ PangoGlyphInfo *glyph = &self->glyphs->glyphs[i];
+ g_variant_builder_add (&builder, "(uiiii)",
+ glyph->glyph,
+ glyph->geometry.width,
+ glyph->geometry.x_offset,
+ glyph->geometry.y_offset,
+ glyph->attr.is_cluster_start);
+ }
+
+ 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);
+
+ g_free (s);
+ pango_font_description_free (desc);
+
+ return v;
+}
+
+static GskRenderNode *
+gsk_text_node_deserialize (GVariant *variant,
+ GError **error)
+{
+ PangoFont *font;
+ int x, y;
+ PangoGlyphString *glyphs;
+ GVariantIter iter;
+ GskRenderNode *result;
+ PangoGlyphInfo glyph;
+ PangoFontDescription *desc;
+ int cluster_start;
+ char *s;
+ 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);
+
+ desc = pango_font_description_from_string (s);
+ font = NULL; /* FIXME: need a fontmap and context */
+
+ glyphs = pango_glyph_string_new ();
+ pango_glyph_string_set_size (glyphs, g_variant_iter_n_children (&iter));
+ i = 0;
+ while (g_variant_iter_next (&iter, "(uiiii)", &glyph.glyph, &glyph.geometry.width,
&glyph.geometry.x_offset, &glyph.geometry.y_offset, &cluster_start))
+ {
+ glyph.attr.is_cluster_start = cluster_start;
+ glyphs->glyphs[i] = glyph;
+ i++;
+ }
+
+ result = gsk_text_node_new (font, x, y, glyphs);
+
+ pango_glyph_string_free (glyphs);
+ pango_font_description_free (desc);
+
+ return result;
+}
+
+static const GskRenderNodeClass GSK_TEXT_NODE_CLASS = {
+ GSK_TEXT_NODE,
+ sizeof (GskTextNode),
+ "GskTextNode",
+ gsk_text_node_finalize,
+ gsk_text_node_draw,
+ gsk_text_node_serialize,
+ gsk_text_node_deserialize
+};
+
+GskRenderNode *
+gsk_text_node_new (PangoFont *font,
+ int x,
+ int y,
+ PangoGlyphString *glyphs)
+{
+ GskTextNode *self;
+
+ 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->glyphs = pango_glyph_string_copy (glyphs);
+
+ return &self->render_node;
+}
+
static const GskRenderNodeClass *klasses[] = {
[GSK_CONTAINER_NODE] = &GSK_CONTAINER_NODE_CLASS,
[GSK_CAIRO_NODE] = &GSK_CAIRO_NODE_CLASS,
@@ -3818,7 +3972,8 @@ static const GskRenderNodeClass *klasses[] = {
[GSK_ROUNDED_CLIP_NODE] = &GSK_ROUNDED_CLIP_NODE_CLASS,
[GSK_SHADOW_NODE] = &GSK_SHADOW_NODE_CLASS,
[GSK_BLEND_NODE] = &GSK_BLEND_NODE_CLASS,
- [GSK_CROSS_FADE_NODE] = &GSK_CROSS_FADE_NODE_CLASS
+ [GSK_CROSS_FADE_NODE] = &GSK_CROSS_FADE_NODE_CLASS,
+ [GSK_TEXT_NODE] = &GSK_TEXT_NODE_CLASS
};
GskRenderNode *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]