image: Fix up glyphs compositing

Jose Dapena Paz reported an assertion following the uninitialised status
value being returned. Also the function failed to free its allocations.

Based on a patch by Jose Dapena Paz <jdapena@igalia.com>.
Reported-by: Jose Dapena Paz <jdapena@igalia.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=51104
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2012-06-15 10:52:25 +01:00
parent 9bc1ea4431
commit 35e4ffd91c

View file

@ -795,7 +795,7 @@ composite_glyphs (void *_dst,
int dst_y,
cairo_composite_glyphs_info_t *info)
{
cairo_status_t status;
cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
pixman_glyph_cache_t *glyph_cache;
pixman_glyph_t pglyphs_stack[CAIRO_STACK_ARRAY_LENGTH (pixman_glyph_t)];
pixman_glyph_t *pglyphs = pglyphs_stack;
@ -807,28 +807,21 @@ composite_glyphs (void *_dst,
CAIRO_MUTEX_LOCK (_cairo_glyph_cache_mutex);
glyph_cache = get_glyph_cache();
if (unlikely (!glyph_cache)) {
if (unlikely (glyph_cache == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto out_no_glyph_cache;
goto out_unlock;
}
pixman_glyph_cache_freeze (glyph_cache);
if (info->num_glyphs > ARRAY_LENGTH (pglyphs_stack)) {
pglyphs = _cairo_malloc_ab (info->num_glyphs, sizeof (pixman_glyph_t));
if (unlikely (!pglyphs)) {
if (unlikely (pglyphs == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto out;
goto out_thaw;
}
}
if (unlikely (!glyph_cache)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto out;
}
pg = pglyphs;
for (i = 0; i < info->num_glyphs; i++) {
unsigned long index = info->glyphs[i].index;
@ -849,35 +842,30 @@ composite_glyphs (void *_dst,
CAIRO_MUTEX_LOCK (_cairo_glyph_cache_mutex);
if (unlikely (status))
goto out;
goto out_thaw;
glyph_surface = scaled_glyph->surface;
if (!glyph) {
glyph = pixman_glyph_cache_insert (glyph_cache, info->font, (void *)index,
glyph_surface->base.device_transform.x0,
glyph_surface->base.device_transform.y0,
glyph_surface->pixman_image);
if (unlikely (!glyph)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto out;
}
glyph = pixman_glyph_cache_insert (glyph_cache, info->font, (void *)index,
glyph_surface->base.device_transform.x0,
glyph_surface->base.device_transform.y0,
glyph_surface->pixman_image);
if (unlikely (!glyph)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto out_thaw;
}
}
pg->x = _cairo_lround (info->glyphs[i].x);
pg->y = _cairo_lround (info->glyphs[i].y);
pg->glyph = glyph;
pg++;
}
if (info->use_mask)
{
if (info->use_mask) {
pixman_format_code_t mask_format;
mask_format = pixman_glyph_get_mask_format (glyph_cache, pg - pglyphs, pglyphs);
pixman_composite_glyphs (_pixman_operator (op),
((cairo_image_source_t *)_src)->pixman_image,
to_pixman_image (_dst),
@ -887,9 +875,7 @@ composite_glyphs (void *_dst,
info->extents.x - dst_x, info->extents.y - dst_y,
info->extents.width, info->extents.height,
glyph_cache, pg - pglyphs, pglyphs);
}
else
{
} else {
pixman_composite_glyphs_no_mask (_pixman_operator (op),
((cairo_image_source_t *)_src)->pixman_image,
to_pixman_image (_dst),
@ -898,12 +884,14 @@ composite_glyphs (void *_dst,
glyph_cache, pg - pglyphs, pglyphs);
}
out:
out_thaw:
pixman_glyph_cache_thaw (glyph_cache);
out_no_glyph_cache:
if (pglyphs != pglyphs_stack)
free(pglyphs);
out_unlock:
CAIRO_MUTEX_UNLOCK (_cairo_glyph_cache_mutex);
return status;
}