2007-02-28 Sebastien Pouliot <sebastien@ximian.com>
[mono.git] / mcs / class / System.Drawing / System.Drawing / gdipFunctions.cs
index 8f9b3835fe83ba9aef7c245b7966d01a93b0bbca..e58b6cc4a332904ce27cac67bd60de0d246fe0f7 100644 (file)
@@ -7,8 +7,9 @@
 //     Sanjay Gupta (gsanjay@novell.com)
 //     Ravindra (rkumar@novell.com)
 //     Peter Dennis Bartok (pbartok@novell.com)
+//     Sebastien Pouliot  <sebastien@ximian.com>
 //
-// Copyright (C) 2004 - 2006 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004 - 2007 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
@@ -67,7 +68,7 @@ namespace System.Drawing
                [DllImport("gdiplus.dll")]
                static internal extern void GdiplusShutdown(ref ulong token);
                
-               static ulong GdiPlusToken;
+               internal static ulong GdiPlusToken = 0;
 
                static void ProcessExit (object sender, EventArgs e)
                {               
@@ -75,6 +76,8 @@ namespace System.Drawing
                        // shutting down
                        GC.Collect ();  
                        GC.WaitForPendingFinalizers ();
+                       
+                       GdiPlusToken = 0;
 
                        // This causes crashes in MS GDI+ because this call occurs before
                        // all managed GDI objects are finalized. When they are finalized they call
@@ -100,9 +103,28 @@ namespace System.Drawing
 
                        GdiplusStartupInput input = GdiplusStartupInput.MakeGdiplusStartupInput();
                        GdiplusStartupOutput output = GdiplusStartupOutput.MakeGdiplusStartupOutput();
-                       GdiplusStartup (ref GdiPlusToken, ref input, ref output);
+                       try {
+                               GdiplusStartup (ref GdiPlusToken, ref input, ref output);
+                       }
+                       catch (TypeInitializationException) {
+                               Console.Error.WriteLine (
+                                       "* ERROR: Can not initialize GDI+ library\n" +
+                                       "\n" +
+                                       "Please check http://www.mono-project.com/Problem:GDIPlusInit for details");
+                       }
+                       
                        AppDomain.CurrentDomain.ProcessExit += new EventHandler (ProcessExit);
                }
+
+               static public bool RunningOnWindows ()
+               {
+                       return !UseX11Drawable;
+               }
+
+               static public bool RunningOnUnix ()
+               {
+                       return UseX11Drawable;
+               }
                
                // Copies a Ptr to an array of Points and releases the memory
                static public void FromUnManagedMemoryToPointI(IntPtr prt, Point [] pts)
@@ -207,6 +229,9 @@ namespace System.Drawing
                                case Status.FontFamilyNotFound:
                                        throw new ArgumentException ("FontFamily wasn't found.");
 
+                               case Status.ValueOverflow:
+                                       throw new OverflowException ("Argument out of range.");
+
                                default:
                                        throw new Exception ("Unknown Error.");
                        }
@@ -966,6 +991,9 @@ namespace System.Drawing
                [DllImport("gdiplus.dll")]
                internal static extern Status GdipGetImageFlags(IntPtr image, out int flag);
 
+               [DllImport ("gdiplus.dll")]
+               internal static extern Status GdipGetImageType (IntPtr image, out ImageType type);
+
                [DllImport("gdiplus.dll")]
                internal static extern Status GdipImageGetFrameDimensionsCount ( IntPtr image, out uint count );
                                                                                                   
@@ -973,7 +1001,7 @@ namespace System.Drawing
                internal static extern Status GdipImageGetFrameDimensionsList ( IntPtr image, [Out] Guid [] dimensionIDs, uint count );
  
                [DllImport("gdiplus.dll")]
-               internal static extern Status GdipGetImageHeight (IntPtr image, out int height);
+               internal static extern Status GdipGetImageHeight (IntPtr image, out uint height);
                                                                                                   
                [DllImport("gdiplus.dll")]
                internal static extern Status GdipGetImageHorizontalResolution ( IntPtr image, out float resolution );
@@ -1024,7 +1052,7 @@ namespace System.Drawing
                internal static extern Status GdipGetEncoderParameterList ( IntPtr image, ref Guid encoder, uint size, IntPtr buffer );
                
                [DllImport("gdiplus.dll")]
-               internal static extern Status GdipImageGetFrameCount (IntPtr image, ref Guid guidDimension, out int count );
+               internal static extern Status GdipImageGetFrameCount (IntPtr image, ref Guid guidDimension, out uint count );
                
                [DllImport("gdiplus.dll")]
                internal static extern Status GdipImageSelectActiveFrame (IntPtr image, ref Guid guidDimension, int frameIndex);
@@ -1414,12 +1442,17 @@ namespace System.Drawing
                [DllImport("user32.dll", EntryPoint="GetDC", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
                internal static extern IntPtr GetDC(IntPtr hwnd);       
                [DllImport("user32.dll", EntryPoint="ReleaseDC", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
-               internal static extern int ReleaseDC(IntPtr hdc);
+               internal static extern int ReleaseDC (IntPtr hWnd, IntPtr hDC);
                [DllImport("gdi32.dll", EntryPoint="SelectObject", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
                internal static extern IntPtr SelectObject(IntPtr hdc, IntPtr obj);     
                [DllImport("user32.dll", SetLastError=true)]
                internal static extern bool GetIconInfo (IntPtr hIcon, out IconInfo iconinfo);
+               [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall, SetLastError=true)]
+               internal static extern IntPtr CreateIconIndirect ([In] ref IconInfo piconinfo);
+               [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall, SetLastError=true)]
+               internal static extern bool DestroyIcon (IntPtr hIcon);
+               [DllImport("gdi32.dll")]
+               internal static extern bool DeleteObject (IntPtr hObject);
                [DllImport("user32.dll")]
                internal static extern IntPtr GetDesktopWindow ();
 
@@ -1573,6 +1606,35 @@ namespace System.Drawing
                 [DllImport ("gdiplus.dll")]
                 internal static extern Status GdipGetStringFormatTabStops(IntPtr format, int count, out float firstTabOffset, [In, Out] float [] tabStops);
                                
+               // metafile
+               [DllImport ("gdiplus.dll", CharSet = CharSet.Auto)]
+               internal static extern Status GdipCreateMetafileFromFile ([MarshalAs (UnmanagedType.LPWStr)] string filename, out IntPtr metafile);
+               [DllImport ("gdiplus.dll")]
+               internal static extern Status GdipCreateMetafileFromEmf (IntPtr hEmf, bool deleteEmf, out IntPtr metafile);
+               [DllImport ("gdiplus.dll")]
+               internal static extern Status GdipCreateMetafileFromWmf (IntPtr hWmf, bool deleteWmf, WmfPlaceableFileHeader wmfPlaceableFileHeader, out IntPtr metafile);
+               [DllImport ("gdiplus.dll", CharSet = CharSet.Auto)]
+               internal static extern Status GdipGetMetafileHeaderFromFile ([MarshalAs (UnmanagedType.LPWStr)] string filename, IntPtr header);
+               [DllImport ("gdiplus.dll")]
+               internal static extern Status GdipGetMetafileHeaderFromMetafile (IntPtr metafile, IntPtr header);
+               [DllImport ("gdiplus.dll")]
+               internal static extern Status GdipGetMetafileHeaderFromEmf (IntPtr hEmf, IntPtr header);
+               [DllImport ("gdiplus.dll")]
+               internal static extern Status GdipGetMetafileHeaderFromWmf (IntPtr hWmf, IntPtr wmfPlaceableFileHeader, IntPtr header);
+               [DllImport ("gdiplus.dll")]
+               internal static extern Status GdipGetHemfFromMetafile (IntPtr metafile, out IntPtr hEmf);
+               [DllImport ("gdiplus.dll")]
+               internal static extern Status GdipGetMetafileDownLevelRasterizationLimit (IntPtr metafile, ref uint metafileRasterizationLimitDpi);
+               [DllImport ("gdiplus.dll")]
+               internal static extern Status GdipSetMetafileDownLevelRasterizationLimit (IntPtr metafile, uint metafileRasterizationLimitDpi);
+               [DllImport ("gdiplus.dll")]
+               internal static extern Status GdipPlayMetafileRecord (IntPtr metafile, EmfPlusRecordType recordType, int flags, int dataSize, byte[] data);
+#if !TEST
+               [DllImport("gdiplus.dll", ExactSpelling=true, CharSet=CharSet.Unicode)]
+               internal static extern Status GdipCreateMetafileFromStream([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(ComIStreamMarshaler))] IStream stream, out IntPtr metafile);
+               [DllImport("gdiplus.dll", ExactSpelling=true, CharSet=CharSet.Unicode)]
+               internal static extern Status GdipGetMetafileHeaderFromStream([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(ComIStreamMarshaler))] IStream stream, IntPtr header);
+#endif
                //ImageCodecInfo functions
                [DllImport("gdiplus.dll")]
                static internal extern Status GdipGetImageDecodersSize (out int decoderNums, out int arraySize);
@@ -1606,9 +1668,13 @@ namespace System.Drawing
                        private byte[]  start_buf;
                        private int     start_buf_pos;
                        private int     start_buf_len;
+                       private byte[]  managedBuf;
+                       private const int default_bufsize = 4096;
                        
                        public GdiPlusStreamHelper (Stream s) 
                        { 
+                               managedBuf = new byte [default_bufsize];
+                               
                                stream = s;
                                if (stream != null && stream.CanSeek) {
                                        stream.Seek (0, SeekOrigin.Begin);
@@ -1654,7 +1720,8 @@ namespace System.Drawing
                                        return -1;
                                }
 
-                               byte[] managedBuf = new byte[bufsz];
+                               if (bufsz > managedBuf.Length)
+                                       managedBuf = new byte[bufsz];
                                int bytesRead = 0;
                                long streamPosition = 0;
 
@@ -1762,7 +1829,8 @@ namespace System.Drawing
 
                        public int StreamPutBytesImpl (IntPtr buf, int bufsz) 
                        {
-                               byte[] managedBuf = new byte[bufsz];
+                               if (bufsz > managedBuf.Length)
+                                       managedBuf = new byte[bufsz];
                                Marshal.Copy (buf, managedBuf, 0, bufsz);
                                stream.Write (managedBuf, 0, bufsz);
                                return bufsz;
@@ -1831,14 +1899,26 @@ namespace System.Drawing
                [DllImport("gdiplus.dll")]
                internal static extern Status GdipCreateFromXDrawable_linux (IntPtr drawable, IntPtr display, out IntPtr graphics);
                
-               // Stream functions for non-Win32 (libgdiplus specific(
+               // Stream functions for non-Win32 (libgdiplus specific)
                [DllImport("gdiplus.dll")]
-               static internal extern Status GdipLoadImageFromDelegate_linux ( StreamGetHeaderDelegate getHeader, StreamGetBytesDelegate getBytes, StreamPutBytesDelegate putBytes, 
-                                                       StreamSeekDelegate doSeek, StreamCloseDelegate close, StreamSizeDelegate size, out IntPtr image);
+               static internal extern Status GdipLoadImageFromDelegate_linux (StreamGetHeaderDelegate getHeader, 
+                       StreamGetBytesDelegate getBytes, StreamPutBytesDelegate putBytes, StreamSeekDelegate doSeek, 
+                       StreamCloseDelegate close, StreamSizeDelegate size, out IntPtr image);
+
                [DllImport("gdiplus.dll")]
-               static internal extern Status GdipSaveImageToDelegate_linux ( IntPtr image, StreamGetBytesDelegate getBytes, StreamPutBytesDelegate putBytes, 
-                       StreamSeekDelegate doSeek, StreamCloseDelegate close, StreamSizeDelegate size, ref Guid encoderClsID, IntPtr encoderParameters );               
-               
+               static internal extern Status GdipSaveImageToDelegate_linux (IntPtr image, StreamGetBytesDelegate getBytes, 
+                       StreamPutBytesDelegate putBytes, StreamSeekDelegate doSeek, StreamCloseDelegate close, 
+                       StreamSizeDelegate size, ref Guid encoderClsID, IntPtr encoderParameters);              
+
+               [DllImport("gdiplus.dll")]
+               static internal extern Status GdipCreateMetafileFromDelegate_linux (StreamGetHeaderDelegate getHeader, 
+                       StreamGetBytesDelegate getBytes, StreamPutBytesDelegate putBytes, StreamSeekDelegate doSeek, 
+                       StreamCloseDelegate close, StreamSizeDelegate size, out IntPtr metafile);
+
+               [DllImport("gdiplus.dll")]
+               static internal extern Status GdipGetMetafileHeaderFromDelegate_linux (StreamGetHeaderDelegate getHeader, 
+                       StreamGetBytesDelegate getBytes, StreamPutBytesDelegate putBytes, StreamSeekDelegate doSeek, 
+                       StreamCloseDelegate close, StreamSizeDelegate size, IntPtr header);
 #endregion
        }
 }