[cairo-commit] 6 commits - configure.in src/cairo.c src/cairo-image-surface.c src/cairoint.h src/cairo-surface.c src/cairo-surface-fallback.c src/cairo-xlib-surface.c

Carl Worth cworth at kemper.freedesktop.org
Tue Mar 25 17:27:27 PDT 2008


 configure.in                 |    2 
 src/cairo-image-surface.c    |  203 ++++++++++++++++++-------------------------
 src/cairo-surface-fallback.c |    4 
 src/cairo-surface.c          |   18 +++
 src/cairo-xlib-surface.c     |   25 -----
 src/cairo.c                  |   14 ++
 src/cairoint.h               |   21 ++++
 7 files changed, 144 insertions(+), 143 deletions(-)

New commits:
commit 6dc75ab0f8370154aae7719ed805c5a8bdf1c9f4
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Mar 25 10:21:50 2008 -0700

    Quiet compiler warnings about unhandled PIXMAN_yuy2 and PIXMAN_yv12
    
    We still don't handle these format codes of course, (they're meaningless
    for the context in which they're used here).
    
    Note that we previously avoided adding these to avoid people being forced
    to upgrade pixman just to get two enum values that cairo doesn't really
    care about. But now we're depending on a new pixman anyway, (for the
    pixman_format_code_to_masks function), so we'll go ahead and do this now.

diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index fdc835a..e8fc4d5 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -59,6 +59,7 @@ _cairo_format_from_pixman_format (pixman_format_code_t pixman_format)
     case PIXMAN_a4:       case PIXMAN_r1g2b1:   case PIXMAN_b1g2r1:
     case PIXMAN_a1r1g1b1: case PIXMAN_a1b1g1r1: case PIXMAN_c4:
     case PIXMAN_g4:       case PIXMAN_g1:
+    case PIXMAN_yuy2:     case PIXMAN_yv12:
     default:
 	return CAIRO_FORMAT_INVALID;
     }
@@ -100,6 +101,8 @@ _cairo_content_from_pixman_format (pixman_format_code_t pixman_format)
     case PIXMAN_c4:
     case PIXMAN_g4:
     case PIXMAN_g1:
+    case PIXMAN_yuy2:
+    case PIXMAN_yv12:
 	return CAIRO_CONTENT_COLOR;
     case PIXMAN_a8:
     case PIXMAN_a1:
commit 1675713aff7311461e26d7badccb9942573f2bca
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Mar 25 16:45:21 2008 -0700

    Depend on pixman 0.9.7 for new pixman_format_supported_destination function
    
    This allows us to do a much more general and complete implementation of
    _pixman_format_from_masks and _pixman_format_to_masks so that we'll
    even pick up new pixman formats as they get added.

diff --git a/configure.in b/configure.in
index e314115..6d5756a 100644
--- a/configure.in
+++ b/configure.in
@@ -299,7 +299,7 @@ CAIRO_LIBS=$CAIRO_NONPKGCONFIG_LIBS
 
 dnl ===========================================================================
 
-PIXMAN_VERSION="0.9.6"
+PIXMAN_VERSION="0.9.7"
 PIXMAN_REQUIRES="pixman-1 >= $PIXMAN_VERSION"
 PKG_CHECK_MODULES(pixman, $PIXMAN_REQUIRES, ,
 	[AC_MSG_ERROR([pixman >= $PIXMAN_VERSION is required
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index d6f2595..fdc835a 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -141,132 +141,102 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t		*pixman_image,
     return &surface->base;
 }
 
-/* XXX: This function should really live inside pixman. */
 cairo_int_status_t
 _pixman_format_from_masks (cairo_format_masks_t *masks,
-			   pixman_format_code_t	*format_ret)
+			   pixman_format_code_t *format_ret)
 {
-    switch (masks->bpp) {
-    case 32:
-	if (masks->alpha_mask == 0xff000000 &&
-	    masks->red_mask   == 0x00ff0000 &&
-	    masks->green_mask == 0x0000ff00 &&
-	    masks->blue_mask  == 0x000000ff)
-	{
-	    *format_ret = PIXMAN_a8r8g8b8;
-	    return CAIRO_STATUS_SUCCESS;
-	}
-	if (masks->alpha_mask == 0x00000000 &&
-	    masks->red_mask   == 0x00ff0000 &&
-	    masks->green_mask == 0x0000ff00 &&
-	    masks->blue_mask  == 0x000000ff)
-	{
-	    *format_ret = PIXMAN_x8r8g8b8;
-	    return CAIRO_STATUS_SUCCESS;
-	}
-	if (masks->alpha_mask == 0xff000000 &&
-	    masks->red_mask   == 0x000000ff &&
-	    masks->green_mask == 0x0000ff00 &&
-	    masks->blue_mask  == 0x00ff0000)
-	{
-	    *format_ret = PIXMAN_a8b8g8r8;
-	    return CAIRO_STATUS_SUCCESS;
-	}
-	if (masks->alpha_mask == 0x00000000 &&
-	    masks->red_mask   == 0x000000ff &&
-	    masks->green_mask == 0x0000ff00 &&
-	    masks->blue_mask  == 0x00ff0000)
-	{
-	    *format_ret = PIXMAN_x8b8g8r8;
-	    return CAIRO_STATUS_SUCCESS;
-	}
-	break;
-    case 16:
-	if (masks->alpha_mask == 0x0000 &&
-	    masks->red_mask   == 0xf800 &&
-	    masks->green_mask == 0x07e0 &&
-	    masks->blue_mask  == 0x001f)
-	{
-	    *format_ret = PIXMAN_r5g6b5;
-	    return CAIRO_STATUS_SUCCESS;
-	}
-	if (masks->alpha_mask == 0x0000 &&
-	    masks->red_mask   == 0x7c00 &&
-	    masks->green_mask == 0x03e0 &&
-	    masks->blue_mask  == 0x001f)
-	{
-	    *format_ret = PIXMAN_x1r5g5b5;
-	    return CAIRO_STATUS_SUCCESS;
-	}
-	break;
-    case 8:
-	if (masks->alpha_mask == 0xff)
-	{
-	    *format_ret = PIXMAN_a8;
-	    return CAIRO_STATUS_SUCCESS;
-	}
-	break;
-    case 1:
-	if (masks->alpha_mask == 0x1)
-	{
-	    *format_ret = PIXMAN_a1;
-	    return CAIRO_STATUS_SUCCESS;
-	}
-	break;
+    pixman_format_code_t format;
+    int format_type;
+    uint32_t color_masks;
+    int a, r, g, b;
+    cairo_format_masks_t format_masks;
+
+    a = _cairo_popcount (masks->alpha_mask);
+    r = _cairo_popcount (masks->red_mask);
+    g = _cairo_popcount (masks->green_mask);
+    b = _cairo_popcount (masks->blue_mask);
+
+    if (masks->red_mask) {
+	if (masks->red_mask > masks->blue_mask)
+	    format_type = PIXMAN_TYPE_ARGB;
+	else
+	    format_type = PIXMAN_TYPE_ABGR;
+    } else if (masks->alpha_mask) {
+	format_type = PIXMAN_TYPE_A;
+    } else {
+	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
-    return CAIRO_INT_STATUS_UNSUPPORTED;
-}
-
-/* XXX: This function should really live inside pixman. */
-void
-_pixman_format_to_masks (pixman_format_code_t	 pixman_format,
-			 cairo_format_masks_t	*masks)
-{
-    masks->red_mask   = 0x0;
-    masks->green_mask = 0x0;
-    masks->blue_mask  = 0x0;
+    format = PIXMAN_FORMAT (masks->bpp, format_type, a, r, g, b);
 
-    switch (pixman_format)
-    {
-    case PIXMAN_a8r8g8b8:
-    case PIXMAN_x8r8g8b8:
-    default:
-	masks->bpp        = 32;
-	masks->red_mask   = 0x00ff0000;
-	masks->green_mask = 0x0000ff00;
-	masks->blue_mask  = 0x000000ff;
-	break;
+    if (! pixman_format_supported_destination (format))
+	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    case PIXMAN_a8b8g8r8:
-    case PIXMAN_x8b8g8r8:
-	masks->bpp        = 32;
-	masks->red_mask   = 0x000000ff;
-	masks->green_mask = 0x0000ff00;
-	masks->blue_mask  = 0x00ff0000;
-	break;
+    /* Sanity check that we got out of PIXMAN_FORMAT exactly what we
+     * expected. This avoid any problems from something bizarre like
+     * alpha in the least-significant bits, or insane channel order,
+     * or whatever. */
+     _pixman_format_to_masks (format, &format_masks);
 
-    case PIXMAN_r5g6b5:
-	masks->bpp        = 16;
-	masks->red_mask   = 0xf800;
-	masks->green_mask = 0x07e0;
-	masks->blue_mask  = 0x001f;
-	break;
+     if (masks->bpp        != format_masks.bpp        ||
+	 masks->red_mask   != format_masks.red_mask   ||
+	 masks->green_mask != format_masks.green_mask ||
+	 masks->blue_mask  != format_masks.blue_mask)
+     {
+	 return CAIRO_INT_STATUS_UNSUPPORTED;
+     }
 
-    case PIXMAN_x1r5g5b5:
-	masks->bpp        = 16;
-	masks->red_mask   = 0x7c00;
-	masks->green_mask = 0x03e0;
-	masks->blue_mask  = 0x001f;
-	break;
+    *format_ret = format;
+    return CAIRO_STATUS_SUCCESS;
+}
 
-    case PIXMAN_a8:
-	masks->bpp = 8;
-	break;
+/* A mask consisting of N bits set to 1. */
+#define MASK(N) ((1 << (N))-1)
 
-    case PIXMAN_a1:
-	masks->bpp = 1;
-	break;
+void
+_pixman_format_to_masks (pixman_format_code_t	 format,
+			 cairo_format_masks_t	*masks)
+{
+    int a, r, g, b;
+
+    masks->bpp = PIXMAN_FORMAT_BPP (format);
+
+    /* Number of bits in each channel */
+    a = PIXMAN_FORMAT_A (format);
+    r = PIXMAN_FORMAT_R (format);
+    g = PIXMAN_FORMAT_G (format);
+    b = PIXMAN_FORMAT_B (format);
+
+    switch (PIXMAN_FORMAT_TYPE (format)) {
+    case PIXMAN_TYPE_ARGB:
+        masks->alpha_mask = MASK (a) << (r + g + b);
+        masks->red_mask   = MASK (r) << (g + b);
+        masks->green_mask = MASK (g) << (b);
+        masks->blue_mask  = MASK (b);
+        return;
+    case PIXMAN_TYPE_ABGR:
+        masks->alpha_mask = MASK (a) << (b + g + r);
+        masks->blue_mask  = MASK (b) << (g +r);
+        masks->green_mask = MASK (g) << (r);
+        masks->red_mask   = MASK (r);
+        return;
+    case PIXMAN_TYPE_A:
+        masks->alpha_mask = MASK (a);
+        masks->red_mask   = 0;
+        masks->green_mask = 0;
+        masks->blue_mask  = 0;
+        return;
+    case PIXMAN_TYPE_OTHER:
+    case PIXMAN_TYPE_COLOR:
+    case PIXMAN_TYPE_GRAY:
+    case PIXMAN_TYPE_YUY2:
+    case PIXMAN_TYPE_YV12:
+    default:
+        masks->alpha_mask = 0;
+        masks->red_mask   = 0;
+        masks->green_mask = 0;
+        masks->blue_mask  = 0;
+        return;
     }
 }
 
commit d7e5f6b6a00912e22cb5ca837d0a56d30cf59124
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Mar 25 16:32:24 2008 -0700

    Rename _popcount to _cairo_popcount and make it available for internal use
    
    Both cairo-image-surface.c and cairo-xlib-surface.c want to
    use this function now.

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 5df69f8..9e8776a 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -455,36 +455,15 @@ _swap_ximage_to_native (XImage *ximage)
     }
 }
 
-/* Return the number of 1 bits in mask.
- *
- * GCC 3.4 supports a "population count" builtin, which on many targets is
- * implemented with a single instruction. There is a fallback definition
- * in libgcc in case a target does not have one, which should be just as
- * good as the open-coded solution below, (which is "HACKMEM 169").
- */
-static inline int
-_popcount (uint32_t mask)
-{
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
-    return __builtin_popcount (mask);
-#else
-    register int y;
-
-    y = (mask >> 1) &033333333333;
-    y = mask - y - ((y >>1) & 033333333333);
-    return (((y + (y >> 3)) & 030707070707) % 077);
-#endif
-}
-
 /* Given a mask, (with a single sequence of contiguous 1 bits), return
  * the number of 1 bits in 'width' and the number of 0 bits to its
  * right in 'shift'. */
 static inline void
 _characterize_field (uint32_t mask, int *width, int *shift)
 {
-    *width = _popcount (mask);
+    *width = _cairo_popcount (mask);
     /* The final '& 31' is to force a 0 mask to result in 0 shift. */
-    *shift = _popcount ((mask - 1) & ~mask) & 31;
+    *shift = _cairo_popcount ((mask - 1) & ~mask) & 31;
 }
 
 /* Convert a field of 'width' bits to 'new_width' bits with correct
diff --git a/src/cairoint.h b/src/cairoint.h
index 5ab213d..ea47ed5 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -140,6 +140,27 @@ do {					\
  */
 #define CAIRO_BITSWAP8(c) ((((c) * 0x0802LU & 0x22110LU) | ((c) * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16)
 
+/* Return the number of 1 bits in mask.
+ *
+ * GCC 3.4 supports a "population count" builtin, which on many targets is
+ * implemented with a single instruction. There is a fallback definition
+ * in libgcc in case a target does not have one, which should be just as
+ * good as the open-coded solution below, (which is "HACKMEM 169").
+ */
+static inline int
+_cairo_popcount (uint32_t mask)
+{
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+    return __builtin_popcount (mask);
+#else
+    register int y;
+
+    y = (mask >> 1) &033333333333;
+    y = mask - y - ((y >>1) & 033333333333);
+    return (((y + (y >> 3)) & 030707070707) % 077);
+#endif
+}
+
 #ifdef WORDS_BIGENDIAN
 #define CAIRO_BITSWAP8_IF_LITTLE_ENDIAN(c) (c)
 #else
commit 90cf7c2faf167b4b86443eb340af23cf853b146a
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Mar 25 10:40:01 2008 -0700

    Quiet warning about signed vs. unsigned comparison

diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index f9f5b04..f84be7a 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -1151,9 +1151,9 @@ _cairo_surface_fallback_fill_rectangles (cairo_surface_t         *surface,
 	if (rects[i].y < y1)
 	    y1 = rects[i].y;
 
-	if (rects[i].x + rects[i].width > x2)
+	if ((int)(rects[i].x + rects[i].width) > x2)
 	    x2 = rects[i].x + rects[i].width;
-	if (rects[i].y + rects[i].height > y2)
+	if ((int)(rects[i].y + rects[i].height) > y2)
 	    y2 = rects[i].y + rects[i].height;
     }
 
commit 770633c05acf12b911cdbdaa94b20ccf34ce742a
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Mar 25 10:27:36 2008 -0700

    Quiet warnings about unhandled enum values in _cairo_surface_create_in_error

diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 42ee3ec..23e79d2 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -2487,6 +2487,24 @@ _cairo_surface_create_in_error (cairo_status_t status)
 	return (cairo_surface_t *) &_cairo_surface_nil_temp_file_error;
     case CAIRO_STATUS_INVALID_STRIDE:
 	return (cairo_surface_t *) &_cairo_surface_nil_invalid_stride;
+    case CAIRO_STATUS_SUCCESS:
+	ASSERT_NOT_REACHED;
+	/* fall-through */
+    case CAIRO_STATUS_INVALID_RESTORE:
+    case CAIRO_STATUS_INVALID_POP_GROUP:
+    case CAIRO_STATUS_NO_CURRENT_POINT:
+    case CAIRO_STATUS_INVALID_MATRIX:
+    case CAIRO_STATUS_INVALID_STATUS:
+    case CAIRO_STATUS_NULL_POINTER:
+    case CAIRO_STATUS_INVALID_STRING:
+    case CAIRO_STATUS_INVALID_PATH_DATA:
+    case CAIRO_STATUS_SURFACE_FINISHED:
+    case CAIRO_STATUS_SURFACE_TYPE_MISMATCH:
+    case CAIRO_STATUS_PATTERN_TYPE_MISMATCH:
+    case CAIRO_STATUS_INVALID_DASH:
+    case CAIRO_STATUS_INVALID_DSC_COMMENT:
+    case CAIRO_STATUS_INVALID_INDEX:
+    case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE:
     default:
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t *) &_cairo_surface_nil;
commit d15c7c94bdfc714845bd88f9e3ed5317afcfce72
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Mar 25 12:12:40 2008 -0700

    Document performance advantage of cairo_path_extents
    
    The cairo_path_extents function can perform better than either
    cairo_stroke_extents or cairo_fill_extents, so provide that
    pointer from the documentation of the other two functions.

diff --git a/src/cairo.c b/src/cairo.c
index a0fbb49..8f82cb6 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -2299,6 +2299,11 @@ cairo_in_fill (cairo_t *cr, double x, double y)
  * cairo_path_extents() which can be used to compute the non-empty
  * bounds as the line width approaches zero.
  *
+ * Note that cairo_stroke_extents must necessarily do more work to
+ * compute the precise inked areas in light of the stroke parameters,
+ * so cairo_path_extents() may be more desirable for sake of
+ * performance if non-inked path extents are desired.
+ *
  * See cairo_stroke(), cairo_set_line_width(), cairo_set_line_join(),
  * cairo_set_line_cap(), cairo_set_dash(), and
  * cairo_stroke_preserve().
@@ -2344,8 +2349,13 @@ cairo_stroke_extents (cairo_t *cr,
  * dimensions and clipping are not taken into account.
  *
  * Contrast with cairo_path_extents(), which is similar, but returns
- * non-zero extents for some paths no inked area, (such as a simple
- * line segment).
+ * non-zero extents for some paths with no inked area, (such as a
+ * simple line segment).
+ *
+ * Note that cairo_fill_extents must necessarily do more work to
+ * compute the precise inked areas in light of the fill rule, so
+ * cairo_path_extents() may be more desirable for sake of performance
+ * if the non-inked path extents are desired.
  *
  * See cairo_fill(), cairo_set_fill_rule() and cairo_fill_preserve().
  **/


More information about the cairo-commit mailing list