From 4e44d54f3e99b65f5e80485b22d31890ea3d6561 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 4 Oct 2007 15:58:21 +0100 Subject: [PATCH] [cairo-matrix] Check whether a matrix is invertible before use. Provide an early check as to whether the font matrix is invertible. --- src/cairo-gstate.c | 3 +++ src/cairo-matrix.c | 10 ++++++++++ src/cairo-scaled-font.c | 3 +++ src/cairoint.h | 3 +++ 4 files changed, 19 insertions(+) diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index b1fc6b34d..2867243f4 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -1289,6 +1289,9 @@ cairo_status_t _cairo_gstate_set_font_matrix (cairo_gstate_t *gstate, const cairo_matrix_t *matrix) { + if (! _cairo_matrix_is_invertible (matrix)) + return _cairo_error (CAIRO_STATUS_INVALID_MATRIX); + _cairo_gstate_unset_scaled_font (gstate); gstate->font_matrix = *matrix; diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c index cf31c5d4d..00c2d4866 100644 --- a/src/cairo-matrix.c +++ b/src/cairo-matrix.c @@ -486,6 +486,16 @@ cairo_matrix_invert (cairo_matrix_t *matrix) } slim_hidden_def(cairo_matrix_invert); +cairo_bool_t +_cairo_matrix_is_invertible (const cairo_matrix_t *matrix) +{ + double det; + + _cairo_matrix_compute_determinant (matrix, &det); + + return det != 0. && det * det > 0.; +} + void _cairo_matrix_compute_determinant (const cairo_matrix_t *matrix, double *det) diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c index 2da991204..e90591746 100644 --- a/src/cairo-scaled-font.c +++ b/src/cairo-scaled-font.c @@ -603,6 +603,9 @@ cairo_scaled_font_create (cairo_font_face_t *font_face, if (cairo_font_options_status ((cairo_font_options_t *) options)) return (cairo_scaled_font_t *)&_cairo_scaled_font_nil; + if (! _cairo_matrix_is_invertible (font_matrix)) + return (cairo_scaled_font_t *)&_cairo_scaled_font_nil; + font_map = _cairo_scaled_font_map_lock (); if (font_map == NULL) return (cairo_scaled_font_t *)&_cairo_scaled_font_nil; diff --git a/src/cairoint.h b/src/cairoint.h index 80915d770..c5cdf1a5d 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -2104,6 +2104,9 @@ _cairo_matrix_transform_bounding_box (const cairo_matrix_t *matrix, double *x2, double *y2, cairo_bool_t *is_tight); +cairo_private cairo_bool_t +_cairo_matrix_is_invertible (const cairo_matrix_t *matrix); + cairo_private void _cairo_matrix_compute_determinant (const cairo_matrix_t *matrix, double *det);