mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-05 05:18:01 +02:00
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:
parent
a810b012cf
commit
da95bdfcd7
3 changed files with 111 additions and 7 deletions
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
107
src/cairo-clip.c
107
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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue