[gtk+/wip/matthiasc/gskpango] Use cairo types in the text node API



commit e7458812c555670e4e2947cd52cc3c77295a5baa
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Sep 1 00:47:59 2017 -0400

    Use cairo types in the text node API
    
    This makes the code a bit simpler, at the cost of having
    to figure out how to serialize a cairo_scaled_font_t.

 gsk/gskrendernode.h     |   15 ++++---
 gsk/gskrendernodeimpl.c |  108 +++++++++++++---------------------------------
 gtk/gskpango.c          |   69 ++++++++++++++++-------------
 3 files changed, 77 insertions(+), 115 deletions(-)
---
diff --git a/gsk/gskrendernode.h b/gsk/gskrendernode.h
index 4c94f8d..25adfdb 100644
--- a/gsk/gskrendernode.h
+++ b/gsk/gskrendernode.h
@@ -175,13 +175,14 @@ GskRenderNode *         gsk_cross_fade_node_new                 (GskRenderNode
                                                                  double                    progress);
 
 GDK_AVAILABLE_IN_3_92
-GskRenderNode *         gsk_text_node_new                       (PangoFont        *font,
-                                                                 PangoGlyphString *glyphs,
-                                                                 const GdkRGBA    *color,
-                                                                 int               x_offset,
-                                                                 int               y_offset,
-                                                                 double            base_x,
-                                                                 double            base_y);
+GskRenderNode *         gsk_text_node_new                       (cairo_scaled_font_t *font,
+                                                                 cairo_glyph_t       *glyphs,
+                                                                 int                  num_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 2d04bb3..eafa5b8 100644
--- a/gsk/gskrendernodeimpl.c
+++ b/gsk/gskrendernodeimpl.c
@@ -3809,8 +3809,9 @@ struct _GskTextNode
 {
   GskRenderNode render_node;
 
-  PangoFont *font;
-  PangoGlyphString *glyphs;
+  cairo_scaled_font_t *font;
+  cairo_glyph_t *glyphs;
+  int num_glyphs;
   GdkRGBA color;
   int x_offset;
   int y_offset;
@@ -3823,80 +3824,26 @@ gsk_text_node_finalize (GskRenderNode *node)
 {
   GskTextNode *self = (GskTextNode *) node;
 
-  g_object_unref (self->font);
-  pango_glyph_string_free (self->glyphs);
+  cairo_scaled_font_destroy (self->font);
+  g_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;
-}
-
-#ifndef STACK_BUFFER_SIZE
-#define STACK_BUFFER_SIZE (512 * sizeof (int))
-#endif
-
-#define STACK_ARRAY_LENGTH(T) (STACK_BUFFER_SIZE / sizeof(T))
-
 static void
 gsk_text_node_draw (GskRenderNode *node,
                     cairo_t       *cr)
 {
   GskTextNode *self = (GskTextNode *) node;
-  int i, count;
-  int x_position = 0;
-  cairo_glyph_t *cairo_glyphs;
-  cairo_glyph_t stack_glyphs[STACK_ARRAY_LENGTH (cairo_glyph_t)];
 
   cairo_save (cr);
 
+  cairo_set_scaled_font (cr, self->font);
+
   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;
 
-  if (self->glyphs->num_glyphs > (int) G_N_ELEMENTS (stack_glyphs))
-    cairo_glyphs = g_new (cairo_glyph_t, self->glyphs->num_glyphs);
-  else
-    cairo_glyphs = stack_glyphs;
-
-  count = 0;
-  for (i = 0; i < self->glyphs->num_glyphs; i++)
-    {
-      PangoGlyphInfo *gi = &self->glyphs->glyphs[i];
+  cairo_show_glyphs (cr, self->glyphs, self->num_glyphs);
 
-      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;
-    }
-
-  cairo_show_glyphs (cr, cairo_glyphs, count);
-
-  if (cairo_glyphs != stack_glyphs)
-    g_free (cairo_glyphs);
-
-done:
   cairo_restore (cr);
 }
 
@@ -3905,6 +3852,7 @@ done:
 static GVariant *
 gsk_text_node_serialize (GskRenderNode *node)
 {
+#if 0
   GskTextNode *self = (GskTextNode *) node;
   GVariant *v;
   GVariantBuilder builder;
@@ -3942,12 +3890,15 @@ gsk_text_node_serialize (GskRenderNode *node)
   pango_font_description_free (desc);
 
   return v;
+#endif
+  return NULL;
 }
 
 static GskRenderNode *
 gsk_text_node_deserialize (GVariant  *variant,
                            GError   **error)
 {
+#if 0
   PangoFont *font;
   PangoGlyphString *glyphs;
   GVariantIter iter;
@@ -3997,6 +3948,8 @@ gsk_text_node_deserialize (GVariant  *variant,
   g_object_unref (font);
 
   return result;
+#endif
+  return NULL;
 }
 
 static const GskRenderNodeClass GSK_TEXT_NODE_CLASS = {
@@ -4010,35 +3963,36 @@ static const GskRenderNodeClass GSK_TEXT_NODE_CLASS = {
 };
 
 GskRenderNode *
-gsk_text_node_new (PangoFont        *font,
-                   PangoGlyphString *glyphs,
-                   const GdkRGBA    *color,
-                   int               x_offset,
-                   int               y_offset,
-                   double            base_x,
-                   double            base_y)
+gsk_text_node_new (cairo_scaled_font_t *font,
+                   cairo_glyph_t       *glyphs,
+                   int                  num_glyphs,
+                   const GdkRGBA       *color,
+                   int                  x_offset,
+                   int                  y_offset,
+                   double               base_x,
+                   double               base_y)
 {
   GskTextNode *self;
-  PangoRectangle ink_rect;
+  cairo_text_extents_t extents;
 
   self = (GskTextNode *) gsk_render_node_new (&GSK_TEXT_NODE_CLASS, 0);
 
-  self->font = g_object_ref (font);
-  self->glyphs = pango_glyph_string_copy (glyphs);
+  self->font = cairo_scaled_font_reference (font);
+  self->glyphs = g_memdup (glyphs, sizeof (cairo_glyph_t) * num_glyphs);
+  self->num_glyphs = num_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);
+  cairo_scaled_font_glyph_extents (font, glyphs, num_glyphs, &extents);
 
   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);
+                      x_offset + base_x + extents.x_bearing,
+                      y_offset + base_y + extents.y_bearing,
+                      extents.width,
+                      extents.height);
 
   return &self->render_node;
 }
diff --git a/gtk/gskpango.c b/gtk/gskpango.c
index 83376e4..a24d923 100644
--- a/gtk/gskpango.c
+++ b/gtk/gskpango.c
@@ -122,6 +122,12 @@ gsk_pango_renderer_draw_unknown_glyph (GskPangoRenderer *crenderer,
   cairo_destroy (cr);
 }
 
+#ifndef STACK_BUFFER_SIZE
+#define STACK_BUFFER_SIZE (512 * sizeof (int))
+#endif
+
+#define STACK_ARRAY_LENGTH(T) (STACK_BUFFER_SIZE / sizeof(T))
+
 static void
 gsk_pango_renderer_show_text_glyphs (PangoRenderer        *renderer,
                                      const char           *text,
@@ -141,62 +147,63 @@ gsk_pango_renderer_show_text_glyphs (PangoRenderer        *renderer,
   cairo_scaled_font_t *scaled_font;
   gboolean font_failed = FALSE;
   int x_position;
-  int num_glyphs;
-  int i;
+  int i, count;
+  cairo_glyph_t *cairo_glyphs;
+  cairo_glyph_t stack_glyphs[STACK_ARRAY_LENGTH (cairo_glyph_t)];
+  GskRenderNode *node;
+  char name[64];
 
   gtk_snapshot_get_offset (crenderer->snapshot, &x_offset, &y_offset);
 
+  gtk_snapshot_offset (crenderer->snapshot, base_x, base_y);
+
   scaled_font = pango_cairo_font_get_scaled_font ((PangoCairoFont *)font);
   if (scaled_font == NULL || cairo_scaled_font_status (scaled_font) != CAIRO_STATUS_SUCCESS)
     font_failed = TRUE;
 
+  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;
+
+  count = 0;
   x_position = 0;
-  num_glyphs = 0;
   for (i = 0; i < glyphs->num_glyphs; i++)
     {
       PangoGlyphInfo *gi = &glyphs->glyphs[i];
 
-      if (gi->glyph != PANGO_GLYPH_EMPTY &&
-          (font_failed || gi->glyph & PANGO_GLYPH_UNKNOWN_FLAG))
+      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);
-
-          if (num_glyphs == 0)
-            base_x += (gi->geometry.x_offset + gi->geometry.width) / PANGO_SCALE;
+          if (font_failed || ((gi->glyph & PANGO_GLYPH_UNKNOWN_FLAG) != 0))
+            gsk_pango_renderer_draw_unknown_glyph (crenderer, font, gi, cx, cy);
           else
-            glyphs->glyphs[num_glyphs - 1].geometry.width += gi->geometry.x_offset + gi->geometry.width;
-        }
-      else
-        {
-          if (i != num_glyphs)
-            glyphs->glyphs[num_glyphs] = glyphs->glyphs[i];
-          num_glyphs++;
+            {
+              cairo_glyphs[count].index = gi->glyph;
+              cairo_glyphs[count].x = cx;
+              cairo_glyphs[count].y = cy;
+              count++;
+            }
         }
       x_position += gi->geometry.width;
     }
 
-  glyphs->num_glyphs = num_glyphs;
-
-  if (glyphs->num_glyphs > 0)
-    {
-      GskRenderNode *node;
-      char name[64];
-
-      gtk_snapshot_offset (crenderer->snapshot, base_x, base_y);
+  node = gsk_text_node_new (scaled_font, cairo_glyphs, count,
+                            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);
 
-      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);
+  gtk_snapshot_offset (crenderer->snapshot, -base_x, -base_y);
 
-      gtk_snapshot_offset (crenderer->snapshot, -base_x, -base_y);
-    }
+  if (cairo_glyphs != stack_glyphs)
+    g_free (cairo_glyphs);
 }
 
 static void


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