[cairo-commit] cairo/src cairo-glitz-surface.c,1.58,1.59
David Reveman
commit at pdx.freedesktop.org
Wed Sep 14 09:07:02 PDT 2005
Committed by: davidr
Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv8217/src
Modified Files:
cairo-glitz-surface.c
Log Message:
Track changes to glitz and update glyph caching in glitz backend
Index: cairo-glitz-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-glitz-surface.c,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -d -r1.58 -r1.59
--- cairo-glitz-surface.c 10 Aug 2005 18:40:11 -0000 1.58
+++ cairo-glitz-surface.c 14 Sep 2005 16:07:00 -0000 1.59
@@ -35,6 +35,9 @@
pixman_region16_t *clip;
} cairo_glitz_surface_t;
+static const cairo_surface_backend_t *
+_cairo_glitz_surface_get_backend (void);
+
static cairo_status_t
_cairo_glitz_surface_finish (void *abstract_surface)
{
@@ -454,11 +457,54 @@
static glitz_status_t
_glitz_ensure_target (glitz_surface_t *surface)
{
- if (glitz_surface_get_attached_drawable (surface) ||
- CAIRO_GLITZ_FEATURE_OK (surface, FRAMEBUFFER_OBJECT))
- return CAIRO_STATUS_SUCCESS;
+ if (!glitz_surface_get_attached_drawable (surface))
+ {
+ glitz_drawable_format_t *target_format, templ;
+ glitz_format_t *format;
+ glitz_drawable_t *drawable, *target;
+ unsigned int width, height;
+ unsigned long mask;
- return CAIRO_INT_STATUS_UNSUPPORTED;
+ drawable = glitz_surface_get_drawable (surface);
+ format = glitz_surface_get_format (surface);
+ width = glitz_surface_get_width (surface);
+ height = glitz_surface_get_height (surface);
+
+ if (format->type != GLITZ_FORMAT_TYPE_COLOR)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ templ.color = format->color;
+ templ.depth_size = 0;
+ templ.stencil_size = 0;
+ templ.doublebuffer = 0;
+ templ.samples = 1;
+
+ mask =
+ GLITZ_FORMAT_RED_SIZE_MASK |
+ GLITZ_FORMAT_GREEN_SIZE_MASK |
+ GLITZ_FORMAT_BLUE_SIZE_MASK |
+ GLITZ_FORMAT_ALPHA_SIZE_MASK |
+ GLITZ_FORMAT_DEPTH_SIZE_MASK |
+ GLITZ_FORMAT_STENCIL_SIZE_MASK |
+ GLITZ_FORMAT_DOUBLEBUFFER_MASK |
+ GLITZ_FORMAT_SAMPLES_MASK;
+
+ target_format = glitz_find_drawable_format (drawable, mask, &templ, 0);
+ if (!target_format)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ target = glitz_create_drawable (drawable, target_format,
+ width, height);
+ if (!target)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ glitz_surface_attach (surface, target,
+ GLITZ_DRAWABLE_BUFFER_FRONT_COLOR);
+
+ glitz_drawable_destroy (target);
+ }
+
+ return CAIRO_STATUS_SUCCESS;
}
typedef struct _cairo_glitz_surface_attributes {
@@ -1218,8 +1264,6 @@
return CAIRO_STATUS_SUCCESS;
}
-#define CAIRO_GLITZ_GLYPH_CACHE_MEMORY_DEFAULT 0x100000
-
#define CAIRO_GLITZ_AREA_AVAILABLE 0
#define CAIRO_GLITZ_AREA_DIVIDED 1
#define CAIRO_GLITZ_AREA_OCCUPIED 2
@@ -1530,47 +1574,24 @@
_cairo_glitz_area_destroy (root->area);
}
-#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); \
- WRITE_VEC2 (ptr, (p1)->x, (p1)->y)
-
-typedef struct _cairo_glitz_glyph_cache {
- cairo_cache_t base;
+typedef struct _cairo_glitz_surface_font_private {
cairo_glitz_root_area_t root;
glitz_surface_t *surface;
-} cairo_glitz_glyph_cache_t;
+} cairo_glitz_surface_font_private_t;
-typedef struct {
- cairo_glyph_cache_key_t key;
- int ref_count;
- cairo_glyph_size_t size;
- cairo_glitz_area_t *area;
- cairo_bool_t locked;
- cairo_point_double_t p1, p2;
-} cairo_glitz_glyph_cache_entry_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_glyph_cache_entry_t *entry = closure;
-
- entry->area = area;
+ cairo_glitz_surface_glyph_private_t *glyph_private = closure;
+
+ glyph_private->area = area;
return CAIRO_STATUS_SUCCESS;
}
@@ -1579,9 +1600,9 @@
_cairo_glitz_glyph_move_out (cairo_glitz_area_t *area,
void *closure)
{
- cairo_glitz_glyph_cache_entry_t *entry = closure;
-
- entry->area = NULL;
+ cairo_glitz_surface_glyph_private_t *glyph_private = closure;
+
+ glyph_private->area = NULL;
}
static int
@@ -1589,9 +1610,9 @@
void *closure1,
void *closure2)
{
- cairo_glitz_glyph_cache_entry_t *entry = closure1;
-
- if (entry->locked)
+ cairo_glitz_surface_glyph_private_t *glyph_private = closure1;
+
+ if (glyph_private->locked)
return 1;
return -1;
@@ -1603,212 +1624,189 @@
_cairo_glitz_glyph_compare
};
-static cairo_status_t
-_cairo_glitz_glyph_cache_create_entry (void *abstract_cache,
- void *abstract_key,
- void **return_entry)
-{
- cairo_glitz_glyph_cache_entry_t *entry;
- cairo_glyph_cache_key_t *key = abstract_key;
-
- cairo_status_t status;
- cairo_cache_t *im_cache;
- cairo_image_glyph_cache_entry_t *im;
+#define GLYPH_CACHE_TEXTURE_SIZE 512
+#define GLYPH_CACHE_MAX_LEVEL 64
+#define GLYPH_CACHE_MAX_HEIGHT 72
+#define GLYPH_CACHE_MAX_WIDTH 72
- unsigned long entry_memory = 0;
+#define WRITE_VEC2(ptr, _x, _y) \
+ *(ptr)++ = (_x); \
+ *(ptr)++ = (_y)
- entry = malloc (sizeof (cairo_glitz_glyph_cache_entry_t));
- if (!entry)
- return CAIRO_STATUS_NO_MEMORY;
+#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); \
+ WRITE_VEC2 (ptr, (p1)->x, (p1)->y)
- _cairo_lock_global_image_glyph_cache ();
+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;
- im_cache = _cairo_get_global_image_glyph_cache ();
- if (im_cache == NULL) {
- _cairo_unlock_global_image_glyph_cache ();
- free (entry);
- return CAIRO_STATUS_NO_MEMORY;
- }
+ drawable = glitz_surface_get_drawable (surface->surface);
- status = _cairo_cache_lookup (im_cache, key, (void **) (&im), NULL);
- if (status != CAIRO_STATUS_SUCCESS || im == NULL) {
- _cairo_unlock_global_image_glyph_cache ();
- free (entry);
- return CAIRO_STATUS_NO_MEMORY;
+ 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 (im->image)
- entry_memory = im->image->width * im->image->stride;
+ if (!surface_format)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
- _cairo_unlock_global_image_glyph_cache ();
+ font_private = malloc (sizeof (cairo_glitz_surface_font_private_t));
+ if (!font_private)
+ return CAIRO_STATUS_NO_MEMORY;
- entry->ref_count = 1;
- entry->key = *key;
- entry->key.base.memory = entry_memory;
- entry->area = NULL;
- entry->locked = FALSE;
+ 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);
- _cairo_unscaled_font_reference (entry->key.unscaled);
-
- *return_entry = entry;
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+ }
- return CAIRO_STATUS_SUCCESS;
-}
+ if (format == CAIRO_FORMAT_ARGB32)
+ glitz_surface_set_component_alpha (font_private->surface, 1);
-static void
-_cairo_glitz_glyph_cache_destroy_entry (void *abstract_cache,
- void *abstract_entry)
-{
- cairo_glitz_glyph_cache_entry_t *entry = abstract_entry;
+ 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);
- entry->ref_count--;
- if (entry->ref_count)
- return;
+ return status;
+ }
- if (entry->area)
- _cairo_glitz_area_move_out (entry->area);
-
- _cairo_unscaled_font_destroy (entry->key.unscaled);
+ scaled_font->surface_private = font_private;
+ scaled_font->surface_backend = _cairo_glitz_surface_get_backend ();
- free (entry);
+ return CAIRO_STATUS_SUCCESS;
}
-static void
-_cairo_glitz_glyph_cache_entry_reference (void *abstract_entry)
+static void
+_cairo_glitz_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font)
{
- cairo_glitz_glyph_cache_entry_t *entry = abstract_entry;
+ cairo_glitz_surface_font_private_t *font_private;
- entry->ref_count++;
+ 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_glyph_cache_destroy_cache (void *abstract_cache)
+static void
+_cairo_glitz_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph,
+ cairo_scaled_font_t *scaled_font)
{
- cairo_glitz_glyph_cache_t *cache = abstract_cache;
+ cairo_glitz_surface_glyph_private_t *glyph_private;
- _cairo_glitz_root_area_fini (&cache->root);
-
- glitz_surface_destroy (cache->surface);
-}
+ glyph_private = scaled_glyph->surface_private;
+ if (glyph_private)
+ {
+ if (glyph_private->area)
+ _cairo_glitz_area_move_out (glyph_private->area);
-static const cairo_cache_backend_t _cairo_glitz_glyph_cache_backend = {
- _cairo_glyph_cache_hash,
- _cairo_glyph_cache_keys_equal,
- _cairo_glitz_glyph_cache_create_entry,
- _cairo_glitz_glyph_cache_destroy_entry,
- _cairo_glitz_glyph_cache_destroy_cache
-};
+ free (glyph_private);
+ }
+}
-static cairo_glitz_glyph_cache_t *_cairo_glitz_glyph_caches = NULL;
+#define FIXED_TO_FLOAT(f) (((glitz_float_t) (f)) / 65536)
-static cairo_glitz_glyph_cache_t *
-_cairo_glitz_get_glyph_cache (cairo_glitz_surface_t *surface)
+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_glitz_glyph_cache_t *cache;
- glitz_drawable_t *drawable;
- glitz_format_t *format;
+ 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;
- /*
- * FIXME: caches should be thread specific, display specific and screen
- * specific.
- */
-
- if (_cairo_glitz_glyph_caches)
- return _cairo_glitz_glyph_caches;
+ 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;
- drawable = glitz_surface_get_drawable (surface->surface);
-
- format = glitz_find_standard_format (drawable, GLITZ_STANDARD_A8);
- if (!format)
- return NULL;
-
- cache = malloc (sizeof (cairo_glitz_glyph_cache_t));
- if (!cache)
- return NULL;
+ glyph_private->area = NULL;
+ glyph_private->locked = FALSE;
- cache->surface =
- glitz_surface_create (drawable, format,
- GLYPH_CACHE_TEXTURE_SIZE,
- GLYPH_CACHE_TEXTURE_SIZE,
- 0, NULL);
- if (cache->surface == NULL)
- {
- free (cache);
- return NULL;
+ scaled_glyph->surface_private = (void *) glyph_private;
}
- if (_cairo_glitz_root_area_init (&cache->root,
- GLYPH_CACHE_MAX_LEVEL,
- GLYPH_CACHE_TEXTURE_SIZE,
- GLYPH_CACHE_TEXTURE_SIZE,
- &_cairo_glitz_area_funcs))
- {
- glitz_surface_destroy (cache->surface);
- free (cache);
- return NULL;
- }
+ if (glyph_surface->width > GLYPH_CACHE_MAX_WIDTH ||
+ glyph_surface->height > GLYPH_CACHE_MAX_HEIGHT)
+ return CAIRO_STATUS_SUCCESS;
- if (_cairo_cache_init (&cache->base,
- &_cairo_glitz_glyph_cache_backend,
- CAIRO_GLITZ_GLYPH_CACHE_MEMORY_DEFAULT))
+ if (scaled_font->surface_private == NULL)
{
- _cairo_glitz_root_area_fini (&cache->root);
- glitz_surface_destroy (cache->surface);
- free (cache);
- return NULL;
+ status = _cairo_glitz_surface_font_init (surface, scaled_font,
+ glyph_surface->format);
+ if (status)
+ return status;
}
-
- _cairo_glitz_glyph_caches = cache;
-
- return cache;
-}
-
-#define FIXED_TO_FLOAT(f) (((glitz_float_t) (f)) / 65536)
-
-static cairo_status_t
-_cairo_glitz_cache_glyph (cairo_glitz_glyph_cache_t *cache,
- cairo_glitz_glyph_cache_entry_t *entry,
- cairo_image_glyph_cache_entry_t *image_entry)
-{
- glitz_point_fixed_t p1, p2;
- glitz_pixel_format_t pf;
- glitz_buffer_t *buffer;
- pixman_format_t *format;
- int am, rm, gm, bm;
- entry->size = image_entry->size;
-
- if (entry->size.width > GLYPH_CACHE_MAX_WIDTH ||
- entry->size.height > GLYPH_CACHE_MAX_HEIGHT)
- return CAIRO_STATUS_SUCCESS;
+ font_private = scaled_font->surface_private;
- if ((entry->size.width == 0 && entry->size.height == 0) ||
- !image_entry->image)
+ if (glyph_surface->width == 0 || glyph_surface->height == 0)
{
- entry->area = &_empty_area;
+ glyph_private->area = &_empty_area;
return CAIRO_STATUS_SUCCESS;
}
-
- format = pixman_image_get_format (image_entry->image->pixman_image);
+
+ format = pixman_image_get_format (glyph_surface->pixman_image);
if (!format)
return CAIRO_STATUS_NO_MEMORY;
-
- if (_cairo_glitz_area_find (cache->root.area,
- entry->size.width,
- entry->size.height,
- FALSE, entry))
+
+ if (_cairo_glitz_area_find (font_private->root.area,
+ glyph_surface->width,
+ glyph_surface->height,
+ FALSE, glyph_private))
{
- if (_cairo_glitz_area_find (cache->root.area,
- entry->size.width,
- entry->size.height,
- TRUE, entry))
+ 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 (image_entry->image->data);
+
+ buffer = glitz_buffer_create_for_data (glyph_surface->data);
if (!buffer)
{
- _cairo_glitz_area_move_out (entry->area);
+ _cairo_glitz_area_move_out (glyph_private->area);
return CAIRO_STATUS_NO_MEMORY;
}
@@ -1818,34 +1816,34 @@
pf.masks.red_mask = rm;
pf.masks.green_mask = gm;
pf.masks.blue_mask = bm;
-
- pf.bytes_per_line = image_entry->image->stride;
+
+ 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 (cache->surface,
- entry->area->x,
- entry->area->y,
- entry->size.width,
- entry->size.height,
+
+ 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 = entry->area->x << 16;
- p1.y = entry->area->y << 16;
- p2.x = (entry->area->x + entry->size.width) << 16;
- p2.y = (entry->area->y + entry->size.height) << 16;
-
- glitz_surface_translate_point (cache->surface, &p1, &p1);
- glitz_surface_translate_point (cache->surface, &p2, &p2);
-
- entry->p1.x = FIXED_TO_FLOAT (p1.x);
- entry->p1.y = FIXED_TO_FLOAT (p1.y);
- entry->p2.x = FIXED_TO_FLOAT (p2.x);
- entry->p2.y = FIXED_TO_FLOAT (p2.y);
-
+
+ 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;
}
@@ -1865,21 +1863,21 @@
const cairo_glyph_t *glyphs,
int num_glyphs)
{
- cairo_glitz_surface_attributes_t attributes;
- cairo_glitz_surface_t *dst = abstract_surface;
- cairo_glitz_surface_t *src;
- cairo_glitz_glyph_cache_t *cache;
- cairo_glitz_glyph_cache_entry_t *stack_entries[N_STACK_BUF];
- cairo_glitz_glyph_cache_entry_t **entries;
- cairo_glyph_cache_key_t key;
- glitz_float_t stack_vertices[N_STACK_BUF * 16];
- glitz_float_t *vertices;
- glitz_buffer_t *buffer;
- cairo_int_status_t status;
- int i, cached_glyphs = 0;
- int remaining_glyps = num_glyphs;
- glitz_float_t x1, y1, x2, y2;
- static glitz_vertex_format_t format = {
+ 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,
@@ -1892,6 +1890,10 @@
}
};
+ 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;
@@ -1910,67 +1912,57 @@
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;
-
- entries = (cairo_glitz_glyph_cache_entry_t **) data;
+
+ scaled_glyphs = (cairo_scaled_glyph_t **) data;
vertices = (glitz_float_t *) (data + num_glyphs * sizeof (void *));
}
else
{
- entries = stack_entries;
+ scaled_glyphs = stack_scaled_glyphs;
vertices = stack_vertices;
}
buffer = glitz_buffer_create_for_data (vertices);
if (!buffer)
goto FAIL2;
-
- cache = _cairo_glitz_get_glyph_cache (dst);
- if (!cache)
- {
- num_glyphs = 0;
- goto UNLOCK;
- }
-
- status = _cairo_scaled_font_get_glyph_cache_key (scaled_font, &key);
- if (status)
- goto UNLOCK;
for (i = 0; i < num_glyphs; i++)
{
- key.index = glyphs[i].index;
-
- status = _cairo_cache_lookup (&cache->base,
- &key,
- (void **) &entries[i],
- NULL);
- if (status)
+ 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;
}
- _cairo_glitz_glyph_cache_entry_reference (entries[i]);
-
- if (entries[i]->area)
+ glyph_private = scaled_glyphs[i]->surface_private;
+ if (glyph_private && glyph_private->area)
{
remaining_glyps--;
- if (entries[i]->area->width)
+ if (glyph_private->area->width)
{
- x1 = floor (glyphs[i].x + 0.5) + entries[i]->size.x;
- y1 = floor (glyphs[i].y + 0.5) + entries[i]->size.y;
- x2 = x1 + entries[i]->size.width;
- y2 = y1 + entries[i]->size.height;
-
+ x_offset = scaled_glyphs[i]->surface->base.device_x_offset;
+ y_offset = scaled_glyphs[i]->surface->base.device_y_offset;
+
+ 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,
- &entries[i]->p1, &entries[i]->p2);
-
- entries[i]->locked = TRUE;
+ &glyph_private->p1, &glyph_private->p2);
+
+ glyph_private->locked = TRUE;
+
cached_glyphs++;
}
}
@@ -1978,96 +1970,65 @@
if (remaining_glyps)
{
- cairo_cache_t *image_cache;
- cairo_image_glyph_cache_entry_t *image_entry;
- cairo_surface_t *image;
- cairo_glitz_surface_t *clone;
-
- _cairo_lock_global_image_glyph_cache ();
+ cairo_surface_t *image;
+ cairo_glitz_surface_t *clone;
- image_cache = _cairo_get_global_image_glyph_cache ();
- if (!image_cache)
- {
- _cairo_unlock_global_image_glyph_cache ();
- status = CAIRO_STATUS_NO_MEMORY;
- goto UNLOCK;
- }
-
for (i = 0; i < num_glyphs; i++)
{
- if (!entries[i]->area)
+ glyph_private = scaled_glyphs[i]->surface_private;
+ if (!glyph_private || !glyph_private->area)
{
- key.index = glyphs[i].index;
-
- status = _cairo_cache_lookup (image_cache,
- &key,
- (void **) &image_entry,
- NULL);
+ status = _cairo_glitz_surface_add_glyph (dst,
+ scaled_font,
+ scaled_glyphs[i]);
if (status)
- {
- _cairo_unlock_global_image_glyph_cache ();
goto UNLOCK;
- }
- status = _cairo_glitz_cache_glyph (cache,
- entries[i],
- image_entry);
- if (status)
- {
- _cairo_unlock_global_image_glyph_cache ();
- goto UNLOCK;
- }
+ glyph_private = scaled_glyphs[i]->surface_private;
}
-
- x1 = floor (glyphs[i].x + 0.5);
- y1 = floor (glyphs[i].y + 0.5);
- if (entries[i]->area)
+ x_offset = scaled_glyphs[i]->surface->base.device_x_offset;
+ y_offset = scaled_glyphs[i]->surface->base.device_y_offset;
+
+ x1 = floor (glyphs[i].x + 0.5) + x_offset;
+ y1 = floor (glyphs[i].y + 0.5) + y_offset;
+
+ if (glyph_private->area)
{
- if (entries[i]->area->width)
+ if (glyph_private->area->width)
{
- x1 += entries[i]->size.x;
- y1 += entries[i]->size.y;
- x2 = x1 + entries[i]->size.width;
- y2 = y1 + entries[i]->size.height;
-
+ x2 = x1 + glyph_private->area->width;
+ y2 = y1 + glyph_private->area->height;
+
WRITE_BOX (vertices, x1, y1, x2, y2,
- &entries[i]->p1, &entries[i]->p2);
-
- entries[i]->locked = TRUE;
+ &glyph_private->p1, &glyph_private->p2);
+
+ glyph_private->locked = TRUE;
+
cached_glyphs++;
}
}
else
{
- x1 += image_entry->size.x;
- y1 += image_entry->size.y;
-
- if (!image_entry->image)
- continue;
-
- image = &image_entry->image->base;
+ image = &scaled_glyphs[i]->surface->base;
status =
_cairo_glitz_surface_clone_similar (abstract_surface,
image,
(cairo_surface_t **)
&clone);
if (status)
- {
- _cairo_unlock_global_image_glyph_cache ();
goto UNLOCK;
- }
- glitz_composite (_glitz_operator (op),
- src->surface,
+ 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,
- image_entry->size.width,
- image_entry->size.height);
+ scaled_glyphs[i]->surface->width,
+ scaled_glyphs[i]->surface->height);
cairo_surface_destroy (&clone->base);
@@ -2075,17 +2036,16 @@
GLITZ_STATUS_NOT_SUPPORTED)
{
status = CAIRO_INT_STATUS_UNSUPPORTED;
- _cairo_unlock_global_image_glyph_cache ();
goto UNLOCK;
}
}
}
-
- _cairo_unlock_global_image_glyph_cache ();
}
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,
@@ -2093,9 +2053,11 @@
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,
- cache->surface,
+ font_private->surface,
dst->surface,
src_x + attributes.base.x_offset,
src_y + attributes.base.y_offset,
@@ -2107,22 +2069,23 @@
GLITZ_GEOMETRY_TYPE_NONE,
NULL, NULL);
}
-
+
UNLOCK:
if (cached_glyphs)
{
for (i = 0; i < num_glyphs; i++)
- entries[i]->locked = FALSE;
+ {
+ glyph_private = scaled_glyphs[i]->surface_private;
+ if (glyph_private)
+ glyph_private->locked = FALSE;
+ }
}
-
- for (i = 0; i < num_glyphs; i++)
- _cairo_glitz_glyph_cache_destroy_entry (cache, entries[i]);
glitz_buffer_destroy (buffer);
FAIL2:
if (num_glyphs > N_STACK_BUF)
- free (entries);
+ free (scaled_glyphs);
FAIL1:
if (attributes.n_params)
@@ -2132,10 +2095,10 @@
if (status)
return status;
-
+
if (glitz_surface_get_status (dst->surface) == GLITZ_STATUS_NOT_SUPPORTED)
return CAIRO_INT_STATUS_UNSUPPORTED;
-
+
return CAIRO_STATUS_SUCCESS;
}
@@ -2155,9 +2118,21 @@
_cairo_glitz_surface_set_clip_region,
NULL, /* intersect_clip_path */
_cairo_glitz_surface_get_extents,
- _cairo_glitz_surface_show_glyphs
+ _cairo_glitz_surface_show_glyphs,
+ NULL, /* fill_path */
+ NULL, /* get_font_options */
+ NULL, /* 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;
+}
+
cairo_surface_t *
cairo_glitz_surface_create (glitz_surface_t *surface)
{
@@ -2175,10 +2150,10 @@
_cairo_surface_init (&crsurface->base, &cairo_glitz_surface_backend);
glitz_surface_reference (surface);
-
+
crsurface->surface = surface;
crsurface->format = glitz_surface_get_format (surface);
crsurface->clip = NULL;
-
+
return (cairo_surface_t *) crsurface;
}
More information about the cairo-commit
mailing list