static cairo_status_t line_to (void *closure, const cairo_point_t *point) { struct stroker *stroker = closure; cairo_stroke_face_t start; cairo_point_t *p1 = &stroker->current_face.point; cairo_slope_t dev_slope; stroker->has_initial_sub_path = TRUE; if (p1->x == point->x && p1->y == point->y) return CAIRO_STATUS_SUCCESS; #if DEBUG _cairo_contour_add_point (&stroker->path, point); #endif _cairo_slope_init (&dev_slope, p1, point); compute_face (p1, &dev_slope, stroker, &start); if (stroker->has_current_face) { int clockwise = _cairo_slope_compare (&stroker->current_face.dev_vector, &start.dev_vector); if (clockwise) { clockwise = clockwise < 0; /* Join with final face from previous segment */ if (! within_tolerance (&stroker->current_face.ccw, &start.ccw, stroker->contour_tolerance) || ! within_tolerance (&stroker->current_face.cw, &start.cw, stroker->contour_tolerance)) { outer_join (stroker, &stroker->current_face, &start, clockwise); inner_join (stroker, &stroker->current_face, &start, clockwise); } } } else { if (! stroker->has_first_face) { /* Save sub path's first face in case needed for closing join */ stroker->first_face = start; stroker->has_first_face = TRUE; } stroker->has_current_face = TRUE; contour_add_point (stroker, &stroker->cw, &start.cw); contour_add_point (stroker, &stroker->ccw, &start.ccw); } stroker->current_face = start; stroker->current_face.point = *point; stroker->current_face.ccw.x += dev_slope.dx; stroker->current_face.ccw.y += dev_slope.dy; stroker->current_face.cw.x += dev_slope.dx; stroker->current_face.cw.y += dev_slope.dy; contour_add_point (stroker, &stroker->cw, &stroker->current_face.cw); contour_add_point (stroker, &stroker->ccw, &stroker->current_face.ccw); return CAIRO_STATUS_SUCCESS; }
static cairo_status_t line_to (void *closure, const cairo_point_t *point) { struct stroker *stroker = closure; cairo_stroke_face_t start; cairo_point_t *p1 = &stroker->current_face.point; cairo_slope_t dev_slope; stroker->has_sub_path = TRUE; if (p1->x == point->x && p1->y == point->y) return CAIRO_STATUS_SUCCESS; _cairo_slope_init (&dev_slope, p1, point); compute_face (p1, &dev_slope, stroker, &start); if (stroker->has_current_face) { int clockwise = join_is_clockwise (&stroker->current_face, &start); /* Join with final face from previous segment */ outer_join (stroker, &stroker->current_face, &start, clockwise); inner_join (stroker, &stroker->current_face, &start, clockwise); } else { if (! stroker->has_first_face) { /* Save sub path's first face in case needed for closing join */ stroker->first_face = start; _cairo_tristrip_move_to (stroker->strip, &start.cw); stroker->has_first_face = TRUE; } stroker->has_current_face = TRUE; _cairo_tristrip_add_point (stroker->strip, &start.cw); _cairo_tristrip_add_point (stroker->strip, &start.ccw); } stroker->current_face = start; stroker->current_face.point = *point; stroker->current_face.ccw.x += dev_slope.dx; stroker->current_face.ccw.y += dev_slope.dy; stroker->current_face.cw.x += dev_slope.dx; stroker->current_face.cw.y += dev_slope.dy; _cairo_tristrip_add_point (stroker->strip, &stroker->current_face.cw); _cairo_tristrip_add_point (stroker->strip, &stroker->current_face.ccw); return CAIRO_STATUS_SUCCESS; }
static cairo_status_t curve_to (void *closure, const cairo_point_t *b, const cairo_point_t *c, const cairo_point_t *d) { struct stroker *stroker = closure; cairo_spline_t spline; cairo_stroke_face_t face; if (stroker->has_limits) { if (! _cairo_spline_intersects (&stroker->current_face.point, b, c, d, &stroker->limit)) return line_to (closure, d); } if (! _cairo_spline_init (&spline, spline_to, stroker, &stroker->current_face.point, b, c, d)) return line_to (closure, d); compute_face (&stroker->current_face.point, &spline.initial_slope, stroker, &face); if (stroker->has_current_face) { int clockwise = join_is_clockwise (&stroker->current_face, &face); /* Join with final face from previous segment */ outer_join (stroker, &stroker->current_face, &face, clockwise); inner_join (stroker, &stroker->current_face, &face, clockwise); } else { if (! stroker->has_first_face) { /* Save sub path's first face in case needed for closing join */ stroker->first_face = face; _cairo_tristrip_move_to (stroker->strip, &face.cw); stroker->has_first_face = TRUE; } stroker->has_current_face = TRUE; _cairo_tristrip_add_point (stroker->strip, &face.cw); _cairo_tristrip_add_point (stroker->strip, &face.ccw); } stroker->current_face = face; return _cairo_spline_decompose (&spline, stroker->tolerance); }