[cairo-commit] cairo/src cairo-win32-private.h, 1.1, 1.2 cairo_win32_surface.c, 1.5, 1.6

Owen Taylor commit at pdx.freedesktop.org
Thu Feb 24 12:51:35 PST 2005


Committed by: otaylor

Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv24837/src

Modified Files:
	cairo-win32-private.h cairo_win32_surface.c 
Log Message:
2005-02-24  Owen Taylor  <otaylor at redhat.com>

	* src/cairo_win32_surface.[ch]: Instead of counting
	on ordering deletion to work (apparently it didn't on
	older Windows), save the initial bitmap created
	with the DC and reselect that into the DC. (Based
	on a patch by Hans Breuer)

Index: cairo-win32-private.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-win32-private.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- cairo-win32-private.h	2 Feb 2005 05:45:52 -0000	1.1
+++ cairo-win32-private.h	24 Feb 2005 20:51:33 -0000	1.2
@@ -54,6 +54,16 @@
 
     /* We create off-screen surfaces as DIBs */
     HBITMAP bitmap;
+
+    /* Used to save the initial 1x1 monochrome bitmap for the DC to
+     * select back into the DC before deleting the DC and our
+     * bitmap. For Windows XP, this doesn't seem to be necessary
+     * ... we can just delete the DC and that automatically unselects
+     * out bitmap. But it's standard practice so apparently is needed
+     * on some versions of Windows.
+     */
+    HBITMAP saved_dc_bitmap;
+    
     cairo_surface_t *image;
     
     cairo_rectangle_t clip_rect;

Index: cairo_win32_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_win32_surface.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- cairo_win32_surface.c	24 Feb 2005 16:20:14 -0000	1.5
+++ cairo_win32_surface.c	24 Feb 2005 20:51:33 -0000	1.6
@@ -98,19 +98,17 @@
 }
 
 static cairo_status_t
-_create_dc_and_bitmap (HDC             original_dc,
-		       cairo_format_t  format,
-		       int             width,
-		       int             height,
-		       HDC            *dc_out,
-		       HBITMAP        *bitmap_out,
-		       char          **bits_out,
-		       int            *rowstride_out)
+_create_dc_and_bitmap (cairo_win32_surface_t *surface,
+		       HDC                    original_dc,
+		       cairo_format_t         format,
+		       int                    width,
+		       int                    height,
+		       char                 **bits_out,
+		       int                   *rowstride_out)
 {
-    HDC dc = NULL;
-    HBITMAP bitmap = NULL;
     cairo_status_t status;
 
+    HBITMAP oldbitmap = NULL;
     BITMAPINFO *bitmap_info = NULL;
     struct {
 	BITMAPINFOHEADER bmiHeader;
@@ -121,6 +119,9 @@
     int num_palette = 0;	/* Quiet GCC */
     int i;
 
+    surface->dc = NULL;
+    surface->bitmap = NULL;
+
     switch (format) {
     case CAIRO_FORMAT_ARGB32:
     case CAIRO_FORMAT_RGB24:
@@ -191,26 +192,26 @@
 	}
     }
 
-    dc = CreateCompatibleDC (original_dc);
-    if (!dc)
+    surface->dc = CreateCompatibleDC (original_dc);
+    if (!surface->dc)
 	goto FAIL;
 
-    bitmap = CreateDIBSection (dc,
-			       bitmap_info,
-			       DIB_RGB_COLORS,
-			       &bits,
-			       NULL, 0);
-    if (!bitmap)
-	goto FAIL;
-    
-    if (!SelectObject (dc, bitmap))
+    surface->bitmap = CreateDIBSection (surface->dc,
+			                bitmap_info,
+			                DIB_RGB_COLORS,
+			                &bits,
+			                NULL, 0);
+    if (!surface->bitmap)
 	goto FAIL;
 
+    surface->saved_dc_bitmap = SelectObject (surface->dc,
+					     surface->bitmap);
+    if (!surface->saved_dc_bitmap)
+	goto FAIL;
+    
     if (bitmap_info && num_palette > 2)
 	free (bitmap_info);
 
-    *dc_out = dc;
-    *bitmap_out = bitmap;
     if (bits_out)
 	*bits_out = bits;
 
@@ -231,7 +232,7 @@
 	    break;
 	}
     }
-    
+
     return CAIRO_STATUS_SUCCESS;
 
  FAIL:
@@ -240,12 +241,21 @@
     if (bitmap_info && num_palette > 2)
 	free (bitmap_info);
 
-    if (dc)
-	DeleteDC (dc);
+    if (surface->saved_dc_bitmap) {
+	SelectObject (surface->dc, surface->saved_dc_bitmap);
+	surface->saved_dc_bitmap = NULL;
+    }
     
-    if (bitmap)
-	DeleteObject (bitmap);
+    if (surface->bitmap) {
+	DeleteObject (surface->bitmap);
+	surface->bitmap = NULL;
+    }
     
+    if (surface->dc) {
+ 	DeleteDC (surface->dc);
+	surface->dc = NULL;
+    }
+ 
     return status;
 }
 
@@ -257,8 +267,6 @@
 				    int	            height)
 {
     cairo_win32_surface_t *surface;
-    HDC dc = NULL;
-    HBITMAP bitmap = NULL;
     char *bits;
     int rowstride;
 
@@ -266,9 +274,9 @@
     if (!surface)
 	return NULL;
 
-    if (_create_dc_and_bitmap (original_dc, format,
+    if (_create_dc_and_bitmap (surface, original_dc, format,
 			       width, height,
-			       &dc, &bitmap, &bits, &rowstride) != CAIRO_STATUS_SUCCESS)
+			       &bits, &rowstride) != CAIRO_STATUS_SUCCESS)
 	goto FAIL;
 
     surface->image = cairo_image_surface_create_for_data (bits, format,
@@ -277,8 +285,6 @@
 	goto FAIL;
     
     surface->format = format;
-    surface->dc = dc;
-    surface->bitmap = bitmap;
     
     surface->clip_rect.x = 0;
     surface->clip_rect.y = 0;
@@ -293,10 +299,11 @@
     return (cairo_surface_t *)surface;
 
  FAIL:
-    if (bitmap)
-	DeleteObject (bitmap);
-    if (dc)
-	DeleteDC (dc);
+    if (surface->bitmap) {
+	SelectObject (surface->dc, surface->saved_dc_bitmap);
+  	DeleteObject (surface->bitmap);
+        DeleteDC (surface->dc);
+    }
     if (surface)
 	free (surface);
     
@@ -350,11 +357,13 @@
     if (surface->saved_clip)
 	DeleteObject (surface->saved_clip);
 
+    /* If we created the Bitmap and DC, destroy them */
     if (surface->bitmap) {
-	DeleteDC (surface->dc);
-	DeleteObject (surface->bitmap);
+	SelectObject (surface->dc, surface->saved_dc_bitmap);
+  	DeleteObject (surface->bitmap);
+        DeleteDC (surface->dc);
     }
-
+  
     free (surface);
 }
 




More information about the cairo-commit mailing list