[cairo-commit] 2 commits - src/cairo-xlib-surface.c

Carl Worth cworth at kemper.freedesktop.org
Thu May 18 16:32:13 PDT 2006


 src/cairo-xlib-surface.c |  127 +++++++++++++++++++++++++----------------------
 1 files changed, 68 insertions(+), 59 deletions(-)

New commits:
diff-tree 3487191b2230571323201ed045263433e77e5345 (from a96bd2b4f9ab399eee5198c0d27a6cd67798931b)
Author: Carl Worth <cworth at cworth.org>
Date:   Thu May 18 15:36:43 2006 -0700

    xlib: Style cleanups for _cairo_xlib_surface_create_similar
    
    Including style cleanups for _xrender_format_matches_content.
    
    There's even a bug fix here as well. Previously, we would miss compatibility
    if the existing xlib surface had a NULL visual, (even if it had a compatible
    xrender_format). We now catch this case, and don't bother even trying to
    store a visual into the resulting surface.

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 0c6ae14..3d528bf 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -209,8 +209,9 @@ _cairo_xlib_surface_create_similar_with_
     XRenderPictFormat *xrender_format = _CAIRO_FORMAT_TO_XRENDER_FORMAT (dpy, 
 									 format);
 
-    /* As a good first approximation, if the display doesn't have COMPOSITE,
-     * we're better off using image surfaces for all temporary operations
+    /* As a good first approximation, if the display doesn't have even
+     * the most elementary RENDER operation, then we're better off
+     * using image surfaces for all temporary operations
      */
     if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE(src)) {
 	return cairo_image_surface_create (format, width, height);
@@ -238,16 +239,17 @@ 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;
+    cairo_bool_t format_has_alpha = format->direct.alpha != 0;
+    cairo_bool_t format_has_color = (format->direct.red   != 0 ||
+				     format->direct.green != 0 ||
+				     format->direct.blue  != 0);
+    cairo_bool_t content_has_alpha = (content == CAIRO_CONTENT_ALPHA ||
+				      content == CAIRO_CONTENT_COLOR_ALPHA);
+    cairo_bool_t content_has_color = (content == CAIRO_CONTENT_COLOR ||
+				      content == CAIRO_CONTENT_COLOR_ALPHA);
+
+    return (format_has_alpha == content_has_alpha &&
+	    format_has_color == content_has_color);
 }
 
 static cairo_surface_t *
@@ -256,43 +258,50 @@ _cairo_xlib_surface_create_similar (void
 				    int			width,
 				    int			height)
 {
-    cairo_format_t format = _cairo_format_from_content (content);
     cairo_xlib_surface_t *src = abstract_src;
+    XRenderPictFormat *xrender_format = src->xrender_format;
+    cairo_xlib_surface_t *surface;
+    Pixmap pix;
 
-    /* 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;
+    /* Start by examining the surface's XRenderFormat, or if it
+     * doesn't have one, then look one up through its visual (in the
+     * case of a bitmap, it won't even have that). */
+    if (xrender_format == NULL && src->visual != NULL)
+        xrender_format = XRenderFindVisualFormat (src->dpy, src->visual);
+
+    /* If we never found an XRenderFormat or if it isn't compatible
+     * with the content being requested, then we fallback to just
+     * constructing a cairo_format_t instead, (which will fairly
+     * arbitrarily pick a visual/depth for the similar surface.
+     */
+    if (xrender_format == NULL ||
+	! _xrender_format_matches_content (xrender_format, content))
+    {
+	return _cairo_xlib_surface_create_similar_with_format (abstract_src,
+							       _cairo_format_from_content (content),
+							       width, height);
+    }
+
+    /* We've got a compatible XRenderFormat now, which means the
+     * similar surface will match the existing surface as closely in
+     * visual/depth etc. as possible. */
+    pix = XCreatePixmap (src->dpy, RootWindowOfScreen (src->screen),
+			 width <= 0 ? 1 : width, height <= 0 ? 1 : height,
+			 xrender_format->depth);
 
-            return &surface->base;
-        }
+    surface = (cairo_xlib_surface_t *)
+	cairo_xlib_surface_create_with_xrender_format (src->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;
 
-    return _cairo_xlib_surface_create_similar_with_format (abstract_src,
-							   format, width, height);
+    return &surface->base;
 }
 
 static cairo_status_t
diff-tree a96bd2b4f9ab399eee5198c0d27a6cd67798931b (from ea05e027111d5f336b7e3f2170f929b0b1e37692)
Author: Carl Worth <cworth at cworth.org>
Date:   Thu May 18 15:20:25 2006 -0700

    xlib: Rename surface->format to surface->xrender_format to avoid confusion
    
    With both XRenderPictFormat* and cairo_format_t values being manipulated in the same
    functions, this really needed to be done.

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index b92a3f9..0c6ae14 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -116,7 +116,7 @@ struct _cairo_xlib_surface {
     XRectangle *clip_rects;
     int num_clip_rects;
 
-    XRenderPictFormat *format;
+    XRenderPictFormat *xrender_format;
 };
 
 #define CAIRO_SURFACE_RENDER_AT_LEAST(surface, major, minor)	\
@@ -595,12 +595,12 @@ _get_image_surface (cairo_xlib_surface_t
 	masks.red_mask = surface->visual->red_mask;
 	masks.green_mask = surface->visual->green_mask;
 	masks.blue_mask = surface->visual->blue_mask;
-    } else if (surface->format) {
+    } else if (surface->xrender_format) {
 	masks.bpp = ximage->bits_per_pixel;
-	masks.red_mask = (unsigned long)surface->format->direct.redMask << surface->format->direct.red;
-	masks.green_mask = (unsigned long)surface->format->direct.greenMask << surface->format->direct.green;
-	masks.blue_mask = (unsigned long)surface->format->direct.blueMask << surface->format->direct.blue;
-	masks.alpha_mask = (unsigned long)surface->format->direct.alphaMask << surface->format->direct.alpha;
+	masks.red_mask = (unsigned long)surface->xrender_format->direct.redMask << surface->xrender_format->direct.red;
+	masks.green_mask = (unsigned long)surface->xrender_format->direct.greenMask << surface->xrender_format->direct.green;
+	masks.blue_mask = (unsigned long)surface->xrender_format->direct.blueMask << surface->xrender_format->direct.blue;
+	masks.alpha_mask = (unsigned long)surface->xrender_format->direct.alphaMask << surface->xrender_format->direct.alpha;
     } else {
 	masks.bpp = ximage->bits_per_pixel;
 	masks.red_mask = 0;
@@ -664,7 +664,7 @@ _cairo_xlib_surface_ensure_src_picture (
     if (!surface->src_picture)
 	surface->src_picture = XRenderCreatePicture (surface->dpy, 
 						     surface->drawable, 
-						     surface->format,
+						     surface->xrender_format,
 						     0, NULL);
 }
 	
@@ -694,7 +694,7 @@ _cairo_xlib_surface_ensure_dst_picture (
     if (!surface->dst_picture) {
 	surface->dst_picture = XRenderCreatePicture (surface->dpy, 
 						     surface->drawable, 
-						     surface->format,
+						     surface->xrender_format,
 						     0, NULL);
 	_cairo_xlib_surface_set_picture_clip_rects (surface);
     }
@@ -1014,7 +1014,7 @@ _surfaces_compatible (cairo_xlib_surface
 	return FALSE;
 
     /* if Render is supported, match picture formats */
-    if (src->format != NULL && src->format == dst->format)
+    if (src->xrender_format != NULL && src->xrender_format == dst->xrender_format)
 	return TRUE;
     
     /* Without Render, match visuals instead */
@@ -1027,9 +1027,9 @@ _surfaces_compatible (cairo_xlib_surface
 static cairo_bool_t
 _surface_has_alpha (cairo_xlib_surface_t *surface)
 {
-    if (surface->format) {
-	if (surface->format->type == PictTypeDirect &&
-	    surface->format->direct.alphaMask != 0)
+    if (surface->xrender_format) {
+	if (surface->xrender_format->type == PictTypeDirect &&
+	    surface->xrender_format->direct.alphaMask != 0)
 	    return TRUE;
 	else
 	    return FALSE;
@@ -1632,7 +1632,7 @@ _cairo_xlib_surface_set_clip_region (voi
 	if (surface->gc)
 	    XSetClipMask (surface->dpy, surface->gc, None);
 	
-	if (surface->format && surface->dst_picture) {
+	if (surface->xrender_format && surface->dst_picture) {
 	    XRenderPictureAttributes pa;
 	    pa.clip_mask = None;
 	    XRenderChangePicture (surface->dpy, surface->dst_picture,
@@ -1851,7 +1851,7 @@ _cairo_xlib_surface_create_internal (Dis
     }
 
     surface->visual = visual;
-    surface->format = format;
+    surface->xrender_format = format;
     surface->depth = depth;
 
     surface->have_clip_rects = FALSE;
@@ -2565,7 +2565,7 @@ _cairo_xlib_surface_old_show_glyphs (cai
     int i;
     unsigned long max_index = 0;
     
-    if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE_TEXT (self) || !self->format)
+    if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE_TEXT (self) || !self->xrender_format)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     operation = _categorize_composite_operation (self, op, pattern, TRUE);


More information about the cairo-commit mailing list