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

📄 cairo-xlib-surface.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 5 页
字号:
    XRenderSetPictureTransform (surface->dpy, surface->src_picture, &xtransform);    return CAIRO_STATUS_SUCCESS;}static cairo_status_t_cairo_xlib_surface_set_filter (cairo_xlib_surface_t *surface,				cairo_filter_t	     filter){    char *render_filter;    if (!surface->src_picture)	return CAIRO_STATUS_SUCCESS;    if (!CAIRO_SURFACE_RENDER_HAS_FILTERS (surface))    {	if (filter == CAIRO_FILTER_FAST || filter == CAIRO_FILTER_NEAREST)	    return CAIRO_STATUS_SUCCESS;	return CAIRO_INT_STATUS_UNSUPPORTED;    }    switch (filter) {    case CAIRO_FILTER_FAST:	render_filter = FilterFast;	break;    case CAIRO_FILTER_GOOD:	render_filter = FilterGood;	break;    case CAIRO_FILTER_BEST:	render_filter = FilterBest;	break;    case CAIRO_FILTER_NEAREST:	render_filter = FilterNearest;	break;    case CAIRO_FILTER_BILINEAR:	render_filter = FilterBilinear;	break;    default:	render_filter = FilterBest;	break;    }    XRenderSetPictureFilter (surface->dpy, surface->src_picture,			     render_filter, NULL, 0);    return CAIRO_STATUS_SUCCESS;}static cairo_status_t_cairo_xlib_surface_set_repeat (cairo_xlib_surface_t *surface, int repeat){    XRenderPictureAttributes pa;    unsigned long	     mask;    if (!surface->src_picture)	return CAIRO_STATUS_SUCCESS;    mask = CPRepeat;    pa.repeat = repeat;    XRenderChangePicture (surface->dpy, surface->src_picture, mask, &pa);    return CAIRO_STATUS_SUCCESS;}static cairo_int_status_t_cairo_xlib_surface_set_attributes (cairo_xlib_surface_t	  *surface,				       cairo_surface_attributes_t *attributes){    cairo_int_status_t status;    _cairo_xlib_surface_ensure_src_picture (surface);    status = _cairo_xlib_surface_set_matrix (surface, &attributes->matrix);    if (status)	return status;    switch (attributes->extend) {    case CAIRO_EXTEND_NONE:	_cairo_xlib_surface_set_repeat (surface, 0);	break;    case CAIRO_EXTEND_REPEAT:	_cairo_xlib_surface_set_repeat (surface, 1);	break;    case CAIRO_EXTEND_REFLECT:    case CAIRO_EXTEND_PAD:	return CAIRO_INT_STATUS_UNSUPPORTED;    }    status = _cairo_xlib_surface_set_filter (surface, attributes->filter);    if (status)	return status;    return CAIRO_STATUS_SUCCESS;}/* Checks whether we can can directly draw from src to dst with * the core protocol: either with CopyArea or using src as a * a tile in a GC. */static cairo_bool_t_surfaces_compatible (cairo_xlib_surface_t *dst,		      cairo_xlib_surface_t *src){    /* same screen */    if (!_cairo_xlib_surface_same_screen (dst, src))	return FALSE;    /* same depth (for core) */    if (src->depth != dst->depth)	return FALSE;    /* if Render is supported, match picture formats */    if (src->xrender_format != NULL && src->xrender_format == dst->xrender_format)	return TRUE;    /* Without Render, match visuals instead */    if (src->visual == dst->visual)	return TRUE;    return FALSE;}static cairo_bool_t_surface_has_alpha (cairo_xlib_surface_t *surface){    if (surface->xrender_format) {	if (surface->xrender_format->type == PictTypeDirect &&	    surface->xrender_format->direct.alphaMask != 0)	    return TRUE;	else	    return FALSE;    } else {	/* In the no-render case, we never have alpha */	return FALSE;    }}/* Returns true if the given operator and source-alpha combination * requires alpha compositing to complete. */static cairo_bool_t_operator_needs_alpha_composite (cairo_operator_t op,				 cairo_bool_t     surface_has_alpha){    if (op == CAIRO_OPERATOR_SOURCE ||	(!surface_has_alpha &&	 (op == CAIRO_OPERATOR_OVER ||	  op == CAIRO_OPERATOR_ATOP ||	  op == CAIRO_OPERATOR_IN)))	return FALSE;    return TRUE;}/* There is a bug in most older X servers with compositing using a * untransformed repeating source pattern when the source is in off-screen * video memory, and another with repeated transformed images using a * general tranform matrix. When these bugs could be triggered, we need a * fallback: in the common case where we have no transformation and the * source and destination have the same format/visual, we can do the * operation using the core protocol for the first bug, otherwise, we need * a software fallback. * * We can also often optimize a compositing operation by calling XCopyArea * for some common cases where there is no alpha compositing to be done. * We figure that out here as well. */typedef enum {    DO_RENDER,		/* use render */    DO_XCOPYAREA,	/* core protocol XCopyArea optimization/fallback */    DO_XTILE,		/* core protocol XSetTile optimization/fallback */    DO_UNSUPPORTED	/* software fallback */} composite_operation_t;/* Initial check for the render bugs; we need to recheck for the * offscreen-memory bug after we turn patterns into surfaces, since that * may introduce a repeating pattern for gradient patterns.  We don't need * to check for the repeat+transform bug because gradient surfaces aren't * transformed. * * All we do here is reject cases where we *know* are going to * hit the bug and won't be able to use a core protocol fallback. */static composite_operation_t_categorize_composite_operation (cairo_xlib_surface_t *dst,				 cairo_operator_t      op,				 cairo_pattern_t      *src_pattern,				 cairo_bool_t	       have_mask){    if (!dst->buggy_repeat)	return DO_RENDER;    if (src_pattern->type == CAIRO_PATTERN_TYPE_SURFACE)    {	cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *)src_pattern;	if (_cairo_matrix_is_integer_translation (&src_pattern->matrix, NULL, NULL) &&	    src_pattern->extend == CAIRO_EXTEND_REPEAT)	{	    /* This is the case where we have the bug involving	     * untransformed repeating source patterns with off-screen	     * video memory; reject some cases where a core protocol	     * fallback is impossible.	     */	    if (have_mask ||		!(op == CAIRO_OPERATOR_SOURCE || op == CAIRO_OPERATOR_OVER))		return DO_UNSUPPORTED;	    if (_cairo_surface_is_xlib (surface_pattern->surface)) {		cairo_xlib_surface_t *src = (cairo_xlib_surface_t *)surface_pattern->surface;		if (op == CAIRO_OPERATOR_OVER && _surface_has_alpha (src))		    return DO_UNSUPPORTED;		/* If these are on the same screen but otherwise incompatible,		 * make a copy as core drawing can't cross depths and doesn't		 * work rightacross visuals of the same depth		 */		if (_cairo_xlib_surface_same_screen (dst, src) &&		    !_surfaces_compatible (dst, src))		    return DO_UNSUPPORTED;	    }	}	/* Check for the other bug involving repeat patterns with general	 * transforms. */	if (!_cairo_matrix_is_integer_translation (&src_pattern->matrix, NULL, NULL) &&	    src_pattern->extend == CAIRO_EXTEND_REPEAT)	    return DO_UNSUPPORTED;    }    return DO_RENDER;}/* Recheck for composite-repeat once we've turned patterns into Xlib surfaces * If we end up returning DO_UNSUPPORTED here, we're throwing away work we * did to turn gradients into a pattern, but most of the time we can handle * that case with core protocol fallback. * * Also check here if we can just use XCopyArea, instead of going through * Render. */static composite_operation_t_recategorize_composite_operation (cairo_xlib_surface_t	      *dst,				   cairo_operator_t	       op,				   cairo_xlib_surface_t	      *src,				   cairo_surface_attributes_t *src_attr,				   cairo_bool_t		       have_mask){    cairo_bool_t is_integer_translation =	_cairo_matrix_is_integer_translation (&src_attr->matrix, NULL, NULL);    cairo_bool_t needs_alpha_composite =	_operator_needs_alpha_composite (op, _surface_has_alpha (src));    if (!have_mask &&	is_integer_translation &&	src_attr->extend == CAIRO_EXTEND_NONE &&	!needs_alpha_composite &&	_surfaces_compatible(src, dst))    {	return DO_XCOPYAREA;    }    if (!dst->buggy_repeat)	return DO_RENDER;    if (is_integer_translation &&	src_attr->extend == CAIRO_EXTEND_REPEAT &&	(src->width != 1 || src->height != 1))    {	if (!have_mask &&	    !needs_alpha_composite &&	    _surfaces_compatible (dst, src))	{	    return DO_XTILE;	}	return DO_UNSUPPORTED;    }    return DO_RENDER;}static int_render_operator (cairo_operator_t op){    switch (op) {    case CAIRO_OPERATOR_CLEAR:	return PictOpClear;    case CAIRO_OPERATOR_SOURCE:	return PictOpSrc;    case CAIRO_OPERATOR_OVER:	return PictOpOver;    case CAIRO_OPERATOR_IN:	return PictOpIn;    case CAIRO_OPERATOR_OUT:	return PictOpOut;    case CAIRO_OPERATOR_ATOP:	return PictOpAtop;    case CAIRO_OPERATOR_DEST:	return PictOpDst;    case CAIRO_OPERATOR_DEST_OVER:	return PictOpOverReverse;    case CAIRO_OPERATOR_DEST_IN:	return PictOpInReverse;    case CAIRO_OPERATOR_DEST_OUT:	return PictOpOutReverse;    case CAIRO_OPERATOR_DEST_ATOP:	return PictOpAtopReverse;    case CAIRO_OPERATOR_XOR:	return PictOpXor;    case CAIRO_OPERATOR_ADD:	return PictOpAdd;    case CAIRO_OPERATOR_SATURATE:	return PictOpSaturate;    default:	return PictOpOver;    }}static cairo_int_status_t_cairo_xlib_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_xlib_surface_t	*dst = abstract_dst;    cairo_xlib_surface_t	*src;    cairo_xlib_surface_t	*mask;    cairo_int_status_t		status;    composite_operation_t       operation;    int				itx, ity;    if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst))	return CAIRO_INT_STATUS_UNSUPPORTED;    operation = _categorize_composite_operation (dst, op, src_pattern,						 mask_pattern != NULL);    if (operation == DO_UNSUPPORTED)	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;    operation = _recategorize_composite_operation (dst, op, src, &src_attr,						   mask_pattern != NULL);    if (operation == DO_UNSUPPORTED) {	status = CAIRO_INT_STATUS_UNSUPPORTED;	goto BAIL;    }    status = _cairo_xlib_surface_set_attributes (src, &src_attr);    if (status)	goto BAIL;    switch (operation)    {    case DO_RENDER:	_cairo_xlib_surface_ensure_dst_picture (dst);	if (mask) {	    status = _cairo_xlib_surface_set_attributes (mask, &mask_attr);	    if (status)		goto BAIL;	    XRenderComposite (dst->dpy,			      _render_operator (op),			      src->src_picture,			      mask->src_picture,			      dst->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 (op),			      src->src_picture,			      0,			      dst->dst_picture,			      src_x + src_attr.x_offset,			      src_y + src_attr.y_offset,			      0, 0,			      dst_x, dst_y,			      width, height);	}	break;    case DO_XCOPYAREA:	_cairo_xlib_surface_ensure_gc (dst);	XCopyArea (dst->dpy,		   src->drawable,		   dst->drawable,		   dst->gc,		   src_x + src_attr.x_offset,		   src_y + src_attr.y_offset,		   width, height,		   dst_x, dst_y);	break;    case DO_XTILE:	/* This case is only used for bug fallbacks, though it is theoretically	 * applicable to the case where we don't have the RENDER extension as	 * well.	 *	 * We've checked that we have a repeating unscaled source in	 * _recategorize_composite_operation.	 */	_cairo_xlib_surface_ensure_gc (dst);	_cairo_matrix_is_integer_translation (&src_attr.matrix, &itx, &ity);	XSetTSOrigin (dst->dpy, dst->gc,		      - (itx + src_attr.x_offset), - (ity + src_attr.y_offset));	XSetTile (dst->dpy, dst->gc, src->drawable);	XSetFillStyle (dst->dpy, dst->gc, FillTiled);	XFillRectangle (dst->dpy, dst->drawable, dst->gc,			dst_x, dst_y, width, height);	break;    default:	ASSERT_NOT_REACHED;    }    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); BAIL:

⌨️ 快捷键说明

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