[gtk+/wip/matthiasc/gskpango] wip: Add a render node for text



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]