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; }