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;
}
示例#2
0
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;
}
示例#3
0
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);
}