[cairo-commit] src/cairo-win32-font.c

Kristian Høgsberg krh at kemper.freedesktop.org
Mon Aug 21 09:53:58 PDT 2006


 src/cairo-win32-font.c |   88 ++++++++++++++++++++++++++++++++++---------------
 1 files changed, 62 insertions(+), 26 deletions(-)

New commits:
diff-tree 782e3eb65b143a6e658eda69ba15da3ac432c711 (from 6de226be0e879709c4068cb7836d485e75928287)
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Mon Aug 21 12:52:56 2006 -0400

    Get correct unhinted outlines on win32.
    
    The documentation for GetGlyphOutline() states that outline returned is grid
    fitted and if an application requires an unmodified outline it can request an
    outline for a font whose size is equal to the font's em unit.
    
    This seems to suggest that the solution to this bug would be to obtain the
    unmodified outline data and scale it to the required size.
    
    https://bugs.freedesktop.org/show_bug.cgi?id=7603

diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c
index 95a44e1..62c0f46 100644
--- a/src/cairo-win32-font.c
+++ b/src/cairo-win32-font.c
@@ -755,7 +755,7 @@ _cairo_win32_scaled_font_init_glyph_metr
     else
         glyph_index_option = 0;
 
-    if (scaled_font->preserve_axes) {
+    if (scaled_font->preserve_axes && scaled_font->base.options.hint_style != CAIRO_HINT_METRICS_OFF) {
 	/* If we aren't rotating / skewing the axes, then we get the metrics
 	 * from the GDI in device space and convert to font space.
 	 */
@@ -1107,7 +1107,7 @@ _compute_a8_mask (cairo_win32_surface_t 
     return &image8->base;
 }
 
-static cairo_status_t
+static cairo_int_status_t
 _cairo_win32_scaled_font_glyph_init (void		       *abstract_font,
 				     cairo_scaled_glyph_t      *scaled_glyph,
 				     cairo_scaled_glyph_info_t  info)
@@ -1275,10 +1275,18 @@ _cairo_win32_scaled_font_load_truetype_t
     return status;
 }
 
-static cairo_fixed_t
-_cairo_fixed_from_FIXED (FIXED f)
-{
-    return *((cairo_fixed_t *)&f);
+static void
+_cairo_win32_transform_FIXED_to_fixed (cairo_matrix_t *matrix,
+                                       FIXED Fx, FIXED Fy,
+                                       cairo_fixed_t *fx, cairo_fixed_t *fy)
+{
+    double x, y;
+
+    x = _cairo_fixed_to_double (*((cairo_fixed_t *)&Fx));
+    y = _cairo_fixed_to_double (*((cairo_fixed_t *)&Fy));
+    cairo_matrix_transform_point (matrix, &x, &y);
+    *fx =  _cairo_fixed_from_double (x);
+    *fy =  _cairo_fixed_from_double (y);
 }
 
 static cairo_status_t
@@ -1292,6 +1300,8 @@ _cairo_win32_scaled_font_init_glyph_path
     DWORD bytesGlyph;
     unsigned char *buffer, *ptr;
     cairo_path_fixed_t *path;
+    cairo_matrix_t transform;
+    cairo_fixed_t x, y;
     UINT glyph_index_option;
 
     hdc = _get_global_font_dc ();
@@ -1302,7 +1312,14 @@ _cairo_win32_scaled_font_init_glyph_path
     if (!path)
 	return CAIRO_STATUS_NO_MEMORY;
 
-    status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);
+    if (scaled_font->base.options.hint_style == CAIRO_HINT_STYLE_NONE) {
+        status = _cairo_win32_scaled_font_select_unscaled_font (&scaled_font->base, hdc);
+        transform = scaled_font->base.scale;
+        cairo_matrix_scale (&transform, 1.0/scaled_font->em_square, 1.0/scaled_font->em_square);
+    } else {
+        status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);
+        cairo_matrix_init_identity(&transform);
+    }
     if (status)
         goto CLEANUP_PATH;
 
@@ -1341,9 +1358,11 @@ _cairo_win32_scaled_font_init_glyph_path
 
 	ptr += sizeof (TTPOLYGONHEADER);
 
-	_cairo_path_fixed_move_to (path,
-				   _cairo_fixed_from_FIXED (header->pfxStart.x),
-				   _cairo_fixed_from_FIXED (header->pfxStart.y));
+        _cairo_win32_transform_FIXED_to_fixed (&transform,
+                                               header->pfxStart.x,
+                                               header->pfxStart.y,
+                                               &x, &y);
+        _cairo_path_fixed_move_to (path, x, y);
 
 	while (ptr < endPoly) {
 	    TTPOLYCURVE *curve = (TTPOLYCURVE *)ptr;
@@ -1352,26 +1371,36 @@ _cairo_win32_scaled_font_init_glyph_path
 	    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));
+                    _cairo_win32_transform_FIXED_to_fixed (&transform,
+                                                           points[i].x,
+                                                           points[i].y,
+                                                           &x, &y);
+		    _cairo_path_fixed_line_to (path, x, 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);
+                    _cairo_win32_transform_FIXED_to_fixed (&transform,
+                                                           points[i].x,
+                                                           points[i].y,
+                                                           &cx, &cy);
 
 		    if (i + 1 == curve->cpfx - 1) {
-			p2x = _cairo_fixed_from_FIXED (points[i + 1].x);
-			p2y = _cairo_fixed_from_FIXED (points[i + 1].y);
+                        _cairo_win32_transform_FIXED_to_fixed (&transform,
+                                                               points[i + 1].x,
+                                                               points[i + 1].y,
+                                                               &p2x, &p2y);
 		    } 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;
+                        _cairo_win32_transform_FIXED_to_fixed (&transform,
+                                                               points[i + 1].x,
+                                                               points[i + 1].y,
+                                                               &x, &y);
+                        p2x = (cx + x) / 2;
+			p2y = (cy + y) / 2;
 		    }
 
 		    c1x = 2 * cx / 3 + p1x / 3;
@@ -1384,13 +1413,20 @@ _cairo_win32_scaled_font_init_glyph_path
 		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));
+		    cairo_fixed_t x1, y1, x2, y2;
+                    _cairo_win32_transform_FIXED_to_fixed (&transform,
+                                                           points[i].x,
+                                                           points[i].y,
+                                                           &x, &y);
+                    _cairo_win32_transform_FIXED_to_fixed (&transform,
+                                                           points[i + 1].x,
+                                                           points[i + 1].y,
+                                                           &x1, &y1);
+                    _cairo_win32_transform_FIXED_to_fixed (&transform,
+                                                           points[i + 2].x,
+                                                           points[i + 2].y,
+                                                           &x2, &y2);
+		    _cairo_path_fixed_curve_to (path, x, y, x1, y1, x2, y2);
 		}
 		break;
 	    }


More information about the cairo-commit mailing list