[gtk: 12/31] GskPango: Allow specifying a custom shape snapshot handler



commit 7c73f2fb02d8b4c11beed0748ad3791af2081800
Author: Alexander Larsson <alexl redhat com>
Date:   Thu Feb 6 16:21:54 2020 +0100

    GskPango: Allow specifying a custom shape snapshot handler
    
    We will need this for GtkTextView to render the textures in it.

 gtk/gskpango.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++------------
 gtk/gskpango.h |  8 ++++++++
 2 files changed, 56 insertions(+), 12 deletions(-)
---
diff --git a/gtk/gskpango.c b/gtk/gskpango.c
index 0e04a0b95a..5d2eb3c527 100644
--- a/gtk/gskpango.c
+++ b/gtk/gskpango.c
@@ -45,6 +45,15 @@ gsk_pango_renderer_set_state (GskPangoRenderer      *crenderer,
   crenderer->state = state;
 }
 
+void
+gsk_pango_renderer_set_shape_handler (GskPangoRenderer    *crenderer,
+                                      GskPangoShapeHandler handler)
+{
+  g_return_if_fail (GSK_IS_PANGO_RENDERER (crenderer));
+
+  crenderer->shape_handler = handler;
+}
+
 static void
 get_color (GskPangoRenderer *crenderer,
            PangoRenderPart   part,
@@ -240,26 +249,49 @@ gsk_pango_renderer_draw_shape (PangoRenderer  *renderer,
   gpointer shape_renderer_data;
   double base_x = (double)x / PANGO_SCALE;
   double base_y = (double)y / PANGO_SCALE;
+  gboolean handled = FALSE;
 
-  cr = gtk_snapshot_append_cairo (crenderer->snapshot, &crenderer->bounds);
+  if (crenderer->shape_handler)
+    {
+      double shape_x = base_x;
+      double shape_y = (double) (y + attr->logical_rect.y) / PANGO_SCALE;
 
-  layout = pango_renderer_get_layout (renderer);
-  if (!layout)
-    return;
+      if (shape_x != 0 || shape_y != 0)
+        {
+          gtk_snapshot_save (crenderer->snapshot);
+          gtk_snapshot_translate (crenderer->snapshot, &GRAPHENE_POINT_INIT (shape_x, shape_y));
+        }
 
-  shape_renderer = pango_cairo_context_get_shape_renderer (pango_layout_get_context (layout),
-                                                           &shape_renderer_data);
+      handled = crenderer->shape_handler (attr,
+                                          crenderer->snapshot,
+                                          (double)attr->logical_rect.width / PANGO_SCALE,
+                                          (double)attr->logical_rect.height / PANGO_SCALE);
+      if (shape_x != 0 || shape_y != 0)
+        gtk_snapshot_restore (crenderer->snapshot);
+    }
 
-  if (!shape_renderer)
-    return;
+  if (!handled)
+    {
+      cr = gtk_snapshot_append_cairo (crenderer->snapshot, &crenderer->bounds);
 
-  set_color (crenderer, PANGO_RENDER_PART_FOREGROUND, cr);
+      layout = pango_renderer_get_layout (renderer);
+      if (!layout)
+        return;
 
-  cairo_move_to (cr, base_x, base_y);
+      shape_renderer = pango_cairo_context_get_shape_renderer (pango_layout_get_context (layout),
+                                                               &shape_renderer_data);
 
-  shape_renderer (cr, attr, FALSE, shape_renderer_data);
+      if (!shape_renderer)
+        return;
 
-  cairo_destroy (cr);
+      set_color (crenderer, PANGO_RENDER_PART_FOREGROUND, cr);
+
+      cairo_move_to (cr, base_x, base_y);
+
+      shape_renderer (cr, attr, FALSE, shape_renderer_data);
+
+      cairo_destroy (cr);
+    }
 }
 
 static void
@@ -408,6 +440,10 @@ gsk_pango_renderer_acquire (void)
         }
 
       renderer = cached_renderer;
+
+      /* Reset to standard state */
+      renderer->state = GSK_PANGO_RENDERER_NORMAL;
+      renderer->shape_handler = NULL;
     }
   else
     {
diff --git a/gtk/gskpango.h b/gtk/gskpango.h
index 33ebff422a..bbd3699f43 100644
--- a/gtk/gskpango.h
+++ b/gtk/gskpango.h
@@ -41,6 +41,11 @@ typedef enum
   GSK_PANGO_RENDERER_CURSOR
 } GskPangoRendererState;
 
+typedef gboolean (*GskPangoShapeHandler) (PangoAttrShape         *attr,
+                                          GdkSnapshot            *snapshot,
+                                          double                  width,
+                                          double                  height);
+
 /*
  * This is a PangoRenderer implementation that translates all the draw calls to
  * gsk render nodes, using the GtkSnapshot helper class. Glyphs are translated
@@ -60,6 +65,7 @@ struct _GskPangoRenderer
   GdkRGBA               *error_color;
 
   GskPangoRendererState  state;
+  GskPangoShapeHandler shape_handler;
 
   /* house-keeping options */
   guint                  is_cached_renderer : 1;
@@ -73,6 +79,8 @@ struct _GskPangoRendererClass
 GType             gsk_pango_renderer_get_type  (void) G_GNUC_CONST;
 void              gsk_pango_renderer_set_state (GskPangoRenderer      *crenderer,
                                                 GskPangoRendererState  state);
+void              gsk_pango_renderer_set_shape_handler (GskPangoRenderer      *crenderer,
+                                                        GskPangoShapeHandler handler);
 GskPangoRenderer *gsk_pango_renderer_acquire   (void);
 void              gsk_pango_renderer_release   (GskPangoRenderer      *crenderer);
 


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