wrapper: transform the clip into device space

We need more than just mere translation!

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2011-09-20 14:04:29 +01:00
parent a810b012cf
commit da95bdfcd7
3 changed files with 111 additions and 7 deletions

View file

@ -102,6 +102,9 @@ _cairo_clip_copy_region (const cairo_clip_t *clip);
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);

View file

@ -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)
{

View file

@ -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