diff options
author | Carl Worth <cworth@cworth.org> | 2006-03-03 11:13:36 -0800 |
---|---|---|
committer | Carl Worth <cworth@cworth.org> | 2006-03-03 11:13:36 -0800 |
commit | 7d498ca91279a4e793d704c5b878f070be4c878f (patch) | |
tree | b89dc37993dafa024098cc5195466c42e28a9d35 | |
parent | 3aac0bf670facd6523e64b3585a93f29da7ffba2 (diff) | |
download | cairo-7d498ca91279a4e793d704c5b878f070be4c878f.tar.gz |
_cairo_xlib_surface_show_glyphs: Break up rendering into chunks to fit
into X max request length protocol limits.
This fixes bug #5528:
_XError from XRenderCompositeText8
https://bugs.freedesktop.org/show_bug.cgi?id=5528
-rw-r--r-- | src/cairo-xlib-surface.c | 61 |
1 files changed, 42 insertions, 19 deletions
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index e5ffc6ecc..0efabf497 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -41,6 +41,7 @@ #include "cairo-xlib-test.h" #include "cairo-xlib-private.h" #include <X11/extensions/Xrender.h> +#include <X11/extensions/renderproto.h> /* Xlib doesn't define a typedef, so define one ourselves */ typedef int (*cairo_xlib_error_func_t) (Display *display, @@ -2710,7 +2711,9 @@ _cairo_xlib_surface_show_glyphs (cairo_scaled_font_t *scaled_font, cairo_xlib_surface_t *src; glyphset_cache_t *cache; cairo_glyph_cache_key_t key; - glyphset_cache_entry_t **entries; + const cairo_glyph_t *glyphs_chunk; + glyphset_cache_entry_t **entries, **entries_chunk; + int glyphs_remaining, chunk_size, max_chunk_size; glyphset_cache_entry_t *stack_entries [N_STACK_BUF]; composite_operation_t operation; int i; @@ -2777,26 +2780,46 @@ _cairo_xlib_surface_show_glyphs (cairo_scaled_font_t *scaled_font, /* Call the appropriate sub-function. */ _cairo_xlib_surface_ensure_dst_picture (self); + + max_chunk_size = XMaxRequestSize (self->dpy); if (elt_size == 8) + max_chunk_size -= sz_xRenderCompositeGlyphs8Req; + if (elt_size == 16) + max_chunk_size -= sz_xRenderCompositeGlyphs16Req; + if (elt_size == 32) + max_chunk_size -= sz_xRenderCompositeGlyphs32Req; + max_chunk_size /= sz_xGlyphElt; + + for (glyphs_remaining = num_glyphs, glyphs_chunk = glyphs, entries_chunk = entries; + glyphs_remaining; + glyphs_remaining -= chunk_size, glyphs_chunk += chunk_size, entries_chunk += chunk_size) { - status = _cairo_xlib_surface_show_glyphs8 (scaled_font, operator, cache, &key, src, self, - source_x + attributes.x_offset - dest_x, - source_y + attributes.y_offset - dest_y, - glyphs, entries, num_glyphs); - } - else if (elt_size == 16) - { - status = _cairo_xlib_surface_show_glyphs16 (scaled_font, operator, cache, &key, src, self, - source_x + attributes.x_offset - dest_x, - source_y + attributes.y_offset - dest_y, - glyphs, entries, num_glyphs); - } - else - { - status = _cairo_xlib_surface_show_glyphs32 (scaled_font, operator, cache, &key, src, self, - source_x + attributes.x_offset - dest_x, - source_y + attributes.y_offset - dest_y, - glyphs, entries, num_glyphs); + chunk_size = MIN (glyphs_remaining, max_chunk_size); + + if (elt_size == 8) + { + status = _cairo_xlib_surface_show_glyphs8 (scaled_font, operator, cache, &key, src, self, + source_x + attributes.x_offset - dest_x, + source_y + attributes.y_offset - dest_y, + glyphs_chunk, entries_chunk, chunk_size); + } + else if (elt_size == 16) + { + status = _cairo_xlib_surface_show_glyphs16 (scaled_font, operator, cache, &key, src, self, + source_x + attributes.x_offset - dest_x, + source_y + attributes.y_offset - dest_y, + glyphs_chunk, entries_chunk, chunk_size); + } + else + { + status = _cairo_xlib_surface_show_glyphs32 (scaled_font, operator, cache, &key, src, self, + source_x + attributes.x_offset - dest_x, + source_y + attributes.y_offset - dest_y, + glyphs_chunk, entries_chunk, chunk_size); + } + + if (status != CAIRO_STATUS_SUCCESS) + break; } if (status == CAIRO_STATUS_SUCCESS && |