[cairo-commit] src/cairo-matrix.c

Chris Wilson ickle at kemper.freedesktop.org
Fri Jan 11 16:44:12 PST 2008


 src/cairo-matrix.c |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

New commits:
commit ae1e044e328deec7a430de3724a7ae0ad958d22d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jan 12 00:31:42 2008 +0000

    [cairo-matrix] Use isfinite() to check matrix determinant.
    
    The current NaN check is insufficient as it classifies inf as a valid
    determinant. We can improve the test by using isfinite() - but only
    when it is available. We use the feature test macros as being the
    simplest way of determining the presence of isfinite() as it may be
    implemented as a macro, making checking for its usability troublesome
    during configure.

diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c
index 00c2d48..df6d3cd 100644
--- a/src/cairo-matrix.c
+++ b/src/cairo-matrix.c
@@ -38,6 +38,10 @@
 
 #include "cairoint.h"
 
+#if _XOPEN_SOURCE >= 600 || _ISOC99_SOURCE
+#define HAVE_ISFINITE 1
+#endif
+
 static void
 _cairo_matrix_scalar_multiply (cairo_matrix_t *matrix, double scalar);
 
@@ -475,9 +479,14 @@ cairo_matrix_invert (cairo_matrix_t *matrix)
     if (det == 0)
 	return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
 
+#if HAVE_ISFINITE
+    if (! isfinite (det))
+	return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
+#else
     /* this weird construct is for detecting NaNs */
     if (! (det * det > 0.))
 	return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
+#endif
 
     _cairo_matrix_compute_adjoint (matrix);
     _cairo_matrix_scalar_multiply (matrix, 1 / det);
@@ -493,7 +502,14 @@ _cairo_matrix_is_invertible (const cairo_matrix_t *matrix)
 
     _cairo_matrix_compute_determinant (matrix, &det);
 
+#if HAVE_ISFINITE
+    if (! isfinite (det))
+	return FALSE;
+
+    return det != 0.;
+#else
     return det != 0. && det * det > 0.;
+#endif
 }
 
 void
@@ -517,6 +533,10 @@ _cairo_matrix_compute_scale_factors (const cairo_matrix_t *matrix,
 
     _cairo_matrix_compute_determinant (matrix, &det);
 
+#if HAVE_ISFINITE
+    assert (isfinite (det));
+#endif
+
     if (det == 0)
     {
 	*sx = *sy = 0;


More information about the cairo-commit mailing list