[cairo-commit] src/cairo-xlib-surface.c
Carl Worth
cworth at kemper.freedesktop.org
Thu Jul 27 00:23:47 PDT 2006
src/cairo-xlib-surface.c | 28 ++++++++++++++++++++++------
1 files changed, 22 insertions(+), 6 deletions(-)
New commits:
diff-tree 456cdb3058f3b416109a9600167cd8842300ae14 (from 8601c2c68306c956744399099a941363d446b906)
Author: Carl Worth <cworth at cworth.org>
Date: Wed Jul 26 15:48:56 2006 -0700
Elide size-zero glyphs from calls to XRender functions.
There appears to be a bug in some X servers which is triggered by
rendering 1-bit glyphs with zero size via the functions
XRenderAddGlyphs and XRenderCompositeText8 (and likely its variants).
We avoid this bug by making a copy of the glyphs array which does not
include any of the size-zero glyphs so that the X server never sees them.
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index cac6787..58ad459 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -2674,12 +2674,13 @@ _cairo_xlib_surface_show_glyphs (void
cairo_surface_attributes_t attributes;
cairo_xlib_surface_t *src = NULL;
+ cairo_glyph_t *output_glyphs;
const cairo_glyph_t *glyphs_chunk;
int glyphs_remaining, chunk_size, max_chunk_size;
cairo_scaled_glyph_t *scaled_glyph;
cairo_xlib_surface_font_private_t *font_private;
- int i;
+ int i, o;
unsigned long max_index = 0;
cairo_xlib_surface_show_glyphs_func_t show_glyphs_func;
@@ -2723,6 +2724,13 @@ _cairo_xlib_surface_show_glyphs (void
(font_private != NULL && font_private->dpy != dst->dpy))
return CAIRO_INT_STATUS_UNSUPPORTED;
+ /* We make a copy of the glyphs so that we can elide any size-zero
+ * glyphs to workaround an X server bug, (present in at least Xorg
+ * 7.1 without EXA). */
+ output_glyphs = malloc (num_glyphs * sizeof (cairo_glyph_t));
+ if (output_glyphs == NULL)
+ return CAIRO_STATUS_NO_MEMORY;
+
/* After passing all those tests, we're now committed to rendering
* these glyphs or to fail trying. We first upload any glyphs to
* the X server that it doesn't have already, then we draw
@@ -2781,7 +2789,7 @@ _cairo_xlib_surface_show_glyphs (void
goto BAIL;
/* Send all unsent glyphs to the server, and count the max of the glyph indices */
- for (i = 0; i < num_glyphs; i++) {
+ for (i = 0, o = 0; i < num_glyphs; i++) {
if (glyphs[i].index > max_index)
max_index = glyphs[i].index;
status = _cairo_scaled_glyph_lookup (scaled_font,
@@ -2790,11 +2798,18 @@ _cairo_xlib_surface_show_glyphs (void
&scaled_glyph);
if (status != CAIRO_STATUS_SUCCESS)
goto BAIL;
- if (scaled_glyph->surface_private == NULL) {
- _cairo_xlib_surface_add_glyph (dst->dpy, scaled_font, scaled_glyph);
- scaled_glyph->surface_private = (void *) 1;
+ /* Don't put any size-zero glyphs into output_glyphs to avoid
+ * an X server bug which stops rendering glyphs after the
+ * first size-zero glyph. */
+ if (scaled_glyph->surface->width && scaled_glyph->surface->height) {
+ output_glyphs[o++] = glyphs[i];
+ if (scaled_glyph->surface_private == NULL) {
+ _cairo_xlib_surface_add_glyph (dst->dpy, scaled_font, scaled_glyph);
+ scaled_glyph->surface_private = (void *) 1;
+ }
}
}
+ num_glyphs = o;
_cairo_xlib_surface_ensure_dst_picture (dst);
@@ -2811,7 +2826,7 @@ _cairo_xlib_surface_show_glyphs (void
}
max_chunk_size /= sz_xGlyphElt;
- for (glyphs_remaining = num_glyphs, glyphs_chunk = glyphs;
+ for (glyphs_remaining = num_glyphs, glyphs_chunk = output_glyphs;
glyphs_remaining;
glyphs_remaining -= chunk_size, glyphs_chunk += chunk_size)
{
@@ -2826,6 +2841,7 @@ _cairo_xlib_surface_show_glyphs (void
BAIL:
_cairo_scaled_font_thaw_cache (scaled_font);
+ free (output_glyphs);
if (src)
_cairo_pattern_release_surface (src_pattern, &src->base, &attributes);
More information about the cairo-commit
mailing list