cairo_bool_t _cairo_path_fixed_in_fill (const cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, double x, double y) { cairo_in_fill_t in_fill; cairo_status_t status; cairo_bool_t is_inside; if (_cairo_path_fixed_fill_is_empty (path)) return FALSE; _cairo_in_fill_init (&in_fill, tolerance, x, y); status = _cairo_path_fixed_interpret (path, _cairo_in_fill_move_to, _cairo_in_fill_line_to, _cairo_in_fill_curve_to, _cairo_in_fill_close_path, &in_fill); assert (status == CAIRO_STATUS_SUCCESS); _cairo_in_fill_close_path (&in_fill); if (in_fill.on_edge) { is_inside = TRUE; } else switch (fill_rule) { case CAIRO_FILL_RULE_EVEN_ODD: is_inside = in_fill.winding & 1; break; case CAIRO_FILL_RULE_WINDING: is_inside = in_fill.winding != 0; break; default: ASSERT_NOT_REACHED; is_inside = FALSE; break; } _cairo_in_fill_fini (&in_fill); return is_inside; }
cairo_status_t _cairo_clip_clip (cairo_clip_t *clip, const cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias) { if (clip->all_clipped) return CAIRO_STATUS_SUCCESS; /* catch the empty clip path */ if (_cairo_path_fixed_fill_is_empty (path)) { _cairo_clip_set_all_clipped (clip); return CAIRO_STATUS_SUCCESS; } return _cairo_clip_intersect_path (clip, path, fill_rule, tolerance, antialias); }
cairo_status_t _cairo_path_fixed_fill_to_traps (const cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, cairo_traps_t *traps) { cairo_polygon_t polygon; cairo_status_t status; if (_cairo_path_fixed_fill_is_empty (path)) return CAIRO_STATUS_SUCCESS; _cairo_polygon_init (&polygon, traps->limits, traps->num_limits); status = _cairo_path_fixed_fill_to_polygon (path, tolerance, &polygon); if (unlikely (status || polygon.num_edges == 0)) goto CLEANUP; status = _cairo_bentley_ottmann_tessellate_polygon (traps, &polygon, fill_rule); CLEANUP: _cairo_polygon_fini (&polygon); return status; }