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

📄 cairo-glitz-surface.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 4 页
字号:
    attr->acquired = FALSE;    switch (pattern->type) {    case CAIRO_PATTERN_TYPE_LINEAR:    case CAIRO_PATTERN_TYPE_RADIAL: {	cairo_gradient_pattern_t    *gradient =	    (cairo_gradient_pattern_t *) pattern;	char			    *data;	glitz_fixed16_16_t	    *params;	int			    n_params;	unsigned int		    *pixels;	int			    i, n_base_params;	glitz_buffer_t		    *buffer;	static glitz_pixel_format_t format = {	    GLITZ_FOURCC_RGB,	    {		32,		0xff000000,		0x00ff0000,		0x0000ff00,		0x000000ff	    },	    0, 0, 0,	    GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP	};	/* XXX: the current color gradient acceleration provided by glitz is	 * experimental, it's been proven inappropriate in a number of ways,	 * most importantly, it's currently implemented as filters and	 * gradients are not filters. eventually, it will be replaced with	 * something more appropriate.	 */	if (gradient->n_stops < 2)	    break;	if (!CAIRO_GLITZ_FEATURE_OK (dst->surface, FRAGMENT_PROGRAM))	    break;	if (pattern->type == CAIRO_PATTERN_TYPE_RADIAL)	    n_base_params = 6;	else	    n_base_params = 4;	n_params = gradient->n_stops * 3 + n_base_params;	data = malloc (sizeof (glitz_fixed16_16_t) * n_params +		       sizeof (unsigned int) * gradient->n_stops);	if (!data)	    return CAIRO_STATUS_NO_MEMORY;	params = (glitz_fixed16_16_t *) data;	pixels = (unsigned int *)	    (data + sizeof (glitz_fixed16_16_t) * n_params);	buffer = glitz_buffer_create_for_data (pixels);	if (!buffer)	{	    free (data);	    return CAIRO_STATUS_NO_MEMORY;	}	src = (cairo_glitz_surface_t *)	    _cairo_surface_create_similar_scratch (&dst->base,						   CAIRO_CONTENT_COLOR_ALPHA,						   gradient->n_stops, 1);	if (src->base.status)	{	    glitz_buffer_destroy (buffer);	    free (data);	    return CAIRO_STATUS_NO_MEMORY;	}	for (i = 0; i < gradient->n_stops; i++)	{	    pixels[i] =		(((int) (gradient->stops[i].color.alpha >> 8)) << 24) |		(((int) (gradient->stops[i].color.red   >> 8)) << 16) |		(((int) (gradient->stops[i].color.green >> 8)) << 8)  |		(((int) (gradient->stops[i].color.blue  >> 8)));	    params[n_base_params + 3 * i + 0] = gradient->stops[i].x;	    params[n_base_params + 3 * i + 1] = i << 16;	    params[n_base_params + 3 * i + 2] = 0;	}	glitz_set_pixels (src->surface, 0, 0, gradient->n_stops, 1,			  &format, buffer);	glitz_buffer_destroy (buffer);	if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR)	{	    cairo_linear_pattern_t *grad = (cairo_linear_pattern_t *) pattern;	    params[0] = grad->gradient.p1.x;	    params[1] = grad->gradient.p1.y;	    params[2] = grad->gradient.p2.x;	    params[3] = grad->gradient.p2.y;	    attr->filter = GLITZ_FILTER_LINEAR_GRADIENT;	}	else	{	    cairo_radial_pattern_t *grad = (cairo_radial_pattern_t *) pattern;	    params[0] = grad->gradient.inner.x;	    params[1] = grad->gradient.inner.y;	    params[2] = grad->gradient.inner.radius;	    params[3] = grad->gradient.outer.x;	    params[4] = grad->gradient.outer.y;	    params[5] = grad->gradient.outer.radius;	    attr->filter = GLITZ_FILTER_RADIAL_GRADIENT;	}	switch (pattern->extend) {	case CAIRO_EXTEND_NONE:	    attr->fill = GLITZ_FILL_TRANSPARENT;	    break;	case CAIRO_EXTEND_REPEAT:	    attr->fill = GLITZ_FILL_REPEAT;	    break;	case CAIRO_EXTEND_REFLECT:	    attr->fill = GLITZ_FILL_REFLECT;	    break;	case CAIRO_EXTEND_PAD:	    attr->fill = GLITZ_FILL_NEAREST;	    break;	}	attr->params	    = params;	attr->n_params	    = n_params;	attr->base.matrix   = pattern->matrix;	attr->base.x_offset = 0;	attr->base.y_offset = 0;    } break;    default:	break;    }    if (!src)    {	cairo_int_status_t status;	status = _cairo_pattern_acquire_surface (pattern, &dst->base,						 x, y, width, height,						 (cairo_surface_t **) &src,						 &attr->base);	if (status)	    return status;	if (src)	{	    switch (attr->base.extend) {	    case CAIRO_EXTEND_NONE:		attr->fill = GLITZ_FILL_TRANSPARENT;		break;	    case CAIRO_EXTEND_REPEAT:		attr->fill = GLITZ_FILL_REPEAT;		break;	    case CAIRO_EXTEND_REFLECT:		attr->fill = GLITZ_FILL_REFLECT;		break;	    case CAIRO_EXTEND_PAD:	    default:               attr->fill = GLITZ_FILL_NEAREST;               break;	    }	    switch (attr->base.filter) {	    case CAIRO_FILTER_FAST:	    case CAIRO_FILTER_NEAREST:		attr->filter = GLITZ_FILTER_NEAREST;		break;	    case CAIRO_FILTER_GOOD:	    case CAIRO_FILTER_BEST:	    case CAIRO_FILTER_BILINEAR:	    default:		attr->filter = GLITZ_FILTER_BILINEAR;		break;	    }	    attr->params   = NULL;	    attr->n_params = 0;	    attr->acquired = TRUE;	}    }    *surface_out = src;    return CAIRO_STATUS_SUCCESS;}static void_cairo_glitz_pattern_release_surface (cairo_pattern_t		      *pattern,				      cairo_glitz_surface_t	      *surface,				      cairo_glitz_surface_attributes_t *attr){    if (attr->acquired)	_cairo_pattern_release_surface (pattern, &surface->base, &attr->base);    else	cairo_surface_destroy (&surface->base);}static cairo_int_status_t_cairo_glitz_pattern_acquire_surfaces (cairo_pattern_t	                *src,				       cairo_pattern_t	                *mask,				       cairo_glitz_surface_t	        *dst,				       int			        src_x,				       int			        src_y,				       int			        mask_x,				       int			        mask_y,				       unsigned int		        width,				       unsigned int		        height,				       cairo_glitz_surface_t	    **src_out,				       cairo_glitz_surface_t	    **mask_out,				       cairo_glitz_surface_attributes_t *sattr,				       cairo_glitz_surface_attributes_t *mattr){    cairo_int_status_t	  status;    cairo_pattern_union_t tmp;    /* If src and mask are both solid, then the mask alpha can be     * combined into src and mask can be ignored. */    /* XXX: This optimization assumes that there is no color     * information in mask, so this will need to change when we     * support RENDER-style 4-channel masks. */    if (src->type == CAIRO_PATTERN_TYPE_SOLID &&	mask->type == CAIRO_PATTERN_TYPE_SOLID)    {	cairo_color_t combined;	cairo_solid_pattern_t *src_solid = (cairo_solid_pattern_t *) src;	cairo_solid_pattern_t *mask_solid = (cairo_solid_pattern_t *) mask;	combined = src_solid->color;	_cairo_color_multiply_alpha (&combined, mask_solid->color.alpha);	_cairo_pattern_init_solid (&tmp.solid, &combined);	mask = NULL;    } else {	_cairo_pattern_init_copy (&tmp.base, src);    }    status = _cairo_glitz_pattern_acquire_surface (&tmp.base, dst,						   src_x, src_y,						   width, height,						   src_out, sattr);    _cairo_pattern_fini (&tmp.base);    if (status)	return status;    if (mask)    {	_cairo_pattern_init_copy (&tmp.base, mask);	status = _cairo_glitz_pattern_acquire_surface (&tmp.base, dst,						       mask_x, mask_y,						       width, height,						       mask_out, mattr);	if (status)	    _cairo_glitz_pattern_release_surface (&tmp.base, *src_out, sattr);	_cairo_pattern_fini (&tmp.base);	return status;    }    else    {	*mask_out = NULL;    }    return CAIRO_STATUS_SUCCESS;}static void_cairo_glitz_surface_set_attributes (cairo_glitz_surface_t	      *surface,				     cairo_glitz_surface_attributes_t *a){    _cairo_glitz_surface_set_matrix (surface, &a->base.matrix);    glitz_surface_set_fill (surface->surface, a->fill);    glitz_surface_set_filter (surface->surface, a->filter,			      a->params, a->n_params);}static cairo_int_status_t_cairo_glitz_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_glitz_surface_attributes_t	src_attr, mask_attr;    cairo_glitz_surface_t		*dst = abstract_dst;    cairo_glitz_surface_t		*src;    cairo_glitz_surface_t		*mask;    cairo_int_status_t			status;    if (op == CAIRO_OPERATOR_SATURATE)	return CAIRO_INT_STATUS_UNSUPPORTED;    if (_glitz_ensure_target (dst->surface))	return CAIRO_INT_STATUS_UNSUPPORTED;    status = _cairo_glitz_pattern_acquire_surfaces (src_pattern, mask_pattern,						    dst,						    src_x, src_y,						    mask_x, mask_y,						    width, height,						    &src, &mask,						    &src_attr, &mask_attr);    if (status)	return status;    _cairo_glitz_surface_set_attributes (src, &src_attr);    if (mask)    {	_cairo_glitz_surface_set_attributes (mask, &mask_attr);	glitz_composite (_glitz_operator (op),			 src->surface,			 mask->surface,			 dst->surface,			 src_x + src_attr.base.x_offset,			 src_y + src_attr.base.y_offset,			 mask_x + mask_attr.base.x_offset,			 mask_y + mask_attr.base.y_offset,			 dst_x, dst_y,			 width, height);	if (mask_attr.n_params)	    free (mask_attr.params);	_cairo_glitz_pattern_release_surface (mask_pattern, mask, &mask_attr);    }    else    {	glitz_composite (_glitz_operator (op),			 src->surface,			 NULL,			 dst->surface,			 src_x + src_attr.base.x_offset,			 src_y + src_attr.base.y_offset,			 0, 0,			 dst_x, dst_y,			 width, height);    }    if (src_attr.n_params)	free (src_attr.params);    _cairo_glitz_pattern_release_surface (src_pattern, src, &src_attr);    if (glitz_surface_get_status (dst->surface) == GLITZ_STATUS_NOT_SUPPORTED)	return CAIRO_INT_STATUS_UNSUPPORTED;    return CAIRO_STATUS_SUCCESS;}static cairo_int_status_t_cairo_glitz_surface_fill_rectangles (void		      *abstract_dst,				      cairo_operator_t	       op,				      const cairo_color_t     *color,				      cairo_rectangle_int16_t *rects,				      int		       n_rects){    cairo_glitz_surface_t *dst = abstract_dst;    if (op == CAIRO_OPERATOR_SOURCE)    {	glitz_color_t glitz_color;	glitz_color.red = color->red_short;	glitz_color.green = color->green_short;	glitz_color.blue = color->blue_short;	glitz_color.alpha = color->alpha_short;	glitz_set_rectangles (dst->surface, &glitz_color,			      (glitz_rectangle_t *) rects, n_rects);    }    else    {	cairo_glitz_surface_t *src;	if (op == CAIRO_OPERATOR_SATURATE)	    return CAIRO_INT_STATUS_UNSUPPORTED;	if (_glitz_ensure_target (dst->surface))	    return CAIRO_INT_STATUS_UNSUPPORTED;	src = (cairo_glitz_surface_t *)	    _cairo_surface_create_similar_solid (&dst->base,						 CAIRO_CONTENT_COLOR_ALPHA,						 1, 1,						 (cairo_color_t *) color);	if (src->base.status)	    return CAIRO_STATUS_NO_MEMORY;	glitz_surface_set_fill (src->surface, GLITZ_FILL_REPEAT);	while (n_rects--)	{	    glitz_composite (_glitz_operator (op),			     src->surface,			     NULL,			     dst->surface,			     0, 0,			     0, 0,			     rects->x, rects->y,			     rects->width, rects->height);	    rects++;	}	cairo_surface_destroy (&src->base);    }    if (glitz_surface_get_status (dst->surface) == GLITZ_STATUS_NOT_SUPPORTED)	return CAIRO_INT_STATUS_UNSUPPORTED;    return CAIRO_STATUS_SUCCESS;}static cairo_int_status_t_cairo_glitz_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		     n_traps){    cairo_pattern_union_t	     tmp_src_pattern;    cairo_pattern_t		     *src_pattern;    cairo_glitz_surface_attributes_t attributes;    cairo_glitz_surface_t	     *dst = abstract_dst;    cairo_glitz_surface_t	     *src;    cairo_glitz_surface_t	     *mask = NULL;    glitz_buffer_t		     *buffer = NULL;    void			     *data = NULL;    cairo_int_status_t		     status;    unsigned short		     alpha;    if (antialias != CAIRO_ANTIALIAS_DEFAULT &&	antialias != CAIRO_ANTIALIAS_GRAY)	return CAIRO_INT_STATUS_UNSUPPORTED;    if (dst->base.status)	return dst->base.status;    if (op == CAIRO_OPERATOR_SATURATE)	return CAIRO_INT_STATUS_UNSUPPORTED;    if (_glitz_ensure_target (dst->surface))	return CAIRO_INT_STATUS_UNSUPPORTED;    if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE)    {	_cairo_pattern_init_copy (&tmp_src_pattern.base, pattern);	status = _cairo_glitz_pattern_acquire_surface (&tmp_src_pattern.base,						       dst,						       src_x, src_y,						       width, height,						       &src, &attributes);	src_pattern = &tmp_src_pattern.base;    }    else    {	status = _cairo_glitz_pattern_acquire_surface (pattern, dst,						       src_x, src_y,						       width, height,						       &src, &attributes);	src_pattern = pattern;    }    alpha = 0xffff;    if (status)	return status;    if (op == CAIRO_OPERATOR_ADD || n_traps <= 1)    {	static glitz_color_t	clear_black = { 0, 0, 0, 0 };	glitz_color_t		color;	glitz_geometry_format_t	format;	int			n_trap_added;	int			offset = 0;	int			data_size = 0;	int			size = 30 * n_traps; /* just a guess */	format.vertex.primitive = GLITZ_PRIMITIVE_QUADS;	format.vertex.type = GLITZ_DATA_TYPE_FLOAT;	format.vertex.bytes_per_vertex = 3 * sizeof (glitz_float_t);	format.vertex.attributes = GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK;	format.vertex.mask.type = GLITZ_DATA_TYPE_FLOAT;	format.vertex.mask.size = GLITZ_COORDINATE_SIZE_X;	format.vertex.mask.offset = 2 * sizeof (glitz_float_t);	mask = (cairo_glitz_surface_t *)	    _cairo_glitz_surface_create_similar (&dst->base,						 CAIRO_CONTENT_ALPHA,						 2, 1);	if (mask->base.status)	{	    _cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);	    if (src_pattern == &tmp_src_pattern.base)		_cairo_pattern_fini (&tmp_src_pattern.base);	    return CAIRO_STATUS_NO_MEMORY;	}	color.red = color.green = color.blue = color.alpha = 0xffff;	glitz_set_rectangle (mask->surface, &clear_black, 0, 0, 1, 1);	glitz_set_rectangle (mask->surface, &color, 1, 0, 1, 1);	glitz_surface_set_fill (mask->surface, GLITZ_FILL_NEAREST);	glitz_surface_set_filter (mask->surface,				  GLITZ_FILTER_BILINEAR,				  NULL, 0);	size *= format.vertex.bytes_per_vertex;	while (n_traps)	{	    if (data_size < size)	    {		data_size = size;		data = realloc (data, data_size);		if (!data)		{		    _cairo_glitz_pattern_release_surface (src_pattern, src,							  &attributes);		    if (src_pattern == &tmp_src_pattern.base)			_cairo_pattern_fini (&tmp_src_pattern.base);

⌨️ 快捷键说明

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