[cairo] Patch for win32 clipping crash + Visual Studio project file

LRN lrn1986 at gmail.com
Thu Jul 24 07:52:49 PDT 2014


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 09.07.2014 1:43, Bryce W. Harrington wrote:
> On Tue, May 20, 2014 at 06:16:23PM +0200, z wrote:
>> Hi, I'm new here, please tell me if I write anything inappropriate to
>> this list.
>> 
>> As others before me I also met a crash using cairo with a win32 dc when
>> it has clipping. For example: 
>> http://lists.cairographics.org/archives/cairo/2012-October/023683.html
>> 
>> It took me a few hours but I figured out what the problem is. I don't
>> know how to post patches (i.e. just add attachment or something) so let
>> me paste in the diff output. (it was done with the source of the latest
>> stable release, 1.12.16)
>> 
>> The original code could be optimized to work faster with smaller memory
>> usage as it is currently not really optimal, but I don't have the time
>> to do it. If anyone wants to, I might be able to help after I spent so
>> much time reading this code to make the patch. (Currently it is better
>> to just allocate some memory and let cairo write to it directly.)
>> 
>> I also made a project file that works with Visual Studio 2012 (and 
>> presumably 2013) and compiles the pixman 0.32.4  / cairo 1.12.16 into a
>> static library without having to install other tools: 
>> http://sourceforge.net/projects/cairosolutionvs2012/
>> 
>> Here's the patch: (I don't know if the format is good, I used winmerge
>> to make it, but looks very similar to other patches)
> 
> Here's a document with some directions on how to properly format patches:
> 
> http://wiki.x.org/wiki/Development/Documentation/SubmittingPatches/
> 
> Basically, you should generate them via `git format-patch`

Since the OP seems to be absent, here's a beautified version of the same
patch, with suggested changes.

>> @@ -446,2 +446,3 @@ cairo_status_t status; +    cairo_rectangle_int_t
>> tmpextents; /* z-one */
> 
> Why not call 'tmpextents' just 'rect', to match the chunk of code at line
> 562?

Done.

>> @@ -562,3 +569,4 @@ if (!BitBlt (surface->win32.dc, -
>> rect.x, rect.y, +/* z-one removed: rect.x, rext.y, */ +
>> rect.x + surface->win32.extents.x, rect.y + surface->win32.extents.y,
>> /* z-one */ rect.width, rect.height,
> 
> Probably better to add the win32 offsets to the rect structure before the
> BitBlt.  rect isn't used anywhere else.

Not sure about this one. Currently, with z-one's changes, the call looks like
this:

if (!BitBlt (surface->win32.dc,
	     rect.x + surface->win32.extents.x, rect.y + surface->win32.extents.y
	     rect.width, rect.height,
	     fallback->win32.dc,
	     rect.x, rect.y,
	     SRCCOPY)) {

since rect.x and rect.y are used in the same call unmodified, just adding
offsets to them is not an option.


- -- 
O< ascii ribbon - stop html email! - www.asciiribbon.org
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (MingW32)

iQEcBAEBAgAGBQJT0R2/AAoJEOs4Jb6SI2CwergIAKh4fNw17/3nUeX0UMT0QaSI
aZ5vKSo/hUsyAvBvBfpMAFNQcktNBv3OAfHQSFthBltq1R6iGdpg0KREzeGjNspp
D2HN6fllBBihSK0rSGYZrTpr/RwzCVD6ljJrPzX50+Hsmo/xlmq4bwqvTid11DAU
ImcdQq6vuqHquVs4rdgNcOJQgphvF8EYRFWAU10QEeC9R1HjnfToXiGk9hfmzw2V
rix61XSIuAReP3TWngor87FNJrFzJpjkEwT9SN0MyR6fvoyfU2j+/4n8K2FGL6j5
pw3vAqZvyv30D/LveOrtbcTC5m+XVZ/HKVAV8hdOGFft8bd1ebr5WLBPOG0B8xE=
=pNza
-----END PGP SIGNATURE-----
-------------- next part --------------
From d675ce2cb151924caecd50e103b09ee245f73b77 Mon Sep 17 00:00:00 2001
From: z <z-one at freemail.hu>
Date: Tue, 20 May 2014 09:16:56 -0700
Subject: [PATCH] Fix win32 clipping crash

As others before me I also met a crash using cairo with a win32 dc when
it has clipping. For example:
http://lists.cairographics.org/archives/cairo/2012-October/023683.html

It took me a few hours but I figured out what the problem is.

The original code could be optimized to work faster with smaller memory
usage as it is currently not really optimal, but I don't have the time
to do it. If anyone wants to, I might be able to help after I spent so
much time reading this code to make the patch. (Currently it is better
to just allocate some memory and let cairo write to it directly.)
---
 src/win32/cairo-win32-display-surface.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/src/win32/cairo-win32-display-surface.c b/src/win32/cairo-win32-display-surface.c
index 5ecdbee..c780e1c 100644
--- a/src/win32/cairo-win32-display-surface.c
+++ b/src/win32/cairo-win32-display-surface.c
@@ -444,6 +444,7 @@ _cairo_win32_display_surface_map_to_image (void                    *abstract_sur
 {
     cairo_win32_display_surface_t *surface = abstract_surface;
     cairo_status_t status;
+    cairo_rectangle_int_t rect;
 
     TRACE ((stderr, "%s (surface=%d)\n",
 	    __FUNCTION__, surface->win32.base.unique_id));
@@ -465,17 +466,21 @@ _cairo_win32_display_surface_map_to_image (void                    *abstract_sur
 		     surface->win32.extents.width,
 		     surface->win32.extents.height,
 		     surface->win32.dc,
-		     0, 0,
+		     surface->win32.extents.x, surface->win32.extents.y,
 		     SRCCOPY)) {
 	    status = _cairo_error (CAIRO_STATUS_DEVICE_ERROR);
 	    goto err;
 	}
     }
 
+    rect.x = extents->x - surface->win32.extents.x;
+    rect.y = extents->y - surface->win32.extents.y;
+    rect.width = extents->width;
+    rect.height = extents->height;
     surface = to_win32_display_surface (surface->fallback);
 done:
     GdiFlush();
-    return _cairo_surface_map_to_image (surface->image, extents);
+    return _cairo_surface_map_to_image (surface->image, &rect);
 
 err:
     cairo_surface_destroy (surface->fallback);
@@ -543,7 +548,7 @@ _cairo_win32_display_surface_flush (void *abstract_surface, unsigned flags)
 
 	if (damage->status) {
 	    if (!BitBlt (surface->win32.dc,
-			 0, 0,
+			 surface->win32.extents.x, surface->win32.extents.y,
 			 surface->win32.extents.width,
 			 surface->win32.extents.height,
 			 fallback->win32.dc,
@@ -560,7 +565,7 @@ _cairo_win32_display_surface_flush (void *abstract_surface, unsigned flags)
 			rect.x, rect.y,
 			rect.width, rect.height));
 		if (!BitBlt (surface->win32.dc,
-			     rect.x, rect.y,
+			     rect.x + surface->win32.extents.x, rect.y + surface->win32.extents.y
 			     rect.width, rect.height,
 			     fallback->win32.dc,
 			     rect.x, rect.y,
-- 
1.8.5.3



More information about the cairo mailing list