mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-08 17:18:42 +02:00
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
This commit is contained in:
parent
6de226be0e
commit
782e3eb65b
1 changed files with 61 additions and 25 deletions
|
|
@ -755,7 +755,7 @@ _cairo_win32_scaled_font_init_glyph_metrics (cairo_win32_scaled_font_t *scaled_f
|
|||
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 *mask_surface)
|
|||
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_table (void *abstract_font,
|
|||
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 (cairo_win32_scaled_font_t *scaled_font
|
|||
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 (cairo_win32_scaled_font_t *scaled_font
|
|||
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 (cairo_win32_scaled_font_t *scaled_font
|
|||
|
||||
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 (cairo_win32_scaled_font_t *scaled_font
|
|||
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 (cairo_win32_scaled_font_t *scaled_font
|
|||
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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue