[cairo] (Grossly) Misplaced glyph(s) at certain font sizes
Peter Clifton
pcjc2 at cam.ac.uk
Sat May 3 08:25:58 PDT 2008
On Sat, 2008-05-03 at 15:00 +0100, Peter Clifton wrote:
> Hi,
>
> I've been playing with Behdad's userfont branch (rebased onto git HEAD),
> and encountered what I presumed to be a bug in that code..
>
> I've been able to distill a small test-case, and it turns out that this
> happens with the toy text API, without the userfont code. (git HEAD).
>
> A screenshot of the bug, displaying the string "PA" at different sizes,
> is here:
>
> http://www2.eng.cam.ac.uk/~pcjc2/misplaced_glyph.png
>
> Testcase source code:
>
> http://www2.eng.cam.ac.uk/~pcjc2/misplaced_glyph.c
A bit of diagnosis reveals the problem in cairo...
We end up in _cairo_surface_show_glyphs, and we try the backend first:
if (surface->backend->show_glyphs)
status = surface->backend->show_glyphs (surface, op, dev_source,
glyphs, num_glyphs,
dev_scaled_font);
Delving into the xlib backend code, we get as far as trying to emit the
glyphs, but bail because the request is too large (in
_cairo_xlib_surface_add_glyph):
/* XXX XRenderAddGlyph does not handle a glyph surface larger than the
* maximum XRequest size.
*/
{
/* pessimistic length estimation in case we need to change formats */
int len = 4 * glyph_surface->width * glyph_surface->height;
int max_request_size = XMaxRequestSize (dpy) -
sz_xRenderAddGlyphsReq -
sz_xGlyphInfo -
4;
if (len >= max_request_size)
return CAIRO_INT_STATUS_UNSUPPORTED;
}
This violates the condition required of the backends in commit
5a9642c5746fd677aed35ce620ce90b1029b1a0c, where it states:
"The desired semantics is that they may modify the contents of the array
as long as they do not return CAIRO_STATUS_UNSUPPORTED. This makes it
possible to avoid copying the glyph array again and again, and edit it
in-place. Backends are in fact free to use the array as a generic
buffer as they see fit."
This CAIRO_INT_STATUS_UNSUPPORTED is propagated back to the
_cairo_surface_show_glyphs, where it then calls on the fallback
rendering function, but unfortunately _cairo_xlib_surface_emit_glyphs
already trampled the memory of the glyph array.
Any ideas how this could be fixed, or a workaround I can test with for
now?
--
Peter Clifton
Electrical Engineering Division,
Engineering Department,
University of Cambridge,
9, JJ Thomson Avenue,
Cambridge
CB3 0FA
Tel: +44 (0)7729 980173 - (No signal in the lab!)
More information about the cairo
mailing list