diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2008-12-17 09:32:16 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2009-08-29 08:08:28 +0100 |
commit | f8bb3617c3a7ec598c42eff1f8562e3ccc95127f (patch) | |
tree | f6c8f949ab44ca126053fb5cea2b9b88a4748cb8 /src/cairo-pen.c | |
parent | 7c499db8afe8a7cf8c512ec166fe7dbf11a25c02 (diff) | |
download | cairo-f8bb3617c3a7ec598c42eff1f8562e3ccc95127f.tar.gz |
Eliminate self-intersecting strokes.
We refactor the surface fallbacks to convert full strokes and fills to the
intermediate polygon representation (as opposed to before where we
returned the trapezoidal representation). This allow greater flexibility
to choose how then to rasterize the polygon. Where possible we use the
local spans rasteriser for its increased performance, but still have the
option to use the tessellator instead (for example, with the current
Render protocol which does not yet have a polygon image).
In order to accommodate this, the spans interface is tweaked to accept
whole polygons instead of a path and the tessellator is tweaked for speed.
Performance Impact
==================
...
Still measuring, expecting some severe regressions.
...
Diffstat (limited to 'src/cairo-pen.c')
-rw-r--r-- | src/cairo-pen.c | 191 |
1 files changed, 0 insertions, 191 deletions
diff --git a/src/cairo-pen.c b/src/cairo-pen.c index b2fd85575..8db8fcb36 100644 --- a/src/cairo-pen.c +++ b/src/cairo-pen.c @@ -393,194 +393,3 @@ _cairo_pen_find_active_ccw_vertex_index (const cairo_pen_t *pen, return i; } - -static int -_cairo_pen_stroke_spline_add_convolved_point (cairo_pen_stroke_spline_t *stroker, - const cairo_point_t *last_point, - const cairo_slope_t *slope, - cairo_point_t *last_hull_point, - int active, - int step) -{ - do { - cairo_point_t hull_point; - - hull_point.x = last_point->x + stroker->pen.vertices[active].point.x; - hull_point.y = last_point->y + stroker->pen.vertices[active].point.y; - _cairo_polygon_add_edge (&stroker->polygon, - last_hull_point, &hull_point, - step); - *last_hull_point = hull_point; - - /* The strict inequalities here ensure that if a spline slope - * compares identically with either of the slopes of the - * active vertex, then it remains the active vertex. This is - * very important since otherwise we can trigger an infinite - * loop in the case of a degenerate pen, (a line), where - * neither vertex considers itself active for the slope---one - * will consider it as equal and reject, and the other will - * consider it unequal and reject. This is due to the inherent - * ambiguity when comparing slopes that differ by exactly - * pi. */ - if (_cairo_slope_compare (slope, - &stroker->pen.vertices[active].slope_ccw) > 0) - { - if (++active == stroker->pen.num_vertices) - active = 0; - } - else if (_cairo_slope_compare (slope, - &stroker->pen.vertices[active].slope_cw) < 0) - { - if (--active == -1) - active = stroker->pen.num_vertices - 1; - } - else - { - return active; - } - } while (TRUE); -} - - -/* Compute outline of a given spline using the pen. - * The trapezoids needed to fill that outline will be added to traps - */ -cairo_status_t -_cairo_pen_stroke_spline (cairo_pen_stroke_spline_t *stroker, - double tolerance, - cairo_traps_t *traps) -{ - cairo_status_t status; - cairo_slope_t slope; - - /* If the line width is so small that the pen is reduced to a - single point, then we have nothing to do. */ - if (stroker->pen.num_vertices <= 1) - return CAIRO_STATUS_SUCCESS; - - /* open the polygon */ - slope = stroker->spline.initial_slope; - stroker->forward_vertex = - _cairo_pen_find_active_cw_vertex_index (&stroker->pen, &slope); - stroker->forward_hull_point.x = stroker->last_point.x + - stroker->pen.vertices[stroker->forward_vertex].point.x; - stroker->forward_hull_point.y = stroker->last_point.y + - stroker->pen.vertices[stroker->forward_vertex].point.y; - - slope.dx = -slope.dx; - slope.dy = -slope.dy; - stroker->backward_vertex = - _cairo_pen_find_active_cw_vertex_index (&stroker->pen, &slope); - stroker->backward_hull_point.x = stroker->last_point.x + - stroker->pen.vertices[stroker->backward_vertex].point.x; - stroker->backward_hull_point.y = stroker->last_point.y + - stroker->pen.vertices[stroker->backward_vertex].point.y; - - _cairo_polygon_add_edge (&stroker->polygon, - &stroker->backward_hull_point, - &stroker->forward_hull_point, - 1); - - status = _cairo_spline_decompose (&stroker->spline, tolerance); - if (unlikely (status)) - return status; - - /* close the polygon */ - slope = stroker->spline.final_slope; - _cairo_pen_stroke_spline_add_convolved_point (stroker, - &stroker->last_point, - &slope, - &stroker->forward_hull_point, - stroker->forward_vertex, - 1); - - slope.dx = -slope.dx; - slope.dy = -slope.dy; - _cairo_pen_stroke_spline_add_convolved_point (stroker, - &stroker->last_point, - &slope, - &stroker->backward_hull_point, - stroker->backward_vertex, - -1); - - _cairo_polygon_add_edge (&stroker->polygon, - &stroker->forward_hull_point, - &stroker->backward_hull_point, - 1); - - status = _cairo_polygon_status (&stroker->polygon); - if (unlikely (status)) - return status; - - status = _cairo_bentley_ottmann_tessellate_polygon (traps, - &stroker->polygon, - CAIRO_FILL_RULE_WINDING); - - return status; -} - -static cairo_status_t -_cairo_pen_stroke_spline_add_point (void *closure, - const cairo_point_t *point) -{ - cairo_pen_stroke_spline_t *stroker = closure; - cairo_slope_t slope; - - _cairo_slope_init (&slope, &stroker->last_point, point); - stroker->forward_vertex = - _cairo_pen_stroke_spline_add_convolved_point (stroker, - &stroker->last_point, - &slope, - &stroker->forward_hull_point, - stroker->forward_vertex, - 1); - - slope.dx = -slope.dx; - slope.dy = -slope.dy; - stroker->backward_vertex = - _cairo_pen_stroke_spline_add_convolved_point (stroker, - &stroker->last_point, - &slope, - &stroker->backward_hull_point, - stroker->backward_vertex, - -1); - stroker->last_point = *point; - - return CAIRO_STATUS_SUCCESS; -} - -cairo_int_status_t -_cairo_pen_stroke_spline_init (cairo_pen_stroke_spline_t *stroker, - const cairo_pen_t *pen, - const cairo_point_t *a, - const cairo_point_t *b, - const cairo_point_t *c, - const cairo_point_t *d) -{ - cairo_int_status_t status; - - if (! _cairo_spline_init (&stroker->spline, - _cairo_pen_stroke_spline_add_point, - stroker, - a, b, c, d)) - { - return CAIRO_INT_STATUS_DEGENERATE; - } - - status = _cairo_pen_init_copy (&stroker->pen, pen); - if (unlikely (status)) - return status; - - _cairo_polygon_init (&stroker->polygon); - - stroker->last_point = *a; - - return CAIRO_STATUS_SUCCESS; -} - -void -_cairo_pen_stroke_spline_fini (cairo_pen_stroke_spline_t *stroker) -{ - _cairo_polygon_fini (&stroker->polygon); - _cairo_pen_fini (&stroker->pen); -} |