⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cairo-surface-fallback.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 3 页
字号:
/* cairo - a vector graphics library with display and print output * * Copyright © 2002 University of Southern California * Copyright © 2005 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public * License version 2.1 as published by the Free Software Foundation * (the "LGPL") or, at your option, under the terms of the Mozilla * Public License Version 1.1 (the "MPL"). If you do not alter this * notice, a recipient may use your version of this file under either * the MPL or the LGPL. * * You should have received a copy of the LGPL along with this library * in the file COPYING-LGPL-2.1; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * You should have received a copy of the MPL along with this library * in the file COPYING-MPL-1.1 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY * OF ANY KIND, either express or implied. See the LGPL or the MPL for * the specific language governing rights and limitations. * * The Original Code is the cairo graphics library. * * The Initial Developer of the Original Code is University of Southern * California. * * Contributor(s): *	Carl D. Worth <cworth@cworth.org> */#include "cairo-surface-fallback-private.h"#include "cairo-clip-private.h"typedef struct {    cairo_surface_t *dst;    cairo_rectangle_int16_t extents;    cairo_image_surface_t *image;    cairo_rectangle_int16_t image_rect;    void *image_extra;} fallback_state_t;/** * _fallback_init: * * Acquire destination image surface needed for an image-based * fallback. * * Return value: CAIRO_INT_STATUS_NOTHING_TO_DO if the extents are not * visible, CAIRO_STATUS_SUCCESS if some portion is visible and all * went well, or some error status otherwise. **/static cairo_int_status_t_fallback_init (fallback_state_t *state,		cairo_surface_t  *dst,		int               x,		int               y,		int               width,		int               height){    cairo_status_t status;    state->extents.x = x;    state->extents.y = y;    state->extents.width = width;    state->extents.height = height;    state->dst = dst;    status = _cairo_surface_acquire_dest_image (dst, &state->extents,						&state->image, &state->image_rect,						&state->image_extra);    if (status)	return status;    /* XXX: This NULL value tucked away in state->image is a rather     * ugly interface. Cleaner would be to push the     * CAIRO_INT_STATUS_NOTHING_TO_DO value down into     * _cairo_surface_acquire_dest_image and its backend     * counterparts. */    if (state->image == NULL)	return CAIRO_INT_STATUS_NOTHING_TO_DO;    return CAIRO_STATUS_SUCCESS;}static void_fallback_fini (fallback_state_t *state){    _cairo_surface_release_dest_image (state->dst, &state->extents,				       state->image, &state->image_rect,				       state->image_extra);}typedef cairo_status_t (*cairo_draw_func_t) (void                          *closure,					     cairo_operator_t               op,					     cairo_pattern_t               *src,					     cairo_surface_t               *dst,					     int                            dst_x,					     int                            dst_y,					     const cairo_rectangle_int16_t *extents);static cairo_status_t_create_composite_mask_pattern (cairo_surface_pattern_t       *mask_pattern,				cairo_clip_t                  *clip,				cairo_draw_func_t             draw_func,				void                          *draw_closure,				cairo_surface_t               *dst,				const cairo_rectangle_int16_t *extents){    cairo_surface_t *mask;    cairo_status_t status;    mask = cairo_surface_create_similar (dst,					 CAIRO_CONTENT_ALPHA,					 extents->width,					 extents->height);    if (mask->status)	return CAIRO_STATUS_NO_MEMORY;    status = (*draw_func) (draw_closure, CAIRO_OPERATOR_ADD,			   NULL, mask,			   extents->x, extents->y,			   extents);    if (status)	goto CLEANUP_SURFACE;    if (clip && clip->surface)	status = _cairo_clip_combine_to_surface (clip, CAIRO_OPERATOR_IN,						 mask,						 extents->x, extents->y,						 extents);    if (status)	goto CLEANUP_SURFACE;    _cairo_pattern_init_for_surface (mask_pattern, mask); CLEANUP_SURFACE:    cairo_surface_destroy (mask);    return status;}/* Handles compositing with a clip surface when the operator allows * us to combine the clip with the mask */static cairo_status_t_clip_and_composite_with_mask (cairo_clip_t                  *clip,			       cairo_operator_t               op,			       cairo_pattern_t               *src,			       cairo_draw_func_t              draw_func,			       void                          *draw_closure,			       cairo_surface_t               *dst,			       const cairo_rectangle_int16_t *extents){    cairo_surface_pattern_t mask_pattern;    cairo_status_t status;    status = _create_composite_mask_pattern (&mask_pattern,					     clip,					     draw_func, draw_closure,					     dst, extents);    if (status)	return status;    status = _cairo_surface_composite (op,				       src, &mask_pattern.base, dst,				       extents->x,     extents->y,				       0,              0,				       extents->x,     extents->y,				       extents->width, extents->height);    _cairo_pattern_fini (&mask_pattern.base);    return status;}/* Handles compositing with a clip surface when we have to do the operation * in two pieces and combine them together. */static cairo_status_t_clip_and_composite_combine (cairo_clip_t                  *clip,			     cairo_operator_t               op,			     cairo_pattern_t               *src,			     cairo_draw_func_t              draw_func,			     void                          *draw_closure,			     cairo_surface_t               *dst,			     const cairo_rectangle_int16_t *extents){    cairo_surface_t *intermediate;    cairo_surface_pattern_t dst_pattern;    cairo_surface_pattern_t intermediate_pattern;    cairo_status_t status;    /* We'd be better off here creating a surface identical in format     * to dst, but we have no way of getting that information.     * A CAIRO_CONTENT_CLONE or something might be useful.     * cairo_surface_create_similar() also unnecessarily clears the surface.     */    intermediate = cairo_surface_create_similar (dst,						 CAIRO_CONTENT_COLOR_ALPHA,						 extents->width,						 extents->height);    if (intermediate->status)	return CAIRO_STATUS_NO_MEMORY;    /* Initialize the intermediate surface from the destination surface     */    _cairo_pattern_init_for_surface (&dst_pattern, dst);    status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,				       &dst_pattern.base, NULL, intermediate,				       extents->x,     extents->y,				       0,              0,				       0,              0,				       extents->width, extents->height);    _cairo_pattern_fini (&dst_pattern.base);    if (status)	goto CLEANUP_SURFACE;    status = (*draw_func) (draw_closure, op,			   src, intermediate,			   extents->x, extents->y,			   extents);    if (status)	goto CLEANUP_SURFACE;    /* Combine that with the clip     */    status = _cairo_clip_combine_to_surface (clip, CAIRO_OPERATOR_DEST_IN,					     intermediate,					     extents->x, extents->y,					     extents);    if (status)	goto CLEANUP_SURFACE;    /* Punch the clip out of the destination     */    status = _cairo_clip_combine_to_surface (clip, CAIRO_OPERATOR_DEST_OUT,					     dst,					     0, 0,					     extents);    if (status)	goto CLEANUP_SURFACE;    /* Now add the two results together     */    _cairo_pattern_init_for_surface (&intermediate_pattern, intermediate);    status = _cairo_surface_composite (CAIRO_OPERATOR_ADD,				       &intermediate_pattern.base, NULL, dst,				       0,              0,				       0,              0,				       extents->x,     extents->y,				       extents->width, extents->height);    _cairo_pattern_fini (&intermediate_pattern.base); CLEANUP_SURFACE:    cairo_surface_destroy (intermediate);    return status;}/* Handles compositing for CAIRO_OPERATOR_SOURCE, which is special; it's * defined as (src IN mask IN clip) ADD (dst OUT (mask IN clip)) */static cairo_status_t_clip_and_composite_source (cairo_clip_t                  *clip,			    cairo_pattern_t               *src,			    cairo_draw_func_t              draw_func,			    void                          *draw_closure,			    cairo_surface_t               *dst,			    const cairo_rectangle_int16_t *extents){    cairo_surface_pattern_t mask_pattern;    cairo_status_t status;    /* Create a surface that is mask IN clip     */    status = _create_composite_mask_pattern (&mask_pattern,					     clip,					     draw_func, draw_closure,					     dst, extents);    if (status)	return status;    /* Compute dest' = dest OUT (mask IN clip)     */    status = _cairo_surface_composite (CAIRO_OPERATOR_DEST_OUT,				       &mask_pattern.base, NULL, dst,				       0,              0,				       0,              0,				       extents->x,     extents->y,				       extents->width, extents->height);    if (status)	goto CLEANUP_MASK_PATTERN;    /* Now compute (src IN (mask IN clip)) ADD dest'     */    status = _cairo_surface_composite (CAIRO_OPERATOR_ADD,				       src, &mask_pattern.base, dst,				       extents->x,     extents->y,				       0,              0,				       extents->x,     extents->y,				       extents->width, extents->height); CLEANUP_MASK_PATTERN:    _cairo_pattern_fini (&mask_pattern.base);    return status;}static int_cairo_rectangle_empty (const cairo_rectangle_int16_t *rect){    return rect->width == 0 || rect->height == 0;}/** * _clip_and_composite: * @clip: a #cairo_clip_t * @op: the operator to draw with * @src: source pattern * @draw_func: function that can be called to draw with the mask onto a surface. * @draw_closure: data to pass to @draw_func. * @dst: destination surface * @extents: rectangle holding a bounding box for the operation; this *           rectangle will be used as the size for the temporary *           surface. * * When there is a surface clip, we typically need to create an intermediate * surface. This function handles the logic of creating a temporary surface * drawing to it, then compositing the result onto the target surface. * * @draw_func is to called to draw the mask; it will be called no more * than once. * * Return value: %CAIRO_STATUS_SUCCESS if the drawing succeeded. **/static cairo_status_t_clip_and_composite (cairo_clip_t                  *clip,		     cairo_operator_t               op,		     cairo_pattern_t               *src,		     cairo_draw_func_t              draw_func,		     void                          *draw_closure,		     cairo_surface_t               *dst,		     const cairo_rectangle_int16_t *extents){    cairo_pattern_union_t solid_pattern;    cairo_status_t status;    if (_cairo_rectangle_empty (extents))	/* Nothing to do */	return CAIRO_STATUS_SUCCESS;    if (op == CAIRO_OPERATOR_CLEAR) {	_cairo_pattern_init_solid (&solid_pattern.solid, CAIRO_COLOR_WHITE);	src = &solid_pattern.base;	op = CAIRO_OPERATOR_DEST_OUT;    }    if ((clip && clip->surface) || op == CAIRO_OPERATOR_SOURCE)    {	if (op == CAIRO_OPERATOR_SOURCE)	    status = _clip_and_composite_source (clip,						 src,						 draw_func, draw_closure,						 dst, extents);	else if (_cairo_operator_bounded_by_mask (op))	    status = _clip_and_composite_with_mask (clip, op,						    src,						    draw_func, draw_closure,						    dst, extents);	else	    status = _clip_and_composite_combine (clip, op,						  src,						  draw_func, draw_closure,						  dst, extents);    }    else    {	status = (*draw_func) (draw_closure, op,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -