[cairo-commit] src/cairo-xlib-surface.c
Carl Worth
cworth at kemper.freedesktop.org
Mon May 1 14:54:38 PDT 2006
src/cairo-xlib-surface.c | 61 ++++++++++++++++++++++++++++++++++++-----------
1 files changed, 48 insertions(+), 13 deletions(-)
New commits:
diff-tree 8dff692db6e7083633fc9b81548b0554a985fabd (from 0c927c53880f9ece2903a9b2c7843aaff1c78dec)
Author: Carl Worth <cworth at cworth.org>
Date: Mon May 1 10:17:08 2006 -0700
Support multiple glyph image formats within the same font (fix #4705).
If we find a glyph image of a format that is different from the font's
format, then we use a temporary image and convert to the font's
format.
This provides a simple fix for the crash identified in bug #4705:
crash at XRenderAddGlyphs
https://bugs.freedesktop.org/show_bug.cgi?id=4705
A later improvement would guarantee that the "font's format" was
carefully chosen to be able to contain all glyphs in the font without
information loss.
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 0f195bf..c2eeab9 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -2009,7 +2009,8 @@ cairo_xlib_surface_set_drawable (cairo_s
typedef struct _cairo_xlib_surface_font_private {
Display *dpy;
GlyphSet glyphset;
- XRenderPictFormat *format;
+ cairo_format_t format;
+ XRenderPictFormat *xrender_format;
} cairo_xlib_surface_font_private_t;
static cairo_status_t
@@ -2024,8 +2025,9 @@ _cairo_xlib_surface_font_init (Display
return CAIRO_STATUS_NO_MEMORY;
font_private->dpy = dpy;
- font_private->format = _CAIRO_FORMAT_XRENDER_FORMAT(dpy, format);
- font_private->glyphset = XRenderCreateGlyphSet (dpy, font_private->format);
+ font_private->format = format;
+ font_private->xrender_format = _CAIRO_FORMAT_TO_XRENDER_FORMAT(dpy, format);
+ font_private->glyphset = XRenderCreateGlyphSet (dpy, font_private->xrender_format);
scaled_font->surface_private = font_private;
scaled_font->surface_backend = &cairo_xlib_surface_backend;
return CAIRO_STATUS_SUCCESS;
@@ -2072,7 +2074,7 @@ _cairo_xlib_surface_add_glyph (Display *
XGlyphInfo glyph_info;
unsigned long glyph_index;
unsigned char *data;
- cairo_status_t status;
+ cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_xlib_surface_font_private_t *font_private;
cairo_image_surface_t *glyph_surface = scaled_glyph->surface;
@@ -2084,6 +2086,32 @@ _cairo_xlib_surface_add_glyph (Display *
}
font_private = scaled_font->surface_private;
+ /* If the glyph format does not match the font format, then we
+ * create a temporary surface for the glyph image with the font's
+ * format.
+ */
+ if (glyph_surface->format != font_private->format) {
+ cairo_t *cr;
+ cairo_surface_t *tmp_surface;
+
+ tmp_surface = cairo_image_surface_create (font_private->format,
+ glyph_surface->width,
+ glyph_surface->height);
+ cr = cairo_create (tmp_surface);
+ cairo_set_source_surface (cr, &glyph_surface->base, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+
+ status = cairo_status (cr);
+
+ cairo_destroy (cr);
+
+ glyph_surface = (cairo_image_surface_t *) tmp_surface;
+
+ if (status)
+ goto BAIL;
+ }
+
/*
* Most of the font rendering system thinks of glyph tiles as having
* an origin at (0,0) and an x and y bounding box "offset" which
@@ -2139,8 +2167,10 @@ _cairo_xlib_surface_add_glyph (Display *
unsigned char *new, *n;
new = malloc (c);
- if (!new)
- return CAIRO_STATUS_NO_MEMORY;
+ if (!new) {
+ status = CAIRO_STATUS_NO_MEMORY;
+ goto BAIL;
+ }
n = new;
d = data;
while (c--)
@@ -2163,8 +2193,10 @@ _cairo_xlib_surface_add_glyph (Display *
unsigned char *new, *n;
new = malloc (c);
- if (new == NULL)
- return CAIRO_STATUS_NO_MEMORY;
+ if (new == NULL) {
+ status = CAIRO_STATUS_NO_MEMORY;
+ goto BAIL;
+ }
n = new;
d = data;
while ((c -= 4) >= 0)
@@ -2196,7 +2228,11 @@ _cairo_xlib_surface_add_glyph (Display *
if (data != glyph_surface->data)
free (data);
- return CAIRO_STATUS_SUCCESS;
+ BAIL:
+ if (glyph_surface != scaled_glyph->surface)
+ cairo_surface_destroy (&glyph_surface->base);
+
+ return status;
}
#define N_STACK_BUF 1024
@@ -2252,7 +2288,7 @@ _cairo_xlib_surface_old_show_glyphs8 (c
_render_operator (op),
src->src_picture,
self->dst_picture,
- font_private->format,
+ font_private->xrender_format,
source_x + elts[0].xOff, source_y + elts[0].yOff,
0, 0,
elts, num_glyphs);
@@ -2314,7 +2350,7 @@ _cairo_xlib_surface_old_show_glyphs16 (c
_render_operator (op),
src->src_picture,
self->dst_picture,
- font_private->format,
+ font_private->xrender_format,
source_x + elts[0].xOff, source_y + elts[0].yOff,
0, 0,
elts, num_glyphs);
@@ -2376,7 +2412,7 @@ _cairo_xlib_surface_old_show_glyphs32 (c
_render_operator (op),
src->src_picture,
self->dst_picture,
- font_private->format,
+ font_private->xrender_format,
source_x + elts[0].xOff, source_y + elts[0].yOff,
0, 0,
elts, num_glyphs);
@@ -2413,7 +2449,6 @@ _cairo_xlib_surface_old_show_glyphs (cai
int i;
unsigned long max_index = 0;
-
if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE_TEXT (self) || !self->format)
return CAIRO_INT_STATUS_UNSUPPORTED;
More information about the cairo-commit
mailing list