2 // Metafile class unit tests
5 // Sebastien Pouliot <sebastien@ximian.com>
7 // Copyright (C) 2007 Novell, Inc (http://www.novell.com)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System.Drawing.Drawing2D;
32 using System.Drawing.Imaging;
34 using System.Runtime.InteropServices;
35 using System.Security.Permissions;
36 using NUnit.Framework;
38 namespace MonoTests.System.Drawing.Imaging {
41 [SecurityPermission (SecurityAction.Deny, UnmanagedCode = true)]
42 public class MetafileTest {
44 public const string Bitmap = "bitmaps/non-inverted.bmp";
45 public const string WmfPlaceable = "bitmaps/telescope_01.wmf";
46 public const string Emf = "bitmaps/milkmateya01.emf";
48 // Get the input directory depending on the runtime
49 static public string getInFile (string file)
51 string sRslt = Path.GetFullPath ("../System.Drawing/" + file);
53 if (!File.Exists (sRslt))
54 sRslt = "Test/System.Drawing/" + file;
60 public void Metafile_Stream_Null ()
62 Assert.Throws<ArgumentException> (() => new Metafile ((Stream)null));
66 public void Metafile_String_Null ()
68 Assert.Throws<ArgumentNullException> (() => new Metafile ((string) null));
72 public void Metafile_String_Empty ()
74 Assert.Throws<ArgumentException> (() => new Metafile (String.Empty));
78 public void Metafile_String_FileDoesNotExists ()
80 string filename = getInFile ("telescope_02.wmf");
81 Assert.Throws<ExternalException> (() => new Metafile (filename));
85 public void Metafile_String ()
87 string filename = getInFile (WmfPlaceable);
88 Metafile mf = new Metafile (filename);
89 Metafile clone = (Metafile) mf.Clone ();
93 public void GetMetafileHeader_Bitmap ()
95 Assert.Throws<ExternalException> (() => new Metafile (getInFile (Bitmap)));
98 static public void Check_MetaHeader_WmfPlaceable (MetaHeader mh)
100 Assert.AreEqual (9, mh.HeaderSize, "HeaderSize");
101 Assert.AreEqual (98, mh.MaxRecord, "MaxRecord");
102 Assert.AreEqual (3, mh.NoObjects, "NoObjects");
103 Assert.AreEqual (0, mh.NoParameters, "NoParameters");
104 Assert.AreEqual (1737, mh.Size, "Size");
105 Assert.AreEqual (1, mh.Type, "Type");
106 Assert.AreEqual (0x300, mh.Version, "Version");
109 public static void Check_MetafileHeader_WmfPlaceable (MetafileHeader header)
111 Assert.AreEqual (MetafileType.WmfPlaceable, header.Type, "Type");
112 Assert.AreEqual (0x300, header.Version, "Version");
113 // filesize - 22, which happens to be the size (22) of a PLACEABLEMETAHEADER struct
114 Assert.AreEqual (3474, header.MetafileSize, "MetafileSize");
116 Assert.AreEqual (-30, header.Bounds.X, "Bounds.X");
117 Assert.AreEqual (-40, header.Bounds.Y, "Bounds.Y");
118 Assert.AreEqual (3096, header.Bounds.Width, "Bounds.Width");
119 Assert.AreEqual (4127, header.Bounds.Height, "Bounds.Height");
120 Assert.AreEqual (606, header.DpiX, "DpiX");
121 Assert.AreEqual (606, header.DpiY, "DpiY");
122 Assert.AreEqual (0, header.EmfPlusHeaderSize, "EmfPlusHeaderSize");
123 Assert.AreEqual (0, header.LogicalDpiX, "LogicalDpiX");
124 Assert.AreEqual (0, header.LogicalDpiY, "LogicalDpiY");
126 Assert.IsNotNull (header.WmfHeader, "WmfHeader");
127 Check_MetaHeader_WmfPlaceable (header.WmfHeader);
129 Assert.IsFalse (header.IsDisplay (), "IsDisplay");
130 Assert.IsFalse (header.IsEmf (), "IsEmf");
131 Assert.IsFalse (header.IsEmfOrEmfPlus (), "IsEmfOrEmfPlus");
132 Assert.IsFalse (header.IsEmfPlus (), "IsEmfPlus");
133 Assert.IsFalse (header.IsEmfPlusDual (), "IsEmfPlusDual");
134 Assert.IsFalse (header.IsEmfPlusOnly (), "IsEmfPlusOnly");
135 Assert.IsTrue (header.IsWmf (), "IsWmf");
136 Assert.IsTrue (header.IsWmfPlaceable (), "IsWmfPlaceable");
140 public void GetMetafileHeader_WmfPlaceable ()
142 using (Metafile mf = new Metafile (getInFile (WmfPlaceable))) {
143 MetafileHeader header1 = mf.GetMetafileHeader ();
144 Check_MetafileHeader_WmfPlaceable (header1);
146 MetafileHeader header2 = mf.GetMetafileHeader ();
147 Assert.IsFalse (Object.ReferenceEquals (header1, header2), "Same object");
152 public void GetMetafileHeader_FromFile_WmfPlaceable ()
154 using (Metafile mf = new Metafile (getInFile (WmfPlaceable))) {
155 MetafileHeader header1 = mf.GetMetafileHeader ();
156 Check_MetafileHeader_WmfPlaceable (header1);
158 MetaHeader mh1 = header1.WmfHeader;
159 Check_MetaHeader_WmfPlaceable (mh1);
161 MetaHeader mh2 = mf.GetMetafileHeader ().WmfHeader;
162 Assert.IsFalse (Object.ReferenceEquals (mh1, mh2), "Same object");
167 public void GetMetafileHeader_FromFileStream_WmfPlaceable ()
169 using (FileStream fs = File.OpenRead (getInFile (WmfPlaceable))) {
170 using (Metafile mf = new Metafile (fs)) {
171 MetafileHeader header1 = mf.GetMetafileHeader ();
172 Check_MetafileHeader_WmfPlaceable (header1);
174 MetaHeader mh1 = header1.WmfHeader;
175 Check_MetaHeader_WmfPlaceable (mh1);
177 MetaHeader mh2 = mf.GetMetafileHeader ().WmfHeader;
178 Assert.IsFalse (Object.ReferenceEquals (mh1, mh2), "Same object");
184 public void GetMetafileHeader_FromMemoryStream_WmfPlaceable ()
187 string filename = getInFile (WmfPlaceable);
188 using (FileStream fs = File.OpenRead (filename)) {
189 byte[] data = new byte[fs.Length];
190 fs.Read (data, 0, data.Length);
191 ms = new MemoryStream (data);
193 using (Metafile mf = new Metafile (ms)) {
194 MetafileHeader header1 = mf.GetMetafileHeader ();
195 Check_MetafileHeader_WmfPlaceable (header1);
197 MetaHeader mh1 = header1.WmfHeader;
198 Check_MetaHeader_WmfPlaceable (mh1);
200 MetaHeader mh2 = mf.GetMetafileHeader ().WmfHeader;
201 Assert.IsFalse (Object.ReferenceEquals (mh1, mh2), "Same object");
206 public static void Check_MetafileHeader_Emf (MetafileHeader header)
208 Assert.AreEqual (MetafileType.Emf, header.Type, "Type");
209 Assert.AreEqual (65536, header.Version, "Version");
210 // extactly the filesize
211 Assert.AreEqual (20456, header.MetafileSize, "MetafileSize");
213 Assert.AreEqual (0, header.Bounds.X, "Bounds.X");
214 Assert.AreEqual (0, header.Bounds.Y, "Bounds.Y");
216 Assert.AreEqual (759, header.Bounds.Width, "Bounds.Width");
217 Assert.AreEqual (1073, header.Bounds.Height, "Bounds.Height");
218 Assert.AreEqual (96f, header.DpiX, 0.5f, "DpiX");
219 Assert.AreEqual (96f, header.DpiY, 0.5f, "DpiY");
220 Assert.AreEqual (6619188, header.EmfPlusHeaderSize, "EmfPlusHeaderSize");
221 Assert.AreEqual (3670064, header.LogicalDpiX, "LogicalDpiX");
222 Assert.AreEqual (3670064, header.LogicalDpiY, "LogicalDpiY");
225 Assert.IsNotNull (header.WmfHeader, "WmfHeader");
226 Assert.Fail ("WmfHeader didn't throw an ArgumentException");
228 catch (ArgumentException) {
230 catch (Exception e) {
231 Assert.Fail ("WmfHeader didn't throw an ArgumentException but: {0}.", e.ToString ());
234 Assert.IsFalse (header.IsDisplay (), "IsDisplay");
235 Assert.IsTrue (header.IsEmf (), "IsEmf");
236 Assert.IsTrue (header.IsEmfOrEmfPlus (), "IsEmfOrEmfPlus");
237 Assert.IsFalse (header.IsEmfPlus (), "IsEmfPlus");
238 Assert.IsFalse (header.IsEmfPlusDual (), "IsEmfPlusDual");
239 Assert.IsFalse (header.IsEmfPlusOnly (), "IsEmfPlusOnly");
240 Assert.IsFalse (header.IsWmf (), "IsWmf");
241 Assert.IsFalse (header.IsWmfPlaceable (), "IsWmfPlaceable");
245 public void GetMetafileHeader_FromFile_Emf ()
247 using (Metafile mf = new Metafile (getInFile (Emf))) {
248 MetafileHeader header1 = mf.GetMetafileHeader ();
249 Check_MetafileHeader_Emf (header1);
254 public void GetMetafileHeader_FromFileStream_Emf ()
256 using (FileStream fs = File.OpenRead (getInFile (Emf))) {
257 using (Metafile mf = new Metafile (fs)) {
258 MetafileHeader header1 = mf.GetMetafileHeader ();
259 Check_MetafileHeader_Emf (header1);
265 public void GetMetafileHeader_FromMemoryStream_Emf ()
268 string filename = getInFile (Emf);
269 using (FileStream fs = File.OpenRead (filename)) {
270 byte[] data = new byte[fs.Length];
271 fs.Read (data, 0, data.Length);
272 ms = new MemoryStream (data);
274 using (Metafile mf = new Metafile (ms)) {
275 MetafileHeader header1 = mf.GetMetafileHeader ();
276 Check_MetafileHeader_Emf (header1);
282 public void Static_GetMetafileHeader_Stream_Null ()
284 Assert.Throws<NullReferenceException> (() => Metafile.GetMetafileHeader ((Stream)null));
288 public void Static_GetMetafileHeader_Stream ()
290 string filename = getInFile (WmfPlaceable);
291 using (FileStream fs = File.OpenRead (filename)) {
292 MetafileHeader header = Metafile.GetMetafileHeader (fs);
293 Check_MetafileHeader_WmfPlaceable (header);
298 public void Static_GetMetafileHeader_Filename_Null ()
300 Assert.Throws<ArgumentNullException> (() => Metafile.GetMetafileHeader ((string) null));
304 public void Static_GetMetafileHeader_Filename ()
306 string filename = getInFile (WmfPlaceable);
307 MetafileHeader header = Metafile.GetMetafileHeader (filename);
308 Check_MetafileHeader_WmfPlaceable (header);
313 public class MetafileFulltrustTest {
315 private Font test_font;
318 public void FixtureSetUp ()
321 test_font = new Font (FontFamily.GenericMonospace, 12);
323 catch (ArgumentException) {
328 public void Static_GetMetafileHeader_IntPtr_Zero ()
330 Assert.Throws<ArgumentException> (() => Metafile.GetMetafileHeader (IntPtr.Zero));
334 public void Static_GetMetafileHeader_IntPtr ()
336 string filename = MetafileTest.getInFile (MetafileTest.WmfPlaceable);
337 using (Metafile mf = new Metafile (filename)) {
339 IntPtr hemf = mf.GetHenhmetafile ();
340 Assert.IsTrue (hemf != IntPtr.Zero, "GetHenhmetafile");
342 Assert.Throws<ArgumentException> (() => Metafile.GetMetafileHeader (hemf));
347 public void Metafile_IntPtrBool_Zero ()
349 Assert.Throws<ArgumentException> (() => new Metafile (IntPtr.Zero, false));
353 public void Metafile_IntPtrEmfType_Zero ()
355 Assert.Throws<ArgumentException> (() => new Metafile (IntPtr.Zero, EmfType.EmfOnly));
358 private void CheckEmptyHeader (Metafile mf, EmfType type)
360 MetafileHeader mh = mf.GetMetafileHeader ();
361 Assert.AreEqual (0, mh.Bounds.X, "Bounds.X");
362 Assert.AreEqual (0, mh.Bounds.Y, "Bounds.Y");
363 Assert.AreEqual (0, mh.Bounds.Width, "Bounds.Width");
364 Assert.AreEqual (0, mh.Bounds.Height, "Bounds.Height");
365 Assert.AreEqual (0, mh.MetafileSize, "MetafileSize");
367 case EmfType.EmfOnly:
368 Assert.AreEqual (MetafileType.Emf, mh.Type, "Type");
370 case EmfType.EmfPlusDual:
371 Assert.AreEqual (MetafileType.EmfPlusDual, mh.Type, "Type");
373 case EmfType.EmfPlusOnly:
374 Assert.AreEqual (MetafileType.EmfPlusOnly, mh.Type, "Type");
377 Assert.Fail ("Unknown EmfType '{0}'", type);
382 private void Metafile_IntPtrEmfType (EmfType type)
384 using (Bitmap bmp = new Bitmap (10, 10, PixelFormat.Format32bppArgb)) {
385 using (Graphics g = Graphics.FromImage (bmp)) {
386 IntPtr hdc = g.GetHdc ();
388 Metafile mf = new Metafile (hdc, type);
389 CheckEmptyHeader (mf, type);
399 public void Metafile_IntPtrEmfType_Invalid ()
401 Assert.Throws<ArgumentException> (() => Metafile_IntPtrEmfType ((EmfType)Int32.MinValue));
405 public void Metafile_IntPtrEmfType_EmfOnly ()
407 Metafile_IntPtrEmfType (EmfType.EmfOnly);
411 public void Metafile_IntPtrEmfType_EmfPlusDual ()
413 Metafile_IntPtrEmfType (EmfType.EmfPlusDual);
417 public void Metafile_IntPtrEmfType_EmfPlusOnly ()
419 Metafile_IntPtrEmfType (EmfType.EmfPlusOnly);
423 public void Metafile_IntPtrRectangle_Zero ()
425 Assert.Throws<ArgumentException> (() => new Metafile (IntPtr.Zero, new Rectangle (1, 2, 3, 4)));
429 public void Metafile_IntPtrRectangle_Empty ()
431 using (Bitmap bmp = new Bitmap (10, 10, PixelFormat.Format32bppArgb)) {
432 using (Graphics g = Graphics.FromImage (bmp)) {
433 IntPtr hdc = g.GetHdc ();
435 Metafile mf = new Metafile (hdc, new Rectangle ());
436 CheckEmptyHeader (mf, EmfType.EmfPlusDual);
446 public void Metafile_IntPtrRectangleF_Zero ()
448 Assert.Throws<ArgumentException> (() => new Metafile (IntPtr.Zero, new RectangleF (1, 2, 3, 4)));
452 public void Metafile_IntPtrRectangleF_Empty ()
454 using (Bitmap bmp = new Bitmap (10, 10, PixelFormat.Format32bppArgb)) {
455 using (Graphics g = Graphics.FromImage (bmp)) {
456 IntPtr hdc = g.GetHdc ();
458 Metafile mf = new Metafile (hdc, new RectangleF ());
459 CheckEmptyHeader (mf, EmfType.EmfPlusDual);
468 private void Metafile_StreamEmfType (Stream stream, EmfType type)
470 using (Bitmap bmp = new Bitmap (10, 10, PixelFormat.Format32bppArgb)) {
471 using (Graphics g = Graphics.FromImage (bmp)) {
472 IntPtr hdc = g.GetHdc ();
474 Metafile mf = new Metafile (stream, hdc, type);
475 CheckEmptyHeader (mf, type);
485 public void Metafile_StreamIntPtrEmfType_Null ()
487 Assert.Throws<NullReferenceException> (() => Metafile_StreamEmfType (null, EmfType.EmfOnly));
491 public void Metafile_StreamIntPtrEmfType_EmfOnly ()
493 using (MemoryStream ms = new MemoryStream ()) {
494 Metafile_StreamEmfType (ms, EmfType.EmfOnly);
499 public void Metafile_StreamIntPtrEmfType_Invalid ()
501 using (MemoryStream ms = new MemoryStream ()) {
502 Assert.Throws<ArgumentException> (() => Metafile_StreamEmfType (ms, (EmfType)Int32.MinValue));
506 private void CreateFilename (EmfType type, bool single)
508 string name = String.Format ("{0}-{1}.emf", type, single ? "Single" : "Multiple");
509 string filename = Path.Combine (Path.GetTempPath (), name);
511 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppArgb)) {
512 using (Graphics g = Graphics.FromImage (bmp)) {
513 IntPtr hdc = g.GetHdc ();
515 mf = new Metafile (filename, hdc, type);
516 Assert.AreEqual (0, new FileInfo (filename).Length, "Empty");
523 using (Graphics g = Graphics.FromImage (mf)) {
524 g.FillRectangle (Brushes.BlueViolet, 10, 10, 80, 80);
525 size = new FileInfo (filename).Length;
526 Assert.AreEqual (0, size, "Still-Empty");
528 // FIXME / doesn't work on mono yet
529 // size = new FileInfo (filename).Length;
530 // Assert.IsTrue (size > 0, "Non-Empty/GraphicsDisposed");
532 // can we append stuff ?
533 using (Graphics g = Graphics.FromImage (mf)) {
534 g.DrawRectangle (Pens.Azure, 10, 10, 80, 80);
539 Assert.AreEqual (size, new FileInfo (filename).Length, "Non-Empty/MetafileDisposed");
544 public void CreateFilename_SingleGraphics_EmfOnly ()
546 CreateFilename (EmfType.EmfOnly, true);
550 public void CreateFilename_SingleGraphics_EmfPlusDual ()
552 CreateFilename (EmfType.EmfPlusDual, true);
556 public void CreateFilename_SingleGraphics_EmfPlusOnly ()
558 CreateFilename (EmfType.EmfPlusOnly, true);
562 public void CreateFilename_MultipleGraphics_EmfOnly ()
564 Assert.Throws<OutOfMemoryException> (() => CreateFilename (EmfType.EmfOnly, false));
568 public void CreateFilename_MultipleGraphics_EmfPlusDual ()
570 Assert.Throws<OutOfMemoryException> (() => CreateFilename (EmfType.EmfPlusDual, false));
574 public void CreateFilename_MultipleGraphics_EmfPlusOnly ()
576 Assert.Throws<OutOfMemoryException> (() => CreateFilename (EmfType.EmfPlusOnly, false));
580 public void Measure ()
582 if (test_font == null)
583 Assert.Ignore ("No font family could be found.");
586 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppArgb)) {
587 using (Graphics g = Graphics.FromImage (bmp)) {
588 IntPtr hdc = g.GetHdc ();
590 mf = new Metafile (hdc, EmfType.EmfPlusOnly);
596 using (Graphics g = Graphics.FromImage (mf)) {
597 string text = "this\nis a test";
598 CharacterRange[] ranges = new CharacterRange[2];
599 ranges[0] = new CharacterRange (0, 5);
600 ranges[1] = new CharacterRange (5, 9);
602 SizeF size = g.MeasureString (text, test_font);
603 Assert.IsFalse (size.IsEmpty, "MeasureString");
605 StringFormat sf = new StringFormat ();
606 sf.FormatFlags = StringFormatFlags.NoClip;
607 sf.SetMeasurableCharacterRanges (ranges);
609 RectangleF rect = new RectangleF (0, 0, size.Width, size.Height);
610 Region[] region = g.MeasureCharacterRanges (text, test_font, rect, sf);
611 Assert.AreEqual (2, region.Length, "MeasureCharacterRanges");
618 public void WorldTransforms ()
621 using (Bitmap bmp = new Bitmap (100, 100, PixelFormat.Format32bppArgb)) {
622 using (Graphics g = Graphics.FromImage (bmp)) {
623 IntPtr hdc = g.GetHdc ();
625 mf = new Metafile (hdc, EmfType.EmfPlusOnly);
631 using (Graphics g = Graphics.FromImage (mf)) {
632 Assert.IsTrue (g.Transform.IsIdentity, "Initial/IsIdentity");
633 g.ScaleTransform (2f, 0.5f);
634 Assert.IsFalse (g.Transform.IsIdentity, "Scale/IsIdentity");
635 g.RotateTransform (90);
636 g.TranslateTransform (-2, 2);
637 Matrix m = g.Transform;
638 g.MultiplyTransform (m);
640 float[] elements = g.Transform.Elements;
641 Assert.AreEqual (-1f, elements[0], 0.00001f, "a0");
642 Assert.AreEqual (0f, elements[1], 0.00001f, "a1");
643 Assert.AreEqual (0f, elements[2], 0.00001f, "a2");
644 Assert.AreEqual (-1f, elements[3], 0.00001f, "a3");
645 Assert.AreEqual (-2f, elements[4], 0.00001f, "a4");
646 Assert.AreEqual (-3f, elements[5], 0.00001f, "a5");
649 elements = g.Transform.Elements;
650 Assert.AreEqual (0f, elements[0], 0.00001f, "b0");
651 Assert.AreEqual (0.5f, elements[1], 0.00001f, "b1");
652 Assert.AreEqual (-2f, elements[2], 0.00001f, "b2");
653 Assert.AreEqual (0f, elements[3], 0.00001f, "b3");
654 Assert.AreEqual (-4f, elements[4], 0.00001f, "b4");
655 Assert.AreEqual (-1f, elements[5], 0.00001f, "b5");
658 Assert.IsTrue (g.Transform.IsIdentity, "Reset/IsIdentity");