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

📄 cairo-xlib-surface.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 5 页
字号:
	ximage->bitmap_bit_order != native_byte_order) {	_swap_ximage_bits (ximage);	if (ximage->bitmap_bit_order == ximage->byte_order)	    return;    }    if (ximage->byte_order == native_byte_order)	return;    switch (ximage->bits_per_pixel) {    case 1:	unit_bytes = ximage->bitmap_unit / 8;	break;    case 8:    case 16:    case 32:	unit_bytes = ximage->bits_per_pixel / 8;	break;    default:        /* This could be hit on some uncommon but possible cases,	 * such as bpp=4. These are cases that libpixman can't deal	 * with in any case.	 */	ASSERT_NOT_REACHED;    }    switch (unit_bytes) {    case 1:	return;    case 2:	_swap_ximage_2bytes (ximage);	break;    case 4:	_swap_ximage_4bytes (ximage);	break;    default:	ASSERT_NOT_REACHED;    }}static cairo_status_t_get_image_surface (cairo_xlib_surface_t    *surface,		    cairo_rectangle_int16_t *interest_rect,		    cairo_image_surface_t  **image_out,		    cairo_rectangle_int16_t *image_rect){    cairo_image_surface_t *image;    XImage *ximage;    int x1, y1, x2, y2;    cairo_format_masks_t masks;    cairo_format_t format;    x1 = 0;    y1 = 0;    x2 = surface->width;    y2 = surface->height;    if (interest_rect) {	cairo_rectangle_int16_t rect;	rect.x = interest_rect->x;	rect.y = interest_rect->y;	rect.width = interest_rect->width;	rect.height = interest_rect->height;	if (rect.x > x1)	    x1 = rect.x;	if (rect.y > y1)	    y1 = rect.y;	if (rect.x + rect.width < x2)	    x2 = rect.x + rect.width;	if (rect.y + rect.height < y2)	    y2 = rect.y + rect.height;	if (x1 >= x2 || y1 >= y2) {	    *image_out = NULL;	    return CAIRO_STATUS_SUCCESS;	}    }    if (image_rect) {	image_rect->x = x1;	image_rect->y = y1;	image_rect->width = x2 - x1;	image_rect->height = y2 - y1;    }    /* XXX: This should try to use the XShm extension if available */    if (surface->use_pixmap == 0)    {	cairo_xlib_error_func_t old_handler;	old_handler = XSetErrorHandler (_noop_error_handler);	ximage = XGetImage (surface->dpy,			    surface->drawable,			    x1, y1,			    x2 - x1, y2 - y1,			    AllPlanes, ZPixmap);	XSetErrorHandler (old_handler);	/* If we get an error, the surface must have been a window,	 * so retry with the safe code path.	 */	if (!ximage)	    surface->use_pixmap = CAIRO_ASSUME_PIXMAP;    }    else    {	surface->use_pixmap--;	ximage = NULL;    }    if (!ximage)    {	/* XGetImage from a window is dangerous because it can	 * produce errors if the window is unmapped or partially	 * outside the screen. We could check for errors and	 * retry, but to keep things simple, we just create a	 * temporary pixmap	 */	Pixmap pixmap = XCreatePixmap (surface->dpy,				       surface->drawable,				       x2 - x1, y2 - y1,				       surface->depth);	_cairo_xlib_surface_ensure_gc (surface);	XCopyArea (surface->dpy, surface->drawable, pixmap, surface->gc,		   x1, y1, x2 - x1, y2 - y1, 0, 0);	ximage = XGetImage (surface->dpy,			    pixmap,			    0, 0,			    x2 - x1, y2 - y1,			    AllPlanes, ZPixmap);	XFreePixmap (surface->dpy, pixmap);    }    if (!ximage)	return CAIRO_STATUS_NO_MEMORY;    _swap_ximage_to_native (ximage);    /*     * Compute the pixel format masks from either a visual or a     * XRenderFormat, 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 = ximage->bits_per_pixel;	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->xrender_format) {	masks.bpp = ximage->bits_per_pixel;	masks.red_mask = (unsigned long)surface->xrender_format->direct.redMask << surface->xrender_format->direct.red;	masks.green_mask = (unsigned long)surface->xrender_format->direct.greenMask << surface->xrender_format->direct.green;	masks.blue_mask = (unsigned long)surface->xrender_format->direct.blueMask << surface->xrender_format->direct.blue;	masks.alpha_mask = (unsigned long)surface->xrender_format->direct.alphaMask << surface->xrender_format->direct.alpha;    } else {	masks.bpp = ximage->bits_per_pixel;	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 ((unsigned char *) ximage->data,						 format,						 ximage->width,						 ximage->height,						 ximage->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 ((unsigned char *) ximage->data,						    &masks,						    ximage->width,						    ximage->height,						    ximage->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);    ximage->data = NULL;    XDestroyImage (ximage);    *image_out = image;    return CAIRO_STATUS_SUCCESS; FAIL:    XDestroyImage (ximage);    return CAIRO_STATUS_NO_MEMORY;}static void_cairo_xlib_surface_ensure_src_picture (cairo_xlib_surface_t    *surface){    if (!surface->src_picture)	surface->src_picture = XRenderCreatePicture (surface->dpy,						     surface->drawable,						     surface->xrender_format,						     0, NULL);}static void_cairo_xlib_surface_set_picture_clip_rects (cairo_xlib_surface_t *surface){    if (surface->have_clip_rects)	XRenderSetPictureClipRectangles (surface->dpy, surface->dst_picture,					 0, 0,					 surface->clip_rects,					 surface->num_clip_rects);}static void_cairo_xlib_surface_set_gc_clip_rects (cairo_xlib_surface_t *surface){    if (surface->have_clip_rects)	XSetClipRectangles(surface->dpy, surface->gc,			   0, 0,			   surface->clip_rects,			   surface->num_clip_rects, YXSorted);}static void_cairo_xlib_surface_ensure_dst_picture (cairo_xlib_surface_t    *surface){    if (!surface->dst_picture) {	surface->dst_picture = XRenderCreatePicture (surface->dpy,						     surface->drawable,						     surface->xrender_format,						     0, NULL);	_cairo_xlib_surface_set_picture_clip_rects (surface);    }}static void_cairo_xlib_surface_ensure_gc (cairo_xlib_surface_t *surface){    XGCValues gcv;    if (surface->gc)	return;    gcv.graphics_exposures = False;    surface->gc = XCreateGC (surface->dpy, surface->drawable,			     GCGraphicsExposures, &gcv);    _cairo_xlib_surface_set_gc_clip_rects (surface);}static cairo_status_t_draw_image_surface (cairo_xlib_surface_t   *surface,		     cairo_image_surface_t  *image,		     int                    dst_x,		     int                    dst_y){    XImage ximage;    int bpp, alpha, red, green, blue;    int native_byte_order = _native_byte_order_lsb () ? LSBFirst : MSBFirst;    pixman_format_get_masks (pixman_image_get_format (image->pixman_image),			     &bpp, &alpha, &red, &green, &blue);    ximage.width = image->width;    ximage.height = image->height;    ximage.format = ZPixmap;    ximage.data = (char *)image->data;    ximage.byte_order = native_byte_order;    ximage.bitmap_unit = 32;	/* always for libpixman */    ximage.bitmap_bit_order = native_byte_order;    ximage.bitmap_pad = 32;	/* always for libpixman */    ximage.depth = image->depth;    ximage.bytes_per_line = image->stride;    ximage.bits_per_pixel = bpp;    ximage.red_mask = red;    ximage.green_mask = green;    ximage.blue_mask = blue;    ximage.xoffset = 0;    XInitImage (&ximage);    _cairo_xlib_surface_ensure_gc (surface);    XPutImage(surface->dpy, surface->drawable, surface->gc,	      &ximage, 0, 0, dst_x, dst_y,	      image->width, image->height);    return CAIRO_STATUS_SUCCESS;}static cairo_status_t_cairo_xlib_surface_acquire_source_image (void                    *abstract_surface,					  cairo_image_surface_t  **image_out,					  void                   **image_extra){    cairo_xlib_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_xlib_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_xlib_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_xlib_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_xlib_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_xlib_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 xlib surfaces share the same * screen.  Both core and Render drawing require this * when using multiple drawables in an operation. */static cairo_bool_t_cairo_xlib_surface_same_screen (cairo_xlib_surface_t *dst,				 cairo_xlib_surface_t *src){    return dst->dpy == src->dpy && dst->screen == src->screen;}static cairo_status_t_cairo_xlib_surface_clone_similar (void			*abstract_surface,				   cairo_surface_t	*src,				   cairo_surface_t     **clone_out){    cairo_xlib_surface_t *surface = abstract_surface;    cairo_xlib_surface_t *clone;    if (src->backend == surface->base.backend ) {	cairo_xlib_surface_t *xlib_src = (cairo_xlib_surface_t *)src;	if (_cairo_xlib_surface_same_screen (surface, xlib_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;	clone = (cairo_xlib_surface_t *)	    _cairo_xlib_surface_create_similar_with_format (surface, image_src->format,						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_xlib_surface_set_matrix (cairo_xlib_surface_t *surface,				cairo_matrix_t	     *matrix){    XTransform xtransform;    if (!surface->src_picture)	return CAIRO_STATUS_SUCCESS;    xtransform.matrix[0][0] = _cairo_fixed_from_double (matrix->xx);    xtransform.matrix[0][1] = _cairo_fixed_from_double (matrix->xy);    xtransform.matrix[0][2] = _cairo_fixed_from_double (matrix->x0);    xtransform.matrix[1][0] = _cairo_fixed_from_double (matrix->yx);    xtransform.matrix[1][1] = _cairo_fixed_from_double (matrix->yy);    xtransform.matrix[1][2] = _cairo_fixed_from_double (matrix->y0);    xtransform.matrix[2][0] = 0;    xtransform.matrix[2][1] = 0;    xtransform.matrix[2][2] = _cairo_fixed_from_double (1);    if (!CAIRO_SURFACE_RENDER_HAS_PICTURE_TRANSFORM (surface))    {	static const XTransform identity = { {	    { 1 << 16, 0x00000, 0x00000 },	    { 0x00000, 1 << 16, 0x00000 },	    { 0x00000, 0x00000, 1 << 16 },	} };	if (memcmp (&xtransform, &identity, sizeof (XTransform)) == 0)	    return CAIRO_STATUS_SUCCESS;	return CAIRO_INT_STATUS_UNSUPPORTED;    }

⌨️ 快捷键说明

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