[cairo-commit] cairo/src cairo-ft-font.c, 1.111, 1.112 cairo-scaled-font.c, 1.1, 1.2 cairo-win32-font.c, 1.39, 1.40 cairoint.h, 1.208, 1.209

Owen Taylor commit at pdx.freedesktop.org
Wed Aug 31 19:11:25 PDT 2005


Committed by: otaylor

Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv2034/src

Modified Files:
	cairo-ft-font.c cairo-scaled-font.c cairo-win32-font.c 
	cairoint.h 
Log Message:
2005-08-31  Carl Worth  <cworth at cworth.org>

	* test/cairo-test.c: (create_xlib_surface): Add call to
	XSynchronize, (the expected clip-all failure isn't occuring
	without it for some reason).
	
	* test/clip-all.c: (main): Note reason for expected failure.

2005-08-31  Owen Taylor  <otaylor at redhat.com>

	* src/cairoint.h (_cairo_scaled_font_backend)
	src/cairo-scaled-font.c: Add an optional text_to_glyphs() virtual
	function that the backend can implement instead of
	ucs4_to_index().

	* test/cairo-test.c: Protect inclusion of fontconfig.h
	with HAVE_FCFINI.

Index: cairo-ft-font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-ft-font.c,v
retrieving revision 1.111
retrieving revision 1.112
diff -u -d -r1.111 -r1.112
--- cairo-ft-font.c	31 Aug 2005 22:08:02 -0000	1.111
+++ cairo-ft-font.c	1 Sep 2005 02:11:22 -0000	1.112
@@ -1907,6 +1907,7 @@
     _cairo_ft_scaled_font_create_toy,
     _cairo_ft_scaled_font_fini,
     _cairo_ft_scaled_glyph_init,
+    NULL,			/* text_to_glyphs */
     _cairo_ft_ucs4_to_index,
     _cairo_ft_show_glyphs,
 };

Index: cairo-scaled-font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-scaled-font.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- cairo-scaled-font.c	31 Aug 2005 22:08:02 -0000	1.1
+++ cairo-scaled-font.c	1 Sep 2005 02:11:22 -0000	1.2
@@ -659,6 +659,14 @@
     cairo_status_t status = CAIRO_STATUS_SUCCESS;
     cairo_scaled_glyph_t *scaled_glyph;
 
+    if (scaled_font->backend->text_to_glyphs)
+	status = scaled_font->backend->text_to_glyphs (scaled_font,
+						       x, y, utf8,
+						       glyphs, num_glyphs);
+
+    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+	return status;
+
     status = _cairo_utf8_to_ucs4 ((unsigned char*)utf8, -1, &ucs4, num_glyphs);
     if (status)
 	return status;

Index: cairo-win32-font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-win32-font.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -d -r1.39 -r1.40
--- cairo-win32-font.c	19 Aug 2005 19:08:42 -0000	1.39
+++ cairo-win32-font.c	1 Sep 2005 02:11:22 -0000	1.40
@@ -101,6 +101,17 @@
     
 } cairo_win32_scaled_font_t;
 
+static cairo_status_t 
+_cairo_win32_scaled_font_set_metrics (cairo_win32_scaled_font_t *scaled_font);
+
+static cairo_status_t 
+_cairo_win32_scaled_font_init_glyph_metrics (cairo_win32_scaled_font_t *scaled_font,
+					     cairo_scaled_glyph_t      *scaled_glyph);
+
+static cairo_status_t
+_cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font,
+					  cairo_scaled_glyph_t      *scaled_glyph);
+
 #define NEARLY_ZERO(d) (fabs(d) < (1. / 65536.))
 
 static void
@@ -221,6 +232,7 @@
 {
     cairo_win32_scaled_font_t *f;
     cairo_matrix_t scale;
+    cairo_status_t status;
 
     f = malloc (sizeof(cairo_win32_scaled_font_t));
     if (f == NULL)
@@ -252,6 +264,8 @@
 	    else
 		f->quality = ANTIALIASED_QUALITY;
 	    break;
+	case CAIRO_ANTIALIAS_DEFAULT:
+	    ASSERT_NOT_REACHED;
 	}
     }
     
@@ -266,6 +280,12 @@
 			     font_matrix, ctm, options,
 			     &cairo_win32_scaled_font_backend);
 
+    status = _cairo_win32_scaled_font_set_metrics (f);
+    if (status) {
+	cairo_scaled_font_destroy (&f->base);
+	return NULL;
+    }
+
     return &f->base;
 }
 
@@ -496,7 +516,7 @@
     if (!logfont.lfFaceName)
 	return CAIRO_STATUS_NO_MEMORY;
     
-    scaled_font = _win32_scaled_font_create (&logfont, toy_face,
+    scaled_font = _win32_scaled_font_create (&logfont, &toy_face->base,
 					     font_matrix, ctm, options);
     if (!scaled_font)
 	return CAIRO_STATUS_NO_MEMORY;
@@ -521,14 +541,10 @@
 	DeleteObject (scaled_font->unscaled_hfont);
 }
 
-static void
-_cairo_win32_scaled_font_get_glyph_cache_key (void                    *abstract_font,
-					      cairo_glyph_cache_key_t *key)
-{
-}
-
-static cairo_status_t 
+static cairo_int_status_t 
 _cairo_win32_scaled_font_text_to_glyphs (void		*abstract_font,
+					 double		x,
+					 double		y,
 					 const char	*utf8,
 					 cairo_glyph_t **glyphs, 
 					 int		*num_glyphs)
@@ -541,9 +557,17 @@
     WCHAR *glyph_indices = NULL;
     int *dx = NULL;
     cairo_status_t status = CAIRO_STATUS_SUCCESS;
-    double x_pos;
+    double x_pos, y_pos;
+    double x_incr, y_incr;
     HDC hdc = NULL;
 
+    /* Compute a vector in user space along the baseline of length one logical space unit */
+    x_incr = 1;
+    y_incr = 0;
+    cairo_matrix_transform_distance (&scaled_font->base.font_matrix, &x_incr, &y_incr);
+    x_incr /= scaled_font->logical_scale;
+    y_incr /= scaled_font->logical_scale;
+    
     status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &n16);
     if (status)
 	return status;
@@ -618,13 +642,16 @@
 	goto FAIL2;
     }
 
-    x_pos = 0;
+    x_pos = x;
+    y_pos = y;
+    
     for (i = 0; i < gcp_results.nGlyphs; i++) {
 	(*glyphs)[i].index = glyph_indices[i];
 	(*glyphs)[i].x = x_pos ;
-	(*glyphs)[i].y = 0;
+	(*glyphs)[i].y = y_pos;
 
-	x_pos += dx[i] / scaled_font->logical_scale;
+	x_pos += x_incr * dx[i];
+	y_pos += y_incr * dx[i];
     }
 
  FAIL2:
@@ -642,11 +669,11 @@
 }
 
 static cairo_status_t 
-_cairo_win32_scaled_font_font_extents (void		    *abstract_font,
-				       cairo_font_extents_t *extents)
+_cairo_win32_scaled_font_set_metrics (cairo_win32_scaled_font_t *scaled_font)
 {
-    cairo_win32_scaled_font_t *scaled_font = abstract_font;
     cairo_status_t status;
+    cairo_font_extents_t extents;
+
     TEXTMETRIC metrics;
     HDC hdc;
 
@@ -664,12 +691,12 @@
 	GetTextMetrics (hdc, &metrics);
 	cairo_win32_scaled_font_done_font (&scaled_font->base);
 
-	extents->ascent = metrics.tmAscent / scaled_font->logical_scale;
-	extents->descent = metrics.tmDescent / scaled_font->logical_scale;
+	extents.ascent = metrics.tmAscent / scaled_font->logical_scale;
+	extents.descent = metrics.tmDescent / scaled_font->logical_scale;
 
-	extents->height = (metrics.tmHeight + metrics.tmExternalLeading) / scaled_font->logical_scale;
-	extents->max_x_advance = metrics.tmMaxCharWidth / scaled_font->logical_scale;
-	extents->max_y_advance = 0;
+	extents.height = (metrics.tmHeight + metrics.tmExternalLeading) / scaled_font->logical_scale;
+	extents.max_x_advance = metrics.tmMaxCharWidth / scaled_font->logical_scale;
+	extents.max_y_advance = 0;
 
     } else {
 	/* For all other transformations, we use the design metrics
@@ -683,39 +710,33 @@
 	GetTextMetrics (hdc, &metrics);
 	_cairo_win32_scaled_font_done_unscaled_font (&scaled_font->base);
 
-	extents->ascent = (double)metrics.tmAscent / scaled_font->em_square;
-	extents->descent = metrics.tmDescent * scaled_font->em_square;
-	extents->height = (double)(metrics.tmHeight + metrics.tmExternalLeading) / scaled_font->em_square;
-	extents->max_x_advance = (double)(metrics.tmMaxCharWidth) / scaled_font->em_square;
-	extents->max_y_advance = 0;
+	extents.ascent = (double)metrics.tmAscent / scaled_font->em_square;
+	extents.descent = metrics.tmDescent * scaled_font->em_square;
+	extents.height = (double)(metrics.tmHeight + metrics.tmExternalLeading) / scaled_font->em_square;
+	extents.max_x_advance = (double)(metrics.tmMaxCharWidth) / scaled_font->em_square;
+	extents.max_y_advance = 0;
 	
     }
 
+    _cairo_scaled_font_set_metrics (&scaled_font->base, &extents);
+
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t 
-_cairo_win32_scaled_font_glyph_extents (void		     *abstract_font,
-					cairo_glyph_t	     *glyphs, 
-					int		      num_glyphs,
-					cairo_text_extents_t *extents)
+_cairo_win32_scaled_font_init_glyph_metrics (cairo_win32_scaled_font_t *scaled_font,
+					     cairo_scaled_glyph_t      *scaled_glyph)
 {
-    cairo_win32_scaled_font_t *scaled_font = abstract_font;
     static const MAT2 matrix = { { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 1 } };
     GLYPHMETRICS metrics;
     cairo_status_t status;
+    cairo_text_extents_t extents;
     HDC hdc;
 
     hdc = _get_global_font_dc ();
     if (!hdc)
 	return CAIRO_STATUS_NO_MEMORY;
 
-    /* We handle only the case num_glyphs == 1, glyphs[i].x == glyphs[0].y == 0.
-     * This is all that the calling code triggers, and the backend interface
-     * will eventually be changed to match
-     */
-    assert (num_glyphs == 1);
-
     if (scaled_font->preserve_axes) {
 	/* If we aren't rotating / skewing the axes, then we get the metrics
 	 * from the GDI in device space and convert to font space.
@@ -723,34 +744,35 @@
 	status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);
 	if (status)
 	    return status;
-	GetGlyphOutlineW (hdc, glyphs[0].index, GGO_METRICS | GGO_GLYPH_INDEX,
+	GetGlyphOutlineW (hdc, _cairo_scaled_glyph_index (scaled_glyph),
+			  GGO_METRICS | GGO_GLYPH_INDEX,
 			  &metrics, 0, NULL, &matrix);
 	cairo_win32_scaled_font_done_font (&scaled_font->base);
 
 	if (scaled_font->swap_axes) {
-	    extents->x_bearing = - metrics.gmptGlyphOrigin.y / scaled_font->y_scale;
-	    extents->y_bearing = metrics.gmptGlyphOrigin.x / scaled_font->x_scale;
-	    extents->width = metrics.gmBlackBoxY / scaled_font->y_scale;
-	    extents->height = metrics.gmBlackBoxX / scaled_font->x_scale;
-	    extents->x_advance = metrics.gmCellIncY / scaled_font->x_scale;
-	    extents->y_advance = metrics.gmCellIncX / scaled_font->y_scale;
+	    extents.x_bearing = - metrics.gmptGlyphOrigin.y / scaled_font->y_scale;
+	    extents.y_bearing = metrics.gmptGlyphOrigin.x / scaled_font->x_scale;
+	    extents.width = metrics.gmBlackBoxY / scaled_font->y_scale;
+	    extents.height = metrics.gmBlackBoxX / scaled_font->x_scale;
+	    extents.x_advance = metrics.gmCellIncY / scaled_font->x_scale;
+	    extents.y_advance = metrics.gmCellIncX / scaled_font->y_scale;
 	} else {
-	    extents->x_bearing = metrics.gmptGlyphOrigin.x / scaled_font->x_scale;
-	    extents->y_bearing = - metrics.gmptGlyphOrigin.y / scaled_font->y_scale;
-	    extents->width = metrics.gmBlackBoxX / scaled_font->x_scale;
-	    extents->height = metrics.gmBlackBoxY / scaled_font->y_scale;
-	    extents->x_advance = metrics.gmCellIncX / scaled_font->x_scale;
-	    extents->y_advance = metrics.gmCellIncY / scaled_font->y_scale;
+	    extents.x_bearing = metrics.gmptGlyphOrigin.x / scaled_font->x_scale;
+	    extents.y_bearing = - metrics.gmptGlyphOrigin.y / scaled_font->y_scale;
+	    extents.width = metrics.gmBlackBoxX / scaled_font->x_scale;
+	    extents.height = metrics.gmBlackBoxY / scaled_font->y_scale;
+	    extents.x_advance = metrics.gmCellIncX / scaled_font->x_scale;
+	    extents.y_advance = metrics.gmCellIncY / scaled_font->y_scale;
 	}
 
 	if (scaled_font->swap_x) {
-	    extents->x_bearing = (- extents->x_bearing - extents->width);
-	    extents->x_advance = - extents->x_advance;
+	    extents.x_bearing = (- extents.x_bearing - extents.width);
+	    extents.x_advance = - extents.x_advance;
 	}
 
 	if (scaled_font->swap_y) {
-	    extents->y_bearing = (- extents->y_bearing - extents->height);
-	    extents->y_advance = - extents->y_advance;
+	    extents.y_bearing = (- extents.y_bearing - extents.height);
+	    extents.y_advance = - extents.y_advance;
 	}
 	
     } else {
@@ -758,22 +780,32 @@
 	 * of the font.
 	 */
 	status = _cairo_win32_scaled_font_select_unscaled_font (&scaled_font->base, hdc);
-	GetGlyphOutlineW (hdc, glyphs[0].index, GGO_METRICS | GGO_GLYPH_INDEX,
+	GetGlyphOutlineW (hdc, _cairo_scaled_glyph_index (scaled_glyph),
+			  GGO_METRICS | GGO_GLYPH_INDEX,
 			  &metrics, 0, NULL, &matrix);
 	_cairo_win32_scaled_font_done_unscaled_font (&scaled_font->base);
 
-	extents->x_bearing = (double)metrics.gmptGlyphOrigin.x / scaled_font->em_square;
-	extents->y_bearing = - (double)metrics.gmptGlyphOrigin.y / scaled_font->em_square;
-	extents->width = (double)metrics.gmBlackBoxX / scaled_font->em_square;
-	extents->height = (double)metrics.gmBlackBoxY / scaled_font->em_square;
-	extents->x_advance = (double)metrics.gmCellIncX / scaled_font->em_square;
-	extents->y_advance = (double)metrics.gmCellIncY / scaled_font->em_square;
+	extents.x_bearing = (double)metrics.gmptGlyphOrigin.x / scaled_font->em_square;
+	extents.y_bearing = - (double)metrics.gmptGlyphOrigin.y / scaled_font->em_square;
+	extents.width = (double)metrics.gmBlackBoxX / scaled_font->em_square;
+	extents.height = (double)metrics.gmBlackBoxY / scaled_font->em_square;
+	extents.x_advance = (double)metrics.gmCellIncX / scaled_font->em_square;
+	extents.y_advance = (double)metrics.gmCellIncY / scaled_font->em_square;
     }
 
+    _cairo_scaled_glyph_set_metrics (scaled_glyph,
+				     &scaled_font->base,
+				     &extents);
+
     return CAIRO_STATUS_SUCCESS;
 }
 
-
+/* Not currently used code, but may be useful in the future if we add
+ * back the capability to the scaled font backend interface to get the
+ * actual device space bbox rather than computing it from the
+ * font-space metrics.
+ */
+#if 0
 static cairo_status_t 
 _cairo_win32_scaled_font_glyph_bbox (void		 *abstract_font,
 				     const cairo_glyph_t *glyphs,
@@ -824,6 +856,7 @@
 
     return CAIRO_STATUS_SUCCESS;
 }
+#endif
 
 typedef struct {
     cairo_win32_scaled_font_t *scaled_font;
@@ -1027,7 +1060,35 @@
     return &image8->base;
 }
 
-static cairo_status_t 
+
+static cairo_status_t
+_cairo_win32_scaled_font_glyph_init (void		       *abstract_font,
+				     cairo_scaled_glyph_t      *scaled_glyph,
+				     cairo_scaled_glyph_info_t  info)
+{
+    cairo_win32_scaled_font_t *scaled_font = abstract_font;
+    cairo_status_t status;
+
+    if ((info & CAIRO_SCALED_GLYPH_INFO_METRICS) != 0) {
+	status = _cairo_win32_scaled_font_init_glyph_metrics (scaled_font, scaled_glyph);
+	if (status)
+	    return status;
+    }
+
+    if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {
+	ASSERT_NOT_REACHED;
+    }
+
+    if ((info & CAIRO_SCALED_GLYPH_INFO_PATH) != 0) {
+	status = _cairo_win32_scaled_font_init_glyph_path (scaled_font, scaled_glyph);
+	if (status)
+	    return status;
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t 
 _cairo_win32_scaled_font_show_glyphs (void		       *abstract_font,
 				      cairo_operator_t    	operator,
 				      cairo_pattern_t          *pattern,
@@ -1148,141 +1209,137 @@
 }
 
 static cairo_status_t 
-_cairo_win32_scaled_font_glyph_path (void               *abstract_font,
-                                     cairo_glyph_t      *glyphs, 
-                                     int                 num_glyphs,
-                                     cairo_path_fixed_t *path)
+_cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font,
+					  cairo_scaled_glyph_t      *scaled_glyph)
 {
     static const MAT2 matrix = { { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, -1 } };
-    cairo_win32_scaled_font_t *scaled_font = abstract_font;
     cairo_status_t status;
     GLYPHMETRICS metrics;
     HDC hdc;
-    int i;
+    DWORD bytesGlyph;
+    unsigned char *buffer, *ptr;
+    cairo_path_fixed_t *path;
 
     hdc = _get_global_font_dc ();
     if (!hdc)
         return CAIRO_STATUS_NO_MEMORY;
 
+    path = _cairo_path_fixed_create ();
+    if (!path)
+	return CAIRO_STATUS_NO_MEMORY;
+
     status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);
     if (status)
-        return status;
-
-    for (i = 0; i < num_glyphs; i++)
-    {
-        DWORD bytesGlyph;
-        unsigned char *buffer, *ptr;
-
-        cairo_fixed_t x = _cairo_fixed_from_double (glyphs[i].x);
-        cairo_fixed_t y = _cairo_fixed_from_double (glyphs[i].y);
-
-        bytesGlyph = GetGlyphOutlineW (hdc, glyphs[i].index,
-                                       GGO_NATIVE | GGO_GLYPH_INDEX,
-                                       &metrics, 0, NULL, &matrix);
-
-        if (bytesGlyph == GDI_ERROR) {
-            status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_glyph_path");
-            goto FAIL;
-        }
-
-        ptr = buffer = malloc (bytesGlyph);
-
-        if (!buffer) {
-            status = CAIRO_STATUS_NO_MEMORY;
-            goto FAIL;
-        }
-
-        if (GetGlyphOutlineW (hdc, glyphs[i].index,
-                              GGO_NATIVE | GGO_GLYPH_INDEX,
-                              &metrics, bytesGlyph, buffer, &matrix) == GDI_ERROR) {
-            status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_glyph_path");
-            free (buffer);
-            goto FAIL;
-        }
-        
-        while (ptr < buffer + bytesGlyph) {
-            TTPOLYGONHEADER *header = (TTPOLYGONHEADER *)ptr;
-            unsigned char *endPoly = ptr + header->cb;
-
-            ptr += sizeof (TTPOLYGONHEADER);
-
-            _cairo_path_fixed_move_to (path,
-                                       _cairo_fixed_from_FIXED (header->pfxStart.x) + x,
-                                       _cairo_fixed_from_FIXED (header->pfxStart.y) + y);
-
-            while (ptr < endPoly) {
-                TTPOLYCURVE *curve = (TTPOLYCURVE *)ptr;
-                POINTFX *points = curve->apfx;
-                int i;
-                switch (curve->wType) {
-                case TT_PRIM_LINE:
-                    for (i = 0; i < curve->cpfx; i++) {
-                        _cairo_path_fixed_line_to (path,
-                                                   _cairo_fixed_from_FIXED (points[i].x) + x,
-                                                   _cairo_fixed_from_FIXED (points[i].y) + y);
-                    }
-                    break;
-                case TT_PRIM_QSPLINE:
-                    for (i = 0; i < curve->cpfx - 1; i++) {
-                        cairo_fixed_t p1x, p1y, p2x, p2y, cx, cy, c1x, c1y, c2x, c2y;
-                        _cairo_path_fixed_get_current_point (path, &p1x, &p1y);
-                        cx = _cairo_fixed_from_FIXED (points[i].x) + x;
-                        cy = _cairo_fixed_from_FIXED (points[i].y) + y;
+        goto CLEANUP_PATH;
+    
+    bytesGlyph = GetGlyphOutlineW (hdc, _cairo_scaled_glyph_index (scaled_glyph),
+				   GGO_NATIVE | GGO_GLYPH_INDEX,
+				   &metrics, 0, NULL, &matrix);
+    
+    if (bytesGlyph == GDI_ERROR) {
+	status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_glyph_path");
+	goto CLEANUP_FONT;
+    }
 
-                        if (i + 1 == curve->cpfx - 1) {
-                            p2x = _cairo_fixed_from_FIXED (points[i + 1].x) + x;
-                            p2y = _cairo_fixed_from_FIXED (points[i + 1].y) + y;
-                        } else {
-                            /* records with more than one curve use interpolation for
-                               control points, per http://support.microsoft.com/kb/q87115/ */
-                            p2x = (cx + _cairo_fixed_from_FIXED (points[i + 1].x) + x) / 2;
-                            p2y = (cy + _cairo_fixed_from_FIXED (points[i + 1].y) + y) / 2;
-                        }
+    ptr = buffer = malloc (bytesGlyph);
+    
+    if (!buffer) {
+	status = CAIRO_STATUS_NO_MEMORY;
+	goto CLEANUP_FONT;
+    }
 
-                        c1x = 2 * cx / 3 + p1x / 3;
-                        c1y = 2 * cy / 3 + p1y / 3;
-                        c2x = 2 * cx / 3 + p2x / 3;
-                        c2y = 2 * cy / 3 + p2y / 3;
+    if (GetGlyphOutlineW (hdc, _cairo_scaled_glyph_index (scaled_glyph),
+			  GGO_NATIVE | GGO_GLYPH_INDEX,
+			  &metrics, bytesGlyph, buffer, &matrix) == GDI_ERROR) {
+	status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_glyph_path");
+	free (buffer);
+	goto CLEANUP_FONT;
+    }
+    
+    while (ptr < buffer + bytesGlyph) {
+	TTPOLYGONHEADER *header = (TTPOLYGONHEADER *)ptr;
+	unsigned char *endPoly = ptr + header->cb;
+	
+	ptr += sizeof (TTPOLYGONHEADER);
+	
+	_cairo_path_fixed_move_to (path,
+				   _cairo_fixed_from_FIXED (header->pfxStart.x),
+				   _cairo_fixed_from_FIXED (header->pfxStart.y));
 
-                        _cairo_path_fixed_curve_to (path, c1x, c1y, c2x, c2y, p2x, p2y);
-                    }
-                    break;
-                case TT_PRIM_CSPLINE:
-                    for (i = 0; i < curve->cpfx - 2; i += 2) {
-                        _cairo_path_fixed_curve_to (path,
-                                                    _cairo_fixed_from_FIXED (points[i].x) + x,
-                                                    _cairo_fixed_from_FIXED (points[i].y) + y,
-                                                    _cairo_fixed_from_FIXED (points[i + 1].x) + x,
-                                                    _cairo_fixed_from_FIXED (points[i + 1].y) + y,
-                                                    _cairo_fixed_from_FIXED (points[i + 2].x) + x,
-                                                    _cairo_fixed_from_FIXED (points[i + 2].y) + y);
-                    }
-                    break;
-                }
-                ptr += sizeof(TTPOLYCURVE) + sizeof (POINTFX) * (curve->cpfx - 1);
-            }
-            _cairo_path_fixed_close_path (path);
-        }
-        free(buffer);
+	while (ptr < endPoly) {
+	    TTPOLYCURVE *curve = (TTPOLYCURVE *)ptr;
+	    POINTFX *points = curve->apfx;
+	    int i;
+	    switch (curve->wType) {
+	    case TT_PRIM_LINE:
+		for (i = 0; i < curve->cpfx; i++) {
+		    _cairo_path_fixed_line_to (path,
+					       _cairo_fixed_from_FIXED (points[i].x),
+					       _cairo_fixed_from_FIXED (points[i].y));
+		}
+		break;
+	    case TT_PRIM_QSPLINE:
+		for (i = 0; i < curve->cpfx - 1; i++) {
+		    cairo_fixed_t p1x, p1y, p2x, p2y, cx, cy, c1x, c1y, c2x, c2y;
+		    _cairo_path_fixed_get_current_point (path, &p1x, &p1y);
+		    cx = _cairo_fixed_from_FIXED (points[i].x);
+		    cy = _cairo_fixed_from_FIXED (points[i].y);
+		    
+		    if (i + 1 == curve->cpfx - 1) {
+			p2x = _cairo_fixed_from_FIXED (points[i + 1].x);
+			p2y = _cairo_fixed_from_FIXED (points[i + 1].y);
+		    } else {
+			/* records with more than one curve use interpolation for
+			   control points, per http://support.microsoft.com/kb/q87115/ */
+			p2x = (cx + _cairo_fixed_from_FIXED (points[i + 1].x)) / 2;
+			p2y = (cy + _cairo_fixed_from_FIXED (points[i + 1].y)) / 2;
+		    }
+		    
+		    c1x = 2 * cx / 3 + p1x / 3;
+		    c1y = 2 * cy / 3 + p1y / 3;
+		    c2x = 2 * cx / 3 + p2x / 3;
+		    c2y = 2 * cy / 3 + p2y / 3;
+		    
+		    _cairo_path_fixed_curve_to (path, c1x, c1y, c2x, c2y, p2x, p2y);
+		}
+		break;
+	    case TT_PRIM_CSPLINE:
+		for (i = 0; i < curve->cpfx - 2; i += 2) {
+		    _cairo_path_fixed_curve_to (path,
+						_cairo_fixed_from_FIXED (points[i].x),
+						_cairo_fixed_from_FIXED (points[i].y),
+						_cairo_fixed_from_FIXED (points[i + 1].x),
+						_cairo_fixed_from_FIXED (points[i + 1].y),
+						_cairo_fixed_from_FIXED (points[i + 2].x),
+						_cairo_fixed_from_FIXED (points[i + 2].y));
+		}
+		break;
+	    }
+	    ptr += sizeof(TTPOLYCURVE) + sizeof (POINTFX) * (curve->cpfx - 1);
+	}
+	_cairo_path_fixed_close_path (path);
     }
+    free(buffer);
 
-FAIL:
+CLEANUP_FONT:
 
     cairo_win32_scaled_font_done_font (&scaled_font->base);
 
+ CLEANUP_PATH:
+
+    if (status != CAIRO_STATUS_SUCCESS)
+	_cairo_path_fixed_destroy (path);
+
     return status;
 }
 
 const cairo_scaled_font_backend_t cairo_win32_scaled_font_backend = {
     _cairo_win32_scaled_font_create_toy,
     _cairo_win32_scaled_font_fini,
-    _cairo_win32_scaled_font_font_extents,
+    _cairo_win32_scaled_font_glyph_init,
     _cairo_win32_scaled_font_text_to_glyphs,
-    _cairo_win32_scaled_font_glyph_extents,
-    _cairo_win32_scaled_font_glyph_bbox,
+    NULL,			/* ucs4_to_index */
     _cairo_win32_scaled_font_show_glyphs,
-    _cairo_win32_scaled_font_glyph_path,
-    _cairo_win32_scaled_font_get_glyph_cache_key
 };
 
 /* cairo_win32_font_face_t */
@@ -1311,7 +1368,7 @@
     cairo_win32_font_face_t *font_face = abstract_face;
 
     *font = _win32_scaled_font_create (&font_face->logfont,
-				       font_face,
+				       &font_face->base,
 				       font_matrix, ctm, options);
     if (*font)
 	return CAIRO_STATUS_SUCCESS;

Index: cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.208
retrieving revision 1.209
diff -u -d -r1.208 -r1.209
--- cairoint.h	31 Aug 2005 22:08:02 -0000	1.208
+++ cairoint.h	1 Sep 2005 02:11:22 -0000	1.209
@@ -480,6 +480,18 @@
 				 cairo_scaled_glyph_t	     *scaled_glyph,
 				 cairo_scaled_glyph_info_t    info);
 
+    /* A backend only needs to implement this or ucs4_to_index(), not
+     * both. This allows the backend to do something more sophisticated
+     * then just converting characters one by one.
+     */
+    cairo_int_status_t
+    (*text_to_glyphs) (void                *scaled_font,
+		       double		    x,
+		       double		    y,
+		       const char          *utf8, 
+		       cairo_glyph_t      **glyphs, 
+		       int 		   *num_glyphs);
+    
     unsigned long
     (*ucs4_to_index)		(void			     *scaled_font,
 				 uint32_t		      ucs4);



More information about the cairo-commit mailing list