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

📄 cairo-glitz-surface.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 4 页
字号:
		    return CAIRO_STATUS_NO_MEMORY;		}		if (buffer)		    glitz_buffer_destroy (buffer);		buffer = glitz_buffer_create_for_data (data);		if (!buffer) {		    free (data);		    _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;		}	    }	    offset +=		glitz_add_trapezoids (buffer,				      offset, size - offset,				      format.vertex.type, mask->surface,				      (glitz_trapezoid_t *) traps, n_traps,				      &n_trap_added);	    n_traps -= n_trap_added;	    traps   += n_trap_added;	    size    *= 2;	}	glitz_set_geometry (dst->surface,			    GLITZ_GEOMETRY_TYPE_VERTEX,			    &format, buffer);	glitz_set_array (dst->surface, 0, 3,			 offset / format.vertex.bytes_per_vertex,			 0, 0);    }    else    {	cairo_image_surface_t *image;	unsigned char	      *ptr;	int		      stride;	stride = (width + 3) & -4;	data = calloc (stride * height, 1);	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);	    return CAIRO_STATUS_NO_MEMORY;	}	/* using negative stride */	ptr = (unsigned char *) data + stride * (height - 1);	image = (cairo_image_surface_t *)	    cairo_image_surface_create_for_data (ptr,						 CAIRO_FORMAT_A8,						 width, height,						 -stride);	if (image->base.status)	{	    cairo_surface_destroy (&src->base);	    free (data);	    return CAIRO_STATUS_NO_MEMORY;	}	pixman_add_trapezoids (image->pixman_image, -dst_x, -dst_y,			       (pixman_trapezoid_t *) traps, n_traps);	mask = (cairo_glitz_surface_t *)	    _cairo_surface_create_similar_scratch (&dst->base,						   CAIRO_CONTENT_ALPHA,						   width, height);	if (mask->base.status)	{	    _cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);	    free (data);	    cairo_surface_destroy (&image->base);	    return CAIRO_STATUS_NO_MEMORY;	}	_cairo_glitz_surface_set_image (mask, image, 0, 0);    }    _cairo_glitz_surface_set_attributes (src, &attributes);    glitz_composite (_glitz_operator (op),		     src->surface,		     mask->surface,		     dst->surface,		     src_x + attributes.base.x_offset,		     src_y + attributes.base.y_offset,		     0, 0,		     dst_x, dst_y,		     width, height);    if (attributes.n_params)	free (attributes.params);    glitz_set_geometry (dst->surface,			GLITZ_GEOMETRY_TYPE_NONE,			NULL, NULL);    if (buffer)	glitz_buffer_destroy (buffer);    free (data);    _cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);    if (src_pattern == &tmp_src_pattern.base)	_cairo_pattern_fini (&tmp_src_pattern.base);    if (mask)	cairo_surface_destroy (&mask->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_set_clip_region (void		*abstract_surface,				      pixman_region16_t *region){    cairo_glitz_surface_t *surface = abstract_surface;    if (region)    {	glitz_box_t *box;	int	    n;	if (!surface->clip)	{	    surface->clip = pixman_region_create ();	    if (!surface->clip)		return CAIRO_STATUS_NO_MEMORY;	}	pixman_region_copy (surface->clip, region);	box = (glitz_box_t *) pixman_region_rects (surface->clip);	n = pixman_region_num_rects (surface->clip);	glitz_surface_set_clip_region (surface->surface, 0, 0, box, n);    }    else    {	glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0);	if (surface->clip)	    pixman_region_destroy (surface->clip);	surface->clip = NULL;    }    return CAIRO_STATUS_SUCCESS;}static cairo_int_status_t_cairo_glitz_surface_get_extents (void		          *abstract_surface,				  cairo_rectangle_int16_t *rectangle){    cairo_glitz_surface_t *surface = abstract_surface;    rectangle->x = 0;    rectangle->y = 0;    rectangle->width = glitz_surface_get_width  (surface->surface);    rectangle->height = glitz_surface_get_height (surface->surface);    return CAIRO_STATUS_SUCCESS;}#define CAIRO_GLITZ_AREA_AVAILABLE 0#define CAIRO_GLITZ_AREA_DIVIDED   1#define CAIRO_GLITZ_AREA_OCCUPIED  2typedef struct _cairo_glitz_root_area cairo_glitz_root_area_t;typedef struct _cairo_glitz_area {    int			     state;    int			     level;    int			     x, y;    int			     width, height;    struct _cairo_glitz_area *area[4];    cairo_glitz_root_area_t  *root;    void		     *closure;} cairo_glitz_area_t;static cairo_glitz_area_t _empty_area = {    0, 0, 0, 0, 0, 0,    { NULL, NULL, NULL, NULL },    NULL,    NULL};typedef struct _cairo_glitz_area_funcs {    cairo_status_t (*move_in)	    (cairo_glitz_area_t *area,				     void		*closure);    void	   (*move_out)	    (cairo_glitz_area_t *area,				     void		*closure);    int		   (*compare_score) (cairo_glitz_area_t *area,				     void		*closure1,				     void		*closure2);} cairo_glitz_area_funcs_t;struct _cairo_glitz_root_area {    int				   max_level;    int				   width, height;    cairo_glitz_area_t		   *area;    const cairo_glitz_area_funcs_t *funcs;};static cairo_status_t_cairo_glitz_area_move_in (cairo_glitz_area_t *area,			   void		      *closure){    area->closure = closure;    area->state   = CAIRO_GLITZ_AREA_OCCUPIED;    return (*area->root->funcs->move_in) (area, area->closure);}static void_cairo_glitz_area_move_out (cairo_glitz_area_t *area){    if (area->root)    {	(*area->root->funcs->move_out) (area, area->closure);	area->closure = NULL;	area->state   = CAIRO_GLITZ_AREA_AVAILABLE;    }}static cairo_glitz_area_t *_cairo_glitz_area_create (cairo_glitz_root_area_t *root,			  int			  level,			  int			  x,			  int			  y,			  int			  width,			  int			  height){    cairo_glitz_area_t *area;    int		       n = 4;    area = malloc (sizeof (cairo_glitz_area_t));    if (!area)	return NULL;    area->level   = level;    area->x	  = x;    area->y	  = y;    area->width   = width;    area->height  = height;    area->root    = root;    area->closure = NULL;    area->state   = CAIRO_GLITZ_AREA_AVAILABLE;    while (n--)	area->area[n] = NULL;    return area;}static void_cairo_glitz_area_destroy (cairo_glitz_area_t *area){    if (area == NULL)	return;    if (area->state == CAIRO_GLITZ_AREA_OCCUPIED)    {	_cairo_glitz_area_move_out (area);    }    else    {	int n = 4;	while (n--)	    _cairo_glitz_area_destroy (area->area[n]);    }    free (area);}static cairo_glitz_area_t *_cairo_glitz_area_get_top_scored_sub_area (cairo_glitz_area_t *area){    if (!area)	return NULL;    switch (area->state) {    case CAIRO_GLITZ_AREA_OCCUPIED:	return area;    case CAIRO_GLITZ_AREA_AVAILABLE:	break;    case CAIRO_GLITZ_AREA_DIVIDED: {	cairo_glitz_area_t *tmp, *top = NULL;	int		   i;	for (i = 0; i < 4; i++)	{	    tmp = _cairo_glitz_area_get_top_scored_sub_area (area->area[i]);	    if (tmp && top)	    {		if ((*area->root->funcs->compare_score) (tmp,							 tmp->closure,							 top->closure) > 0)		    top = tmp;	    }	    else if (tmp)	    {		top = tmp;	    }	}	return top;    }    }    return NULL;}static cairo_int_status_t_cairo_glitz_area_find (cairo_glitz_area_t *area,			int		   width,			int		   height,			cairo_bool_t	   kick_out,			void		   *closure){    cairo_status_t status;    if (area->width < width || area->height < height)	return CAIRO_INT_STATUS_UNSUPPORTED;    switch (area->state) {    case CAIRO_GLITZ_AREA_OCCUPIED:	if (kick_out)	{	    if ((*area->root->funcs->compare_score) (area,						     area->closure,						     closure) >= 0)		return CAIRO_INT_STATUS_UNSUPPORTED;	    _cairo_glitz_area_move_out (area);	} else {	    return CAIRO_INT_STATUS_UNSUPPORTED;	}    /* fall-through */    case CAIRO_GLITZ_AREA_AVAILABLE: {	if (area->level == area->root->max_level ||	    (area->width == width && area->height == height))	{	    return _cairo_glitz_area_move_in (area, closure);	}	else	{	    int dx[4], dy[4], w[4], h[4], i;	    dx[0] = dx[2] = dy[0] = dy[1] = 0;	    w[0] = w[2] = dx[1] = dx[3] = width;	    h[0] = h[1] = dy[2] = dy[3] = height;	    w[1] = w[3] = area->width - width;	    h[2] = h[3] = area->height - height;	    for (i = 0; i < 2; i++)	    {		if (w[i])		    area->area[i] =			_cairo_glitz_area_create (area->root,						  area->level + 1,						  area->x + dx[i],						  area->y + dy[i],						  w[i], h[i]);	    }	    for (; i < 4; i++)	    {		if (w[i] && h[i])		    area->area[i] =			_cairo_glitz_area_create (area->root,						  area->level + 1,						  area->x + dx[i],						  area->y + dy[i],						  w[i], h[i]);	    }	    area->state = CAIRO_GLITZ_AREA_DIVIDED;	    status = _cairo_glitz_area_find (area->area[0],					     width, height,					     kick_out, closure);	    if (status == CAIRO_STATUS_SUCCESS)		return CAIRO_STATUS_SUCCESS;	}    } break;    case CAIRO_GLITZ_AREA_DIVIDED: {	cairo_glitz_area_t *to_area;	int		   i, rejected = FALSE;	for (i = 0; i < 4; i++)	{	    if (area->area[i])	    {		if (area->area[i]->width >= width &&		    area->area[i]->height >= height)		{		    status = _cairo_glitz_area_find (area->area[i],						     width, height,						     kick_out, closure);		    if (status == CAIRO_STATUS_SUCCESS)			return CAIRO_STATUS_SUCCESS;		    rejected = TRUE;		}	    }	}	if (rejected)	    return CAIRO_INT_STATUS_UNSUPPORTED;	to_area = _cairo_glitz_area_get_top_scored_sub_area (area);	if (to_area)	{	    if (kick_out)	    {		if ((*area->root->funcs->compare_score) (to_area,							 to_area->closure,							 closure) >= 0)		    return CAIRO_INT_STATUS_UNSUPPORTED;	    } else {		return CAIRO_INT_STATUS_UNSUPPORTED;	    }	}	for (i = 0; i < 4; i++)	{	    _cairo_glitz_area_destroy (area->area[i]);	    area->area[i] = NULL;	}	area->closure = NULL;	area->state   = CAIRO_GLITZ_AREA_AVAILABLE;	status = _cairo_glitz_area_find (area, width, height,					 TRUE, closure);	if (status == CAIRO_STATUS_SUCCESS)	    return CAIRO_STATUS_SUCCESS;    } break;    }    return CAIRO_INT_STATUS_UNSUPPORTED;}static cairo_status_t_cairo_glitz_root_area_init (cairo_glitz_root_area_t	    *root,			     int			    max_level,			     int			    width,			     int			    height,			     const cairo_glitz_area_funcs_t *funcs){    root->max_level = max_level;    root->funcs     = funcs;    root->area = _cairo_glitz_area_create (root, 0, 0, 0, width, height);    if (!root->area)	return CAIRO_STATUS_NO_MEMORY;    return CAIRO_STATUS_SUCCESS;}static void_cairo_glitz_root_area_fini (cairo_glitz_root_area_t *root){    _cairo_glitz_area_destroy (root->area);}typedef struct _cairo_glitz_surface_font_private {    cairo_glitz_root_area_t root;    glitz_surface_t	    *surface;} cairo_glitz_surface_font_private_t;typedef struct _cairo_glitz_surface_glyph_private {    cairo_glitz_area_t	 *area;    cairo_bool_t	 locked;    cairo_point_double_t p1, p2;} cairo_glitz_surface_glyph_private_t;static cairo_status_t_cairo_glitz_glyph_move_in (cairo_glitz_area_t *area,			    void	       *closure){    cairo_glitz_surface_glyph_private_t *glyph_private = closure;    glyph_private->area = area;    return CAIRO_STATUS_SUCCESS;}static void_cairo_glitz_glyph_move_out (cairo_glitz_area_t	*area,			     void	        *closure){    cairo_glitz_surface_glyph_private_t *glyph_private = closure;    glyph_private->area = NULL;}static int_cairo_glitz_glyph_compare (cairo_glitz_area_t *area,			    void	       *closure1,			    void	       *closure2){    cairo_glitz_surface_glyph_private_t *glyph_private = closure1;    if (glyph_private->locked)	return 1;    return -1;}static const cairo_glitz_area_funcs_t _cairo_glitz_area_funcs = {    _cairo_glitz_glyph_move_in,    _cairo_glitz_glyph_move_out,    _cairo_glitz_glyph_compare};#define GLYPH_CACHE_TEXTURE_SIZE 512#define GLYPH_CACHE_MAX_LEVEL     64#define GLYPH_CACHE_MAX_HEIGHT    72#define GLYPH_CACHE_MAX_WIDTH     72#define WRITE_VEC2(ptr, _x, _y) \    *(ptr)++ = (_x);		\    *(ptr)++ = (_y)#define WRITE_BOX(ptr, _vx1, _vy1, _vx2, _vy2, p1, p2) \    WRITE_VEC2 (ptr, _vx1, _vy1);		       \    WRITE_VEC2 (ptr, (p1)->x, (p2)->y);		       \    WRITE_VEC2 (ptr, _vx2, _vy1);		       \    WRITE_VEC2 (ptr, (p2)->x, (p2)->y);		       \    WRITE_VEC2 (ptr, _vx2, _vy2);		       \    WRITE_VEC2 (ptr, (p2)->x, (p1)->y);		       \    WRITE_VEC2 (ptr, _vx1, _vy2);		       \

⌨️ 快捷键说明

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