mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2025-12-30 15:30:14 +01:00
Pass mask to composite operation as pattern
This commit is contained in:
parent
a97f4cce5e
commit
50b5344d7d
21 changed files with 566 additions and 269 deletions
16
ChangeLog
16
ChangeLog
|
|
@ -1,5 +1,21 @@
|
|||
2005-03-04 David Reveman <davidr@novell.com>
|
||||
|
||||
* src/cairo_pattern.c:
|
||||
* src/cairoint.h:
|
||||
Add convenience function _cairo_pattern_acquire_surfaces.
|
||||
|
||||
* src/cairo_xlib_surface.c:
|
||||
* src/cairo_surface.c:
|
||||
* src/cairo_ps_surface.c:
|
||||
* src/cairo_png_surface.c:
|
||||
* src/cairo_pdf_surface.c:
|
||||
* src/cairo_pattern.c:
|
||||
* src/cairo_image_surface.c:
|
||||
* src/cairo_gstate.c:
|
||||
* src/cairo_glitz_surface.c:
|
||||
* src/cairo_ft_font.c (_cairo_ft_font_show_glyphs): Mask to composite
|
||||
operation is now passed as a pattern.
|
||||
|
||||
* src/cairoint.h:
|
||||
* src/cairo_xlib_surface.c:
|
||||
(_cairo_xlib_surface_set_matrix): Setting identity transform should
|
||||
|
|
|
|||
|
|
@ -989,6 +989,7 @@ _cairo_ft_font_show_glyphs (void *abstract_font,
|
|||
cairo_cache_t *cache;
|
||||
cairo_glyph_cache_key_t key;
|
||||
cairo_ft_font_t *font = abstract_font;
|
||||
cairo_surface_pattern_t glyph_pattern;
|
||||
cairo_status_t status;
|
||||
int x, y;
|
||||
int i;
|
||||
|
|
@ -1023,8 +1024,10 @@ _cairo_ft_font_show_glyphs (void *abstract_font,
|
|||
x = (int) floor (glyphs[i].x + 0.5);
|
||||
y = (int) floor (glyphs[i].y + 0.5);
|
||||
|
||||
_cairo_pattern_init_for_surface (&glyph_pattern, &(img->image->base));
|
||||
|
||||
status = _cairo_surface_composite (operator, pattern,
|
||||
&(img->image->base),
|
||||
&glyph_pattern.base,
|
||||
surface,
|
||||
x + img->size.x,
|
||||
y + img->size.y,
|
||||
|
|
@ -1034,6 +1037,8 @@ _cairo_ft_font_show_glyphs (void *abstract_font,
|
|||
(double) img->size.width,
|
||||
(double) img->size.height);
|
||||
|
||||
_cairo_pattern_fini (&glyph_pattern.base);
|
||||
|
||||
if (status) {
|
||||
_cairo_unlock_global_image_glyph_cache ();
|
||||
return status;
|
||||
|
|
|
|||
|
|
@ -708,6 +708,50 @@ _cairo_glitz_pattern_release_surface (cairo_glitz_surface_t *dst,
|
|||
_cairo_glitz_surface_destroy (surface);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_glitz_pattern_acquire_surfaces (cairo_pattern_t *src,
|
||||
cairo_pattern_t *mask,
|
||||
cairo_glitz_surface_t *dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int mask_x,
|
||||
int mask_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
cairo_glitz_surface_t **src_out,
|
||||
cairo_glitz_surface_t **mask_out,
|
||||
cairo_glitz_surface_attributes_t *sattr,
|
||||
cairo_glitz_surface_attributes_t *mattr)
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
|
||||
status = _cairo_glitz_pattern_acquire_surface (src, dst,
|
||||
src_x, src_y,
|
||||
width, height,
|
||||
src_out, sattr);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (mask)
|
||||
{
|
||||
status = _cairo_glitz_pattern_acquire_surface (mask, dst,
|
||||
mask_x, mask_y,
|
||||
width, height,
|
||||
mask_out, mattr);
|
||||
if (status)
|
||||
{
|
||||
_cairo_glitz_pattern_release_surface (dst, *src_out, sattr);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*mask_out = NULL;
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_glitz_surface_set_attributes (cairo_glitz_surface_t *surface,
|
||||
cairo_glitz_surface_attributes_t *a)
|
||||
|
|
@ -720,8 +764,8 @@ _cairo_glitz_surface_set_attributes (cairo_glitz_surface_t *surface,
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_glitz_surface_composite (cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *generic_mask,
|
||||
cairo_pattern_t *src_pattern,
|
||||
cairo_pattern_t *mask_pattern,
|
||||
void *abstract_dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
|
|
@ -732,11 +776,10 @@ _cairo_glitz_surface_composite (cairo_operator_t op,
|
|||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
cairo_glitz_surface_attributes_t attributes;
|
||||
cairo_glitz_surface_attributes_t src_attr, mask_attr;
|
||||
cairo_glitz_surface_t *dst = abstract_dst;
|
||||
cairo_glitz_surface_t *src;
|
||||
cairo_glitz_surface_t *mask;
|
||||
cairo_surface_t *mask_clone = NULL;
|
||||
cairo_int_status_t status;
|
||||
|
||||
if (op == CAIRO_OPERATOR_SATURATE)
|
||||
|
|
@ -745,48 +788,53 @@ _cairo_glitz_surface_composite (cairo_operator_t op,
|
|||
if (_glitz_ensure_target (dst->surface))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
mask = (cairo_glitz_surface_t *) generic_mask;
|
||||
|
||||
/* XXX: this stuff can go when we change the mask to be a pattern. */
|
||||
if (generic_mask && (generic_mask->backend != dst->base.backend))
|
||||
{
|
||||
status = _cairo_surface_clone_similar (abstract_dst, generic_mask,
|
||||
&mask_clone);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
mask = (cairo_glitz_surface_t *) mask_clone;
|
||||
}
|
||||
|
||||
status = _cairo_glitz_pattern_acquire_surface (pattern, dst,
|
||||
src_x, src_y, width, height,
|
||||
&src, &attributes);
|
||||
status = _cairo_glitz_pattern_acquire_surfaces (src_pattern, mask_pattern,
|
||||
dst,
|
||||
src_x, src_y,
|
||||
mask_x, mask_y,
|
||||
width, height,
|
||||
&src, &mask,
|
||||
&src_attr, &mask_attr);
|
||||
if (status)
|
||||
{
|
||||
if (mask_clone)
|
||||
cairo_surface_destroy (mask_clone);
|
||||
|
||||
return status;
|
||||
|
||||
_cairo_glitz_surface_set_attributes (src, &src_attr);
|
||||
if (mask)
|
||||
{
|
||||
_cairo_glitz_surface_set_attributes (mask, &mask_attr);
|
||||
glitz_composite (_glitz_operator (op),
|
||||
src->surface,
|
||||
mask->surface,
|
||||
dst->surface,
|
||||
src_x + src_attr.base.x_offset,
|
||||
src_y + src_attr.base.y_offset,
|
||||
mask_x + mask_attr.base.x_offset,
|
||||
mask_y + mask_attr.base.y_offset,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
|
||||
if (mask_attr.n_params)
|
||||
free (mask_attr.params);
|
||||
|
||||
_cairo_glitz_pattern_release_surface (dst, mask, &mask_attr);
|
||||
}
|
||||
else
|
||||
{
|
||||
glitz_composite (_glitz_operator (op),
|
||||
src->surface,
|
||||
NULL,
|
||||
dst->surface,
|
||||
src_x + src_attr.base.x_offset,
|
||||
src_y + src_attr.base.y_offset,
|
||||
0, 0,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
}
|
||||
|
||||
_cairo_glitz_surface_set_attributes (src, &attributes);
|
||||
|
||||
glitz_composite (_glitz_operator (op),
|
||||
src->surface,
|
||||
(mask) ? mask->surface : NULL,
|
||||
dst->surface,
|
||||
src_x + attributes.base.x_offset,
|
||||
src_y + attributes.base.y_offset,
|
||||
mask_x, mask_y,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
if (src_attr.n_params)
|
||||
free (src_attr.params);
|
||||
|
||||
if (attributes.n_params)
|
||||
free (attributes.params);
|
||||
|
||||
_cairo_glitz_pattern_release_surface (dst, src, &attributes);
|
||||
if (mask_clone)
|
||||
cairo_surface_destroy (mask_clone);
|
||||
_cairo_glitz_pattern_release_surface (dst, src, &src_attr);
|
||||
|
||||
if (glitz_surface_get_status (dst->surface) == GLITZ_STATUS_NOT_SUPPORTED)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
|
|
|||
|
|
@ -1487,6 +1487,7 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate,
|
|||
|
||||
if (gstate->clip.surface) {
|
||||
cairo_surface_t *intermediate;
|
||||
cairo_surface_pattern_t intermediate_pattern;
|
||||
cairo_color_t empty_color;
|
||||
|
||||
_cairo_rectangle_intersect (&extents, &gstate->clip.rect);
|
||||
|
|
@ -1544,16 +1545,20 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate,
|
|||
if (status)
|
||||
goto BAIL2;
|
||||
|
||||
_cairo_pattern_init_for_surface (&intermediate_pattern, intermediate);
|
||||
_cairo_gstate_pattern_init_copy (gstate, &pattern, src);
|
||||
|
||||
status = _cairo_surface_composite (operator,
|
||||
&pattern.base, intermediate, dst,
|
||||
&pattern.base,
|
||||
&intermediate_pattern.base,
|
||||
dst,
|
||||
extents.x, extents.y,
|
||||
0, 0,
|
||||
extents.x, extents.y,
|
||||
extents.width, extents.height);
|
||||
|
||||
_cairo_pattern_fini (&pattern.base);
|
||||
_cairo_pattern_fini (&intermediate_pattern.base);
|
||||
|
||||
BAIL2:
|
||||
cairo_surface_destroy (intermediate);
|
||||
|
|
@ -2043,14 +2048,21 @@ _cairo_gstate_show_surface (cairo_gstate_t *gstate,
|
|||
|
||||
/* We only need to composite if the rectangle is not empty. */
|
||||
if (!_cairo_rectangle_empty (&extents)) {
|
||||
cairo_surface_pattern_t clip_pattern;
|
||||
|
||||
_cairo_pattern_init_for_surface (&clip_pattern,
|
||||
gstate->clip.surface);
|
||||
|
||||
status = _cairo_surface_composite (gstate->operator,
|
||||
&pattern.base,
|
||||
gstate->clip.surface,
|
||||
&clip_pattern.base,
|
||||
gstate->surface,
|
||||
extents.x, extents.y,
|
||||
0, 0,
|
||||
extents.x, extents.y,
|
||||
extents.width, extents.height);
|
||||
|
||||
_cairo_pattern_fini (&clip_pattern.base);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -2421,6 +2433,7 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate,
|
|||
if (gstate->clip.surface)
|
||||
{
|
||||
cairo_surface_t *intermediate;
|
||||
cairo_surface_pattern_t intermediate_pattern;
|
||||
cairo_color_t empty_color;
|
||||
|
||||
_cairo_rectangle_intersect (&extents, &gstate->clip.rect);
|
||||
|
|
@ -2483,17 +2496,19 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate,
|
|||
if (status)
|
||||
goto BAIL2;
|
||||
|
||||
_cairo_pattern_init_for_surface (&intermediate_pattern, intermediate);
|
||||
_cairo_gstate_pattern_init_copy (gstate, &pattern, gstate->pattern);
|
||||
|
||||
status = _cairo_surface_composite (gstate->operator,
|
||||
&pattern.base,
|
||||
intermediate,
|
||||
&intermediate_pattern.base,
|
||||
gstate->surface,
|
||||
extents.x, extents.y,
|
||||
0, 0,
|
||||
extents.x, extents.y,
|
||||
extents.width, extents.height);
|
||||
_cairo_pattern_fini (&pattern.base);
|
||||
_cairo_pattern_fini (&intermediate_pattern.base);
|
||||
|
||||
BAIL2:
|
||||
cairo_surface_destroy (intermediate);
|
||||
|
|
|
|||
|
|
@ -453,8 +453,8 @@ _pixman_operator (cairo_operator_t operator)
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_image_surface_composite (cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *generic_mask,
|
||||
cairo_pattern_t *src_pattern,
|
||||
cairo_pattern_t *mask_pattern,
|
||||
void *abstract_dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
|
|
@ -465,50 +465,60 @@ _cairo_image_surface_composite (cairo_operator_t operator,
|
|||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
cairo_surface_attributes_t attributes;
|
||||
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 = NULL;
|
||||
void *extra;
|
||||
cairo_image_surface_t *mask;
|
||||
cairo_int_status_t status;
|
||||
|
||||
/* XXX This stuff can go when we change the mask to be a pattern also. */
|
||||
if (generic_mask)
|
||||
{
|
||||
status = _cairo_surface_acquire_source_image (generic_mask,
|
||||
&mask, &extra);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _cairo_pattern_acquire_surface (pattern, &dst->base,
|
||||
src_x, src_y, width, height,
|
||||
(cairo_surface_t **) &src,
|
||||
&attributes);
|
||||
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 (CAIRO_OK (status))
|
||||
{
|
||||
if (mask)
|
||||
_cairo_surface_release_source_image (&dst->base, mask, extra);
|
||||
|
||||
return status;
|
||||
{
|
||||
status = _cairo_image_surface_set_attributes (mask, &mask_attr);
|
||||
if (CAIRO_OK (status))
|
||||
pixman_composite (_pixman_operator (operator),
|
||||
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 (operator),
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
status = _cairo_image_surface_set_attributes (src, &attributes);
|
||||
if (CAIRO_OK (status))
|
||||
pixman_composite (_pixman_operator (operator),
|
||||
src->pixman_image,
|
||||
mask ? mask->pixman_image : NULL,
|
||||
dst->pixman_image,
|
||||
src_x + attributes.x_offset,
|
||||
src_y + attributes.y_offset,
|
||||
mask_x, mask_y,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
|
||||
_cairo_pattern_release_surface (&dst->base, &src->base, &attributes);
|
||||
if (mask)
|
||||
_cairo_surface_release_source_image (&dst->base, mask, extra);
|
||||
|
||||
_cairo_pattern_release_surface (&dst->base, &mask->base, &mask_attr);
|
||||
|
||||
_cairo_pattern_release_surface (&dst->base, &src->base, &src_attr);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1113,3 +1113,47 @@ _cairo_pattern_release_surface (cairo_surface_t *dst,
|
|||
else
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_pattern_acquire_surfaces (cairo_pattern_t *src,
|
||||
cairo_pattern_t *mask,
|
||||
cairo_surface_t *dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int mask_x,
|
||||
int mask_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
cairo_surface_t **src_out,
|
||||
cairo_surface_t **mask_out,
|
||||
cairo_surface_attributes_t *src_attributes,
|
||||
cairo_surface_attributes_t *mask_attributes)
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
|
||||
status = _cairo_pattern_acquire_surface (src, dst,
|
||||
src_x, src_y,
|
||||
width, height,
|
||||
src_out, src_attributes);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (mask)
|
||||
{
|
||||
status = _cairo_pattern_acquire_surface (mask, dst,
|
||||
mask_x, mask_y,
|
||||
width, height,
|
||||
mask_out, mask_attributes);
|
||||
if (status)
|
||||
{
|
||||
_cairo_pattern_release_surface (dst, *src_out, src_attributes);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*mask_out = NULL;
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1312,8 +1312,8 @@ _cairo_pdf_surface_composite_pdf (cairo_pdf_surface_t *dst,
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_pdf_surface_composite (cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *generic_mask,
|
||||
cairo_pattern_t *src_pattern,
|
||||
cairo_pattern_t *mask_pattern,
|
||||
void *abstract_dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
|
|
@ -1325,9 +1325,12 @@ _cairo_pdf_surface_composite (cairo_operator_t operator,
|
|||
unsigned int height)
|
||||
{
|
||||
cairo_pdf_surface_t *dst = abstract_dst;
|
||||
cairo_surface_pattern_t *src = (cairo_surface_pattern_t *) pattern;
|
||||
cairo_surface_pattern_t *src = (cairo_surface_pattern_t *) src_pattern;
|
||||
|
||||
if (pattern->type != CAIRO_PATTERN_SURFACE)
|
||||
if (mask_pattern)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
if (src_pattern->type != CAIRO_PATTERN_SURFACE)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (src->surface->backend == &cairo_pdf_surface_backend)
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ _cairo_ps_surface_clone_similar (void *abstract_surface,
|
|||
static cairo_int_status_t
|
||||
_cairo_ps_surface_composite (cairo_operator_t operator,
|
||||
cairo_pattern_t *src,
|
||||
cairo_surface_t *generic_mask,
|
||||
cairo_pattern_t *mask,
|
||||
void *abstract_dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
|
|
|
|||
|
|
@ -397,8 +397,8 @@ _fallback_cleanup (fallback_state_t *state)
|
|||
|
||||
static cairo_status_t
|
||||
_fallback_composite (cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *mask,
|
||||
cairo_pattern_t *src,
|
||||
cairo_pattern_t *mask,
|
||||
cairo_surface_t *dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
|
|
@ -416,7 +416,7 @@ _fallback_composite (cairo_operator_t operator,
|
|||
if (!CAIRO_OK (status) || !state.image)
|
||||
return status;
|
||||
|
||||
state.image->base.backend->composite (operator, pattern, mask,
|
||||
state.image->base.backend->composite (operator, src, mask,
|
||||
&state.image->base,
|
||||
src_x, src_y, mask_x, mask_y,
|
||||
dst_x - state.image_rect.x,
|
||||
|
|
@ -430,8 +430,8 @@ _fallback_composite (cairo_operator_t operator,
|
|||
|
||||
cairo_status_t
|
||||
_cairo_surface_composite (cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *mask,
|
||||
cairo_pattern_t *src,
|
||||
cairo_pattern_t *mask,
|
||||
cairo_surface_t *dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
|
|
@ -445,7 +445,7 @@ _cairo_surface_composite (cairo_operator_t operator,
|
|||
cairo_int_status_t status;
|
||||
|
||||
status = dst->backend->composite (operator,
|
||||
pattern, mask, dst,
|
||||
src, mask, dst,
|
||||
src_x, src_y,
|
||||
mask_x, mask_y,
|
||||
dst_x, dst_y,
|
||||
|
|
@ -454,7 +454,7 @@ _cairo_surface_composite (cairo_operator_t operator,
|
|||
return status;
|
||||
|
||||
return _fallback_composite (operator,
|
||||
pattern, mask, dst,
|
||||
src, mask, dst,
|
||||
src_x, src_y,
|
||||
mask_x, mask_y,
|
||||
dst_x, dst_y,
|
||||
|
|
|
|||
|
|
@ -618,8 +618,8 @@ _render_operator (cairo_operator_t operator)
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_xlib_surface_composite (cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *generic_mask,
|
||||
cairo_pattern_t *src_pattern,
|
||||
cairo_pattern_t *mask_pattern,
|
||||
void *abstract_dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
|
|
@ -630,56 +630,64 @@ _cairo_xlib_surface_composite (cairo_operator_t operator,
|
|||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
cairo_surface_attributes_t attributes;
|
||||
cairo_surface_attributes_t src_attr, mask_attr;
|
||||
cairo_xlib_surface_t *dst = abstract_dst;
|
||||
cairo_xlib_surface_t *src;
|
||||
cairo_xlib_surface_t *mask = (cairo_xlib_surface_t *) generic_mask;
|
||||
cairo_surface_t *mask_clone = NULL;
|
||||
cairo_xlib_surface_t *mask;
|
||||
cairo_int_status_t status;
|
||||
|
||||
if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
/* XXX This stuff can go when we change the mask to be a pattern also. */
|
||||
if (generic_mask && (generic_mask->backend != dst->base.backend ||
|
||||
mask->dpy != dst->dpy)) {
|
||||
status = _cairo_surface_clone_similar (abstract_dst, generic_mask,
|
||||
&mask_clone);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
mask = (cairo_xlib_surface_t *) mask_clone;
|
||||
}
|
||||
|
||||
status = _cairo_pattern_acquire_surface (pattern, &dst->base,
|
||||
src_x, src_y, width, height,
|
||||
(cairo_surface_t **) &src,
|
||||
&attributes);
|
||||
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)
|
||||
{
|
||||
if (mask_clone)
|
||||
cairo_surface_destroy (mask_clone);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _cairo_xlib_surface_set_attributes (src, &attributes);
|
||||
status = _cairo_xlib_surface_set_attributes (src, &src_attr);
|
||||
if (CAIRO_OK (status))
|
||||
XRenderComposite (dst->dpy,
|
||||
_render_operator (operator),
|
||||
src->picture,
|
||||
mask ? mask->picture : 0,
|
||||
dst->picture,
|
||||
src_x + attributes.x_offset,
|
||||
src_y + attributes.y_offset,
|
||||
mask_x, mask_y,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
{
|
||||
if (mask)
|
||||
{
|
||||
status = _cairo_xlib_surface_set_attributes (mask, &mask_attr);
|
||||
if (CAIRO_OK (status))
|
||||
XRenderComposite (dst->dpy,
|
||||
_render_operator (operator),
|
||||
src->picture,
|
||||
mask->picture,
|
||||
dst->picture,
|
||||
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
|
||||
{
|
||||
XRenderComposite (dst->dpy,
|
||||
_render_operator (operator),
|
||||
src->picture,
|
||||
0,
|
||||
dst->picture,
|
||||
src_x + src_attr.x_offset,
|
||||
src_y + src_attr.y_offset,
|
||||
0, 0,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
}
|
||||
}
|
||||
|
||||
if (mask_clone)
|
||||
cairo_surface_destroy (mask_clone);
|
||||
if (mask)
|
||||
_cairo_pattern_release_surface (&dst->base, &mask->base, &mask_attr);
|
||||
|
||||
_cairo_pattern_release_surface (&dst->base, &src->base, &attributes);
|
||||
_cairo_pattern_release_surface (&dst->base, &src->base, &src_attr);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -989,6 +989,7 @@ _cairo_ft_font_show_glyphs (void *abstract_font,
|
|||
cairo_cache_t *cache;
|
||||
cairo_glyph_cache_key_t key;
|
||||
cairo_ft_font_t *font = abstract_font;
|
||||
cairo_surface_pattern_t glyph_pattern;
|
||||
cairo_status_t status;
|
||||
int x, y;
|
||||
int i;
|
||||
|
|
@ -1023,8 +1024,10 @@ _cairo_ft_font_show_glyphs (void *abstract_font,
|
|||
x = (int) floor (glyphs[i].x + 0.5);
|
||||
y = (int) floor (glyphs[i].y + 0.5);
|
||||
|
||||
_cairo_pattern_init_for_surface (&glyph_pattern, &(img->image->base));
|
||||
|
||||
status = _cairo_surface_composite (operator, pattern,
|
||||
&(img->image->base),
|
||||
&glyph_pattern.base,
|
||||
surface,
|
||||
x + img->size.x,
|
||||
y + img->size.y,
|
||||
|
|
@ -1034,6 +1037,8 @@ _cairo_ft_font_show_glyphs (void *abstract_font,
|
|||
(double) img->size.width,
|
||||
(double) img->size.height);
|
||||
|
||||
_cairo_pattern_fini (&glyph_pattern.base);
|
||||
|
||||
if (status) {
|
||||
_cairo_unlock_global_image_glyph_cache ();
|
||||
return status;
|
||||
|
|
|
|||
|
|
@ -708,6 +708,50 @@ _cairo_glitz_pattern_release_surface (cairo_glitz_surface_t *dst,
|
|||
_cairo_glitz_surface_destroy (surface);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_glitz_pattern_acquire_surfaces (cairo_pattern_t *src,
|
||||
cairo_pattern_t *mask,
|
||||
cairo_glitz_surface_t *dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int mask_x,
|
||||
int mask_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
cairo_glitz_surface_t **src_out,
|
||||
cairo_glitz_surface_t **mask_out,
|
||||
cairo_glitz_surface_attributes_t *sattr,
|
||||
cairo_glitz_surface_attributes_t *mattr)
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
|
||||
status = _cairo_glitz_pattern_acquire_surface (src, dst,
|
||||
src_x, src_y,
|
||||
width, height,
|
||||
src_out, sattr);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (mask)
|
||||
{
|
||||
status = _cairo_glitz_pattern_acquire_surface (mask, dst,
|
||||
mask_x, mask_y,
|
||||
width, height,
|
||||
mask_out, mattr);
|
||||
if (status)
|
||||
{
|
||||
_cairo_glitz_pattern_release_surface (dst, *src_out, sattr);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*mask_out = NULL;
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_glitz_surface_set_attributes (cairo_glitz_surface_t *surface,
|
||||
cairo_glitz_surface_attributes_t *a)
|
||||
|
|
@ -720,8 +764,8 @@ _cairo_glitz_surface_set_attributes (cairo_glitz_surface_t *surface,
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_glitz_surface_composite (cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *generic_mask,
|
||||
cairo_pattern_t *src_pattern,
|
||||
cairo_pattern_t *mask_pattern,
|
||||
void *abstract_dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
|
|
@ -732,11 +776,10 @@ _cairo_glitz_surface_composite (cairo_operator_t op,
|
|||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
cairo_glitz_surface_attributes_t attributes;
|
||||
cairo_glitz_surface_attributes_t src_attr, mask_attr;
|
||||
cairo_glitz_surface_t *dst = abstract_dst;
|
||||
cairo_glitz_surface_t *src;
|
||||
cairo_glitz_surface_t *mask;
|
||||
cairo_surface_t *mask_clone = NULL;
|
||||
cairo_int_status_t status;
|
||||
|
||||
if (op == CAIRO_OPERATOR_SATURATE)
|
||||
|
|
@ -745,48 +788,53 @@ _cairo_glitz_surface_composite (cairo_operator_t op,
|
|||
if (_glitz_ensure_target (dst->surface))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
mask = (cairo_glitz_surface_t *) generic_mask;
|
||||
|
||||
/* XXX: this stuff can go when we change the mask to be a pattern. */
|
||||
if (generic_mask && (generic_mask->backend != dst->base.backend))
|
||||
{
|
||||
status = _cairo_surface_clone_similar (abstract_dst, generic_mask,
|
||||
&mask_clone);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
mask = (cairo_glitz_surface_t *) mask_clone;
|
||||
}
|
||||
|
||||
status = _cairo_glitz_pattern_acquire_surface (pattern, dst,
|
||||
src_x, src_y, width, height,
|
||||
&src, &attributes);
|
||||
status = _cairo_glitz_pattern_acquire_surfaces (src_pattern, mask_pattern,
|
||||
dst,
|
||||
src_x, src_y,
|
||||
mask_x, mask_y,
|
||||
width, height,
|
||||
&src, &mask,
|
||||
&src_attr, &mask_attr);
|
||||
if (status)
|
||||
{
|
||||
if (mask_clone)
|
||||
cairo_surface_destroy (mask_clone);
|
||||
|
||||
return status;
|
||||
|
||||
_cairo_glitz_surface_set_attributes (src, &src_attr);
|
||||
if (mask)
|
||||
{
|
||||
_cairo_glitz_surface_set_attributes (mask, &mask_attr);
|
||||
glitz_composite (_glitz_operator (op),
|
||||
src->surface,
|
||||
mask->surface,
|
||||
dst->surface,
|
||||
src_x + src_attr.base.x_offset,
|
||||
src_y + src_attr.base.y_offset,
|
||||
mask_x + mask_attr.base.x_offset,
|
||||
mask_y + mask_attr.base.y_offset,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
|
||||
if (mask_attr.n_params)
|
||||
free (mask_attr.params);
|
||||
|
||||
_cairo_glitz_pattern_release_surface (dst, mask, &mask_attr);
|
||||
}
|
||||
else
|
||||
{
|
||||
glitz_composite (_glitz_operator (op),
|
||||
src->surface,
|
||||
NULL,
|
||||
dst->surface,
|
||||
src_x + src_attr.base.x_offset,
|
||||
src_y + src_attr.base.y_offset,
|
||||
0, 0,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
}
|
||||
|
||||
_cairo_glitz_surface_set_attributes (src, &attributes);
|
||||
|
||||
glitz_composite (_glitz_operator (op),
|
||||
src->surface,
|
||||
(mask) ? mask->surface : NULL,
|
||||
dst->surface,
|
||||
src_x + attributes.base.x_offset,
|
||||
src_y + attributes.base.y_offset,
|
||||
mask_x, mask_y,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
if (src_attr.n_params)
|
||||
free (src_attr.params);
|
||||
|
||||
if (attributes.n_params)
|
||||
free (attributes.params);
|
||||
|
||||
_cairo_glitz_pattern_release_surface (dst, src, &attributes);
|
||||
if (mask_clone)
|
||||
cairo_surface_destroy (mask_clone);
|
||||
_cairo_glitz_pattern_release_surface (dst, src, &src_attr);
|
||||
|
||||
if (glitz_surface_get_status (dst->surface) == GLITZ_STATUS_NOT_SUPPORTED)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
|
|
|||
|
|
@ -1487,6 +1487,7 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate,
|
|||
|
||||
if (gstate->clip.surface) {
|
||||
cairo_surface_t *intermediate;
|
||||
cairo_surface_pattern_t intermediate_pattern;
|
||||
cairo_color_t empty_color;
|
||||
|
||||
_cairo_rectangle_intersect (&extents, &gstate->clip.rect);
|
||||
|
|
@ -1544,16 +1545,20 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate,
|
|||
if (status)
|
||||
goto BAIL2;
|
||||
|
||||
_cairo_pattern_init_for_surface (&intermediate_pattern, intermediate);
|
||||
_cairo_gstate_pattern_init_copy (gstate, &pattern, src);
|
||||
|
||||
status = _cairo_surface_composite (operator,
|
||||
&pattern.base, intermediate, dst,
|
||||
&pattern.base,
|
||||
&intermediate_pattern.base,
|
||||
dst,
|
||||
extents.x, extents.y,
|
||||
0, 0,
|
||||
extents.x, extents.y,
|
||||
extents.width, extents.height);
|
||||
|
||||
_cairo_pattern_fini (&pattern.base);
|
||||
_cairo_pattern_fini (&intermediate_pattern.base);
|
||||
|
||||
BAIL2:
|
||||
cairo_surface_destroy (intermediate);
|
||||
|
|
@ -2043,14 +2048,21 @@ _cairo_gstate_show_surface (cairo_gstate_t *gstate,
|
|||
|
||||
/* We only need to composite if the rectangle is not empty. */
|
||||
if (!_cairo_rectangle_empty (&extents)) {
|
||||
cairo_surface_pattern_t clip_pattern;
|
||||
|
||||
_cairo_pattern_init_for_surface (&clip_pattern,
|
||||
gstate->clip.surface);
|
||||
|
||||
status = _cairo_surface_composite (gstate->operator,
|
||||
&pattern.base,
|
||||
gstate->clip.surface,
|
||||
&clip_pattern.base,
|
||||
gstate->surface,
|
||||
extents.x, extents.y,
|
||||
0, 0,
|
||||
extents.x, extents.y,
|
||||
extents.width, extents.height);
|
||||
|
||||
_cairo_pattern_fini (&clip_pattern.base);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -2421,6 +2433,7 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate,
|
|||
if (gstate->clip.surface)
|
||||
{
|
||||
cairo_surface_t *intermediate;
|
||||
cairo_surface_pattern_t intermediate_pattern;
|
||||
cairo_color_t empty_color;
|
||||
|
||||
_cairo_rectangle_intersect (&extents, &gstate->clip.rect);
|
||||
|
|
@ -2483,17 +2496,19 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate,
|
|||
if (status)
|
||||
goto BAIL2;
|
||||
|
||||
_cairo_pattern_init_for_surface (&intermediate_pattern, intermediate);
|
||||
_cairo_gstate_pattern_init_copy (gstate, &pattern, gstate->pattern);
|
||||
|
||||
status = _cairo_surface_composite (gstate->operator,
|
||||
&pattern.base,
|
||||
intermediate,
|
||||
&intermediate_pattern.base,
|
||||
gstate->surface,
|
||||
extents.x, extents.y,
|
||||
0, 0,
|
||||
extents.x, extents.y,
|
||||
extents.width, extents.height);
|
||||
_cairo_pattern_fini (&pattern.base);
|
||||
_cairo_pattern_fini (&intermediate_pattern.base);
|
||||
|
||||
BAIL2:
|
||||
cairo_surface_destroy (intermediate);
|
||||
|
|
|
|||
|
|
@ -453,8 +453,8 @@ _pixman_operator (cairo_operator_t operator)
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_image_surface_composite (cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *generic_mask,
|
||||
cairo_pattern_t *src_pattern,
|
||||
cairo_pattern_t *mask_pattern,
|
||||
void *abstract_dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
|
|
@ -465,50 +465,60 @@ _cairo_image_surface_composite (cairo_operator_t operator,
|
|||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
cairo_surface_attributes_t attributes;
|
||||
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 = NULL;
|
||||
void *extra;
|
||||
cairo_image_surface_t *mask;
|
||||
cairo_int_status_t status;
|
||||
|
||||
/* XXX This stuff can go when we change the mask to be a pattern also. */
|
||||
if (generic_mask)
|
||||
{
|
||||
status = _cairo_surface_acquire_source_image (generic_mask,
|
||||
&mask, &extra);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _cairo_pattern_acquire_surface (pattern, &dst->base,
|
||||
src_x, src_y, width, height,
|
||||
(cairo_surface_t **) &src,
|
||||
&attributes);
|
||||
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 (CAIRO_OK (status))
|
||||
{
|
||||
if (mask)
|
||||
_cairo_surface_release_source_image (&dst->base, mask, extra);
|
||||
|
||||
return status;
|
||||
{
|
||||
status = _cairo_image_surface_set_attributes (mask, &mask_attr);
|
||||
if (CAIRO_OK (status))
|
||||
pixman_composite (_pixman_operator (operator),
|
||||
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 (operator),
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
status = _cairo_image_surface_set_attributes (src, &attributes);
|
||||
if (CAIRO_OK (status))
|
||||
pixman_composite (_pixman_operator (operator),
|
||||
src->pixman_image,
|
||||
mask ? mask->pixman_image : NULL,
|
||||
dst->pixman_image,
|
||||
src_x + attributes.x_offset,
|
||||
src_y + attributes.y_offset,
|
||||
mask_x, mask_y,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
|
||||
_cairo_pattern_release_surface (&dst->base, &src->base, &attributes);
|
||||
if (mask)
|
||||
_cairo_surface_release_source_image (&dst->base, mask, extra);
|
||||
|
||||
_cairo_pattern_release_surface (&dst->base, &mask->base, &mask_attr);
|
||||
|
||||
_cairo_pattern_release_surface (&dst->base, &src->base, &src_attr);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1113,3 +1113,47 @@ _cairo_pattern_release_surface (cairo_surface_t *dst,
|
|||
else
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_pattern_acquire_surfaces (cairo_pattern_t *src,
|
||||
cairo_pattern_t *mask,
|
||||
cairo_surface_t *dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int mask_x,
|
||||
int mask_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
cairo_surface_t **src_out,
|
||||
cairo_surface_t **mask_out,
|
||||
cairo_surface_attributes_t *src_attributes,
|
||||
cairo_surface_attributes_t *mask_attributes)
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
|
||||
status = _cairo_pattern_acquire_surface (src, dst,
|
||||
src_x, src_y,
|
||||
width, height,
|
||||
src_out, src_attributes);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (mask)
|
||||
{
|
||||
status = _cairo_pattern_acquire_surface (mask, dst,
|
||||
mask_x, mask_y,
|
||||
width, height,
|
||||
mask_out, mask_attributes);
|
||||
if (status)
|
||||
{
|
||||
_cairo_pattern_release_surface (dst, *src_out, src_attributes);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*mask_out = NULL;
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1312,8 +1312,8 @@ _cairo_pdf_surface_composite_pdf (cairo_pdf_surface_t *dst,
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_pdf_surface_composite (cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *generic_mask,
|
||||
cairo_pattern_t *src_pattern,
|
||||
cairo_pattern_t *mask_pattern,
|
||||
void *abstract_dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
|
|
@ -1325,9 +1325,12 @@ _cairo_pdf_surface_composite (cairo_operator_t operator,
|
|||
unsigned int height)
|
||||
{
|
||||
cairo_pdf_surface_t *dst = abstract_dst;
|
||||
cairo_surface_pattern_t *src = (cairo_surface_pattern_t *) pattern;
|
||||
cairo_surface_pattern_t *src = (cairo_surface_pattern_t *) src_pattern;
|
||||
|
||||
if (pattern->type != CAIRO_PATTERN_SURFACE)
|
||||
if (mask_pattern)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
if (src_pattern->type != CAIRO_PATTERN_SURFACE)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (src->surface->backend == &cairo_pdf_surface_backend)
|
||||
|
|
|
|||
|
|
@ -242,8 +242,8 @@ _cairo_png_surface_clone_similar (void *abstract_surface,
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_png_surface_composite (cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *generic_mask,
|
||||
cairo_pattern_t *src,
|
||||
cairo_pattern_t *mask,
|
||||
void *abstract_dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ _cairo_ps_surface_clone_similar (void *abstract_surface,
|
|||
static cairo_int_status_t
|
||||
_cairo_ps_surface_composite (cairo_operator_t operator,
|
||||
cairo_pattern_t *src,
|
||||
cairo_surface_t *generic_mask,
|
||||
cairo_pattern_t *mask,
|
||||
void *abstract_dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
|
|
|
|||
|
|
@ -397,8 +397,8 @@ _fallback_cleanup (fallback_state_t *state)
|
|||
|
||||
static cairo_status_t
|
||||
_fallback_composite (cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *mask,
|
||||
cairo_pattern_t *src,
|
||||
cairo_pattern_t *mask,
|
||||
cairo_surface_t *dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
|
|
@ -416,7 +416,7 @@ _fallback_composite (cairo_operator_t operator,
|
|||
if (!CAIRO_OK (status) || !state.image)
|
||||
return status;
|
||||
|
||||
state.image->base.backend->composite (operator, pattern, mask,
|
||||
state.image->base.backend->composite (operator, src, mask,
|
||||
&state.image->base,
|
||||
src_x, src_y, mask_x, mask_y,
|
||||
dst_x - state.image_rect.x,
|
||||
|
|
@ -430,8 +430,8 @@ _fallback_composite (cairo_operator_t operator,
|
|||
|
||||
cairo_status_t
|
||||
_cairo_surface_composite (cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *mask,
|
||||
cairo_pattern_t *src,
|
||||
cairo_pattern_t *mask,
|
||||
cairo_surface_t *dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
|
|
@ -445,7 +445,7 @@ _cairo_surface_composite (cairo_operator_t operator,
|
|||
cairo_int_status_t status;
|
||||
|
||||
status = dst->backend->composite (operator,
|
||||
pattern, mask, dst,
|
||||
src, mask, dst,
|
||||
src_x, src_y,
|
||||
mask_x, mask_y,
|
||||
dst_x, dst_y,
|
||||
|
|
@ -454,7 +454,7 @@ _cairo_surface_composite (cairo_operator_t operator,
|
|||
return status;
|
||||
|
||||
return _fallback_composite (operator,
|
||||
pattern, mask, dst,
|
||||
src, mask, dst,
|
||||
src_x, src_y,
|
||||
mask_x, mask_y,
|
||||
dst_x, dst_y,
|
||||
|
|
|
|||
|
|
@ -618,8 +618,8 @@ _render_operator (cairo_operator_t operator)
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_xlib_surface_composite (cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *generic_mask,
|
||||
cairo_pattern_t *src_pattern,
|
||||
cairo_pattern_t *mask_pattern,
|
||||
void *abstract_dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
|
|
@ -630,56 +630,64 @@ _cairo_xlib_surface_composite (cairo_operator_t operator,
|
|||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
cairo_surface_attributes_t attributes;
|
||||
cairo_surface_attributes_t src_attr, mask_attr;
|
||||
cairo_xlib_surface_t *dst = abstract_dst;
|
||||
cairo_xlib_surface_t *src;
|
||||
cairo_xlib_surface_t *mask = (cairo_xlib_surface_t *) generic_mask;
|
||||
cairo_surface_t *mask_clone = NULL;
|
||||
cairo_xlib_surface_t *mask;
|
||||
cairo_int_status_t status;
|
||||
|
||||
if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
/* XXX This stuff can go when we change the mask to be a pattern also. */
|
||||
if (generic_mask && (generic_mask->backend != dst->base.backend ||
|
||||
mask->dpy != dst->dpy)) {
|
||||
status = _cairo_surface_clone_similar (abstract_dst, generic_mask,
|
||||
&mask_clone);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
mask = (cairo_xlib_surface_t *) mask_clone;
|
||||
}
|
||||
|
||||
status = _cairo_pattern_acquire_surface (pattern, &dst->base,
|
||||
src_x, src_y, width, height,
|
||||
(cairo_surface_t **) &src,
|
||||
&attributes);
|
||||
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)
|
||||
{
|
||||
if (mask_clone)
|
||||
cairo_surface_destroy (mask_clone);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _cairo_xlib_surface_set_attributes (src, &attributes);
|
||||
status = _cairo_xlib_surface_set_attributes (src, &src_attr);
|
||||
if (CAIRO_OK (status))
|
||||
XRenderComposite (dst->dpy,
|
||||
_render_operator (operator),
|
||||
src->picture,
|
||||
mask ? mask->picture : 0,
|
||||
dst->picture,
|
||||
src_x + attributes.x_offset,
|
||||
src_y + attributes.y_offset,
|
||||
mask_x, mask_y,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
{
|
||||
if (mask)
|
||||
{
|
||||
status = _cairo_xlib_surface_set_attributes (mask, &mask_attr);
|
||||
if (CAIRO_OK (status))
|
||||
XRenderComposite (dst->dpy,
|
||||
_render_operator (operator),
|
||||
src->picture,
|
||||
mask->picture,
|
||||
dst->picture,
|
||||
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
|
||||
{
|
||||
XRenderComposite (dst->dpy,
|
||||
_render_operator (operator),
|
||||
src->picture,
|
||||
0,
|
||||
dst->picture,
|
||||
src_x + src_attr.x_offset,
|
||||
src_y + src_attr.y_offset,
|
||||
0, 0,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
}
|
||||
}
|
||||
|
||||
if (mask_clone)
|
||||
cairo_surface_destroy (mask_clone);
|
||||
if (mask)
|
||||
_cairo_pattern_release_surface (&dst->base, &mask->base, &mask_attr);
|
||||
|
||||
_cairo_pattern_release_surface (&dst->base, &src->base, &attributes);
|
||||
_cairo_pattern_release_surface (&dst->base, &src->base, &src_attr);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -589,7 +589,7 @@ typedef struct _cairo_surface_backend {
|
|||
cairo_int_status_t
|
||||
(*composite) (cairo_operator_t operator,
|
||||
cairo_pattern_t *src,
|
||||
cairo_surface_t *mask,
|
||||
cairo_pattern_t *mask,
|
||||
void *dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
|
|
@ -1427,8 +1427,8 @@ _cairo_surface_fill_rectangle (cairo_surface_t *surface,
|
|||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_composite (cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_surface_t *mask,
|
||||
cairo_pattern_t *src,
|
||||
cairo_pattern_t *mask,
|
||||
cairo_surface_t *dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
|
|
@ -1730,6 +1730,21 @@ _cairo_pattern_release_surface (cairo_surface_t *dst,
|
|||
cairo_surface_t *surface,
|
||||
cairo_surface_attributes_t *attributes);
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_pattern_acquire_surfaces (cairo_pattern_t *src,
|
||||
cairo_pattern_t *mask,
|
||||
cairo_surface_t *dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int mask_x,
|
||||
int mask_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
cairo_surface_t **src_out,
|
||||
cairo_surface_t **mask_out,
|
||||
cairo_surface_attributes_t *src_attributes,
|
||||
cairo_surface_attributes_t *mask_attributes);
|
||||
|
||||
|
||||
/* cairo_unicode.c */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue