[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