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

📄 cairo-xlib-surface.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (mask)	_cairo_pattern_release_surface (mask_pattern, &mask->base, &mask_attr);    _cairo_pattern_release_surface (src_pattern, &src->base, &src_attr);    return status;}static cairo_int_status_t_cairo_xlib_surface_fill_rectangles (void		     *abstract_surface,				     cairo_operator_t	      op,				     const cairo_color_t     *color,				     cairo_rectangle_int16_t *rects,				     int			      num_rects){    cairo_xlib_surface_t *surface = abstract_surface;    XRenderColor render_color;    if (!CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLE (surface))	return CAIRO_INT_STATUS_UNSUPPORTED;    render_color.red   = color->red_short;    render_color.green = color->green_short;    render_color.blue  = color->blue_short;    render_color.alpha = color->alpha_short;    /* XXX: This XRectangle cast is evil... it needs to go away somehow. */    _cairo_xlib_surface_ensure_dst_picture (surface);    XRenderFillRectangles (surface->dpy,			   _render_operator (op),			   surface->dst_picture,			   &render_color, (XRectangle *) rects, num_rects);    return CAIRO_STATUS_SUCCESS;}/* Creates an A8 picture of size @width x @height, initialized with @color */static Picture_create_a8_picture (cairo_xlib_surface_t *surface,		    XRenderColor         *color,		    int                   width,		    int                   height,		    cairo_bool_t          repeat){    XRenderPictureAttributes pa;    unsigned long mask = 0;    Pixmap pixmap = XCreatePixmap (surface->dpy, surface->drawable,				   width <= 0 ? 1 : width,				   height <= 0 ? 1 : height,				   8);    Picture picture;    if (repeat) {	pa.repeat = TRUE;	mask = CPRepeat;    }    picture = XRenderCreatePicture (surface->dpy, pixmap,				    XRenderFindStandardFormat (surface->dpy, PictStandardA8),				    mask, &pa);    XRenderFillRectangle (surface->dpy, PictOpSrc, picture, color,			  0, 0, width, height);    XFreePixmap (surface->dpy, pixmap);    return picture;}/* Creates a temporary mask for the trapezoids covering the area * [@dst_x, @dst_y, @width, @height] of the destination surface. */static Picture_create_trapezoid_mask (cairo_xlib_surface_t *dst,			cairo_trapezoid_t    *traps,			int                   num_traps,			int                   dst_x,			int                   dst_y,			int                   width,			int                   height,			XRenderPictFormat     *pict_format){    XRenderColor transparent = { 0, 0, 0, 0 };    XRenderColor solid = { 0xffff, 0xffff, 0xffff, 0xffff };    Picture mask_picture, solid_picture;    XTrapezoid *offset_traps;    int i;    /* This would be considerably simpler using XRenderAddTraps(), but since     * we are only using this in the unbounded-operator case, we stick with     * XRenderCompositeTrapezoids, which is available on older versions     * of RENDER rather than conditionalizing. We should still hit an     * optimization that avoids creating another intermediate surface on     * the servers that have XRenderAddTraps().     */    mask_picture = _create_a8_picture (dst, &transparent, width, height, FALSE);    solid_picture = _create_a8_picture (dst, &solid, width, height, TRUE);    offset_traps = malloc (sizeof (XTrapezoid) * num_traps);    if (!offset_traps)	return None;    for (i = 0; i < num_traps; i++) {	offset_traps[i].top = traps[i].top - 0x10000 * dst_y;	offset_traps[i].bottom = traps[i].bottom - 0x10000 * dst_y;	offset_traps[i].left.p1.x = traps[i].left.p1.x - 0x10000 * dst_x;	offset_traps[i].left.p1.y = traps[i].left.p1.y - 0x10000 * dst_y;	offset_traps[i].left.p2.x = traps[i].left.p2.x - 0x10000 * dst_x;	offset_traps[i].left.p2.y = traps[i].left.p2.y - 0x10000 * dst_y;	offset_traps[i].right.p1.x = traps[i].right.p1.x - 0x10000 * dst_x;	offset_traps[i].right.p1.y = traps[i].right.p1.y - 0x10000 * dst_y;	offset_traps[i].right.p2.x = traps[i].right.p2.x - 0x10000 * dst_x;	offset_traps[i].right.p2.y = traps[i].right.p2.y - 0x10000 * dst_y;    }    XRenderCompositeTrapezoids (dst->dpy, PictOpAdd,				solid_picture, mask_picture,				pict_format,				0, 0,				offset_traps, num_traps);    XRenderFreePicture (dst->dpy, solid_picture);    free (offset_traps);    return mask_picture;}static cairo_int_status_t_cairo_xlib_surface_composite_trapezoids (cairo_operator_t	op,					  cairo_pattern_t	*pattern,					  void			*abstract_dst,					  cairo_antialias_t	antialias,					  int			src_x,					  int			src_y,					  int			dst_x,					  int			dst_y,					  unsigned int		width,					  unsigned int		height,					  cairo_trapezoid_t	*traps,					  int			num_traps){    cairo_surface_attributes_t	attributes;    cairo_xlib_surface_t	*dst = abstract_dst;    cairo_xlib_surface_t	*src;    cairo_int_status_t		status;    composite_operation_t       operation;    int				render_reference_x, render_reference_y;    int				render_src_x, render_src_y;    XRenderPictFormat		*pict_format;    if (!CAIRO_SURFACE_RENDER_HAS_TRAPEZOIDS (dst))	return CAIRO_INT_STATUS_UNSUPPORTED;    operation = _categorize_composite_operation (dst, op, pattern, TRUE);    if (operation == DO_UNSUPPORTED)	return CAIRO_INT_STATUS_UNSUPPORTED;    status = _cairo_pattern_acquire_surface (pattern, &dst->base,					     src_x, src_y, width, height,					     (cairo_surface_t **) &src,					     &attributes);    if (status)	return status;    operation = _recategorize_composite_operation (dst, op, src, &attributes, TRUE);    if (operation == DO_UNSUPPORTED) {	status = CAIRO_INT_STATUS_UNSUPPORTED;	goto BAIL;    }    switch (antialias) {    case CAIRO_ANTIALIAS_NONE:	pict_format = XRenderFindStandardFormat (dst->dpy, PictStandardA1);	break;    default:	pict_format = XRenderFindStandardFormat (dst->dpy, PictStandardA8);	break;    }    if (traps[0].left.p1.y < traps[0].left.p2.y) {	render_reference_x = _cairo_fixed_integer_floor (traps[0].left.p1.x);	render_reference_y = _cairo_fixed_integer_floor (traps[0].left.p1.y);    } else {	render_reference_x = _cairo_fixed_integer_floor (traps[0].left.p2.x);	render_reference_y = _cairo_fixed_integer_floor (traps[0].left.p2.y);    }    render_src_x = src_x + render_reference_x - dst_x;    render_src_y = src_y + render_reference_y - dst_y;    _cairo_xlib_surface_ensure_dst_picture (dst);    status = _cairo_xlib_surface_set_attributes (src, &attributes);    if (status)	goto BAIL;    if (!_cairo_operator_bounded_by_mask (op)) {	/* XRenderCompositeTrapezoids() creates a mask only large enough for the	 * trapezoids themselves, but if the operator is unbounded, then we need	 * to actually composite all the way out to the bounds, so we create	 * the mask and composite ourselves. There actually would	 * be benefit to doing this in all cases, since RENDER implementations	 * will frequently create a too temporary big mask, ignoring destination	 * bounds and clip. (XRenderAddTraps() could be used to make creating	 * the mask somewhat cheaper.)	 */	Picture mask_picture = _create_trapezoid_mask (dst, traps, num_traps,						       dst_x, dst_y, width, height,						       pict_format);	if (!mask_picture) {	    status = CAIRO_STATUS_NO_MEMORY;	    goto BAIL;	}	XRenderComposite (dst->dpy,			  _render_operator (op),			  src->src_picture,			  mask_picture,			  dst->dst_picture,			  src_x + attributes.x_offset,			  src_y + attributes.y_offset,			  0, 0,			  dst_x, dst_y,			  width, height);	XRenderFreePicture (dst->dpy, mask_picture);	status = _cairo_surface_composite_shape_fixup_unbounded (&dst->base,								 &attributes, src->width, src->height,								 width, height,								 src_x, src_y,								 0, 0,								 dst_x, dst_y, width, height);    } else {	/* XXX: The XTrapezoid cast is evil and needs to go away somehow. */	XRenderCompositeTrapezoids (dst->dpy,				    _render_operator (op),				    src->src_picture, dst->dst_picture,				    pict_format,				    render_src_x + attributes.x_offset,				    render_src_y + attributes.y_offset,				    (XTrapezoid *) traps, num_traps);    } BAIL:    _cairo_pattern_release_surface (pattern, &src->base, &attributes);    return status;}static cairo_int_status_t_cairo_xlib_surface_set_clip_region (void              *abstract_surface,				     pixman_region16_t *region){    cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;    if (surface->clip_rects) {	free (surface->clip_rects);	surface->clip_rects = NULL;    }    surface->have_clip_rects = FALSE;    surface->num_clip_rects = 0;    if (region == NULL) {	if (surface->gc)	    XSetClipMask (surface->dpy, surface->gc, None);	if (surface->xrender_format && surface->dst_picture) {	    XRenderPictureAttributes pa;	    pa.clip_mask = None;	    XRenderChangePicture (surface->dpy, surface->dst_picture,				  CPClipMask, &pa);	}    } else {	pixman_box16_t *boxes;	XRectangle *rects = NULL;	int n_boxes, i;	n_boxes = pixman_region_num_rects (region);	if (n_boxes > 0) {	    rects = malloc (sizeof(XRectangle) * n_boxes);	    if (rects == NULL)		return CAIRO_STATUS_NO_MEMORY;	} else {	    rects = NULL;	}	boxes = pixman_region_rects (region);	for (i = 0; i < n_boxes; 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;	}	surface->have_clip_rects = TRUE;	surface->clip_rects = rects;	surface->num_clip_rects = n_boxes;	if (surface->gc)	    _cairo_xlib_surface_set_gc_clip_rects (surface);	if (surface->dst_picture)	    _cairo_xlib_surface_set_picture_clip_rects (surface);    }    return CAIRO_STATUS_SUCCESS;}static cairo_int_status_t_cairo_xlib_surface_get_extents (void		         *abstract_surface,				 cairo_rectangle_int16_t *rectangle){    cairo_xlib_surface_t *surface = abstract_surface;    rectangle->x = 0;    rectangle->y = 0;    rectangle->width  = surface->width;    rectangle->height = surface->height;    return CAIRO_STATUS_SUCCESS;}static void_cairo_xlib_surface_get_font_options (void                  *abstract_surface,				      cairo_font_options_t  *options){    cairo_xlib_surface_t *surface = abstract_surface;    *options = surface->screen_info->font_options;}static cairo_status_t_cairo_xlib_surface_flush (void *abstract_surface){    cairo_xlib_surface_t *surface = abstract_surface;    XSync (surface->dpy, False);    return CAIRO_STATUS_SUCCESS;}static void_cairo_xlib_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font);static void_cairo_xlib_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph,				       cairo_scaled_font_t  *scaled_font);static const cairo_surface_backend_t cairo_xlib_surface_backend = {    CAIRO_SURFACE_TYPE_XLIB,    _cairo_xlib_surface_create_similar,    _cairo_xlib_surface_finish,    _cairo_xlib_surface_acquire_source_image,    _cairo_xlib_surface_release_source_image,    _cairo_xlib_surface_acquire_dest_image,    _cairo_xlib_surface_release_dest_image,    _cairo_xlib_surface_clone_similar,    _cairo_xlib_surface_composite,    _cairo_xlib_surface_fill_rectangles,    _cairo_xlib_surface_composite_trapezoids,    NULL, /* copy_page */    NULL, /* show_page */    _cairo_xlib_surface_set_clip_region,    NULL, /* intersect_clip_path */    _cairo_xlib_surface_get_extents,    NULL, /* old_show_glyphs */    _cairo_xlib_surface_get_font_options,    _cairo_xlib_surface_flush,    NULL, /* mark_dirty_rectangle */    _cairo_xlib_surface_scaled_font_fini,    _cairo_xlib_surface_scaled_glyph_fini,    NULL, /* paint */    NULL, /* mask */    NULL, /* stroke */    NULL, /* fill */    _cairo_xlib_surface_show_glyphs,    NULL  /* snapshot */};/** * _cairo_surface_is_xlib: * @surface: a #cairo_surface_t * * Checks if a surface is a #cairo_xlib_surface_t * * Return value: True if the surface is an xlib surface **/static cairo_bool_t_cairo_surface_is_xlib (cairo_surface_t *surface){    return surface->backend == &cairo_xlib_surface_backend;}static cairo_surface_t *_cairo_xlib_surface_create_internal (Display		       *dpy,				     Drawable		        drawable,				     Screen		       *screen,				     Visual		       *visual,				     XRenderPictFormat	       *xrender_format,				     int			width,				     int			height,				     int			depth){    cairo_xlib_surface_t *surface;    cairo_xlib_screen_info_t *screen_info;    screen_info = _cairo_xlib_screen_info_get (dpy, screen);    if (screen_info == NULL) {	_cairo_error (CAIRO_STATUS_NO_MEMORY);	return (cairo_surface_t*) &_cairo_surface_nil;    }    surface = malloc (sizeof (cairo_xlib_surface_t));    if (surface == NULL) {	_cairo_error (CAIRO_STATUS_NO_MEMORY);	return (cairo_surface_t*) &_cairo_surface_nil;    }    if (xrender_format) {	depth = xrender_format->depth;    } else if (visual) {	int j, k;	/* This is ugly, but we have to walk over all visuals	 * for the display to find the depth.	 */	for (j = 0; j < screen->ndepths; j++) {	    Depth *d = &screen->depths[j];	    for (k = 0; k < d->nvisuals; k++) {		if (&d->visuals[k] == visual) {		    depth = d->depth;		    goto found;		}	    }	}    found:	;    }    if (cairo_xlib_render_disabled ||	! XRenderQueryVersion (dpy, &surface->render_major, &surface->render_minor)) {	surface->render_major = -1;	surface->render_minor = -1;    }    if (CAIRO_SURFACE_RENDER_HAS_CREATE_PICTURE (surface)) {	if (!xrender_format) {	    if (visual)		xrender_format = XRenderFindVisualFormat (dpy, visual);	    else if (depth == 1)		xrender_format = XRenderFindStandardFormat (dpy, PictStandardA1);	}    } else {	xrender_format = NULL;    }    _cairo_surface_init (&surface->base, &cairo_xlib_surface_backend,			 _xrender_format_to_content (xrender_format));    surface->dpy = dpy;

⌨️ 快捷键说明

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