mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-04-19 02:00:43 +02:00
[cairo-gstate] Check that the matrix remains invertible.
Ensure that the ctm remains invertible after multiplying the user supplied matrices. Although the arguments are checked so that they are valid per se, we double check that the result after multiplication is still a valid invertible matrix. This should catch pathological cases where the user concatenates a long series of matrix operations, which either exceed our numerical limits or become degenerate through rounding errors.
This commit is contained in:
parent
2f600affaa
commit
5e32dcf863
1 changed files with 16 additions and 0 deletions
|
|
@ -642,6 +642,10 @@ _cairo_gstate_translate (cairo_gstate_t *gstate, double tx, double ty)
|
|||
cairo_matrix_init_translate (&tmp, tx, ty);
|
||||
cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm);
|
||||
|
||||
/* paranoid check against gradual numerical instability */
|
||||
if (! _cairo_matrix_is_invertible (&gstate->ctm))
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
|
||||
|
||||
cairo_matrix_init_translate (&tmp, -tx, -ty);
|
||||
cairo_matrix_multiply (&gstate->ctm_inverse, &gstate->ctm_inverse, &tmp);
|
||||
|
||||
|
|
@ -668,6 +672,10 @@ _cairo_gstate_scale (cairo_gstate_t *gstate, double sx, double sy)
|
|||
cairo_matrix_init_scale (&tmp, sx, sy);
|
||||
cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm);
|
||||
|
||||
/* paranoid check against gradual numerical instability */
|
||||
if (! _cairo_matrix_is_invertible (&gstate->ctm))
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
|
||||
|
||||
cairo_matrix_init_scale (&tmp, 1/sx, 1/sy);
|
||||
cairo_matrix_multiply (&gstate->ctm_inverse, &gstate->ctm_inverse, &tmp);
|
||||
|
||||
|
|
@ -695,6 +703,10 @@ _cairo_gstate_rotate (cairo_gstate_t *gstate, double angle)
|
|||
cairo_matrix_init_rotate (&tmp, angle);
|
||||
cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm);
|
||||
|
||||
/* paranoid check against gradual numerical instability */
|
||||
if (! _cairo_matrix_is_invertible (&gstate->ctm))
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
|
||||
|
||||
cairo_matrix_init_rotate (&tmp, -angle);
|
||||
cairo_matrix_multiply (&gstate->ctm_inverse, &gstate->ctm_inverse, &tmp);
|
||||
|
||||
|
|
@ -718,6 +730,10 @@ _cairo_gstate_transform (cairo_gstate_t *gstate,
|
|||
cairo_matrix_multiply (&gstate->ctm, matrix, &gstate->ctm);
|
||||
cairo_matrix_multiply (&gstate->ctm_inverse, &gstate->ctm_inverse, &tmp);
|
||||
|
||||
/* paranoid check against gradual numerical instability */
|
||||
if (! _cairo_matrix_is_invertible (&gstate->ctm))
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue