[cairo-commit] Changes to 'master'

Vladimir Vukicevic vladimir at kemper.freedesktop.org
Mon Feb 27 14:18:55 PST 2006


 pixman/src/fbcompose.c    |    8 +
 pixman/src/pixregion.c    |    6 -
 src/cairo-atsui-font.c    |   10 +
 src/cairo-surface.c       |   19 +++
 src/cairo-win32-font.c    |    2 
 src/cairo-win32-private.h |    7 -
 src/cairo-win32-surface.c |  246 ++++++++++++++++++++++++++++++----------------
 src/cairo-win32.h         |    8 +
 src/cairoint.h            |    4 
 9 files changed, 215 insertions(+), 95 deletions(-)

New commits:
diff-tree 1a1441912604c89e2912ec764fe26b7a9db995a3 (from 2d784815ffac1ca8c10dac12525f2e8d0b412c1a)
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)

diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index d27185d..c7f4555 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -364,8 +364,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;
     
@@ -580,6 +590,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;
@@ -913,7 +925,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 2d784815ffac1ca8c10dac12525f2e8d0b412c1a (from 68ed40b6da242816a43cd68cc2c7feb779cf0acf)
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)

diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index 57f5aa5..d27185d 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>
@@ -964,6 +966,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
      */
@@ -973,7 +977,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);
@@ -981,7 +1004,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 68ed40b6da242816a43cd68cc2c7feb779cf0acf (from 0852cd449259eb9a52bfa63f19428c47c78baf91)
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)

diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index eb0456d..57f5aa5 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -643,6 +643,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 &&
 	(op == CAIRO_OPERATOR_SOURCE ||
@@ -652,7 +679,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");
 
@@ -664,7 +691,7 @@ _cairo_win32_surface_composite (cairo_op
 	       op == 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 0852cd449259eb9a52bfa63f19428c47c78baf91 (from 0fe8a93d95ab0b2235133fa089be8ec99d1a5248)
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date:   Mon Feb 27 12:49:27 2006 +0100

    Win32: rename cairo_surface_create_dib to cairo_surface_create_with_dib
    
    Also adds some documentation for the win32 creation functions.
    (cherry picked from 3a148bd620d709237d98a72f65118759bfc5a76d commit)

diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c
index 1c9d3bf..841459f 100644
--- a/src/cairo-win32-font.c
+++ b/src/cairo-win32-font.c
@@ -1159,7 +1159,7 @@ _cairo_win32_scaled_font_show_glyphs (vo
 	cairo_surface_pattern_t mask;
 	RECT r;
 
-	tmp_surface = (cairo_win32_surface_t *)cairo_win32_surface_create_dib (CAIRO_FORMAT_ARGB32, width, height);
+	tmp_surface = (cairo_win32_surface_t *)cairo_win32_surface_create_with_dib (CAIRO_FORMAT_ARGB32, width, height);
 	if (tmp_surface->base.status)
 	    return CAIRO_STATUS_NO_MEMORY;
 
diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index 888dadd..eb0456d 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -316,27 +316,6 @@ _cairo_win32_surface_create_similar (voi
     return _cairo_win32_surface_create_for_dc (src->dc, format, width, height);
 }
 
-/**
- * _cairo_win32_surface_create_dib:
- * @format: format of pixels in the surface to create 
- * @width: width of the surface, in pixels
- * @height: height of the surface, in pixels
- * 
- * Creates a device-independent-bitmap surface not associated with
- * any particular existing surface or device context. The created
- * bitmap will be unititialized.
- * 
- * Return value: the newly created surface, or %NULL if it couldn't
- *   be created (probably because of lack of memory)
- **/
-cairo_surface_t *
-cairo_win32_surface_create_dib (cairo_format_t format,
-				int	       width,
-				int	       height)
-{
-    return _cairo_win32_surface_create_for_dc (NULL, format, width, height);
-}
-
 static cairo_status_t
 _cairo_win32_surface_finish (void *abstract_surface)
 {
@@ -941,6 +920,18 @@ _cairo_win32_surface_flush (void *abstra
     return _cairo_surface_reset_clip (abstract_surface);
 }
 
+/**
+ * cairo_win32_surface_create:
+ * @hdc: the DC to create a surface for
+ * 
+ * Creates a cairo surface that targets the given DC.  The DC will be
+ * queried for its initial clip extents, and this will be used as the
+ * size of the cairo surface.  Also, if the DC is a raster DC, it will
+ * be queried for its pixel format and the cairo surface format will
+ * be set appropriately.
+ * 
+ * Return value: the newly created surface
+ **/
 cairo_surface_t *
 cairo_win32_surface_create (HDC hdc)
 {
@@ -994,6 +985,28 @@ cairo_win32_surface_create (HDC hdc)
 }
 
 /**
+ * cairo_win32_surface_create_with_dib:
+ * @format: format of pixels in the surface to create 
+ * @width: width of the surface, in pixels
+ * @height: height of the surface, in pixels
+ * 
+ * Creates a device-independent-bitmap surface not associated with
+ * any particular existing surface or device context. The created
+ * bitmap will be unititialized.
+ * 
+ * Return value: the newly created surface
+ *
+ **/
+cairo_surface_t *
+cairo_win32_surface_create_with_dib (cairo_format_t format,
+                                     int	    width,
+                                     int	    height)
+{
+    return _cairo_win32_surface_create_for_dc (NULL, format, width, height);
+}
+
+
+/**
  * _cairo_surface_is_win32:
  * @surface: a #cairo_surface_t
  * 
diff --git a/src/cairo-win32.h b/src/cairo-win32.h
index a631820..6ba37de 100644
--- a/src/cairo-win32.h
+++ b/src/cairo-win32.h
@@ -48,9 +48,9 @@ cairo_public cairo_surface_t *
 cairo_win32_surface_create (HDC hdc);
 
 cairo_public cairo_surface_t *
-cairo_win32_surface_create_dib (cairo_format_t format,
-				int width,
-				int height);
+cairo_win32_surface_create_with_dib (cairo_format_t format,
+                                     int width,
+                                     int height);
 
 cairo_public HDC
 cairo_win32_surface_get_dc (cairo_surface_t *surface);
diff-tree 0fe8a93d95ab0b2235133fa089be8ec99d1a5248 (from f4b34df6b6c07024a1b552236d8e0db959771b15)
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date:   Fri Feb 17 23:17:23 2006 -0800

    Win32: expose win32 DIB (image) surface creation function, and DC getter
    
    Adds cairo_win32_surface_create_dib() for creating a win32 DIB-backed
    surface with a particular format.  Also exposes
    cairo_win32_surface_get_dc() to obtain the DC of a win32 surface.
    (cherry picked from 0813a1b9b6f35d786fe8cb0d4748771023956cde commit)

diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c
index 3343abf..1c9d3bf 100644
--- a/src/cairo-win32-font.c
+++ b/src/cairo-win32-font.c
@@ -1159,7 +1159,7 @@ _cairo_win32_scaled_font_show_glyphs (vo
 	cairo_surface_pattern_t mask;
 	RECT r;
 
-	tmp_surface = (cairo_win32_surface_t *)_cairo_win32_surface_create_dib (CAIRO_FORMAT_ARGB32, width, height);
+	tmp_surface = (cairo_win32_surface_t *)cairo_win32_surface_create_dib (CAIRO_FORMAT_ARGB32, width, height);
 	if (tmp_surface->base.status)
 	    return CAIRO_STATUS_NO_MEMORY;
 
diff --git a/src/cairo-win32-private.h b/src/cairo-win32-private.h
index b3143c9..fd66424 100644
--- a/src/cairo-win32-private.h
+++ b/src/cairo-win32-private.h
@@ -70,11 +70,6 @@ typedef struct _cairo_win32_surface {
 cairo_status_t
 _cairo_win32_print_gdi_error (const char *context);
 
-cairo_surface_t *
-_cairo_win32_surface_create_dib (cairo_format_t format,
-				 int            width,
-				 int            height);
-
 cairo_bool_t
 _cairo_surface_is_win32 (cairo_surface_t *surface);
 
diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index 9c46efe..888dadd 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -330,9 +330,9 @@ _cairo_win32_surface_create_similar (voi
  *   be created (probably because of lack of memory)
  **/
 cairo_surface_t *
-_cairo_win32_surface_create_dib (cairo_format_t format,
-				 int	        width,
-				 int	        height)
+cairo_win32_surface_create_dib (cairo_format_t format,
+				int	       width,
+				int	       height)
 {
     return _cairo_win32_surface_create_for_dc (NULL, format, width, height);
 }
@@ -1007,6 +1007,31 @@ _cairo_surface_is_win32 (cairo_surface_t
     return surface->backend == &cairo_win32_surface_backend;
 }
 
+/**
+ * cairo_win32_surface_get_dc
+ * @surface: a #cairo_surface_t
+ *
+ * Returns the HDC associated with this surface, or NULL if none.
+ * Also returns NULL if the surface is not a win32 surface.
+ *
+ * Return value: HDC or NULL if no HDC available.
+ **/
+HDC
+cairo_win32_surface_get_dc (cairo_surface_t *surface)
+{
+    cairo_win32_surface_t *winsurf;
+
+    if (surface == NULL)
+	return NULL;
+
+    if (!_cairo_surface_is_win32(surface))
+	return NULL;
+
+    winsurf = (cairo_win32_surface_t *) surface;
+
+    return winsurf->dc;
+}
+
 static const cairo_surface_backend_t cairo_win32_surface_backend = {
     _cairo_win32_surface_create_similar,
     _cairo_win32_surface_finish,
diff --git a/src/cairo-win32.h b/src/cairo-win32.h
index 8d43bb7..a631820 100644
--- a/src/cairo-win32.h
+++ b/src/cairo-win32.h
@@ -47,6 +47,14 @@ CAIRO_BEGIN_DECLS
 cairo_public cairo_surface_t *
 cairo_win32_surface_create (HDC hdc);
 
+cairo_public cairo_surface_t *
+cairo_win32_surface_create_dib (cairo_format_t format,
+				int width,
+				int height);
+
+cairo_public HDC
+cairo_win32_surface_get_dc (cairo_surface_t *surface);
+
 cairo_public cairo_font_face_t *
 cairo_win32_font_face_create_for_logfontw (LOGFONTW *logfont);
 
diff-tree f4b34df6b6c07024a1b552236d8e0db959771b15 (from e0f4eecb91c8f7f09ef4977703d4ca21b06797a9)
Author: Vladimir Vukicevic <vladimir at h-216.office.mozilla.org>
Date:   Wed Feb 15 13:14:52 2006 -0800

    Have mark_dirty always invalidate the last clip set on the surface
    
    mark_dirty will force cairo to set its own clip the next time the cairo clip
    is applied after mark_dirty; otherwise we run the risk of cairo's cached
    clip and the device clip getting out of sync if any clip-related functions
    are used on the native device back-end.
    (cherry picked from 1935a28949da8569f924e37714ec19571fa95987 commit)
    (cherry picked from ef8b472f0ffab7b8b828d7297c7e454bb22bd5ec commit)

diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 2982017..93095fc 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -502,6 +502,10 @@ cairo_surface_mark_dirty (cairo_surface_
  * Like cairo_surface_mark_dirty(), but drawing has been done only to
  * the specified rectangle, so that cairo can retain cached contents
  * for other parts of the surface.
+ *
+ * Any cached clip set on the surface will be reset by this function,
+ * to make sure that future cairo calls have the clip set that they
+ * expect.
  */
 void
 cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
@@ -520,6 +524,13 @@ cairo_surface_mark_dirty_rectangle (cair
 	return;
     }
 
+    /* Always reset the clip here, to avoid having external calls to
+     * clip manipulation functions of the underlying device clip result
+     * in a desync between the cairo clip and the backend clip, due to
+     * the clip caching.
+     */
+    surface->current_clip_serial = -1;
+
     if (surface->backend->mark_dirty_rectangle) {
 	cairo_status_t status;
 	
@@ -1329,6 +1340,12 @@ _cairo_surface_set_clip (cairo_surface_t
     if (!surface)
 	return CAIRO_STATUS_NULL_POINTER;
 
+    if (surface->status)
+	return surface->status;
+
+    if (surface->finished)
+	return CAIRO_STATUS_SURFACE_FINISHED;
+
     if (clip) {
 	serial = clip->serial;
 	if (serial == 0)
@@ -1336,7 +1353,7 @@ _cairo_surface_set_clip (cairo_surface_t
     }
     
     surface->clip = clip;
-    
+
     if (serial == _cairo_surface_get_current_clip_serial (surface))
 	return CAIRO_STATUS_SUCCESS;
 
diff-tree e0f4eecb91c8f7f09ef4977703d4ca21b06797a9 (from f6b4fabaf59227d6cafcdd7e27cf0d8e26b4eeb8)
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)

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 b1811a1..9c46efe 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 f6b4fabaf59227d6cafcdd7e27cf0d8e26b4eeb8 (from dba214b944a16dd7ee781f495cd5fbe83f678451)
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date:   Tue Feb 14 11:55:00 2006 -0800

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

diff --git a/pixman/src/fbcompose.c b/pixman/src/fbcompose.c
index c14986c..e316c6d 100644
--- a/pixman/src/fbcompose.c
+++ b/pixman/src/fbcompose.c
@@ -33,8 +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_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/cairo-atsui-font.c b/src/cairo-atsui-font.c
index 12cd329..74a4fca 100644
--- a/src/cairo-atsui-font.c
+++ b/src/cairo-atsui-font.c
@@ -40,6 +40,16 @@
 #include "cairo.h"
 #include "cairo-quartz-private.h"
 
+/*
+ * FixedToFloat/FloatToFixed are 10.3+ SDK items - include definitions
+ * here so we can use older SDKs.
+ */
+#ifndef FixedToFloat
+#define fixed1              ((Fixed) 0x00010000L)
+#define FixedToFloat(a)     ((float)(a) / fixed1)
+#define FloatToFixed(a)     ((Fixed)((float)(a) * fixed1))
+#endif
+
 typedef struct _cairo_atsui_font_face cairo_atsui_font_face_t;
 typedef struct _cairo_atsui_font cairo_atsui_font_t;
 
diff --git a/src/cairoint.h b/src/cairoint.h
index 88fccae..2581bc6 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -184,6 +184,10 @@ cairo_private void _cairo_beos_unlock(vo
 #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