? examples/TEST-ARABIC
? examples/TEST-IPA-I-GUESS
Index: pango/pangocairo-private.h
===================================================================
RCS file: /cvs/gnome/pango/pango/pangocairo-private.h,v
retrieving revision 1.6
diff -u -p -r1.6 pangocairo-private.h
--- pango/pangocairo-private.h	6 Dec 2005 01:20:46 -0000	1.6
+++ pango/pangocairo-private.h	27 Dec 2005 12:46:45 -0000
@@ -43,6 +43,16 @@ struct _PangoCairoFontMapIface
   PangoRenderer *(*get_renderer)   (PangoCairoFontMap *fontmap);
 };
 
+typedef struct _PangoCairoMiniFont PangoCairoMiniFont;
+
+struct _PangoCairoMiniFont
+{
+	PangoFont *font;
+	int width;
+	int height;	
+	int pad;	
+};
+
 PangoRenderer *_pango_cairo_font_map_get_renderer (PangoCairoFontMap *cfontmap);
 
 #define PANGO_CAIRO_FONT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), PANGO_TYPE_CAIRO_FONT, PangoCairoFontIface))
Index: pango/pangocairo-render.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pangocairo-render.c,v
retrieving revision 1.10
diff -u -p -r1.10 pangocairo-render.c
--- pango/pangocairo-render.c	6 Dec 2005 01:20:46 -0000	1.10
+++ pango/pangocairo-render.c	27 Dec 2005 12:46:46 -0000
@@ -55,7 +55,155 @@ set_color (PangoCairoRenderer *crenderer
 			  color->green / 65535.,
 			  color->blue / 65535.);
 }
-     
+
+static PangoCairoMiniFont *
+_pango_cairo_mini_font_new (PangoCairoRenderer *crenderer,
+                            PangoFont          *font)
+{
+  PangoFont *mini_font;
+  PangoCairoMiniFont *c_mini_font;
+  int new_size;
+  int i;
+  int width = 0, height = 0;
+  cairo_text_extents_t extents;
+  guchar c[2] = {0, 0};
+  const char hexdigits[] = "0123456789ABCDEF";
+  PangoFontMap *fontmap, *mini_fontmap;
+  PangoFontDescription *desc;
+  PangoContext *context, *mini_context;
+
+  fontmap = pango_font_get_font_map (font);
+  g_assert (fontmap);
+
+  desc = pango_font_description_new ();
+
+  context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (fontmap));
+  pango_context_set_language (context, pango_language_from_string ("en"));
+
+  pango_font_description_set_family_static (desc, "monospace");
+
+  new_size = pango_font_description_get_size (pango_font_describe (font)) / 2;
+
+  if (pango_font_description_get_size_is_absolute (pango_font_describe (font)))
+      pango_font_description_set_absolute_size (desc, new_size);
+  else
+      pango_font_description_set_size (desc, new_size);
+
+  mini_font = pango_font_map_load_font (fontmap, context, desc);
+
+  mini_fontmap = pango_font_get_font_map (mini_font);
+  mini_context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (mini_fontmap));
+  pango_cairo_update_context (crenderer->cr, mini_context);
+
+  cairo_save (crenderer->cr);
+  _pango_cairo_font_install (PANGO_CAIRO_FONT (mini_font), crenderer->cr);
+
+  for (i = 0 ; i < 16 ; i++)
+    {
+      c[0] = hexdigits[i];
+      cairo_text_extents (crenderer->cr, (const char *)c, &extents);
+      width = MAX (width, extents.width);
+      height = MAX (height, extents.height);
+    }
+
+  cairo_restore (crenderer->cr);
+
+  pango_cairo_update_context (crenderer->cr, context);
+  pango_font_description_free (desc);
+  g_object_unref (context);
+  g_object_unref (mini_context);
+
+  c_mini_font = g_slice_new (PangoCairoMiniFont);
+  c_mini_font->font = mini_font;
+  c_mini_font->width = width;
+  c_mini_font->height = height;
+  c_mini_font->pad = MAX (height / 10, 1);
+
+  return c_mini_font;
+} 
+
+static void
+_pango_cairo_mini_font_destroy (PangoCairoMiniFont *c_mini_font)
+{
+  if (c_mini_font)
+    {
+      g_object_unref (c_mini_font->font);
+      g_slice_free (PangoCairoMiniFont, c_mini_font);
+    }
+}  
+   
+static void
+_pango_cairo_renderer_draw_unknown_glyph (PangoCairoRenderer *crenderer,
+					  PangoFont          *font,
+					  PangoGlyphInfo     *gi,
+					  double              cx,
+					  double              cy)
+{
+  char buf[7];
+  double ys[3];
+  double xs[4];
+  int row, col;
+  int cols;
+  char hexbox_string[2] = {0, 0};
+  double temp_x, temp_y;
+  PangoCairoMiniFont *mini;
+  gunichar ch;
+
+  mini = (PangoCairoMiniFont *) g_object_get_data (G_OBJECT (font), "mini_font");
+  if (!mini)
+    {
+      mini = _pango_cairo_mini_font_new (crenderer, font);
+      g_object_set_data_full (G_OBJECT (font), "mini_font", mini, (GDestroyNotify)_pango_cairo_mini_font_destroy); 
+    }
+
+  ch = gi->glyph & ~PANGO_CAIRO_UNKNOWN_FLAG;
+
+  cols = ch > 0xffff ? 3 : 2;
+  g_snprintf (buf, sizeof(buf), cols == 2 ? "%04X" : "%06X", ch);
+
+  ys[2] = cy - mini->pad * 2;
+  ys[1] = ys[2] - mini->height - mini->pad;
+  ys[0] = ys[1] - mini->height - mini->pad * 2;
+
+  xs[0] = cx + mini->pad;
+  xs[1] = xs[0] + mini->pad;
+  xs[2] = xs[1] + mini->width + mini->pad;
+  xs[3] = xs[2] + mini->width + mini->pad;
+
+  cairo_save (crenderer->cr);
+
+  cairo_rectangle (crenderer->cr,
+		   (double) xs[0],
+		   (double) ys[0],
+		   (double)(gi->geometry.width) / PANGO_SCALE - 2 * mini->pad,
+		   (double)(mini->height * 2 + mini->pad * 5));
+
+  if (!crenderer->do_path)
+    {
+      cairo_save (crenderer->cr);
+      cairo_set_line_width (crenderer->cr, ((double)mini->pad) / 2);
+      cairo_stroke (crenderer->cr);
+      cairo_restore (crenderer->cr);
+    }
+
+  cairo_get_current_point (crenderer->cr, &temp_x, &temp_y);
+  _pango_cairo_font_install (PANGO_CAIRO_FONT (mini->font), crenderer->cr);
+  for (row = 0; row < 2; row++)
+      for (col = 0; col < cols; col++)
+	{
+	  hexbox_string[0] = buf[row * cols + col];
+	  cairo_move_to (crenderer->cr, xs[col + 1], ys[row + 1]);
+
+	  if (crenderer->do_path)
+	      cairo_text_path (crenderer->cr, hexbox_string);
+	  else
+	      cairo_show_text (crenderer->cr, hexbox_string);
+	}
+  cairo_move_to (crenderer->cr, temp_x, temp_y);
+
+  cairo_restore (crenderer->cr);
+}
+
 static void
 pango_cairo_renderer_draw_glyphs (PangoRenderer     *renderer,
 				  PangoFont         *font,
@@ -67,11 +215,11 @@ pango_cairo_renderer_draw_glyphs (PangoR
 
   /* cairo_glyph_t is 24 bytes */
 #define MAX_STACK 40
-  
+
   int i, count;
   int x_position = 0;
   cairo_glyph_t *cairo_glyphs;
-  cairo_glyph_t stack_glyphs[MAX_STACK];
+  cairo_glyph_t stack_glyphs[MAX_STACK];  
 
   if (!crenderer->do_path)
     {
@@ -91,36 +239,21 @@ pango_cairo_renderer_draw_glyphs (PangoR
       PangoGlyphInfo *gi = &glyphs->glyphs[i];
 
       if (gi->glyph)
-	{
-	  if (gi->glyph & PANGO_CAIRO_UNKNOWN_FLAG)
-	    {
-	      int mini_pad = gi->geometry.width / 10;
-	      /* draw an empty dashed box, no hexbox for now */
-	      cairo_rectangle (crenderer->cr,
-			       crenderer->x_offset + (double)(x + x_position + mini_pad) / PANGO_SCALE,
-			       crenderer->y_offset + (double)(y - mini_pad) / PANGO_SCALE, 
-			       (double)(gi->geometry.width - 2 * mini_pad) / PANGO_SCALE,
-			       -(double)(gi->geometry.width - 2 * mini_pad) / PANGO_SCALE);
-	      if (!crenderer->do_path)
-		{
-		  double dash = (double)mini_pad * 2 / PANGO_SCALE;
-		  cairo_save (crenderer->cr);
-		  cairo_set_line_width (crenderer->cr, (double)mini_pad / PANGO_SCALE);
-		  cairo_set_dash (crenderer->cr, &dash, 1, 0);
-		  cairo_stroke (crenderer->cr);
-		  cairo_restore (crenderer->cr);
-		}
-	    }
-	  else
-	    {
-	      cairo_glyphs[count].index = gi->glyph;
-	      cairo_glyphs[count].x = crenderer->x_offset + (double)(x + x_position + gi->geometry.x_offset) / PANGO_SCALE;
-	      cairo_glyphs[count].y = crenderer->y_offset + (double)(y + gi->geometry.y_offset) / PANGO_SCALE;
-
-	      count++;
-	    }
-	}
-	  
+        {
+	  PangoGlyph glyph = gi->glyph;
+          double cx = crenderer->x_offset + (double)(x + x_position + gi->geometry.x_offset) / PANGO_SCALE;
+          double cy = crenderer->y_offset + (double)(y + gi->geometry.y_offset) / PANGO_SCALE;
+
+          if (gi->glyph & PANGO_CAIRO_UNKNOWN_FLAG)
+	    _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;
     }
 

