[gtk+/wip/matthiasc/gskpango: 1/4] Move node creation into the renderer



commit 2f0518674eea342abc277a033d01e149e2f88a98
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Aug 30 13:52:40 2017 -0400

    Move node creation into the renderer
    
    Create a cairo node for each show_text_glyphs call.

 gtk/gskpango.c    |  575 ++++++++++++-----------------------------------------
 gtk/gskpango.h    |    8 +-
 gtk/gtksnapshot.c |   39 ++--
 3 files changed, 157 insertions(+), 465 deletions(-)
---
diff --git a/gtk/gskpango.c b/gtk/gskpango.c
index 643af01..f63179f 100644
--- a/gtk/gskpango.c
+++ b/gtk/gskpango.c
@@ -19,6 +19,7 @@
 
 #include "config.h"
 
+#include "gsk/gsk.h"
 #include "gskpango.h"
 
 #include <math.h>
@@ -26,21 +27,6 @@
 #include <pango/pango.h>
 #include <cairo/cairo.h>
 
-typedef struct _PangoCairoFontHexBoxInfo             PangoCairoFontHexBoxInfo;
-
-struct _PangoCairoFontHexBoxInfo
-{
-  PangoCairoFont *font;
-  int rows;
-  double digit_width;
-  double digit_height;
-  double pad_x;
-  double pad_y;
-  double line_width;
-  double box_descent;
-  double box_height;
-};
-
 #define GSK_PANGO_RENDERER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_PANGO_RENDERER, 
GskPangoRendererClass))
 #define GSK_IS_PANGO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_PANGO_RENDERER))
 #define GSK_PANGO_RENDERER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_PANGO_RENDERER, 
GskPangoRendererClass))
@@ -49,14 +35,13 @@ struct _GskPangoRenderer
 {
   PangoRenderer parent_instance;
 
-  cairo_t *cr;
-  gboolean do_path;
-  gboolean has_show_text_glyphs;
+  GtkSnapshot *snapshot;
+  const GdkRGBA *fg_color;
   double x_offset, y_offset;
+  graphene_rect_t bounds;
 
   /* house-keeping options */
   gboolean is_cached_renderer;
-  gboolean cr_had_current_point;
 };
 
 struct _GskPangoRendererClass
@@ -66,16 +51,17 @@ struct _GskPangoRendererClass
 
 G_DEFINE_TYPE (GskPangoRenderer, gsk_pango_renderer, PANGO_TYPE_RENDERER)
 
-static void
-set_color (GskPangoRenderer *crenderer,
-           PangoRenderPart     part)
+static gboolean
+get_color (GskPangoRenderer *crenderer,
+           PangoRenderPart   part,
+           GdkRGBA          *rgba)
 {
   PangoColor *color = pango_renderer_get_color ((PangoRenderer *) (crenderer), part);
   guint16 a = pango_renderer_get_alpha ((PangoRenderer *) (crenderer), part);
   gdouble red, green, blue, alpha;
 
   if (!a && !color)
-    return;
+    return FALSE;
 
   if (color)
     {
@@ -85,158 +71,31 @@ set_color (GskPangoRenderer *crenderer,
       alpha = 1.;
     }
   else
-    {
-      cairo_pattern_t *pattern = cairo_get_source (crenderer->cr);
-
-      if (pattern && cairo_pattern_get_type (pattern) == CAIRO_PATTERN_TYPE_SOLID)
-        cairo_pattern_get_rgba (pattern, &red, &green, &blue, &alpha);
-      else
-        {
-          red = 0.;
-          green = 0.;
-          blue = 0.;
-          alpha = 1.;
-        }
-    }
+    return FALSE;
 
   if (a)
     alpha = a / 65535.;
 
-  cairo_set_source_rgba (crenderer->cr, red, green, blue, alpha);
-}
-
-#if 0
-/* note: modifies crenderer->cr without doing cairo_save/restore() */
-static void
-gsk_pango_renderer_draw_frame (GskPangoRenderer *crenderer,
-                               double              x,
-                               double              y,
-                               double              width,
-                               double              height,
-                               double              line_width,
-                               gboolean            invalid)
-{
-  cairo_t *cr = crenderer->cr;
-
-  if (crenderer->do_path)
-    {
-      double d2 = line_width * .5, d = line_width;
-
-      /* we draw an outer box in one winding direction and an inner one in the
-       * opposite direction.  This works for both cairo windings rules.
-       *
-       * what we really want is cairo_stroke_to_path(), but that's not
-       * implemented in cairo yet.
-       */
-
-      /* outer */
-      cairo_rectangle (cr, x-d2, y-d2, width+d, height+d);
+  rgba->red = red;
+  rgba->green = green;
+  rgba->blue = blue;
+  rgba->alpha = alpha;
 
-      /* inner */
-      if (invalid)
-        {
-          /* delicacies of computing the joint... this is REALLY slow */
-
-          double alpha, tan_alpha2, cos_alpha;
-          double sx, sy;
-
-          alpha = atan2 (height, width);
-
-          tan_alpha2 = tan (alpha * .5);
-          if (tan_alpha2 < 1e-5 || (sx = d2 / tan_alpha2, 2. * sx > width - d))
-            sx = (width - d) * .5;
-
-          cos_alpha = cos (alpha);
-          if (cos_alpha < 1e-5 || (sy = d2 / cos_alpha, 2. * sy > height - d))
-            sy = (height - d) * .5;
-
-          /* top triangle */
-          cairo_new_sub_path (cr);
-          cairo_line_to (cr, x+width-sx, y+d2);
-          cairo_line_to (cr, x+sx, y+d2);
-          cairo_line_to (cr, x+.5*width, y+.5*height-sy);
-          cairo_close_path (cr);
-
-          /* bottom triangle */
-          cairo_new_sub_path (cr);
-          cairo_line_to (cr, x+width-sx, y+height-d2);
-          cairo_line_to (cr, x+.5*width, y+.5*height+sy);
-          cairo_line_to (cr, x+sx, y+height-d2);
-          cairo_close_path (cr);
-
-
-          alpha = G_PI_2 - alpha;
-          tan_alpha2 = tan (alpha * .5);
-          if (tan_alpha2 < 1e-5 || (sy = d2 / tan_alpha2, 2. * sy > height - d))
-            sy = (height - d) * .5;
-
-          cos_alpha = cos (alpha);
-          if (cos_alpha < 1e-5 || (sx = d2 / cos_alpha, 2. * sx > width - d))
-            sx = (width - d) * .5;
-
-          /* left triangle */
-          cairo_new_sub_path (cr);
-          cairo_line_to (cr, x+d2, y+sy);
-          cairo_line_to (cr, x+d2, y+height-sy);
-          cairo_line_to (cr, x+.5*width-sx, y+.5*height);
-          cairo_close_path (cr);
-
-          /* right triangle */
-          cairo_new_sub_path (cr);
-          cairo_line_to (cr, x+width-d2, y+sy);
-          cairo_line_to (cr, x+.5*width+sx, y+.5*height);
-          cairo_line_to (cr, x+width-d2, y+height-sy);
-          cairo_close_path (cr);
-        }
-      else
-        cairo_rectangle (cr, x+width-d2, y+d2, - (width-d), height-d);
-    }
-  else
-    {
-      cairo_rectangle (cr, x, y, width, height);
-
-      if (invalid)
-        {
-          /* draw an X */
-
-          cairo_new_sub_path (cr);
-          cairo_move_to (cr, x, y);
-          cairo_rel_line_to (cr, width, height);
-
-          cairo_new_sub_path (cr);
-          cairo_move_to (cr, x + width, y);
-          cairo_rel_line_to (cr, -width, height);
-
-          cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
-        }
-
-      cairo_set_line_width (cr, line_width);
-      cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
-      cairo_set_miter_limit (cr, 2.);
-      cairo_stroke (cr);
-    }
+  return TRUE;
 }
 
 static void
-gsk_pango_renderer_draw_box_glyph (GskPangoRenderer *crenderer,
-                                   PangoGlyphInfo     *gi,
-                                   double              cx,
-                                   double              cy,
-                                   gboolean            invalid)
+set_color (GskPangoRenderer *crenderer,
+           PangoRenderPart   part,
+           cairo_t          *cr)
 {
-  cairo_save (crenderer->cr);
-
-  gsk_pango_renderer_draw_frame (crenderer,
-                                    cx + 1.5,
-                                    cy + 1.5 - PANGO_UNKNOWN_GLYPH_HEIGHT,
-                                    (double)gi->geometry.width / PANGO_SCALE - 3.0,
-                                    PANGO_UNKNOWN_GLYPH_HEIGHT - 3.0,
-                                    1.0,
-                                    invalid);
+  GdkRGBA rgba = { 0, 0, 0, 1 };
 
-  cairo_restore (crenderer->cr);
+  if (get_color (crenderer, part, &rgba))
+    gdk_cairo_set_source_rgba (cr, &rgba);
+  else
+    gdk_cairo_set_source_rgba (cr, crenderer->fg_color);
 }
-#endif
 
 static gboolean
 _pango_cairo_font_install (PangoFont *font,
@@ -254,84 +113,27 @@ _pango_cairo_font_install (PangoFont *font,
 
 static void
 gsk_pango_renderer_draw_unknown_glyph (GskPangoRenderer *crenderer,
-                                       PangoFont          *font,
-                                       PangoGlyphInfo     *gi,
-                                       double              cx,
-                                       double              cy)
+                                       PangoFont        *font,
+                                       PangoGlyphInfo   *gi,
+                                       double            cx,
+                                       double            cy)
 {
-#if 0
-  char buf[7];
-  double x0, y0;
-  int row, col;
-  int rows, cols;
-  double width, lsb;
-  char hexbox_string[2] = {0, 0};
-  PangoCairoFontHexBoxInfo *hbi;
-  gunichar ch;
-  gboolean invalid_input;
-
-  cairo_save (crenderer->cr);
-
-  ch = gi->glyph & ~PANGO_GLYPH_UNKNOWN_FLAG;
-  invalid_input = G_UNLIKELY (gi->glyph == PANGO_GLYPH_INVALID_INPUT || ch > 0x10FFFF);
-
-  hbi = pango_cairo_font_get_hex_box_info ((PangoCairoFont *)font);
-  if (!hbi || !_pango_cairo_font_install ((PangoFont *)(hbi->font), crenderer->cr))
-    {
-      gsk_pango_renderer_draw_box_glyph (crenderer, gi, cx, cy, invalid_input);
-      goto done;
-    }
-
-  rows = hbi->rows;
-  if (G_UNLIKELY (invalid_input))
-    {
-      cols = 1;
-    }
-  else
-    {
-      cols = (ch > 0xffff ? 6 : 4) / rows;
-      g_snprintf (buf, sizeof(buf), (ch > 0xffff) ? "%06X" : "%04X", ch);
-    }
+  cairo_t *cr;
+  PangoGlyphString *glyphs;
 
-  width = (3 * hbi->pad_x + cols * (hbi->digit_width + hbi->pad_x));
-  lsb = ((double)gi->geometry.width / PANGO_SCALE - width) * .5;
-  lsb = floor (lsb / hbi->pad_x) * hbi->pad_x;
+  cr = gtk_snapshot_append_cairo (crenderer->snapshot, &crenderer->bounds, "DrawUnknownGlyph<%u>", 
gi->glyph);
 
-  gsk_pango_renderer_draw_frame (crenderer,
-                                 cx + lsb + .5 * hbi->pad_x,
-                                 cy + hbi->box_descent - hbi->box_height + hbi->pad_y * 0.5,
-                                 width - hbi->pad_x,
-                                 (hbi->box_height - hbi->pad_y),
-                                 hbi->line_width,
-                                 invalid_input);
+  gdk_cairo_set_source_rgba (cr, crenderer->fg_color);
 
-  if (invalid_input)
-    goto done;
+  cairo_move_to (cr, cx, cy);
 
-  x0 = cx + lsb + hbi->pad_x * 2;
-  y0 = cy + hbi->box_descent - hbi->pad_y * 2;
+  glyphs = pango_glyph_string_new ();
+  pango_glyph_string_set_size (glyphs, 1);
+  glyphs->glyphs[0] = *gi;
 
-  for (row = 0; row < rows; row++)
-    {
-      double y = y0 - (rows - 1 - row) * (hbi->digit_height + hbi->pad_y);
-      for (col = 0; col < cols; col++)
-        {
-          double x = x0 + col * (hbi->digit_width + hbi->pad_x);
+  pango_cairo_show_glyph_string (cr, font, glyphs);
 
-          cairo_move_to (crenderer->cr, x, y);
-
-          hexbox_string[0] = buf[row * cols + col];
-
-          if (crenderer->do_path)
-              cairo_text_path (crenderer->cr, hexbox_string);
-          else
-              cairo_show_text (crenderer->cr, hexbox_string);
-        }
-    }
-
-done:
-  cairo_restore (crenderer->cr);
-#endif
+  cairo_destroy (cr);
 }
 
 #ifndef STACK_BUFFER_SIZE
@@ -354,6 +156,7 @@ gsk_pango_renderer_show_text_glyphs (PangoRenderer        *renderer,
 {
   GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
 
+  cairo_t *cr;
   int i, count;
   int x_position = 0;
   cairo_glyph_t *cairo_glyphs;
@@ -361,11 +164,11 @@ gsk_pango_renderer_show_text_glyphs (PangoRenderer        *renderer,
   double base_x = crenderer->x_offset + (double)x / PANGO_SCALE;
   double base_y = crenderer->y_offset + (double)y / PANGO_SCALE;
 
-  cairo_save (crenderer->cr);
-  if (!crenderer->do_path)
-    set_color (crenderer, PANGO_RENDER_PART_FOREGROUND);
+  cr = gtk_snapshot_append_cairo (crenderer->snapshot, &crenderer->bounds, "Text<%dglyphs>", 
glyphs->num_glyphs);
+
+  set_color (crenderer, PANGO_RENDER_PART_FOREGROUND, cr);
 
-  if (!_pango_cairo_font_install (font, crenderer->cr))
+  if (!_pango_cairo_font_install (font, cr))
     {
       for (i = 0; i < glyphs->num_glyphs; i++)
         {
@@ -416,39 +219,30 @@ gsk_pango_renderer_show_text_glyphs (PangoRenderer        *renderer,
       x_position += gi->geometry.width;
     }
 
-  if (G_UNLIKELY (crenderer->do_path))
-    cairo_glyph_path (crenderer->cr, cairo_glyphs, count);
+  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
-    if (G_UNLIKELY (clusters))
-      cairo_show_text_glyphs (crenderer->cr,
-                              text, text_len,
-                              cairo_glyphs, count,
-                              clusters, num_clusters,
-                              backward ? CAIRO_TEXT_CLUSTER_FLAG_BACKWARD : 0);
-    else
-      cairo_show_glyphs (crenderer->cr, cairo_glyphs, count);
+    cairo_show_glyphs (cr, cairo_glyphs, count);
 
   if (cairo_glyphs != stack_glyphs)
     g_free (cairo_glyphs);
 
 done:
-  cairo_restore (crenderer->cr);
+  cairo_destroy (cr);
 }
 
 static void
-gsk_pango_renderer_draw_glyphs (PangoRenderer     *renderer,
-                                PangoFont         *font,
-                                PangoGlyphString  *glyphs,
-                                int                x,
-                                int                y)
+gsk_pango_renderer_draw_glyphs (PangoRenderer    *renderer,
+                                PangoFont        *font,
+                                PangoGlyphString *glyphs,
+                                int               x,
+                                int               y)
 {
-  gsk_pango_renderer_show_text_glyphs (renderer,
-                                       NULL, 0,
-                                       glyphs,
-                                       NULL, 0,
-                                       FALSE,
-                                       font,
-                                       x, y);
+  gsk_pango_renderer_show_text_glyphs (renderer, NULL, 0, glyphs, NULL, 0, FALSE, font, x, y);
 }
 
 static void
@@ -458,128 +252,52 @@ gsk_pango_renderer_draw_glyph_item (PangoRenderer  *renderer,
                                     int             x,
                                     int             y)
 {
-  GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
-  PangoFont          *font      = glyph_item->item->analysis.font;
-  PangoGlyphString   *glyphs    = glyph_item->glyphs;
-  PangoItem          *item      = glyph_item->item;
-  gboolean            backward  = (item->analysis.level & 1) != 0;
-
-  PangoGlyphItemIter   iter;
-  cairo_text_cluster_t *cairo_clusters;
-  cairo_text_cluster_t stack_clusters[STACK_ARRAY_LENGTH (cairo_text_cluster_t)];
-  int num_clusters;
-
-  if (!crenderer->has_show_text_glyphs || crenderer->do_path)
-    {
-      gsk_pango_renderer_show_text_glyphs (renderer,
-                                           NULL, 0,
-                                           glyphs,
-                                           NULL, 0,
-                                           FALSE,
-                                           font,
-                                           x, y);
-      return;
-    }
-
-  if (glyphs->num_glyphs > (int) G_N_ELEMENTS (stack_clusters))
-    cairo_clusters = g_new (cairo_text_cluster_t, glyphs->num_glyphs);
-  else
-    cairo_clusters = stack_clusters;
+  PangoFont *font = glyph_item->item->analysis.font;
+  PangoGlyphString *glyphs = glyph_item->glyphs;
 
-  num_clusters = 0;
-  if (pango_glyph_item_iter_init_start (&iter, glyph_item, text))
-    {
-      do {
-        int num_bytes, num_glyphs, i;
-
-        num_bytes  = iter.end_index - iter.start_index;
-        num_glyphs = backward ? iter.start_glyph - iter.end_glyph : iter.end_glyph - iter.start_glyph;
-
-        if (num_bytes < 1)
-          g_warning ("gsk_pango_renderer_draw_glyph_item: bad cluster has num_bytes %d", num_bytes);
-        if (num_glyphs < 1)
-          g_warning ("gsk_pango_renderer_draw_glyph_item: bad cluster has num_glyphs %d", num_glyphs);
-
-        /* Discount empty and unknown glyphs */
-        for (i = MIN (iter.start_glyph, iter.end_glyph+1);
-             i < MAX (iter.start_glyph+1, iter.end_glyph);
-             i++)
-          {
-            PangoGlyphInfo *gi = &glyphs->glyphs[i];
-
-            if (gi->glyph == PANGO_GLYPH_EMPTY ||
-                gi->glyph & PANGO_GLYPH_UNKNOWN_FLAG)
-              num_glyphs--;
-          }
-
-        cairo_clusters[num_clusters].num_bytes  = num_bytes;
-        cairo_clusters[num_clusters].num_glyphs = num_glyphs;
-        num_clusters++;
-      } while (pango_glyph_item_iter_next_cluster (&iter));
-    }
-
-  gsk_pango_renderer_show_text_glyphs (renderer,
-                                         text + item->offset, item->length,
-                                         glyphs,
-                                         cairo_clusters, num_clusters,
-                                         backward,
-                                         font,
-                                         x, y);
-
-  if (cairo_clusters != stack_clusters)
-    g_free (cairo_clusters);
+  gsk_pango_renderer_show_text_glyphs (renderer, NULL, 0, glyphs, NULL, 0, FALSE, font, x, y);
 }
 
 static void
 gsk_pango_renderer_draw_rectangle (PangoRenderer     *renderer,
-                                     PangoRenderPart    part,
-                                     int                x,
-                                     int                y,
-                                     int                width,
-                                     int                height)
+                                   PangoRenderPart    part,
+                                   int                x,
+                                   int                y,
+                                   int                width,
+                                   int                height)
 {
   GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
+  GdkRGBA rgba;
+  graphene_rect_t bounds;
 
-  if (!crenderer->do_path)
-    {
-      cairo_save (crenderer->cr);
-
-      set_color (crenderer, part);
-    }
-
-  cairo_rectangle (crenderer->cr,
-                   crenderer->x_offset + (double)x / PANGO_SCALE,
-                   crenderer->y_offset + (double)y / PANGO_SCALE,
-                   (double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
+  if (!get_color (crenderer, part, &rgba))
+    rgba = *crenderer->fg_color;
 
-  if (!crenderer->do_path)
-    {
-      cairo_fill (crenderer->cr);
+  graphene_rect_init (&bounds,
+                      crenderer->x_offset + (double)x / PANGO_SCALE,
+                      crenderer->y_offset + (double)y / PANGO_SCALE,
+                      (double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
 
-      cairo_restore (crenderer->cr);
-    }
+  gtk_snapshot_append_color (crenderer->snapshot, &rgba, &bounds, "DrawRectangle");
 }
 
 static void
-gsk_pango_renderer_draw_trapezoid (PangoRenderer     *renderer,
-                                     PangoRenderPart    part,
-                                     double             y1_,
-                                     double             x11,
-                                     double             x21,
-                                     double             y2,
-                                     double             x12,
-                                     double             x22)
+gsk_pango_renderer_draw_trapezoid (PangoRenderer   *renderer,
+                                   PangoRenderPart  part,
+                                   double           y1_,
+                                   double           x11,
+                                   double           x21,
+                                   double           y2,
+                                   double           x12,
+                                   double           x22)
 {
   GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
   cairo_t *cr;
-  double x, y;
-
-  cr = crenderer->cr;
+  gdouble x, y;
 
-  cairo_save (cr);
+  cr = gtk_snapshot_append_cairo (crenderer->snapshot, &crenderer->bounds, "DrawTrapezoid");
 
-  if (!crenderer->do_path)
-    set_color (crenderer, part);
+  set_color (crenderer, part, cr);
 
   x = crenderer->x_offset,
   y = crenderer->y_offset;
@@ -593,10 +311,9 @@ gsk_pango_renderer_draw_trapezoid (PangoRenderer     *renderer,
   cairo_line_to (cr, x12, y2);
   cairo_close_path (cr);
 
-  if (!crenderer->do_path)
-    cairo_fill (cr);
+  cairo_fill (cr);
 
-  cairo_restore (cr);
+  cairo_destroy (cr);
 }
 
 /* Draws an error underline that looks like one of:
@@ -674,56 +391,54 @@ draw_error_underline (cairo_t *cr,
 
 static void
 gsk_pango_renderer_draw_error_underline (PangoRenderer *renderer,
-                                           int            x,
-                                           int            y,
-                                           int            width,
-                                           int            height)
+                                         int            x,
+                                         int            y,
+                                         int            width,
+                                         int            height)
 {
   GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
-  cairo_t *cr = crenderer->cr;
+  cairo_t *cr;
+  GdkRGBA rgba = { 0, 0, 0, 1 };
 
-  if (!crenderer->do_path)
-    {
-      cairo_save (cr);
+  cr = gtk_snapshot_append_cairo (crenderer->snapshot, &crenderer->bounds, "DrawTrapezoid");
 
-      set_color (crenderer, PANGO_RENDER_PART_UNDERLINE);
+  if (get_color (crenderer, PANGO_RENDER_PART_UNDERLINE, &rgba))
+    gdk_cairo_set_source_rgba (cr, &rgba);
+  else
+    gdk_cairo_set_source_rgba (cr, crenderer->fg_color);
 
-      cairo_new_path (cr);
-    }
+  cairo_new_path (cr);
 
   draw_error_underline (cr,
                         crenderer->x_offset + (double)x / PANGO_SCALE,
                         crenderer->y_offset + (double)y / PANGO_SCALE,
                         (double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
 
-  if (!crenderer->do_path)
-    {
-      cairo_fill (cr);
+  cairo_fill (cr);
 
-      cairo_restore (cr);
-    }
+  cairo_destroy (cr);
 }
 
 static void
 gsk_pango_renderer_draw_shape (PangoRenderer  *renderer,
-                                 PangoAttrShape *attr,
-                                 int             x,
-                                 int             y)
+                               PangoAttrShape *attr,
+                               int             x,
+                               int             y)
 {
-#if 0
   GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
-  cairo_t *cr = crenderer->cr;
+  cairo_t *cr;
   PangoLayout *layout;
-  GskPangoShapeRendererFunc shape_renderer;
-  gpointer                    shape_renderer_data;
+  PangoCairoShapeRendererFunc shape_renderer;
+  gpointer shape_renderer_data;
   double base_x, base_y;
 
-  layout = pango_renderer_get_layout (renderer);
+  cr = gtk_snapshot_append_cairo (crenderer->snapshot, &crenderer->bounds, "DrawShape");
 
+  layout = pango_renderer_get_layout (renderer);
   if (!layout)
-        return;
+    return;
 
-  shape_renderer = gsk_pango_context_get_shape_renderer (pango_layout_get_context (layout),
+  shape_renderer = pango_cairo_context_get_shape_renderer (pango_layout_get_context (layout),
                                                            &shape_renderer_data);
 
   if (!shape_renderer)
@@ -732,16 +447,13 @@ gsk_pango_renderer_draw_shape (PangoRenderer  *renderer,
   base_x = crenderer->x_offset + (double)x / PANGO_SCALE;
   base_y = crenderer->y_offset + (double)y / PANGO_SCALE;
 
-  cairo_save (cr);
-  if (!crenderer->do_path)
-    set_color (crenderer, PANGO_RENDER_PART_FOREGROUND);
+  set_color (crenderer, PANGO_RENDER_PART_FOREGROUND, cr);
 
   cairo_move_to (cr, base_x, base_y);
 
-  shape_renderer (cr, attr, crenderer->do_path, shape_renderer_data);
+  shape_renderer (cr, attr, FALSE, shape_renderer_data);
 
-  cairo_restore (cr);
-#endif
+  cairo_destroy (cr);
 }
 
 static void
@@ -793,9 +505,7 @@ release_renderer (GskPangoRenderer *renderer)
 {
   if (G_LIKELY (renderer->is_cached_renderer))
     {
-      renderer->cr = NULL;
-      renderer->do_path = FALSE;
-      renderer->has_show_text_glyphs = FALSE;
+      renderer->snapshot = NULL;
       renderer->x_offset = 0.;
       renderer->y_offset = 0.;
 
@@ -805,54 +515,29 @@ release_renderer (GskPangoRenderer *renderer)
     g_object_unref (renderer);
 }
 
-static void
-save_current_point (GskPangoRenderer *renderer)
-{
-  renderer->cr_had_current_point = cairo_has_current_point (renderer->cr);
-  cairo_get_current_point (renderer->cr, &renderer->x_offset, &renderer->y_offset);
-
-  /* abuse save_current_point() to cache cairo_has_show_text_glyphs() result */
-  renderer->has_show_text_glyphs = cairo_surface_has_show_text_glyphs (cairo_get_target (renderer->cr));
-}
-
-static void
-restore_current_point (GskPangoRenderer *renderer)
-{
-  if (renderer->cr_had_current_point)
-    /* XXX should do cairo_set_current_point() when we have that function */
-    cairo_move_to (renderer->cr, renderer->x_offset, renderer->y_offset);
-  else
-    cairo_new_sub_path (renderer->cr);
-}
-
-
 /* convenience wrappers using the default renderer */
 
-static void
-gsk_pango_do_layout (cairo_t     *cr,
-                     PangoLayout *layout,
-                     gboolean     do_path)
+void
+gsk_pango_show_layout (GtkSnapshot   *snapshot,
+                       const GdkRGBA *fg_color,
+                       PangoLayout   *layout)
 {
-  GskPangoRenderer *crenderer = acquire_renderer ();
-  PangoRenderer *renderer = (PangoRenderer *) crenderer;
+  GskPangoRenderer *crenderer;
+  PangoRectangle ink_rect;
 
-  crenderer->cr = cr;
-  crenderer->do_path = do_path;
-  save_current_point (crenderer);
+  g_return_if_fail (snapshot != NULL);
+  g_return_if_fail (PANGO_IS_LAYOUT (layout));
 
-  pango_renderer_draw_layout (renderer, layout, 0, 0);
+  crenderer = acquire_renderer ();
 
-  restore_current_point (crenderer);
+  crenderer->snapshot = snapshot;
+  crenderer->fg_color = fg_color;
+  crenderer->x_offset = crenderer->y_offset = 0;
 
-  release_renderer (crenderer);
-}
+  pango_layout_get_pixel_extents (layout, &ink_rect, NULL);
+  graphene_rect_init (&crenderer->bounds, ink_rect.x, ink_rect.y, ink_rect.width, ink_rect.height);
 
-void
-gsk_pango_show_layout (cairo_t     *cr,
-                       PangoLayout *layout)
-{
-  g_return_if_fail (cr != NULL);
-  g_return_if_fail (PANGO_IS_LAYOUT (layout));
+  pango_renderer_draw_layout (PANGO_RENDERER (crenderer), layout, 0, 0);
 
-  gsk_pango_do_layout (cr, layout, FALSE);
+  release_renderer (crenderer);
 }
diff --git a/gtk/gskpango.h b/gtk/gskpango.h
index 75a54d8..f8703d2 100644
--- a/gtk/gskpango.h
+++ b/gtk/gskpango.h
@@ -19,7 +19,8 @@
 #ifndef __GSK_PANGO_H__
 #define __GSK_PANGO_H__
 
-#include <gsk/gsk.h>
+#include <pango/pango.h>
+#include "gtk/gtksnapshot.h"
 
 G_BEGIN_DECLS
 
@@ -35,8 +36,9 @@ GDK_AVAILABLE_IN_3_92
 GType gsk_pango_renderer_get_type (void) G_GNUC_CONST;
 
 GDK_AVAILABLE_IN_3_92
-void gsk_pango_show_layout (cairo_t     *cr,
-                            PangoLayout *layout);
+void gsk_pango_show_layout (GtkSnapshot   *snapshot,
+                            const GdkRGBA *fg_color,
+                            PangoLayout   *layout);
 
 G_END_DECLS
 
diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c
index d46c0a0..11e594e 100644
--- a/gtk/gtksnapshot.c
+++ b/gtk/gtksnapshot.c
@@ -1332,37 +1332,42 @@ gtk_snapshot_render_layout (GtkSnapshot     *snapshot,
                             PangoLayout     *layout)
 {
   const GdkRGBA *fg_color;
-  graphene_rect_t bounds;
-  GtkBorder shadow_extents;
-  PangoRectangle ink_rect;
   GtkCssValue *shadow;
-  cairo_t *cr;
 
   g_return_if_fail (snapshot != NULL);
   g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
   g_return_if_fail (PANGO_IS_LAYOUT (layout));
 
+  gtk_snapshot_offset (snapshot, x, y);
+
   fg_color = _gtk_css_rgba_value_get_rgba (_gtk_style_context_peek_property (context, 
GTK_CSS_PROPERTY_COLOR));
+
   shadow = _gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_TEXT_SHADOW);
-  pango_layout_get_pixel_extents (layout, &ink_rect, NULL);
-  _gtk_css_shadows_value_get_extents (shadow, &shadow_extents);
-  graphene_rect_init (&bounds,
-                      ink_rect.x - shadow_extents.left,
-                      ink_rect.y - shadow_extents.top,
-                      ink_rect.width + shadow_extents.left + shadow_extents.right,
-                      ink_rect.height + shadow_extents.top + shadow_extents.bottom);
+  if (!_gtk_css_shadows_value_is_none (shadow))
+    {
+      PangoRectangle ink_rect;
+      graphene_rect_t bounds;
+      GtkBorder shadow_extents = { 0, };
+      cairo_t *cr;
 
-  gtk_snapshot_offset (snapshot, x, y);
+      pango_layout_get_pixel_extents (layout, &ink_rect, NULL);
+      _gtk_css_shadows_value_get_extents (shadow, &shadow_extents);
+      graphene_rect_init (&bounds,
+                          ink_rect.x - shadow_extents.left,
+                          ink_rect.y - shadow_extents.top,
+                          ink_rect.width + shadow_extents.left + shadow_extents.right,
+                          ink_rect.height + shadow_extents.top + shadow_extents.bottom);
 
-  cr = gtk_snapshot_append_cairo (snapshot, &bounds, "Text<%dchars>", pango_layout_get_character_count 
(layout));
+      cr = gtk_snapshot_append_cairo (snapshot, &bounds, "Text<%dchars>", pango_layout_get_character_count 
(layout));
 
-  _gtk_css_shadows_value_paint_layout (shadow, cr, layout);
+      gdk_cairo_set_source_rgba (cr, fg_color);
 
-  gdk_cairo_set_source_rgba (cr, fg_color);
+      _gtk_css_shadows_value_paint_layout (shadow, cr, layout);
+      cairo_destroy (cr);
+    }
 
-  gsk_pango_show_layout (cr, layout);
+  gsk_pango_show_layout (snapshot, fg_color, layout);
 
-  cairo_destroy (cr);
   gtk_snapshot_offset (snapshot, -x, -y);
 }
 


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