[cairo-commit] 3 commits - src/cairo-atsui-font.c src/cairo-clip.c src/cairo-ft-font.c src/cairoint.h src/cairo-matrix.c src/cairo-scaled-font.c src/cairo-win32-font.c test/font-matrix-translation.c
Carl Worth
cworth at kemper.freedesktop.org
Tue Jan 29 09:12:10 PST 2008
src/cairo-atsui-font.c | 56 ++++++++++++++++++++++++++++++-----------
src/cairo-clip.c | 34 +++++++++++++++++++++++-
src/cairo-ft-font.c | 20 ++++++++++----
src/cairo-matrix.c | 7 +++--
src/cairo-scaled-font.c | 13 ++++++---
src/cairo-win32-font.c | 20 ++++++++------
src/cairoint.h | 4 +-
test/font-matrix-translation.c | 2 -
8 files changed, 116 insertions(+), 40 deletions(-)
New commits:
commit 3b0adf4f5ac78e3f19b4e19267da2aa1b3c7d57b
Author: Jeff Muizelaar <jeff at infidigm.net>
Date: Tue Jan 29 09:07:54 2008 -0800
Use ADD instead of IN for clipping.
ADD is already special-cased by pixman, so using it instead avoids hitting
the slower general path.
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index ae30515..fd9f3a8 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -451,11 +451,41 @@ _cairo_clip_intersect_mask (cairo_clip_t *clip,
_cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE,
CAIRO_CONTENT_COLOR);
+ /* The clipping operation should ideally be something like the following to
+ * avoid having to do as many passes over the data
+
+ if (clip->surface != NULL) {
+ _cairo_pattern_init_for_surface (&pattern.surface, clip->surface);
+ } else {
+ _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE,
+ CAIRO_CONTENT_COLOR);
+ }
+ status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_IN,
+ &pattern.base,
+ surface,
+ antialias,
+ 0, 0,
+ 0, 0,
+ surface_rect.width,
+ surface_rect.height,
+ traps->traps,
+ traps->num_traps);
+
+ However this operation is not accelerated by pixman
+
+ I believe the best possible operation would probably an unbounded SRC
+ operator. Using SRC we could potentially avoid having to initialize
+ the surface which would be ideal from an efficiency point of view.
+ However, _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_SOURCE) is
+ bounded by the mask.
+
+ */
+
surface = _cairo_surface_create_similar_solid (target,
CAIRO_CONTENT_ALPHA,
surface_rect.width,
surface_rect.height,
- CAIRO_COLOR_WHITE,
+ CAIRO_COLOR_TRANSPARENT,
&pattern.base);
if (surface->status) {
_cairo_pattern_fini (&pattern.base);
@@ -466,7 +496,7 @@ _cairo_clip_intersect_mask (cairo_clip_t *clip,
_cairo_traps_translate (traps, -surface_rect.x, -surface_rect.y);
- status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_IN,
+ status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_ADD,
&pattern.base,
surface,
antialias,
commit fa6aedf2d68941bf8532bf487d5412cfc508e0a9
Author: Carl Worth <cworth at cworth.org>
Date: Tue Jan 29 09:01:47 2008 -0800
Fix typo in printf arguments in error message
diff --git a/test/font-matrix-translation.c b/test/font-matrix-translation.c
index 5e780cb..06b407d 100644
--- a/test/font-matrix-translation.c
+++ b/test/font-matrix-translation.c
@@ -65,7 +65,7 @@ box_text (cairo_t *cr, const char *utf8, double x, double y)
cairo_scaled_font_text_extents (scaled_font, TEXT, &scaled_extents);
if (! text_extents_equal (&extents, &scaled_extents)) {
cairo_test_log ("Error: extents differ when they shouldn't:\n"
- "cairo_text_extents(); extents (%g, %g, %g, %g, %g, %g)\n",
+ "cairo_text_extents(); extents (%g, %g, %g, %g, %g, %g)\n"
"cairo_scaled_font_text_extents(); extents (%g, %g, %g, %g, %g, %g)\n",
extents.x_bearing, extents.y_bearing,
extents.width, extents.height,
commit e2bb36fe08546e6461fcbd40f5f3f81e5efc7686
Author: Carl Worth <cworth at cworth.org>
Date: Tue Jan 29 08:41:21 2008 -0800
wAdd proper error propagation to _cairo_matrix_compute_scale_factors
Before there was just an assert statement here that the
determinant of the matrix was not infinite. That was bogus
since a user-provided can end up here. So instead, do the
correct error propagation of any CAIRO_STATUS_INVALID_MATRIX
error as necessary.
This eliminates the current failure of the invalid-matrix
test case.
diff --git a/src/cairo-atsui-font.c b/src/cairo-atsui-font.c
index d4c1f64..55629c5 100644
--- a/src/cairo-atsui-font.c
+++ b/src/cairo-atsui-font.c
@@ -208,6 +208,7 @@ CreateSizedCopyOfStyle(ATSUStyle inStyle,
static cairo_status_t
_cairo_atsui_font_set_metrics (cairo_atsui_font_t *font)
{
+ cairo_status_t status;
ATSFontRef atsFont;
ATSFontMetrics metrics;
OSStatus err;
@@ -228,9 +229,9 @@ _cairo_atsui_font_set_metrics (cairo_atsui_font_t *font)
/* The FT backend doesn't handle max_y_advance either, so we'll ignore it for now. */
extents.max_y_advance = 0.0;
- _cairo_scaled_font_set_metrics (&font->base, &extents);
+ status = _cairo_scaled_font_set_metrics (&font->base, &extents);
- return CAIRO_STATUS_SUCCESS;
+ return status;
}
}
@@ -264,8 +265,11 @@ _cairo_atsui_font_create_scaled (cairo_font_face_t *font_face,
return status;
}
- _cairo_matrix_compute_scale_factors (&font->base.scale,
- &xscale, &yscale, 1);
+ status = _cairo_matrix_compute_scale_factors (&font->base.scale,
+ &xscale, &yscale, 1);
+ if (status)
+ goto FAIL;
+
font->font_matrix = CGAffineTransformMake (1., 0.,
0., yscale/xscale,
0., 0.);
@@ -466,6 +470,7 @@ static cairo_status_t
_cairo_atsui_font_init_glyph_metrics (cairo_atsui_font_t *scaled_font,
cairo_scaled_glyph_t *scaled_glyph)
{
+ cairo_status_t status;
cairo_text_extents_t extents = {0, 0, 0, 0, 0, 0};
OSStatus err;
ATSGlyphScreenMetrics metricsH;
@@ -489,8 +494,11 @@ _cairo_atsui_font_init_glyph_metrics (cairo_atsui_font_t *scaled_font,
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
/* Scale down to font units.*/
- _cairo_matrix_compute_scale_factors (&scaled_font->base.scale,
- &xscale, &yscale, 1);
+ status = _cairo_matrix_compute_scale_factors (&scaled_font->base.scale,
+ &xscale, &yscale, 1);
+ if (status)
+ return status;
+
xscale = 1.0/xscale;
yscale = 1.0/yscale;
@@ -601,6 +609,7 @@ static cairo_status_t
_cairo_atsui_scaled_font_init_glyph_path (cairo_atsui_font_t *scaled_font,
cairo_scaled_glyph_t *scaled_glyph)
{
+ cairo_status_t status;
static ATSCubicMoveToUPP moveProc = NULL;
static ATSCubicLineToUPP lineProc = NULL;
static ATSCubicCurveToUPP curveProc = NULL;
@@ -625,7 +634,10 @@ _cairo_atsui_scaled_font_init_glyph_path (cairo_atsui_font_t *scaled_font,
}
/* extract the rotation/shear component of the scale matrix. */
- _cairo_matrix_compute_scale_factors (font_to_device, &xscale, &yscale, 1);
+ status = _cairo_matrix_compute_scale_factors (font_to_device, &xscale, &yscale, 1);
+ if (status)
+ goto FAIL;
+
cairo_matrix_init (&unscaled_font_to_device,
font_to_device->xx,
font_to_device->yx,
@@ -649,14 +661,18 @@ _cairo_atsui_scaled_font_init_glyph_path (cairo_atsui_font_t *scaled_font,
curveProc,
closePathProc, (void *)&scaled_path, &err);
if (err != noErr) {
- _cairo_path_fixed_destroy (scaled_path.path);
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ goto FAIL;
}
_cairo_scaled_glyph_set_path (scaled_glyph, &scaled_font->base,
scaled_path.path);
return CAIRO_STATUS_SUCCESS;
+
+ FAIL:
+ _cairo_path_fixed_destroy (scaled_path.path);
+ return status;
}
static cairo_status_t
@@ -681,7 +697,6 @@ _cairo_atsui_scaled_font_init_glyph_surface (cairo_atsui_font_t *scaled_font,
CGRect bbox;
CGAffineTransform transform;
-
if (theGlyph == kATSDeletedGlyphcode) {
surface = (cairo_image_surface_t *)cairo_image_surface_create (CAIRO_FORMAT_A8, 2, 2);
status = cairo_surface_status ((cairo_surface_t *)surface);
@@ -701,8 +716,11 @@ _cairo_atsui_scaled_font_init_glyph_surface (cairo_atsui_font_t *scaled_font,
height = extents.ascent + extents.descent + 2.0;
bottom = -extents.descent - 1.0;
- _cairo_matrix_compute_scale_factors (&base.scale,
- &xscale, &yscale, 1);
+ status = _cairo_matrix_compute_scale_factors (&base.scale,
+ &xscale, &yscale, 1);
+ if (status)
+ return status;
+
bbox = CGRectApplyAffineTransform (CGRectMake (1.0, bottom, 1.0, height), CGAffineTransformMakeScale(xscale, yscale));
bottom = CGRectGetMinY (bbox);
height = bbox.size.height;
@@ -734,8 +752,11 @@ _cairo_atsui_scaled_font_init_glyph_surface (cairo_atsui_font_t *scaled_font,
-base.scale.xy,
base.scale.yy,
0., 0.);
- _cairo_matrix_compute_scale_factors (&base.scale,
- &xscale, &yscale, 1);
+ status = _cairo_matrix_compute_scale_factors (&base.scale,
+ &xscale, &yscale, 1);
+ if (status)
+ return status;
+
transform = CGAffineTransformScale (transform, 1.0/xscale, 1.0/yscale);
/* Rotate the bounding box. This computes the smallest CGRect
@@ -896,6 +917,11 @@ _cairo_atsui_font_text_to_glyphs (void *abstract_font,
goto BAIL2;
}
+ status = _cairo_matrix_compute_scale_factors (&font->base.ctm,
+ &xscale, &yscale, 1);
+ if (status)
+ goto BAIL2;
+
*num_glyphs = glyphCount - 1;
*glyphs =
(cairo_glyph_t *) _cairo_malloc_ab(*num_glyphs, sizeof (cairo_glyph_t));
@@ -903,7 +929,7 @@ _cairo_atsui_font_text_to_glyphs (void *abstract_font,
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto BAIL1;
}
- _cairo_matrix_compute_scale_factors (&font->base.ctm, &xscale, &yscale, 1);
+
device_to_user_scale =
CGAffineTransformInvert (CGAffineTransformMake (xscale, 0,
0, yscale,
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 00f3b91..a502813 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -589,10 +589,11 @@ _cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t *unscaled)
}
slim_hidden_def (cairo_ft_scaled_font_unlock_face);
-static void
+static cairo_status_t
_compute_transform (cairo_ft_font_transform_t *sf,
cairo_matrix_t *scale)
{
+ cairo_status_t status;
cairo_matrix_t normalized = *scale;
/* The font matrix has x and y "scale" components which we extract and
@@ -602,9 +603,11 @@ _compute_transform (cairo_ft_font_transform_t *sf,
* freetype's transformation.
*/
- _cairo_matrix_compute_scale_factors (&normalized,
- &sf->x_scale, &sf->y_scale,
- /* XXX */ 1);
+ status = _cairo_matrix_compute_scale_factors (&normalized,
+ &sf->x_scale, &sf->y_scale,
+ /* XXX */ 1);
+ if (status)
+ return status;
if (sf->x_scale != 0 && sf->y_scale != 0) {
cairo_matrix_scale (&normalized, 1.0 / sf->x_scale, 1.0 / sf->y_scale);
@@ -617,6 +620,8 @@ _compute_transform (cairo_ft_font_transform_t *sf,
sf->shape[0][0] = sf->shape[1][1] = 1.0;
sf->shape[0][1] = sf->shape[1][0] = 0.0;
}
+
+ return CAIRO_STATUS_SUCCESS;
}
/* Temporarily scales an unscaled font to the give scale. We catch
@@ -626,6 +631,7 @@ static cairo_status_t
_cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled,
cairo_matrix_t *scale)
{
+ cairo_status_t status;
cairo_ft_font_transform_t sf;
FT_Matrix mat;
FT_Error error;
@@ -642,7 +648,9 @@ _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled,
unscaled->have_scale = TRUE;
unscaled->current_scale = *scale;
- _compute_transform (&sf, scale);
+ status = _compute_transform (&sf, scale);
+ if (status)
+ return status;
unscaled->x_scale = sf.x_scale;
unscaled->y_scale = sf.y_scale;
@@ -1562,7 +1570,7 @@ _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t *unscaled,
}
}
- _cairo_scaled_font_set_metrics (&scaled_font->base, &fs_metrics);
+ status = _cairo_scaled_font_set_metrics (&scaled_font->base, &fs_metrics);
*font_out = &scaled_font->base;
diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c
index ebf448e..b86b1fd 100644
--- a/src/cairo-matrix.c
+++ b/src/cairo-matrix.c
@@ -514,7 +514,7 @@ _cairo_matrix_compute_determinant (const cairo_matrix_t *matrix,
}
/* Compute the amount that each basis vector is scaled by. */
-void
+cairo_status_t
_cairo_matrix_compute_scale_factors (const cairo_matrix_t *matrix,
double *sx, double *sy, int x_major)
{
@@ -522,7 +522,8 @@ _cairo_matrix_compute_scale_factors (const cairo_matrix_t *matrix,
_cairo_matrix_compute_determinant (matrix, &det);
- assert (ISFINITE (det));
+ if (! ISFINITE (det))
+ return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
if (det == 0)
{
@@ -556,6 +557,8 @@ _cairo_matrix_compute_scale_factors (const cairo_matrix_t *matrix,
*sy = major;
}
}
+
+ return CAIRO_STATUS_SUCCESS;
}
cairo_bool_t
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 43fe29b..1e532bc 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -544,15 +544,18 @@ _cairo_scaled_font_reset_cache (cairo_scaled_font_t *scaled_font)
MAX_GLYPHS_CACHED_PER_FONT);
}
-void
+cairo_status_t
_cairo_scaled_font_set_metrics (cairo_scaled_font_t *scaled_font,
cairo_font_extents_t *fs_metrics)
{
+ cairo_status_t status;
double font_scale_x, font_scale_y;
- _cairo_matrix_compute_scale_factors (&scaled_font->font_matrix,
- &font_scale_x, &font_scale_y,
- /* XXX */ 1);
+ status = _cairo_matrix_compute_scale_factors (&scaled_font->font_matrix,
+ &font_scale_x, &font_scale_y,
+ /* XXX */ 1);
+ if (status)
+ return status;
/*
* The font responded in unscaled units, scale by the font
@@ -564,6 +567,8 @@ _cairo_scaled_font_set_metrics (cairo_scaled_font_t *scaled_font,
scaled_font->extents.height = fs_metrics->height * font_scale_y;
scaled_font->extents.max_x_advance = fs_metrics->max_x_advance * font_scale_x;
scaled_font->extents.max_y_advance = fs_metrics->max_y_advance * font_scale_y;
+
+ return CAIRO_STATUS_SUCCESS;
}
void
diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c
index eb4d3b1..34c2736 100644
--- a/src/cairo-win32-font.c
+++ b/src/cairo-win32-font.c
@@ -130,7 +130,7 @@ _cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font
#define NEARLY_ZERO(d) (fabs(d) < (1. / 65536.))
-static void
+static cairo_status_t
_compute_transform (cairo_win32_scaled_font_t *scaled_font,
cairo_matrix_t *sc)
{
@@ -175,9 +175,11 @@ _compute_transform (cairo_win32_scaled_font_t *scaled_font,
sc->xx, sc->yx, sc->xy, sc->yy, 0, 0);
if (!scaled_font->preserve_axes) {
- _cairo_matrix_compute_scale_factors (&scaled_font->logical_to_device,
- &scaled_font->x_scale, &scaled_font->y_scale,
- TRUE); /* XXX: Handle vertical text */
+ status = _cairo_matrix_compute_scale_factors (&scaled_font->logical_to_device,
+ &scaled_font->x_scale, &scaled_font->y_scale,
+ TRUE); /* XXX: Handle vertical text */
+ if (status)
+ return status;
scaled_font->logical_size = _cairo_lround (WIN32_FONT_LOGICAL_SCALE *
scaled_font->y_scale);
@@ -192,6 +194,8 @@ _compute_transform (cairo_win32_scaled_font_t *scaled_font,
status = cairo_matrix_invert (&scaled_font->device_to_logical);
if (status)
cairo_matrix_init_identity (&scaled_font->device_to_logical);
+
+ return CAIRO_STATUS_SUCCESS;
}
static cairo_bool_t
@@ -312,7 +316,9 @@ _win32_scaled_font_create (LOGFONTW *logfont,
f->delete_scaled_hfont = !f->scaled_hfont;
cairo_matrix_multiply (&scale, font_matrix, ctm);
- _compute_transform (f, &scale);
+ status = _compute_transform (f, &scale);
+ if (status)
+ goto FAIL;
status = _cairo_scaled_font_init (&f->base, font_face,
font_matrix, ctm, options,
@@ -872,9 +878,7 @@ _cairo_win32_scaled_font_set_metrics (cairo_win32_scaled_font_t *scaled_font)
}
}
- _cairo_scaled_font_set_metrics (&scaled_font->base, &extents);
-
- return CAIRO_STATUS_SUCCESS;
+ return _cairo_scaled_font_set_metrics (&scaled_font->base, &extents);
}
static cairo_status_t
diff --git a/src/cairoint.h b/src/cairoint.h
index 75b646e..13f21fb 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1395,7 +1395,7 @@ _cairo_scaled_font_init (cairo_scaled_font_t *scaled_font,
const cairo_font_options_t *options,
const cairo_scaled_font_backend_t *backend);
-cairo_private void
+cairo_private cairo_status_t
_cairo_scaled_font_set_metrics (cairo_scaled_font_t *scaled_font,
cairo_font_extents_t *fs_metrics);
@@ -1967,7 +1967,7 @@ _cairo_matrix_is_invertible (const cairo_matrix_t *matrix);
cairo_private void
_cairo_matrix_compute_determinant (const cairo_matrix_t *matrix, double *det);
-cairo_private void
+cairo_private cairo_status_t
_cairo_matrix_compute_scale_factors (const cairo_matrix_t *matrix,
double *sx, double *sy, int x_major);
More information about the cairo-commit
mailing list