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

📄 cairo-xcb-surface.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 3 页
字号:
	 * retry, but to keep things simple, we just create a	 * temporary pixmap	 */	XCBDRAWABLE drawable;	drawable.pixmap = XCBPIXMAPNew (surface->dpy);	XCBCreatePixmap (surface->dpy,			 surface->depth,			 drawable.pixmap,			 surface->drawable,			 x2 - x1, y2 - y1);	_cairo_xcb_surface_ensure_gc (surface);	XCBCopyArea (surface->dpy, surface->drawable, drawable, surface->gc,		     x1, y1, 0, 0, x2 - x1, y2 - y1);	imagerep = XCBGetImageReply(surface->dpy,				    XCBGetImage(surface->dpy, XCBImageFormatZPixmap,						drawable,						x1, y1,						x2 - x1, y2 - y1,						AllPlanes), 0);	XCBFreePixmap (surface->dpy, drawable.pixmap);    }    if (!imagerep)	return CAIRO_STATUS_NO_MEMORY;    bpp = _bits_per_pixel(surface->dpy, imagerep->depth);    bytes_per_line = _bytes_per_line(surface->dpy, surface->width, bpp);    data = malloc (bytes_per_line * surface->height);    if (data == NULL) {	free (imagerep);	return CAIRO_STATUS_NO_MEMORY;    }    memcpy (data, XCBGetImageData (imagerep), bytes_per_line * surface->height);    free (imagerep);    /*     * Compute the pixel format masks from either an XCBVISUALTYPE or     * a XCBRenderPCTFORMINFO, failing we assume the drawable is an     * alpha-only pixmap as it could only have been created that way     * through the cairo_xlib_surface_create_for_bitmap function.     */    if (surface->visual) {	masks.bpp = bpp;	masks.alpha_mask = 0;	masks.red_mask = surface->visual->red_mask;	masks.green_mask = surface->visual->green_mask;	masks.blue_mask = surface->visual->blue_mask;    } else if (surface->has_format) {	masks.bpp = bpp;	masks.red_mask = (unsigned long)surface->format.direct.red_mask << surface->format.direct.red_shift;	masks.green_mask = (unsigned long)surface->format.direct.green_mask << surface->format.direct.green_shift;	masks.blue_mask = (unsigned long)surface->format.direct.blue_mask << surface->format.direct.blue_shift;	masks.alpha_mask = (unsigned long)surface->format.direct.alpha_mask << surface->format.direct.alpha_shift;    } else {	masks.bpp = bpp;	masks.red_mask = 0;	masks.green_mask = 0;	masks.blue_mask = 0;	if (surface->depth < 32)	    masks.alpha_mask = (1 << surface->depth) - 1;	else	    masks.alpha_mask = 0xffffffff;    }    /*     * Prefer to use a standard pixman format instead of the     * general masks case.     */    if (_CAIRO_MASK_FORMAT (&masks, &format)) {	image = (cairo_image_surface_t *)	    cairo_image_surface_create_for_data (data,						 format,						 x2 - x1,						 y2 - y1,						 bytes_per_line);	if (image->base.status)	    goto FAIL;    } else {	/*	 * XXX This can't work.  We must convert the data to one of the	 * supported pixman formats.  Pixman needs another function	 * which takes data in an arbitrary format and converts it	 * to something supported by that library.	 */	image = (cairo_image_surface_t *)	    _cairo_image_surface_create_with_masks (data,						    &masks,						    x2 - x1,						    y2 - y1,						    bytes_per_line);	if (image->base.status)	    goto FAIL;    }    /* Let the surface take ownership of the data */    _cairo_image_surface_assume_ownership_of_data (image);    *image_out = image;    return CAIRO_STATUS_SUCCESS; FAIL:    free (data);    return CAIRO_STATUS_NO_MEMORY;}static void_cairo_xcb_surface_ensure_gc (cairo_xcb_surface_t *surface){    if (surface->gc.xid)	return;    surface->gc = XCBGCONTEXTNew(surface->dpy);    XCBCreateGC (surface->dpy, surface->gc, surface->drawable, 0, 0);}static cairo_status_t_draw_image_surface (cairo_xcb_surface_t    *surface,		     cairo_image_surface_t  *image,		     int                    dst_x,		     int                    dst_y){    int bpp, data_len;    _cairo_xcb_surface_ensure_gc (surface);    bpp = _bits_per_pixel(surface->dpy, image->depth);    data_len = _bytes_per_line(surface->dpy, image->width, bpp) * image->height;    XCBPutImage(surface->dpy, XCBImageFormatZPixmap, surface->drawable, surface->gc,	      image->width,	      image->height,	      dst_x, dst_y,	      /* left_pad */ 0, image->depth,	      data_len, image->data);    return CAIRO_STATUS_SUCCESS;}static cairo_status_t_cairo_xcb_surface_acquire_source_image (void                    *abstract_surface,					 cairo_image_surface_t  **image_out,					 void                   **image_extra){    cairo_xcb_surface_t *surface = abstract_surface;    cairo_image_surface_t *image;    cairo_status_t status;    status = _get_image_surface (surface, NULL, &image, NULL);    if (status)	return status;    *image_out = image;    *image_extra = NULL;    return CAIRO_STATUS_SUCCESS;}static void_cairo_xcb_surface_release_source_image (void                   *abstract_surface,					 cairo_image_surface_t  *image,					 void                   *image_extra){    cairo_surface_destroy (&image->base);}static cairo_status_t_cairo_xcb_surface_acquire_dest_image (void                    *abstract_surface,				       cairo_rectangle_int16_t *interest_rect,				       cairo_image_surface_t  **image_out,				       cairo_rectangle_int16_t *image_rect_out,				       void                   **image_extra){    cairo_xcb_surface_t *surface = abstract_surface;    cairo_image_surface_t *image;    cairo_status_t status;    status = _get_image_surface (surface, interest_rect, &image, image_rect_out);    if (status)	return status;    *image_out = image;    *image_extra = NULL;    return CAIRO_STATUS_SUCCESS;}static void_cairo_xcb_surface_release_dest_image (void                   *abstract_surface,				       cairo_rectangle_int16_t      *interest_rect,				       cairo_image_surface_t  *image,				       cairo_rectangle_int16_t      *image_rect,				       void                   *image_extra){    cairo_xcb_surface_t *surface = abstract_surface;    /* ignore errors */    _draw_image_surface (surface, image, image_rect->x, image_rect->y);    cairo_surface_destroy (&image->base);}/* * Return whether two xcb surfaces share the same * screen.  Both core and Render drawing require this * when using multiple drawables in an operation. */static cairo_bool_t_cairo_xcb_surface_same_screen (cairo_xcb_surface_t *dst,				cairo_xcb_surface_t *src){    return dst->dpy == src->dpy && dst->screen == src->screen;}static cairo_status_t_cairo_xcb_surface_clone_similar (void			*abstract_surface,				  cairo_surface_t	*src,				  cairo_surface_t     **clone_out){    cairo_xcb_surface_t *surface = abstract_surface;    cairo_xcb_surface_t *clone;    if (src->backend == surface->base.backend ) {	cairo_xcb_surface_t *xcb_src = (cairo_xcb_surface_t *)src;	if (_cairo_xcb_surface_same_screen(surface, xcb_src)) {	    *clone_out = cairo_surface_reference (src);	    return CAIRO_STATUS_SUCCESS;	}    } else if (_cairo_surface_is_image (src)) {	cairo_image_surface_t *image_src = (cairo_image_surface_t *)src;	cairo_content_t content = _cairo_content_from_format (image_src->format);	if (surface->base.status)	    return surface->base.status;	clone = (cairo_xcb_surface_t *)	    _cairo_xcb_surface_create_similar (surface, content,					       image_src->width, image_src->height);	if (clone->base.status)	    return CAIRO_STATUS_NO_MEMORY;	_draw_image_surface (clone, image_src, 0, 0);	*clone_out = &clone->base;	return CAIRO_STATUS_SUCCESS;    }    return CAIRO_INT_STATUS_UNSUPPORTED;}static cairo_status_t_cairo_xcb_surface_set_matrix (cairo_xcb_surface_t *surface,			       cairo_matrix_t	   *matrix){    XCBRenderTRANSFORM xtransform;    if (!surface->picture.xid)	return CAIRO_STATUS_SUCCESS;    xtransform.matrix11 = _cairo_fixed_from_double (matrix->xx);    xtransform.matrix12 = _cairo_fixed_from_double (matrix->xy);    xtransform.matrix13 = _cairo_fixed_from_double (matrix->x0);    xtransform.matrix21 = _cairo_fixed_from_double (matrix->yx);    xtransform.matrix22 = _cairo_fixed_from_double (matrix->yy);    xtransform.matrix23 = _cairo_fixed_from_double (matrix->y0);    xtransform.matrix31 = 0;    xtransform.matrix32 = 0;    xtransform.matrix33 = _cairo_fixed_from_double (1);    if (!CAIRO_SURFACE_RENDER_HAS_PICTURE_TRANSFORM (surface))    {	static const XCBRenderTRANSFORM identity = {	    1 << 16, 0x00000, 0x00000,	    0x00000, 1 << 16, 0x00000,	    0x00000, 0x00000, 1 << 16	};	if (memcmp (&xtransform, &identity, sizeof (XCBRenderTRANSFORM)) == 0)	    return CAIRO_STATUS_SUCCESS;	return CAIRO_INT_STATUS_UNSUPPORTED;    }    XCBRenderSetPictureTransform (surface->dpy, surface->picture, xtransform);    return CAIRO_STATUS_SUCCESS;}static cairo_status_t_cairo_xcb_surface_set_filter (cairo_xcb_surface_t *surface,			       cairo_filter_t	   filter){    char *render_filter;    if (!surface->picture.xid)	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 = "fast";	break;    case CAIRO_FILTER_GOOD:	render_filter = "good";	break;    case CAIRO_FILTER_BEST:	render_filter = "best";	break;    case CAIRO_FILTER_NEAREST:	render_filter = "nearest";	break;    case CAIRO_FILTER_BILINEAR:	render_filter = "bilinear";	break;    default:	render_filter = "best";	break;    }    XCBRenderSetPictureFilter(surface->dpy, surface->picture,			     strlen(render_filter), render_filter, 0, NULL);    return CAIRO_STATUS_SUCCESS;}static cairo_status_t_cairo_xcb_surface_set_repeat (cairo_xcb_surface_t *surface, int repeat){    CARD32 mask = XCBRenderCPRepeat;    CARD32 pa[] = { repeat };    if (!surface->picture.xid)	return CAIRO_STATUS_SUCCESS;    XCBRenderChangePicture (surface->dpy, surface->picture, mask, pa);    return CAIRO_STATUS_SUCCESS;}static cairo_int_status_t_cairo_xcb_surface_set_attributes (cairo_xcb_surface_t	      *surface,				   cairo_surface_attributes_t *attributes){    cairo_int_status_t status;    status = _cairo_xcb_surface_set_matrix (surface, &attributes->matrix);    if (status)	return status;    switch (attributes->extend) {    case CAIRO_EXTEND_NONE:	_cairo_xcb_surface_set_repeat (surface, 0);	break;    case CAIRO_EXTEND_REPEAT:	_cairo_xcb_surface_set_repeat (surface, 1);	break;    case CAIRO_EXTEND_REFLECT:	return CAIRO_INT_STATUS_UNSUPPORTED;    case CAIRO_EXTEND_PAD:	return CAIRO_INT_STATUS_UNSUPPORTED;    }    status = _cairo_xcb_surface_set_filter (surface, attributes->filter);    if (status)	return status;    return CAIRO_STATUS_SUCCESS;}static int_render_operator (cairo_operator_t op){    switch (op) {    case CAIRO_OPERATOR_CLEAR:	return XCBRenderPictOpClear;    case CAIRO_OPERATOR_SOURCE:	return XCBRenderPictOpSrc;    case CAIRO_OPERATOR_DEST:	return XCBRenderPictOpDst;    case CAIRO_OPERATOR_OVER:	return XCBRenderPictOpOver;    case CAIRO_OPERATOR_DEST_OVER:	return XCBRenderPictOpOverReverse;    case CAIRO_OPERATOR_IN:	return XCBRenderPictOpIn;    case CAIRO_OPERATOR_DEST_IN:	return XCBRenderPictOpInReverse;    case CAIRO_OPERATOR_OUT:	return XCBRenderPictOpOut;    case CAIRO_OPERATOR_DEST_OUT:	return XCBRenderPictOpOutReverse;    case CAIRO_OPERATOR_ATOP:	return XCBRenderPictOpAtop;    case CAIRO_OPERATOR_DEST_ATOP:	return XCBRenderPictOpAtopReverse;    case CAIRO_OPERATOR_XOR:	return XCBRenderPictOpXor;    case CAIRO_OPERATOR_ADD:	return XCBRenderPictOpAdd;    case CAIRO_OPERATOR_SATURATE:	return XCBRenderPictOpSaturate;    default:	return XCBRenderPictOpOver;    }}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)	{

⌨️ 快捷键说明

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