[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