Exemplo n.º 1
0
static cairo_bool_t
within_tolerance (const cairo_point_t *p1,
	      const cairo_point_t *p2,
	      cairo_uint64_t tolerance)
{
    return FALSE;
    return _cairo_int64_lt (point_distance_sq (p1, p2), tolerance);
}
Exemplo n.º 2
0
void
_cairo_contour_simplify (cairo_contour_t *contour, double tolerance)
{
    cairo_contour_chain_t *chain;
    cairo_point_t *last = NULL;
    cairo_contour_iter_t iter, furthest;
    cairo_bool_t simplified;
    uint64_t max = 0;
    int i;

    if (contour->chain.num_points <= 2)
	return;

    tolerance = tolerance * CAIRO_FIXED_ONE;
    tolerance *= tolerance;

    /* stage 1: vertex reduction */
    for (chain = &contour->chain; chain; chain = chain->next) {
	for (i = 0; i < chain->num_points; i++) {
	    if (last == NULL ||
		point_distance_sq (last, &chain->points[i]) > tolerance) {
		last = &chain->points[i];
	    } else {
		MARK_DELETED (&chain->points[i]);
	    }
	}
    }

    /* stage2: polygon simplification using Douglas-Peucker */
    simplified = FALSE;
    do {
	last = &contour->chain.points[0];
	iter_init (&furthest, contour);
	max = 0;
	for (chain = &contour->chain; chain; chain = chain->next) {
	    for (i = 0; i < chain->num_points; i++) {
		uint64_t d;

		if (DELETED (&chain->points[i]))
		    continue;

		d = point_distance_sq (last, &chain->points[i]);
		if (d > max) {
		    furthest.chain = chain;
		    furthest.point = &chain->points[i];
		    max = d;
		}
	    }
	}
	assert (max);

	simplified = FALSE;
	iter_init (&iter, contour);
	simplified |= _cairo_contour_simplify_chain (contour, tolerance,
						     &iter, &furthest);

	iter_init_last (&iter, contour);
	if (! iter_equal (&furthest, &iter))
	    simplified |= _cairo_contour_simplify_chain (contour, tolerance,
							 &furthest, &iter);
    } while (simplified);

    iter_init (&iter, contour);
    for (chain = &contour->chain; chain; chain = chain->next) {
	int num_points = chain->num_points;
	chain->num_points = 0;
	for (i = 0; i < num_points; i++) {
	    if (! DELETED(&chain->points[i])) {
		if (iter.point != &chain->points[i])
		    *iter.point = chain->points[i];
		iter.chain->num_points++;
		iter_next (&iter);
	    }
	}
    }

    if (iter.chain) {
	cairo_contour_chain_t *next;

	for (chain = iter.chain->next; chain; chain = next) {
	    next = chain->next;
	    free (chain);
	}

	iter.chain->next = NULL;
	contour->tail = iter.chain;
    }
}