[cairo-commit] Branch '1.0' - 6 commits - pixman/src src/cairoint.h src/cairo-wideint.c src/cairo-wideint.h src/cairo-win32-private.h src/cairo-win32-surface.c

Behdad Esfahbod behdad at kemper.freedesktop.org
Wed Mar 15 08:58:00 PST 2006


 pixman/src/fbcompose.c    |   10 ++
 pixman/src/pixregion.c    |    6 -
 src/cairo-wideint.c       |    3 
 src/cairo-wideint.h       |    3 
 src/cairo-win32-private.h |    2 
 src/cairo-win32-surface.c |  166 ++++++++++++++++++++++++++++------------------
 src/cairoint.h            |    4 +
 7 files changed, 123 insertions(+), 71 deletions(-)

New commits:
diff-tree ba5b30117b076193f5f113be468eec0d951fd919 (from 9acc981e440bdf370aee25cc5ea2b836db0886b1)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Feb 27 17:07:22 2006 -0800

    Remove unused RCS $Id:$ tags.
    (cherry picked from f2245a7932b857ff70dc0476490090d906ae61f8 commit)

diff --git a/src/cairo-wideint.c b/src/cairo-wideint.c
index 9e4914e..89df00b 100644
--- a/src/cairo-wideint.c
+++ b/src/cairo-wideint.c
@@ -1,5 +1,4 @@
-/*
- * $Id: cairo-wideint.c,v 1.6 2005-07-30 19:57:54 keithp Exp $
+/* cairo - a vector graphics library with display and print output
  *
  * Copyright © 2004 Keith Packard
  *
diff --git a/src/cairo-wideint.h b/src/cairo-wideint.h
index b008b5d..795cde7 100644
--- a/src/cairo-wideint.h
+++ b/src/cairo-wideint.h
@@ -1,5 +1,4 @@
-/*
- * $Id: cairo-wideint.h,v 1.12 2005-08-05 14:48:19 cworth Exp $
+/* cairo - a vector graphics library with display and print output
  *
  * Copyright © 2004 Keith Packard
  *
diff-tree 9acc981e440bdf370aee25cc5ea2b836db0886b1 (from ec4b006c162292ea3b2719dc18a4a3bd40a971ab)
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date:   Fri Feb 17 23:37:54 2006 -0800

    Win32: Handle BitBlt in get_image failure and AlphaBlend not being supported
    
    If the BitBlt in get_image fails, we pretty much can't do anything -- so
    fill the destination with white and hope for the best.  This enables
    somewhat accurate printing of complex operations.  Also, check the
    destination device caps before calling AlphaBlend; return UNSUPPORTED if
    the destination DC can't do AlphaBlend.
    (cherry picked from 9831de538e347a624af5b0ca38242b198b64bd45 commit)
    (cherry picked from 1a1441912604c89e2912ec764fe26b7a9db995a3 commit)

diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index 84105e5..b00251c 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -385,8 +385,18 @@ _cairo_win32_surface_get_subimage (cairo
 		 width, height,
 		 surface->dc,
 		 x, y,
-		 SRCCOPY))
-	goto FAIL;
+		 SRCCOPY)) {
+	/* If we fail to BitBlt here, most likely the source is a printer.
+	 * You can't reliably get bits from a printer DC, so just fill in
+	 * the surface as white (common case for printing).
+	 */
+
+	RECT r;
+	r.left = r.top = 0;
+	r.right = width;
+	r.bottom = height;
+	FillRect(local->dc, &r, (HBRUSH)GetStockObject(WHITE_BRUSH));
+    }
 
     *local_out = local;
     
@@ -601,6 +611,8 @@ _composite_alpha_blend (cairo_win32_surf
 
     if (alpha_blend == NULL)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
+    if (GetDeviceCaps(dst->dc, SHADEBLENDCAPS) == SB_NONE)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
     
     blend_function.BlendOp = AC_SRC_OVER;
     blend_function.BlendFlags = 0;
@@ -934,7 +946,7 @@ _cairo_win32_surface_set_clip_region (vo
 	    return CAIRO_STATUS_NO_MEMORY;
 
 	/* Combine the new region with the original clip */
-	    
+
 	if (surface->saved_clip) {
 	    if (CombineRgn (gdi_region, gdi_region, surface->saved_clip, RGN_AND) == ERROR)
 		goto FAIL;
diff-tree ec4b006c162292ea3b2719dc18a4a3bd40a971ab (from d7b280a3add4ec84670e56a85b2a256225b21d0d)
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date:   Fri Feb 17 23:34:51 2006 -0800

    Win32: Set surface format based on device caps
    
    If the DC is a display DC, inspect its depth and set out local format
    appropriately.  If it's not a display DC, assume RGB24.
    (cherry picked from 6dd0a70d271f93df95f4bcaff5073b9bf90cecb6 commit)
    (cherry picked from 2d784815ffac1ca8c10dac12525f2e8d0b412c1a commit)

diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index 66fc1c4..84105e5 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -31,6 +31,8 @@
  *
  * Contributor(s):
  *	Owen Taylor <otaylor at redhat.com>
+ *	Stuart Parmenter <stuart at mozilla.com>
+ *	Vladimir Vukicevic <vladimir at pobox.com>
  */
 
 #include <stdio.h>
@@ -973,6 +975,8 @@ cairo_win32_surface_create (HDC hdc)
 {
     cairo_win32_surface_t *surface;
     RECT rect;
+    int depth;
+    cairo_format_t format;
 
     /* Try to figure out the drawing bounds for the Device context
      */
@@ -982,7 +986,26 @@ cairo_win32_surface_create (HDC hdc)
 	_cairo_error (CAIRO_STATUS_NO_MEMORY);
 	return &_cairo_surface_nil;
     }
-    
+
+    if (GetDeviceCaps(hdc, TECHNOLOGY) == DT_RASDISPLAY) {
+	depth = GetDeviceCaps(hdc, BITSPIXEL);
+	if (depth == 32)
+	    format = CAIRO_FORMAT_ARGB32;
+	else if (depth == 24)
+	    format = CAIRO_FORMAT_RGB24;
+	else if (depth == 8)
+	    format = CAIRO_FORMAT_A8;
+	else if (depth == 1)
+	    format = CAIRO_FORMAT_A1;
+	else {
+	    _cairo_win32_print_gdi_error("cairo_win32_surface_create(bad BITSPIXEL)");
+	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    return &_cairo_surface_nil;
+	}
+    } else {
+	format = CAIRO_FORMAT_RGB24;
+    }
+
     surface = malloc (sizeof (cairo_win32_surface_t));
     if (surface == NULL) {
 	_cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -990,7 +1013,7 @@ cairo_win32_surface_create (HDC hdc)
     }
 
     surface->image = NULL;
-    surface->format = CAIRO_FORMAT_RGB24;
+    surface->format = format;
     
     surface->dc = hdc;
     surface->bitmap = NULL;
diff-tree d7b280a3add4ec84670e56a85b2a256225b21d0d (from b07f042861602812ca02e01f566026256ba075db)
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date:   Fri Feb 17 23:24:06 2006 -0800

    Win32: Fix up src coords before calling AlphaBlend/BitBlt to avoid invalid calls
    
    Fixes up src coords and width/height before calling AlphaBlend/BitBlt; it's
    an error to try to use a region that extents outside of the source surface
    as a source DC.
    
    Doesn't repair the extra region relative to the operator -- e.g. regions
    outside of an ARGB source surface with SOURCE operator should be cleared
    to fully transparent black in the destination.
    (cherry picked from bc19c5b64b0e38e9d20045907d7b47d79f6afc60 commit)
    (cherry picked from 68ed40b6da242816a43cd68cc2c7feb779cf0acf commit)

diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index df7ec41..66fc1c4 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -664,6 +664,33 @@ _cairo_win32_surface_composite (cairo_op
     if (!integer_transform)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
+    /* Fix up src coordinates; the src coords and size must be within the
+     * bounds of the source surface.
+     * XXX the region not covered should be appropriately rendered!
+     * - for OVER/SOURCE with RGB24 source -> opaque black
+     * - for SOURCE with ARGB32 source -> 100% transparent black
+     */
+    src_x += itx;
+    src_y += ity;
+
+    if (src_x < 0) {
+        width += src_x;
+        dst_x -= src_x;
+        src_x = 0;
+    }
+
+    if (src_y < 0) {
+        height += src_y;
+        dst_y -= src_y;
+        src_y = 0;
+    }
+
+    if (src_x + width > src->extents.width)
+        width = src->extents.width - src_x;
+
+    if (src_y + height > src->extents.height)
+        height = src->extents.height - src_y;
+
     if (alpha == 255 &&
 	src->format == dst->format &&
 	(operator == CAIRO_OPERATOR_SOURCE ||
@@ -673,7 +700,7 @@ _cairo_win32_surface_composite (cairo_op
 		     dst_x, dst_y,
 		     width, height,
 		     src->dc,
-		     src_x + itx, src_y + ity,
+		     src_x, src_y,
 		     SRCCOPY))
 	    return _cairo_win32_print_gdi_error ("_cairo_win32_surface_composite");
 
@@ -685,7 +712,7 @@ _cairo_win32_surface_composite (cairo_op
 	       operator == CAIRO_OPERATOR_OVER) {
 
 	return _composite_alpha_blend (dst, src, alpha,
-				       src_x + itx, src_y + ity,
+				       src_x, src_y,
 				       dst_x, dst_y, width, height);
     }
     
diff-tree b07f042861602812ca02e01f566026256ba075db (from 5cbf914770cc01060fae1abe8cdda9b915352845)
Author: Vladimir Vukicevic <vladimir at h\-216.office.mozilla.org>
Date:   Wed Feb 15 12:43:01 2006 -0800

    Win32: Rework clip and extents handling
    
    - Save extents at surface creation and always return these
    - Simplify clipping paths
    (cherry picked from a67722b3d7280e6c2375778c2d46556cca261bfc commit)
    (cherry picked from 7ce09732a978749a4da814feb77f50161dc42c91 commit)
    (cherry picked from e0f4eecb91c8f7f09ef4977703d4ca21b06797a9 commit)

diff --git a/src/cairo-win32-private.h b/src/cairo-win32-private.h
index a229147..b3143c9 100644
--- a/src/cairo-win32-private.h
+++ b/src/cairo-win32-private.h
@@ -62,9 +62,9 @@ typedef struct _cairo_win32_surface {
     
     cairo_rectangle_t clip_rect;
 
-    int set_clip;
     HRGN saved_clip;
 
+    cairo_rectangle_t extents;
 } cairo_win32_surface_t;
 
 cairo_status_t
diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index 9286ea5..df7ec41 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -274,9 +274,14 @@ _cairo_win32_surface_create_for_dc (HDC 
     surface->clip_rect.width = width;
     surface->clip_rect.height = height;
 
-    surface->set_clip = 0;
-    surface->saved_clip = NULL;
-    
+    surface->saved_clip = CreateRectRgn (0, 0, 0, 0);
+    if (GetClipRgn (surface->dc, surface->saved_clip) == 0) {
+        DeleteObject(surface->saved_clip);
+        surface->saved_clip = NULL;
+    }
+
+    surface->extents = surface->clip_rect;
+
     _cairo_surface_init (&surface->base, &cairo_win32_surface_backend);
 
     return (cairo_surface_t *)surface;
@@ -340,9 +345,8 @@ _cairo_win32_surface_finish (void *abstr
     if (surface->image)
 	cairo_surface_destroy (surface->image);
 
-    if (surface->saved_clip) {
+    if (surface->saved_clip)
 	DeleteObject (surface->saved_clip);
-    }
 
     /* If we created the Bitmap and DC, destroy them */
     if (surface->bitmap) {
@@ -403,7 +407,7 @@ _cairo_win32_surface_acquire_source_imag
     cairo_win32_surface_t *surface = abstract_surface;
     cairo_win32_surface_t *local = NULL;
     cairo_status_t status;
-        
+
     if (surface->image) {
 	*image_out = (cairo_image_surface_t *)surface->image;
 	*image_extra = NULL;
@@ -446,7 +450,7 @@ _cairo_win32_surface_acquire_dest_image 
     cairo_status_t status;
     RECT clip_box;
     int x1, y1, x2, y2;
-        
+
     if (surface->image) {
 	image_rect->x = 0;
 	image_rect->y = 0;
@@ -461,12 +465,12 @@ _cairo_win32_surface_acquire_dest_image 
 
     if (GetClipBox (surface->dc, &clip_box) == ERROR)
 	return _cairo_win32_print_gdi_error ("_cairo_win3_surface_acquire_dest_image");
-    
+
     x1 = clip_box.left;
     x2 = clip_box.right;
     y1 = clip_box.top;
     y2 = clip_box.bottom;
-    
+
     if (interest_rect->x > x1)
 	x1 = interest_rect->x;
     if (interest_rect->y > y1)
@@ -855,19 +859,9 @@ _cairo_win32_surface_set_clip_region (vo
 
     if (region == NULL) {
 	/* Clear any clip set by cairo, return to the original */
-	
-	if (surface->set_clip) {
-	    if (SelectClipRgn (surface->dc, surface->saved_clip) == ERROR)
-		return _cairo_win32_print_gdi_error ("_cairo_win32_surface_set_clip_region");
-
-	    if (surface->saved_clip) {
-		DeleteObject (surface->saved_clip);
-		surface->saved_clip = NULL;
-	    }
+	if (SelectClipRgn (surface->dc, surface->saved_clip) == ERROR)
+	    return _cairo_win32_print_gdi_error ("_cairo_win32_surface_set_clip_region (reset)");
 
-	    surface->set_clip = 0;
-	}
-	    
 	return CAIRO_STATUS_SUCCESS;
     
     } else {
@@ -910,36 +904,16 @@ _cairo_win32_surface_set_clip_region (vo
 	if (!gdi_region)
 	    return CAIRO_STATUS_NO_MEMORY;
 
-	if (surface->set_clip) {
-	    /* Combine the new region with the original clip */
+	/* Combine the new region with the original clip */
 	    
-	    if (surface->saved_clip) {
-		if (CombineRgn (gdi_region, gdi_region, surface->saved_clip, RGN_AND) == ERROR)
-		    goto FAIL;
-	    }
-
-	    if (SelectClipRgn (surface->dc, gdi_region) == ERROR)
+	if (surface->saved_clip) {
+	    if (CombineRgn (gdi_region, gdi_region, surface->saved_clip, RGN_AND) == ERROR)
 		goto FAIL;
-		
-	} else {
-	    /* Save the the current region */
-
-	    surface->saved_clip = CreateRectRgn (0, 0, 0, 0);
-	    if (!surface->saved_clip) {
-		goto FAIL;	    }
-
-	    /* This function has no error return! */
-	    if (GetClipRgn (surface->dc, surface->saved_clip) == 0) { /* No clip */
-		DeleteObject (surface->saved_clip);
-		surface->saved_clip = NULL;
-	    }
-		
-	    if (ExtSelectClipRgn (surface->dc, gdi_region, RGN_AND) == ERROR)
-		goto FAIL;
-
-	    surface->set_clip = 1;
 	}
 
+	if (SelectClipRgn (surface->dc, gdi_region) == ERROR)
+	    goto FAIL;
+
 	DeleteObject (gdi_region);
 	return CAIRO_STATUS_SUCCESS;
 
@@ -955,15 +929,8 @@ _cairo_win32_surface_get_extents (void		
 				  cairo_rectangle_t *rectangle)
 {
     cairo_win32_surface_t *surface = abstract_surface;
-    RECT clip_box;
 
-    if (GetClipBox (surface->dc, &clip_box) == ERROR)
-	return _cairo_win32_print_gdi_error ("_cairo_win3_surface_acquire_dest_image");
-
-    rectangle->x = clip_box.left;
-    rectangle->y = clip_box.top;
-    rectangle->width  = clip_box.right  - clip_box.left;
-    rectangle->height = clip_box.bottom - clip_box.top;
+    *rectangle = surface->extents;
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -1007,8 +974,19 @@ cairo_win32_surface_create (HDC hdc)
     surface->clip_rect.width = rect.right - rect.left;
     surface->clip_rect.height = rect.bottom - rect.top;
 
-    surface->set_clip = 0;
-    surface->saved_clip = NULL;
+    if (surface->clip_rect.width == 0 ||
+        surface->clip_rect.height == 0)
+    {
+        surface->saved_clip = NULL;
+    } else {
+        surface->saved_clip = CreateRectRgn (0, 0, 0, 0);
+        if (GetClipRgn (hdc, surface->saved_clip) == 0) {
+            DeleteObject(surface->saved_clip);
+            surface->saved_clip = NULL;
+        }
+    }
+
+    surface->extents = surface->clip_rect;
 
     _cairo_surface_init (&surface->base, &cairo_win32_surface_backend);
 
diff-tree 5cbf914770cc01060fae1abe8cdda9b915352845 (from e78c945b6149a5b209be775d8b240467fbb4cc02)
Author: Behdad Esfahbod <behdad at home.(none)>
Date:   Wed Mar 15 11:49:37 2006 -0500

    Misc compilation fixes (C++-style comments, M_PI decls, etc.)
    (cherry picked from d0cc56b9a24fa59febc15ac5de073da0e785e1cc commit)
    (cherry picked from a6a054abe45287eb950c294e20366594313138f5 commit)
    (cherry picked from f6b4fabaf59227d6cafcdd7e27cf0d8e26b4eeb8 commit)

diff --git a/pixman/src/fbcompose.c b/pixman/src/fbcompose.c
index 4598ab2..c832981 100644
--- a/pixman/src/fbcompose.c
+++ b/pixman/src/fbcompose.c
@@ -33,6 +33,16 @@
 
 #include "pixregionint.h"
 
+#ifdef _MSC_VER
+#define _USE_MATH_DEFINES
+#endif
+
+#include <math.h>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
 /* #define PIXMAN_CONVOLUTION */
 /* #define PIXMAN_GRADIENTS */
 /* #define PIXMAN_INDEXED_FORMATS */
diff --git a/pixman/src/pixregion.c b/pixman/src/pixregion.c
index 9c122f5..e566096 100644
--- a/pixman/src/pixregion.c
+++ b/pixman/src/pixregion.c
@@ -60,7 +60,7 @@ SOFTWARE.
 #endif
 
 #undef assert
-#ifdef DEBUG
+#ifdef DEBUG_PIXREGION
 #define assert(expr) {if (!(expr)) \
 		FatalError("Assertion failed file %s, line %d: expr\n", \
 			__FILE__, __LINE__); }
@@ -208,7 +208,7 @@ if (((numRects) < ((reg)->data->size >> 
 }
 
 
-#ifdef DEBUG
+#ifdef DEBUG_PIXREGION
 int
 pixman_region16_print(rgn)
     pixman_region16_t * rgn;
@@ -302,7 +302,7 @@ pixman_region16_valid(reg)
     }
 }
 
-#endif /* DEBUG */
+#endif /* DEBUG_PIXREGION */
 
 
 /*	Create a new empty region	*/
diff --git a/src/cairoint.h b/src/cairoint.h
index 80132de..4ea1563 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -171,6 +171,10 @@
 #define TRUE 1
 #endif
 
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
 #define ASSERT_NOT_REACHED		\
 do {					\
     static const int NOT_REACHED = 0;	\


More information about the cairo-commit mailing list