Пример #1
0
static cairo_int_status_t
_cairo_image_surface_composite (cairo_operator_t	op,
				cairo_pattern_t		*src_pattern,
				cairo_pattern_t		*mask_pattern,
				void			*abstract_dst,
				int			src_x,
				int			src_y,
				int			mask_x,
				int			mask_y,
				int			dst_x,
				int			dst_y,
				unsigned int		width,
				unsigned int		height)
{
    cairo_surface_attributes_t	src_attr, mask_attr;
    cairo_image_surface_t	*dst = abstract_dst;
    cairo_image_surface_t	*src;
    cairo_image_surface_t	*mask;
    cairo_int_status_t		status;

    status = _cairo_pattern_acquire_surfaces (src_pattern, mask_pattern,
					      &dst->base,
					      src_x, src_y,
					      mask_x, mask_y,
					      width, height,
					      (cairo_surface_t **) &src,
					      (cairo_surface_t **) &mask,
					      &src_attr, &mask_attr);
    if (status)
	return status;
    
    status = _cairo_image_surface_set_attributes (src, &src_attr);
    if (status)
      goto CLEANUP_SURFACES;

    if (mask)
    {
	status = _cairo_image_surface_set_attributes (mask, &mask_attr);
	if (status)
	    goto CLEANUP_SURFACES;
	
	pixman_composite (_pixman_operator (op),
			  src->pixman_image,
			  mask->pixman_image,
			  dst->pixman_image,
			  src_x + src_attr.x_offset,
			  src_y + src_attr.y_offset,
			  mask_x + mask_attr.x_offset,
			  mask_y + mask_attr.y_offset,
			  dst_x, dst_y,
			  width, height);
    }
    else
    {
	pixman_composite (_pixman_operator (op),
			  src->pixman_image,
			  NULL,
			  dst->pixman_image,
			  src_x + src_attr.x_offset,
			  src_y + src_attr.y_offset,
			  0, 0,
			  dst_x, dst_y,
			  width, height);
    }
    
    if (!_cairo_operator_bounded_by_source (op))
	status = _cairo_surface_composite_fixup_unbounded (&dst->base,
							   &src_attr, src->width, src->height,
							   mask ? &mask_attr : NULL,
							   mask ? mask->width : 0,
							   mask ? mask->height : 0,
							   src_x, src_y,
							   mask_x, mask_y,
							   dst_x, dst_y, width, height);

 CLEANUP_SURFACES:
    if (mask)
	_cairo_pattern_release_surface (mask_pattern, &mask->base, &mask_attr);
    
    _cairo_pattern_release_surface (src_pattern, &src->base, &src_attr);
    
    return status;
}
Пример #2
0
static cairo_int_status_t _cairo_xynth_surface_composite (cairo_operator_t cairo_operator, cairo_pattern_t *src_pattern, cairo_pattern_t *mask_pattern, void *abstract_surface, int src_x, int src_y, int mask_x, int mask_y, int dst_x, int dst_y, unsigned int width, unsigned int height)
{
	cairo_int_status_t status;
	cairo_xynth_surface_t *dst;
	cairo_xynth_surface_t *src;
	cairo_xynth_surface_t *mask;
	cairo_surface_attributes_t src_attr;
	cairo_surface_attributes_t mask_attr;
	ENTER();
	dst = (cairo_xynth_surface_t *) abstract_surface;
	status = _cairo_pattern_acquire_surfaces(src_pattern, mask_pattern, &dst->cairo, src_x, src_y, mask_x, mask_y, width, height, (cairo_surface_t **) &src, (cairo_surface_t **) &mask, &src_attr, &mask_attr);
	if (status) {
		return status;
	}
	status = _cairo_xynth_surface_set_attributes(src, &src_attr);
	if (status) {
		goto out;
	}
	if (mask) {
		status = _cairo_xynth_surface_set_attributes(mask, &mask_attr);
		if (status) {
			goto out;
		}
		s_render_composite(_cairo_xynth_operator(cairo_operator),
	                           src->render,
	                           mask->render,
	                           dst->render,
	                           src_x + src_attr.x_offset,
	                           src_y + src_attr.y_offset,
	                           mask_x + mask_attr.x_offset,
	                           mask_y + mask_attr.y_offset,
	                           dst_x, dst_y,
	                           width, height);
	} else {
		s_render_composite(_cairo_xynth_operator(cairo_operator),
		                   src->render,
		                   NULL,
		                   dst->render,
		                   src_x + src_attr.x_offset,
		                   src_y + src_attr.y_offset,
		                   0, 0,
		                   dst_x, dst_y,
		                   width, height);
	}
	if (!_cairo_operator_bounded_by_source(cairo_operator)) {
		status = _cairo_surface_composite_fixup_unbounded(&dst->cairo,
		                                                  &src_attr, src->render->width, src->render->height,
		                                                  mask ? &mask_attr : NULL,
		                                                  mask ? mask->render->width : 0,
		                                                  mask ? mask->render->height : 0,
		                                                  src_x, src_y,
		                                                  mask_x, mask_y,
		                                                  dst_x, dst_y,
		                                                  width, height);
	}
 out: 	if (mask) {
 		_cairo_pattern_release_surface(mask_pattern, &mask->cairo, &mask_attr);
 	}
 	_cairo_pattern_release_surface(src_pattern, &src->cairo, &src_attr);
	LEAVE();
	return CAIRO_STATUS_SUCCESS;
}