mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-01 07:58:04 +02:00
[fill] Use trivial rectilinear_to_traps
Avoid a small amount of unnecessary overhead by performing a simple conversion of the path to traps when it consists solely of simple boxes.
This commit is contained in:
parent
30e5fa0ce0
commit
4bf96bad96
3 changed files with 93 additions and 0 deletions
|
|
@ -347,3 +347,77 @@ TESSELLATE:
|
|||
|
||||
return region;
|
||||
}
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_path_fixed_fill_rectilinear_to_traps (const cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
cairo_traps_t *traps)
|
||||
{
|
||||
cairo_box_t box;
|
||||
cairo_status_t status;
|
||||
|
||||
if (_cairo_path_fixed_is_box (path, &box)) {
|
||||
if (box.p1.x > box.p2.x) {
|
||||
cairo_fixed_t t;
|
||||
|
||||
t = box.p1.x;
|
||||
box.p1.x = box.p2.x;
|
||||
box.p2.x = t;
|
||||
}
|
||||
|
||||
if (box.p1.y > box.p2.y) {
|
||||
cairo_fixed_t t;
|
||||
|
||||
t = box.p1.y;
|
||||
box.p1.y = box.p2.y;
|
||||
box.p2.y = t;
|
||||
}
|
||||
|
||||
return _cairo_traps_tessellate_rectangle (traps, &box.p1, &box.p2);
|
||||
} else if (fill_rule == CAIRO_FILL_RULE_WINDING) {
|
||||
cairo_path_fixed_iter_t iter;
|
||||
int last_cw = -1;
|
||||
|
||||
_cairo_path_fixed_iter_init (&iter, path);
|
||||
while (_cairo_path_fixed_iter_is_fill_box (&iter, &box)) {
|
||||
int cw = 0;
|
||||
|
||||
if (box.p1.x > box.p2.x) {
|
||||
cairo_fixed_t t;
|
||||
|
||||
t = box.p1.x;
|
||||
box.p1.x = box.p2.x;
|
||||
box.p2.x = t;
|
||||
|
||||
cw = ! cw;
|
||||
}
|
||||
|
||||
if (box.p1.y > box.p2.y) {
|
||||
cairo_fixed_t t;
|
||||
|
||||
t = box.p1.y;
|
||||
box.p1.y = box.p2.y;
|
||||
box.p2.y = t;
|
||||
|
||||
cw = ! cw;
|
||||
}
|
||||
|
||||
if (last_cw < 0)
|
||||
last_cw = cw;
|
||||
else if (last_cw != cw)
|
||||
goto out;
|
||||
|
||||
status = _cairo_traps_tessellate_rectangle (traps,
|
||||
&box.p1, &box.p2);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
}
|
||||
|
||||
if (_cairo_path_fixed_iter_at_end (&iter))
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
out:
|
||||
_cairo_traps_clear (traps);
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1193,6 +1193,20 @@ _cairo_surface_fallback_fill (cairo_surface_t *surface,
|
|||
_cairo_polygon_init (&polygon);
|
||||
_cairo_polygon_limit (&polygon, boxes, num_boxes);
|
||||
|
||||
if (path->is_empty_fill)
|
||||
goto DO_TRAPS;
|
||||
|
||||
if (path->is_rectilinear) {
|
||||
status = _cairo_path_fixed_fill_rectilinear_to_traps (path,
|
||||
fill_rule,
|
||||
&traps);
|
||||
if (likely (status == CAIRO_STATUS_SUCCESS))
|
||||
goto DO_TRAPS;
|
||||
|
||||
if (_cairo_status_is_error (status))
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
status = _cairo_path_fixed_fill_to_polygon (path, tolerance, &polygon);
|
||||
if (unlikely (status))
|
||||
goto CLEANUP;
|
||||
|
|
|
|||
|
|
@ -1617,6 +1617,11 @@ _cairo_path_fixed_fill_to_polygon (const cairo_path_fixed_t *path,
|
|||
double tolerance,
|
||||
cairo_polygon_t *polygon);
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_path_fixed_fill_rectilinear_to_traps (const cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
cairo_traps_t *traps);
|
||||
|
||||
cairo_private cairo_region_t *
|
||||
_cairo_path_fixed_fill_rectilinear_to_region (const cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue