Exemple #1
0
cairo_surface_t *
_cairo_clip_get_image (const cairo_clip_t *clip,
		       cairo_surface_t *target,
		       const cairo_rectangle_int_t *extents)
{
    cairo_surface_t *surface;
    cairo_status_t status;

    surface = cairo_surface_create_similar_image (target,
						  CAIRO_FORMAT_A8,
						  extents->width,
						  extents->height);
    if (unlikely (surface->status))
	return surface;

    status = _cairo_surface_paint (surface, CAIRO_OPERATOR_SOURCE,
				   &_cairo_pattern_white.base, NULL);
    if (likely (status == CAIRO_STATUS_SUCCESS))
	status = _cairo_clip_combine_with_surface (clip, surface,
						   extents->x, extents->y);

    if (unlikely (status)) {
	cairo_surface_destroy (surface);
	surface = _cairo_surface_create_in_error (status);
    }

    return surface;
}
static cairo_image_surface_t *
create_composite_mask (cairo_image_surface_t	*dst,
		       void			*draw_closure,
		       draw_func_t		 draw_func,
		       const cairo_composite_rectangles_t *extents)
{
    cairo_image_surface_t *surface;
    cairo_int_status_t status;

    surface = (cairo_image_surface_t *)
	_cairo_surface_create_similar_solid (&dst->base,
					     CAIRO_CONTENT_ALPHA,
					     extents->bounded.width,
					     extents->bounded.height,
					     CAIRO_COLOR_TRANSPARENT);
    if (unlikely (surface->base.status))
	return surface;

    status = draw_func (surface, draw_closure,
			CAIRO_OPERATOR_ADD, &_cairo_pattern_white.base,
			extents->bounded.x, extents->bounded.y,
			&extents->bounded);
    if (unlikely (status))
	goto error;

    if (extents->clip->boxes) {
	status = combine_in_boxes (surface,
				   extents->clip->boxes,
				   extents->clip->num_boxes,
				   &extents->bounded);
	if (unlikely (status))
	    goto error;
    }

    if (extents->clip->path) {
	status = _cairo_clip_combine_with_surface (extents->clip,
						   &surface->base,
						   extents->bounded.x,
						   extents->bounded.y);
	if (unlikely (status))
	    goto error;
    }

    return surface;

error:
    cairo_surface_destroy (&surface->base);
    return (cairo_image_surface_t *)_cairo_surface_create_in_error (status);
}
static cairo_image_surface_t *
get_clip_surface (cairo_image_surface_t	*dst,
		  const cairo_composite_rectangles_t *extents,
		  int *clip_x,
		  int *clip_y)
{
    cairo_image_surface_t *surface;
    cairo_int_status_t status;

    surface = (cairo_image_surface_t *)
	_cairo_surface_create_similar_solid (&dst->base,
					     CAIRO_CONTENT_ALPHA,
					     extents->unbounded.width,
					     extents->unbounded.height,
					     CAIRO_COLOR_WHITE);
    if (unlikely (surface->base.status))
	return surface;

    if (extents->clip->boxes) {
	status = combine_in_boxes (surface,
				   extents->clip->boxes,
				   extents->clip->num_boxes,
				   &extents->unbounded);
	if (unlikely (status))
	    goto error;
    }

    if (extents->clip->path) {
	status = _cairo_clip_combine_with_surface (extents->clip,
						   &surface->base,
						   extents->unbounded.x,
						   extents->unbounded.y);
	if (unlikely (status))
	    goto error;
    }

    *clip_x = extents->unbounded.x;
    *clip_y = extents->unbounded.y;
    return surface;

error:
    cairo_surface_destroy (&surface->base);
    return (cairo_image_surface_t *)_cairo_surface_create_in_error (status);
}
static cairo_image_surface_t *
create_composite_mask (cairo_image_surface_t	*dst,
		       void			*draw_closure,
		       draw_func_t		 draw_func,
		       const cairo_composite_rectangles_t *extents)
{
    cairo_image_surface_t *surface;
    cairo_int_status_t status;

    TRACE ((stderr, "%s\n", __FUNCTION__));

    surface = (cairo_image_surface_t *)
	_cairo_image_surface_create_with_pixman_format (NULL, PIXMAN_a8,
							extents->bounded.width,
							extents->bounded.height,
							0);
    if (unlikely (surface->base.status))
	return surface;

    status = draw_func (surface, draw_closure,
			CAIRO_OPERATOR_ADD, &_cairo_pattern_white.base,
			extents->bounded.x, extents->bounded.y,
			&extents->bounded);
    if (unlikely (status))
	goto error;

    status = _cairo_clip_combine_with_surface (extents->clip,
					       &surface->base,
					       extents->bounded.x,
					       extents->bounded.y);
    if (unlikely (status))
	goto error;

    return surface;

error:
    cairo_surface_destroy (&surface->base);
    return (cairo_image_surface_t *)_cairo_surface_create_in_error (status);
}
static cairo_int_status_t
_cairo_shape_mask_compositor_stroke (const cairo_compositor_t *_compositor,
				     cairo_composite_rectangles_t *extents,
				     const cairo_path_fixed_t	*path,
				     const cairo_stroke_style_t	*style,
				     const cairo_matrix_t	*ctm,
				     const cairo_matrix_t	*ctm_inverse,
				     double		 tolerance,
				     cairo_antialias_t	 antialias)
{
    cairo_surface_t *mask;
    cairo_surface_pattern_t pattern;
    cairo_int_status_t status;
    cairo_clip_t *clip;

    if (! extents->is_bounded)
	return CAIRO_INT_STATUS_UNSUPPORTED;

    TRACE ((stderr, "%s\n", __FUNCTION__));
    mask = _cairo_surface_create_scratch (extents->surface,
					  CAIRO_CONTENT_ALPHA,
					  extents->bounded.width,
					  extents->bounded.height,
					  NULL);
    if (unlikely (mask->status))
	return mask->status;

    clip = extents->clip;
    if (! _cairo_clip_is_region (clip))
	clip = _cairo_clip_copy_region (clip);

    if (! mask->is_clear) {
	status = _cairo_surface_offset_paint (mask,
					      extents->bounded.x,
					      extents->bounded.y,
					      CAIRO_OPERATOR_CLEAR,
					      &_cairo_pattern_clear.base,
					      clip);
	if (unlikely (status))
	    goto error;
    }

    status = _cairo_surface_offset_stroke (mask,
					   extents->bounded.x,
					   extents->bounded.y,
					   CAIRO_OPERATOR_ADD,
					   &_cairo_pattern_white.base,
					   path, style, ctm, ctm_inverse,
					   tolerance, antialias,
					   clip);
    if (unlikely (status))
	goto error;

    if (clip != extents->clip) {
	status = _cairo_clip_combine_with_surface (extents->clip, mask,
						   extents->bounded.x,
						   extents->bounded.y);
	if (unlikely (status))
	    goto error;
    }

    _cairo_pattern_init_for_surface (&pattern, mask);
    cairo_matrix_init_translate (&pattern.base.matrix,
				 -extents->bounded.x,
				 -extents->bounded.y);
    pattern.base.filter = CAIRO_FILTER_NEAREST;
    pattern.base.extend = CAIRO_EXTEND_NONE;
    if (extents->op == CAIRO_OPERATOR_SOURCE) {
	status = _cairo_surface_mask (extents->surface,
				      CAIRO_OPERATOR_DEST_OUT,
				      &_cairo_pattern_white.base,
				      &pattern.base,
				      clip);
	if ((status == CAIRO_INT_STATUS_SUCCESS)) {
	    status = _cairo_surface_mask (extents->surface,
					  CAIRO_OPERATOR_ADD,
					  &extents->source_pattern.base,
					  &pattern.base,
					  clip);
	}
    } else {
	status = _cairo_surface_mask (extents->surface,
				      extents->op,
				      &extents->source_pattern.base,
				      &pattern.base,
				      clip);
    }
    _cairo_pattern_fini (&pattern.base);

error:
    cairo_surface_destroy (mask);
    if (clip != extents->clip)
	_cairo_clip_destroy (clip);
    return status;
}