--- a/src/cairo-path-stroke.c +++ b/src/cairo-path-stroke.c @@ -547,28 +547,11 @@ _compute_face (cairo_point_t *point, cai } static cairo_status_t -_cairo_stroker_add_sub_edge (cairo_stroker_t *stroker, cairo_point_t *p1, cairo_point_t *p2, - cairo_stroke_face_t *start, cairo_stroke_face_t *end) +_cairo_stroker_add_sub_edge_polygon (cairo_stroker_t *stroker, cairo_stroke_face_t *start, + cairo_stroke_face_t *end) { cairo_status_t status; cairo_polygon_t polygon; - cairo_slope_t slope; - - if (p1->x == p2->x && p1->y == p2->y) { - /* XXX: Need to rethink how this case should be handled, (both - here and in _compute_face). The key behavior is that - degenerate paths should draw as much as possible. */ - return CAIRO_STATUS_SUCCESS; - } - - _cairo_slope_init (&slope, p1, p2); - _compute_face (p1, &slope, stroker, start); - - /* XXX: This could be optimized slightly by not calling - _compute_face again but rather translating the relevant - fields from start. */ - _compute_face (p2, &slope, stroker, end); - /* XXX: I should really check the return value of the move_to/line_to functions here to catch out of memory conditions. But since that would be ugly, I'd prefer to add a @@ -596,6 +579,41 @@ _cairo_stroker_add_sub_edge (cairo_strok } static cairo_status_t +_cairo_stroker_add_sub_edge_slope (cairo_stroker_t *stroker, cairo_point_t *p1, cairo_point_t *p2, + cairo_slope_t *slope, + cairo_stroke_face_t *start, cairo_stroke_face_t *end) +{ + _compute_face (p1, slope, stroker, start); + + /* XXX: This could be optimized slightly by not calling + _compute_face again but rather translating the relevant + fields from start. */ + _compute_face (p2, slope, stroker, end); + + if (p1->x == p2->x && p1->y == p2->y) + return CAIRO_STATUS_SUCCESS; + else + return _cairo_stroker_add_sub_edge_polygon (stroker, start, end); +} + +static cairo_status_t +_cairo_stroker_add_sub_edge (cairo_stroker_t *stroker, cairo_point_t *p1, cairo_point_t *p2, + cairo_stroke_face_t *start, cairo_stroke_face_t *end) +{ + cairo_slope_t slope; + + _cairo_slope_init (&slope, p1, p2); + _compute_face (p1, &slope, stroker, start); + + /* XXX: This could be optimized slightly by not calling + _compute_face again but rather translating the relevant + fields from start. */ + _compute_face (p2, &slope, stroker, end); + + return _cairo_stroker_add_sub_edge_polygon (stroker, start, end); +} + +static cairo_status_t _cairo_stroker_move_to (void *closure, cairo_point_t *point) { cairo_status_t status; @@ -665,6 +683,7 @@ _cairo_stroker_line_to_dashed (void *clo { cairo_status_t status = CAIRO_STATUS_SUCCESS; cairo_stroker_t *stroker = closure; + cairo_slope_t slope; double mag, remain, tmp; double dx, dy; double dx2, dy2; @@ -676,6 +695,16 @@ _cairo_stroker_line_to_dashed (void *clo if (!stroker->has_current_point) return _cairo_stroker_move_to (stroker, point); + + if (p1->x == p2->x && p1->y == p2->y) { + /* XXX: Need to rethink how this case should be handled, (both + here and in _compute_face). The key behavior is that + degenerate paths should draw as much as possible. */ + return CAIRO_STATUS_SUCCESS; + } + + /* compute the slope once for the entire line */ + _cairo_slope_init (&slope, p1, p2); dx = _cairo_fixed_to_double (p2->x - p1->x); dy = _cairo_fixed_to_double (p2->y - p1->y); @@ -700,8 +729,9 @@ _cairo_stroker_line_to_dashed (void *clo /* * XXX simplify this case analysis */ + if (stroker->dash_on) { - status = _cairo_stroker_add_sub_edge (stroker, &fd1, &fd2, &sub_start, &sub_end); + status = _cairo_stroker_add_sub_edge_slope (stroker, &fd1, &fd2, &slope, &sub_start, &sub_end); if (status) return status; if (!first) {