[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?