[cairo-commit] 2 commits - src/cairo-clip.c src/cairo-clip-private.h src/cairo-image-source.c src/cairo-surface-wrapper.c
Chris Wilson
ickle at kemper.freedesktop.org
Tue Sep 20 06:29:54 PDT 2011
src/cairo-clip-private.h | 3 +
src/cairo-clip.c | 107 ++++++++++++++++++++++++++++++++++++++++++++
src/cairo-image-source.c | 29 +++++++++--
src/cairo-surface-wrapper.c | 8 ---
4 files changed, 134 insertions(+), 13 deletions(-)
New commits:
commit 5f0dcf610f8714dcffe49c3ea6edea479590c34b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Sep 20 14:05:31 2011 +0100
image: clip the replay to the sample extents in device space
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/cairo-image-source.c b/src/cairo-image-source.c
index 4c2c1d2..da6dc08 100644
--- a/src/cairo-image-source.c
+++ b/src/cairo-image-source.c
@@ -623,7 +623,7 @@ _pixman_image_for_recording (cairo_image_surface_t *dst,
if (_cairo_surface_get_extents (source, &limit)) {
if (sample->x >= limit.x &&
sample->y >= limit.y &&
- sample->x + sample->width <= limit.x + limit.width &&
+ sample->x + sample->width <= limit.x + limit.width &&
sample->y + sample->height <= limit.y + limit.height)
{
extend = CAIRO_EXTEND_NONE;
@@ -640,9 +640,29 @@ _pixman_image_for_recording (cairo_image_surface_t *dst,
extend = CAIRO_EXTEND_NONE;
if (extend == CAIRO_EXTEND_NONE) {
- limit = *extents;
if (! _cairo_rectangle_intersect (&limit, sample))
return _pixman_transparent_image ();
+
+ if (! _cairo_matrix_is_identity (&pattern->base.matrix)) {
+ double x1, y1, x2, y2;
+
+ matrix = pattern->base.matrix;
+ status = cairo_matrix_invert (&matrix);
+ assert (status == CAIRO_STATUS_SUCCESS);
+
+ x1 = limit.x;
+ y1 = limit.y;
+ x2 = limit.x + limit.width;
+ y2 = limit.y + limit.height;
+
+ _cairo_matrix_transform_bounding_box (&matrix,
+ &x1, &y1, &x2, &y2, NULL);
+
+ limit.x = floor (x1);
+ limit.y = floor (y1);
+ limit.width = ceil (x2) - limit.x;
+ limit.height = ceil (y2) - limit.y;
+ }
}
if (dst->base.content == source->content)
@@ -652,7 +672,7 @@ _pixman_image_for_recording (cairo_image_surface_t *dst,
clone = _cairo_image_surface_create_with_content (source->content,
limit.width,
limit.height);
- cairo_surface_set_device_offset (clone, limit.x, limit.y);
+ cairo_surface_set_device_offset (clone, -limit.x, -limit.y);
m = NULL;
if (extend == CAIRO_EXTEND_NONE) {
@@ -662,9 +682,6 @@ _pixman_image_for_recording (cairo_image_surface_t *dst,
&pattern->base.matrix);
if (tx | ty)
cairo_matrix_translate (m, tx, ty);
-
- status = cairo_matrix_invert (m);
- assert (status == CAIRO_STATUS_SUCCESS);
} else {
/* XXX extract scale factor for repeating patterns */
}
commit da95bdfcd77c56a52e08544946786cff8a33ca1e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Sep 20 14:04:29 2011 +0100
wrapper: transform the clip into device space
We need more than just mere translation!
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h
index a682ce4..aaf16f3 100644
--- a/src/cairo-clip-private.h
+++ b/src/cairo-clip-private.h
@@ -103,6 +103,9 @@ cairo_private cairo_clip_t *
_cairo_clip_translate (cairo_clip_t *clip, int tx, int ty);
cairo_private cairo_clip_t *
+_cairo_clip_transform (cairo_clip_t *clip, const cairo_matrix_t *m);
+
+cairo_private cairo_clip_t *
_cairo_clip_copy_with_translation (const cairo_clip_t *clip, int tx, int ty);
cairo_private cairo_bool_t
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index 44f4e7b..11ba54d 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -452,6 +452,113 @@ _cairo_clip_translate (cairo_clip_t *clip, int tx, int ty)
return clip;
}
+static cairo_status_t
+_cairo_path_fixed_add_box (cairo_path_fixed_t *path,
+ const cairo_box_t *box)
+{
+ cairo_status_t status;
+
+ status = _cairo_path_fixed_move_to (path, box->p1.x, box->p1.y);
+ if (unlikely (status))
+ return status;
+
+ status = _cairo_path_fixed_line_to (path, box->p2.x, box->p1.y);
+ if (unlikely (status))
+ return status;
+
+ status = _cairo_path_fixed_line_to (path, box->p2.x, box->p2.y);
+ if (unlikely (status))
+ return status;
+
+ status = _cairo_path_fixed_line_to (path, box->p1.x, box->p2.y);
+ if (unlikely (status))
+ return status;
+
+ return _cairo_path_fixed_close_path (path);
+}
+
+static cairo_status_t
+_cairo_path_fixed_init_from_boxes (cairo_path_fixed_t *path,
+ const cairo_boxes_t *boxes)
+{
+ cairo_status_t status;
+ const struct _cairo_boxes_chunk *chunk;
+ int i;
+
+ _cairo_path_fixed_init (path);
+ if (boxes->num_boxes == 0)
+ return CAIRO_STATUS_SUCCESS;
+
+ for (chunk = &boxes->chunks; chunk; chunk = chunk->next) {
+ for (i = 0; i < chunk->count; i++) {
+ status = _cairo_path_fixed_add_box (path, &chunk->base[i]);
+ if (unlikely (status)) {
+ _cairo_path_fixed_fini (path);
+ return status;
+ }
+ }
+ }
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_clip_t *
+_cairo_clip_intersect_clip_path_transformed (cairo_clip_t *clip,
+ const cairo_clip_path_t *clip_path,
+ const cairo_matrix_t *m)
+{
+ cairo_path_fixed_t path;
+
+ if (clip_path->prev)
+ clip = _cairo_clip_intersect_clip_path_transformed (clip,
+ clip_path->prev,
+ m);
+
+ if (_cairo_path_fixed_init_copy (&path, &clip_path->path))
+ return _cairo_clip_set_all_clipped (clip);
+
+ clip = _cairo_clip_intersect_path (clip,
+ &path,
+ clip_path->fill_rule,
+ clip_path->tolerance,
+ clip_path->antialias);
+ _cairo_path_fixed_fini (&path);
+
+ return clip;
+}
+
+cairo_clip_t *
+_cairo_clip_transform (cairo_clip_t *clip, const cairo_matrix_t *m)
+{
+ cairo_clip_t *copy;
+
+ if (_cairo_matrix_is_translation (m))
+ return _cairo_clip_translate (clip, m->x0, m->y0);
+
+ copy = _cairo_clip_create ();
+
+ if (clip->num_boxes) {
+ cairo_path_fixed_t path;
+ cairo_boxes_t boxes;
+
+ _cairo_boxes_init_for_array (&boxes, clip->boxes, clip->num_boxes);
+ _cairo_path_fixed_init_from_boxes (&path, &boxes);
+ _cairo_path_fixed_transform (&path, m);
+
+ copy = _cairo_clip_intersect_path (copy, &path,
+ CAIRO_FILL_RULE_WINDING,
+ 0.1,
+ CAIRO_ANTIALIAS_DEFAULT);
+
+ _cairo_path_fixed_fini (&path);
+ }
+
+ if (clip->path)
+ copy = _cairo_clip_intersect_clip_path_transformed (copy, clip->path,m);
+
+ return copy;
+}
+
cairo_clip_t *
_cairo_clip_copy_with_translation (const cairo_clip_t *clip, int tx, int ty)
{
diff --git a/src/cairo-surface-wrapper.c b/src/cairo-surface-wrapper.c
index 48bd30a..00d9aa3 100644
--- a/src/cairo-surface-wrapper.c
+++ b/src/cairo-surface-wrapper.c
@@ -127,12 +127,7 @@ _cairo_surface_wrapper_get_clip (cairo_surface_wrapper_t *wrapper,
-wrapper->extents.x,
-wrapper->extents.y);
}
- if (! _cairo_matrix_is_identity (&wrapper->transform)) {
- /* XXX */
- copy = _cairo_clip_translate (copy,
- wrapper->transform.x0,
- wrapper->transform.y0);
- }
+ copy = _cairo_clip_transform (copy, &wrapper->transform);
if (! _cairo_matrix_is_identity (&wrapper->target->device_transform)) {
/* XXX */
copy = _cairo_clip_translate (copy,
@@ -562,7 +557,6 @@ _cairo_surface_wrapper_set_inverse_transform (cairo_surface_wrapper_t *wrapper,
wrapper->needs_transform = TRUE;
}
-
}
void
More information about the cairo-commit
mailing list