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; }
static cairo_int_status_t _cairo_xcb_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_xcb_surface_t *dst = abstract_dst; cairo_xcb_surface_t *src; cairo_xcb_surface_t *mask; cairo_int_status_t status; if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst)) return CAIRO_INT_STATUS_UNSUPPORTED; 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_xcb_surface_set_attributes (src, &src_attr); if (status == CAIRO_STATUS_SUCCESS) { if (mask) { status = _cairo_xcb_surface_set_attributes (mask, &mask_attr); if (status == CAIRO_STATUS_SUCCESS) XCBRenderComposite (dst->dpy, _render_operator (op), 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 { static XCBRenderPICTURE maskpict = { 0 }; XCBRenderComposite (dst->dpy, _render_operator (op), src->picture, maskpict, dst->picture, src_x + src_attr.x_offset, src_y + src_attr.y_offset, 0, 0, dst_x, dst_y, width, height); } } if (mask) _cairo_pattern_release_surface (mask_pattern, &mask->base, &mask_attr); _cairo_pattern_release_surface (src_pattern, &src->base, &src_attr); return status; }
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; }