📄 cairo-surface.c
字号:
}/** * _cairo_surface_acquire_dest_image: * @surface: a #cairo_surface_t * @interest_rect: area of @surface for which fallback drawing is being done. * A value of %NULL indicates that the entire surface is desired. * XXXX I'd like to get rid of being able to pass NULL here (nothing seems to) * @image_out: location to store a pointer to an image surface that includes at least * the intersection of @interest_rect with the visible area of @surface. * This surface could be @surface itself, a surface held internal to @surface, * or it could be a new surface with a copy of the relevant portion of @surface. * If a new surface is created, it should have the same channels and depth * as @surface so that copying to and from it is exact. * @image_rect: location to store area of the original surface occupied * by the surface stored in @image. * @image_extra: location to store image specific backend data * * Retrieves a local image for a surface for implementing a fallback drawing * operation. After calling this function, the implementation of the fallback * drawing operation draws the primitive to the surface stored in @image_out * then calls _cairo_surface_release_dest_image(), * which, if a temporary surface was created, copies the bits back to the * main surface and frees the temporary surface. * * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY. * %CAIRO_INT_STATUS_UNSUPPORTED can be returned but this will mean that * the backend can't draw with fallbacks. It's possible for the routine * to store NULL in @local_out and return %CAIRO_STATUS_SUCCESS; * that indicates that no part of @interest_rect is visible, so no drawing * is necessary. _cairo_surface_release_dest_image() should not be called in that * case. **/cairo_status_t_cairo_surface_acquire_dest_image (cairo_surface_t *surface, cairo_rectangle_int16_t *interest_rect, cairo_image_surface_t **image_out, cairo_rectangle_int16_t *image_rect, void **image_extra){ assert (!surface->finished); return surface->backend->acquire_dest_image (surface, interest_rect, image_out, image_rect, image_extra);}/** * _cairo_surface_release_dest_image: * @surface: a #cairo_surface_t * @interest_rect: same as passed to the matching _cairo_surface_acquire_dest_image() * @image: same as returned from the matching _cairo_surface_acquire_dest_image() * @image_rect: same as returned from the matching _cairo_surface_acquire_dest_image() * @image_extra: same as return from the matching _cairo_surface_acquire_dest_image() * * Finishes the operation started with _cairo_surface_acquire_dest_image(), by, if * necessary, copying the image from @image back to @surface and freeing any * resources that were allocated. **/void_cairo_surface_release_dest_image (cairo_surface_t *surface, cairo_rectangle_int16_t *interest_rect, cairo_image_surface_t *image, cairo_rectangle_int16_t *image_rect, void *image_extra){ assert (!surface->finished); if (surface->backend->release_dest_image) surface->backend->release_dest_image (surface, interest_rect, image, image_rect, image_extra);}/** * _cairo_surface_clone_similar: * @surface: a #cairo_surface_t * @src: the source image * @clone_out: location to store a surface compatible with @surface * and with contents identical to @src. The caller must call * cairo_surface_destroy() on the result. * * Creates a surface with contents identical to @src but that * can be used efficiently with @surface. If @surface and @src are * already compatible then it may return a new reference to @src. * * Return value: %CAIRO_STATUS_SUCCESS if a surface was created and stored * in @clone_out. Otherwise %CAIRO_INT_STATUS_UNSUPPORTED or another * error like %CAIRO_STATUS_NO_MEMORY. **/cairo_status_t_cairo_surface_clone_similar (cairo_surface_t *surface, cairo_surface_t *src, cairo_surface_t **clone_out){ cairo_status_t status; cairo_image_surface_t *image; void *image_extra; if (surface->finished) return CAIRO_STATUS_SURFACE_FINISHED; if (surface->backend->clone_similar == NULL) return CAIRO_INT_STATUS_UNSUPPORTED; status = surface->backend->clone_similar (surface, src, clone_out); if (status == CAIRO_STATUS_SUCCESS) (*clone_out)->device_transform = src->device_transform; if (status != CAIRO_INT_STATUS_UNSUPPORTED) return status; status = _cairo_surface_acquire_source_image (src, &image, &image_extra); if (status != CAIRO_STATUS_SUCCESS) return status; status = surface->backend->clone_similar (surface, &image->base, clone_out); if (status == CAIRO_STATUS_SUCCESS) (*clone_out)->device_transform = src->device_transform; /* If the above failed point, we could implement a full fallback * using acquire_dest_image, but that's going to be very * inefficient compared to a backend-specific implementation of * clone_similar() with an image source. So we don't bother */ _cairo_surface_release_source_image (src, image, image_extra); return status;}/* XXX: Shouldn't really need to do this here. */#include "cairo-meta-surface-private.h"/** * _cairo_surface_snapshot * @surface: a #cairo_surface_t * * Make an immutable copy of @surface. It is an error to call a * surface-modifying function on the result of this function. * * The caller owns the return value and should call * cairo_surface_destroy when finished with it. This function will not * return NULL, but will return a nil surface instead. * * Return value: The snapshot surface. Note that the return surface * may not necessarily be of the same type as @surface. **/cairo_surface_t *_cairo_surface_snapshot (cairo_surface_t *surface){ if (surface->finished) return (cairo_surface_t *) &_cairo_surface_nil; if (surface->backend->snapshot) return surface->backend->snapshot (surface); return _cairo_surface_fallback_snapshot (surface);}cairo_status_t_cairo_surface_composite (cairo_operator_t op, cairo_pattern_t *src, cairo_pattern_t *mask, cairo_surface_t *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_int_status_t status; assert (! dst->is_snapshot); if (mask) { /* These operators aren't interpreted the same way by the backends; * they are implemented in terms of other operators in cairo-gstate.c */ assert (op != CAIRO_OPERATOR_SOURCE && op != CAIRO_OPERATOR_CLEAR); } if (dst->status) return dst->status; if (dst->finished) return CAIRO_STATUS_SURFACE_FINISHED; if (dst->backend->composite) { status = dst->backend->composite (op, src, mask, dst, src_x, src_y, mask_x, mask_y, dst_x, dst_y, width, height); if (status != CAIRO_INT_STATUS_UNSUPPORTED) return status; } return _cairo_surface_fallback_composite (op, src, mask, dst, src_x, src_y, mask_x, mask_y, dst_x, dst_y, width, height);}/** * _cairo_surface_fill_rectangle: * @surface: a #cairo_surface_t * @op: the operator to apply to the rectangle * @color: the source color * @x: X coordinate of rectangle, in backend coordinates * @y: Y coordinate of rectangle, in backend coordinates * @width: width of rectangle, in backend coordinates * @height: height of rectangle, in backend coordinates * * Applies an operator to a rectangle using a solid color as the source. * See _cairo_surface_fill_rectangles() for full details. * * Return value: %CAIRO_STATUS_SUCCESS or the error that occurred **/cairo_status_t_cairo_surface_fill_rectangle (cairo_surface_t *surface, cairo_operator_t op, const cairo_color_t *color, int x, int y, int width, int height){ cairo_rectangle_int16_t rect; assert (! surface->is_snapshot); if (surface->status) return surface->status; if (surface->finished) return CAIRO_STATUS_SURFACE_FINISHED; rect.x = x; rect.y = y; rect.width = width; rect.height = height; return _cairo_surface_fill_rectangles (surface, op, color, &rect, 1);}/** * _cairo_surface_fill_region: * @surface: a #cairo_surface_t * @op: the operator to apply to the region * @color: the source color * @region: the region to modify, in backend coordinates * * Applies an operator to a set of rectangles specified as a * #pixman_region16_t using a solid color as the source. * See _cairo_surface_fill_rectangles() for full details. * * Return value: %CAIRO_STATUS_SUCCESS or the error that occurred **/cairo_status_t_cairo_surface_fill_region (cairo_surface_t *surface, cairo_operator_t op, const cairo_color_t *color, pixman_region16_t *region){ int num_rects = pixman_region_num_rects (region); pixman_box16_t *boxes = pixman_region_rects (region); cairo_rectangle_int16_t *rects; cairo_status_t status; int i; assert (! surface->is_snapshot); if (!num_rects) return CAIRO_STATUS_SUCCESS; rects = malloc (sizeof (pixman_rectangle_t) * num_rects); if (!rects) return CAIRO_STATUS_NO_MEMORY; for (i = 0; i < num_rects; i++) { rects[i].x = boxes[i].x1; rects[i].y = boxes[i].y1; rects[i].width = boxes[i].x2 - boxes[i].x1; rects[i].height = boxes[i].y2 - boxes[i].y1; } status = _cairo_surface_fill_rectangles (surface, op, color, rects, num_rects); free (rects); return status;}/** * _cairo_surface_fill_rectangles: * @surface: a #cairo_surface_t * @op: the operator to apply to the region * @color: the source color * @rects: the rectangles to modify, in backend coordinates * @num_rects: the number of rectangles in @rects * * Applies an operator to a set of rectangles using a solid color * as the source. Note that even if the operator is an unbounded operator * such as %CAIRO_OPERATOR_IN, only the given set of rectangles * is affected. This differs from _cairo_surface_composite_trapezoids() * where the entire destination rectangle is cleared. * * Return value: %CAIRO_STATUS_SUCCESS or the error that occurred **/cairo_status_t_cairo_surface_fill_rectangles (cairo_surface_t *surface, cairo_operator_t op, const cairo_color_t *color, cairo_rectangle_int16_t *rects, int num_rects){ cairo_int_status_t status; assert (! surface->is_snapshot); if (surface->status) return surface->status; if (surface->finished) return CAIRO_STATUS_SURFACE_FINISHED; if (num_rects == 0) return CAIRO_STATUS_SUCCESS; if (surface->backend->fill_rectangles) { status = surface->backend->fill_rectangles (surface, op, color, rects, num_rects); if (status != CAIRO_INT_STATUS_UNSUPPORTED) return status; } return _cairo_surface_fallback_fill_rectangles (surface, op, color, rects, num_rects);}cairo_status_t_cairo_surface_paint (cairo_surface_t *surface, cairo_operator_t op, cairo_pattern_t *source){ cairo_status_t status; cairo_pattern_union_t dev_source; assert (! surface->is_snapshot); if (source->type == CAIRO_PATTERN_TYPE_SURFACE && (source->extend == CAIRO_EXTEND_REFLECT || source->extend == CAIRO_EXTEND_PAD)) { return CAIRO_STATUS_NO_MEMORY; } _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base); if (surface->backend->paint) { status = surface->backend->paint (surface, op, &dev_source.base); if (status != CAIRO_INT_STATUS_UNSUPPORTED) goto FINISH; } status = _cairo_surface_fallback_paint (surface, op, &dev_source.base); FINISH: _cairo_pattern_fini (&dev_source.base); return status;}cairo_status_t_cairo_surface_mask (cairo_surface_t *surface, cairo_operator_t op, cairo_pattern_t *source, cairo_pattern_t *mask){ cairo_status_t status; cairo_pattern_union_t dev_source; cairo_pattern_union_t dev_mask; assert (! surface->is_snapshot); if (source->type == CAIRO_PATTERN_TYPE_SURFACE && (source->extend == CAIRO_EXTEND_REFLECT || source->extend == CAIRO_EXTEND_PAD)) { return CAIRO_STATUS_NO_MEMORY; } _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base); _cairo_surface_copy_pattern_for_destination (mask, surface, &dev_mask.base); if (surface->backend->mask) { status = surface->backend->mask (surface, op, &dev_source.base, &dev_mask.base); if (status != CAIRO_INT_STATUS_UNSUPPORTED) goto FINISH; } status = _cairo_surface_fallback_mask (surface, op, &dev_source.base, &dev_mask.base); FINISH: _cairo_pattern_fini (&dev_mask.base); _cairo_pattern_fini (&dev_source.base); return status;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -