[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