cairo_status_t _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other) { clip->mode = other->mode; clip->all_clipped = other->all_clipped; clip->surface = cairo_surface_reference (other->surface); clip->surface_rect = other->surface_rect; clip->serial = other->serial; _cairo_region_init (&clip->region); if (other->has_region) { cairo_status_t status; status = _cairo_region_copy (&clip->region, &other->region); if (status) { _cairo_region_fini (&clip->region); cairo_surface_destroy (clip->surface); return status; } clip->has_region = TRUE; } else { clip->has_region = FALSE; } clip->path = _cairo_clip_path_reference (other->path); return CAIRO_STATUS_SUCCESS; }
static cairo_int_status_t _cairo_clip_intersect_region (cairo_clip_t *clip, cairo_traps_t *traps, cairo_surface_t *target) { cairo_region_t region; cairo_int_status_t status; if (clip->all_clipped) return CAIRO_STATUS_SUCCESS; if (clip->mode != CAIRO_CLIP_MODE_REGION) return CAIRO_INT_STATUS_UNSUPPORTED; status = _cairo_traps_extract_region (traps, ®ion); if (status) return status; status = CAIRO_STATUS_SUCCESS; if (!clip->has_region) { status = _cairo_region_copy (&clip->region, ®ion); if (status == CAIRO_STATUS_SUCCESS) clip->has_region = TRUE; } else { cairo_region_t intersection; _cairo_region_init (&intersection); status = _cairo_region_intersect (&intersection, &clip->region, ®ion); if (status == CAIRO_STATUS_SUCCESS) status = _cairo_region_copy (&clip->region, &intersection); _cairo_region_fini (&intersection); } clip->serial = _cairo_surface_allocate_clip_serial (target); _cairo_region_fini (®ion); if (! _cairo_region_not_empty (&clip->region)) _cairo_clip_set_all_clipped (clip, target); return status; }
cairo_status_t _cairo_clip_init_deep_copy (cairo_clip_t *clip, cairo_clip_t *other, cairo_surface_t *target) { cairo_status_t status; _cairo_clip_init (clip, target); if (other->mode != clip->mode) { /* We should reapply the original clip path in this case, and let * whatever the right handling is happen */ } else { if (other->has_region) { status = _cairo_region_copy (&clip->region, &other->region); if (unlikely (status)) goto BAIL; clip->has_region = TRUE; } if (other->surface) { int dx, dy; status = _cairo_surface_clone_similar (target, other->surface, 0, 0, other->surface_rect.width, other->surface_rect.height, &dx, &dy, &clip->surface); if (unlikely (status)) goto BAIL; clip->surface_rect = other->surface_rect; /* src offset was 0, so we expect an exact replica of the surface */ assert (dx == 0); assert (dy == 0); } if (other->path) { status = _cairo_clip_path_reapply_clip_path (clip, other->path); if (_cairo_status_is_error (status)) goto BAIL; } } return CAIRO_STATUS_SUCCESS; BAIL: if (clip->has_region) _cairo_region_fini (&clip->region); if (clip->surface) cairo_surface_destroy (clip->surface); return status; }
cairo_status_t _cairo_clip_init_deep_copy (cairo_clip_t *clip, cairo_clip_t *other, cairo_surface_t *target) { cairo_status_t status; _cairo_clip_init (clip, target); if (other->mode != clip->mode) { /* We should reapply the original clip path in this case, and let * whatever the right handling is happen */ } else { if (other->has_region) { status = _cairo_region_copy (&clip->region, &other->region); if (status) goto BAIL; clip->has_region = TRUE; } if (other->surface) { status = _cairo_surface_clone_similar (target, other->surface, other->surface_rect.x, other->surface_rect.y, other->surface_rect.width, other->surface_rect.height, &clip->surface); if (status) goto BAIL; clip->surface_rect = other->surface_rect; } if (other->path) { status = _cairo_clip_path_reapply_clip_path (clip, other->path); if (status && status != CAIRO_INT_STATUS_UNSUPPORTED) goto BAIL; } } return CAIRO_STATUS_SUCCESS; BAIL: if (clip->has_region) _cairo_region_fini (&clip->region); if (clip->surface) cairo_surface_destroy (clip->surface); return status; }