[cairo-commit] 3 commits - src/cairo-gstate.c

Chris Wilson ickle at kemper.freedesktop.org
Wed Oct 24 17:05:39 PDT 2007


 src/cairo-gstate.c |   35 ++++++++++++++++++++++++-----------
 1 file changed, 24 insertions(+), 11 deletions(-)

New commits:
commit ce44cd65238d38dd6958bf1f7b8ffb9d0e8723c3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Oct 25 00:01:21 2007 +0100

    [cairo-gstate] Add a missing _cairo_error() markup.
    
    Missed calling _cairo_error() for the CAIRO_STATUS_NULL_POINTER
    returned by _cairo_gstate_init(). Rearrange the code to avoid the
    overly complicated return statement. We note that _cairo_gstate_init()
    is special as _cairo_gstate_fini() will always be called, even if an
    error is thrown, and so do not do the usual cleanup in the case of an
    aborted initialization.

diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index 43a73f8..1d70611 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -62,6 +62,8 @@ cairo_status_t
 _cairo_gstate_init (cairo_gstate_t  *gstate,
 		    cairo_surface_t *target)
 {
+    cairo_status_t status;
+
     gstate->next = NULL;
 
     gstate->op = CAIRO_GSTATE_OPERATOR_DEFAULT;
@@ -93,15 +95,23 @@ _cairo_gstate_init (cairo_gstate_t  *gstate,
 
     gstate->source = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK,
 						  CAIRO_CONTENT_COLOR);
-    if (gstate->source->status) {
-	cairo_surface_destroy (gstate->target);
-	gstate->target = NULL;
-	cairo_surface_destroy (gstate->original_target);
-	gstate->original_target = NULL;
-	return gstate->source->status;
-    }
 
-    return target ? target->status : CAIRO_STATUS_NULL_POINTER;
+    /* Now that the gstate is fully initialized and ready for the eventual
+     * _cairo_gstate_fini(), we can check for errors (and not worry about
+     * the resource deallocation). */
+
+    if (target == NULL)
+	return _cairo_error (CAIRO_STATUS_NULL_POINTER);
+
+    status = target->status;
+    if (status)
+	return status;
+
+    status = gstate->source->status;
+    if (status)
+	return status;
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 /**
commit 4ce785e6a9433e7c862efaa6ef9c113412bf51a5
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Oct 24 21:58:08 2007 +0100

    [cairo-gstate] Add NaN check to rotate.
    
    Check the user input to _cairo_gstate_rotate() for invalid numbers.

diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index d14a0d6..43a73f8 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -653,6 +653,9 @@ _cairo_gstate_rotate (cairo_gstate_t *gstate, double angle)
 {
     cairo_matrix_t tmp;
 
+    if (! (angle * angle > 0.)) /* check for NaNs */
+	return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
+
     _cairo_gstate_unset_scaled_font (gstate);
 
     cairo_matrix_init_rotate (&tmp, angle);
commit 6295a296b0064f0959ca7f39e1d8d00fa51b6251
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Oct 24 21:29:54 2007 +0100

    [cairo-gstate] Check scale sx * sy != 0.
    
    Bill Spitzak said
        "If you really want to match when the determinant is non-zero in the
        resulting matrix, use sx*sy != 0. This appears the same as sx&&sy but
        may also catch when underflow makes the determinant zero."
    
    Return CAIRO_STATUS_INVALID_MATRIX if we know the user input will
    generate a degenerate matrix. For additional paranoia we could recompute
    and validate the inverse each time as well.

diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index 499e9aa..d14a0d6 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -613,7 +613,7 @@ _cairo_gstate_translate (cairo_gstate_t *gstate, double tx, double ty)
 {
     cairo_matrix_t tmp;
 
-    if (! (tx * tx >= 0.) || ! (ty * ty >= 0.))
+    if (! (tx * tx >= 0.) || ! (ty * ty >= 0.)) /* check for NaNs */
 	return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
 
     _cairo_gstate_unset_scaled_font (gstate);
@@ -632,9 +632,9 @@ _cairo_gstate_scale (cairo_gstate_t *gstate, double sx, double sy)
 {
     cairo_matrix_t tmp;
 
-    if (sx == 0 || sy == 0)
+    if (sx * sy == 0.) /* either sx or sy is 0, or det == 0 due to underflow */
 	return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
-    if (! (sx * sx > 0.) || ! (sy * sy > 0.))
+    if (! (sx * sx > 0.) || ! (sy * sy > 0.)) /* check for NaNs */
 	return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
 
     _cairo_gstate_unset_scaled_font (gstate);


More information about the cairo-commit mailing list