summaryrefslogtreecommitdiff
path: root/src/cairo-matrix.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2008-10-23 12:28:25 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2008-10-30 17:52:12 +0000
commit13ba43eb8ffc3bb6c8881d91824102a8df86d928 (patch)
tree7d4d394f8bbb8047ba0a9b9d18edec382a3824c6 /src/cairo-matrix.c
parent6ed957fc242d7890117f4dea121c03ec2523470c (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.c42
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.