[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