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

📄 cairo-glitz-surface.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 4 页
字号:
    WRITE_VEC2 (ptr, (p1)->x, (p1)->y)static cairo_status_t_cairo_glitz_surface_font_init (cairo_glitz_surface_t *surface,				cairo_scaled_font_t   *scaled_font,				cairo_format_t	      format){    cairo_glitz_surface_font_private_t *font_private;    glitz_drawable_t		       *drawable;    glitz_format_t		       *surface_format = NULL;    cairo_int_status_t		       status;    drawable = glitz_surface_get_drawable (surface->surface);    switch (format) {    case CAIRO_FORMAT_A8:	surface_format =	    glitz_find_standard_format (drawable, GLITZ_STANDARD_A8);	break;    case CAIRO_FORMAT_ARGB32:	surface_format =	    glitz_find_standard_format (drawable, GLITZ_STANDARD_ARGB32);    default:	break;    }    if (!surface_format)	return CAIRO_INT_STATUS_UNSUPPORTED;    font_private = malloc (sizeof (cairo_glitz_surface_font_private_t));    if (!font_private)	return CAIRO_STATUS_NO_MEMORY;    font_private->surface = glitz_surface_create (drawable, surface_format,						  GLYPH_CACHE_TEXTURE_SIZE,						  GLYPH_CACHE_TEXTURE_SIZE,						  0, NULL);    if (font_private->surface == NULL)    {	free (font_private);	return CAIRO_INT_STATUS_UNSUPPORTED;    }    if (format == CAIRO_FORMAT_ARGB32)	glitz_surface_set_component_alpha (font_private->surface, 1);    status = _cairo_glitz_root_area_init (&font_private->root,					  GLYPH_CACHE_MAX_LEVEL,					  GLYPH_CACHE_TEXTURE_SIZE,					  GLYPH_CACHE_TEXTURE_SIZE,					  &_cairo_glitz_area_funcs);    if (status != CAIRO_STATUS_SUCCESS)    {	glitz_surface_destroy (font_private->surface);	free (font_private);	return status;    }    scaled_font->surface_private = font_private;    scaled_font->surface_backend = _cairo_glitz_surface_get_backend ();    return CAIRO_STATUS_SUCCESS;}static void_cairo_glitz_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font){    cairo_glitz_surface_font_private_t *font_private;    font_private = scaled_font->surface_private;    if (font_private)    {	_cairo_glitz_root_area_fini (&font_private->root);	glitz_surface_destroy (font_private->surface);	free (font_private);    }}static void_cairo_glitz_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph,					cairo_scaled_font_t  *scaled_font){    cairo_glitz_surface_glyph_private_t *glyph_private;    glyph_private = scaled_glyph->surface_private;    if (glyph_private)    {	if (glyph_private->area)	    _cairo_glitz_area_move_out (glyph_private->area);	free (glyph_private);    }}#define FIXED_TO_FLOAT(f) (((glitz_float_t) (f)) / 65536)static cairo_status_t_cairo_glitz_surface_add_glyph (cairo_glitz_surface_t *surface,				cairo_scaled_font_t   *scaled_font,				cairo_scaled_glyph_t  *scaled_glyph){    cairo_image_surface_t		*glyph_surface = scaled_glyph->surface;    cairo_glitz_surface_font_private_t  *font_private;    cairo_glitz_surface_glyph_private_t *glyph_private;    glitz_point_fixed_t			p1, p2;    glitz_pixel_format_t		pf;    glitz_buffer_t			*buffer;    pixman_format_t			*format;    int					am, rm, gm, bm;    cairo_int_status_t			status;    glyph_private = scaled_glyph->surface_private;    if (glyph_private == NULL)    {	glyph_private = malloc (sizeof (cairo_glitz_surface_glyph_private_t));	if (!glyph_private)	    return CAIRO_STATUS_NO_MEMORY;	glyph_private->area   = NULL;	glyph_private->locked = FALSE;	scaled_glyph->surface_private = (void *) glyph_private;    }    if (glyph_surface->width  > GLYPH_CACHE_MAX_WIDTH ||	glyph_surface->height > GLYPH_CACHE_MAX_HEIGHT)	return CAIRO_STATUS_SUCCESS;    if (scaled_font->surface_private == NULL)    {	status = _cairo_glitz_surface_font_init (surface, scaled_font,						 glyph_surface->format);	if (status)	    return status;    }    font_private = scaled_font->surface_private;    if (glyph_surface->width == 0 || glyph_surface->height == 0)    {	glyph_private->area = &_empty_area;	return CAIRO_STATUS_SUCCESS;    }    format = pixman_image_get_format (glyph_surface->pixman_image);    if (!format)	return CAIRO_STATUS_NO_MEMORY;    if (_cairo_glitz_area_find (font_private->root.area,				glyph_surface->width,				glyph_surface->height,				FALSE, glyph_private))    {	if (_cairo_glitz_area_find (font_private->root.area,				    glyph_surface->width,				    glyph_surface->height,				    TRUE, glyph_private))	    return CAIRO_STATUS_SUCCESS;    }    buffer = glitz_buffer_create_for_data (glyph_surface->data);    if (!buffer)    {	_cairo_glitz_area_move_out (glyph_private->area);	return CAIRO_STATUS_NO_MEMORY;    }    pixman_format_get_masks (format, &pf.masks.bpp, &am, &rm, &gm, &bm);    pf.fourcc		= GLITZ_FOURCC_RGB;    pf.masks.alpha_mask = am;    pf.masks.red_mask   = rm;    pf.masks.green_mask = gm;    pf.masks.blue_mask  = bm;    pf.bytes_per_line = glyph_surface->stride;    pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP;    pf.xoffset	      = 0;    pf.skip_lines     = 0;    glitz_set_pixels (font_private->surface,		      glyph_private->area->x,		      glyph_private->area->y,		      glyph_surface->width,		      glyph_surface->height,		      &pf, buffer);    glitz_buffer_destroy (buffer);    p1.x = glyph_private->area->x << 16;    p1.y = glyph_private->area->y << 16;    p2.x = (glyph_private->area->x + glyph_surface->width)  << 16;    p2.y = (glyph_private->area->y + glyph_surface->height) << 16;    glitz_surface_translate_point (font_private->surface, &p1, &p1);    glitz_surface_translate_point (font_private->surface, &p2, &p2);    glyph_private->p1.x = FIXED_TO_FLOAT (p1.x);    glyph_private->p1.y = FIXED_TO_FLOAT (p1.y);    glyph_private->p2.x = FIXED_TO_FLOAT (p2.x);    glyph_private->p2.y = FIXED_TO_FLOAT (p2.y);    return CAIRO_STATUS_SUCCESS;}#define N_STACK_BUF 256static cairo_int_status_t_cairo_glitz_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,				      cairo_operator_t     op,				      cairo_pattern_t     *pattern,				      void		  *abstract_surface,				      int		   src_x,				      int		   src_y,				      int		   dst_x,				      int		   dst_y,				      unsigned int	   width,				      unsigned int	   height,				      const cairo_glyph_t *glyphs,				      int		   num_glyphs){    cairo_glitz_surface_attributes_t	attributes;    cairo_glitz_surface_glyph_private_t *glyph_private;    cairo_glitz_surface_t		*dst = abstract_surface;    cairo_glitz_surface_t		*src;    cairo_scaled_glyph_t		*stack_scaled_glyphs[N_STACK_BUF];    cairo_scaled_glyph_t		**scaled_glyphs;    glitz_float_t			stack_vertices[N_STACK_BUF * 16];    glitz_float_t			*vertices;    glitz_buffer_t			*buffer;    cairo_int_status_t			status;    int					x_offset, y_offset;    int					i, cached_glyphs = 0;    int					remaining_glyps = num_glyphs;    glitz_float_t			x1, y1, x2, y2;    static glitz_vertex_format_t	format = {	GLITZ_PRIMITIVE_QUADS,	GLITZ_DATA_TYPE_FLOAT,	sizeof (glitz_float_t) * 4,	GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK,	{ 0 },	{	    GLITZ_DATA_TYPE_FLOAT,	    GLITZ_COORDINATE_SIZE_XY,	    sizeof (glitz_float_t) * 2,	}    };    if (scaled_font->surface_backend != NULL &&	scaled_font->surface_backend != _cairo_glitz_surface_get_backend ())	return CAIRO_INT_STATUS_UNSUPPORTED;    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_surface (pattern, dst,						   src_x, src_y,						   width, height,						   &src, &attributes);    if (status)	return status;    _cairo_glitz_surface_set_attributes (src, &attributes);    if (num_glyphs > N_STACK_BUF)    {	char *data;	data = malloc (num_glyphs * sizeof (void *) +		       num_glyphs * sizeof (glitz_float_t) * 16);	if (!data)	    goto FAIL1;	scaled_glyphs = (cairo_scaled_glyph_t **) data;	vertices = (glitz_float_t *) (data + num_glyphs * sizeof (void *));    }    else    {	scaled_glyphs = stack_scaled_glyphs;	vertices = stack_vertices;    }    buffer = glitz_buffer_create_for_data (vertices);    if (!buffer)	goto FAIL2;    for (i = 0; i < num_glyphs; i++)    {	status = _cairo_scaled_glyph_lookup (scaled_font,					     glyphs[i].index,					     CAIRO_SCALED_GLYPH_INFO_SURFACE,					     &scaled_glyphs[i]);	if (status != CAIRO_STATUS_SUCCESS)	{	    num_glyphs = i;	    goto UNLOCK;	}	glyph_private = scaled_glyphs[i]->surface_private;	if (glyph_private && glyph_private->area)	{	    remaining_glyps--;	    if (glyph_private->area->width)	    {		x_offset = scaled_glyphs[i]->surface->base.device_transform.x0;		y_offset = scaled_glyphs[i]->surface->base.device_transform.y0;		x1 = floor (glyphs[i].x + 0.5) + x_offset;		y1 = floor (glyphs[i].y + 0.5) + y_offset;		x2 = x1 + glyph_private->area->width;		y2 = y1 + glyph_private->area->height;		WRITE_BOX (vertices, x1, y1, x2, y2,			   &glyph_private->p1, &glyph_private->p2);		glyph_private->locked = TRUE;		cached_glyphs++;	    }	}    }    if (remaining_glyps)    {	cairo_surface_t	      *image;	cairo_glitz_surface_t *clone;	for (i = 0; i < num_glyphs; i++)	{	    glyph_private = scaled_glyphs[i]->surface_private;	    if (!glyph_private || !glyph_private->area)	    {		status = _cairo_glitz_surface_add_glyph (dst,							 scaled_font,							 scaled_glyphs[i]);		if (status)		    goto UNLOCK;		glyph_private = scaled_glyphs[i]->surface_private;	    }	    x_offset = scaled_glyphs[i]->surface->base.device_transform.x0;	    y_offset = scaled_glyphs[i]->surface->base.device_transform.y0;	    x1 = floor (glyphs[i].x + 0.5) + x_offset;	    y1 = floor (glyphs[i].y + 0.5) + y_offset;	    if (glyph_private->area)	    {		if (glyph_private->area->width)		{		    x2 = x1 + glyph_private->area->width;		    y2 = y1 + glyph_private->area->height;		    WRITE_BOX (vertices, x1, y1, x2, y2,			       &glyph_private->p1, &glyph_private->p2);		    glyph_private->locked = TRUE;		    cached_glyphs++;		}	    }	    else	    {		image = &scaled_glyphs[i]->surface->base;		status =		    _cairo_glitz_surface_clone_similar (abstract_surface,							image,							(cairo_surface_t **)							&clone);		if (status)		    goto UNLOCK;		glitz_composite (_glitz_operator (op),				 src->surface,				 clone->surface,				 dst->surface,				 src_x + attributes.base.x_offset + x1,				 src_y + attributes.base.y_offset + y1,				 0, 0,				 x1, y1,				 scaled_glyphs[i]->surface->width,				 scaled_glyphs[i]->surface->height);		cairo_surface_destroy (&clone->base);		if (glitz_surface_get_status (dst->surface) ==		    GLITZ_STATUS_NOT_SUPPORTED)		{		    status = CAIRO_INT_STATUS_UNSUPPORTED;		    goto UNLOCK;		}	    }	}    }    if (cached_glyphs)    {	cairo_glitz_surface_font_private_t *font_private;	glitz_set_geometry (dst->surface,			    GLITZ_GEOMETRY_TYPE_VERTEX,			    (glitz_geometry_format_t *) &format,			    buffer);	glitz_set_array (dst->surface, 0, 4, cached_glyphs * 4, 0, 0);	font_private = scaled_font->surface_private;	glitz_composite (_glitz_operator (op),			 src->surface,			 font_private->surface,			 dst->surface,			 src_x + attributes.base.x_offset,			 src_y + attributes.base.y_offset,			 0, 0,			 dst_x, dst_y,			 width, height);	glitz_set_geometry (dst->surface,			    GLITZ_GEOMETRY_TYPE_NONE,			    NULL, NULL);    }UNLOCK:    if (cached_glyphs)    {	for (i = 0; i < num_glyphs; i++)	{	    glyph_private = scaled_glyphs[i]->surface_private;	    if (glyph_private)		glyph_private->locked = FALSE;	}    }    glitz_buffer_destroy (buffer); FAIL2:    if (num_glyphs > N_STACK_BUF)	free (scaled_glyphs); FAIL1:    if (attributes.n_params)	free (attributes.params);    _cairo_glitz_pattern_release_surface (pattern, src, &attributes);    if (status)	return status;    if (glitz_surface_get_status (dst->surface) == GLITZ_STATUS_NOT_SUPPORTED)	return CAIRO_INT_STATUS_UNSUPPORTED;    return CAIRO_STATUS_SUCCESS;}static cairo_status_t_cairo_glitz_surface_flush (void *abstract_surface){    cairo_glitz_surface_t *surface = abstract_surface;    glitz_surface_flush (surface->surface);    return CAIRO_STATUS_SUCCESS;}static const cairo_surface_backend_t cairo_glitz_surface_backend = {    CAIRO_SURFACE_TYPE_GLITZ,    _cairo_glitz_surface_create_similar,    _cairo_glitz_surface_finish,    _cairo_glitz_surface_acquire_source_image,    _cairo_glitz_surface_release_source_image,    _cairo_glitz_surface_acquire_dest_image,    _cairo_glitz_surface_release_dest_image,    _cairo_glitz_surface_clone_similar,    _cairo_glitz_surface_composite,    _cairo_glitz_surface_fill_rectangles,    _cairo_glitz_surface_composite_trapezoids,    NULL, /* copy_page */    NULL, /* show_page */    _cairo_glitz_surface_set_clip_region,    NULL, /* intersect_clip_path */    _cairo_glitz_surface_get_extents,    _cairo_glitz_surface_old_show_glyphs,    NULL, /* get_font_options */    _cairo_glitz_surface_flush,    NULL, /* mark_dirty_rectangle */    _cairo_glitz_surface_scaled_font_fini,    _cairo_glitz_surface_scaled_glyph_fini};static const cairo_surface_backend_t *_cairo_glitz_surface_get_backend (void){    return &cairo_glitz_surface_backend;}static cairo_content_t_glitz_format_to_content (glitz_format_t * format){    assert (format->color.fourcc == GLITZ_FOURCC_RGB);    if (format->color.alpha_size != 0) {	if (format->color.red_size != 0 &&	    format->color.green_size != 0 &&	    format->color.blue_size  != 0)	    return CAIRO_CONTENT_COLOR_ALPHA;	else	    return CAIRO_CONTENT_ALPHA;    }    return CAIRO_CONTENT_COLOR;}cairo_surface_t *cairo_glitz_surface_create (glitz_surface_t *surface){    cairo_glitz_surface_t *crsurface;    glitz_format_t *format;    if (surface == NULL)	return (cairo_surface_t*) &_cairo_surface_nil;    crsurface = malloc (sizeof (cairo_glitz_surface_t));    if (crsurface == NULL) {	_cairo_error (CAIRO_STATUS_NO_MEMORY);	return (cairo_surface_t*) &_cairo_surface_nil;    }    format = glitz_surface_get_format (surface);    _cairo_surface_init (&crsurface->base, &cairo_glitz_surface_backend,			 _glitz_format_to_content(format));    glitz_surface_reference (surface);    crsurface->surface = surface;    crsurface->format  = format;    crsurface->clip    = NULL;    return (cairo_surface_t *) crsurface;}

⌨️ 快捷键说明

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