Exemplo n.º 1
0
static cairo_status_t
_cairo_pen_stroke_spline_half (cairo_pen_t *pen,
			       cairo_spline_t *spline,
			       cairo_direction_t dir,
			       cairo_polygon_t *polygon)
{
    int i;
    cairo_status_t status;
    int start, stop, step;
    int active = 0;
    cairo_point_t hull_point;
    cairo_slope_t slope, initial_slope, final_slope;
    cairo_point_t *point = spline->points;
    int num_points = spline->num_points;

    if (dir == CAIRO_DIRECTION_FORWARD) {
	start = 0;
	stop = num_points;
	step = 1;
	initial_slope = spline->initial_slope;
	final_slope = spline->final_slope;
    } else {
	start = num_points - 1;
	stop = -1;
	step = -1;
	initial_slope = spline->final_slope;
	initial_slope.dx = -initial_slope.dx;
	initial_slope.dy = -initial_slope.dy;
	final_slope = spline->initial_slope;
	final_slope.dx = -final_slope.dx; 
	final_slope.dy = -final_slope.dy; 
    }

    _cairo_pen_find_active_cw_vertex_index (pen, &initial_slope, &active);

    i = start;
    while (i != stop) {
	hull_point.x = point[i].x + pen->vertices[active].point.x;
	hull_point.y = point[i].y + pen->vertices[active].point.y;
	status = _cairo_polygon_line_to (polygon, &hull_point);
	if (status)
	    return status;

	if (i + step == stop)
	    slope = final_slope;
	else
	    _cairo_slope_init (&slope, &point[i], &point[i+step]);
	if (_cairo_slope_counter_clockwise (&slope, &pen->vertices[active].slope_ccw)) {
	    if (++active == pen->num_vertices)
		active = 0;
	} else if (_cairo_slope_clockwise (&slope, &pen->vertices[active].slope_cw)) {
	    if (--active == -1)
		active = pen->num_vertices - 1;
	} else {
	    i += step;
	}
    }

    return CAIRO_STATUS_SUCCESS;
}
Exemplo n.º 2
0
static cairo_status_t
_cairo_filler_curve_to (void *closure,
			cairo_point_t *b,
			cairo_point_t *c,
			cairo_point_t *d)
{
    int i;
    cairo_status_t status = CAIRO_STATUS_SUCCESS;
    cairo_filler_t *filler = closure;
    cairo_polygon_t *polygon = &filler->polygon;
    cairo_spline_t spline;

    status = _cairo_spline_init (&spline, &filler->current_point, b, c, d);

    if (status == CAIRO_INT_STATUS_DEGENERATE)
	return CAIRO_STATUS_SUCCESS;

    _cairo_spline_decompose (&spline, filler->tolerance);
    if (status)
	goto CLEANUP_SPLINE;

    for (i = 1; i < spline.num_points; i++) {
	status = _cairo_polygon_line_to (polygon, &spline.points[i]);
	if (status)
	    break;
    }

  CLEANUP_SPLINE:
    _cairo_spline_fini (&spline);

    filler->current_point = *d;

    return status;
}
static cairo_status_t
_cairo_filler_line_to (void *closure,
		       const cairo_point_t *point)
{
    cairo_filler_t *filler = closure;
    return _cairo_polygon_line_to (filler->polygon, point);
}
Exemplo n.º 4
0
static cairo_status_t
_cairo_filler_line_to (void *closure, cairo_point_t *point)
{
    cairo_filler_t *filler = closure;
    cairo_polygon_t *polygon = &filler->polygon;

    _cairo_polygon_line_to (polygon, point);

    filler->current_point = *point;

    return _cairo_polygon_status (&filler->polygon);
}
Exemplo n.º 5
0
static cairo_status_t
_cairo_filler_line_to (void *closure, cairo_point_t *point)
{
    cairo_status_t status;
    cairo_filler_t *filler = closure;
    cairo_polygon_t *polygon = &filler->polygon;

    status = _cairo_polygon_line_to (polygon, point);
    if (status)
	return status;

    filler->current_point = *point;

    return CAIRO_STATUS_SUCCESS;
}
Exemplo n.º 6
0
cairo_status_t
_cairo_polygon_close (cairo_polygon_t *polygon)
{
    cairo_status_t status;

    if (polygon->has_current_point) {
	status = _cairo_polygon_line_to (polygon, &polygon->first_point);
	polygon->has_current_point = FALSE;
    }

    if (polygon->has_current_edge) {
	_cairo_polygon_add_edge (polygon,
				 &polygon->last_point,
				 &polygon->current_point);
	polygon->has_current_edge = FALSE;
    }

    return polygon->status;
}
Exemplo n.º 7
0
static cairo_status_t
_cairo_stroker_add_cap (cairo_stroker_t *stroker, cairo_stroke_face_t *f)
{
    cairo_status_t	    status;

    if (stroker->style->line_cap == CAIRO_LINE_CAP_BUTT)
	return CAIRO_STATUS_SUCCESS;

    switch (stroker->style->line_cap) {
    case CAIRO_LINE_CAP_ROUND: {
	int i;
	int start, stop;
	cairo_slope_t slope;
	cairo_point_t tri[3];
	cairo_pen_t *pen = &stroker->pen;

	slope = f->dev_vector;
	start = _cairo_pen_find_active_cw_vertex_index (pen, &slope);
	slope.dx = -slope.dx;
	slope.dy = -slope.dy;
	stop = _cairo_pen_find_active_cw_vertex_index (pen, &slope);

	tri[0] = f->point;
	tri[1] = f->cw;
	for (i=start; i != stop; i = (i+1) % pen->num_vertices) {
	    tri[2] = f->point;
	    _translate_point (&tri[2], &pen->vertices[i].point);
	    status = _cairo_traps_tessellate_triangle (stroker->traps, tri);
	    if (unlikely (status))
		return status;
	    tri[1] = tri[2];
	}
	tri[2] = f->ccw;

	return _cairo_traps_tessellate_triangle (stroker->traps, tri);
    }
    case CAIRO_LINE_CAP_SQUARE: {
	double dx, dy;
	cairo_slope_t	fvector;
	cairo_point_t	occw, ocw;
	cairo_polygon_t	polygon;

	dx = f->usr_vector.x;
	dy = f->usr_vector.y;
	dx *= stroker->style->line_width / 2.0;
	dy *= stroker->style->line_width / 2.0;
	cairo_matrix_transform_distance (stroker->ctm, &dx, &dy);
	fvector.dx = _cairo_fixed_from_double (dx);
	fvector.dy = _cairo_fixed_from_double (dy);
	occw.x = f->ccw.x + fvector.dx;
	occw.y = f->ccw.y + fvector.dy;
	ocw.x = f->cw.x + fvector.dx;
	ocw.y = f->cw.y + fvector.dy;

	_cairo_polygon_init (&polygon);
	_cairo_polygon_move_to (&polygon, &f->cw);
	_cairo_polygon_line_to (&polygon, &ocw);
	_cairo_polygon_line_to (&polygon, &occw);
	_cairo_polygon_line_to (&polygon, &f->ccw);
	_cairo_polygon_close (&polygon);
	status = _cairo_polygon_status (&polygon);

	if (status == CAIRO_STATUS_SUCCESS) {
	    status = _cairo_bentley_ottmann_tessellate_polygon (stroker->traps,
								&polygon,
								CAIRO_FILL_RULE_WINDING);
	}

	_cairo_polygon_fini (&polygon);

	return status;
    }
    case CAIRO_LINE_CAP_BUTT:
    default:
	return CAIRO_STATUS_SUCCESS;
    }
}
Exemplo n.º 8
0
static void
_cairo_pen_stroke_spline_half (cairo_pen_t *pen,
			       cairo_spline_t *spline,
			       cairo_direction_t dir,
			       cairo_polygon_t *polygon)
{
    int i;
    int start, stop, step;
    int active = 0;
    cairo_point_t hull_point;
    cairo_slope_t slope, initial_slope, final_slope;
    cairo_point_t *point = spline->points;
    int num_points = spline->num_points;

    if (dir == CAIRO_DIRECTION_FORWARD) {
	start = 0;
	stop = num_points;
	step = 1;
	initial_slope = spline->initial_slope;
	final_slope = spline->final_slope;
    } else {
	start = num_points - 1;
	stop = -1;
	step = -1;
	initial_slope = spline->final_slope;
	initial_slope.dx = -initial_slope.dx;
	initial_slope.dy = -initial_slope.dy;
	final_slope = spline->initial_slope;
	final_slope.dx = -final_slope.dx;
	final_slope.dy = -final_slope.dy;
    }

    _cairo_pen_find_active_cw_vertex_index (pen,
	                                    &initial_slope,
					    &active);

    i = start;
    while (i != stop) {
	hull_point.x = point[i].x + pen->vertices[active].point.x;
	hull_point.y = point[i].y + pen->vertices[active].point.y;

	_cairo_polygon_line_to (polygon, &hull_point);

	if (i + step == stop)
	    slope = final_slope;
	else
	    _cairo_slope_init (&slope, &point[i], &point[i+step]);

	/* 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, &pen->vertices[active].slope_ccw) > 0) {
	    if (++active == pen->num_vertices)
		active = 0;
	} else if (_cairo_slope_compare (&slope, &pen->vertices[active].slope_cw) < 0) {
	    if (--active == -1)
		active = pen->num_vertices - 1;
	} else {
	    i += step;
	}
    }
}