[Mono-bugs] [Bug 66055][Nor] New - Caching of graphics objects on image causes problems

bugzilla-daemon@bugzilla.ximian.com bugzilla-daemon@bugzilla.ximian.com
Wed, 15 Sep 2004 18:33:06 -0400 (EDT)


Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.

Changed by david.mitchell@telogis.com.

http://bugzilla.ximian.com/show_bug.cgi?id=66055

--- shadow/66055	2004-09-15 18:33:06.000000000 -0400
+++ shadow/66055.tmp.24672	2004-09-15 18:33:06.000000000 -0400
@@ -0,0 +1,90 @@
+Bug#: 66055
+Product: Mono: Class Libraries
+Version: unspecified
+OS: 
+OS Details: 
+Status: NEW   
+Resolution: 
+Severity: 
+Priority: Normal
+Component: Sys.Drawing.
+AssignedTo: mono-bugs@ximian.com                            
+ReportedBy: david.mitchell@telogis.com               
+QAContact: mono-bugs@ximian.com
+TargetMilestone: ---
+URL: 
+Cc: 
+Summary: Caching of graphics objects on image causes problems
+
+Currently, graphics objects are cached against their images
+(GdipGetImageGraphicsContext in image.c:171). This causes problems when
+multiple managed graphics objects are used simultaneously:
+
+using System;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Drawing.Imaging;
+
+public class TestText {
+        public static void Main(string[] args) {
+                Image img = new Bitmap(300,300);
+
+                Graphics g1 = Graphics.FromImage(img);
+
+                Graphics g = Graphics.FromImage(img);
+                g1.Dispose();
+
+                g.DrawLine(Pens.Blue, 0, 0, 100, 100);
+
+                g.Dispose();
+        }
+}
+
+The first call to dispose (g1.Dispose) will dispose the native graphics
+object for both of the graphics. This obviously segfaults (handled as a
+NullReference) on the call to DrawLine because the native graphics is gone.
+
+I think we shouldn't be caching the graphics object like this because we
+don't want to be sharing the objects like that. Consider the situation when
+you have two Graphics objects at the same time, for the same image, and one
+of them has a certain matrix for its Transform, and the other has a
+different one. Currently that isn't possible.
+
+My proposed fix:
+
+Index: image.c
+===================================================================
+RCS file: /mono/libgdiplus/src/image.c,v
+retrieving revision 1.54
+diff -u -r1.54 image.c
+--- image.c     26 Jul 2004 09:42:16 -0000      1.54
++++ image.c     15 Sep 2004 21:49:21 -0000
+@@ -170,18 +170,18 @@
+ GpStatus
+ GdipGetImageGraphicsContext (GpImage *image, GpGraphics **graphics)
+ {
++       GpGraphics *gfx;
+        if (!image || !graphics)
+                return InvalidParameter;
+
+-       if (image->graphics == 0) {
+-               image->graphics = gdip_graphics_new ();
+-               if (image->type == imageBitmap) {
+-                       gdip_graphics_attach_bitmap (image->graphics,
+(GpBitmap *) image);
+-               }
+-               else if (image->type == imageMetafile) {
+-               }
++       gfx = gdip_graphics_new ();
++       if (image->type == imageBitmap) {
++               gdip_graphics_attach_bitmap (gfx, (GpBitmap *) image);
+        }
+-       *graphics = image->graphics;
++       else if (image->type == imageMetafile) {
++       }
++
++       *graphics = gfx;
+        return Ok;
+ }
+
+This will always create a new graphics for each image. Feedback?