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); }
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; } }