pango r2686 - in trunk: . pango



Author: behdad
Date: Wed Aug  6 09:09:46 2008
New Revision: 2686
URL: http://svn.gnome.org/viewvc/pango?rev=2686&view=rev

Log:
2008-08-06  Behdad Esfahbod  <behdad gnome org>

        * pango/pangocairo-render.c
        (pango_cairo_renderer_show_text_glyphs),
        (pango_cairo_renderer_draw_glyphs),
        (pango_cairo_renderer_draw_glyph_item):
        Implement draw_glyph_item using cairo_show_text_glyphs().

        * configure.in: Require cairo >= 1.7.1

Modified:
   trunk/ChangeLog
   trunk/pango/pangocairo-render.c

Modified: trunk/pango/pangocairo-render.c
==============================================================================
--- trunk/pango/pangocairo-render.c	(original)
+++ trunk/pango/pangocairo-render.c	Wed Aug  6 09:09:46 2008
@@ -24,6 +24,7 @@
 #include <math.h>
 
 #include "pangocairo-private.h"
+#include "pango-glyph-item.h"
 
 typedef struct _PangoCairoRendererClass PangoCairoRendererClass;
 
@@ -271,22 +272,30 @@
   cairo_restore (crenderer->cr);
 }
 
-/* cairo_glyph_t is 24 bytes */
-#define MAX_STACK 40
+#ifndef STACK_BUFFER_SIZE
+#define STACK_BUFFER_SIZE (512 * sizeof (int))
+#endif
+
+#define STACK_ARRAY_LENGTH(T) (STACK_BUFFER_SIZE / sizeof(T))
 
 static void
-pango_cairo_renderer_draw_glyphs (PangoRenderer     *renderer,
-				  PangoFont         *font,
-				  PangoGlyphString  *glyphs,
-				  int                x,
-				  int                y)
+pango_cairo_renderer_show_text_glyphs (PangoRenderer        *renderer,
+				       const char           *text,
+				       int                   text_len,
+				       PangoGlyphString     *glyphs,
+				       cairo_text_cluster_t *clusters,
+				       int                   num_clusters,
+				       gboolean              backward,
+				       PangoFont            *font,
+				       int                   x,
+				       int                   y)
 {
   PangoCairoRenderer *crenderer = (PangoCairoRenderer *) (renderer);
 
   int i, count;
   int x_position = 0;
   cairo_glyph_t *cairo_glyphs;
-  cairo_glyph_t stack_glyphs[MAX_STACK];
+  cairo_glyph_t stack_glyphs[STACK_ARRAY_LENGTH (cairo_glyph_t)];
   double base_x = crenderer->x_offset + (double)x / PANGO_SCALE;
   double base_y = crenderer->y_offset + (double)y / PANGO_SCALE;
 
@@ -315,7 +324,7 @@
       goto done;
     }
 
-  if (glyphs->num_glyphs > MAX_STACK)
+  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;
@@ -345,12 +354,19 @@
       x_position += gi->geometry.width;
     }
 
-  if (crenderer->do_path)
+  if (G_UNLIKELY (crenderer->do_path))
     cairo_glyph_path (crenderer->cr, cairo_glyphs, count);
   else
-    cairo_show_glyphs (crenderer->cr, cairo_glyphs, count);
+    if (G_UNLIKELY (clusters))
+      cairo_show_text_glyphs (crenderer->cr,
+			      text, text_len,
+			      cairo_glyphs, count,
+			      clusters, num_clusters,
+			      backward);
+    else
+      cairo_show_glyphs (crenderer->cr, cairo_glyphs, count);
 
-  if (glyphs->num_glyphs > MAX_STACK)
+  if (cairo_glyphs != stack_glyphs)
     g_free (cairo_glyphs);
 
 done:
@@ -358,6 +374,22 @@
 }
 
 static void
+pango_cairo_renderer_draw_glyphs (PangoRenderer     *renderer,
+				  PangoFont         *font,
+				  PangoGlyphString  *glyphs,
+				  int                x,
+				  int                y)
+{
+  pango_cairo_renderer_show_text_glyphs (renderer,
+					 NULL, 0,
+					 glyphs,
+					 NULL, 0,
+					 FALSE,
+					 font,
+					 x, y);
+}
+
+static void
 pango_cairo_renderer_draw_glyph_item (PangoRenderer     *renderer,
 				      const char        *text,
 				      PangoGlyphItem    *glyph_item,
@@ -365,93 +397,77 @@
 				      int                y)
 {
   PangoCairoRenderer *crenderer = (PangoCairoRenderer *) (renderer);
-  PangoFont          *font = glyph_item->item->analysis.font;
-  PangoGlyphString   *glyphs = glyph_item->glyphs;
-
-  int i, count;
-  int x_position = 0;
-  cairo_glyph_t *cairo_glyphs;
-  cairo_glyph_t stack_glyphs[MAX_STACK];
-  double base_x = crenderer->x_offset + (double)x / PANGO_SCALE;
-  double base_y = crenderer->y_offset + (double)y / PANGO_SCALE;
+  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)
     {
-      pango_cairo_renderer_draw_glyphs (renderer,
-					glyph_item->item->analysis.font,
-					glyph_item->glyphs,
-					x, y);
+      pango_cairo_renderer_show_text_glyphs (renderer,
+					     NULL, 0,
+					     glyphs,
+					     NULL, 0,
+					     FALSE,
+					     font,
+					     x, y);
       return;
     }
 
-  cairo_save (crenderer->cr);
-  set_color (crenderer, PANGO_RENDER_PART_FOREGROUND);
-
-  if (!_pango_cairo_font_install (font, crenderer->cr))
-    {
-      for (i = 0; i < glyphs->num_glyphs; i++)
-	{
-	  PangoGlyphInfo *gi = &glyphs->glyphs[i];
-
-	  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;
-
-	      /* XXX */
-	      _pango_cairo_renderer_draw_unknown_glyph (crenderer, font, gi, cx, cy);
-	    }
-	  x_position += gi->geometry.width;
-	}
-
-      goto done;
-    }
-
-  if (glyphs->num_glyphs > MAX_STACK)
-    cairo_glyphs = g_new (cairo_glyph_t, glyphs->num_glyphs);
+  if (glyphs->num_glyphs > (int) G_N_ELEMENTS (stack_clusters))
+    cairo_clusters = g_new (cairo_text_cluster_t, glyphs->num_glyphs);
   else
-    cairo_glyphs = stack_glyphs;
+    cairo_clusters = stack_clusters;
 
-  count = 0;
-  for (i = 0; i < glyphs->num_glyphs; i++)
+  num_clusters = 0;
+  if (pango_glyph_item_iter_init_start (&iter, glyph_item, text))
     {
-      PangoGlyphInfo *gi = &glyphs->glyphs[i];
+      do {
+        int num_bytes, num_glyphs, i;
 
-      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;
+        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 ("pango_cairo_renderer_draw_glyph_item: bad cluster has num_bytess %d", num_bytes);
+	if (num_glyphs < 1)
+	  g_warning ("pango_cairo_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);
+	     i < MAX (iter.start_glyph, 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));
+    }
+
+  pango_cairo_renderer_show_text_glyphs (renderer,
+					 text + item->offset, item->length,
+					 glyphs,
+					 cairo_clusters, num_clusters,
+					 backward,
+					 font,
+					 x, y);
 
-	  if (gi->glyph & PANGO_GLYPH_UNKNOWN_FLAG)
-	    /* XXX */
-	    _pango_cairo_renderer_draw_unknown_glyph (crenderer, font, gi, cx, cy);
-	  else
-	    {
-	      cairo_glyphs[count].index = gi->glyph;
-	      cairo_glyphs[count].x = cx;
-	      cairo_glyphs[count].y = cy;
-	      count++;
-	    }
-	}
-      x_position += gi->geometry.width;
-    }
-
-  /* XXX */
-  cairo_show_glyphs (crenderer->cr, cairo_glyphs, count);
-
-  if (glyphs->num_glyphs > MAX_STACK)
-    g_free (cairo_glyphs);
-
-done:
-  cairo_restore (crenderer->cr);
+  if (cairo_clusters != stack_clusters)
+    g_free (cairo_clusters);
 }
 
-#undef MAX_STACK
-
 static void
 pango_cairo_renderer_draw_rectangle (PangoRenderer     *renderer,
 				     PangoRenderPart    part,



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