* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / System.Drawing / System.Drawing / Graphics.cs
index 59023887fc86b8d2de40a95d9c52fba453fbfd1d..a5a7c0984f1445f1c33bcd56794c56956dfd96bb 100644 (file)
@@ -52,18 +52,25 @@ namespace System.Drawing
                private bool disposed = false;
                private static float defDpiX = 0;
                private static float defDpiY = 0;
+#if NET_2_0
+               private IntPtr deviceContextHdc;
+#endif
 
+#if !NET_2_0
                [ComVisible(false)]
+#endif
                public delegate bool EnumerateMetafileProc (EmfPlusRecordType recordType,
                                                            int flags,
                                                            int dataSize,
                                                            IntPtr data,
                                                            PlayRecordCallback callbackData);
                
+#if !NET_2_0
                [ComVisible (false)]
+#endif
                public delegate bool DrawImageAbort (IntPtr callbackData);
 
-               private Graphics (IntPtr nativeGraphics)
+               internal Graphics (IntPtr nativeGraphics)
                {
                        nativeObject = nativeGraphics;
                }
@@ -79,6 +86,7 @@ namespace System.Drawing
                                        Bitmap bmp = new Bitmap (1, 1);
                                        Graphics g = Graphics.FromImage (bmp);
                                        defDpiX = g.DpiX;
+                                       defDpiY = g.DpiY;
                                }
                                return defDpiX;
                        }
@@ -89,6 +97,7 @@ namespace System.Drawing
                                if (defDpiY == 0) {
                                        Bitmap bmp = new Bitmap (1, 1);
                                        Graphics g = Graphics.FromImage (bmp);
+                                       defDpiX = g.DpiX;
                                        defDpiY = g.DpiY;
                                }
                                return defDpiY;
@@ -111,33 +120,33 @@ namespace System.Drawing
                        throw new NotImplementedException ();
                }
 
-               
                public GraphicsContainer BeginContainer ()
                {
-                       int state;
+                       uint state;
                        Status status;
                        status = GDIPlus.GdipBeginContainer2 (nativeObject, out state);
                        GDIPlus.CheckStatus (status);
 
                         return new GraphicsContainer(state);
                }
-               
+
+               [MonoTODO ("rectangles and unit aren't supported in libgdiplus")]               
                public GraphicsContainer BeginContainer (Rectangle dstrect, Rectangle srcrect, GraphicsUnit unit)
                {
-                       int state;
+                       uint state;
                        Status status;
-                       status = GDIPlus.GdipBeginContainerI (nativeObject, dstrect, srcrect, unit, out state);
+                       status = GDIPlus.GdipBeginContainerI (nativeObject, ref dstrect, ref srcrect, unit, out state);
                        GDIPlus.CheckStatus (status);
 
                        return new GraphicsContainer (state);
                }
 
-               
+               [MonoTODO ("rectangles and unit aren't supported in libgdiplus")]               
                public GraphicsContainer BeginContainer (RectangleF dstrect, RectangleF srcrect, GraphicsUnit unit)
                {
-                       int state;
+                       uint state;
                        Status status;
-                       status = GDIPlus.GdipBeginContainer (nativeObject, dstrect, srcrect, unit, out state);
+                       status = GDIPlus.GdipBeginContainer (nativeObject, ref dstrect, ref srcrect, unit, out state);
                        GDIPlus.CheckStatus (status);
 
                        return new GraphicsContainer (state);
@@ -201,21 +210,31 @@ namespace System.Drawing
                                visual = (XVisualInfo) Marshal.PtrToStructure(vPtr, typeof (XVisualInfo));
 
                                /* Sorry I do not have access to a computer with > deepth. Fell free to add more pixel formats */       
-                               if (visual.depth != 16) 
-                                       throw new NotImplementedException ("Only 16bpp pixel is supported right now");
-                       
                                image = GDIPlus.XGetImage (GDIPlus.Display, window, sourceX, sourceY, blockRegionSize.Width,
                                        blockRegionSize.Height, AllPlanes, 2 /* ZPixmap*/);
                                
                                Bitmap bmp = new Bitmap (blockRegionSize.Width, blockRegionSize.Height);
+                               int red, blue, green;
                                for (int y = sourceY; y <  sourceY + blockRegionSize.Height; y++) {
                                        for (int x = sourceX; x <  sourceX + blockRegionSize.Width; x++) {
                                                pixel = GDIPlus.XGetPixel (image, x, y);                        
-                                               /* 16bbp pixel transformation */
-                                               int red = (int) ((pixel & visual.red_mask ) >> 8) & 0xff;
-                                               int green = (int) (((pixel & visual.green_mask ) >> 3 )) & 0xff;
-                                               int blue = (int) ((pixel & visual.blue_mask ) << 3 ) & 0xff;
 
+                                               switch (visual.depth) {
+                                                       case 16: /* 16bbp pixel transformation */
+                                                               red = (int) ((pixel & visual.red_mask ) >> 8) & 0xff;
+                                                               green = (int) (((pixel & visual.green_mask ) >> 3 )) & 0xff;
+                                                               blue = (int) ((pixel & visual.blue_mask ) << 3 ) & 0xff;
+                                                               break;
+                                                       case 24:
+                                                       case 32:
+                                                               red = (int) ((pixel & visual.red_mask ) >> 16) & 0xff;
+                                                               green = (int) (((pixel & visual.green_mask ) >> 8 )) & 0xff;
+                                                               blue = (int) ((pixel & visual.blue_mask )) & 0xff;
+                                                               break;
+                                                       default:
+                                                               throw new NotImplementedException ("Deepth not supported right now");
+                                               }
+                                               
                                                bmp.SetPixel (x, y, Color.FromArgb (255, red, green, blue));                                                     
                                        }
                                }
@@ -223,6 +242,7 @@ namespace System.Drawing
                                DrawImage (bmp, 0, 0);
                                bmp.Dispose ();
                                GDIPlus.XDestroyImage (image);
+                               GDIPlus.XFree (vPtr);
                                return;
                        }                       
 
@@ -329,10 +349,10 @@ namespace System.Drawing
                         int length = points.Length;
                        Status status;
 
-                        if (length < 3)
+                        if (length < 4)
                                 return;
 
-                       for (int i = 0; i < length; i += 3) {
+                       for (int i = 0; i < length - 1; i += 3) {
                                 Point p1 = points [i];
                                 Point p2 = points [i + 1];
                                 Point p3 = points [i + 2];
@@ -356,10 +376,10 @@ namespace System.Drawing
                        int length = points.Length;
                        Status status;
 
-                        if (length < 3)
+                        if (length < 4)
                                 return;
 
-                       for (int i = 0; i < length; i += 3) {
+                       for (int i = 0; i < length - 1; i += 3) {
                                 PointF p1 = points [i];
                                 PointF p2 = points [i + 1];
                                 PointF p3 = points [i + 2];
@@ -470,7 +490,6 @@ namespace System.Drawing
                        GDIPlus.CheckStatus (status);
                }
                
-               
                public void DrawCurve (Pen pen, PointF [] points, int offset, int numberOfSegments)
                {
                        if (pen == null)
@@ -499,7 +518,6 @@ namespace System.Drawing
                        GDIPlus.CheckStatus (status);
                }
 
-               
                public void DrawCurve (Pen pen, PointF [] points, int offset, int numberOfSegments, float tension)
                {
                        if (pen == null)
@@ -548,20 +566,23 @@ namespace System.Drawing
 
                public void DrawIcon (Icon icon, Rectangle targetRect)
                {
-                       Image img = icon.ToBitmap ();
-                       DrawImage (img, targetRect);
+                       using (Image img = icon.ToBitmap ()) {
+                               DrawImage (img, targetRect);
+                       }
                }
 
                public void DrawIcon (Icon icon, int x, int y)
                {
-                       Image img = icon.ToBitmap ();
-                       DrawImage (img, x, y);
+                       using (Image img = icon.ToBitmap ()) {
+                               DrawImage (img, x, y);
+                       }
                }
 
                public void DrawIconUnstretched (Icon icon, Rectangle targetRect)
                {
-                       Image img = icon.ToBitmap ();
-                       DrawImageUnscaled (img, targetRect);
+                       using (Image img = icon.ToBitmap ()) {
+                               DrawImageUnscaled (img, targetRect);
+                       }
                }
                
                public void DrawImage (Image image, RectangleF rect)
@@ -1156,8 +1177,10 @@ namespace System.Drawing
 
                public void EndContainer (GraphicsContainer container)
                {
+#if NET_2_0
                        if (container == null)
                                throw new ArgumentNullException ("container");
+#endif
                        Status status = GDIPlus.GdipEndContainer(nativeObject, container.NativeObject);
                        GDIPlus.CheckStatus (status);
                }
@@ -1593,7 +1616,9 @@ namespace System.Drawing
                {
                        if (brush == null)
                                throw new ArgumentNullException ("brush");
-                       
+                       if (rects == null)
+                               throw new ArgumentNullException ("rects");
+
                        Status status = GDIPlus.GdipFillRectanglesI (nativeObject, brush.nativeObject, rects, rects.Length);
                        GDIPlus.CheckStatus (status);
                }
@@ -1602,7 +1627,9 @@ namespace System.Drawing
                {
                        if (brush == null)
                                throw new ArgumentNullException ("brush");
-                       
+                       if (rects == null)
+                               throw new ArgumentNullException ("rects");
+
                        Status status = GDIPlus.GdipFillRectangles (nativeObject, brush.nativeObject, rects, rects.Length);
                        GDIPlus.CheckStatus (status);
                }
@@ -1628,6 +1655,10 @@ namespace System.Drawing
                
                public void Flush (FlushIntention intention)
                {
+                       if (nativeObject == IntPtr.Zero) {
+                               return;
+                       }
+
                        Status status = GDIPlus.GdipFlush (nativeObject, intention);
                         GDIPlus.CheckStatus (status);                    
                        if (GDIPlus.UseQuartzDrawable || GDIPlus.UseCocoaDrawable)
@@ -1743,6 +1774,9 @@ namespace System.Drawing
                {
                        IntPtr hdc;
                        GDIPlus.CheckStatus (GDIPlus.GdipGetDC (this.nativeObject, out hdc));
+#if NET_2_0
+                       deviceContextHdc = hdc;
+#endif
                        return hdc;
                }
 
@@ -2006,13 +2040,22 @@ namespace System.Drawing
                {
                        Status status = GDIPlus.GdipReleaseDC (nativeObject, hdc);
                        GDIPlus.CheckStatus (status);
+#if NET_2_0
+                       if (hdc == deviceContextHdc)
+                               deviceContextHdc = IntPtr.Zero;
+#endif
                }
+
 #if NET_2_0
-               public void ReleaseHdc()\r
+               public void ReleaseHdc ()\r
                {\r
-                     \r
+                       if (deviceContextHdc == IntPtr.Zero)
+                               throw new ArgumentException ("Invalid Handle");
+
+                       ReleaseHdc (deviceContextHdc);
                }
 #endif
+
                [MonoTODO]
 #if NET_2_0
                [EditorBrowsable (EditorBrowsableState.Never)]
@@ -2329,6 +2372,7 @@ namespace System.Drawing
                        }
                }
 
+               [MonoTODO ("not supported by libgdiplus")]
                public PixelOffsetMode PixelOffsetMode {
                        get {
                                PixelOffsetMode pixelOffset = PixelOffsetMode.Invalid;
@@ -2372,6 +2416,7 @@ namespace System.Drawing
                        }
                }
 
+               [MonoTODO ("not supported by libgdiplus")]
                public int TextContrast {
                        get {   
                                 int contrast;
@@ -2427,6 +2472,14 @@ namespace System.Drawing
                                 return rect;
                        }
                }
+
+#if NET_2_0
+               [MonoTODO]
+               [EditorBrowsable (EditorBrowsableState.Never)]
+               public object GetContextInfo ()
+               {
+                       throw new NotImplementedException ();
+               }
+#endif
        }
 }
-