gecko-dev/gfx/cairo/cairo-xlib-create-similar.patch

95 lines
4.1 KiB
Diff

Index: gfx/cairo/cairo/src/cairo-xlib-surface.c
===================================================================
RCS file: /home/rocallahan/mozilla-cvs-mirror/mozilla/gfx/cairo/cairo/src/cairo-xlib-surface.c,v
retrieving revision 1.4
diff -u -t -p -1 -2 -r1.4 cairo-xlib-surface.c
--- gfx/cairo/cairo/src/cairo-xlib-surface.c 10 Jan 2006 22:56:38 -0000 1.4
+++ gfx/cairo/cairo/src/cairo-xlib-surface.c 19 Feb 2006 23:59:56 -0000
@@ -224,35 +224,83 @@ _cairo_xlib_surface_create_similar_with_
xrender_format,
width, height);
if (surface->base.status != CAIRO_STATUS_SUCCESS) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
surface->owns_pixmap = TRUE;
return &surface->base;
}
+static cairo_bool_t
+_xrender_format_matches_content (XRenderPictFormat *format,
+ cairo_content_t content)
+{
+ cairo_bool_t has_alpha = format->direct.alpha != 0;
+ cairo_bool_t has_color = format->direct.red != 0 ||
+ format->direct.green != 0 || format->direct.blue != 0;
+ if (has_alpha != (content == CAIRO_CONTENT_ALPHA ||
+ content == CAIRO_CONTENT_COLOR_ALPHA))
+ return False;
+ if (has_color != (content == CAIRO_CONTENT_COLOR ||
+ content == CAIRO_CONTENT_COLOR_ALPHA))
+ return False;
+ return True;
+}
+
static cairo_surface_t *
_cairo_xlib_surface_create_similar (void *abstract_src,
cairo_content_t content,
int width,
int height)
{
cairo_format_t format = _cairo_format_from_content (content);
+ cairo_xlib_surface_t *src = abstract_src;
+
+ /* Try to create a surface with the same visual and depth as the
+ existing surface.
+ Don't bother if the X server doesn't have COMPOSITE, because we prefer
+ to just fall back to image surfaces in that case. */
+ if (src->visual != NULL && CAIRO_SURFACE_RENDER_HAS_COMPOSITE(src)) {
+ Display *dpy = src->dpy;
+ XRenderPictFormat *xrender_format =
+ XRenderFindVisualFormat (dpy, src->visual);
+ /* Give up if the requested content type isn't compatible with the
+ visual format */
+ if (xrender_format != NULL &&
+ _xrender_format_matches_content (xrender_format, content)) {
+ Pixmap pix = XCreatePixmap (dpy, RootWindowOfScreen (src->screen),
+ width <= 0 ? 1 : width, height <= 0 ? 1 : height,
+ xrender_format->depth);
+
+ cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *)
+ cairo_xlib_surface_create_with_xrender_format (dpy, pix, src->screen,
+ xrender_format,
+ width, height);
+ if (surface->base.status != CAIRO_STATUS_SUCCESS) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
+
+ surface->owns_pixmap = TRUE;
+ surface->visual = src->visual;
+
+ return &surface->base;
+ }
+ }
+
return _cairo_xlib_surface_create_similar_with_format (abstract_src,
- format,
- width,
- height);
+ format, width, height);
}
static cairo_status_t
_cairo_xlib_surface_finish (void *abstract_surface)
{
cairo_xlib_surface_t *surface = abstract_surface;
if (surface->dst_picture != None)
XRenderFreePicture (surface->dpy, surface->dst_picture);
if (surface->src_picture != None)
XRenderFreePicture (surface->dpy, surface->src_picture);