cairo_clip_t * _cairo_clip_intersect_boxes (cairo_clip_t *clip, const cairo_boxes_t *boxes) { cairo_boxes_t clip_boxes; cairo_box_t limits; cairo_rectangle_int_t extents; if (_cairo_clip_is_all_clipped (clip)) return clip; if (boxes->num_boxes == 0) return _cairo_clip_set_all_clipped (clip); if (boxes->num_boxes == 1) return _cairo_clip_intersect_box (clip, boxes->chunks.base); if (clip == NULL) clip = _cairo_clip_create (); if (clip->num_boxes) { _cairo_boxes_init_for_array (&clip_boxes, clip->boxes, clip->num_boxes); if (unlikely (_cairo_boxes_intersect (&clip_boxes, boxes, &clip_boxes))) { clip = _cairo_clip_set_all_clipped (clip); goto out; } if (clip->boxes != &clip->embedded_box) free (clip->boxes); clip->boxes = NULL; boxes = &clip_boxes; } if (boxes->num_boxes == 0) { clip = _cairo_clip_set_all_clipped (clip); goto out; } else if (boxes->num_boxes == 1) { clip->boxes = &clip->embedded_box; clip->boxes[0] = boxes->chunks.base[0]; clip->num_boxes = 1; } else { clip->boxes = _cairo_boxes_to_array (boxes, &clip->num_boxes, TRUE); } _cairo_boxes_extents (boxes, &limits); _cairo_box_round_to_rectangle (&limits, &extents); if (clip->path == NULL) clip->extents = extents; else if (! _cairo_rectangle_intersect (&clip->extents, &extents)) clip = _cairo_clip_set_all_clipped (clip); if (clip->region) { cairo_region_destroy (clip->region); clip->region = NULL; } clip->is_region = FALSE; out: if (boxes == &clip_boxes) _cairo_boxes_fini (&clip_boxes); return clip; }
static cairo_int_status_t fixup_unbounded_boxes (const cairo_spans_compositor_t *compositor, const cairo_composite_rectangles_t *extents, cairo_boxes_t *boxes) { cairo_boxes_t tmp, clear; cairo_box_t box; cairo_int_status_t status; assert (boxes->is_pixel_aligned); TRACE ((stderr, "%s\n", __FUNCTION__)); if (extents->bounded.width == extents->unbounded.width && extents->bounded.height == extents->unbounded.height) { return CAIRO_STATUS_SUCCESS; } /* subtract the drawn boxes from the unbounded area */ _cairo_boxes_init (&clear); box.p1.x = _cairo_fixed_from_int (extents->unbounded.x + extents->unbounded.width); box.p1.y = _cairo_fixed_from_int (extents->unbounded.y); box.p2.x = _cairo_fixed_from_int (extents->unbounded.x); box.p2.y = _cairo_fixed_from_int (extents->unbounded.y + extents->unbounded.height); if (boxes->num_boxes) { _cairo_boxes_init (&tmp); status = _cairo_boxes_add (&tmp, CAIRO_ANTIALIAS_DEFAULT, &box); assert (status == CAIRO_INT_STATUS_SUCCESS); tmp.chunks.next = &boxes->chunks; tmp.num_boxes += boxes->num_boxes; status = _cairo_bentley_ottmann_tessellate_boxes (&tmp, CAIRO_FILL_RULE_WINDING, &clear); tmp.chunks.next = NULL; if (unlikely (status)) goto error; } else { box.p1.x = _cairo_fixed_from_int (extents->unbounded.x); box.p2.x = _cairo_fixed_from_int (extents->unbounded.x + extents->unbounded.width); status = _cairo_boxes_add (&clear, CAIRO_ANTIALIAS_DEFAULT, &box); assert (status == CAIRO_INT_STATUS_SUCCESS); } /* If we have a clip polygon, we need to intersect with that as well */ if (extents->clip->path) { status = fixup_unbounded_polygon (compositor, extents, &clear); if (status == CAIRO_INT_STATUS_UNSUPPORTED) status = fixup_unbounded_mask (compositor, extents, &clear); } else { /* Otherwise just intersect with the clip boxes */ if (extents->clip->num_boxes) { _cairo_boxes_init_for_array (&tmp, extents->clip->boxes, extents->clip->num_boxes); status = _cairo_boxes_intersect (&clear, &tmp, &clear); if (unlikely (status)) goto error; } if (clear.is_pixel_aligned) { status = compositor->fill_boxes (extents->surface, CAIRO_OPERATOR_CLEAR, CAIRO_COLOR_TRANSPARENT, &clear); } else { cairo_composite_rectangles_t composite; status = _cairo_composite_rectangles_init_for_boxes (&composite, extents->surface, CAIRO_OPERATOR_CLEAR, &_cairo_pattern_clear.base, &clear, NULL); if (likely (status == CAIRO_INT_STATUS_SUCCESS)) { status = composite_boxes (compositor, &composite, &clear); _cairo_composite_rectangles_fini (&composite); } } } error: _cairo_boxes_fini (&clear); return status; }