summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVladimir Vukicevic <vladimir@pobox.com>2008-08-10 05:05:28 -0700
committerVladimir Vukicevic <vladimir@sleet.vlad1.com>2008-08-09 22:10:10 -0700
commitac2781ec0820e9352b28335e7d9553926d069ff2 (patch)
treea8e9de736f57c5112958264f288209869fad9284 /src
parent7fbda72137d8685718a8e8fe1d3af5b1d377521c (diff)
[dfb] fix crashes due to cached glyphs going away during operation
Diffstat (limited to 'src')
-rw-r--r--src/cairo-directfb-surface.c73
1 files changed, 54 insertions, 19 deletions
diff --git a/src/cairo-directfb-surface.c b/src/cairo-directfb-surface.c
index a402bd18..ecfc0f49 100644
--- a/src/cairo-directfb-surface.c
+++ b/src/cairo-directfb-surface.c
@@ -1384,21 +1384,29 @@ _directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
int h = 8;
int i;
+ D_DEBUG_AT (CairoDFB_Font, "%s( %p [%d] )\n", __FUNCTION__, glyphs, num_glyphs );
+
if (scaled_font->surface_private) {
cache = scaled_font->surface_private;
x = cache->x;
y = cache->y;
}
-
+
+ _cairo_cache_freeze( scaled_font->glyphs );
+
for (i = 0; i < num_glyphs; i++) {
cairo_scaled_glyph_t *scaled_glyph;
cairo_image_surface_t *img;
+ D_DEBUG_AT (CairoDFB_Font, " -> [%2d] = %4lu\n", i, glyphs[i].index );
+
ret = _cairo_scaled_glyph_lookup (scaled_font, glyphs[i].index,
CAIRO_SCALED_GLYPH_INFO_SURFACE,
&scaled_glyph);
- if (ret)
+ if (ret) {
+ _cairo_cache_thaw( scaled_font->glyphs );
return ret;
+ }
img = scaled_glyph->surface;
switch (img->format) {
@@ -1408,18 +1416,25 @@ _directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
break;
default:
D_DEBUG_AT (CairoDFB_Font,
- "Unsupported font format %d!\n", img->format);
+ " -> Unsupported font format %d!\n", img->format);
+ _cairo_cache_thaw( scaled_font->glyphs );
return CAIRO_INT_STATUS_UNSUPPORTED;
}
points[n].x = _cairo_lround (glyphs[i].x - img->base.device_transform.x0);
points[n].y = _cairo_lround (glyphs[i].y - img->base.device_transform.y0);
+// D_DEBUG_AT (CairoDFB_Font, " (%4d,%4d) [%2d]\n", points[n].x, points[n].y, n );
+
if (points[n].x >= surface->width ||
points[n].y >= surface->height ||
points[n].x+img->width <= 0 ||
points[n].y+img->height <= 0)
- continue;
+ {
+ D_DEBUG_AT (CairoDFB_Font,
+ " -> Unsupported font format %d!\n", img->format);
+ continue;
+ }
if (!scaled_glyph->surface_private) {
DFBRectangle *rect;
@@ -1441,30 +1456,31 @@ _directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
/* Remember glyph location */
rect = malloc (sizeof(DFBRectangle));
- if (!rect)
+ if (!rect) {
+ _cairo_cache_thaw( scaled_font->glyphs );
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ }
*rect = rects[n];
scaled_glyph->surface_private = rect;
chars[num_chars++] = scaled_glyph;
- /*D_DEBUG_AT (CairoDFB_Font,
- "Glyph %lu will be loaded at (%d,%d).\n",
- glyphs[i].index, rects[n].x, rects[n].y);*/
+ D_DEBUG_AT (CairoDFB_Font, " -> loading at %4d,%2d <- rect %p, img %p, entry %p\n",
+ rects[n].x, rects[n].y, rect, scaled_glyph->surface, scaled_glyph);
}
else {
rects[n] = *((DFBRectangle *)scaled_glyph->surface_private);
- /*D_DEBUG_AT (CairoDFB_Font,
- "Glyph %lu already loaded at (%d,%d).\n",
- glyphs[i].index, rects[n].x, rects[n].y);*/
+ D_DEBUG_AT (CairoDFB_Font, " -> exists at %4d,%2d\n", rects[n].x, rects[n].y);
}
n++;
}
- if (!n)
+ if (!n) {
+ _cairo_cache_thaw( scaled_font->glyphs );
return CAIRO_INT_STATUS_NOTHING_TO_DO;
+ }
h += y;
w = MAX (w, 8);
@@ -1477,12 +1493,13 @@ _directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
w = MAX (w, cache->width);
h = MAX (h, cache->height);
- D_DEBUG_AT (CairoDFB_Font,
- "Reallocating font cache (%dx%d).\n", w, h);
+ D_DEBUG_AT (CairoDFB_Font, " -> Reallocating font cache (%dx%d).\n", w, h);
new_cache = _directfb_allocate_font_cache (surface->dfb, w, h);
- if (!new_cache)
+ if (!new_cache) {
+ _cairo_cache_thaw( scaled_font->glyphs );
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ }
new_cache->dfbsurface->Blit (new_cache->dfbsurface,
cache->dfbsurface, NULL, 0, 0);
@@ -1492,12 +1509,13 @@ _directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
}
}
else {
- D_DEBUG_AT (CairoDFB_Font,
- "Allocating font cache (%dx%d).\n", w, h);
+ D_DEBUG_AT (CairoDFB_Font, " -> Allocating font cache (%dx%d).\n", w, h);
cache = _directfb_allocate_font_cache (surface->dfb, w, h);
- if (!cache)
+ if (!cache) {
+ _cairo_cache_thaw( scaled_font->glyphs );
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ }
scaled_font->surface_backend = &cairo_directfb_surface_backend;
scaled_font->surface_private = cache;
@@ -1509,17 +1527,30 @@ _directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
if (cache->dfbsurface->Lock (cache->dfbsurface,
DSLF_WRITE, (void *)&data, &pitch))
+ {
+ _cairo_cache_thaw( scaled_font->glyphs );
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ }
+ D_DEBUG_AT (CairoDFB_Font, " => %d chars to load, cache %dx%d\n", num_chars, cache->width, cache->height);
+
for (i = 0; i < num_chars; i++) {
cairo_image_surface_t *img = chars[i]->surface;
DFBRectangle *rect = chars[i]->surface_private;
unsigned char *dst = data;
- unsigned char *src = img->data;
+ unsigned char *src;
int j;
+ D_DEBUG_AT (CairoDFB_Font, " -> loading [%2d] <- rect %p, img %p, entry %p\n", i, rect, img, chars[i]);
+
+ src = img->data;
+
+ D_DEBUG_AT (CairoDFB_Font, " from %p\n", src);
+
dst += rect->y * pitch + (_directfb_argb_font ? (rect->x<<2) : rect->x);
+ D_DEBUG_AT (CairoDFB_Font, " to %4d,%2d (%p)\n", rect->x, rect->y, dst);
+
if (img->format == CAIRO_FORMAT_A1) {
for (h = rect->h; h; h--) {
if (_directfb_argb_font) {
@@ -1568,9 +1599,13 @@ _directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
cache->dfbsurface->Unlock (cache->dfbsurface);
}
+ _cairo_cache_thaw( scaled_font->glyphs );
+
cache->x = x;
cache->y = y;
+ D_DEBUG_AT (CairoDFB_Font, " => cache %d,%d, %p [%d]\n", x, y, cache, n);
+
*ret_cache = cache;
*ret_num = n;