summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pixman/pixman.c94
1 files changed, 36 insertions, 58 deletions
diff --git a/pixman/pixman.c b/pixman/pixman.c
index 264a56b2..3ecd3115 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -514,45 +514,9 @@ compute_transformed_extents (pixman_transform_t *transform,
return TRUE;
}
-static pixman_bool_t
-compute_sample_extents (pixman_transform_t *transform,
- pixman_box32_t *extents,
- pixman_fixed_t x_off, pixman_fixed_t y_off,
- pixman_fixed_t width, pixman_fixed_t height)
-{
- box_48_16_t transformed;
-
- if (!compute_transformed_extents (transform, extents, &transformed))
- return FALSE;
-
- /* Expand the source area by a tiny bit so account of different rounding that
- * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
- * 0.5 so this won't cause the area computed to be overly pessimistic.
- */
- transformed.x1 += x_off - 8 * pixman_fixed_e;
- transformed.y1 += y_off - 8 * pixman_fixed_e;
- transformed.x2 += x_off + width + 8 * pixman_fixed_e;
- transformed.y2 += y_off + height + 8 * pixman_fixed_e;
-
- if (transformed.x1 < pixman_min_fixed_48_16 || transformed.x1 > pixman_max_fixed_48_16 ||
- transformed.y1 < pixman_min_fixed_48_16 || transformed.y1 > pixman_max_fixed_48_16 ||
- transformed.x2 < pixman_min_fixed_48_16 || transformed.x2 > pixman_max_fixed_48_16 ||
- transformed.y2 < pixman_min_fixed_48_16 || transformed.y2 > pixman_max_fixed_48_16)
- {
- return FALSE;
- }
- else
- {
- extents->x1 = pixman_fixed_to_int (transformed.x1);
- extents->y1 = pixman_fixed_to_int (transformed.y1);
- extents->x2 = pixman_fixed_to_int (transformed.x2) + 1;
- extents->y2 = pixman_fixed_to_int (transformed.y2) + 1;
-
- return TRUE;
- }
-}
-
#define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX))
+#define ABS(f) (((f) < 0)? (-(f)) : (f))
+#define IS_16_16(f) (((f) >= pixman_min_fixed_48_16 && ((f) <= pixman_max_fixed_48_16)))
static pixman_bool_t
analyze_extent (pixman_image_t *image,
@@ -563,7 +527,8 @@ analyze_extent (pixman_image_t *image,
pixman_fixed_t *params;
pixman_fixed_t x_off, y_off;
pixman_fixed_t width, height;
- pixman_box32_t ex;
+ pixman_fixed_t m00, m10;
+ box_48_16_t transformed;
if (!image)
return TRUE;
@@ -633,17 +598,6 @@ analyze_extent (pixman_image_t *image,
default:
return FALSE;
}
-
- /* Check whether the non-expanded, transformed extent is entirely within
- * the source image, and set the FAST_PATH_SAMPLES_COVER_CLIP if it is.
- */
- ex = *extents;
- if (compute_sample_extents (transform, &ex, x_off, y_off, width, height) &&
- ex.x1 >= 0 && ex.y1 >= 0 &&
- ex.x2 <= image->bits.width && ex.y2 <= image->bits.height)
- {
- *flags |= FAST_PATH_SAMPLES_COVER_CLIP;
- }
}
else
{
@@ -653,17 +607,41 @@ analyze_extent (pixman_image_t *image,
height = 0;
}
- /* Check that the extents expanded by one don't overflow. This ensures that
- * compositing functions can simply walk the source space using 16.16
- * variables without worrying about overflow.
+ if (!compute_transformed_extents (transform, extents, &transformed))
+ return FALSE;
+
+ /* Expand the source area by a tiny bit so account of different rounding that
+ * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
+ * 0.5 so this won't cause the area computed to be overly pessimistic.
+ */
+ transformed.x1 += x_off - 8 * pixman_fixed_e;
+ transformed.y1 += y_off - 8 * pixman_fixed_e;
+ transformed.x2 += x_off + width + 8 * pixman_fixed_e;
+ transformed.y2 += y_off + height + 8 * pixman_fixed_e;
+
+ /* Check we don't overflow when the destination extents are expanded by one.
+ * This ensures that compositing functions can simply walk the source space
+ * using 16.16 variables without worrying about overflow.
*/
- ex.x1 = extents->x1 - 1;
- ex.y1 = extents->y1 - 1;
- ex.x2 = extents->x2 + 1;
- ex.y2 = extents->y2 + 1;
+ m00 = transform? ABS (transform->matrix[0][0]) : pixman_fixed_1;
+ m10 = transform? ABS (transform->matrix[1][0]) : 0;
- if (!compute_sample_extents (transform, &ex, x_off, y_off, width, height))
+ if (!IS_16_16 (transformed.x1 - m00) ||
+ !IS_16_16 (transformed.y1 - m10) ||
+ !IS_16_16 (transformed.x2 + m00) ||
+ !IS_16_16 (transformed.y2 + m10))
+ {
return FALSE;
+ }
+
+ if (image->common.type == BITS &&
+ pixman_fixed_to_int (transformed.x1) >= 0 &&
+ pixman_fixed_to_int (transformed.y1) >= 0 &&
+ pixman_fixed_to_int (transformed.x2) < image->bits.width &&
+ pixman_fixed_to_int (transformed.y2) < image->bits.height)
+ {
+ *flags |= FAST_PATH_SAMPLES_COVER_CLIP;
+ }
return TRUE;
}