diff options
author | Vladimir Vukicevic <vladimir@pobox.com> | 2008-08-10 05:05:28 -0700 |
---|---|---|
committer | Vladimir Vukicevic <vladimir@sleet.vlad1.com> | 2008-08-09 22:10:10 -0700 |
commit | ac2781ec0820e9352b28335e7d9553926d069ff2 (patch) | |
tree | a8e9de736f57c5112958264f288209869fad9284 | |
parent | 7fbda72137d8685718a8e8fe1d3af5b1d377521c (diff) |
[dfb] fix crashes due to cached glyphs going away during operation
-rw-r--r-- | src/cairo-directfb-surface.c | 73 |
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; |