[cairo-commit] cairo/src cairo-ft-font.c, 1.111,
1.112 cairo-scaled-font.c, 1.1, 1.2 cairo-win32-font.c, 1.39,
1.40 cairoint.h, 1.208, 1.209
Owen Taylor
commit at pdx.freedesktop.org
Wed Aug 31 19:11:25 PDT 2005
Committed by: otaylor
Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv2034/src
Modified Files:
cairo-ft-font.c cairo-scaled-font.c cairo-win32-font.c
cairoint.h
Log Message:
2005-08-31 Carl Worth <cworth at cworth.org>
* test/cairo-test.c: (create_xlib_surface): Add call to
XSynchronize, (the expected clip-all failure isn't occuring
without it for some reason).
* test/clip-all.c: (main): Note reason for expected failure.
2005-08-31 Owen Taylor <otaylor at 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.
Index: cairo-ft-font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-ft-font.c,v
retrieving revision 1.111
retrieving revision 1.112
diff -u -d -r1.111 -r1.112
--- cairo-ft-font.c 31 Aug 2005 22:08:02 -0000 1.111
+++ cairo-ft-font.c 1 Sep 2005 02:11:22 -0000 1.112
@@ -1907,6 +1907,7 @@
_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,
};
Index: cairo-scaled-font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-scaled-font.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- cairo-scaled-font.c 31 Aug 2005 22:08:02 -0000 1.1
+++ cairo-scaled-font.c 1 Sep 2005 02:11:22 -0000 1.2
@@ -659,6 +659,14 @@
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;
Index: cairo-win32-font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-win32-font.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -d -r1.39 -r1.40
--- cairo-win32-font.c 19 Aug 2005 19:08:42 -0000 1.39
+++ cairo-win32-font.c 1 Sep 2005 02:11:22 -0000 1.40
@@ -101,6 +101,17 @@
} 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 @@
{
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 @@
else
f->quality = ANTIALIASED_QUALITY;
break;
+ case CAIRO_ANTIALIAS_DEFAULT:
+ ASSERT_NOT_REACHED;
}
}
@@ -266,6 +280,12 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
* 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 @@
return CAIRO_STATUS_SUCCESS;
}
+#endif
typedef struct {
cairo_win32_scaled_font_t *scaled_font;
@@ -1027,7 +1060,35 @@
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 @@
}
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;
+ 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;
+ }
- 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;
- }
+ ptr = buffer = malloc (bytesGlyph);
+
+ if (!buffer) {
+ status = CAIRO_STATUS_NO_MEMORY;
+ goto CLEANUP_FONT;
+ }
- c1x = 2 * cx / 3 + p1x / 3;
- c1y = 2 * cy / 3 + p1y / 3;
- c2x = 2 * cx / 3 + p2x / 3;
- c2y = 2 * cy / 3 + p2y / 3;
+ 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));
- _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);
+ 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);
-FAIL:
+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_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;
Index: cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.208
retrieving revision 1.209
diff -u -d -r1.208 -r1.209
--- cairoint.h 31 Aug 2005 22:08:02 -0000 1.208
+++ cairoint.h 1 Sep 2005 02:11:22 -0000 1.209
@@ -480,6 +480,18 @@
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);
More information about the cairo-commit
mailing list