Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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, &region);

    if (status)
	return status;

    status = CAIRO_STATUS_SUCCESS;

    if (!clip->has_region) {
        status = _cairo_region_copy (&clip->region, &region);
	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,
		                         &region);

	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 (&region);

    if (! _cairo_region_not_empty (&clip->region))
	_cairo_clip_set_all_clipped (clip, target);

    return status;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;
}