cairo_clip_t * _cairo_clip_intersect_rectilinear_path (cairo_clip_t *clip, const cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, cairo_antialias_t antialias) { cairo_status_t status; cairo_boxes_t boxes; _cairo_boxes_init (&boxes); status = _cairo_path_fixed_fill_rectilinear_to_boxes (path, fill_rule, antialias, &boxes); if (likely (status == CAIRO_STATUS_SUCCESS && boxes.num_boxes)) clip = _cairo_clip_intersect_boxes (clip, &boxes); else clip = _cairo_clip_set_all_clipped (clip); _cairo_boxes_fini (&boxes); return clip; }
static cairo_int_status_t clip_and_composite_boxes (const cairo_spans_compositor_t *compositor, cairo_composite_rectangles_t *extents, cairo_boxes_t *boxes) { cairo_int_status_t status; cairo_polygon_t polygon; TRACE ((stderr, "%s\n", __FUNCTION__)); status = trim_extents_to_boxes (extents, boxes); if (unlikely (status)) return status; if (boxes->num_boxes == 0) { if (extents->is_bounded) return CAIRO_STATUS_SUCCESS; return fixup_unbounded_boxes (compositor, extents, boxes); } /* Can we reduce drawing through a clip-mask to simply drawing the clip? */ if (extents->clip->path != NULL && extents->is_bounded) { cairo_polygon_t polygon; cairo_fill_rule_t fill_rule; cairo_antialias_t antialias; cairo_clip_t *clip; clip = _cairo_clip_copy (extents->clip); clip = _cairo_clip_intersect_boxes (clip, boxes); if (_cairo_clip_is_all_clipped (clip)) return CAIRO_INT_STATUS_NOTHING_TO_DO; status = _cairo_clip_get_polygon (clip, &polygon, &fill_rule, &antialias); _cairo_clip_path_destroy (clip->path); clip->path = NULL; if (likely (status == CAIRO_INT_STATUS_SUCCESS)) { cairo_clip_t *saved_clip = extents->clip; extents->clip = clip; status = clip_and_composite_polygon (compositor, extents, &polygon, fill_rule, antialias); clip = extents->clip; extents->clip = saved_clip; _cairo_polygon_fini (&polygon); } _cairo_clip_destroy (clip); if (status != CAIRO_INT_STATUS_UNSUPPORTED) return status; } if (boxes->is_pixel_aligned) { status = composite_aligned_boxes (compositor, extents, boxes); if (status != CAIRO_INT_STATUS_UNSUPPORTED) return status; } status = composite_boxes (compositor, extents, boxes); if (status != CAIRO_INT_STATUS_UNSUPPORTED) return status; status = _cairo_polygon_init_boxes (&polygon, boxes); if (unlikely (status)) return status; status = composite_polygon (compositor, extents, &polygon, CAIRO_FILL_RULE_WINDING, CAIRO_ANTIALIAS_DEFAULT); _cairo_polygon_fini (&polygon); return status; }