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:
Carl Worth 2005-08-31 19:11:22 +00:00
parent f25ebec368
commit 0f4beab507
8 changed files with 277 additions and 178 deletions

View file

@ -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)

View file

@ -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,
};

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -35,7 +35,9 @@
#endif
#include <errno.h>
#include <string.h>
#if HAVE_FCFINI
#include <fontconfig/fontconfig.h>
#endif
#include "cairo-test.h"

View file

@ -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;

View file

@ -24,7 +24,7 @@
*/
#include "cairo-test.h"
#include <cairo-ft.h>
#include <stddef.h>
/* Test to verify fixes for the following similar bugs:
*