2005-09-26 Sebastien Pouliot <sebastien@ximian.com>
[mono.git] / mcs / class / System.Drawing / System.Drawing / Graphics.cs
old mode 100755 (executable)
new mode 100644 (file)
index e5aee87..42b107c
@@ -1,16 +1,14 @@
 //
 // System.Drawing.Graphics.cs
 //
-// (C) 2003 Ximian, Inc.  http://www.ximian.com
-//
 // Authors:
 //     Gonzalo Paniagua Javier (gonzalo@ximian.com) (stubbed out)
 //      Alexandre Pigolkine(pigolkine@gmx.de)
-//             Jordi Mas i Hernandez (jordi@ximian.com)
+//     Jordi Mas i Hernandez (jordi@ximian.com)
 //
-
+// Copyright (C) 2003 Ximian, Inc. (http://www.ximian.com)
 //
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004-2005 Novell, Inc. (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
-using System;
+
 using System.Drawing.Drawing2D;
 using System.Drawing.Imaging;
 using System.Drawing.Text;
 using System.ComponentModel;
 using System.Runtime.InteropServices;
+using System.Security.Permissions;
 using System.Text;
 
 namespace System.Drawing
@@ -48,7 +47,7 @@ namespace System.Drawing
                private bool disposed = false;
                private static float defDpiX = 0;
                private static float defDpiY = 0;
-       
+
                [ComVisible(false)]
                public delegate bool EnumerateMetafileProc (EmfPlusRecordType recordType,
                                                            int flags,
@@ -57,42 +56,42 @@ namespace System.Drawing
                                                            PlayRecordCallback callbackData);
                
                [ComVisible (false)]
-               public delegate bool DrawImageAbort (IntPtr callbackData);              
-               
+               public delegate bool DrawImageAbort (IntPtr callbackData);
+
                private Graphics (IntPtr nativeGraphics)
                {
                        nativeObject = nativeGraphics;
                }
-               
+
                ~Graphics ()
                {
                        Dispose ();                     
                }               
-               
+
                static internal float systemDpiX {
-                       get {                                   
-                                       if (defDpiX==0) {
-                                               Bitmap bmp = new Bitmap(1,1);
-                                               Graphics g = Graphics.FromImage(bmp);   
-                                               defDpiX = g.DpiX;
-                                       }
-                                       return defDpiX;
+                       get {
+                               if (defDpiX == 0) {
+                                       Bitmap bmp = new Bitmap (1, 1);
+                                       Graphics g = Graphics.FromImage (bmp);
+                                       defDpiX = g.DpiX;
+                               }
+                               return defDpiX;
                        }
                }
 
                static internal float systemDpiY {
                        get {
-                                       if (defDpiY==0) {
-                                               Bitmap bmp = new Bitmap(1,1);
-                                               Graphics g = Graphics.FromImage(bmp);   
-                                               defDpiY = g.DpiY;
-                                       }
-                                       return defDpiY;
+                               if (defDpiY == 0) {
+                                       Bitmap bmp = new Bitmap (1, 1);
+                                       Graphics g = Graphics.FromImage (bmp);
+                                       defDpiY = g.DpiY;
+                               }
+                               return defDpiY;
                        }
                }
-               
+
                internal IntPtr NativeObject {
-                       get{
+                       get {
                                return nativeObject;
                        }
 
@@ -143,19 +142,18 @@ namespace System.Drawing
                public void Clear (Color color)
                {
                        Status status;
-                       status = GDIPlus.GdipGraphicsClear (nativeObject, color.ToArgb ());                             GDIPlus.CheckStatus (status);
+                       status = GDIPlus.GdipGraphicsClear (nativeObject, color.ToArgb ());
+                       GDIPlus.CheckStatus (status);
                }
 
                public void Dispose ()
                {
                        Status status;
                        if (! disposed) {
-                               lock (this)
-                               {
-                                       status = GDIPlus.GdipDeleteGraphics (nativeObject);
-                                       GDIPlus.CheckStatus (status);
-                                       disposed = true;
-                               }
+                               status = GDIPlus.GdipDeleteGraphics (nativeObject);
+                               nativeObject = IntPtr.Zero;
+                               GDIPlus.CheckStatus (status);
+                               disposed = true;                                
                        }
                }
 
@@ -370,22 +368,22 @@ namespace System.Drawing
                        GDIPlus.CheckStatus (status);
                }
 
-               [MonoTODO]
                public void DrawIcon (Icon icon, Rectangle targetRect)
                {
-                       throw new NotImplementedException ();
+                       Image img = icon.ToBitmap ();
+                       DrawImage (img, targetRect);
                }
 
-               [MonoTODO]
                public void DrawIcon (Icon icon, int x, int y)
                {
-                       throw new NotImplementedException ();
+                       Image img = icon.ToBitmap ();
+                       DrawImage (img, x, y);
                }
 
-               [MonoTODO]
                public void DrawIconUnstretched (Icon icon, Rectangle targetRect)
                {
-                       throw new NotImplementedException ();
+                       Image img = icon.ToBitmap ();
+                       DrawImageUnscaled (img, targetRect);
                }
                
                public void DrawImage (Image image, RectangleF rect)
@@ -417,7 +415,7 @@ namespace System.Drawing
                
                public void DrawImage (Image image, Rectangle rect)
                {
-                       DrawImage(image, rect.X, rect.Y, rect.Width, rect.Height);
+                       DrawImage (image, rect.X, rect.Y, rect.Width, rect.Height);
                }
 
                
@@ -651,22 +649,27 @@ namespace System.Drawing
                
                public void DrawImageUnscaled (Image image, Point point)
                {
-                       DrawImage(image, point.X, point.Y);
+                       DrawImageUnscaled (image, point.X, point.Y);
                }
                
                public void DrawImageUnscaled (Image image, Rectangle rect)
                {
-                       DrawImage(image, rect.X, rect.Y, rect.Width, rect.Height);
+                       DrawImageUnscaled (image, rect.X, rect.Y, rect.Width, rect.Height);
                }
                
                public void DrawImageUnscaled (Image image, int x, int y)
                {
-                       DrawImage(image, x, y);
+                       DrawImage (image, x, y, image.Width, image.Height);
                }
 
                public void DrawImageUnscaled (Image image, int x, int y, int width, int height)
                {
-                       DrawImage(image, x, y, width, height);
+                       Image tmpImg = new Bitmap (width, height);
+                       Graphics g = FromImage (tmpImg);
+                       g.DrawImage (image, 0, 0, image.Width, image.Height);
+                       this.DrawImage (tmpImg, x, y, width, height);
+                       tmpImg.Dispose ();
+                       g.Dispose ();
                }
 
                public void DrawLine (Pen pen, PointF pt1, PointF pt2)
@@ -785,50 +788,43 @@ namespace System.Drawing
                }
 
                public void DrawString (string s, Font font, Brush brush, RectangleF layoutRectangle)
-               {                       
-                       Status status = GDIPlus.GdipDrawString (nativeObject, s, s.Length, font.NativeObject, ref layoutRectangle, IntPtr.Zero, brush.nativeObject);
-                       GDIPlus.CheckStatus (status);
+               {
+                       DrawString (s, font, brush, layoutRectangle, null);
                }
-               
+
                public void DrawString (string s, Font font, Brush brush, PointF point)
                {
-                       RectangleF rc = new RectangleF (point.X, point.Y, 0, 0);
-                       Status status = GDIPlus.GdipDrawString (nativeObject, s, s.Length, font.NativeObject, ref rc, IntPtr.Zero, brush.nativeObject);
-                       GDIPlus.CheckStatus (status);
+                       DrawString (s, font, brush, new RectangleF (point.X, point.Y, 0, 0), null);
                }
-               
+
                public void DrawString (string s, Font font, Brush brush, PointF point, StringFormat format)
                {
-                       RectangleF rc = new RectangleF (point.X, point.Y, 0, 0);
-                       Status status = GDIPlus.GdipDrawString (nativeObject, s, s.Length, font.NativeObject, ref rc, format.NativeObject, brush.nativeObject);
-                       GDIPlus.CheckStatus (status);
-               }
-               
-               public void DrawString (string s, Font font, Brush brush, RectangleF layoutRectangle, StringFormat format)
-               {
-                       Status status = GDIPlus.GdipDrawString (nativeObject, s, s.Length, font.NativeObject, ref layoutRectangle, format.NativeObject, brush.nativeObject);
-                       GDIPlus.CheckStatus (status);
+                       DrawString(s, font, brush, new RectangleF(point.X, point.Y, 0, 0), format);
                }
 
                public void DrawString (string s, Font font, Brush brush, float x, float y)
                {
-                       RectangleF rc = new RectangleF (x, y, 0, 0);
-                       
-                       Status status = GDIPlus.GdipDrawString (nativeObject, s, s.Length, font.NativeObject, 
-                               ref rc, IntPtr.Zero, brush.nativeObject);
-                       GDIPlus.CheckStatus (status);
+                       DrawString (s, font, brush, new RectangleF (x, y, 0, 0), null);
                }
 
                public void DrawString (string s, Font font, Brush brush, float x, float y, StringFormat format)
                {
-                       RectangleF rc = new RectangleF (x, y, 0, 0);
+                       DrawString (s, font, brush, new RectangleF(x, y, 0, 0), format);
+               }
+
+               public void DrawString (string s, Font font, Brush brush, RectangleF layoutRectangle, StringFormat format)
+               {
+                       if (font == null)
+                               throw new ArgumentNullException ("font");
+                       if (brush == null)
+                               throw new ArgumentNullException ("brush");
+                       if (s == null || s.Length == 0)
+                               return;
 
-                       Status status = GDIPlus.GdipDrawString (nativeObject, s, s.Length, font.NativeObject,
-                               ref rc, format.NativeObject, brush.nativeObject);
+                       Status status = GDIPlus.GdipDrawString (nativeObject, s, s.Length, font.NativeObject, ref layoutRectangle, format != null ? format.NativeObject : IntPtr.Zero, brush.nativeObject);
                        GDIPlus.CheckStatus (status);
                }
 
-               
                public void EndContainer (GraphicsContainer container)
                {
                        Status status = GDIPlus.GdipEndContainer(nativeObject, container.NativeObject);
@@ -1221,17 +1217,18 @@ namespace System.Drawing
                public void Flush (FlushIntention intention)
                {
                        Status status = GDIPlus.GdipFlush (nativeObject, intention);
-                        GDIPlus.CheckStatus (status);                     
+                        GDIPlus.CheckStatus (status);                    
+                       if (GDIPlus.UseQuartzDrawable || GDIPlus.UseCocoaDrawable)
+                               Carbon.CGContextSynchronize (GDIPlus.Display);
                }
 
                [EditorBrowsable (EditorBrowsableState.Advanced)]               
                public static Graphics FromHdc (IntPtr hdc)
                {
-                       int graphics;
-                       Status status = GDIPlus.GdipCreateFromHDC (hdc, out graphics);                          GDIPlus.CheckStatus (status);
-                           
-                       Graphics result = new Graphics ((IntPtr) graphics);
-                       return result;
+                       IntPtr graphics;
+                       Status status = GDIPlus.GdipCreateFromHDC (hdc, out graphics);
+                       GDIPlus.CheckStatus (status);
+                       return new Graphics (graphics);
                }
 
                [MonoTODO]
@@ -1241,52 +1238,84 @@ namespace System.Drawing
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
                [EditorBrowsable (EditorBrowsableState.Advanced)]
+               [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
                public static Graphics FromHdcInternal (IntPtr hdc)
                {
-                       throw new NotImplementedException ();
+                       GDIPlus.Display = hdc;
+                       return null;
                }
 
                [EditorBrowsable (EditorBrowsableState.Advanced)]               
                public static Graphics FromHwnd (IntPtr hwnd)
                {
                        IntPtr graphics;
-                       
-                       Status status = GDIPlus.GdipCreateFromHWND (hwnd, out graphics);                                GDIPlus.CheckStatus (status);
-                       
-                       return new Graphics (graphics); 
-               }
 
-               [MonoTODO]
+                       if (GDIPlus.UseCocoaDrawable) {
+                               CarbonContext cgContext = Carbon.GetCGContextForNSView (hwnd);
+                               GDIPlus.GdipCreateFromQuartz_macosx (cgContext.ctx, cgContext.width, cgContext.height, out graphics);
+                               
+                               GDIPlus.Display = cgContext.ctx;
+                               return new Graphics (graphics);
+                       }
+                       if (GDIPlus.UseQuartzDrawable) {
+                               CarbonContext cgContext = Carbon.GetCGContextForView (hwnd);
+                               GDIPlus.GdipCreateFromQuartz_macosx (cgContext.ctx, cgContext.width, cgContext.height, out graphics);
+                               
+                               GDIPlus.Display = cgContext.ctx;
+                               return new Graphics (graphics);
+                       }
+                       if (GDIPlus.UseX11Drawable) {
+                               if (GDIPlus.Display == IntPtr.Zero) {
+                                       GDIPlus.Display = GDIPlus.XOpenDisplay (IntPtr.Zero);
+                               }
+
+                               return FromXDrawable (hwnd, GDIPlus.Display);
+
+                       }
+
+                       Status status = GDIPlus.GdipCreateFromHWND (hwnd, out graphics);
+                       GDIPlus.CheckStatus (status);
+
+                       return new Graphics (graphics);
+               }
+               
                [EditorBrowsable (EditorBrowsableState.Advanced)]
+               [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
                public static Graphics FromHwndInternal (IntPtr hwnd)
                {
-                       throw new NotImplementedException ();
+                       return FromHwnd (hwnd);
                }
 
                public static Graphics FromImage (Image image)
                {
-                       lock (typeof (Graphics))
-                       {
-                               if (image == null) throw new ArgumentException ();
-                               int graphics;
-                               Status status = GDIPlus.GdipGetImageGraphicsContext (image.nativeObject, out graphics);
-                               GDIPlus.CheckStatus (status);
-                               Graphics result = new Graphics ((IntPtr) graphics);
-                               return result;
+                       IntPtr graphics;
+
+                       if (image == null) 
+                               throw new ArgumentNullException ();
+
+                       Status status = GDIPlus.GdipGetImageGraphicsContext (image.nativeObject, out graphics);
+                       GDIPlus.CheckStatus (status);
+                       Graphics result = new Graphics (graphics);
+                               
+                       // check for Unix platforms - see FAQ for more details
+                       // http://www.mono-project.com/FAQ:_Technical#How_to_detect_the_execution_platform_.3F
+                       int platform = (int) Environment.OSVersion.Platform;
+                       if ((platform == 4) || (platform == 128)) {
+                               Rectangle rect  = new Rectangle (0,0, image.Width, image.Height);
+                               GDIPlus.GdipSetVisibleClip_linux (result.NativeObject, ref rect);
                        }
+                               
+                       return result;
                }
 
                internal static Graphics FromXDrawable (IntPtr drawable, IntPtr display)
                {
-                       lock (typeof (Graphics))
-                       {
-                               IntPtr graphics;
-                               Status s = GDIPlus.GdipCreateFromXDrawable_linux (drawable, display, out graphics);
-                               GDIPlus.CheckStatus (s);
-                               return new Graphics (graphics);
-                       }
+                       IntPtr graphics;
+
+                       Status s = GDIPlus.GdipCreateFromXDrawable_linux (drawable, display, out graphics);
+                       GDIPlus.CheckStatus (s);
+                       return new Graphics (graphics);
                }
 
                [MonoTODO]
@@ -1295,15 +1324,12 @@ namespace System.Drawing
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
                [EditorBrowsable (EditorBrowsableState.Advanced)]
                public IntPtr GetHdc ()
                {
-                       int hdc;
-                       Status status = GDIPlus.GdipGetDC (nativeObject, out hdc);
-                       GDIPlus.CheckStatus (status);
-
-                       return (IntPtr) hdc;
+                       IntPtr hdc;
+                       GDIPlus.CheckStatus (GDIPlus.GdipGetDC (this.nativeObject, out hdc));
+                       return hdc;
                }
 
                
@@ -1398,85 +1424,149 @@ namespace System.Drawing
                        return IsVisible (new Rectangle (x, y, width, height));
                }
 
-               [MonoTODO]
+               
                public Region [] MeasureCharacterRanges (string text, Font font, RectangleF layoutRect, StringFormat stringFormat)
-               {
-                       Region []       result=new Region[stringFormat.GetCharRanges.Length];
-                       string          textFragment;
-                       SizeF           fragmentSize;
+               {       
+                       Status status;                  
+                       int regcount = stringFormat.GetMeasurableCharacterRangeCount ();
+                       IntPtr[] native_regions = new IntPtr [regcount];
+                       Region[] regions = new Region [regcount];
                        
-                       for (int i=0; i<stringFormat.GetCharRanges.Length; i++) { 
-                               textFragment=text.Substring(stringFormat.GetCharRanges[i].First, stringFormat.GetCharRanges[i].Length);
-                               fragmentSize=MeasureString(textFragment, font, new SizeF(layoutRect.Width, layoutRect.Height), stringFormat);
-                               result[i]=new Region(new RectangleF(layoutRect.X, layoutRect.Y, layoutRect.X+fragmentSize.Width, layoutRect.Y+fragmentSize.Height));
+                       for (int i = 0; i < regcount; i++) {
+                               regions[i] = new Region ();
+                               native_regions[i] = regions[i].NativeObject;
                        }
-
-                       return(result);
+                       
+                       status =  GDIPlus.GdipMeasureCharacterRanges (nativeObject, text, text.Length,
+                               font.NativeObject, ref layoutRect, stringFormat.NativeObject, 
+                               regcount, out native_regions[0]); 
+                       
+                       GDIPlus.CheckStatus (status);                           
+                                                       
+                       return regions;                                                 
                }
 
                
                public SizeF MeasureString (string text, Font font)
                {
-                       return MeasureString (text, font, new Size(0,0));
+                       return MeasureString (text, font, new Size (0, 0));
                }
 
                
                public SizeF MeasureString (string text, Font font, SizeF layoutArea)
                {
-                       int charactersFitted, linesFilled;                      
+                       int charactersFitted, linesFilled;
                        RectangleF boundingBox = new RectangleF ();
-                       RectangleF rect = new RectangleF (0,0,layoutArea.Width, layoutArea.Height);
-                                       
-                       Status status = GDIPlus.GdipMeasureString (nativeObject, text, text.Length, 
-                               font.NativeObject, ref rect, IntPtr.Zero, out boundingBox,
-                               out charactersFitted, out linesFilled);
+                       RectangleF rect = new RectangleF (0, 0, layoutArea.Width,
+                                                         layoutArea.Height);
+
+                       if (text == null || text.Length == 0)
+                               return SizeF.Empty;
+
+                       if (font == null)
+                               throw new ArgumentNullException ("font");
+
+                       Status status = GDIPlus.GdipMeasureString (nativeObject, text, text.Length,
+                                                                  font.NativeObject, ref rect,
+                                                                  IntPtr.Zero, out boundingBox,
+                                                                  out charactersFitted, out linesFilled);
                        GDIPlus.CheckStatus (status);
 
-                       return new SizeF(boundingBox.Width, boundingBox.Height);
+                       return new SizeF (boundingBox.Width, boundingBox.Height);
                }
 
-               [MonoTODO]
+               
                public SizeF MeasureString (string text, Font font, int width)
-               {
-                       throw new NotImplementedException ();
+               {                               
+                       RectangleF boundingBox = new RectangleF ();
+                       RectangleF rect = new RectangleF (0, 0, width, 999999);
+                       int charactersFitted, linesFilled;
+
+                       if (text == null || text.Length == 0)
+                               return SizeF.Empty;
+
+                       if (font == null)
+                               throw new ArgumentNullException ("font");
+
+                       Status status = GDIPlus.GdipMeasureString (nativeObject, text, text.Length, 
+                                                                  font.NativeObject, ref rect,
+                                                                  IntPtr.Zero, out boundingBox,
+                                                                  out charactersFitted, out linesFilled);
+                       GDIPlus.CheckStatus (status);
+
+                       return new SizeF (boundingBox.Width, boundingBox.Height);
                }
 
                
-               public SizeF MeasureString (string text, Font font, SizeF layoutArea, StringFormat stringFormat)
+               public SizeF MeasureString (string text, Font font, SizeF layoutArea,
+                                           StringFormat stringFormat)
                {
                        int charactersFitted, linesFilled;                      
-                       return MeasureString (text, font, layoutArea, stringFormat, out charactersFitted, out linesFilled);
+                       return MeasureString (text, font, layoutArea, stringFormat,
+                                             out charactersFitted, out linesFilled);
                }
 
-               [MonoTODO]
+               
                public SizeF MeasureString (string text, Font font, int width, StringFormat format)
                {
-                       throw new NotImplementedException ();
+                       int charactersFitted, linesFilled;                      
+                       return MeasureString (text, font, new SizeF (width, 999999), 
+                                             format, out charactersFitted, out linesFilled);
                }
 
                
-               public SizeF MeasureString (string text, Font font, PointF origin, StringFormat stringFormat)
+               public SizeF MeasureString (string text, Font font, PointF origin,
+                                           StringFormat stringFormat)
                {
                        RectangleF boundingBox = new RectangleF ();
-                       RectangleF rect = new RectangleF (origin.X, origin.Y, 0,0);
+                       RectangleF rect = new RectangleF (origin.X, origin.Y, 0, 0);
                        int charactersFitted, linesFilled;
 
+                       if (text == null || text.Length == 0)
+                               return SizeF.Empty;
+
+                       if (font == null)
+                               throw new ArgumentNullException ("font");
+
+                       if (stringFormat == null)
+                               stringFormat = new StringFormat ();
+
                        Status status = GDIPlus.GdipMeasureString (nativeObject, text, text.Length, 
-                               font.NativeObject, ref rect, stringFormat.NativeObject, 
-                               out boundingBox, out charactersFitted, out linesFilled);
+                                                                  font.NativeObject, ref rect,
+                                                                  stringFormat.NativeObject, 
+                                                                  out boundingBox,
+                                                                  out charactersFitted,
+                                                                  out linesFilled);
                        GDIPlus.CheckStatus (status);
 
                        return new SizeF (boundingBox.Width, boundingBox.Height);
                }
 
                
-               public SizeF MeasureString (string text, Font font, SizeF layoutArea, StringFormat stringFormat, out int charactersFitted, out int linesFilled)
+               public SizeF MeasureString (string text, Font font, SizeF layoutArea,
+                                           StringFormat stringFormat, out int charactersFitted,
+                                           out int linesFilled)
                {       
                        RectangleF boundingBox = new RectangleF ();
-                       RectangleF rect = new RectangleF (0,0,layoutArea.Width, layoutArea.Height);
+                       RectangleF rect = new RectangleF (0, 0, layoutArea.Width, layoutArea.Height);
+                       charactersFitted = 0;
+                       linesFilled = 0;
+
+                       if (text == null || text.Length == 0)
+                               return SizeF.Empty;
+
+                       if (font == null)
+                               throw new ArgumentNullException ("font");
+
+                       if (stringFormat == null)
+                               stringFormat = new StringFormat ();
+
                        Status status = GDIPlus.GdipMeasureString (nativeObject, text, text.Length, 
-                               font.NativeObject, ref rect, stringFormat.NativeObject,
-                               out boundingBox, out charactersFitted, out linesFilled);
+                                                                  font.NativeObject, ref rect,
+                                                                  stringFormat.NativeObject,
+                                                                  out boundingBox,
+                                                                  out charactersFitted,
+                                                                  out linesFilled);
                        GDIPlus.CheckStatus (status);
 
                        return new SizeF (boundingBox.Width, boundingBox.Height);
@@ -1489,7 +1579,9 @@ namespace System.Drawing
 
                public void MultiplyTransform (Matrix matrix, MatrixOrder order)
                {
-                       Status status = GDIPlus.GdipMultiplyWorldTransform (nativeObject, matrix.nativeMatrix, order);
+                       Status status = GDIPlus.GdipMultiplyWorldTransform (nativeObject,
+                                                                           matrix.nativeMatrix,
+                                                                           order);
                        GDIPlus.CheckStatus (status);
                }
 
@@ -1502,6 +1594,7 @@ namespace System.Drawing
 
                [MonoTODO]
                [EditorBrowsable (EditorBrowsableState.Advanced)]
+               [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
                public void ReleaseHdcInternal (IntPtr hdc)
                {
                        throw new NotImplementedException ();
@@ -1521,8 +1614,7 @@ namespace System.Drawing
                }
 
                public void Restore (GraphicsState gstate)
-               {
-                       Transform = gstate.matrix.Clone ();
+               {                       
                        Status status = GDIPlus.GdipRestoreGraphics (nativeObject, gstate.nativeState);
                        GDIPlus.CheckStatus (status);
                }
@@ -1541,13 +1633,12 @@ namespace System.Drawing
                }
 
                public GraphicsState Save ()
-               {
-                       GraphicsState state = new GraphicsState ();
-                       state.matrix = Transform.Clone ();
+               {                                               
                        uint saveState;
                        Status status = GDIPlus.GdipSaveGraphics (nativeObject, out saveState);
                        GDIPlus.CheckStatus (status);
 
+                       GraphicsState state = new GraphicsState ();
                        state.nativeState = saveState;
                        return state;
                }