📄 cairo-glitz-surface.c
字号:
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 + -