mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-04 11:47:59 +02:00
Add call to XSynchronize, (the expected clip-all failure isn't occuring without it for some reason).
Note reason for expected failure. src/cairo-scaled-font.c: Add an optional text_to_glyphs() virtual function that the backend can implement instead of ucs4_to_index(). Protect inclusion of fontconfig.h with HAVE_FCFINI.
This commit is contained in:
parent
f25ebec368
commit
0f4beab507
8 changed files with 277 additions and 178 deletions
19
ChangeLog
19
ChangeLog
|
|
@ -6,6 +6,25 @@
|
|||
|
||||
* test/clip-all.c: (main): Note reason for expected failure.
|
||||
|
||||
2005-08-31 Owen Taylor <otaylor@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.
|
||||
|
||||
* test/nil-surface.c: Remove stray cairo-ft.h include.
|
||||
|
||||
* test/nil-surface.c: Include stddef.h for NULL.
|
||||
|
||||
* test/create-from-png-stream.c (draw): Open the file "rb".
|
||||
|
||||
* src/cairo-win32-font.c (_win32_scaled_font_create): Add
|
||||
a CAIRO_ANTIALIAS_DEFAULT:
|
||||
|
||||
2005-08-31 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* src/cairo-xlib-surface.c (_get_image_surface)
|
||||
|
|
|
|||
|
|
@ -1907,6 +1907,7 @@ const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend = {
|
|||
_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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: cairo-scaled-font.c,v 1.1 2005-08-31 22:08:02 keithp Exp $
|
||||
/* $Id: cairo-scaled-font.c,v 1.2 2005-09-01 02:11:22 otaylor Exp $
|
||||
*
|
||||
* Copyright © 2005 Keith Packard
|
||||
*
|
||||
|
|
@ -659,6 +659,14 @@ _cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -101,6 +101,17 @@ typedef struct {
|
|||
|
||||
} 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 @@ _win32_scaled_font_create (LOGFONTW *logfont,
|
|||
{
|
||||
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 @@ _win32_scaled_font_create (LOGFONTW *logfont,
|
|||
else
|
||||
f->quality = ANTIALIASED_QUALITY;
|
||||
break;
|
||||
case CAIRO_ANTIALIAS_DEFAULT:
|
||||
ASSERT_NOT_REACHED;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -266,6 +280,12 @@ _win32_scaled_font_create (LOGFONTW *logfont,
|
|||
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 @@ _cairo_win32_scaled_font_create_toy (cairo_toy_font_face_t *toy_face,
|
|||
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 @@ _cairo_win32_scaled_font_fini (void *abstract_font)
|
|||
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 @@ _cairo_win32_scaled_font_text_to_glyphs (void *abstract_font,
|
|||
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 @@ _cairo_win32_scaled_font_text_to_glyphs (void *abstract_font,
|
|||
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 @@ _cairo_win32_scaled_font_text_to_glyphs (void *abstract_font,
|
|||
}
|
||||
|
||||
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 @@ _cairo_win32_scaled_font_font_extents (void *abstract_font,
|
|||
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 @@ _cairo_win32_scaled_font_font_extents (void *abstract_font,
|
|||
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 @@ _cairo_win32_scaled_font_glyph_extents (void *abstract_font,
|
|||
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 @@ _cairo_win32_scaled_font_glyph_extents (void *abstract_font,
|
|||
* 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 @@ _cairo_win32_scaled_font_glyph_bbox (void *abstract_font,
|
|||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
cairo_win32_scaled_font_t *scaled_font;
|
||||
|
|
@ -1027,7 +1060,35 @@ _compute_a8_mask (cairo_win32_surface_t *mask_surface)
|
|||
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 @@ _cairo_fixed_from_FIXED (FIXED f)
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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) + 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);
|
||||
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;
|
||||
}
|
||||
|
||||
FAIL:
|
||||
ptr = buffer = malloc (bytesGlyph);
|
||||
|
||||
if (!buffer) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto CLEANUP_FONT;
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
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);
|
||||
|
||||
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_scaled_font_create (void *abstract_face,
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -480,6 +480,18 @@ struct _cairo_scaled_font_backend {
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -35,7 +35,9 @@
|
|||
#endif
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#if HAVE_FCFINI
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#endif
|
||||
|
||||
#include "cairo-test.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@
|
|||
#define HEIGHT 2
|
||||
|
||||
cairo_test_t test = {
|
||||
"create-from-png",
|
||||
"Tests the creation of an image surface from a PNG file",
|
||||
"create-from-png-stream",
|
||||
"Tests the creation of an image surface from a PNG using a FILE *",
|
||||
WIDTH, HEIGHT
|
||||
};
|
||||
|
||||
|
|
@ -61,7 +61,7 @@ draw (cairo_t *cr, int width, int height)
|
|||
xasprintf (&filename, "%s/%s", srcdir ? srcdir : ".",
|
||||
"create-from-png-stream-ref.png");
|
||||
|
||||
file = fopen (filename, "r");
|
||||
file = fopen (filename, "rb");
|
||||
if (file == NULL) {
|
||||
cairo_test_log ("Error: failed to open file: %s\n", filename);
|
||||
return CAIRO_TEST_FAILURE;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
*/
|
||||
|
||||
#include "cairo-test.h"
|
||||
#include <cairo-ft.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* Test to verify fixes for the following similar bugs:
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue