[RFC Patch] renderer: Add draw_layout vfunc



Hi,

I'm hoping to get some feedback about an experimental addition I made to
the PangoRendererClass vtable which gives renderers more contextual
information when drawing layouts. This adds a draw_layout vfunc which
allows a backend to potentially cache state with a user's layout so when
the same layout is drawn multiple times it may be optimized for
subsequent drawing.

For example; Cogl - the 3D graphics API used by Clutter - implements a
custom renderer which can cache the geometry of a layout in a vertex
buffer which can be mapped into the GPU the first time it is used.  Then
for subsequent draws we only need to bind the glyph cache texture and
re-draw from that existing vertex buffer, avoiding repeatedly processing
and uploading/mapping that vertex data.

Without something like this Cogl needs a cogl_pango_render_layout
function to wrap calls to pango_renderer_draw_layout so it can check and
initialize private state associated with the layout but with this change
that wrapper is no longer necessary and users can instead use the
pristine pango API to draw layouts using Cogl.

An example use of this new vfunc can be found in the
wip/cogl-pango-draw-layout branch in the clutter repo:
git://git.clutter-project.org/clutter.git

kind regards,
- Robert

---
 pango/pango-renderer.c |   61 +++++++++++++++++++++++++++++------------------
 pango/pango-renderer.h |    6 ++++-
 2 files changed, 43 insertions(+), 24 deletions(-)

diff --git a/pango/pango-renderer.c b/pango/pango-renderer.c
index db75446..6d5c0f8 100644
--- a/pango/pango-renderer.c
+++ b/pango/pango-renderer.c
@@ -59,6 +59,11 @@ struct _PangoRendererPrivate
 };
 
 static void pango_renderer_finalize                     (GObject          *gobject);
+static void pango_renderer_default_draw_layout (PangoRenderer *renderer,
+                                                PangoLayout   *layout,
+                                                int            x,
+                                                int            y);
+
 static void pango_renderer_default_draw_glyphs          (PangoRenderer    *renderer,
 							 PangoFont        *font,
 							 PangoGlyphString *glyphs,
@@ -115,6 +120,7 @@ pango_renderer_class_init (PangoRendererClass *klass)
 
   parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
 
+  klass->draw_layout = pango_renderer_default_draw_layout;
   klass->draw_glyphs = pango_renderer_default_draw_glyphs;
   klass->draw_glyph_item = pango_renderer_default_draw_glyph_item;
   klass->draw_rectangle = pango_renderer_default_draw_rectangle;
@@ -146,6 +152,37 @@ pango_renderer_finalize (GObject *gobject)
   parent_class->finalize (gobject);
 }
 
+static void
+pango_renderer_default_draw_layout (PangoRenderer *renderer,
+				    PangoLayout	  *layout,
+				    int		   x,
+				    int		   y)
+{
+  PangoLayoutIter *iter;
+
+  iter = pango_layout_get_iter (layout);
+
+  do
+    {
+      PangoRectangle   logical_rect;
+      PangoLayoutLine *line;
+      int              baseline;
+
+      line = pango_layout_iter_get_line_readonly (iter);
+
+      pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
+      baseline = pango_layout_iter_get_baseline (iter);
+
+      pango_renderer_draw_layout_line (renderer,
+				       line,
+				       x + logical_rect.x,
+				       y + baseline);
+    }
+  while (pango_layout_iter_next_line (iter));
+
+  pango_layout_iter_free (iter);
+}
+
 /**
  * pango_renderer_draw_layout:
  * @renderer: a #PangoRenderer
@@ -165,8 +202,6 @@ pango_renderer_draw_layout (PangoRenderer    *renderer,
 			    int               x,
 			    int               y)
 {
-  PangoLayoutIter *iter;
-
   g_return_if_fail (PANGO_IS_RENDERER (renderer));
   g_return_if_fail (PANGO_IS_LAYOUT (layout));
 
@@ -182,27 +217,7 @@ pango_renderer_draw_layout (PangoRenderer    *renderer,
 
   pango_renderer_activate (renderer);
 
-  iter = pango_layout_get_iter (layout);
-
-  do
-    {
-      PangoRectangle   logical_rect;
-      PangoLayoutLine *line;
-      int              baseline;
-
-      line = pango_layout_iter_get_line_readonly (iter);
-
-      pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
-      baseline = pango_layout_iter_get_baseline (iter);
-
-      pango_renderer_draw_layout_line (renderer,
-				       line,
-				       x + logical_rect.x,
-				       y + baseline);
-    }
-  while (pango_layout_iter_next_line (iter));
-
-  pango_layout_iter_free (iter);
+  PANGO_RENDERER_GET_CLASS (renderer)->draw_layout (renderer, layout, x, y);
 
   pango_renderer_deactivate (renderer);
 }
diff --git a/pango/pango-renderer.h b/pango/pango-renderer.h
index 354127b..74b6d04 100644
--- a/pango/pango-renderer.h
+++ b/pango/pango-renderer.h
@@ -182,12 +182,16 @@ struct _PangoRendererClass
 			   int                x,
 			   int                y);
 
+  void (*draw_layout) (PangoRenderer *renderer,
+		       PangoLayout   *layout,
+		       int	      x,
+		       int	      y);
+
   /*< private >*/
 
   /* Padding for future expansion */
   void (*_pango_reserved2) (void);
   void (*_pango_reserved3) (void);
-  void (*_pango_reserved4) (void);
 };
 
 GType pango_renderer_get_type    (void) G_GNUC_CONST;
-- 
1.7.0.4


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