/** * cairo_matrix_invert: * @matrix: a @cairo_matrix_t * * Changes @matrix to be the inverse of it's original value. Not * all transformation matrices have inverses; if the matrix * collapses points together (it is <firstterm>degenerate</firstterm>), * then it has no inverse and this function will fail. * * Returns: If @matrix has an inverse, modifies @matrix to * be the inverse matrix and returns %CAIRO_STATUS_SUCCESS. Otherwise, * returns %CAIRO_STATUS_INVALID_MATRIX. **/ cairo_status_t cairo_matrix_invert (cairo_matrix_t *matrix) { /* inv (A) = 1/det (A) * adj (A) */ double det; _cairo_matrix_compute_determinant (matrix, &det); if (det == 0) return CAIRO_STATUS_INVALID_MATRIX; _cairo_matrix_compute_adjoint (matrix); _cairo_matrix_scalar_multiply (matrix, 1 / det); return CAIRO_STATUS_SUCCESS; }
/** * cairo_matrix_invert: * @matrix: a #cairo_matrix_t * * Changes @matrix to be the inverse of its original value. Not * all transformation matrices have inverses; if the matrix * collapses points together (it is <firstterm>degenerate</firstterm>), * then it has no inverse and this function will fail. * * Returns: If @matrix has an inverse, modifies @matrix to * be the inverse matrix and returns %CAIRO_STATUS_SUCCESS. Otherwise, * returns %CAIRO_STATUS_INVALID_MATRIX. **/ cairo_status_t cairo_matrix_invert (cairo_matrix_t *matrix) { double det; /* Simple scaling|translation matrices are quite common... */ if (matrix->xy == 0. && matrix->yx == 0.) { matrix->x0 = -matrix->x0; matrix->y0 = -matrix->y0; if (matrix->xx != 1.) { if (matrix->xx == 0.) return _cairo_error (CAIRO_STATUS_INVALID_MATRIX); matrix->xx = 1. / matrix->xx; matrix->x0 *= matrix->xx; } if (matrix->yy != 1.) { if (matrix->yy == 0.) return _cairo_error (CAIRO_STATUS_INVALID_MATRIX); matrix->yy = 1. / matrix->yy; matrix->y0 *= matrix->yy; } return CAIRO_STATUS_SUCCESS; } /* inv (A) = 1/det (A) * adj (A) */ det = _cairo_matrix_compute_determinant (matrix); if (! ISFINITE (det)) return _cairo_error (CAIRO_STATUS_INVALID_MATRIX); if (det == 0) return _cairo_error (CAIRO_STATUS_INVALID_MATRIX); _cairo_matrix_compute_adjoint (matrix); _cairo_matrix_scalar_multiply (matrix, 1 / det); return CAIRO_STATUS_SUCCESS; }