mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2025-12-28 02:50:14 +01:00
[meta] always copy glyph array before passing to _cairo_surface_show_glyphs
_cairo_surface_show_glyphs is allowed to mutate the glyph array; if it's handed the internal array that the meta surface holds, then any subsequent playback (such as for fine-grained fallbacks) will result in incorrect glyph rendering. Ref: https://bugzilla.mozilla.org/show_bug.cgi?id=419917 (I was unable to create a simple cairo testcase to demonstrate the problem.)
This commit is contained in:
parent
4a1f65b63e
commit
d89edde84d
1 changed files with 15 additions and 9 deletions
|
|
@ -1,3 +1,4 @@
|
|||
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc
|
||||
|
|
@ -803,21 +804,28 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
|
|||
case CAIRO_COMMAND_SHOW_GLYPHS:
|
||||
{
|
||||
cairo_glyph_t *glyphs = command->show_glyphs.glyphs;
|
||||
cairo_glyph_t *dev_glyphs = glyphs;
|
||||
cairo_glyph_t *dev_glyphs;
|
||||
int i, num_glyphs = command->show_glyphs.num_glyphs;
|
||||
|
||||
/* show_glyphs is special because _cairo_surface_show_glyphs is allowed
|
||||
* to modify the glyph array that's passed in. We must always
|
||||
* copy the array before handing it to the backend.
|
||||
*/
|
||||
dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
|
||||
if (dev_glyphs == NULL) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
break;
|
||||
}
|
||||
|
||||
if (has_device_transform) {
|
||||
dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
|
||||
if (dev_glyphs == NULL) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < num_glyphs; i++) {
|
||||
dev_glyphs[i] = glyphs[i];
|
||||
cairo_matrix_transform_point (device_transform,
|
||||
&dev_glyphs[i].x,
|
||||
&dev_glyphs[i].y);
|
||||
}
|
||||
} else {
|
||||
memcpy (dev_glyphs, glyphs, sizeof (cairo_glyph_t) * num_glyphs);
|
||||
}
|
||||
|
||||
status = _cairo_surface_show_glyphs (target,
|
||||
|
|
@ -826,9 +834,7 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
|
|||
dev_glyphs, num_glyphs,
|
||||
command->show_glyphs.scaled_font);
|
||||
|
||||
if (dev_glyphs != glyphs)
|
||||
free (dev_glyphs);
|
||||
|
||||
free (dev_glyphs);
|
||||
break;
|
||||
}
|
||||
case CAIRO_COMMAND_INTERSECT_CLIP_PATH:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue