diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c index 95a44e1..62c0f46 --- 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) +static void +_cairo_win32_transform_FIXED_to_fixed (cairo_matrix_t *matrix, + FIXED Fx, FIXED Fy, + cairo_fixed_t *fx, cairo_fixed_t *fy) { - return *((cairo_fixed_t *)&f); + 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; }