diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2008-10-23 12:28:25 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2008-10-30 17:52:12 +0000 |
commit | 13ba43eb8ffc3bb6c8881d91824102a8df86d928 (patch) | |
tree | 7d4d394f8bbb8047ba0a9b9d18edec382a3824c6 /src/cairo-matrix.c | |
parent | 6ed957fc242d7890117f4dea121c03ec2523470c (diff) |
[matrix] Optimize finding the bounding box under an orthogonal matrix.
We frequently need to find the bounds of a pattern under an identity
matrix, or a simple scale+translation. For these cases we do not need to
transform each corner and search for the bounds as the matrix is x/y
separable and so allows us to inspect the results for the extreme x/y
points independently.
Diffstat (limited to 'src/cairo-matrix.c')
-rw-r--r-- | src/cairo-matrix.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c index f01353ee..643c9867 100644 --- a/src/cairo-matrix.c +++ b/src/cairo-matrix.c @@ -371,6 +371,46 @@ _cairo_matrix_transform_bounding_box (const cairo_matrix_t *matrix, double min_x, max_x; double min_y, max_y; + if (_cairo_matrix_is_identity (matrix)) { + if (is_tight) + *is_tight = TRUE; + + return; + } + + if (matrix->xy == 0. && matrix->yx == 0.) { + /* non-rotation/skew matrix, just map the two extreme points */ + quad_x[0] = *x1; + quad_y[0] = *y1; + cairo_matrix_transform_distance (matrix, &quad_x[0], &quad_y[0]); + + quad_x[1] = *x2; + quad_y[1] = *y2; + cairo_matrix_transform_distance (matrix, &quad_x[1], &quad_y[1]); + + if (quad_x[0] < quad_x[1]) { + *x1 = quad_x[0] + matrix->x0; + *x2 = quad_x[1] + matrix->x0; + } else { + *x1 = quad_x[1] + matrix->x0; + *x2 = quad_x[0] + matrix->x0; + } + + if (quad_y[0] < quad_y[1]) { + *y1 = quad_y[0] + matrix->y0; + *y2 = quad_y[1] + matrix->y0; + } else { + *y1 = quad_y[1] + matrix->y0; + *y2 = quad_y[0] + matrix->y0; + } + + if (is_tight) + *is_tight = TRUE; + + return; + } + + /* general matrix */ quad_x[0] = *x1; quad_y[0] = *y1; cairo_matrix_transform_point (matrix, &quad_x[0], &quad_y[0]); @@ -406,7 +446,7 @@ _cairo_matrix_transform_bounding_box (const cairo_matrix_t *matrix, *y1 = min_y; *x2 = max_x; *y2 = max_y; - + if (is_tight) { /* it's tight if and only if the four corner points form an axis-aligned rectangle. |