Ejemplo n.º 1
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_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;
}
Ejemplo n.º 2
0
static void
contour_add_point (struct stroker *stroker,
		   struct stroke_contour *c,
		   const cairo_point_t *point)
{
    if (! within_tolerance (point, _cairo_contour_last_point (&c->contour),
			stroker->contour_tolerance))
	_cairo_contour_add_point (&c->contour, point);
    //*_cairo_contour_last_point (&c->contour) = *point;
}
Ejemplo n.º 3
0
cairo_int_status_t
_cairo_contour_add (cairo_contour_t *dst,
		    const cairo_contour_t *src)
{
    const cairo_contour_chain_t *chain;
    cairo_int_status_t status;
    int i;

    for (chain = &src->chain; chain; chain = chain->next) {
	for (i = 0; i < chain->num_points; i++) {
	    status = _cairo_contour_add_point (dst, &chain->points[i]);
	    if (unlikely (status))
		return status;
	}
    }

    return CAIRO_INT_STATUS_SUCCESS;
}
Ejemplo n.º 4
0
cairo_int_status_t
_cairo_contour_add_reversed (cairo_contour_t *dst,
			     const cairo_contour_t *src)
{
    const cairo_contour_chain_t *last;
    cairo_int_status_t status;
    int i;

    if (src->chain.num_points == 0)
	return CAIRO_INT_STATUS_SUCCESS;

    for (last = src->tail; last; last = prev_const_chain (src, last)) {
	for (i = last->num_points-1; i >= 0; i--) {
	    status = _cairo_contour_add_point (dst, &last->points[i]);
	    if (unlikely (status))
		return status;
	}
    }

    return CAIRO_INT_STATUS_SUCCESS;
}
Ejemplo n.º 5
0
static cairo_status_t
move_to (void *closure,
	 const cairo_point_t *point)
{
    struct stroker *stroker = closure;

    /* Cap the start and end of the previous sub path as needed */
    add_caps (stroker);

    stroker->has_first_face = FALSE;
    stroker->has_current_face = FALSE;
    stroker->has_initial_sub_path = FALSE;

    stroker->first_point = *point;

#if DEBUG
    _cairo_contour_add_point (&stroker->path, point);
#endif

    stroker->current_face.point = *point;

    return CAIRO_STATUS_SUCCESS;
}
Ejemplo n.º 6
0
static void
add_caps (struct stroker *stroker)
{
    /* check for a degenerative sub_path */
    if (stroker->has_initial_sub_path &&
	! stroker->has_first_face &&
	! stroker->has_current_face &&
	stroker->style.line_cap == CAIRO_LINE_CAP_ROUND)
    {
	/* pick an arbitrary slope to use */
	cairo_slope_t slope = { CAIRO_FIXED_ONE, 0 };
	cairo_stroke_face_t face;

	/* arbitrarily choose first_point */
	compute_face (&stroker->first_point, &slope, stroker, &face);

	add_leading_cap (stroker, &face, &stroker->ccw);
	add_trailing_cap (stroker, &face, &stroker->ccw);

	/* ensure the circle is complete */
	_cairo_contour_add_point (&stroker->ccw.contour,
				  _cairo_contour_first_point (&stroker->ccw.contour));

	_cairo_polygon_add_contour (stroker->polygon, &stroker->ccw.contour);
	_cairo_contour_reset (&stroker->ccw.contour);
    } else {
	if (stroker->has_current_face)
	    add_trailing_cap (stroker, &stroker->current_face, &stroker->ccw);

#if DEBUG
	{
	    FILE *file = fopen ("contours.txt", "a");
	    _cairo_debug_print_contour (file, &stroker->path);
	    _cairo_debug_print_contour (file, &stroker->cw.contour);
	    _cairo_debug_print_contour (file, &stroker->ccw.contour);
	    fclose (file);
	    _cairo_contour_reset (&stroker->path);
	}
#endif

	_cairo_polygon_add_contour (stroker->polygon, &stroker->ccw.contour);
	_cairo_contour_reset (&stroker->ccw.contour);

	if (stroker->has_first_face) {
	    _cairo_contour_add_point (&stroker->ccw.contour,
				      &stroker->first_face.cw);
	    add_leading_cap (stroker, &stroker->first_face, &stroker->ccw);
#if DEBUG
	    {
		FILE *file = fopen ("contours.txt", "a");
		_cairo_debug_print_contour (file, &stroker->ccw.contour);
		fclose (file);
	    }
#endif

	    _cairo_polygon_add_contour (stroker->polygon,
					&stroker->ccw.contour);
	    _cairo_contour_reset (&stroker->ccw.contour);
	}

	_cairo_polygon_add_contour (stroker->polygon, &stroker->cw.contour);
	_cairo_contour_reset (&stroker->cw.contour);
    }
}
Ejemplo n.º 7
0
static cairo_status_t
spline_to (void *closure,
	   const cairo_point_t *point,
	   const cairo_slope_t *tangent)
{
    struct stroker *stroker = closure;
    cairo_stroke_face_t face;

#if DEBUG
    _cairo_contour_add_point (&stroker->path, point);
#endif
    if ((tangent->dx | tangent->dy) == 0) {
	const cairo_point_t *inpt, *outpt;
	struct stroke_contour *outer;
	cairo_point_t t;
	int clockwise;

	face = stroker->current_face;

	face.usr_vector.x = -face.usr_vector.x;
	face.usr_vector.y = -face.usr_vector.y;
	face.dev_vector.dx = -face.dev_vector.dx;
	face.dev_vector.dy = -face.dev_vector.dy;

	t = face.cw;
	face.cw = face.ccw;
	face.ccw = t;

	clockwise = join_is_clockwise (&stroker->current_face, &face);
	if (clockwise) {
	    inpt = &stroker->current_face.cw;
	    outpt = &face.cw;
	    outer = &stroker->cw;
	} else {
	    inpt = &stroker->current_face.ccw;
	    outpt = &face.ccw;
	    outer = &stroker->ccw;
	}

	add_fan (stroker,
		 &stroker->current_face.dev_vector,
		 &face.dev_vector,
		 &stroker->current_face.point,
		 clockwise, outer);
    } else {
	compute_face (point, tangent, stroker, &face);

	if ((face.dev_slope.x * stroker->current_face.dev_slope.x +
	     face.dev_slope.y * stroker->current_face.dev_slope.y) < stroker->spline_cusp_tolerance)
	{
	    const cairo_point_t *inpt, *outpt;
	    struct stroke_contour *outer;
	    int clockwise = join_is_clockwise (&stroker->current_face, &face);

	    stroker->current_face.cw.x += face.point.x - stroker->current_face.point.x;
	    stroker->current_face.cw.y += face.point.y - stroker->current_face.point.y;
	    contour_add_point (stroker, &stroker->cw, &stroker->current_face.cw);

	    stroker->current_face.ccw.x += face.point.x - stroker->current_face.point.x;
	    stroker->current_face.ccw.y += face.point.y - stroker->current_face.point.y;
	    contour_add_point (stroker, &stroker->ccw, &stroker->current_face.ccw);

	    if (clockwise) {
		inpt = &stroker->current_face.cw;
		outpt = &face.cw;
		outer = &stroker->cw;
	    } else {
		inpt = &stroker->current_face.ccw;
		outpt = &face.ccw;
		outer = &stroker->ccw;
	    }
	    add_fan (stroker,
		     &stroker->current_face.dev_vector,
		     &face.dev_vector,
		     &stroker->current_face.point,
		     clockwise, outer);
	}

	contour_add_point (stroker, &stroker->cw, &face.cw);
	contour_add_point (stroker, &stroker->ccw, &face.ccw);
    }

    stroker->current_face = face;

    return CAIRO_STATUS_SUCCESS;
}