[cairo-commit] 3 commits - src/cairo-clip.c src/cairo-ft-font.c src/cairo-ft-private.h src/cairo-path-fixed.c

Chris Wilson ickle at kemper.freedesktop.org
Tue Oct 16 03:04:23 PDT 2007


 src/cairo-clip.c       |   12 +--
 src/cairo-ft-font.c    |  178 +++++++++++++++++++++++++++++--------------------
 src/cairo-ft-private.h |    1 
 src/cairo-path-fixed.c |    7 +
 4 files changed, 120 insertions(+), 78 deletions(-)

New commits:
commit 3b1cc128dc4223ac88f7824dca223ed0f84df5d9
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 16 10:55:04 2007 +0100

    [cairo-ft-font] Add paranoid error checking to Fc* operations.
    
    Check the return status when using Fc*() functions to modify the pattern
    and propagate the failure (if necessary).

diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index e141ba7..f56cd8b 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -115,6 +115,10 @@ _cairo_ft_unscaled_font_keys_equal (const void *key_a,
 static void
 _cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t *unscaled);
 
+static cairo_status_t
+_cairo_ft_font_options_substitute (const cairo_font_options_t *options,
+				   FcPattern                  *pattern);
+
 typedef enum _cairo_ft_extra_flags {
     CAIRO_FT_OPTIONS_HINT_METRICS = (1 << 0),
     CAIRO_FT_OPTIONS_EMBOLDEN = (1 << 1)
@@ -1452,15 +1456,16 @@ _cairo_ft_options_merge (cairo_ft_options_t *options,
     options->extra_flags = other->extra_flags;
 }
 
-static cairo_scaled_font_t *
+static cairo_status_t
 _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t	 *unscaled,
 			      cairo_font_face_t		 *font_face,
 			      const cairo_matrix_t	 *font_matrix,
 			      const cairo_matrix_t	 *ctm,
 			      const cairo_font_options_t *options,
-			      cairo_ft_options_t	  ft_options)
+			      cairo_ft_options_t	  ft_options,
+			      cairo_scaled_font_t       **font_out)
 {
-    cairo_ft_scaled_font_t *scaled_font = NULL;
+    cairo_ft_scaled_font_t *scaled_font;
     FT_Face face;
     FT_Size_Metrics *metrics;
     cairo_font_extents_t fs_metrics;
@@ -1468,13 +1473,12 @@ _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t	 *unscaled,
 
     face = _cairo_ft_unscaled_font_lock_face (unscaled);
     if (!face)
-	return NULL;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     scaled_font = malloc (sizeof(cairo_ft_scaled_font_t));
     if (scaled_font == NULL) {
-	_cairo_ft_unscaled_font_unlock_face (unscaled);
-	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
-	return NULL;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	goto FAIL;
     }
 
     _cairo_unscaled_font_reference (&unscaled->base);
@@ -1492,18 +1496,14 @@ _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t	 *unscaled,
 				      &cairo_ft_scaled_font_backend);
     if (status) {
 	free (scaled_font);
-	_cairo_unscaled_font_destroy (&unscaled->base);
-	_cairo_ft_unscaled_font_unlock_face (unscaled);
-	return NULL;
+	goto FAIL;
     }
 
     status = _cairo_ft_unscaled_font_set_scale (unscaled,
 				                &scaled_font->base.scale);
     if (status) {
 	free (scaled_font);
-	_cairo_unscaled_font_destroy (&unscaled->base);
-	_cairo_ft_unscaled_font_unlock_face (unscaled);
-	return NULL;
+	goto FAIL;
     }
 
 
@@ -1553,9 +1553,12 @@ _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t	 *unscaled,
 
     _cairo_scaled_font_set_metrics (&scaled_font->base, &fs_metrics);
 
+    *font_out = &scaled_font->base;
+
+ FAIL:
     _cairo_ft_unscaled_font_unlock_face (unscaled);
 
-    return &scaled_font->base;
+    return status;
 }
 
 cairo_bool_t
@@ -1573,28 +1576,23 @@ _cairo_ft_scaled_font_create_toy (cairo_toy_font_face_t	      *toy_face,
 {
     FcPattern *pattern, *resolved;
     cairo_ft_unscaled_font_t *unscaled;
-    cairo_scaled_font_t *new_font = NULL;
     FcResult result;
     int fcslant;
     int fcweight;
     cairo_matrix_t scale;
+    cairo_status_t status;
     cairo_ft_font_transform_t sf;
     cairo_ft_options_t ft_options;
-    unsigned char *family = (unsigned char*) toy_face->family;
 
     pattern = FcPatternCreate ();
     if (!pattern)
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
-    switch (toy_face->weight)
+    if (!FcPatternAddString (pattern,
+		             FC_FAMILY, (unsigned char *) toy_face->family))
     {
-    case CAIRO_FONT_WEIGHT_BOLD:
-        fcweight = FC_WEIGHT_BOLD;
-        break;
-    case CAIRO_FONT_WEIGHT_NORMAL:
-    default:
-        fcweight = FC_WEIGHT_MEDIUM;
-        break;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	goto FREE_PATTERN;
     }
 
     switch (toy_face->slant)
@@ -1611,36 +1609,65 @@ _cairo_ft_scaled_font_create_toy (cairo_toy_font_face_t	      *toy_face,
         break;
     }
 
-    if (!FcPatternAddString (pattern, FC_FAMILY, family))
-	goto FREE_PATTERN;
-    if (!FcPatternAddInteger (pattern, FC_SLANT, fcslant))
+    if (!FcPatternAddInteger (pattern, FC_SLANT, fcslant)) {
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto FREE_PATTERN;
-    if (!FcPatternAddInteger (pattern, FC_WEIGHT, fcweight))
+    }
+
+    switch (toy_face->weight)
+    {
+    case CAIRO_FONT_WEIGHT_BOLD:
+        fcweight = FC_WEIGHT_BOLD;
+        break;
+    case CAIRO_FONT_WEIGHT_NORMAL:
+    default:
+        fcweight = FC_WEIGHT_MEDIUM;
+        break;
+    }
+
+    if (!FcPatternAddInteger (pattern, FC_WEIGHT, fcweight)) {
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto FREE_PATTERN;
+    }
 
     cairo_matrix_multiply (&scale, font_matrix, ctm);
     _compute_transform (&sf, &scale);
 
-    FcPatternAddInteger (pattern, FC_PIXEL_SIZE, sf.y_scale);
+    if (! FcPatternAddInteger (pattern, FC_PIXEL_SIZE, sf.y_scale)) {
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	goto FREE_PATTERN;
+    }
+
+    if (! FcConfigSubstitute (NULL, pattern, FcMatchPattern)) {
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	goto FREE_PATTERN;
+    }
+
+    status = _cairo_ft_font_options_substitute (font_options, pattern);
+    if (status)
+	goto FREE_PATTERN;
 
-    FcConfigSubstitute (NULL, pattern, FcMatchPattern);
-    cairo_ft_font_options_substitute (font_options, pattern);
     FcDefaultSubstitute (pattern);
 
     resolved = FcFontMatch (NULL, pattern, &result);
-    if (!resolved)
+    if (!resolved) {
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto FREE_PATTERN;
+    }
 
     unscaled = _cairo_ft_unscaled_font_create_for_pattern (resolved);
-    if (!unscaled)
+    if (!unscaled) {
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto FREE_RESOLVED;
+    }
 
     _get_pattern_ft_options (resolved, &ft_options);
 
-    new_font = _cairo_ft_scaled_font_create (unscaled,
-					     &toy_face->base,
-					     font_matrix, ctm,
-					     font_options, ft_options);
+    status = _cairo_ft_scaled_font_create (unscaled,
+					   &toy_face->base,
+					   font_matrix, ctm,
+					   font_options, ft_options,
+					   font);
 
     _cairo_unscaled_font_destroy (&unscaled->base);
 
@@ -1650,11 +1677,7 @@ _cairo_ft_scaled_font_create_toy (cairo_toy_font_face_t	      *toy_face,
  FREE_PATTERN:
     FcPatternDestroy (pattern);
 
-    if (new_font) {
-	*font = new_font;
-	return CAIRO_STATUS_SUCCESS;
-    } else
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    return status;
 }
 
 static void
@@ -2237,14 +2260,11 @@ _cairo_ft_font_face_scaled_font_create (void                     *abstract_face,
 
     ft_options = font_face->ft_options;
 
-    *scaled_font = _cairo_ft_scaled_font_create (font_face->unscaled,
-						 &font_face->base,
-						 font_matrix, ctm,
-						 options, ft_options);
-    if (*scaled_font)
-	return CAIRO_STATUS_SUCCESS;
-    else
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    return  _cairo_ft_scaled_font_create (font_face->unscaled,
+					  &font_face->base,
+					  font_matrix, ctm,
+					  options, ft_options,
+					  scaled_font);
 }
 
 static const cairo_font_face_backend_t _cairo_ft_font_face_backend = {
@@ -2299,20 +2319,9 @@ _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled,
 
 /* implement the platform-specific interface */
 
-/**
- * cairo_ft_font_options_substitute:
- * @options: a #cairo_font_options_t object
- * @pattern: an existing #FcPattern
- *
- * Add options to a #FcPattern based on a #cairo_font_options_t font
- * options object. Options that are already in the pattern, are not overridden,
- * so you should call this function after calling FcConfigSubstitute() (the
- * user's settings should override options based on the surface type), but
- * before calling FcDefaultSubstitute().
- **/
-void
-cairo_ft_font_options_substitute (const cairo_font_options_t *options,
-				  FcPattern                  *pattern)
+static cairo_status_t
+_cairo_ft_font_options_substitute (const cairo_font_options_t *options,
+				   FcPattern                  *pattern)
 {
     FcValue v;
 
@@ -2320,10 +2329,15 @@ cairo_ft_font_options_substitute (const cairo_font_options_t *options,
     {
 	if (FcPatternGet (pattern, FC_ANTIALIAS, 0, &v) == FcResultNoMatch)
 	{
-	    FcPatternAddBool (pattern, FC_ANTIALIAS, options->antialias != CAIRO_ANTIALIAS_NONE);
+	    if (! FcPatternAddBool (pattern,
+			            FC_ANTIALIAS,
+				    options->antialias != CAIRO_ANTIALIAS_NONE))
+		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
 	    if (options->antialias != CAIRO_ANTIALIAS_SUBPIXEL) {
 		FcPatternDel (pattern, FC_RGBA);
-		FcPatternAddInteger (pattern, FC_RGBA, FC_RGBA_NONE);
+		if (! FcPatternAddInteger (pattern, FC_RGBA, FC_RGBA_NONE))
+		    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    }
 	}
     }
@@ -2355,7 +2369,8 @@ cairo_ft_font_options_substitute (const cairo_font_options_t *options,
 		rgba = FC_RGBA_NONE;
 	    }
 
-	    FcPatternAddInteger (pattern, FC_RGBA, rgba);
+	    if (! FcPatternAddInteger (pattern, FC_RGBA, rgba))
+		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	}
     }
 
@@ -2363,7 +2378,10 @@ cairo_ft_font_options_substitute (const cairo_font_options_t *options,
     {
 	if (FcPatternGet (pattern, FC_HINTING, 0, &v) == FcResultNoMatch)
 	{
-	    FcPatternAddBool (pattern, FC_HINTING, options->hint_style != CAIRO_HINT_STYLE_NONE);
+	    if (! FcPatternAddBool (pattern,
+			            FC_HINTING,
+				    options->hint_style != CAIRO_HINT_STYLE_NONE))
+		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	}
 
 #ifdef FC_HINT_STYLE
@@ -2388,12 +2406,32 @@ cairo_ft_font_options_substitute (const cairo_font_options_t *options,
 		break;
 	    }
 
-	    FcPatternAddInteger (pattern, FC_HINT_STYLE, hint_style);
+	    if (! FcPatternAddInteger (pattern, FC_HINT_STYLE, hint_style))
+		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	}
 #endif
     }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+/**
+ * cairo_ft_font_options_substitute:
+ * @options: a #cairo_font_options_t object
+ * @pattern: an existing #FcPattern
+ *
+ * Add options to a #FcPattern based on a #cairo_font_options_t font
+ * options object. Options that are already in the pattern, are not overridden,
+ * so you should call this function after calling FcConfigSubstitute() (the
+ * user's settings should override options based on the surface type), but
+ * before calling FcDefaultSubstitute().
+ **/
+void
+cairo_ft_font_options_substitute (const cairo_font_options_t *options,
+				  FcPattern                  *pattern)
+{
+    _cairo_ft_font_options_substitute (options, pattern);
 }
-slim_hidden_def (cairo_ft_font_options_substitute);
 
 /**
  * cairo_ft_font_face_create_for_pattern:
diff --git a/src/cairo-ft-private.h b/src/cairo-ft-private.h
index 3e28f5e..61f21f1 100644
--- a/src/cairo-ft-private.h
+++ b/src/cairo-ft-private.h
@@ -67,7 +67,6 @@ _cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t *unscaled);
 cairo_private cairo_bool_t
 _cairo_ft_scaled_font_is_vertical (cairo_scaled_font_t *scaled_font);
 
-slim_hidden_proto (cairo_ft_font_options_substitute);
 slim_hidden_proto (cairo_ft_scaled_font_lock_face);
 slim_hidden_proto (cairo_ft_scaled_font_unlock_face);
 
commit a55f1abf7cdc0276fe1eb85db969f33d0df4fe75
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 16 10:29:45 2007 +0100

    [cairo-clip] Pass the local pattern to create_similar_solid().
    
    Avoid the short-lived pattern allocation within
    _cairo_surface_create_similar_solid() by providing the local solid
    pattern to use as the source.

diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index a48f4c4..387e26e 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -395,20 +395,22 @@ _cairo_clip_intersect_mask (cairo_clip_t      *clip,
     if (!status)
 	_cairo_rectangle_intersect (&surface_rect, &target_rect);
 
+    _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE,
+			       CAIRO_CONTENT_COLOR);
     surface = _cairo_surface_create_similar_solid (target,
 						   CAIRO_CONTENT_ALPHA,
 						   surface_rect.width,
 						   surface_rect.height,
 						   CAIRO_COLOR_WHITE,
-						   NULL);
-    if (surface->status)
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+						   &pattern.base);
+    if (surface->status) {
+	_cairo_pattern_fini (&pattern.base);
+	return surface->status;
+    }
 
     /* Render the new clipping path into the new mask surface. */
 
     _cairo_traps_translate (traps, -surface_rect.x, -surface_rect.y);
-    _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE,
-			       CAIRO_CONTENT_COLOR);
 
     status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_IN,
 						  &pattern.base,
commit 7ff80234e3823547395819f96d7f7673df9ce9df
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 16 10:37:45 2007 +0100

    [cairo-path-fixed] Drop the _cairo_error() markup.
    
    Do not use _cairo_error(CAIRO_STATUS_NO_CURRENT_POINT) within
    _cairo_path_fixed_get_current_point() as the only caller,
    cairo_get_current_point(), expects and handles that status.

diff --git a/src/cairo-path-fixed.c b/src/cairo-path-fixed.c
index 1ed674e..a92bcd6 100644
--- a/src/cairo-path-fixed.c
+++ b/src/cairo-path-fixed.c
@@ -345,8 +345,11 @@ _cairo_path_fixed_get_current_point (cairo_path_fixed_t *path,
 				     cairo_fixed_t	*x,
 				     cairo_fixed_t	*y)
 {
-    if (! path->has_current_point)
-	return _cairo_error (CAIRO_STATUS_NO_CURRENT_POINT);
+    if (! path->has_current_point) {
+	/* No need for _cairo_error() as the only caller,
+	 * cairo_get_current_point(), expects and handles NO_CURRENT_POINT */
+	return CAIRO_STATUS_NO_CURRENT_POINT;
+    }
 
     *x = path->current_point.x;
     *y = path->current_point.y;


More information about the cairo-commit mailing list