diff --git a/src/libraries/System.Drawing.Common/src/System.Drawing.Common.csproj b/src/libraries/System.Drawing.Common/src/System.Drawing.Common.csproj index 65731f1d12904..a5fbf0ee8eed1 100644 --- a/src/libraries/System.Drawing.Common/src/System.Drawing.Common.csproj +++ b/src/libraries/System.Drawing.Common/src/System.Drawing.Common.csproj @@ -1,10 +1,10 @@ - + + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) $(DefineConstants);DRAWING_NAMESPACE true CS0618 true - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum)-Unix;$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) enable true true @@ -18,8 +18,9 @@ System.Drawing.Font System.Drawing.Graphics System.Drawing.Icon -Unix support is disabled by default. See https://aka.ms/systemdrawingnonwindows for more information. +Since .NET 7, non-Windows platforms are not supported, even with the runtime configuration switch. See https://aka.ms/systemdrawingnonwindows for more information. + $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) @@ -27,11 +28,9 @@ Unix support is disabled by default. See https://aka.ms/systemdrawingnonwindows true SR.SystemDrawingCommon_PlatformNotSupported - - - - + + @@ -181,72 +180,33 @@ Unix support is disabled by default. See https://aka.ms/systemdrawingnonwindows - - - - - - - - System.Drawing.DefaultComponent.bmp - - - - System.Drawing.ShieldIcon.ico - - - - - - - - - - - + + - - - - + - - - - - - + + + + + - - + - - - - - Component - - - - + + + + + - - - + - @@ -262,6 +222,9 @@ Unix support is disabled by default. See https://aka.ms/systemdrawingnonwindows + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - placeholder.ico - + + + + + + + - + + + + + + + + diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Bitmap.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Bitmap.Unix.cs deleted file mode 100644 index 6d9d13d5f0d3a..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Bitmap.Unix.cs +++ /dev/null @@ -1,66 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// System.Drawing.Bitmap.cs -// -// Copyright (C) 2002 Ximian, Inc. http://www.ximian.com -// Copyright (C) 2004 Novell, Inc. http://www.novell.com -// -// Authors: -// Alexandre Pigolkine (pigolkine@gmx.de) -// Christian Meyer (Christian.Meyer@cs.tum.edu) -// Miguel de Icaza (miguel@ximian.com) -// Jordi Mas i Hernandez (jmas@softcatala.org) -// Ravindra (rkumar@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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// 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.IO; -using System.Drawing.Imaging; -using System.Reflection; -using System.Runtime.Serialization; -using System.Runtime.InteropServices; -using System.ComponentModel; - -namespace System.Drawing -{ - public sealed partial class Bitmap - { - // Usually called when cloning images that need to have - // not only the handle saved, but also the underlying stream - // (when using MS GDI+ and IStream we must ensure the stream stays alive for all the life of the Image) - internal Bitmap(IntPtr ptr, Stream stream) - { - nativeImage = ptr; - } - - public Bitmap(Stream stream, bool useIcm) - { - // false: stream is owned by user code - nativeImage = InitializeFromStream(stream); - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Bitmap.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Bitmap.Windows.cs deleted file mode 100644 index 7670ac88d0227..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Bitmap.Windows.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Internal; -using System.IO; -using Gdip = System.Drawing.SafeNativeMethods.Gdip; - -namespace System.Drawing -{ - public sealed partial class Bitmap - { - public unsafe Bitmap(Stream stream!!, bool useIcm) - { - using DrawingCom.IStreamWrapper streamWrapper = DrawingCom.GetComWrapper(new GPStream(stream)); - - IntPtr bitmap = IntPtr.Zero; - if (useIcm) - { - Gdip.CheckStatus(Gdip.GdipCreateBitmapFromStreamICM(streamWrapper.Ptr, &bitmap)); - } - else - { - Gdip.CheckStatus(Gdip.GdipCreateBitmapFromStream(streamWrapper.Ptr, &bitmap)); - } - - ValidateImage(bitmap); - - SetNativeImage(bitmap); - EnsureSave(this, null, stream); - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Bitmap.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Bitmap.cs index 60a18794093ec..85a5a8012197c 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Bitmap.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Bitmap.cs @@ -3,6 +3,7 @@ using System.ComponentModel; using System.Drawing.Imaging; +using System.Drawing.Internal; using System.IO; using System.Runtime.InteropServices; using Gdip = System.Drawing.SafeNativeMethods.Gdip; @@ -14,7 +15,7 @@ namespace System.Drawing "System.Drawing.Design.UITypeEditor, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] [Serializable] [System.Runtime.CompilerServices.TypeForwardedFrom("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] - public sealed partial class Bitmap : Image + public sealed class Bitmap : Image { private static readonly Color s_defaultTransparentColor = Color.LightGray; @@ -53,12 +54,37 @@ public Bitmap(Stream stream) : this(stream, false) { } + public unsafe Bitmap(Stream stream, bool useIcm) + { + ArgumentNullException.ThrowIfNull(stream); + + using DrawingCom.IStreamWrapper streamWrapper = DrawingCom.GetComWrapper(new GPStream(stream)); + + IntPtr bitmap = IntPtr.Zero; + if (useIcm) + { + Gdip.CheckStatus(Gdip.GdipCreateBitmapFromStreamICM(streamWrapper.Ptr, &bitmap)); + } + else + { + Gdip.CheckStatus(Gdip.GdipCreateBitmapFromStream(streamWrapper.Ptr, &bitmap)); + } + + ValidateImage(bitmap); + + SetNativeImage(bitmap); + EnsureSave(this, null, stream); + } + public Bitmap(Type type, string resource) : this(GetResourceStream(type, resource)) { } - private static Stream GetResourceStream(Type type!!, string resource!!) + private static Stream GetResourceStream(Type type, string resource) { + ArgumentNullException.ThrowIfNull(type); + ArgumentNullException.ThrowIfNull(resource); + Stream? stream = type.Module.Assembly.GetManifestResourceStream(type, resource); if (stream == null) { @@ -72,8 +98,10 @@ public Bitmap(int width, int height) : this(width, height, PixelFormat.Format32b { } - public Bitmap(int width, int height, Graphics g!!) + public Bitmap(int width, int height, Graphics g) { + ArgumentNullException.ThrowIfNull(g); + IntPtr bitmap; int status = Gdip.GdipCreateBitmapFromGraphics(width, height, new HandleRef(g, g.NativeGraphics), out bitmap); Gdip.CheckStatus(status); @@ -107,8 +135,10 @@ public Bitmap(Image original, Size newSize) : this(original, newSize.Width, newS { } - public Bitmap(Image original!!, int width, int height) : this(width, height, PixelFormat.Format32bppArgb) + public Bitmap(Image original, int width, int height) : this(width, height, PixelFormat.Format32bppArgb) { + ArgumentNullException.ThrowIfNull(original); + using (Graphics g = Graphics.FromImage(this)) { g.Clear(Color.Transparent); diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphics.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphics.Unix.cs deleted file mode 100644 index 251fd61538236..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphics.Unix.cs +++ /dev/null @@ -1,95 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// Copyright (C) 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -// Authors: -// -// Jordi Mas i Hernadez -// -// - -using System.ComponentModel; -using System.Runtime.InteropServices; -using System.Runtime.Serialization; - -namespace System.Drawing -{ - public sealed partial class BufferedGraphics - { - private Rectangle size; - private Bitmap membmp; - private Graphics? source; - - internal BufferedGraphics(Graphics? targetGraphics, IntPtr targetDc, Rectangle targetRectangle) - { - _targetGraphics = targetGraphics; - _targetDC = targetDc; - size = targetRectangle; - membmp = new Bitmap(size.Width, size.Height); - } - - public Graphics Graphics - { - get - { - if (source == null && membmp != null) - { - source = Graphics.FromImage(membmp); - } - - return source!; - } - } - - public void Dispose() - { - if (membmp != null) - { - membmp.Dispose(); - membmp = null!; - } - - if (source != null) - { - source.Dispose(); - source = null; - } - - _targetGraphics = null; - } - - public void Render(Graphics? target) - { - if (target == null) - return; - - target.DrawImage(membmp, size); - } - - private void RenderInternal(HandleRef refTargetDC) - { - throw new NotImplementedException(); - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphics.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphics.Windows.cs deleted file mode 100644 index 4ddd7117484d1..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphics.Windows.cs +++ /dev/null @@ -1,100 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.InteropServices; - -namespace System.Drawing -{ - public sealed partial class BufferedGraphics - { - private Graphics _bufferedGraphicsSurface; - private BufferedGraphicsContext _context; - private readonly Point _targetLoc; - private readonly Size _virtualSize; - - /// - /// Internal constructor, this class is created by BufferedGraphicsContext. - /// - internal BufferedGraphics(Graphics bufferedGraphicsSurface, BufferedGraphicsContext context, Graphics? targetGraphics, - IntPtr targetDC, Point targetLoc, Size virtualSize) - { - _context = context; - _bufferedGraphicsSurface = bufferedGraphicsSurface; - _targetDC = targetDC; - _targetGraphics = targetGraphics; - _targetLoc = targetLoc; - _virtualSize = virtualSize; - } - - public void Dispose() - { - if (_context != null) - { - _context.ReleaseBuffer(this); - - if (DisposeContext) - { - _context.Dispose(); - _context = null!; - } - } - - if (_bufferedGraphicsSurface != null) - { - _bufferedGraphicsSurface.Dispose(); - _bufferedGraphicsSurface = null!; - } - } - - /// - /// Allows access to the Graphics wrapper for the buffer. - /// - public Graphics Graphics => _bufferedGraphicsSurface; - - /// - /// Renders the buffer to the specified target graphics. - /// - public void Render(Graphics? target) - { - if (target != null) - { - IntPtr targetDC = target.GetHdc(); - - try - { - RenderInternal(new HandleRef(target, targetDC)); - } - finally - { - target.ReleaseHdcInternal(targetDC); - } - } - } - - /// - /// Internal method that renders the specified buffer into the target. - /// - private void RenderInternal(HandleRef refTargetDC) - { - IntPtr sourceDC = Graphics.GetHdc(); - - try - { - Interop.Gdi32.BitBlt( - refTargetDC, - _targetLoc.X, - _targetLoc.Y, - _virtualSize.Width, - _virtualSize.Height, - new HandleRef(Graphics, sourceDC), - 0, - 0, - Interop.Gdi32.RasterOp.SRCCOPY); - } - finally - { - Graphics.ReleaseHdcInternal(sourceDC); - } - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphics.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphics.cs index 519bf4b519651..256d3fa1b7af8 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphics.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphics.cs @@ -11,10 +11,99 @@ namespace System.Drawing /// buffer is locked. The general design is such that under normal conditions a single BufferedGraphics will be in /// use at one time for a given BufferedGraphicsContext. /// - public sealed partial class BufferedGraphics : IDisposable + public sealed class BufferedGraphics : IDisposable { private Graphics? _targetGraphics; private readonly IntPtr _targetDC; + private Graphics _bufferedGraphicsSurface; + private BufferedGraphicsContext _context; + private readonly Point _targetLoc; + private readonly Size _virtualSize; + + /// + /// Internal constructor, this class is created by BufferedGraphicsContext. + /// + internal BufferedGraphics(Graphics bufferedGraphicsSurface, BufferedGraphicsContext context, Graphics? targetGraphics, + IntPtr targetDC, Point targetLoc, Size virtualSize) + { + _context = context; + _bufferedGraphicsSurface = bufferedGraphicsSurface; + _targetDC = targetDC; + _targetGraphics = targetGraphics; + _targetLoc = targetLoc; + _virtualSize = virtualSize; + } + + public void Dispose() + { + if (_context != null) + { + _context.ReleaseBuffer(this); + + if (DisposeContext) + { + _context.Dispose(); + _context = null!; + } + } + + if (_bufferedGraphicsSurface != null) + { + _bufferedGraphicsSurface.Dispose(); + _bufferedGraphicsSurface = null!; + } + } + + /// + /// Allows access to the Graphics wrapper for the buffer. + /// + public Graphics Graphics => _bufferedGraphicsSurface; + + /// + /// Renders the buffer to the specified target graphics. + /// + public void Render(Graphics? target) + { + if (target != null) + { + IntPtr targetDC = target.GetHdc(); + + try + { + RenderInternal(new HandleRef(target, targetDC)); + } + finally + { + target.ReleaseHdcInternal(targetDC); + } + } + } + + /// + /// Internal method that renders the specified buffer into the target. + /// + private void RenderInternal(HandleRef refTargetDC) + { + IntPtr sourceDC = Graphics.GetHdc(); + + try + { + Interop.Gdi32.BitBlt( + refTargetDC, + _targetLoc.X, + _targetLoc.Y, + _virtualSize.Width, + _virtualSize.Height, + new HandleRef(Graphics, sourceDC), + 0, + 0, + Interop.Gdi32.RasterOp.SRCCOPY); + } + finally + { + Graphics.ReleaseHdcInternal(sourceDC); + } + } /// /// Determines if we need to dispose of the Context when this is disposed. diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphicsContext.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphicsContext.Unix.cs deleted file mode 100644 index 79e54f00e2555..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphicsContext.Unix.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// Copyright (C) 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -// Authors: -// -// Jordi Mas i Hernandez -// -// - -using System.ComponentModel; -using System.Runtime.InteropServices; -using System.Runtime.Serialization; - -namespace System.Drawing -{ - public sealed partial class BufferedGraphicsContext : IDisposable - { -#pragma warning disable CA1822 - private BufferedGraphics AllocBuffer(Graphics? targetGraphics, IntPtr targetDC, Rectangle targetRectangle) - { - BufferedGraphics graphics = new BufferedGraphics(targetGraphics, targetDC, targetRectangle); - return graphics; - } -#pragma warning restore CA1822 - - // Do nothing on Unix. - partial void Dispose(bool disposing); - - public void Invalidate() - { - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphicsContext.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphicsContext.Windows.cs deleted file mode 100644 index 4eb8e61eb2601..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphicsContext.Windows.cs +++ /dev/null @@ -1,431 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Runtime.InteropServices; -using System.Threading; - -namespace System.Drawing -{ - public sealed partial class BufferedGraphicsContext : IDisposable - { - private Size _bufferSize = Size.Empty; - private Size _virtualSize; - private Point _targetLoc; - private IntPtr _compatDC; - private IntPtr _dib; - private IntPtr _oldBitmap; - private Graphics? _compatGraphics; - private BufferedGraphics? _buffer; - private int _busy; - private bool _invalidateWhenFree; - - private const int BufferFree = 0; // The graphics buffer is free to use. - private const int BufferBusyPainting = 1; // The graphics buffer is busy being created/painting. - private const int BufferBusyDisposing = 2; // The graphics buffer is busy disposing. - - /// - /// Returns a BufferedGraphics that is matched for the specified target HDC object. - /// - private BufferedGraphics AllocBuffer(Graphics? targetGraphics, IntPtr targetDC, Rectangle targetRectangle) - { - int oldBusy = Interlocked.CompareExchange(ref _busy, BufferBusyPainting, BufferFree); - - // In the case were we have contention on the buffer - i.e. two threads - // trying to use the buffer at the same time, we just create a temp - // buffermanager and have the buffer dispose of it when it is done. - // - if (oldBusy != BufferFree) - { - return AllocBufferInTempManager(targetGraphics, targetDC, targetRectangle); - } - - Graphics surface; - _targetLoc = new Point(targetRectangle.X, targetRectangle.Y); - - try - { - if (targetGraphics != null) - { - IntPtr destDc = targetGraphics.GetHdc(); - try - { - surface = CreateBuffer(destDc, -_targetLoc.X, -_targetLoc.Y, targetRectangle.Width, targetRectangle.Height); - } - finally - { - targetGraphics.ReleaseHdcInternal(destDc); - } - } - else - { - surface = CreateBuffer(targetDC, -_targetLoc.X, -_targetLoc.Y, targetRectangle.Width, targetRectangle.Height); - } - - _buffer = new BufferedGraphics(surface, this, targetGraphics, targetDC, _targetLoc, _virtualSize); - } - catch - { - // Free the buffer so it can be disposed. - _busy = BufferFree; - throw; - } - - return _buffer; - } - - /// - /// Fills in the fields of a BITMAPINFO so that we can create a bitmap - /// that matches the format of the display. - /// - /// This is done by creating a compatible bitmap and calling GetDIBits - /// to return the color masks. This is done with two calls. The first - /// call passes in biBitCount = 0 to GetDIBits which will fill in the - /// base BITMAPINFOHEADER data. The second call to GetDIBits (passing - /// in the BITMAPINFO filled in by the first call) will return the color - /// table or bitmasks, as appropriate. - /// - /// True if successful, false otherwise. - private unsafe bool FillBitmapInfo(IntPtr hdc, IntPtr hpal, ref Interop.Gdi32.BITMAPINFO_FLAT pbmi) - { - IntPtr hbm = IntPtr.Zero; - bool bRet = false; - try - { - // Create a dummy bitmap from which we can query color format info - // about the device surface. - hbm = Interop.Gdi32.CreateCompatibleBitmap(new HandleRef(null, hdc), 1, 1); - - if (hbm == IntPtr.Zero) - { - throw new OutOfMemoryException(SR.GraphicsBufferQueryFail); - } - - pbmi.bmiHeader_biSize = sizeof(NativeMethods.BITMAPINFOHEADER); - - // Call first time to fill in BITMAPINFO header. - Interop.Gdi32.GetDIBits(new HandleRef(null, hdc), - new HandleRef(null, hbm), - 0, - 0, - IntPtr.Zero, - ref pbmi, - NativeMethods.DIB_RGB_COLORS); - - if (pbmi.bmiHeader_biBitCount <= 8) - { - bRet = FillColorTable(hdc, hpal, ref pbmi); - } - else - { - if (pbmi.bmiHeader_biCompression == NativeMethods.BI_BITFIELDS) - { - // Call a second time to get the color masks. - Interop.Gdi32.GetDIBits(new HandleRef(null, hdc), - new HandleRef(null, hbm), - 0, - pbmi.bmiHeader_biHeight, - IntPtr.Zero, - ref pbmi, - NativeMethods.DIB_RGB_COLORS); - } - bRet = true; - } - } - finally - { - if (hbm != IntPtr.Zero) - { - Interop.Gdi32.DeleteObject(hbm); - } - } - return bRet; - } - - /// - /// Initialize the color table of the BITMAPINFO pointed to by pbmi. Colors - /// are set to the current system palette. - /// - /// Note: call only valid for displays of 8bpp or less. - /// - /// True is successful, false otherwise. - private unsafe bool FillColorTable(IntPtr hdc, IntPtr hpal, ref Interop.Gdi32.BITMAPINFO_FLAT pbmi) - { - byte[] aj = new byte[sizeof(NativeMethods.PALETTEENTRY) * 256]; - - fixed (byte* pcolors = pbmi.bmiColors) - { - fixed (byte* ppal = aj) - { - NativeMethods.RGBQUAD* prgb = (NativeMethods.RGBQUAD*)pcolors; - NativeMethods.PALETTEENTRY* lppe = (NativeMethods.PALETTEENTRY*)ppal; - - int cColors = 1 << pbmi.bmiHeader_biBitCount; - if (cColors <= 256) - { - // Note: we don't support 4bpp displays. - uint palRet; - IntPtr palHalftone = IntPtr.Zero; - if (hpal == IntPtr.Zero) - { - palHalftone = Graphics.GetHalftonePalette(); - palRet = Interop.Gdi32.GetPaletteEntries(new HandleRef(null, palHalftone), 0, cColors, aj); - } - else - { - palRet = Interop.Gdi32.GetPaletteEntries(new HandleRef(null, hpal), 0, cColors, aj); - } - - if (palRet != 0) - { - for (int i = 0; i < cColors; i++) - { - prgb[i].rgbRed = lppe[i].peRed; - prgb[i].rgbGreen = lppe[i].peGreen; - prgb[i].rgbBlue = lppe[i].peBlue; - prgb[i].rgbReserved = 0; - } - - return true; - } - } - } - } - - return false; - } - - /// - /// Returns a Graphics object representing a buffer. - /// - private Graphics CreateBuffer(IntPtr src, int offsetX, int offsetY, int width, int height) - { - // Create the compat DC. - _busy = BufferBusyDisposing; - DisposeDC(); - _busy = BufferBusyPainting; - _compatDC = Interop.Gdi32.CreateCompatibleDC(src); - - // Recreate the bitmap if necessary. - if (width > _bufferSize.Width || height > _bufferSize.Height) - { - int optWidth = Math.Max(width, _bufferSize.Width); - int optHeight = Math.Max(height, _bufferSize.Height); - - _busy = BufferBusyDisposing; - DisposeBitmap(); - _busy = BufferBusyPainting; - - IntPtr pvbits = IntPtr.Zero; - _dib = CreateCompatibleDIB(src, IntPtr.Zero, optWidth, optHeight, ref pvbits); - _bufferSize = new Size(optWidth, optHeight); - } - - // Select the bitmap. - _oldBitmap = Interop.Kernel32.SelectObject(new HandleRef(this, _compatDC), new HandleRef(this, _dib)); - - // Create compat graphics. - _compatGraphics = Graphics.FromHdcInternal(_compatDC); - _compatGraphics.TranslateTransform(-_targetLoc.X, -_targetLoc.Y); - _virtualSize = new Size(width, height); - - return _compatGraphics; - } - - /// - /// Create a DIB section with an optimal format w.r.t. the specified hdc. - /// - /// If DIB <= 8bpp, then the DIB color table is initialized based on the - /// specified palette. If the palette handle is NULL, then the system - /// palette is used. - /// - /// Note: The hdc must be a direct DC (not an info or memory DC). - /// - /// Note: On palettized displays, if the system palette changes the - /// UpdateDIBColorTable function should be called to maintain - /// the identity palette mapping between the DIB and the display. - /// - /// A valid bitmap handle if successful, IntPtr.Zero otherwise. - private IntPtr CreateCompatibleDIB(IntPtr hdc, IntPtr hpal, int ulWidth, int ulHeight, ref IntPtr ppvBits) - { - if (hdc == IntPtr.Zero) - { - throw new ArgumentNullException(nameof(hdc)); - } - - IntPtr hbmRet = IntPtr.Zero; - Interop.Gdi32.BITMAPINFO_FLAT pbmi = default; - - // Validate hdc. - Interop.Gdi32.ObjectType objType = Interop.Gdi32.GetObjectType(hdc); - switch (objType) - { - case Interop.Gdi32.ObjectType.OBJ_DC: - case Interop.Gdi32.ObjectType.OBJ_METADC: - case Interop.Gdi32.ObjectType.OBJ_MEMDC: - case Interop.Gdi32.ObjectType.OBJ_ENHMETADC: - break; - default: - throw new ArgumentException(SR.DCTypeInvalid); - } - - if (FillBitmapInfo(hdc, hpal, ref pbmi)) - { - // Change bitmap size to match specified dimensions. - pbmi.bmiHeader_biWidth = ulWidth; - pbmi.bmiHeader_biHeight = ulHeight; - if (pbmi.bmiHeader_biCompression == NativeMethods.BI_RGB) - { - pbmi.bmiHeader_biSizeImage = 0; - } - else - { - if (pbmi.bmiHeader_biBitCount == 16) - { - pbmi.bmiHeader_biSizeImage = ulWidth * ulHeight * 2; - } - else if (pbmi.bmiHeader_biBitCount == 32) - { - pbmi.bmiHeader_biSizeImage = ulWidth * ulHeight * 4; - } - else - { - pbmi.bmiHeader_biSizeImage = 0; - } - } - pbmi.bmiHeader_biClrUsed = 0; - pbmi.bmiHeader_biClrImportant = 0; - - // Create the DIB section. Let Win32 allocate the memory and return - // a pointer to the bitmap surface. - hbmRet = Interop.Gdi32.CreateDIBSection(new HandleRef(null, hdc), ref pbmi, NativeMethods.DIB_RGB_COLORS, ref ppvBits, IntPtr.Zero, 0); - Win32Exception? ex = null; - if (hbmRet == IntPtr.Zero) - { - ex = new Win32Exception(Marshal.GetLastWin32Error()); - } - - if (ex != null) - { - throw ex; - } - } - - return hbmRet; - } - - /// - /// Disposes the DC, but leaves the bitmap alone. - /// - private void DisposeDC() - { - if (_oldBitmap != IntPtr.Zero && _compatDC != IntPtr.Zero) - { - Interop.Kernel32.SelectObject(new HandleRef(this, _compatDC), new HandleRef(this, _oldBitmap)); - _oldBitmap = IntPtr.Zero; - } - - if (_compatDC != IntPtr.Zero) - { - Interop.Gdi32.DeleteDC(new HandleRef(this, _compatDC)); - _compatDC = IntPtr.Zero; - } - } - - /// - /// Disposes the bitmap, will ASSERT if bitmap is being used (checks oldbitmap). if ASSERTed, call DisposeDC() first. - /// - private void DisposeBitmap() - { - if (_dib != IntPtr.Zero) - { - Debug.Assert(_oldBitmap == IntPtr.Zero); - - Interop.Gdi32.DeleteObject(new HandleRef(this, _dib)); - _dib = IntPtr.Zero; - } - } - - /// - /// Disposes of the Graphics buffer. - /// - private void Dispose(bool disposing) - { - int oldBusy = Interlocked.CompareExchange(ref _busy, BufferBusyDisposing, BufferFree); - - if (disposing) - { - if (oldBusy == BufferBusyPainting) - { - throw new InvalidOperationException(SR.GraphicsBufferCurrentlyBusy); - } - - if (_compatGraphics != null) - { - _compatGraphics.Dispose(); - _compatGraphics = null; - } - } - - DisposeDC(); - DisposeBitmap(); - - if (_buffer != null) - { - _buffer.Dispose(); - _buffer = null; - } - - _bufferSize = Size.Empty; - _virtualSize = Size.Empty; - - _busy = BufferFree; - } - - /// - /// Invalidates the cached graphics buffer. - /// - public void Invalidate() - { - int oldBusy = Interlocked.CompareExchange(ref _busy, BufferBusyDisposing, BufferFree); - - // If we're not busy with our buffer, lets clean it up now - if (oldBusy == BufferFree) - { - Dispose(); - _busy = BufferFree; - } - else - { - // This will indicate to free the buffer as soon as it becomes non-busy. - _invalidateWhenFree = true; - } - } - - /// - /// Returns a Graphics object representing a buffer. - /// - internal void ReleaseBuffer(BufferedGraphics buffer) - { - _buffer = null; - if (_invalidateWhenFree) - { - // Clears everything including the bitmap. - _busy = BufferBusyDisposing; - Dispose(); - } - else - { - // Otherwise, just dispose the DC. A new one will be created next time. - _busy = BufferBusyDisposing; - - // Only clears out the DC. - DisposeDC(); - } - - _busy = BufferFree; - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphicsContext.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphicsContext.cs index c74b1e3860001..2559c26e1440e 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphicsContext.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphicsContext.cs @@ -1,17 +1,33 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.ComponentModel; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Threading; namespace System.Drawing { /// /// The BufferedGraphicsContext class can be used to perform standard double buffer rendering techniques. /// - public sealed partial class BufferedGraphicsContext : IDisposable + public sealed class BufferedGraphicsContext : IDisposable { private Size _maximumBuffer; + private Size _bufferSize = Size.Empty; + private Size _virtualSize; + private Point _targetLoc; + private IntPtr _compatDC; + private IntPtr _dib; + private IntPtr _oldBitmap; + private Graphics? _compatGraphics; + private BufferedGraphics? _buffer; + private int _busy; + private bool _invalidateWhenFree; + + private const int BufferFree = 0; // The graphics buffer is free to use. + private const int BufferBusyPainting = 1; // The graphics buffer is busy being created/painting. + private const int BufferBusyDisposing = 2; // The graphics buffer is busy disposing. /// /// Basic constructor. @@ -78,6 +94,56 @@ public BufferedGraphics Allocate(IntPtr targetDC, Rectangle targetRectangle) return AllocBuffer(null, targetDC, targetRectangle); } + /// + /// Returns a BufferedGraphics that is matched for the specified target HDC object. + /// + private BufferedGraphics AllocBuffer(Graphics? targetGraphics, IntPtr targetDC, Rectangle targetRectangle) + { + int oldBusy = Interlocked.CompareExchange(ref _busy, BufferBusyPainting, BufferFree); + + // In the case were we have contention on the buffer - i.e. two threads + // trying to use the buffer at the same time, we just create a temp + // buffermanager and have the buffer dispose of it when it is done. + // + if (oldBusy != BufferFree) + { + return AllocBufferInTempManager(targetGraphics, targetDC, targetRectangle); + } + + Graphics surface; + _targetLoc = new Point(targetRectangle.X, targetRectangle.Y); + + try + { + if (targetGraphics != null) + { + IntPtr destDc = targetGraphics.GetHdc(); + try + { + surface = CreateBuffer(destDc, -_targetLoc.X, -_targetLoc.Y, targetRectangle.Width, targetRectangle.Height); + } + finally + { + targetGraphics.ReleaseHdcInternal(destDc); + } + } + else + { + surface = CreateBuffer(targetDC, -_targetLoc.X, -_targetLoc.Y, targetRectangle.Width, targetRectangle.Height); + } + + _buffer = new BufferedGraphics(surface, this, targetGraphics, targetDC, _targetLoc, _virtualSize); + } + catch + { + // Free the buffer so it can be disposed. + _busy = BufferFree; + throw; + } + + return _buffer; + } + /// /// Returns a BufferedGraphics that is matched for the specified target HDC object. /// @@ -120,5 +186,357 @@ private bool ShouldUseTempManager(Rectangle targetBounds) { return (targetBounds.Width * targetBounds.Height) > (MaximumBuffer.Width * MaximumBuffer.Height); } + + /// + /// Fills in the fields of a BITMAPINFO so that we can create a bitmap + /// that matches the format of the display. + /// + /// This is done by creating a compatible bitmap and calling GetDIBits + /// to return the color masks. This is done with two calls. The first + /// call passes in biBitCount = 0 to GetDIBits which will fill in the + /// base BITMAPINFOHEADER data. The second call to GetDIBits (passing + /// in the BITMAPINFO filled in by the first call) will return the color + /// table or bitmasks, as appropriate. + /// + /// True if successful, false otherwise. + private unsafe bool FillBitmapInfo(IntPtr hdc, IntPtr hpal, ref Interop.Gdi32.BITMAPINFO_FLAT pbmi) + { + IntPtr hbm = IntPtr.Zero; + bool bRet = false; + try + { + // Create a dummy bitmap from which we can query color format info + // about the device surface. + hbm = Interop.Gdi32.CreateCompatibleBitmap(new HandleRef(null, hdc), 1, 1); + + if (hbm == IntPtr.Zero) + { + throw new OutOfMemoryException(SR.GraphicsBufferQueryFail); + } + + pbmi.bmiHeader_biSize = sizeof(NativeMethods.BITMAPINFOHEADER); + + // Call first time to fill in BITMAPINFO header. + Interop.Gdi32.GetDIBits(new HandleRef(null, hdc), + new HandleRef(null, hbm), + 0, + 0, + IntPtr.Zero, + ref pbmi, + NativeMethods.DIB_RGB_COLORS); + + if (pbmi.bmiHeader_biBitCount <= 8) + { + bRet = FillColorTable(hdc, hpal, ref pbmi); + } + else + { + if (pbmi.bmiHeader_biCompression == NativeMethods.BI_BITFIELDS) + { + // Call a second time to get the color masks. + Interop.Gdi32.GetDIBits(new HandleRef(null, hdc), + new HandleRef(null, hbm), + 0, + pbmi.bmiHeader_biHeight, + IntPtr.Zero, + ref pbmi, + NativeMethods.DIB_RGB_COLORS); + } + bRet = true; + } + } + finally + { + if (hbm != IntPtr.Zero) + { + Interop.Gdi32.DeleteObject(hbm); + } + } + return bRet; + } + + /// + /// Initialize the color table of the BITMAPINFO pointed to by pbmi. Colors + /// are set to the current system palette. + /// + /// Note: call only valid for displays of 8bpp or less. + /// + /// True is successful, false otherwise. + private unsafe bool FillColorTable(IntPtr hdc, IntPtr hpal, ref Interop.Gdi32.BITMAPINFO_FLAT pbmi) + { + byte[] aj = new byte[sizeof(NativeMethods.PALETTEENTRY) * 256]; + + fixed (byte* pcolors = pbmi.bmiColors) + { + fixed (byte* ppal = aj) + { + NativeMethods.RGBQUAD* prgb = (NativeMethods.RGBQUAD*)pcolors; + NativeMethods.PALETTEENTRY* lppe = (NativeMethods.PALETTEENTRY*)ppal; + + int cColors = 1 << pbmi.bmiHeader_biBitCount; + if (cColors <= 256) + { + // Note: we don't support 4bpp displays. + uint palRet; + IntPtr palHalftone = IntPtr.Zero; + if (hpal == IntPtr.Zero) + { + palHalftone = Graphics.GetHalftonePalette(); + palRet = Interop.Gdi32.GetPaletteEntries(new HandleRef(null, palHalftone), 0, cColors, aj); + } + else + { + palRet = Interop.Gdi32.GetPaletteEntries(new HandleRef(null, hpal), 0, cColors, aj); + } + + if (palRet != 0) + { + for (int i = 0; i < cColors; i++) + { + prgb[i].rgbRed = lppe[i].peRed; + prgb[i].rgbGreen = lppe[i].peGreen; + prgb[i].rgbBlue = lppe[i].peBlue; + prgb[i].rgbReserved = 0; + } + + return true; + } + } + } + } + + return false; + } + + /// + /// Returns a Graphics object representing a buffer. + /// + private Graphics CreateBuffer(IntPtr src, int offsetX, int offsetY, int width, int height) + { + // Create the compat DC. + _busy = BufferBusyDisposing; + DisposeDC(); + _busy = BufferBusyPainting; + _compatDC = Interop.Gdi32.CreateCompatibleDC(src); + + // Recreate the bitmap if necessary. + if (width > _bufferSize.Width || height > _bufferSize.Height) + { + int optWidth = Math.Max(width, _bufferSize.Width); + int optHeight = Math.Max(height, _bufferSize.Height); + + _busy = BufferBusyDisposing; + DisposeBitmap(); + _busy = BufferBusyPainting; + + IntPtr pvbits = IntPtr.Zero; + _dib = CreateCompatibleDIB(src, IntPtr.Zero, optWidth, optHeight, ref pvbits); + _bufferSize = new Size(optWidth, optHeight); + } + + // Select the bitmap. + _oldBitmap = Interop.Kernel32.SelectObject(new HandleRef(this, _compatDC), new HandleRef(this, _dib)); + + // Create compat graphics. + _compatGraphics = Graphics.FromHdcInternal(_compatDC); + _compatGraphics.TranslateTransform(-_targetLoc.X, -_targetLoc.Y); + _virtualSize = new Size(width, height); + + return _compatGraphics; + } + + /// + /// Create a DIB section with an optimal format w.r.t. the specified hdc. + /// + /// If DIB <= 8bpp, then the DIB color table is initialized based on the + /// specified palette. If the palette handle is NULL, then the system + /// palette is used. + /// + /// Note: The hdc must be a direct DC (not an info or memory DC). + /// + /// Note: On palettized displays, if the system palette changes the + /// UpdateDIBColorTable function should be called to maintain + /// the identity palette mapping between the DIB and the display. + /// + /// A valid bitmap handle if successful, IntPtr.Zero otherwise. + private IntPtr CreateCompatibleDIB(IntPtr hdc, IntPtr hpal, int ulWidth, int ulHeight, ref IntPtr ppvBits) + { + if (hdc == IntPtr.Zero) + { + throw new ArgumentNullException(nameof(hdc)); + } + + IntPtr hbmRet = IntPtr.Zero; + Interop.Gdi32.BITMAPINFO_FLAT pbmi = default; + + // Validate hdc. + Interop.Gdi32.ObjectType objType = Interop.Gdi32.GetObjectType(hdc); + switch (objType) + { + case Interop.Gdi32.ObjectType.OBJ_DC: + case Interop.Gdi32.ObjectType.OBJ_METADC: + case Interop.Gdi32.ObjectType.OBJ_MEMDC: + case Interop.Gdi32.ObjectType.OBJ_ENHMETADC: + break; + default: + throw new ArgumentException(SR.DCTypeInvalid); + } + + if (FillBitmapInfo(hdc, hpal, ref pbmi)) + { + // Change bitmap size to match specified dimensions. + pbmi.bmiHeader_biWidth = ulWidth; + pbmi.bmiHeader_biHeight = ulHeight; + if (pbmi.bmiHeader_biCompression == NativeMethods.BI_RGB) + { + pbmi.bmiHeader_biSizeImage = 0; + } + else + { + if (pbmi.bmiHeader_biBitCount == 16) + { + pbmi.bmiHeader_biSizeImage = ulWidth * ulHeight * 2; + } + else if (pbmi.bmiHeader_biBitCount == 32) + { + pbmi.bmiHeader_biSizeImage = ulWidth * ulHeight * 4; + } + else + { + pbmi.bmiHeader_biSizeImage = 0; + } + } + pbmi.bmiHeader_biClrUsed = 0; + pbmi.bmiHeader_biClrImportant = 0; + + // Create the DIB section. Let Win32 allocate the memory and return + // a pointer to the bitmap surface. + hbmRet = Interop.Gdi32.CreateDIBSection(new HandleRef(null, hdc), ref pbmi, NativeMethods.DIB_RGB_COLORS, ref ppvBits, IntPtr.Zero, 0); + Win32Exception? ex = null; + if (hbmRet == IntPtr.Zero) + { + ex = new Win32Exception(Marshal.GetLastWin32Error()); + } + + if (ex != null) + { + throw ex; + } + } + + return hbmRet; + } + + /// + /// Disposes the DC, but leaves the bitmap alone. + /// + private void DisposeDC() + { + if (_oldBitmap != IntPtr.Zero && _compatDC != IntPtr.Zero) + { + Interop.Kernel32.SelectObject(new HandleRef(this, _compatDC), new HandleRef(this, _oldBitmap)); + _oldBitmap = IntPtr.Zero; + } + + if (_compatDC != IntPtr.Zero) + { + Interop.Gdi32.DeleteDC(new HandleRef(this, _compatDC)); + _compatDC = IntPtr.Zero; + } + } + + /// + /// Disposes the bitmap, will ASSERT if bitmap is being used (checks oldbitmap). if ASSERTed, call DisposeDC() first. + /// + private void DisposeBitmap() + { + if (_dib != IntPtr.Zero) + { + Debug.Assert(_oldBitmap == IntPtr.Zero); + + Interop.Gdi32.DeleteObject(new HandleRef(this, _dib)); + _dib = IntPtr.Zero; + } + } + + /// + /// Disposes of the Graphics buffer. + /// + private void Dispose(bool disposing) + { + int oldBusy = Interlocked.CompareExchange(ref _busy, BufferBusyDisposing, BufferFree); + + if (disposing) + { + if (oldBusy == BufferBusyPainting) + { + throw new InvalidOperationException(SR.GraphicsBufferCurrentlyBusy); + } + + if (_compatGraphics != null) + { + _compatGraphics.Dispose(); + _compatGraphics = null; + } + } + + DisposeDC(); + DisposeBitmap(); + + if (_buffer != null) + { + _buffer.Dispose(); + _buffer = null; + } + + _bufferSize = Size.Empty; + _virtualSize = Size.Empty; + + _busy = BufferFree; + } + + /// + /// Invalidates the cached graphics buffer. + /// + public void Invalidate() + { + int oldBusy = Interlocked.CompareExchange(ref _busy, BufferBusyDisposing, BufferFree); + + // If we're not busy with our buffer, lets clean it up now + if (oldBusy == BufferFree) + { + Dispose(); + _busy = BufferFree; + } + else + { + // This will indicate to free the buffer as soon as it becomes non-busy. + _invalidateWhenFree = true; + } + } + + /// + /// Returns a Graphics object representing a buffer. + /// + internal void ReleaseBuffer(BufferedGraphics buffer) + { + _buffer = null; + if (_invalidateWhenFree) + { + // Clears everything including the bitmap. + _busy = BufferBusyDisposing; + Dispose(); + } + else + { + // Otherwise, just dispose the DC. A new one will be created next time. + _busy = BufferBusyDisposing; + + // Only clears out the DC. + DisposeDC(); + } + + _busy = BufferFree; + } } } diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphicsManager.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphicsManager.Unix.cs deleted file mode 100644 index e0575dd48ac88..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphicsManager.Unix.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// Copyright (C) 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -// Authors: -// -// Jordi Mas i Hernadez -// -// - -namespace System.Drawing -{ - public static class BufferedGraphicsManager - { - public static BufferedGraphicsContext Current { get; } = new BufferedGraphicsContext(); - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphicsManager.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphicsManager.cs similarity index 100% rename from src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphicsManager.Windows.cs rename to src/libraries/System.Drawing.Common/src/System/Drawing/BufferedGraphicsManager.cs diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/AdjustableArrowCap.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/AdjustableArrowCap.Unix.cs deleted file mode 100644 index 2285303420175..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/AdjustableArrowCap.Unix.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.InteropServices; -using Gdip = System.Drawing.SafeNativeMethods.Gdip; - -namespace System.Drawing.Drawing2D -{ - public sealed partial class AdjustableArrowCap : CustomLineCap - { - internal override object CoreClone() - { - IntPtr clonedCap; - int status = Gdip.GdipCloneCustomLineCap(new HandleRef(this, nativeCap), out clonedCap); - Gdip.CheckStatus(status); - - return new AdjustableArrowCap(clonedCap); - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/CustomLineCap.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/CustomLineCap.Unix.cs deleted file mode 100644 index 09ae929d4c61b..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/CustomLineCap.Unix.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.InteropServices; - -namespace System.Drawing.Drawing2D -{ - public partial class CustomLineCap - { - internal static CustomLineCap CreateCustomLineCapObject(IntPtr cap) - { - // libgdiplus does not implement GdipGetCustomLineCapType, so it will not correctly handle - // AdjustableArrowCap objects. - return new CustomLineCap(cap); - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/CustomLineCap.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/CustomLineCap.Windows.cs deleted file mode 100644 index 51f152c99f5f2..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/CustomLineCap.Windows.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.InteropServices; -using Gdip = System.Drawing.SafeNativeMethods.Gdip; - -namespace System.Drawing.Drawing2D -{ - public partial class CustomLineCap - { - internal static CustomLineCap CreateCustomLineCapObject(IntPtr cap) - { - int status = Gdip.GdipGetCustomLineCapType(cap, out CustomLineCapType capType); - if (status != Gdip.Ok) - { - Gdip.GdipDeleteCustomLineCap(cap); - throw Gdip.StatusException(status); - } - - switch (capType) - { - case CustomLineCapType.Default: - return new CustomLineCap(cap); - - case CustomLineCapType.AdjustableArrowCap: - return new AdjustableArrowCap(cap); - } - - Gdip.GdipDeleteCustomLineCap(cap); - throw Gdip.StatusException(Gdip.NotImplemented); - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/CustomLineCap.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/CustomLineCap.cs index 339084fe9e01f..481fdce78c88f 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/CustomLineCap.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/CustomLineCap.cs @@ -6,7 +6,7 @@ namespace System.Drawing.Drawing2D { - public partial class CustomLineCap : MarshalByRefObject, ICloneable, IDisposable + public class CustomLineCap : MarshalByRefObject, ICloneable, IDisposable { #if FINALIZATION_WATCH private string allocationSite = Graphics.GetAllocationStack(); @@ -40,6 +40,28 @@ public CustomLineCap(GraphicsPath? fillPath, GraphicsPath? strokePath, LineCap b internal CustomLineCap(IntPtr nativeLineCap) => SetNativeLineCap(nativeLineCap); + internal static CustomLineCap CreateCustomLineCapObject(IntPtr cap) + { + int status = Gdip.GdipGetCustomLineCapType(cap, out CustomLineCapType capType); + if (status != Gdip.Ok) + { + Gdip.GdipDeleteCustomLineCap(cap); + throw Gdip.StatusException(status); + } + + switch (capType) + { + case CustomLineCapType.Default: + return new CustomLineCap(cap); + + case CustomLineCapType.AdjustableArrowCap: + return new AdjustableArrowCap(cap); + } + + Gdip.GdipDeleteCustomLineCap(cap); + throw Gdip.StatusException(Gdip.NotImplemented); + } + internal void SetNativeLineCap(IntPtr handle) { if (handle == IntPtr.Zero) diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPath.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPath.Unix.cs deleted file mode 100644 index f644b3d2a9a4a..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPath.Unix.cs +++ /dev/null @@ -1,830 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// System.Drawing.Drawing2D.GraphicsPath.cs -// -// Authors: -// -// Miguel de Icaza (miguel@ximian.com) -// Duncan Mak (duncan@ximian.com) -// Jordi Mas i Hernandez (jordi@ximian.com) -// Ravindra (rkumar@novell.com) -// Sebastien Pouliot -// -// Copyright (C) 2004,2006-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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// 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.ComponentModel; -using System.Runtime.InteropServices; -using Gdip = System.Drawing.SafeNativeMethods.Gdip; - -namespace System.Drawing.Drawing2D -{ - public sealed class GraphicsPath : MarshalByRefObject, ICloneable, IDisposable - { - // 1/4 is the FlatnessDefault as defined in GdiPlusEnums.h - private const float FlatnessDefault = 1.0f / 4.0f; - - internal IntPtr _nativePath = IntPtr.Zero; - - private GraphicsPath(IntPtr ptr) - { - _nativePath = ptr; - } - - public GraphicsPath() - { - int status = Gdip.GdipCreatePath(FillMode.Alternate, out _nativePath); - Gdip.CheckStatus(status); - } - - public GraphicsPath(FillMode fillMode) - { - int status = Gdip.GdipCreatePath(fillMode, out _nativePath); - Gdip.CheckStatus(status); - } - - public GraphicsPath(Point[] pts, byte[] types) - : this(pts, types, FillMode.Alternate) - { - } - - public GraphicsPath(PointF[] pts, byte[] types) - : this(pts, types, FillMode.Alternate) - { - } - - public GraphicsPath(Point[] pts!!, byte[] types, FillMode fillMode) - { - if (pts.Length != types.Length) - throw new ArgumentException(SR.NumberOfPointsAndTypesMustBeSame); - - int status = Gdip.GdipCreatePath2I(pts, types, pts.Length, fillMode, out _nativePath); - Gdip.CheckStatus(status); - } - - public GraphicsPath(PointF[] pts!!, byte[] types, FillMode fillMode) - { - if (pts.Length != types.Length) - throw new ArgumentException(SR.NumberOfPointsAndTypesMustBeSame); - - int status = Gdip.GdipCreatePath2(pts, types, pts.Length, fillMode, out _nativePath); - Gdip.CheckStatus(status); - } - - public object Clone() - { - IntPtr clone; - - int status = Gdip.GdipClonePath(_nativePath, out clone); - Gdip.CheckStatus(status); - - return new GraphicsPath(clone); - } - - public void Dispose() - { - Dispose(true); - System.GC.SuppressFinalize(this); - } - - ~GraphicsPath() - { - Dispose(false); - } - - private void Dispose(bool disposing) - { - int status; - if (_nativePath != IntPtr.Zero) - { - status = Gdip.GdipDeletePath(new HandleRef(this, _nativePath)); - Gdip.CheckStatus(status); - - _nativePath = IntPtr.Zero; - } - } - - public FillMode FillMode - { - get - { - FillMode mode; - int status = Gdip.GdipGetPathFillMode(_nativePath, out mode); - Gdip.CheckStatus(status); - - return mode; - } - set - { - if ((value < FillMode.Alternate) || (value > FillMode.Winding)) - throw new InvalidEnumArgumentException(nameof(FillMode), (int)value, typeof(FillMode)); - - int status = Gdip.GdipSetPathFillMode(_nativePath, value); - Gdip.CheckStatus(status); - } - } - - public PathData PathData - { - get - { - int count; - int status = Gdip.GdipGetPointCount(_nativePath, out count); - Gdip.CheckStatus(status); - - PointF[] points = new PointF[count]; - byte[] types = new byte[count]; - - // status would fail if we ask points or types with a 0 count - // anyway that would only mean two unrequired unmanaged calls - if (count > 0) - { - status = Gdip.GdipGetPathPoints(_nativePath, points, count); - Gdip.CheckStatus(status); - - status = Gdip.GdipGetPathTypes(_nativePath, types, count); - Gdip.CheckStatus(status); - } - - PathData pdata = new PathData(); - pdata.Points = points; - pdata.Types = types; - return pdata; - } - } - - public PointF[] PathPoints - { - get - { - int count; - int status = Gdip.GdipGetPointCount(_nativePath, out count); - Gdip.CheckStatus(status); - if (count == 0) - throw new ArgumentException("PathPoints"); - - PointF[] points = new PointF[count]; - status = Gdip.GdipGetPathPoints(_nativePath, points, count); - Gdip.CheckStatus(status); - - return points; - } - } - - public byte[] PathTypes - { - get - { - int count; - int status = Gdip.GdipGetPointCount(_nativePath, out count); - Gdip.CheckStatus(status); - if (count == 0) - throw new ArgumentException("PathTypes"); - - byte[] types = new byte[count]; - status = Gdip.GdipGetPathTypes(_nativePath, types, count); - Gdip.CheckStatus(status); - - return types; - } - } - - public int PointCount - { - get - { - int count; - int status = Gdip.GdipGetPointCount(_nativePath, out count); - Gdip.CheckStatus(status); - - return count; - } - } - - internal IntPtr NativeObject - { - get - { - return _nativePath; - } - set - { - _nativePath = value; - } - } - - // - // AddArc - // - public void AddArc(Rectangle rect, float startAngle, float sweepAngle) - { - int status = Gdip.GdipAddPathArcI(_nativePath, rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle); - Gdip.CheckStatus(status); - } - - public void AddArc(RectangleF rect, float startAngle, float sweepAngle) - { - int status = Gdip.GdipAddPathArc(_nativePath, rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle); - Gdip.CheckStatus(status); - } - - public void AddArc(int x, int y, int width, int height, float startAngle, float sweepAngle) - { - int status = Gdip.GdipAddPathArcI(_nativePath, x, y, width, height, startAngle, sweepAngle); - Gdip.CheckStatus(status); - } - - public void AddArc(float x, float y, float width, float height, float startAngle, float sweepAngle) - { - int status = Gdip.GdipAddPathArc(_nativePath, x, y, width, height, startAngle, sweepAngle); - Gdip.CheckStatus(status); - } - - // - // AddBezier - // - public void AddBezier(Point pt1, Point pt2, Point pt3, Point pt4) - { - int status = Gdip.GdipAddPathBezierI(_nativePath, pt1.X, pt1.Y, - pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y); - - Gdip.CheckStatus(status); - } - - public void AddBezier(PointF pt1, PointF pt2, PointF pt3, PointF pt4) - { - int status = Gdip.GdipAddPathBezier(_nativePath, pt1.X, pt1.Y, - pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y); - - Gdip.CheckStatus(status); - } - - public void AddBezier(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) - { - int status = Gdip.GdipAddPathBezierI(_nativePath, x1, y1, x2, y2, x3, y3, x4, y4); - Gdip.CheckStatus(status); - } - - public void AddBezier(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) - { - int status = Gdip.GdipAddPathBezier(_nativePath, x1, y1, x2, y2, x3, y3, x4, y4); - Gdip.CheckStatus(status); - } - - // - // AddBeziers - // - public void AddBeziers(params Point[] points!!) - { - int status = Gdip.GdipAddPathBeziersI(_nativePath, points, points.Length); - Gdip.CheckStatus(status); - } - - public void AddBeziers(PointF[] points!!) - { - int status = Gdip.GdipAddPathBeziers(_nativePath, points, points.Length); - Gdip.CheckStatus(status); - } - - // - // AddEllipse - // - public void AddEllipse(RectangleF rect) - { - int status = Gdip.GdipAddPathEllipse(_nativePath, rect.X, rect.Y, rect.Width, rect.Height); - Gdip.CheckStatus(status); - } - - public void AddEllipse(float x, float y, float width, float height) - { - int status = Gdip.GdipAddPathEllipse(_nativePath, x, y, width, height); - Gdip.CheckStatus(status); - } - - public void AddEllipse(Rectangle rect) - { - int status = Gdip.GdipAddPathEllipseI(_nativePath, rect.X, rect.Y, rect.Width, rect.Height); - Gdip.CheckStatus(status); - } - - public void AddEllipse(int x, int y, int width, int height) - { - int status = Gdip.GdipAddPathEllipseI(_nativePath, x, y, width, height); - Gdip.CheckStatus(status); - } - - - // - // AddLine - // - public void AddLine(Point pt1, Point pt2) - { - int status = Gdip.GdipAddPathLineI(_nativePath, pt1.X, pt1.Y, pt2.X, pt2.Y); - Gdip.CheckStatus(status); - } - - public void AddLine(PointF pt1, PointF pt2) - { - int status = Gdip.GdipAddPathLine(_nativePath, pt1.X, pt1.Y, pt2.X, - pt2.Y); - - Gdip.CheckStatus(status); - } - - public void AddLine(int x1, int y1, int x2, int y2) - { - int status = Gdip.GdipAddPathLineI(_nativePath, x1, y1, x2, y2); - Gdip.CheckStatus(status); - } - - public void AddLine(float x1, float y1, float x2, float y2) - { - int status = Gdip.GdipAddPathLine(_nativePath, x1, y1, x2, - y2); - - Gdip.CheckStatus(status); - } - - // - // AddLines - // - public void AddLines(Point[] points!!) - { - if (points.Length == 0) - throw new ArgumentException(null, nameof(points)); - - int status = Gdip.GdipAddPathLine2I(_nativePath, points, points.Length); - Gdip.CheckStatus(status); - } - - public void AddLines(PointF[] points!!) - { - if (points.Length == 0) - throw new ArgumentException(null, nameof(points)); - - int status = Gdip.GdipAddPathLine2(_nativePath, points, points.Length); - Gdip.CheckStatus(status); - } - - // - // AddPie - // - public void AddPie(Rectangle rect, float startAngle, float sweepAngle) - { - int status = Gdip.GdipAddPathPie( - _nativePath, rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle); - Gdip.CheckStatus(status); - } - - public void AddPie(int x, int y, int width, int height, float startAngle, float sweepAngle) - { - int status = Gdip.GdipAddPathPieI(_nativePath, x, y, width, height, startAngle, sweepAngle); - Gdip.CheckStatus(status); - } - - public void AddPie(float x, float y, float width, float height, float startAngle, float sweepAngle) - { - int status = Gdip.GdipAddPathPie(_nativePath, x, y, width, height, startAngle, sweepAngle); - Gdip.CheckStatus(status); - } - - // - // AddPolygon - // - public void AddPolygon(Point[] points!!) - { - int status = Gdip.GdipAddPathPolygonI(_nativePath, points, points.Length); - Gdip.CheckStatus(status); - } - - public void AddPolygon(PointF[] points!!) - { - int status = Gdip.GdipAddPathPolygon(_nativePath, points, points.Length); - Gdip.CheckStatus(status); - } - - // - // AddRectangle - // - public void AddRectangle(Rectangle rect) - { - int status = Gdip.GdipAddPathRectangleI(_nativePath, rect.X, rect.Y, rect.Width, rect.Height); - Gdip.CheckStatus(status); - } - - public void AddRectangle(RectangleF rect) - { - int status = Gdip.GdipAddPathRectangle(_nativePath, rect.X, rect.Y, rect.Width, rect.Height); - Gdip.CheckStatus(status); - } - - // - // AddRectangles - // - public void AddRectangles(Rectangle[] rects!!) - { - if (rects.Length == 0) - throw new ArgumentException(null, nameof(rects)); - - int status = Gdip.GdipAddPathRectanglesI(_nativePath, rects, rects.Length); - Gdip.CheckStatus(status); - } - - public void AddRectangles(RectangleF[] rects!!) - { - if (rects.Length == 0) - throw new ArgumentException(null, nameof(rects)); - - int status = Gdip.GdipAddPathRectangles(_nativePath, rects, rects.Length); - Gdip.CheckStatus(status); - } - - // - // AddPath - // - public void AddPath(GraphicsPath addingPath!!, bool connect) - { - int status = Gdip.GdipAddPathPath(_nativePath, addingPath._nativePath, connect); - Gdip.CheckStatus(status); - } - - public PointF GetLastPoint() - { - PointF pt; - int status = Gdip.GdipGetPathLastPoint(_nativePath, out pt); - Gdip.CheckStatus(status); - - return pt; - } - - // - // AddClosedCurve - // - public void AddClosedCurve(Point[] points!!) - { - int status = Gdip.GdipAddPathClosedCurveI(_nativePath, points, points.Length); - Gdip.CheckStatus(status); - } - - public void AddClosedCurve(PointF[] points!!) - { - int status = Gdip.GdipAddPathClosedCurve(_nativePath, points, points.Length); - Gdip.CheckStatus(status); - } - - public void AddClosedCurve(Point[] points!!, float tension) - { - int status = Gdip.GdipAddPathClosedCurve2I(_nativePath, points, points.Length, tension); - Gdip.CheckStatus(status); - } - - public void AddClosedCurve(PointF[] points!!, float tension) - { - int status = Gdip.GdipAddPathClosedCurve2(_nativePath, points, points.Length, tension); - Gdip.CheckStatus(status); - } - - // - // AddCurve - // - public void AddCurve(Point[] points!!) - { - int status = Gdip.GdipAddPathCurveI(_nativePath, points, points.Length); - Gdip.CheckStatus(status); - } - - public void AddCurve(PointF[] points!!) - { - int status = Gdip.GdipAddPathCurve(_nativePath, points, points.Length); - Gdip.CheckStatus(status); - } - - public void AddCurve(Point[] points!!, float tension) - { - int status = Gdip.GdipAddPathCurve2I(_nativePath, points, points.Length, tension); - Gdip.CheckStatus(status); - } - - public void AddCurve(PointF[] points!!, float tension) - { - int status = Gdip.GdipAddPathCurve2(_nativePath, points, points.Length, tension); - Gdip.CheckStatus(status); - } - - public void AddCurve(Point[] points!!, int offset, int numberOfSegments, float tension) - { - int status = Gdip.GdipAddPathCurve3I(_nativePath, points, points.Length, - offset, numberOfSegments, tension); - - Gdip.CheckStatus(status); - } - - public void AddCurve(PointF[] points!!, int offset, int numberOfSegments, float tension) - { - int status = Gdip.GdipAddPathCurve3(_nativePath, points, points.Length, - offset, numberOfSegments, tension); - - Gdip.CheckStatus(status); - } - - public void Reset() - { - int status = Gdip.GdipResetPath(_nativePath); - Gdip.CheckStatus(status); - } - - public void Reverse() - { - int status = Gdip.GdipReversePath(_nativePath); - Gdip.CheckStatus(status); - } - - public void Transform(Matrix matrix!!) - { - int status = Gdip.GdipTransformPath(_nativePath, matrix.NativeMatrix); - Gdip.CheckStatus(status); - } - - public void AddString(string s, FontFamily family, int style, float emSize, Point origin, StringFormat? format) - { - Rectangle layout = default; - layout.X = origin.X; - layout.Y = origin.Y; - AddString(s, family, style, emSize, layout, format); - } - - public void AddString(string s, FontFamily family, int style, float emSize, PointF origin, StringFormat? format) - { - RectangleF layout = default; - layout.X = origin.X; - layout.Y = origin.Y; - AddString(s, family, style, emSize, layout, format); - } - - public void AddString(string s, FontFamily family!!, int style, float emSize, Rectangle layoutRect, StringFormat? format) - { - IntPtr sformat = (format == null) ? IntPtr.Zero : format.nativeFormat; - // note: the NullReferenceException on s.Length is the expected (MS) exception - int status = Gdip.GdipAddPathStringI(_nativePath, s, s.Length, family.NativeFamily, style, emSize, ref layoutRect, sformat); - Gdip.CheckStatus(status); - } - - public void AddString(string s, FontFamily family!!, int style, float emSize, RectangleF layoutRect, StringFormat? format) - { - IntPtr sformat = (format == null) ? IntPtr.Zero : format.nativeFormat; - // note: the NullReferenceException on s.Length is the expected (MS) exception - int status = Gdip.GdipAddPathString(_nativePath, s, s.Length, family.NativeFamily, style, emSize, ref layoutRect, sformat); - Gdip.CheckStatus(status); - } - - public void ClearMarkers() - { - int s = Gdip.GdipClearPathMarkers(_nativePath); - - Gdip.CheckStatus(s); - } - - public void CloseAllFigures() - { - int s = Gdip.GdipClosePathFigures(_nativePath); - - Gdip.CheckStatus(s); - } - - public void CloseFigure() - { - int s = Gdip.GdipClosePathFigure(_nativePath); - - Gdip.CheckStatus(s); - } - - public void Flatten() - { - Flatten(null, FlatnessDefault); - } - - public void Flatten(Matrix matrix) - { - Flatten(matrix, FlatnessDefault); - } - - public void Flatten(Matrix? matrix, float flatness) - { - IntPtr m = (matrix == null) ? IntPtr.Zero : matrix.NativeMatrix; - int status = Gdip.GdipFlattenPath(_nativePath, m, flatness); - - Gdip.CheckStatus(status); - } - - public RectangleF GetBounds() - { - return GetBounds(null, null); - } - - public RectangleF GetBounds(Matrix? matrix) - { - return GetBounds(matrix, null); - } - - public RectangleF GetBounds(Matrix? matrix, Pen? pen) - { - RectangleF retval; - IntPtr m = (matrix == null) ? IntPtr.Zero : matrix.NativeMatrix; - IntPtr p = (pen == null) ? IntPtr.Zero : pen.NativePen; - - int s = Gdip.GdipGetPathWorldBounds(_nativePath, out retval, m, p); - - Gdip.CheckStatus(s); - - return retval; - } - - public bool IsOutlineVisible(Point point, Pen pen) - { - return IsOutlineVisible(point.X, point.Y, pen, null); - } - - public bool IsOutlineVisible(PointF point, Pen pen) - { - return IsOutlineVisible(point.X, point.Y, pen, null); - } - - public bool IsOutlineVisible(int x, int y, Pen pen) - { - return IsOutlineVisible(x, y, pen, null); - } - - public bool IsOutlineVisible(float x, float y, Pen pen) - { - return IsOutlineVisible(x, y, pen, null); - } - - public bool IsOutlineVisible(Point pt, Pen pen, Graphics? graphics) - { - return IsOutlineVisible(pt.X, pt.Y, pen, graphics); - } - - public bool IsOutlineVisible(PointF pt, Pen pen, Graphics? graphics) - { - return IsOutlineVisible(pt.X, pt.Y, pen, graphics); - } - - public bool IsOutlineVisible(int x, int y, Pen pen!!, Graphics? graphics) - { - bool result; - IntPtr g = (graphics == null) ? IntPtr.Zero : graphics.NativeGraphics; - - int s = Gdip.GdipIsOutlineVisiblePathPointI(_nativePath, x, y, pen.NativePen, g, out result); - Gdip.CheckStatus(s); - - return result; - } - - public bool IsOutlineVisible(float x, float y, Pen pen!!, Graphics? graphics) - { - bool result; - IntPtr g = (graphics == null) ? IntPtr.Zero : graphics.NativeGraphics; - - int s = Gdip.GdipIsOutlineVisiblePathPoint(_nativePath, x, y, pen.NativePen, g, out result); - Gdip.CheckStatus(s); - - return result; - } - - public bool IsVisible(Point point) - { - return IsVisible(point.X, point.Y, null); - } - - public bool IsVisible(PointF point) - { - return IsVisible(point.X, point.Y, null); - } - - public bool IsVisible(int x, int y) - { - return IsVisible(x, y, null); - } - - public bool IsVisible(float x, float y) - { - return IsVisible(x, y, null); - } - - public bool IsVisible(Point pt, Graphics? graphics) - { - return IsVisible(pt.X, pt.Y, graphics); - } - - public bool IsVisible(PointF pt, Graphics? graphics) - { - return IsVisible(pt.X, pt.Y, graphics); - } - - public bool IsVisible(int x, int y, Graphics? graphics) - { - bool retval; - - IntPtr g = (graphics == null) ? IntPtr.Zero : graphics.NativeGraphics; - - int s = Gdip.GdipIsVisiblePathPointI(_nativePath, x, y, g, out retval); - - Gdip.CheckStatus(s); - - return retval; - } - - public bool IsVisible(float x, float y, Graphics? graphics) - { - bool retval; - - IntPtr g = (graphics == null) ? IntPtr.Zero : graphics.NativeGraphics; - - int s = Gdip.GdipIsVisiblePathPoint(_nativePath, x, y, g, out retval); - - Gdip.CheckStatus(s); - - return retval; - } - - public void SetMarkers() - { - int s = Gdip.GdipSetPathMarker(_nativePath); - - Gdip.CheckStatus(s); - } - - public void StartFigure() - { - int s = Gdip.GdipStartPathFigure(_nativePath); - - Gdip.CheckStatus(s); - } - - public void Warp(PointF[] destPoints, RectangleF srcRect) - { - Warp(destPoints, srcRect, null, WarpMode.Perspective, FlatnessDefault); - } - - public void Warp(PointF[] destPoints, RectangleF srcRect, Matrix? matrix) - { - Warp(destPoints, srcRect, matrix, WarpMode.Perspective, FlatnessDefault); - } - - public void Warp(PointF[] destPoints, RectangleF srcRect, Matrix? matrix, WarpMode warpMode) - { - Warp(destPoints, srcRect, matrix, warpMode, FlatnessDefault); - } - - public void Warp(PointF[] destPoints!!, RectangleF srcRect, Matrix? matrix, WarpMode warpMode, float flatness) - { - IntPtr m = (matrix == null) ? IntPtr.Zero : matrix.NativeMatrix; - - int s = Gdip.GdipWarpPath(_nativePath, m, destPoints, destPoints.Length, - srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, warpMode, flatness); - - Gdip.CheckStatus(s); - } - - public void Widen(Pen pen) - { - Widen(pen, null, FlatnessDefault); - } - - public void Widen(Pen pen, Matrix? matrix) - { - Widen(pen, matrix, FlatnessDefault); - } - - public void Widen(Pen pen!!, Matrix? matrix, float flatness) - { - if (PointCount == 0) - return; - IntPtr m = (matrix == null) ? IntPtr.Zero : matrix.NativeMatrix; - - int s = Gdip.GdipWidenPath(_nativePath, pen.NativePen, m, flatness); - Gdip.CheckStatus(s); - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPath.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPath.cs similarity index 86% rename from src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPath.Windows.cs rename to src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPath.cs index aeafa81d13e6b..c591fe883880d 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPath.Windows.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPath.cs @@ -26,8 +26,10 @@ public GraphicsPath(FillMode fillMode) public GraphicsPath(PointF[] pts, byte[] types) : this(pts, types, FillMode.Alternate) { } - public unsafe GraphicsPath(PointF[] pts!!, byte[] types, FillMode fillMode) + public unsafe GraphicsPath(PointF[] pts, byte[] types, FillMode fillMode) { + ArgumentNullException.ThrowIfNull(pts); + if (pts.Length != types.Length) throw Gdip.StatusException(Gdip.InvalidParameter); @@ -43,8 +45,10 @@ public unsafe GraphicsPath(PointF[] pts!!, byte[] types, FillMode fillMode) public GraphicsPath(Point[] pts, byte[] types) : this(pts, types, FillMode.Alternate) { } - public unsafe GraphicsPath(Point[] pts!!, byte[] types, FillMode fillMode) + public unsafe GraphicsPath(Point[] pts, byte[] types, FillMode fillMode) { + ArgumentNullException.ThrowIfNull(pts); + if (pts.Length != types.Length) throw Gdip.StatusException(Gdip.InvalidParameter); @@ -242,8 +246,10 @@ public bool IsOutlineVisible(float x, float y, Pen pen, Graphics? graphics) return IsOutlineVisible(new PointF(x, y), pen, graphics); } - public bool IsOutlineVisible(PointF pt, Pen pen!!, Graphics? graphics) + public bool IsOutlineVisible(PointF pt, Pen pen, Graphics? graphics) { + ArgumentNullException.ThrowIfNull(pen); + Gdip.CheckStatus(Gdip.GdipIsOutlineVisiblePathPoint( new HandleRef(this, _nativePath), pt.X, pt.Y, @@ -260,8 +266,10 @@ public bool IsOutlineVisible(PointF pt, Pen pen!!, Graphics? graphics) public bool IsOutlineVisible(int x, int y, Pen pen, Graphics? graphics) => IsOutlineVisible(new Point(x, y), pen, graphics); - public bool IsOutlineVisible(Point pt, Pen pen!!, Graphics? graphics) + public bool IsOutlineVisible(Point pt, Pen pen, Graphics? graphics) { + ArgumentNullException.ThrowIfNull(pen); + Gdip.CheckStatus(Gdip.GdipIsOutlineVisiblePathPointI( new HandleRef(this, _nativePath), pt.X, pt.Y, @@ -279,8 +287,10 @@ public void AddLine(float x1, float y1, float x2, float y2) Gdip.CheckStatus(Gdip.GdipAddPathLine(new HandleRef(this, _nativePath), x1, y1, x2, y2)); } - public unsafe void AddLines(PointF[] points!!) + public unsafe void AddLines(PointF[] points) { + ArgumentNullException.ThrowIfNull(points); + if (points.Length == 0) throw new ArgumentException(null, nameof(points)); @@ -297,8 +307,10 @@ public void AddLine(int x1, int y1, int x2, int y2) Gdip.CheckStatus(Gdip.GdipAddPathLineI(new HandleRef(this, _nativePath), x1, y1, x2, y2)); } - public unsafe void AddLines(Point[] points!!) + public unsafe void AddLines(Point[] points) { + ArgumentNullException.ThrowIfNull(points); + if (points.Length == 0) throw new ArgumentException(null, nameof(points)); @@ -348,8 +360,10 @@ public void AddBezier(float x1, float y1, float x2, float y2, float x3, float y3 x1, y1, x2, y2, x3, y3, x4, y4)); } - public unsafe void AddBeziers(PointF[] points!!) + public unsafe void AddBeziers(PointF[] points) { + ArgumentNullException.ThrowIfNull(points); + fixed (PointF* p = points) { Gdip.CheckStatus(Gdip.GdipAddPathBeziers(new HandleRef(this, _nativePath), p, points.Length)); @@ -368,8 +382,10 @@ public void AddBezier(int x1, int y1, int x2, int y2, int x3, int y3, int x4, in x1, y1, x2, y2, x3, y3, x4, y4)); } - public unsafe void AddBeziers(params Point[] points!!) + public unsafe void AddBeziers(params Point[] points) { + ArgumentNullException.ThrowIfNull(points); + if (points.Length == 0) return; @@ -382,16 +398,20 @@ public unsafe void AddBeziers(params Point[] points!!) /// /// Add cardinal splines to the path object /// - public unsafe void AddCurve(PointF[] points!!) + public unsafe void AddCurve(PointF[] points) { + ArgumentNullException.ThrowIfNull(points); + fixed (PointF* p = points) { Gdip.CheckStatus(Gdip.GdipAddPathCurve(new HandleRef(this, _nativePath), p, points.Length)); } } - public unsafe void AddCurve(PointF[] points!!, float tension) + public unsafe void AddCurve(PointF[] points, float tension) { + ArgumentNullException.ThrowIfNull(points); + if (points.Length == 0) return; @@ -401,8 +421,10 @@ public unsafe void AddCurve(PointF[] points!!, float tension) } } - public unsafe void AddCurve(PointF[] points!!, int offset, int numberOfSegments, float tension) + public unsafe void AddCurve(PointF[] points, int offset, int numberOfSegments, float tension) { + ArgumentNullException.ThrowIfNull(points); + fixed (PointF* p = points) { Gdip.CheckStatus(Gdip.GdipAddPathCurve3( @@ -410,16 +432,20 @@ public unsafe void AddCurve(PointF[] points!!, int offset, int numberOfSegments, } } - public unsafe void AddCurve(Point[] points!!) + public unsafe void AddCurve(Point[] points) { + ArgumentNullException.ThrowIfNull(points); + fixed (Point* p = points) { Gdip.CheckStatus(Gdip.GdipAddPathCurveI(new HandleRef(this, _nativePath), p, points.Length)); } } - public unsafe void AddCurve(Point[] points!!, float tension) + public unsafe void AddCurve(Point[] points, float tension) { + ArgumentNullException.ThrowIfNull(points); + fixed (Point* p = points) { Gdip.CheckStatus(Gdip.GdipAddPathCurve2I( @@ -427,8 +453,10 @@ public unsafe void AddCurve(Point[] points!!, float tension) } } - public unsafe void AddCurve(Point[] points!!, int offset, int numberOfSegments, float tension) + public unsafe void AddCurve(Point[] points, int offset, int numberOfSegments, float tension) { + ArgumentNullException.ThrowIfNull(points); + fixed (Point* p = points) { Gdip.CheckStatus(Gdip.GdipAddPathCurve3I( @@ -436,8 +464,10 @@ public unsafe void AddCurve(Point[] points!!, int offset, int numberOfSegments, } } - public unsafe void AddClosedCurve(PointF[] points!!) + public unsafe void AddClosedCurve(PointF[] points) { + ArgumentNullException.ThrowIfNull(points); + fixed (PointF* p = points) { Gdip.CheckStatus(Gdip.GdipAddPathClosedCurve( @@ -445,24 +475,30 @@ public unsafe void AddClosedCurve(PointF[] points!!) } } - public unsafe void AddClosedCurve(PointF[] points!!, float tension) + public unsafe void AddClosedCurve(PointF[] points, float tension) { + ArgumentNullException.ThrowIfNull(points); + fixed (PointF* p = points) { Gdip.CheckStatus(Gdip.GdipAddPathClosedCurve2(new HandleRef(this, _nativePath), p, points.Length, tension)); } } - public unsafe void AddClosedCurve(Point[] points!!) + public unsafe void AddClosedCurve(Point[] points) { + ArgumentNullException.ThrowIfNull(points); + fixed (Point* p = points) { Gdip.CheckStatus(Gdip.GdipAddPathClosedCurveI(new HandleRef(this, _nativePath), p, points.Length)); } } - public unsafe void AddClosedCurve(Point[] points!!, float tension) + public unsafe void AddClosedCurve(Point[] points, float tension) { + ArgumentNullException.ThrowIfNull(points); + fixed (Point* p = points) { Gdip.CheckStatus(Gdip.GdipAddPathClosedCurve2I(new HandleRef(this, _nativePath), p, points.Length, tension)); @@ -476,8 +512,10 @@ public void AddRectangle(RectangleF rect) rect.X, rect.Y, rect.Width, rect.Height)); } - public unsafe void AddRectangles(RectangleF[] rects!!) + public unsafe void AddRectangles(RectangleF[] rects) { + ArgumentNullException.ThrowIfNull(rects); + if (rects.Length == 0) throw new ArgumentException(null, nameof(rects)); @@ -495,8 +533,10 @@ public void AddRectangle(Rectangle rect) rect.X, rect.Y, rect.Width, rect.Height)); } - public unsafe void AddRectangles(Rectangle[] rects!!) + public unsafe void AddRectangles(Rectangle[] rects) { + ArgumentNullException.ThrowIfNull(rects); + if (rects.Length == 0) throw new ArgumentException(null, nameof(rects)); @@ -547,8 +587,10 @@ public void AddPie(int x, int y, int width, int height, float startAngle, float sweepAngle)); } - public unsafe void AddPolygon(PointF[] points!!) + public unsafe void AddPolygon(PointF[] points) { + ArgumentNullException.ThrowIfNull(points); + fixed (PointF* p = points) { Gdip.CheckStatus(Gdip.GdipAddPathPolygon(new HandleRef(this, _nativePath), p, points.Length)); @@ -558,16 +600,20 @@ public unsafe void AddPolygon(PointF[] points!!) /// /// Adds a polygon to the current figure. /// - public unsafe void AddPolygon(Point[] points!!) + public unsafe void AddPolygon(Point[] points) { + ArgumentNullException.ThrowIfNull(points); + fixed (Point* p = points) { Gdip.CheckStatus(Gdip.GdipAddPathPolygonI(new HandleRef(this, _nativePath), p, points.Length)); } } - public void AddPath(GraphicsPath addingPath!!, bool connect) + public void AddPath(GraphicsPath addingPath, bool connect) { + ArgumentNullException.ThrowIfNull(addingPath); + Gdip.CheckStatus(Gdip.GdipAddPathPath( new HandleRef(this, _nativePath), new HandleRef(addingPath, addingPath._nativePath), connect)); } @@ -582,8 +628,10 @@ public void AddString(string s, FontFamily family, int style, float emSize, Poin AddString(s, family, style, emSize, new Rectangle(origin.X, origin.Y, 0, 0), format); } - public void AddString(string s, FontFamily family!!, int style, float emSize, RectangleF layoutRect, StringFormat? format) + public void AddString(string s, FontFamily family, int style, float emSize, RectangleF layoutRect, StringFormat? format) { + ArgumentNullException.ThrowIfNull(family); + Gdip.CheckStatus(Gdip.GdipAddPathString( new HandleRef(this, _nativePath), s, @@ -595,8 +643,10 @@ public void AddString(string s, FontFamily family!!, int style, float emSize, Re new HandleRef(format, format?.nativeFormat ?? IntPtr.Zero))); } - public void AddString(string s, FontFamily family!!, int style, float emSize, Rectangle layoutRect, StringFormat? format) + public void AddString(string s, FontFamily family, int style, float emSize, Rectangle layoutRect, StringFormat? format) { + ArgumentNullException.ThrowIfNull(family); + Gdip.CheckStatus(Gdip.GdipAddPathStringI( new HandleRef(this, _nativePath), s, @@ -608,8 +658,10 @@ public void AddString(string s, FontFamily family!!, int style, float emSize, Re new HandleRef(format, format?.nativeFormat ?? IntPtr.Zero))); } - public void Transform(Matrix matrix!!) + public void Transform(Matrix matrix) { + ArgumentNullException.ThrowIfNull(matrix); + if (matrix.NativeMatrix == IntPtr.Zero) return; @@ -649,8 +701,10 @@ public void Flatten(Matrix? matrix, float flatness) public void Widen(Pen pen, Matrix? matrix) => Widen(pen, matrix, Flatness); - public void Widen(Pen pen!!, Matrix? matrix, float flatness) + public void Widen(Pen pen, Matrix? matrix, float flatness) { + ArgumentNullException.ThrowIfNull(pen); + // GDI+ wrongly returns an out of memory status when there is nothing in the path, so we have to check // before calling the widen method and do nothing if we dont have anything in the path. if (PointCount == 0) @@ -672,8 +726,10 @@ public void Warp(PointF[] destPoints, RectangleF srcRect, Matrix? matrix, WarpMo Warp(destPoints, srcRect, matrix, warpMode, 0.25f); } - public unsafe void Warp(PointF[] destPoints!!, RectangleF srcRect, Matrix? matrix, WarpMode warpMode, float flatness) + public unsafe void Warp(PointF[] destPoints, RectangleF srcRect, Matrix? matrix, WarpMode warpMode, float flatness) { + ArgumentNullException.ThrowIfNull(destPoints); + fixed (PointF* p = destPoints) { Gdip.CheckStatus(Gdip.GdipWarpPath( diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/LinearGradientBrush.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/LinearGradientBrush.cs index 56afa27cee56d..bf9aa25a3d7ec 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/LinearGradientBrush.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/LinearGradientBrush.cs @@ -476,8 +476,10 @@ public void ResetTransform() public void MultiplyTransform(Matrix matrix) => MultiplyTransform(matrix, MatrixOrder.Prepend); - public void MultiplyTransform(Matrix matrix!!, MatrixOrder order) + public void MultiplyTransform(Matrix matrix, MatrixOrder order) { + ArgumentNullException.ThrowIfNull(matrix); + // Multiplying the transform by a disposed matrix is a nop in GDI+, but throws // with the libgdiplus backend. Simulate a nop for compatability with GDI+. if (matrix.NativeMatrix == IntPtr.Zero) diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/Matrix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/Matrix.cs index d418b7a7d3055..ffaa33fb55252 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/Matrix.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/Matrix.cs @@ -52,8 +52,10 @@ internal static IntPtr CreateNativeHandle(Matrix3x2 matrix) return nativeMatrix; } - public unsafe Matrix(RectangleF rect, PointF[] plgpts!!) + public unsafe Matrix(RectangleF rect, PointF[] plgpts) { + ArgumentNullException.ThrowIfNull(plgpts); + if (plgpts.Length != 3) throw Gdip.StatusException(Gdip.InvalidParameter); @@ -64,8 +66,10 @@ public unsafe Matrix(RectangleF rect, PointF[] plgpts!!) } } - public unsafe Matrix(Rectangle rect, Point[] plgpts!!) + public unsafe Matrix(Rectangle rect, Point[] plgpts) { + ArgumentNullException.ThrowIfNull(plgpts); + if (plgpts.Length != 3) throw Gdip.StatusException(Gdip.InvalidParameter); @@ -170,8 +174,10 @@ public void Reset() public void Multiply(Matrix matrix) => Multiply(matrix, MatrixOrder.Prepend); - public void Multiply(Matrix matrix!!, MatrixOrder order) + public void Multiply(Matrix matrix, MatrixOrder order) { + ArgumentNullException.ThrowIfNull(matrix); + if (matrix.NativeMatrix == NativeMatrix) throw new InvalidOperationException(SR.GdiplusObjectBusy); @@ -240,8 +246,10 @@ public void Invert() Gdip.CheckStatus(Gdip.GdipInvertMatrix(new HandleRef(this, NativeMatrix))); } - public unsafe void TransformPoints(PointF[] pts!!) + public unsafe void TransformPoints(PointF[] pts) { + ArgumentNullException.ThrowIfNull(pts); + fixed (PointF* p = pts) { Gdip.CheckStatus(Gdip.GdipTransformMatrixPoints( @@ -251,8 +259,10 @@ public unsafe void TransformPoints(PointF[] pts!!) } } - public unsafe void TransformPoints(Point[] pts!!) + public unsafe void TransformPoints(Point[] pts) { + ArgumentNullException.ThrowIfNull(pts); + fixed (Point* p = pts) { Gdip.CheckStatus(Gdip.GdipTransformMatrixPointsI( @@ -262,8 +272,10 @@ public unsafe void TransformPoints(Point[] pts!!) } } - public unsafe void TransformVectors(PointF[] pts!!) + public unsafe void TransformVectors(PointF[] pts) { + ArgumentNullException.ThrowIfNull(pts); + fixed (PointF* p = pts) { Gdip.CheckStatus(Gdip.GdipVectorTransformMatrixPoints( @@ -275,8 +287,10 @@ public unsafe void TransformVectors(PointF[] pts!!) public void VectorTransformPoints(Point[] pts) => TransformVectors(pts); - public unsafe void TransformVectors(Point[] pts!!) + public unsafe void TransformVectors(Point[] pts) { + ArgumentNullException.ThrowIfNull(pts); + fixed (Point* p = pts) { Gdip.CheckStatus(Gdip.GdipVectorTransformMatrixPointsI( diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/PathGradientBrush.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/PathGradientBrush.cs index d05f2585e08f7..9eed53798f8b0 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/PathGradientBrush.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/PathGradientBrush.cs @@ -13,8 +13,10 @@ public sealed class PathGradientBrush : Brush { public PathGradientBrush(PointF[] points) : this(points, WrapMode.Clamp) { } - public unsafe PathGradientBrush(PointF[] points!!, WrapMode wrapMode) + public unsafe PathGradientBrush(PointF[] points, WrapMode wrapMode) { + ArgumentNullException.ThrowIfNull(points); + if (wrapMode < WrapMode.Tile || wrapMode > WrapMode.Clamp) throw new InvalidEnumArgumentException(nameof(wrapMode), unchecked((int)wrapMode), typeof(WrapMode)); @@ -35,8 +37,10 @@ public unsafe PathGradientBrush(PointF[] points!!, WrapMode wrapMode) public PathGradientBrush(Point[] points) : this(points, WrapMode.Clamp) { } - public unsafe PathGradientBrush(Point[] points!!, WrapMode wrapMode) + public unsafe PathGradientBrush(Point[] points, WrapMode wrapMode) { + ArgumentNullException.ThrowIfNull(points); + if (wrapMode < WrapMode.Tile || wrapMode > WrapMode.Clamp) throw new InvalidEnumArgumentException(nameof(wrapMode), unchecked((int)wrapMode), typeof(WrapMode)); @@ -55,8 +59,10 @@ public unsafe PathGradientBrush(Point[] points!!, WrapMode wrapMode) } } - public PathGradientBrush(GraphicsPath path!!) + public PathGradientBrush(GraphicsPath path) { + ArgumentNullException.ThrowIfNull(path); + Gdip.CheckStatus(Gdip.GdipCreatePathGradientFromPath(new HandleRef(path, path._nativePath), out IntPtr nativeBrush)); SetNativeBrushInternal(nativeBrush); } @@ -331,8 +337,9 @@ public void ResetTransform() public void MultiplyTransform(Matrix matrix) => MultiplyTransform(matrix, MatrixOrder.Prepend); - public void MultiplyTransform(Matrix matrix!!, MatrixOrder order) + public void MultiplyTransform(Matrix matrix, MatrixOrder order) { + ArgumentNullException.ThrowIfNull(matrix); // Multiplying the transform by a disposed matrix is a nop in GDI+, but throws // with the libgdiplus backend. Simulate a nop for compatability with GDI+. diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/DrawingCom.COMWrappers.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/DrawingCom.ComWrappers.cs similarity index 100% rename from src/libraries/System.Drawing.Common/src/System/Drawing/DrawingCom.COMWrappers.cs rename to src/libraries/System.Drawing.Common/src/System/Drawing/DrawingCom.ComWrappers.cs diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/DrawingCom.NoCOMWrappers.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/DrawingCom.NoCOMWrappers.cs deleted file mode 100644 index d3fdd2115bffb..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/DrawingCom.NoCOMWrappers.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Internal; -using System.Runtime.InteropServices; - -namespace System.Drawing -{ - internal static partial class DrawingCom - { - internal static IStreamWrapper GetComWrapper(GPStream stream) - { - return new IStreamWrapper(Marshal.GetComInterfaceForObject(stream)); - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Font.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Font.Unix.cs deleted file mode 100644 index 86f5c105ae69d..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Font.Unix.cs +++ /dev/null @@ -1,352 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// System.Drawing.Fonts.cs -// -// Authors: -// Alexandre Pigolkine (pigolkine@gmx.de) -// Miguel de Icaza (miguel@ximian.com) -// Todd Berman (tberman@sevenl.com) -// Jordi Mas i Hernandez (jordi@ximian.com) -// Ravindra (rkumar@novell.com) -// -// Copyright (C) 2004 Ximian, Inc. (http://www.ximian.com) -// Copyright (C) 2004, 2006 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// 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.Reflection; -using System.Runtime.Serialization; -using System.Runtime.InteropServices; -using System.ComponentModel; -using Gdip = System.Drawing.SafeNativeMethods.Gdip; - -namespace System.Drawing -{ - public sealed partial class Font - { - private const byte DefaultCharSet = 1; - - private void CreateFont(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte charSet, bool isVertical) - { - _originalFontName = familyName; - FontFamily family; - // NOTE: If family name is null, empty or invalid, - // MS creates Microsoft Sans Serif font. - try - { - family = new FontFamily(familyName); - } - catch (Exception) - { - family = FontFamily.GenericSansSerif; - } - - Initialize(family, emSize, style, unit, charSet, isVertical); - int status = Gdip.GdipCreateFont(new HandleRef(this, family.NativeFamily), emSize, style, unit, out _nativeFont); - - if (status == Gdip.FontStyleNotFound) - throw new ArgumentException($"Style {style} isn't supported by font {familyName}."); - - Gdip.CheckStatus(status); - } - - internal static void unitConversion(GraphicsUnit fromUnit, GraphicsUnit toUnit, float nSrc, out float nTrg) - { - float inchs; - nTrg = 0; - - switch (fromUnit) - { - case GraphicsUnit.Display: - inchs = nSrc / 75f; - break; - case GraphicsUnit.Document: - inchs = nSrc / 300f; - break; - case GraphicsUnit.Inch: - inchs = nSrc; - break; - case GraphicsUnit.Millimeter: - inchs = nSrc / 25.4f; - break; - case GraphicsUnit.Pixel: - case GraphicsUnit.World: - inchs = nSrc / Graphics.systemDpiX; - break; - case GraphicsUnit.Point: - inchs = nSrc / 72f; - break; - default: - throw new ArgumentException(SR.InvalidGraphicsUnit); - } - - switch (toUnit) - { - case GraphicsUnit.Display: - nTrg = inchs * 75; - break; - case GraphicsUnit.Document: - nTrg = inchs * 300; - break; - case GraphicsUnit.Inch: - nTrg = inchs; - break; - case GraphicsUnit.Millimeter: - nTrg = inchs * 25.4f; - break; - case GraphicsUnit.Pixel: - case GraphicsUnit.World: - nTrg = inchs * Graphics.systemDpiX; - break; - case GraphicsUnit.Point: - nTrg = inchs * 72; - break; - default: - throw new ArgumentException(SR.InvalidGraphicsUnit); - } - } - - private void Initialize(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte charSet, bool isVertical) - { - _originalFontName = familyName; - FontFamily family; - // NOTE: If family name is null, empty or invalid, - // MS creates Microsoft Sans Serif font. - try - { - family = new FontFamily(familyName); - } - catch (Exception) - { - family = FontFamily.GenericSansSerif; - } - - Initialize(family, emSize, style, unit, charSet, isVertical); - } - - private void Initialize(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit, byte charSet, bool isVertical) - { - _fontFamily = family; - _fontSize = emSize; - - // MS throws ArgumentException, if unit is set to GraphicsUnit.Display - _fontUnit = unit; - _fontStyle = style; - _gdiCharSet = charSet; - _gdiVerticalFont = isVertical; - - unitConversion(unit, GraphicsUnit.Point, emSize, out _fontSizeInPoints); - } - - public static Font FromHfont(IntPtr hfont) - { - IntPtr newObject; - FontStyle newStyle = FontStyle.Regular; - float newSize; - Interop.User32.LOGFONT lf = default; - - // Sanity. Should we throw an exception? - if (hfont == IntPtr.Zero) - { - Font result = new Font("Arial", (float)10.0, FontStyle.Regular); - return (result); - } - - // If we're on Unix we use our private gdiplus API to avoid Wine - // dependencies in S.D - int s = Gdip.GdipCreateFontFromHfont(hfont, out newObject, ref lf); - Gdip.CheckStatus(s); - - if (lf.lfItalic != 0) - { - newStyle |= FontStyle.Italic; - } - - if (lf.lfUnderline != 0) - { - newStyle |= FontStyle.Underline; - } - - if (lf.lfStrikeOut != 0) - { - newStyle |= FontStyle.Strikeout; - } - - if (lf.lfWeight > 400) - { - newStyle |= FontStyle.Bold; - } - - if (lf.lfHeight < 0) - { - newSize = lf.lfHeight * -1; - } - else - { - newSize = lf.lfHeight; - } - - return (new Font(newObject, lf.lfFaceName.ToString(), newStyle, newSize)); - } - - public IntPtr ToHfont() - { - if (_nativeFont == IntPtr.Zero) - throw new ArgumentException(SR.ObjectDisposed); - - return _nativeFont; - } - - internal Font(IntPtr nativeFont, string familyName, FontStyle style, float size) - { - Initialize(familyName, size, style, GraphicsUnit.Pixel, 0, false); - _nativeFont = nativeFont; - } - - public Font(Font prototype, FontStyle newStyle) - { - // no null checks, MS throws a NullReferenceException if original is null - Initialize(prototype.FontFamily, prototype.Size, newStyle, prototype.Unit, prototype.GdiCharSet, prototype.GdiVerticalFont); - - int status = Gdip.GdipCreateFont(new HandleRef(_fontFamily, _fontFamily.NativeFamily), Size, Style, Unit, out _nativeFont); - Gdip.CheckStatus(status); - } - - public Font(FontFamily family, float emSize, GraphicsUnit unit) - : this(family, emSize, FontStyle.Regular, unit, DefaultCharSet, false) - { - } - - public Font(string familyName, float emSize, GraphicsUnit unit) - : this(new FontFamily(familyName), emSize, FontStyle.Regular, unit, DefaultCharSet, false) - { - } - - public Font(FontFamily family, float emSize) - : this(family, emSize, FontStyle.Regular, GraphicsUnit.Point, DefaultCharSet, false) - { - } - - public Font(FontFamily family, float emSize, FontStyle style) - : this(family, emSize, style, GraphicsUnit.Point, DefaultCharSet, false) - { - } - - public Font(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit) - : this(family, emSize, style, unit, DefaultCharSet, false) - { - } - - public Font(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet) - : this(family, emSize, style, unit, gdiCharSet, false) - { - } - - public Font(FontFamily family!!, float emSize, FontStyle style, - GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont) - { - int status; - Initialize(family, emSize, style, unit, gdiCharSet, gdiVerticalFont); - status = Gdip.GdipCreateFont(new HandleRef(this, family.NativeFamily), emSize, style, unit, out _nativeFont); - Gdip.CheckStatus(status); - } - - public Font(string familyName, float emSize) - : this(familyName, emSize, FontStyle.Regular, GraphicsUnit.Point, DefaultCharSet, false) - { - } - - public Font(string familyName, float emSize, FontStyle style) - : this(familyName, emSize, style, GraphicsUnit.Point, DefaultCharSet, false) - { - } - - public Font(string familyName, float emSize, FontStyle style, GraphicsUnit unit) - : this(familyName, emSize, style, unit, DefaultCharSet, false) - { - } - - public Font(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet) - : this(familyName, emSize, style, unit, gdiCharSet, false) - { - } - - public Font(string familyName, float emSize, FontStyle style, - GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont) - { - CreateFont(familyName, emSize, style, unit, gdiCharSet, gdiVerticalFont); - } - internal Font(string familyName, float emSize, string systemName) - : this(familyName, emSize, FontStyle.Regular, GraphicsUnit.Point, DefaultCharSet, false) - { - _systemFontName = systemName; - } - - public object Clone() - { - return new Font(this, Style); - } - - private float _fontSizeInPoints; - - [Browsable(false)] - public float SizeInPoints => _fontSizeInPoints; - - public static Font FromHdc(IntPtr hdc) - { - throw new NotImplementedException(); - } - - public static Font FromLogFont(object lf, IntPtr hdc) - { - IntPtr newObject; - Interop.User32.LOGFONT o = (Interop.User32.LOGFONT)lf; - int status = Gdip.GdipCreateFontFromLogfont(hdc, ref o, out newObject); - Gdip.CheckStatus(status); - return new Font(newObject, "Microsoft Sans Serif", FontStyle.Regular, 10); - } - - public float GetHeight() - { - return GetHeight(Graphics.systemDpiY); - } - - public static Font FromLogFont(object lf) - { - return FromLogFont(lf, IntPtr.Zero); - } - - public void ToLogFont(object logFont) - { - // Unix - We don't have a window we could associate the DC with - // so we use an image instead - using (Bitmap img = new Bitmap(1, 1, Imaging.PixelFormat.Format32bppArgb)) - { - using (Graphics g = Graphics.FromImage(img)) - { - ToLogFont(logFont, g); - } - } - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Font.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Font.Windows.cs deleted file mode 100644 index a932a9c17543f..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Font.Windows.cs +++ /dev/null @@ -1,427 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Drawing.Internal; -using System.Runtime.InteropServices; -using Gdip = System.Drawing.SafeNativeMethods.Gdip; - -namespace System.Drawing -{ - public sealed partial class Font - { - /// - /// Creates the GDI+ native font object. - /// - private void CreateNativeFont() - { - Debug.Assert(_nativeFont == IntPtr.Zero, "nativeFont already initialized, this will generate a handle leak."); - Debug.Assert(_fontFamily != null, "fontFamily not initialized."); - - // Note: GDI+ creates singleton font family objects (from the corresponding font file) and reference count them so - // if creating the font object from an external FontFamily, this object's FontFamily will share the same native object. - int status = Gdip.GdipCreateFont( - new HandleRef(this, _fontFamily.NativeFamily), - _fontSize, - _fontStyle, - _fontUnit, - out _nativeFont); - - // Special case this common error message to give more information - if (status == Gdip.FontStyleNotFound) - { - throw new ArgumentException(SR.Format(SR.GdiplusFontStyleNotFound, _fontFamily.Name, _fontStyle.ToString())); - } - else if (status != Gdip.Ok) - { - throw Gdip.StatusException(status); - } - } - - /// - /// Initializes a new instance of the class from the specified existing - /// and . - /// - public Font(Font prototype, FontStyle newStyle) - { - // Copy over the originalFontName because it won't get initialized - _originalFontName = prototype.OriginalFontName; - Initialize(prototype.FontFamily, prototype.Size, newStyle, prototype.Unit, SafeNativeMethods.DEFAULT_CHARSET, false); - } - - /// - /// Initializes a new instance of the class with the specified attributes. - /// - public Font(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit) - { - Initialize(family, emSize, style, unit, SafeNativeMethods.DEFAULT_CHARSET, false); - } - - /// - /// Initializes a new instance of the class with the specified attributes. - /// - public Font(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet) - { - Initialize(family, emSize, style, unit, gdiCharSet, false); - } - - /// - /// Initializes a new instance of the class with the specified attributes. - /// - public Font(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont) - { - Initialize(family, emSize, style, unit, gdiCharSet, gdiVerticalFont); - } - - /// - /// Initializes a new instance of the class with the specified attributes. - /// - public Font(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet) - { - Initialize(familyName, emSize, style, unit, gdiCharSet, IsVerticalName(familyName)); - } - - /// - /// Initializes a new instance of the class with the specified attributes. - /// - public Font(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont) - { - if (float.IsNaN(emSize) || float.IsInfinity(emSize) || emSize <= 0) - { - throw new ArgumentException(SR.Format(SR.InvalidBoundArgument, nameof(emSize), emSize, 0, "System.Single.MaxValue"), nameof(emSize)); - } - - Initialize(familyName, emSize, style, unit, gdiCharSet, gdiVerticalFont); - } - - /// - /// Initializes a new instance of the class with the specified attributes. - /// - public Font(FontFamily family, float emSize, FontStyle style) - { - Initialize(family, emSize, style, GraphicsUnit.Point, SafeNativeMethods.DEFAULT_CHARSET, false); - } - - /// - /// Initializes a new instance of the class with the specified attributes. - /// - public Font(FontFamily family, float emSize, GraphicsUnit unit) - { - Initialize(family, emSize, FontStyle.Regular, unit, SafeNativeMethods.DEFAULT_CHARSET, false); - } - - /// - /// Initializes a new instance of the class with the specified attributes. - /// - public Font(FontFamily family, float emSize) - { - Initialize(family, emSize, FontStyle.Regular, GraphicsUnit.Point, SafeNativeMethods.DEFAULT_CHARSET, false); - } - - /// - /// Initializes a new instance of the class with the specified attributes. - /// - public Font(string familyName, float emSize, FontStyle style, GraphicsUnit unit) - { - Initialize(familyName, emSize, style, unit, SafeNativeMethods.DEFAULT_CHARSET, IsVerticalName(familyName)); - } - - /// - /// Initializes a new instance of the class with the specified attributes. - /// - public Font(string familyName, float emSize, FontStyle style) - { - Initialize(familyName, emSize, style, GraphicsUnit.Point, SafeNativeMethods.DEFAULT_CHARSET, IsVerticalName(familyName)); - } - - /// - /// Initializes a new instance of the class with the specified attributes. - /// - public Font(string familyName, float emSize, GraphicsUnit unit) - { - Initialize(familyName, emSize, FontStyle.Regular, unit, SafeNativeMethods.DEFAULT_CHARSET, IsVerticalName(familyName)); - } - - /// - /// Initializes a new instance of the class with the specified attributes. - /// - public Font(string familyName, float emSize) - { - Initialize(familyName, emSize, FontStyle.Regular, GraphicsUnit.Point, SafeNativeMethods.DEFAULT_CHARSET, IsVerticalName(familyName)); - } - - /// - /// Constructor to initialize fields from an existing native GDI+ object reference. Used by ToLogFont. - /// - private Font(IntPtr nativeFont, byte gdiCharSet, bool gdiVerticalFont) - { - Debug.Assert(_nativeFont == IntPtr.Zero, "GDI+ native font already initialized, this will generate a handle leak"); - Debug.Assert(nativeFont != IntPtr.Zero, "nativeFont is null"); - - _nativeFont = nativeFont; - - Gdip.CheckStatus(Gdip.GdipGetFontUnit(new HandleRef(this, nativeFont), out GraphicsUnit unit)); - Gdip.CheckStatus(Gdip.GdipGetFontSize(new HandleRef(this, nativeFont), out float size)); - Gdip.CheckStatus(Gdip.GdipGetFontStyle(new HandleRef(this, nativeFont), out FontStyle style)); - Gdip.CheckStatus(Gdip.GdipGetFamily(new HandleRef(this, nativeFont), out IntPtr nativeFamily)); - - SetFontFamily(new FontFamily(nativeFamily)); - Initialize(_fontFamily, size, style, unit, gdiCharSet, gdiVerticalFont); - } - - /// - /// Initializes this object's fields. - /// - private void Initialize(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont) - { - _originalFontName = familyName; - - SetFontFamily(new FontFamily(StripVerticalName(familyName), createDefaultOnFail: true)); - Initialize(_fontFamily, emSize, style, unit, gdiCharSet, gdiVerticalFont); - } - - /// - /// Initializes this object's fields. - /// - private void Initialize(FontFamily family!!, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont) - { - if (float.IsNaN(emSize) || float.IsInfinity(emSize) || emSize <= 0) - { - throw new ArgumentException(SR.Format(SR.InvalidBoundArgument, nameof(emSize), emSize, 0, "System.Single.MaxValue"), nameof(emSize)); - } - - int status; - - _fontSize = emSize; - _fontStyle = style; - _fontUnit = unit; - _gdiCharSet = gdiCharSet; - _gdiVerticalFont = gdiVerticalFont; - - if (_fontFamily == null) - { - // GDI+ FontFamily is a singleton object. - SetFontFamily(new FontFamily(family.NativeFamily)); - } - - if (_nativeFont == IntPtr.Zero) - { - CreateNativeFont(); - } - - // Get actual size. - status = Gdip.GdipGetFontSize(new HandleRef(this, _nativeFont), out _fontSize); - Gdip.CheckStatus(status); - } - - /// - /// Creates a from the specified Windows handle. - /// - public static Font FromHfont(IntPtr hfont) - { - Interop.User32.LOGFONT logFont = default; - Interop.Gdi32.GetObject(new HandleRef(null, hfont), ref logFont); - - using (ScreenDC dc = ScreenDC.Create()) - { - return FromLogFontInternal(ref logFont, dc); - } - } - - /// - /// Creates a from the given LOGFONT using the screen device context. - /// - /// A boxed LOGFONT. - /// The newly created . - public static Font FromLogFont(object lf) - { - using (ScreenDC dc = ScreenDC.Create()) - { - return FromLogFont(lf, dc); - } - } - - internal static Font FromLogFont(ref Interop.User32.LOGFONT logFont) - { - using (ScreenDC dc = ScreenDC.Create()) - { - return FromLogFont(logFont, dc); - } - } - - internal static Font FromLogFontInternal(ref Interop.User32.LOGFONT logFont, IntPtr hdc) - { - int status = Gdip.GdipCreateFontFromLogfontW(hdc, ref logFont, out IntPtr font); - - // Special case this incredibly common error message to give more information - if (status == Gdip.NotTrueTypeFont) - { - throw new ArgumentException(SR.GdiplusNotTrueTypeFont_NoName); - } - else if (status != Gdip.Ok) - { - throw Gdip.StatusException(status); - } - - // GDI+ returns font = 0 even though the status is Ok. - if (font == IntPtr.Zero) - { - throw new ArgumentException(SR.Format(SR.GdiplusNotTrueTypeFont, logFont.ToString())); - } - - bool gdiVerticalFont = logFont.lfFaceName[0] == '@'; - return new Font(font, logFont.lfCharSet, gdiVerticalFont); - } - - /// - /// Creates a from the given LOGFONT using the given device context. - /// - /// A boxed LOGFONT. - /// Handle to a device context (HDC). - /// The newly created . - public static unsafe Font FromLogFont(object lf!!, IntPtr hdc) - { - if (lf is Interop.User32.LOGFONT logFont) - { - // A boxed LOGFONT, just use it to create the font - return FromLogFontInternal(ref logFont, hdc); - } - - Type type = lf.GetType(); - int nativeSize = sizeof(Interop.User32.LOGFONT); - if (Marshal.SizeOf(type) != nativeSize) - { - // If we don't actually have an object that is LOGFONT in size, trying to pass - // it to GDI+ is likely to cause an AV. - throw new ArgumentException(null, nameof(lf)); - } - - // Now that we know the marshalled size is the same as LOGFONT, copy in the data - logFont = default; - - Marshal.StructureToPtr(lf, new IntPtr(&logFont), fDeleteOld: false); - - return FromLogFontInternal(ref logFont, hdc); - } - - /// - /// Creates a from the specified handle to a device context (HDC). - /// - /// The newly created . - public static Font FromHdc(IntPtr hdc) - { - IntPtr font = IntPtr.Zero; - int status = Gdip.GdipCreateFontFromDC(hdc, ref font); - - // Special case this incredibly common error message to give more information - if (status == Gdip.NotTrueTypeFont) - { - throw new ArgumentException(SR.GdiplusNotTrueTypeFont_NoName); - } - else if (status != Gdip.Ok) - { - throw Gdip.StatusException(status); - } - - return new Font(font, 0, false); - } - - /// - /// Creates an exact copy of this . - /// - public object Clone() - { - int status = Gdip.GdipCloneFont(new HandleRef(this, _nativeFont), out IntPtr clonedFont); - Gdip.CheckStatus(status); - - return new Font(clonedFont, _gdiCharSet, _gdiVerticalFont); - } - - private void SetFontFamily(FontFamily family) - { - _fontFamily = family; - - // GDI+ creates ref-counted singleton FontFamily objects based on the family name so all managed - // objects with same family name share the underlying GDI+ native pointer. The unmanged object is - // destroyed when its ref-count gets to zero. - // - // Make sure _fontFamily is not finalized so the underlying singleton object is kept alive. - GC.SuppressFinalize(_fontFamily); - } - - [return: NotNullIfNotNull("familyName")] - private static string? StripVerticalName(string? familyName) - { - if (familyName?.Length > 1 && familyName[0] == '@') - { - return familyName.Substring(1); - } - - return familyName; - } - - public void ToLogFont(object logFont) - { - using (ScreenDC dc = ScreenDC.Create()) - using (Graphics graphics = Graphics.FromHdcInternal(dc)) - { - ToLogFont(logFont, graphics); - } - } - - /// - /// Returns a handle to this . - /// - public IntPtr ToHfont() - { - using (ScreenDC dc = ScreenDC.Create()) - using (Graphics graphics = Graphics.FromHdcInternal(dc)) - { - Interop.User32.LOGFONT lf = ToLogFontInternal(graphics); - IntPtr handle = Interop.Gdi32.CreateFontIndirectW(ref lf); - if (handle == IntPtr.Zero) - { - throw new Win32Exception(); - } - - return handle; - } - } - - public float GetHeight() - { - using (ScreenDC dc = ScreenDC.Create()) - using (Graphics graphics = Graphics.FromHdcInternal(dc)) - { - return GetHeight(graphics); - } - } - - /// - /// Gets the size, in points, of this . - /// - [Browsable(false)] - public float SizeInPoints - { - get - { - if (Unit == GraphicsUnit.Point) - { - return Size; - } - - using (ScreenDC dc = ScreenDC.Create()) - using (Graphics graphics = Graphics.FromHdcInternal(dc)) - { - float pixelsPerPoint = (float)(graphics.DpiY / 72.0); - float lineSpacingInPixels = GetHeight(graphics); - float emHeightInPixels = lineSpacingInPixels * FontFamily.GetEmHeight(Style) / FontFamily.GetLineSpacing(Style); - - return emHeightInPixels / pixelsPerPoint; - } - } - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Font.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Font.cs index 3968ee5f63a6f..5fa7227b53721 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Font.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Font.cs @@ -19,7 +19,7 @@ namespace System.Drawing [TypeConverter(typeof(FontConverter))] [Serializable] [System.Runtime.CompilerServices.TypeForwardedFrom("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] - public sealed partial class Font : MarshalByRefObject, ICloneable, IDisposable, ISerializable + public sealed class Font : MarshalByRefObject, ICloneable, IDisposable, ISerializable { private IntPtr _nativeFont; private float _fontSize; @@ -199,8 +199,10 @@ private void Dispose(bool disposing) /// /// Returns the height of this Font in the specified graphics context. /// - public float GetHeight(Graphics graphics!!) + public float GetHeight(Graphics graphics) { + ArgumentNullException.ThrowIfNull(graphics); + float height; int status = Gdip.GdipGetFontHeight(new HandleRef(this, NativeFont), new HandleRef(graphics, graphics.NativeGraphics), out height); Gdip.CheckStatus(status); @@ -261,8 +263,10 @@ public override string ToString() => // This is used by SystemFonts when constructing a system Font objects. internal void SetSystemFontName(string systemFontName) => _systemFontName = systemFontName; - public unsafe void ToLogFont(object logFont!!, Graphics graphics) + public unsafe void ToLogFont(object logFont, Graphics graphics) { + ArgumentNullException.ThrowIfNull(logFont); + Type type = logFont.GetType(); int nativeSize = sizeof(Interop.User32.LOGFONT); if (Marshal.SizeOf(type) != nativeSize) @@ -287,8 +291,10 @@ public unsafe void ToLogFont(object logFont!!, Graphics graphics) } } - private unsafe Interop.User32.LOGFONT ToLogFontInternal(Graphics graphics!!) + private unsafe Interop.User32.LOGFONT ToLogFontInternal(Graphics graphics) { + ArgumentNullException.ThrowIfNull(graphics); + Interop.User32.LOGFONT logFont = default; Gdip.CheckStatus(Gdip.GdipGetLogFontW( new HandleRef(this, NativeFont), new HandleRef(graphics, graphics.NativeGraphics), ref logFont)); @@ -311,5 +317,421 @@ private unsafe Interop.User32.LOGFONT ToLogFontInternal(Graphics graphics!!) return logFont; } + + /// + /// Creates the GDI+ native font object. + /// + private void CreateNativeFont() + { + Debug.Assert(_nativeFont == IntPtr.Zero, "nativeFont already initialized, this will generate a handle leak."); + Debug.Assert(_fontFamily != null, "fontFamily not initialized."); + + // Note: GDI+ creates singleton font family objects (from the corresponding font file) and reference count them so + // if creating the font object from an external FontFamily, this object's FontFamily will share the same native object. + int status = Gdip.GdipCreateFont( + new HandleRef(this, _fontFamily.NativeFamily), + _fontSize, + _fontStyle, + _fontUnit, + out _nativeFont); + + // Special case this common error message to give more information + if (status == Gdip.FontStyleNotFound) + { + throw new ArgumentException(SR.Format(SR.GdiplusFontStyleNotFound, _fontFamily.Name, _fontStyle.ToString())); + } + else if (status != Gdip.Ok) + { + throw Gdip.StatusException(status); + } + } + + /// + /// Initializes a new instance of the class from the specified existing + /// and . + /// + public Font(Font prototype, FontStyle newStyle) + { + // Copy over the originalFontName because it won't get initialized + _originalFontName = prototype.OriginalFontName; + Initialize(prototype.FontFamily, prototype.Size, newStyle, prototype.Unit, SafeNativeMethods.DEFAULT_CHARSET, false); + } + + /// + /// Initializes a new instance of the class with the specified attributes. + /// + public Font(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit) + { + Initialize(family, emSize, style, unit, SafeNativeMethods.DEFAULT_CHARSET, false); + } + + /// + /// Initializes a new instance of the class with the specified attributes. + /// + public Font(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet) + { + Initialize(family, emSize, style, unit, gdiCharSet, false); + } + + /// + /// Initializes a new instance of the class with the specified attributes. + /// + public Font(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont) + { + Initialize(family, emSize, style, unit, gdiCharSet, gdiVerticalFont); + } + + /// + /// Initializes a new instance of the class with the specified attributes. + /// + public Font(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet) + { + Initialize(familyName, emSize, style, unit, gdiCharSet, IsVerticalName(familyName)); + } + + /// + /// Initializes a new instance of the class with the specified attributes. + /// + public Font(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont) + { + if (float.IsNaN(emSize) || float.IsInfinity(emSize) || emSize <= 0) + { + throw new ArgumentException(SR.Format(SR.InvalidBoundArgument, nameof(emSize), emSize, 0, "System.Single.MaxValue"), nameof(emSize)); + } + + Initialize(familyName, emSize, style, unit, gdiCharSet, gdiVerticalFont); + } + + /// + /// Initializes a new instance of the class with the specified attributes. + /// + public Font(FontFamily family, float emSize, FontStyle style) + { + Initialize(family, emSize, style, GraphicsUnit.Point, SafeNativeMethods.DEFAULT_CHARSET, false); + } + + /// + /// Initializes a new instance of the class with the specified attributes. + /// + public Font(FontFamily family, float emSize, GraphicsUnit unit) + { + Initialize(family, emSize, FontStyle.Regular, unit, SafeNativeMethods.DEFAULT_CHARSET, false); + } + + /// + /// Initializes a new instance of the class with the specified attributes. + /// + public Font(FontFamily family, float emSize) + { + Initialize(family, emSize, FontStyle.Regular, GraphicsUnit.Point, SafeNativeMethods.DEFAULT_CHARSET, false); + } + + /// + /// Initializes a new instance of the class with the specified attributes. + /// + public Font(string familyName, float emSize, FontStyle style, GraphicsUnit unit) + { + Initialize(familyName, emSize, style, unit, SafeNativeMethods.DEFAULT_CHARSET, IsVerticalName(familyName)); + } + + /// + /// Initializes a new instance of the class with the specified attributes. + /// + public Font(string familyName, float emSize, FontStyle style) + { + Initialize(familyName, emSize, style, GraphicsUnit.Point, SafeNativeMethods.DEFAULT_CHARSET, IsVerticalName(familyName)); + } + + /// + /// Initializes a new instance of the class with the specified attributes. + /// + public Font(string familyName, float emSize, GraphicsUnit unit) + { + Initialize(familyName, emSize, FontStyle.Regular, unit, SafeNativeMethods.DEFAULT_CHARSET, IsVerticalName(familyName)); + } + + /// + /// Initializes a new instance of the class with the specified attributes. + /// + public Font(string familyName, float emSize) + { + Initialize(familyName, emSize, FontStyle.Regular, GraphicsUnit.Point, SafeNativeMethods.DEFAULT_CHARSET, IsVerticalName(familyName)); + } + + /// + /// Constructor to initialize fields from an existing native GDI+ object reference. Used by ToLogFont. + /// + private Font(IntPtr nativeFont, byte gdiCharSet, bool gdiVerticalFont) + { + Debug.Assert(_nativeFont == IntPtr.Zero, "GDI+ native font already initialized, this will generate a handle leak"); + Debug.Assert(nativeFont != IntPtr.Zero, "nativeFont is null"); + + _nativeFont = nativeFont; + + Gdip.CheckStatus(Gdip.GdipGetFontUnit(new HandleRef(this, nativeFont), out GraphicsUnit unit)); + Gdip.CheckStatus(Gdip.GdipGetFontSize(new HandleRef(this, nativeFont), out float size)); + Gdip.CheckStatus(Gdip.GdipGetFontStyle(new HandleRef(this, nativeFont), out FontStyle style)); + Gdip.CheckStatus(Gdip.GdipGetFamily(new HandleRef(this, nativeFont), out IntPtr nativeFamily)); + + SetFontFamily(new FontFamily(nativeFamily)); + Initialize(_fontFamily, size, style, unit, gdiCharSet, gdiVerticalFont); + } + + /// + /// Initializes this object's fields. + /// + private void Initialize(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont) + { + _originalFontName = familyName; + + SetFontFamily(new FontFamily(StripVerticalName(familyName), createDefaultOnFail: true)); + Initialize(_fontFamily, emSize, style, unit, gdiCharSet, gdiVerticalFont); + } + + /// + /// Initializes this object's fields. + /// + private void Initialize(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont) + { + ArgumentNullException.ThrowIfNull(family); + + if (float.IsNaN(emSize) || float.IsInfinity(emSize) || emSize <= 0) + { + throw new ArgumentException(SR.Format(SR.InvalidBoundArgument, nameof(emSize), emSize, 0, "System.Single.MaxValue"), nameof(emSize)); + } + + int status; + + _fontSize = emSize; + _fontStyle = style; + _fontUnit = unit; + _gdiCharSet = gdiCharSet; + _gdiVerticalFont = gdiVerticalFont; + + if (_fontFamily == null) + { + // GDI+ FontFamily is a singleton object. + SetFontFamily(new FontFamily(family.NativeFamily)); + } + + if (_nativeFont == IntPtr.Zero) + { + CreateNativeFont(); + } + + // Get actual size. + status = Gdip.GdipGetFontSize(new HandleRef(this, _nativeFont), out _fontSize); + Gdip.CheckStatus(status); + } + + /// + /// Creates a from the specified Windows handle. + /// + public static Font FromHfont(IntPtr hfont) + { + Interop.User32.LOGFONT logFont = default; + Interop.Gdi32.GetObject(new HandleRef(null, hfont), ref logFont); + + using (ScreenDC dc = ScreenDC.Create()) + { + return FromLogFontInternal(ref logFont, dc); + } + } + + /// + /// Creates a from the given LOGFONT using the screen device context. + /// + /// A boxed LOGFONT. + /// The newly created . + public static Font FromLogFont(object lf) + { + using (ScreenDC dc = ScreenDC.Create()) + { + return FromLogFont(lf, dc); + } + } + + internal static Font FromLogFont(ref Interop.User32.LOGFONT logFont) + { + using (ScreenDC dc = ScreenDC.Create()) + { + return FromLogFont(logFont, dc); + } + } + + internal static Font FromLogFontInternal(ref Interop.User32.LOGFONT logFont, IntPtr hdc) + { + int status = Gdip.GdipCreateFontFromLogfontW(hdc, ref logFont, out IntPtr font); + + // Special case this incredibly common error message to give more information + if (status == Gdip.NotTrueTypeFont) + { + throw new ArgumentException(SR.GdiplusNotTrueTypeFont_NoName); + } + else if (status != Gdip.Ok) + { + throw Gdip.StatusException(status); + } + + // GDI+ returns font = 0 even though the status is Ok. + if (font == IntPtr.Zero) + { + throw new ArgumentException(SR.Format(SR.GdiplusNotTrueTypeFont, logFont.ToString())); + } + + bool gdiVerticalFont = logFont.lfFaceName[0] == '@'; + return new Font(font, logFont.lfCharSet, gdiVerticalFont); + } + + /// + /// Creates a from the given LOGFONT using the given device context. + /// + /// A boxed LOGFONT. + /// Handle to a device context (HDC). + /// The newly created . + public static unsafe Font FromLogFont(object lf, IntPtr hdc) + { + ArgumentNullException.ThrowIfNull(lf); + + if (lf is Interop.User32.LOGFONT logFont) + { + // A boxed LOGFONT, just use it to create the font + return FromLogFontInternal(ref logFont, hdc); + } + + Type type = lf.GetType(); + int nativeSize = sizeof(Interop.User32.LOGFONT); + if (Marshal.SizeOf(type) != nativeSize) + { + // If we don't actually have an object that is LOGFONT in size, trying to pass + // it to GDI+ is likely to cause an AV. + throw new ArgumentException(null, nameof(lf)); + } + + // Now that we know the marshalled size is the same as LOGFONT, copy in the data + logFont = default; + + Marshal.StructureToPtr(lf, new IntPtr(&logFont), fDeleteOld: false); + + return FromLogFontInternal(ref logFont, hdc); + } + + /// + /// Creates a from the specified handle to a device context (HDC). + /// + /// The newly created . + public static Font FromHdc(IntPtr hdc) + { + IntPtr font = IntPtr.Zero; + int status = Gdip.GdipCreateFontFromDC(hdc, ref font); + + // Special case this incredibly common error message to give more information + if (status == Gdip.NotTrueTypeFont) + { + throw new ArgumentException(SR.GdiplusNotTrueTypeFont_NoName); + } + else if (status != Gdip.Ok) + { + throw Gdip.StatusException(status); + } + + return new Font(font, 0, false); + } + + /// + /// Creates an exact copy of this . + /// + public object Clone() + { + int status = Gdip.GdipCloneFont(new HandleRef(this, _nativeFont), out IntPtr clonedFont); + Gdip.CheckStatus(status); + + return new Font(clonedFont, _gdiCharSet, _gdiVerticalFont); + } + + private void SetFontFamily(FontFamily family) + { + _fontFamily = family; + + // GDI+ creates ref-counted singleton FontFamily objects based on the family name so all managed + // objects with same family name share the underlying GDI+ native pointer. The unmanged object is + // destroyed when its ref-count gets to zero. + // + // Make sure _fontFamily is not finalized so the underlying singleton object is kept alive. + GC.SuppressFinalize(_fontFamily); + } + + [return: NotNullIfNotNull("familyName")] + private static string? StripVerticalName(string? familyName) + { + if (familyName?.Length > 1 && familyName[0] == '@') + { + return familyName.Substring(1); + } + + return familyName; + } + + public void ToLogFont(object logFont) + { + using (ScreenDC dc = ScreenDC.Create()) + using (Graphics graphics = Graphics.FromHdcInternal(dc)) + { + ToLogFont(logFont, graphics); + } + } + + /// + /// Returns a handle to this . + /// + public IntPtr ToHfont() + { + using (ScreenDC dc = ScreenDC.Create()) + using (Graphics graphics = Graphics.FromHdcInternal(dc)) + { + Interop.User32.LOGFONT lf = ToLogFontInternal(graphics); + IntPtr handle = Interop.Gdi32.CreateFontIndirectW(ref lf); + if (handle == IntPtr.Zero) + { + throw new Win32Exception(); + } + + return handle; + } + } + + public float GetHeight() + { + using (ScreenDC dc = ScreenDC.Create()) + using (Graphics graphics = Graphics.FromHdcInternal(dc)) + { + return GetHeight(graphics); + } + } + + /// + /// Gets the size, in points, of this . + /// + [Browsable(false)] + public float SizeInPoints + { + get + { + if (Unit == GraphicsUnit.Point) + { + return Size; + } + + using (ScreenDC dc = ScreenDC.Create()) + using (Graphics graphics = Graphics.FromHdcInternal(dc)) + { + float pixelsPerPoint = (float)(graphics.DpiY / 72.0); + float lineSpacingInPixels = GetHeight(graphics); + float emHeightInPixels = lineSpacingInPixels * FontFamily.GetEmHeight(Style) / FontFamily.GetLineSpacing(Style); + + return emHeightInPixels / pixelsPerPoint; + } + } + } } } diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/FontConverter.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/FontConverter.cs index 42fe50531576d..d818eb096d9e3 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/FontConverter.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/FontConverter.cs @@ -270,8 +270,10 @@ private static GraphicsUnit ParseGraphicsUnits(string units) => _ => throw new ArgumentException(SR.Format(SR.InvalidArgumentValueFontConverter, units), nameof(units)), }; - public override object CreateInstance(ITypeDescriptorContext? context, IDictionary propertyValues!!) + public override object CreateInstance(ITypeDescriptorContext? context, IDictionary propertyValues) { + ArgumentNullException.ThrowIfNull(propertyValues); + object? value; byte charSet = 1; float size = 8; diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/FontFamily.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/FontFamily.Unix.cs deleted file mode 100644 index 9724ec7b86f1a..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/FontFamily.Unix.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics.CodeAnalysis; - -namespace System.Drawing -{ - /// - /// Abstracts a group of type faces having a similar basic design but having certain variation in styles. - /// - public sealed partial class FontFamily : MarshalByRefObject, IDisposable - { - public override bool Equals([NotNullWhen(true)] object? obj) - { - if (obj == this) - { - return true; - } - - // if obj = null then (obj is FontFamily) = false. - if (!(obj is FontFamily otherFamily)) - { - return false; - } - - // In unix FontFamily objects are not singleton so they don't share the same native pointer, - // the best we have to know if they are the same is FontFamily.Name which gets resolved from the native pointer. - return Name.Equals(otherFamily.Name, StringComparison.Ordinal); - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/FontFamily.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/FontFamily.Windows.cs deleted file mode 100644 index a83331b1b0a69..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/FontFamily.Windows.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics.CodeAnalysis; - -namespace System.Drawing -{ - /// - /// Abstracts a group of type faces having a similar basic design but having certain variation in styles. - /// - public sealed partial class FontFamily : MarshalByRefObject, IDisposable - { - public override bool Equals([NotNullWhen(true)] object? obj) - { - if (obj == this) - { - return true; - } - - // if obj = null then (obj is FontFamily) = false. - if (!(obj is FontFamily otherFamily)) - { - return false; - } - - // We can safely use the ptr to the native GDI+ FontFamily because in windows it is common to - // all objects of the same family (singleton RO object). - return otherFamily.NativeFamily == NativeFamily; - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/FontFamily.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/FontFamily.cs index 666f19a60461c..7991b1ad6b645 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/FontFamily.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/FontFamily.cs @@ -13,7 +13,7 @@ namespace System.Drawing /// /// Abstracts a group of type faces having a similar basic design but having certain variation in styles. /// - public sealed partial class FontFamily : MarshalByRefObject, IDisposable + public sealed class FontFamily : MarshalByRefObject, IDisposable { private const int NeutralLanguage = 0; private IntPtr _nativeFamily; @@ -135,6 +135,24 @@ public FontFamily(GenericFontFamilies genericFamily) /// public override string ToString() => $"[{GetType().Name}: Name={Name}]"; + public override bool Equals([NotNullWhen(true)] object? obj) + { + if (obj == this) + { + return true; + } + + // if obj = null then (obj is FontFamily) = false. + if (!(obj is FontFamily otherFamily)) + { + return false; + } + + // We can safely use the ptr to the native GDI+ FontFamily because in windows it is common to + // all objects of the same family (singleton RO object). + return otherFamily.NativeFamily == NativeFamily; + } + /// /// Gets a hash code for this . /// @@ -226,8 +244,10 @@ private static IntPtr GetGdipGenericSansSerif() /// graphics context. /// [Obsolete("FontFamily.GetFamilies has been deprecated. Use Families instead.")] - public static FontFamily[] GetFamilies(Graphics graphics!!) + public static FontFamily[] GetFamilies(Graphics graphics) { + ArgumentNullException.ThrowIfNull(graphics); + return new InstalledFontCollection().Families; } diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/GdiPlusStreamHelper.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/GdiPlusStreamHelper.Unix.cs deleted file mode 100644 index 8013e23f54936..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/GdiPlusStreamHelper.Unix.cs +++ /dev/null @@ -1,158 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// System.Drawing.GdiPlusStreamHelper.cs -// - Originally in System.Drawing.gdipFunctions.cs -// -// Authors: -// Alexandre Pigolkine (pigolkine@gmx.de) -// Jordi Mas i Hernandez (jordi@ximian.com) -// Sanjay Gupta (gsanjay@novell.com) -// Ravindra (rkumar@novell.com) -// Peter Dennis Bartok (pbartok@novell.com) -// Sebastien Pouliot -// -// 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// 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.IO; -using System.Runtime.InteropServices; - -namespace System.Drawing -{ - internal sealed partial class GdiPlusStreamHelper - { - private Stream _stream; - - public unsafe GdiPlusStreamHelper(Stream stream, bool seekToOrigin, bool makeSeekable = true) - { - // Seeking required - if (makeSeekable && !stream.CanSeek) - { - var memoryStream = new MemoryStream(); - stream.CopyTo(memoryStream); - memoryStream.Position = 0; - _stream = memoryStream; - } - else - { - _stream = stream; - - if (seekToOrigin) - { - _stream.Seek(0, SeekOrigin.Begin); - } - } - - CloseDelegate = StreamCloseImpl; - GetBytesDelegate = StreamGetBytesImpl; - GetHeaderDelegate = StreamGetHeaderImpl; - PutBytesDelegate = StreamPutBytesImpl; - SeekDelegate = StreamSeekImpl; - SizeDelegate = StreamSizeImpl; - } - - public unsafe int StreamGetHeaderImpl(byte* buf, int bufsz) - { - return StreamGetBytesImpl(buf, bufsz, peek: true); - } - - public unsafe int StreamGetBytesImpl(byte* buf, int bufsz, bool peek) - { - if ((buf == null && peek) || !_stream.CanRead) - return -1; - - if (bufsz <= 0) - return 0; - - int read; - long originalPosition = 0; - if (peek) - { - originalPosition = _stream.Position; - } - - try - { - Span buffer = new Span(buf, bufsz); - read = _stream.Read(buffer); - } - catch (IOException) - { - return -1; - } - - if (peek) - { - // If we are peeking bytes, then go back to original position before peeking - _stream.Seek(originalPosition, SeekOrigin.Begin); - } - - return read; - } - - public long StreamSeekImpl(int offset, int whence) - { - // Make sure we have a valid 'whence'. - if ((whence < 0) || (whence > 2)) - return -1; - - return _stream.Seek((long)offset, (SeekOrigin)whence); - } - - public unsafe int StreamPutBytesImpl(byte* buf, int bufsz) - { - if (!_stream.CanWrite) - return -1; - - var buffer = new ReadOnlySpan(buf, bufsz); - _stream.Write(buffer); - - return bufsz; - } - - public void StreamCloseImpl() - { - _stream.Dispose(); - } - - public long StreamSizeImpl() - { - try - { - return _stream.Length; - } - catch - { - return -1; - } - } - - public StreamCloseDelegate CloseDelegate { get; } - public StreamGetBytesDelegate GetBytesDelegate { get; } - public StreamGetHeaderDelegate GetHeaderDelegate { get; } - public StreamPutBytesDelegate PutBytesDelegate { get; } - public StreamSeekDelegate SeekDelegate { get; } - public StreamSizeDelegate SizeDelegate { get; } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Gdiplus.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Gdiplus.cs index 743a41ad51790..723e2804a880e 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Gdiplus.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Gdiplus.cs @@ -3,12 +3,9 @@ using System.Collections; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; using System.IO; -using System.Runtime.CompilerServices; -using System.Runtime.ConstrainedExecution; +using System.Reflection; using System.Runtime.InteropServices; -using System.Threading; namespace System.Drawing { @@ -18,13 +15,19 @@ internal static partial class SafeNativeMethods internal static partial class Gdip { private static readonly IntPtr s_initToken; - private const string ThreadDataSlotName = "system.drawing.threaddata"; + + [ThreadStatic] + private static IDictionary? t_threadData; static Gdip() { - Debug.Assert(s_initToken == IntPtr.Zero, "GdiplusInitialization: Initialize should not be called more than once in the same domain!"); + if (!OperatingSystem.IsWindows()) + { + NativeLibrary.SetDllImportResolver(Assembly.GetExecutingAssembly(), static (_, _, _) => + throw new PlatformNotSupportedException(SR.PlatformNotSupported_Unix)); + } - PlatformInitialize(); + Debug.Assert(s_initToken == IntPtr.Zero, "GdiplusInitialization: Initialize should not be called more than once in the same domain!"); // GDI+ ref counts multiple calls to Startup in the same process, so calls from multiple // domains are ok, just make sure to pair each w/GdiplusShutdown @@ -42,21 +45,7 @@ static Gdip() /// a per-thread basis. This way we can avoid 'object in use' crashes when different threads are /// referencing the same drawing object. /// - internal static IDictionary ThreadData - { - get - { - LocalDataStoreSlot slot = Thread.GetNamedDataSlot(ThreadDataSlotName); - IDictionary? threadData = (IDictionary?)Thread.GetData(slot); - if (threadData == null) - { - threadData = new Hashtable(); - Thread.SetData(slot, threadData); - } - - return threadData; - } - } + internal static IDictionary ThreadData => t_threadData ??= new Hashtable(); // Used to ensure static constructor has run. internal static void DummyFunction() diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/GdiplusNative.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/GdiplusNative.Unix.cs deleted file mode 100644 index 7408d70ab74bc..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/GdiplusNative.Unix.cs +++ /dev/null @@ -1,430 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using System.Drawing.Drawing2D; -using System.Drawing.Imaging; -using System.Drawing.Printing; -using System.Drawing.Text; -using System.IO; -using System.Reflection; -using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER -using System.Runtime.InteropServices.GeneratedMarshalling; -#endif - -namespace System.Drawing -{ - internal static partial class SafeNativeMethods - { - internal unsafe partial class Gdip - { - internal const string LibraryName = "libgdiplus"; - public static IntPtr Display = IntPtr.Zero; - - // Indicates whether X11 is available. It's available on Linux but not on recent macOS versions - // When set to false, where Carbon Drawing is used instead. - // macOS users can force X11 by setting the SYSTEM_DRAWING_COMMON_FORCE_X11 flag. - public static bool UseX11Drawable { get; } = - !RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || - Environment.GetEnvironmentVariable("SYSTEM_DRAWING_COMMON_FORCE_X11") != null; - - internal static IntPtr LoadNativeLibrary() - { - var assembly = System.Reflection.Assembly.GetExecutingAssembly(); - - IntPtr lib; - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - if (!NativeLibrary.TryLoad("libgdiplus.dylib", assembly, default, out lib)) - { - // homebrew install location - if (!NativeLibrary.TryLoad("/usr/local/lib/libgdiplus.dylib", assembly, default, out lib)) - { - // macports install location - NativeLibrary.TryLoad("/opt/local/lib/libgdiplus.dylib", assembly, default, out lib); - } - } - } - else - { - // Various Unix package managers have chosen different names for the "libgdiplus" shared library. - // The mono project, where libgdiplus originated, allowed both of the names below to be used, via - // a global configuration setting. We prefer the "unversioned" shared object name, and fallback to - // the name suffixed with ".0". - if (!NativeLibrary.TryLoad("libgdiplus.so", assembly, default, out lib)) - { - NativeLibrary.TryLoad("libgdiplus.so.0", assembly, default, out lib); - } - } - - // This function may return a null handle. If it does, individual functions loaded from it will throw a DllNotFoundException, - // but not until an attempt is made to actually use the function (rather than load it). This matches how PInvokes behave. - return lib; - } - - private static void PlatformInitialize() - { - LibraryResolver.EnsureRegistered(); - } - - // Imported functions - [LibraryImport(LibraryName)] - internal static partial int GdiplusStartup(out IntPtr token, in StartupInputEx input, out StartupOutput output); - - [LibraryImport(LibraryName)] - internal static partial void GdiplusShutdown(ref ulong token); - - [LibraryImport(LibraryName)] - internal static partial IntPtr GdipAlloc(int size); - - [LibraryImport(LibraryName)] - internal static partial void GdipFree(IntPtr ptr); - - [LibraryImport(LibraryName)] - internal static partial int GdipDeleteBrush( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef brush); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetBrushType(IntPtr brush, out BrushType type); - - [LibraryImport(LibraryName)] - internal static partial int GdipDeleteGraphics( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics); - - [LibraryImport(LibraryName)] - internal static partial int GdipRestoreGraphics(IntPtr graphics, uint graphicsState); - - [LibraryImport(LibraryName)] - internal static partial int GdipReleaseDC( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef hdc); - - [LibraryImport(LibraryName)] - internal static partial int GdipFillPath(IntPtr graphics, IntPtr brush, IntPtr path); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetNearestColor(IntPtr graphics, out int argb); - - [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf16)] - internal static partial int GdipAddPathString(IntPtr path, string s, int lenght, IntPtr family, int style, float emSize, ref RectangleF layoutRect, IntPtr format); - - [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf16)] - internal static partial int GdipAddPathStringI(IntPtr path, string s, int lenght, IntPtr family, int style, float emSize, ref Rectangle layoutRect, IntPtr format); - - [LibraryImport(LibraryName)] - internal static partial int GdipCreateFromHWND(IntPtr hwnd, out IntPtr graphics); - - [LibraryImport(LibraryName)] - internal static partial int GdipCloneImage(IntPtr image, out IntPtr imageclone); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetImagePaletteSize(IntPtr image, out int size); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetImagePalette(IntPtr image, IntPtr palette, int size); - - [LibraryImport(LibraryName)] - internal static partial int GdipSetImagePalette(IntPtr image, IntPtr palette); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetImageBounds(IntPtr image, out RectangleF source, ref GraphicsUnit unit); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetImageThumbnail(IntPtr image, uint width, uint height, out IntPtr thumbImage, IntPtr callback, IntPtr callBackData); - - [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf16)] - internal static partial int GdipSaveImageToFile(IntPtr image, string filename, ref Guid encoderClsID, IntPtr encoderParameters); - - [LibraryImport(LibraryName)] - internal static partial int GdipSaveAdd(IntPtr image, IntPtr encoderParameters); - - [LibraryImport(LibraryName)] - internal static partial int GdipSaveAddImage(IntPtr image, IntPtr imagenew, IntPtr encoderParameters); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetImageGraphicsContext(IntPtr image, out IntPtr graphics); - - [LibraryImport(LibraryName)] - internal static partial int GdipCreatePath(FillMode brushMode, out IntPtr path); - - [LibraryImport(LibraryName)] - internal static partial int GdipCreatePath2(PointF[] points, byte[] types, int count, FillMode brushMode, out IntPtr path); - - [LibraryImport(LibraryName)] - internal static partial int GdipCreatePath2I(Point[] points, byte[] types, int count, FillMode brushMode, out IntPtr path); - - [LibraryImport(LibraryName)] - internal static partial int GdipClonePath(IntPtr path, out IntPtr clonePath); - - [LibraryImport(LibraryName)] - internal static partial int GdipDeletePath( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path); - - [LibraryImport(LibraryName)] - internal static partial int GdipResetPath(IntPtr path); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetPointCount(IntPtr path, out int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetPathTypes(IntPtr path, byte[] types, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetPathPoints(IntPtr path, PointF[] points, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetPathPointsI(IntPtr path, Point[] points, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetPathFillMode(IntPtr path, out FillMode fillMode); - - [LibraryImport(LibraryName)] - internal static partial int GdipSetPathFillMode(IntPtr path, FillMode fillMode); - - [LibraryImport(LibraryName)] - internal static partial int GdipStartPathFigure(IntPtr path); - - [LibraryImport(LibraryName)] - internal static partial int GdipClosePathFigure(IntPtr path); - - [LibraryImport(LibraryName)] - internal static partial int GdipClosePathFigures(IntPtr path); - - [LibraryImport(LibraryName)] - internal static partial int GdipSetPathMarker(IntPtr path); - - [LibraryImport(LibraryName)] - internal static partial int GdipClearPathMarkers(IntPtr path); - - [LibraryImport(LibraryName)] - internal static partial int GdipReversePath(IntPtr path); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetPathLastPoint(IntPtr path, out PointF lastPoint); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathLine(IntPtr path, float x1, float y1, float x2, float y2); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathLine2(IntPtr path, PointF[] points, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathLine2I(IntPtr path, Point[] points, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathArc(IntPtr path, float x, float y, float width, float height, float startAngle, float sweepAngle); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathBezier(IntPtr path, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathBeziers(IntPtr path, PointF[] points, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathCurve(IntPtr path, PointF[] points, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathCurveI(IntPtr path, Point[] points, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathCurve2(IntPtr path, PointF[] points, int count, float tension); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathCurve2I(IntPtr path, Point[] points, int count, float tension); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathCurve3(IntPtr path, PointF[] points, int count, int offset, int numberOfSegments, float tension); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathCurve3I(IntPtr path, Point[] points, int count, int offset, int numberOfSegments, float tension); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathClosedCurve(IntPtr path, PointF[] points, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathClosedCurveI(IntPtr path, Point[] points, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathClosedCurve2(IntPtr path, PointF[] points, int count, float tension); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathClosedCurve2I(IntPtr path, Point[] points, int count, float tension); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathRectangle(IntPtr path, float x, float y, float width, float height); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathRectangles(IntPtr path, RectangleF[] rects, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathEllipse(IntPtr path, float x, float y, float width, float height); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathEllipseI(IntPtr path, int x, int y, int width, int height); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathPie(IntPtr path, float x, float y, float width, float height, float startAngle, float sweepAngle); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathPieI(IntPtr path, int x, int y, int width, int height, float startAngle, float sweepAngle); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathPolygon(IntPtr path, PointF[] points, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathPath(IntPtr path, IntPtr addingPath, [MarshalAs(UnmanagedType.Bool)] bool connect); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathLineI(IntPtr path, int x1, int y1, int x2, int y2); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathArcI(IntPtr path, int x, int y, int width, int height, float startAngle, float sweepAngle); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathBezierI(IntPtr path, int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathBeziersI(IntPtr path, Point[] points, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathPolygonI(IntPtr path, Point[] points, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathRectangleI(IntPtr path, int x, int y, int width, int height); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathRectanglesI(IntPtr path, Rectangle[] rects, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipFlattenPath(IntPtr path, IntPtr matrix, float floatness); - - [LibraryImport(LibraryName)] - internal static partial int GdipTransformPath(IntPtr path, IntPtr matrix); - - [LibraryImport(LibraryName)] - internal static partial int GdipWarpPath(IntPtr path, IntPtr matrix, PointF[] points, int count, float srcx, float srcy, float srcwidth, float srcheight, WarpMode mode, float flatness); - - [LibraryImport(LibraryName)] - internal static partial int GdipWidenPath(IntPtr path, IntPtr pen, IntPtr matrix, float flatness); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetPathWorldBounds(IntPtr path, out RectangleF bounds, IntPtr matrix, IntPtr pen); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetPathWorldBoundsI(IntPtr path, out Rectangle bounds, IntPtr matrix, IntPtr pen); - - [LibraryImport(LibraryName)] - internal static partial int GdipIsVisiblePathPoint(IntPtr path, float x, float y, IntPtr graphics, [MarshalAs(UnmanagedType.Bool)] out bool result); - - [LibraryImport(LibraryName)] - internal static partial int GdipIsVisiblePathPointI(IntPtr path, int x, int y, IntPtr graphics, [MarshalAs(UnmanagedType.Bool)] out bool result); - - [LibraryImport(LibraryName)] - internal static partial int GdipIsOutlineVisiblePathPoint(IntPtr path, float x, float y, IntPtr pen, IntPtr graphics, [MarshalAs(UnmanagedType.Bool)] out bool result); - - [LibraryImport(LibraryName)] - internal static partial int GdipIsOutlineVisiblePathPointI(IntPtr path, int x, int y, IntPtr pen, IntPtr graphics, [MarshalAs(UnmanagedType.Bool)] out bool result); - - [LibraryImport(LibraryName)] - internal static partial int GdipCreateFontFromLogfont(IntPtr hdc, ref Interop.User32.LOGFONT lf, out IntPtr ptr); - - [LibraryImport(LibraryName)] - internal static partial int GdipCreateFontFromHfont(IntPtr hdc, out IntPtr font, ref Interop.User32.LOGFONT lf); - - [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf16)] - internal static partial int GdipGetMetafileHeaderFromFile(string filename, IntPtr header); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetMetafileHeaderFromMetafile(IntPtr metafile, IntPtr header); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetMetafileHeaderFromEmf(IntPtr hEmf, IntPtr header); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetMetafileHeaderFromWmf(IntPtr hWmf, IntPtr wmfPlaceableFileHeader, IntPtr header); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetHemfFromMetafile(IntPtr metafile, out IntPtr hEmf); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetMetafileDownLevelRasterizationLimit(IntPtr metafile, ref uint metafileRasterizationLimitDpi); - - [LibraryImport(LibraryName)] - internal static partial int GdipSetMetafileDownLevelRasterizationLimit(IntPtr metafile, uint metafileRasterizationLimitDpi); - - [LibraryImport(LibraryName)] - internal static partial int GdipCreateFromContext_macosx(IntPtr cgref, int width, int height, out IntPtr graphics); - - [LibraryImport(LibraryName)] - internal static partial int GdipSetVisibleClip_linux(IntPtr graphics, ref Rectangle rect); - - [LibraryImport(LibraryName)] - internal static partial int GdipCreateFromXDrawable_linux(IntPtr drawable, IntPtr display, out IntPtr graphics); - - // Stream functions for non-Win32 (libgdiplus specific) - [LibraryImport(LibraryName)] - internal static partial int GdipLoadImageFromDelegate_linux(StreamGetHeaderDelegate getHeader, - StreamGetBytesDelegate getBytes, StreamPutBytesDelegate putBytes, StreamSeekDelegate doSeek, - StreamCloseDelegate close, StreamSizeDelegate size, out IntPtr image); - - [LibraryImport(LibraryName)] - internal static partial int GdipSaveImageToDelegate_linux(IntPtr image, StreamGetBytesDelegate getBytes, - StreamPutBytesDelegate putBytes, StreamSeekDelegate doSeek, StreamCloseDelegate close, - StreamSizeDelegate size, ref Guid encoderClsID, IntPtr encoderParameters); - - [LibraryImport(LibraryName)] - internal static partial int GdipCreateMetafileFromDelegate_linux(StreamGetHeaderDelegate getHeader, - StreamGetBytesDelegate getBytes, StreamPutBytesDelegate putBytes, StreamSeekDelegate doSeek, - StreamCloseDelegate close, StreamSizeDelegate size, out IntPtr metafile); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetMetafileHeaderFromDelegate_linux(StreamGetHeaderDelegate getHeader, - StreamGetBytesDelegate getBytes, StreamPutBytesDelegate putBytes, StreamSeekDelegate doSeek, - StreamCloseDelegate close, StreamSizeDelegate size, IntPtr header); - - [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf16)] - internal static partial int GdipRecordMetafileFromDelegate_linux(StreamGetHeaderDelegate getHeader, - StreamGetBytesDelegate getBytes, StreamPutBytesDelegate putBytes, StreamSeekDelegate doSeek, - StreamCloseDelegate close, StreamSizeDelegate size, IntPtr hdc, EmfType type, ref RectangleF frameRect, - MetafileFrameUnit frameUnit, string? description, out IntPtr metafile); - - [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf16)] - internal static partial int GdipRecordMetafileFromDelegateI_linux(StreamGetHeaderDelegate getHeader, - StreamGetBytesDelegate getBytes, StreamPutBytesDelegate putBytes, StreamSeekDelegate doSeek, - StreamCloseDelegate close, StreamSizeDelegate size, IntPtr hdc, EmfType type, ref Rectangle frameRect, - MetafileFrameUnit frameUnit, string? description, out IntPtr metafile); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetPostScriptGraphicsContext( - [MarshalAs(UnmanagedType.LPUTF8Str)] string filename, - int width, int height, double dpix, double dpiy, ref IntPtr graphics); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetPostScriptSavePage(IntPtr graphics); - } - } - - // These are unix-only - internal unsafe delegate int StreamGetHeaderDelegate(byte* buf, int bufsz); - internal unsafe delegate int StreamGetBytesDelegate(byte* buf, int bufsz, bool peek); - internal delegate long StreamSeekDelegate(int offset, int whence); - internal unsafe delegate int StreamPutBytesDelegate(byte* buf, int bufsz); - internal delegate void StreamCloseDelegate(); - internal delegate long StreamSizeDelegate(); -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/GdiplusNative.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/GdiplusNative.Windows.cs deleted file mode 100644 index e5a1b81cb28ff..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/GdiplusNative.Windows.cs +++ /dev/null @@ -1,962 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Drawing2D; -using System.Drawing.Imaging; -using System.Drawing.Internal; -using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER -using System.Runtime.InteropServices.GeneratedMarshalling; -#endif - -namespace System.Drawing -{ - internal static partial class SafeNativeMethods - { - internal static unsafe partial class Gdip - { - private const string LibraryName = "gdiplus.dll"; - - private static void PlatformInitialize() - { - } - - // Imported functions - [LibraryImport(LibraryName)] - private static partial int GdiplusStartup(out IntPtr token, in StartupInputEx input, out StartupOutput output); - - [LibraryImport(LibraryName)] - internal static partial int GdipCreatePath(int brushMode, out IntPtr path); - - [LibraryImport(LibraryName)] - internal static partial int GdipCreatePath2(PointF* points, byte* types, int count, int brushMode, out IntPtr path); - - [LibraryImport(LibraryName)] - internal static partial int GdipCreatePath2I(Point* points, byte* types, int count, int brushMode, out IntPtr path); - - [LibraryImport(LibraryName)] - internal static partial int GdipClonePath( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, out IntPtr clonepath); - - [LibraryImport(LibraryName)] - internal static partial int GdipDeletePath( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path); - - [LibraryImport(LibraryName)] - internal static partial int GdipResetPath( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetPointCount( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, out int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetPathTypes( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, byte[] types, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetPathPoints( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, PointF* points, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetPathFillMode( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, out FillMode fillmode); - - [LibraryImport(LibraryName)] - internal static partial int GdipSetPathFillMode( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, FillMode fillmode); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetPathData( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, GpPathData* pathData); - - [LibraryImport(LibraryName)] - internal static partial int GdipStartPathFigure( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path); - - [LibraryImport(LibraryName)] - internal static partial int GdipClosePathFigure( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path); - - [LibraryImport(LibraryName)] - internal static partial int GdipClosePathFigures( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path); - - [LibraryImport(LibraryName)] - internal static partial int GdipSetPathMarker( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path); - - [LibraryImport(LibraryName)] - internal static partial int GdipClearPathMarkers( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path); - - [LibraryImport(LibraryName)] - internal static partial int GdipReversePath( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetPathLastPoint( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, out PointF lastPoint); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathLine( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, float x1, float y1, float x2, float y2); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathLine2( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, PointF* points, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathArc( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, float x, float y, float width, float height, float startAngle, float sweepAngle); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathBezier( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathBeziers( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, PointF* points, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathCurve( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, PointF* points, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathCurve2( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, PointF* points, int count, float tension); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathCurve3( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, PointF* points, int count, int offset, int numberOfSegments, float tension); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathClosedCurve( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, PointF* points, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathClosedCurve2( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, PointF* points, int count, float tension); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathRectangle( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, float x, float y, float width, float height); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathRectangles( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, RectangleF* rects, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathEllipse( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, float x, float y, float width, float height); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathPie( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, float x, float y, float width, float height, float startAngle, float sweepAngle); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathPolygon( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, PointF* points, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathPath( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef addingPath, [MarshalAs(UnmanagedType.Bool)] bool connect); - - [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf16)] - internal static partial int GdipAddPathString( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, string s, int length, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef fontFamily, int style, float emSize, ref RectangleF layoutRect, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef format); - - [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf16)] - internal static partial int GdipAddPathStringI( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, string s, int length, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef fontFamily, int style, float emSize, ref Rectangle layoutRect, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef format); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathLineI( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, int x1, int y1, int x2, int y2); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathLine2I( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, Point* points, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathArcI( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, int x, int y, int width, int height, float startAngle, float sweepAngle); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathBezierI( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathBeziersI( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, Point* points, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathCurveI( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, Point* points, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathCurve2I( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, Point* points, int count, float tension); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathCurve3I( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, Point* points, int count, int offset, int numberOfSegments, float tension); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathClosedCurveI( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, Point* points, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathClosedCurve2I( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, Point* points, int count, float tension); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathRectangleI( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, int x, int y, int width, int height); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathRectanglesI( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, Rectangle* rects, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathEllipseI( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, int x, int y, int width, int height); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathPieI( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, int x, int y, int width, int height, float startAngle, float sweepAngle); - - [LibraryImport(LibraryName)] - internal static partial int GdipAddPathPolygonI( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, Point* points, int count); - - [LibraryImport(LibraryName)] - internal static partial int GdipFlattenPath( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef matrixfloat, float flatness); - - [LibraryImport(LibraryName)] - internal static partial int GdipWidenPath( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef pen, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef matrix, float flatness); - - [LibraryImport(LibraryName)] - internal static partial int GdipWarpPath( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef matrix, PointF* points, int count, float srcX, float srcY, float srcWidth, float srcHeight, WarpMode warpMode, float flatness); - - [LibraryImport(LibraryName)] - internal static partial int GdipTransformPath( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef matrix); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetPathWorldBounds( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, out RectangleF gprectf, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef matrix, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef pen); - - [LibraryImport(LibraryName)] - internal static partial int GdipIsVisiblePathPoint( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, float x, float y, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics, [MarshalAs(UnmanagedType.Bool)] out bool result); - - [LibraryImport(LibraryName)] - internal static partial int GdipIsVisiblePathPointI( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, int x, int y, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics, [MarshalAs(UnmanagedType.Bool)] out bool result); - - [LibraryImport(LibraryName)] - internal static partial int GdipIsOutlineVisiblePathPoint( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, float x, float y, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef pen, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics, [MarshalAs(UnmanagedType.Bool)] out bool result); - - [LibraryImport(LibraryName)] - internal static partial int GdipIsOutlineVisiblePathPointI( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path, int x, int y, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef pen, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics, [MarshalAs(UnmanagedType.Bool)] out bool result); - - [LibraryImport(LibraryName)] - internal static partial int GdipDeleteBrush( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef brush); - - [LibraryImport(LibraryName)] - internal static partial int GdipLoadImageFromStream(IntPtr stream, IntPtr* image); - - [LibraryImport(LibraryName)] - internal static partial int GdipLoadImageFromStreamICM(IntPtr stream, IntPtr* image); - - [LibraryImport(LibraryName)] - internal static partial int GdipCloneImage( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef image, out IntPtr cloneimage); - - [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf16)] - internal static partial int GdipSaveImageToFile( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef image, string filename, ref Guid classId, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef encoderParams); - - [LibraryImport(LibraryName)] - internal static partial int GdipSaveImageToStream( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef image, IntPtr stream, Guid* classId, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef encoderParams); - - [LibraryImport(LibraryName)] - internal static partial int GdipSaveAdd( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef image, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef encoderParams); - - [LibraryImport(LibraryName)] - internal static partial int GdipSaveAddImage( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef image, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef newImage, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef encoderParams); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetImageGraphicsContext( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef image, out IntPtr graphics); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetImageBounds( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef image, out RectangleF gprectf, out GraphicsUnit unit); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetImageThumbnail( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef image, int thumbWidth, int thumbHeight, out IntPtr thumbImage, Image.GetThumbnailImageAbort? callback, IntPtr callbackdata); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetImagePalette( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef image, IntPtr palette, int size); - - [LibraryImport(LibraryName)] - internal static partial int GdipSetImagePalette( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef image, IntPtr palette); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetImagePaletteSize( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef image, out int size); - - [LibraryImport(LibraryName)] - internal static partial int GdipImageForceValidation(IntPtr image); - - [LibraryImport(LibraryName)] - internal static partial int GdipCreateFromHDC2(IntPtr hdc, IntPtr hdevice, out IntPtr graphics); - - [LibraryImport(LibraryName)] - internal static partial int GdipCreateFromHWND(IntPtr hwnd, out IntPtr graphics); - - [LibraryImport(LibraryName)] - internal static partial int GdipDeleteGraphics( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics); - - [LibraryImport(LibraryName)] - internal static partial int GdipReleaseDC( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics, IntPtr hdc); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetNearestColor( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics, ref int color); - - [LibraryImport(LibraryName)] - internal static partial IntPtr GdipCreateHalftonePalette(); - - [LibraryImport(LibraryName, SetLastError = true)] - internal static partial int GdipDrawBeziers( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef pen, PointF* points, int count); - - [LibraryImport(LibraryName, SetLastError = true)] - internal static partial int GdipDrawBeziersI( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef pen, Point* points, int count); - - [LibraryImport(LibraryName, SetLastError = true)] - internal static partial int GdipFillPath( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef brush, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef path); - - [LibraryImport(LibraryName)] - internal static partial int GdipEnumerateMetafileDestPoint( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef metafile, ref PointF destPoint, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef imageattributes); - - [LibraryImport(LibraryName)] - internal static partial int GdipEnumerateMetafileDestPointI( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef metafile, ref Point destPoint, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef imageattributes); - - [LibraryImport(LibraryName)] - internal static partial int GdipEnumerateMetafileDestRect( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef metafile, ref RectangleF destRect, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef imageattributes); - - [LibraryImport(LibraryName)] - internal static partial int GdipEnumerateMetafileDestRectI( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef metafile, ref Rectangle destRect, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef imageattributes); - - [LibraryImport(LibraryName)] - internal static partial int GdipEnumerateMetafileDestPoints( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef metafile, PointF* destPoints, int count, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef imageattributes); - - [LibraryImport(LibraryName)] - internal static partial int GdipEnumerateMetafileDestPointsI( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef metafile, Point* destPoints, int count, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef imageattributes); - - [LibraryImport(LibraryName)] - internal static partial int GdipEnumerateMetafileSrcRectDestPoint( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef metafile, ref PointF destPoint, ref RectangleF srcRect, GraphicsUnit pageUnit, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef imageattributes); - - [LibraryImport(LibraryName)] - internal static partial int GdipEnumerateMetafileSrcRectDestPointI( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef metafile, ref Point destPoint, ref Rectangle srcRect, GraphicsUnit pageUnit, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef imageattributes); - - [LibraryImport(LibraryName)] - internal static partial int GdipEnumerateMetafileSrcRectDestRect( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef metafile, ref RectangleF destRect, ref RectangleF srcRect, GraphicsUnit pageUnit, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef imageattributes); - - [LibraryImport(LibraryName)] - internal static partial int GdipEnumerateMetafileSrcRectDestRectI( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef metafile, ref Rectangle destRect, ref Rectangle srcRect, GraphicsUnit pageUnit, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef imageattributes); - - [LibraryImport(LibraryName)] - internal static partial int GdipEnumerateMetafileSrcRectDestPoints( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef metafile, PointF* destPoints, int count, ref RectangleF srcRect, GraphicsUnit pageUnit, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef imageattributes); - - [LibraryImport(LibraryName)] - internal static partial int GdipEnumerateMetafileSrcRectDestPointsI( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef metafile, Point* destPoints, int count, ref Rectangle srcRect, GraphicsUnit pageUnit, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef imageattributes); - - [LibraryImport(LibraryName)] - internal static partial int GdipRestoreGraphics( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics, int state); - - [LibraryImport(LibraryName, EntryPoint = "GdipGetMetafileHeaderFromWmf")] - private static partial int GdipGetMetafileHeaderFromWmf_Internal(IntPtr hMetafile, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(WmfPlaceableFileHeader.PinningMarshaller))] -#endif - WmfPlaceableFileHeader wmfplaceable, -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(MetafileHeaderWmf.InPlaceMarshaller))] - ref MetafileHeaderWmf metafileHeaderWmf -#else - MetafileHeaderWmf metafileHeaderWmf -#endif - ); - - internal static int GdipGetMetafileHeaderFromWmf(IntPtr hMetafile, - WmfPlaceableFileHeader wmfplaceable, - MetafileHeaderWmf metafileHeaderWmf - ) - { - return GdipGetMetafileHeaderFromWmf_Internal(hMetafile, - wmfplaceable, -#if NET7_0_OR_GREATER - ref -#endif - metafileHeaderWmf - ); - } - - [LibraryImport(LibraryName)] - internal static partial int GdipGetMetafileHeaderFromEmf(IntPtr hEnhMetafile, MetafileHeaderEmf metafileHeaderEmf); - - [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf16)] - internal static partial int GdipGetMetafileHeaderFromFile(string filename, IntPtr header); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetMetafileHeaderFromStream(IntPtr stream, IntPtr header); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetMetafileHeaderFromMetafile( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef metafile, IntPtr header); - - [LibraryImport(LibraryName)] - internal static partial int GdipGetHemfFromMetafile( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef metafile, out IntPtr hEnhMetafile); - - [LibraryImport(LibraryName)] - internal static partial int GdipCreateMetafileFromStream(IntPtr stream, IntPtr* metafile); - - [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf16)] - internal static partial int GdipRecordMetafileStream(IntPtr stream, IntPtr referenceHdc, EmfType emfType, RectangleF* frameRect, MetafileFrameUnit frameUnit, string? description, IntPtr* metafile); - - [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf16)] - internal static partial int GdipRecordMetafileStream(IntPtr stream, IntPtr referenceHdc, EmfType emfType, IntPtr pframeRect, MetafileFrameUnit frameUnit, string? description, IntPtr* metafile); - - [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf16)] - internal static partial int GdipRecordMetafileStreamI(IntPtr stream, IntPtr referenceHdc, EmfType emfType, Rectangle* frameRect, MetafileFrameUnit frameUnit, string? description, IntPtr* metafile); - - [LibraryImport(LibraryName)] - internal static partial int GdipComment( -#if NET7_0_OR_GREATER - [MarshalUsing(typeof(HandleRefMarshaller))] -#endif - HandleRef graphics, int sizeData, byte[] data); - - [LibraryImport(LibraryName)] - internal static partial int GdipCreateFontFromLogfontW(IntPtr hdc, ref Interop.User32.LOGFONT lf, out IntPtr font); - - [LibraryImport(LibraryName)] - internal static partial int GdipCreateBitmapFromStream(IntPtr stream, IntPtr* bitmap); - - [LibraryImport(LibraryName)] - internal static partial int GdipCreateBitmapFromStreamICM(IntPtr stream, IntPtr* bitmap); - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/GdiplusNative.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/GdiplusNative.cs index fcc863646d8cc..6fed3bdce2210 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/GdiplusNative.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/GdiplusNative.cs @@ -3,6 +3,7 @@ using System.Drawing.Drawing2D; using System.Drawing.Imaging; +using System.Drawing.Internal; using System.Drawing.Text; using System.Runtime.InteropServices; #if NET7_0_OR_GREATER @@ -12,12 +13,16 @@ namespace System.Drawing { // Raw function imports for gdiplus - // Functions are loaded manually in order to accomodate different shared library names on Unix. internal static partial class SafeNativeMethods { internal static unsafe partial class Gdip { - // Shared function imports (all platforms) + private const string LibraryName = "gdiplus.dll"; + + // Imported functions + [LibraryImport(LibraryName)] + private static partial int GdiplusStartup(out IntPtr token, in StartupInputEx input, out StartupOutput output); + [LibraryImport(LibraryName)] internal static partial int GdipBeginContainer( #if NET7_0_OR_GREATER @@ -3449,6 +3454,940 @@ internal static partial int GdipGetEncoderParameterList( [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef image, ref Guid encoder, int size, IntPtr buffer); + + [LibraryImport(LibraryName)] + internal static partial int GdipCreatePath(int brushMode, out IntPtr path); + + [LibraryImport(LibraryName)] + internal static partial int GdipCreatePath2(PointF* points, byte* types, int count, int brushMode, out IntPtr path); + + [LibraryImport(LibraryName)] + internal static partial int GdipCreatePath2I(Point* points, byte* types, int count, int brushMode, out IntPtr path); + + [LibraryImport(LibraryName)] + internal static partial int GdipClonePath( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, out IntPtr clonepath); + + [LibraryImport(LibraryName)] + internal static partial int GdipDeletePath( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path); + + [LibraryImport(LibraryName)] + internal static partial int GdipResetPath( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path); + + [LibraryImport(LibraryName)] + internal static partial int GdipGetPointCount( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, out int count); + + [LibraryImport(LibraryName)] + internal static partial int GdipGetPathTypes( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, byte[] types, int count); + + [LibraryImport(LibraryName)] + internal static partial int GdipGetPathPoints( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, PointF* points, int count); + + [LibraryImport(LibraryName)] + internal static partial int GdipGetPathFillMode( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, out FillMode fillmode); + + [LibraryImport(LibraryName)] + internal static partial int GdipSetPathFillMode( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, FillMode fillmode); + + [LibraryImport(LibraryName)] + internal static partial int GdipGetPathData( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, GpPathData* pathData); + + [LibraryImport(LibraryName)] + internal static partial int GdipStartPathFigure( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path); + + [LibraryImport(LibraryName)] + internal static partial int GdipClosePathFigure( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path); + + [LibraryImport(LibraryName)] + internal static partial int GdipClosePathFigures( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path); + + [LibraryImport(LibraryName)] + internal static partial int GdipSetPathMarker( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path); + + [LibraryImport(LibraryName)] + internal static partial int GdipClearPathMarkers( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path); + + [LibraryImport(LibraryName)] + internal static partial int GdipReversePath( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path); + + [LibraryImport(LibraryName)] + internal static partial int GdipGetPathLastPoint( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, out PointF lastPoint); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathLine( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, float x1, float y1, float x2, float y2); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathLine2( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, PointF* points, int count); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathArc( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, float x, float y, float width, float height, float startAngle, float sweepAngle); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathBezier( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathBeziers( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, PointF* points, int count); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathCurve( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, PointF* points, int count); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathCurve2( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, PointF* points, int count, float tension); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathCurve3( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, PointF* points, int count, int offset, int numberOfSegments, float tension); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathClosedCurve( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, PointF* points, int count); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathClosedCurve2( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, PointF* points, int count, float tension); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathRectangle( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, float x, float y, float width, float height); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathRectangles( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, RectangleF* rects, int count); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathEllipse( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, float x, float y, float width, float height); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathPie( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, float x, float y, float width, float height, float startAngle, float sweepAngle); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathPolygon( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, PointF* points, int count); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathPath( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef addingPath, [MarshalAs(UnmanagedType.Bool)] bool connect); + + [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf16)] + internal static partial int GdipAddPathString( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, string s, int length, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef fontFamily, int style, float emSize, ref RectangleF layoutRect, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef format); + + [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf16)] + internal static partial int GdipAddPathStringI( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, string s, int length, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef fontFamily, int style, float emSize, ref Rectangle layoutRect, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef format); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathLineI( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, int x1, int y1, int x2, int y2); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathLine2I( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, Point* points, int count); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathArcI( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, int x, int y, int width, int height, float startAngle, float sweepAngle); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathBezierI( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathBeziersI( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, Point* points, int count); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathCurveI( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, Point* points, int count); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathCurve2I( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, Point* points, int count, float tension); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathCurve3I( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, Point* points, int count, int offset, int numberOfSegments, float tension); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathClosedCurveI( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, Point* points, int count); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathClosedCurve2I( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, Point* points, int count, float tension); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathRectangleI( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, int x, int y, int width, int height); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathRectanglesI( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, Rectangle* rects, int count); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathEllipseI( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, int x, int y, int width, int height); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathPieI( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, int x, int y, int width, int height, float startAngle, float sweepAngle); + + [LibraryImport(LibraryName)] + internal static partial int GdipAddPathPolygonI( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, Point* points, int count); + + [LibraryImport(LibraryName)] + internal static partial int GdipFlattenPath( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef matrixfloat, float flatness); + + [LibraryImport(LibraryName)] + internal static partial int GdipWidenPath( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef pen, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef matrix, float flatness); + + [LibraryImport(LibraryName)] + internal static partial int GdipWarpPath( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef matrix, PointF* points, int count, float srcX, float srcY, float srcWidth, float srcHeight, WarpMode warpMode, float flatness); + + [LibraryImport(LibraryName)] + internal static partial int GdipTransformPath( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef matrix); + + [LibraryImport(LibraryName)] + internal static partial int GdipGetPathWorldBounds( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, out RectangleF gprectf, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef matrix, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef pen); + + [LibraryImport(LibraryName)] + internal static partial int GdipIsVisiblePathPoint( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, float x, float y, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef graphics, [MarshalAs(UnmanagedType.Bool)] out bool result); + + [LibraryImport(LibraryName)] + internal static partial int GdipIsVisiblePathPointI( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, int x, int y, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef graphics, [MarshalAs(UnmanagedType.Bool)] out bool result); + + [LibraryImport(LibraryName)] + internal static partial int GdipIsOutlineVisiblePathPoint( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, float x, float y, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef pen, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef graphics, [MarshalAs(UnmanagedType.Bool)] out bool result); + + [LibraryImport(LibraryName)] + internal static partial int GdipIsOutlineVisiblePathPointI( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path, int x, int y, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef pen, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef graphics, [MarshalAs(UnmanagedType.Bool)] out bool result); + + [LibraryImport(LibraryName)] + internal static partial int GdipDeleteBrush( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef brush); + + [LibraryImport(LibraryName)] + internal static partial int GdipLoadImageFromStream(IntPtr stream, IntPtr* image); + + [LibraryImport(LibraryName)] + internal static partial int GdipLoadImageFromStreamICM(IntPtr stream, IntPtr* image); + + [LibraryImport(LibraryName)] + internal static partial int GdipCloneImage( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef image, out IntPtr cloneimage); + + [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf16)] + internal static partial int GdipSaveImageToFile( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef image, string filename, ref Guid classId, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef encoderParams); + + [LibraryImport(LibraryName)] + internal static partial int GdipSaveImageToStream( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef image, IntPtr stream, Guid* classId, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef encoderParams); + + [LibraryImport(LibraryName)] + internal static partial int GdipSaveAdd( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef image, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef encoderParams); + + [LibraryImport(LibraryName)] + internal static partial int GdipSaveAddImage( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef image, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef newImage, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef encoderParams); + + [LibraryImport(LibraryName)] + internal static partial int GdipGetImageGraphicsContext( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef image, out IntPtr graphics); + + [LibraryImport(LibraryName)] + internal static partial int GdipGetImageBounds( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef image, out RectangleF gprectf, out GraphicsUnit unit); + + [LibraryImport(LibraryName)] + internal static partial int GdipGetImageThumbnail( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef image, int thumbWidth, int thumbHeight, out IntPtr thumbImage, Image.GetThumbnailImageAbort? callback, IntPtr callbackdata); + + [LibraryImport(LibraryName)] + internal static partial int GdipGetImagePalette( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef image, IntPtr palette, int size); + + [LibraryImport(LibraryName)] + internal static partial int GdipSetImagePalette( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef image, IntPtr palette); + + [LibraryImport(LibraryName)] + internal static partial int GdipGetImagePaletteSize( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef image, out int size); + + [LibraryImport(LibraryName)] + internal static partial int GdipImageForceValidation(IntPtr image); + + [LibraryImport(LibraryName)] + internal static partial int GdipCreateFromHDC2(IntPtr hdc, IntPtr hdevice, out IntPtr graphics); + + [LibraryImport(LibraryName)] + internal static partial int GdipCreateFromHWND(IntPtr hwnd, out IntPtr graphics); + + [LibraryImport(LibraryName)] + internal static partial int GdipDeleteGraphics( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef graphics); + + [LibraryImport(LibraryName)] + internal static partial int GdipReleaseDC( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef graphics, IntPtr hdc); + + [LibraryImport(LibraryName)] + internal static partial int GdipGetNearestColor( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef graphics, ref int color); + + [LibraryImport(LibraryName)] + internal static partial IntPtr GdipCreateHalftonePalette(); + + [LibraryImport(LibraryName, SetLastError = true)] + internal static partial int GdipDrawBeziers( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef graphics, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef pen, PointF* points, int count); + + [LibraryImport(LibraryName, SetLastError = true)] + internal static partial int GdipDrawBeziersI( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef graphics, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef pen, Point* points, int count); + + [LibraryImport(LibraryName, SetLastError = true)] + internal static partial int GdipFillPath( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef graphics, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef brush, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef path); + + [LibraryImport(LibraryName)] + internal static partial int GdipEnumerateMetafileDestPoint( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef graphics, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef metafile, ref PointF destPoint, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef imageattributes); + + [LibraryImport(LibraryName)] + internal static partial int GdipEnumerateMetafileDestPointI( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef graphics, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef metafile, ref Point destPoint, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef imageattributes); + + [LibraryImport(LibraryName)] + internal static partial int GdipEnumerateMetafileDestRect( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef graphics, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef metafile, ref RectangleF destRect, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef imageattributes); + + [LibraryImport(LibraryName)] + internal static partial int GdipEnumerateMetafileDestRectI( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef graphics, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef metafile, ref Rectangle destRect, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef imageattributes); + + [LibraryImport(LibraryName)] + internal static partial int GdipEnumerateMetafileDestPoints( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef graphics, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef metafile, PointF* destPoints, int count, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef imageattributes); + + [LibraryImport(LibraryName)] + internal static partial int GdipEnumerateMetafileDestPointsI( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef graphics, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef metafile, Point* destPoints, int count, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef imageattributes); + + [LibraryImport(LibraryName)] + internal static partial int GdipEnumerateMetafileSrcRectDestPoint( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef graphics, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef metafile, ref PointF destPoint, ref RectangleF srcRect, GraphicsUnit pageUnit, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef imageattributes); + + [LibraryImport(LibraryName)] + internal static partial int GdipEnumerateMetafileSrcRectDestPointI( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef graphics, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef metafile, ref Point destPoint, ref Rectangle srcRect, GraphicsUnit pageUnit, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef imageattributes); + + [LibraryImport(LibraryName)] + internal static partial int GdipEnumerateMetafileSrcRectDestRect( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef graphics, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef metafile, ref RectangleF destRect, ref RectangleF srcRect, GraphicsUnit pageUnit, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef imageattributes); + + [LibraryImport(LibraryName)] + internal static partial int GdipEnumerateMetafileSrcRectDestRectI( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef graphics, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef metafile, ref Rectangle destRect, ref Rectangle srcRect, GraphicsUnit pageUnit, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef imageattributes); + + [LibraryImport(LibraryName)] + internal static partial int GdipEnumerateMetafileSrcRectDestPoints( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef graphics, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef metafile, PointF* destPoints, int count, ref RectangleF srcRect, GraphicsUnit pageUnit, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef imageattributes); + + [LibraryImport(LibraryName)] + internal static partial int GdipEnumerateMetafileSrcRectDestPointsI( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef graphics, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef metafile, Point* destPoints, int count, ref Rectangle srcRect, GraphicsUnit pageUnit, Graphics.EnumerateMetafileProc callback, IntPtr callbackdata, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef imageattributes); + + [LibraryImport(LibraryName)] + internal static partial int GdipRestoreGraphics( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef graphics, int state); + + [LibraryImport(LibraryName, EntryPoint = "GdipGetMetafileHeaderFromWmf")] + private static partial int GdipGetMetafileHeaderFromWmf_Internal(IntPtr hMetafile, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(WmfPlaceableFileHeader.PinningMarshaller))] +#endif + WmfPlaceableFileHeader wmfplaceable, +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(MetafileHeaderWmf.InPlaceMarshaller))] + ref MetafileHeaderWmf metafileHeaderWmf +#else + MetafileHeaderWmf metafileHeaderWmf +#endif + ); + + internal static int GdipGetMetafileHeaderFromWmf(IntPtr hMetafile, + WmfPlaceableFileHeader wmfplaceable, + MetafileHeaderWmf metafileHeaderWmf + ) + { + return GdipGetMetafileHeaderFromWmf_Internal(hMetafile, + wmfplaceable, +#if NET7_0_OR_GREATER + ref +#endif + metafileHeaderWmf + ); + } + + [LibraryImport(LibraryName)] + internal static partial int GdipGetMetafileHeaderFromEmf(IntPtr hEnhMetafile, MetafileHeaderEmf metafileHeaderEmf); + + [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf16)] + internal static partial int GdipGetMetafileHeaderFromFile(string filename, IntPtr header); + + [LibraryImport(LibraryName)] + internal static partial int GdipGetMetafileHeaderFromStream(IntPtr stream, IntPtr header); + + [LibraryImport(LibraryName)] + internal static partial int GdipGetMetafileHeaderFromMetafile( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef metafile, IntPtr header); + + [LibraryImport(LibraryName)] + internal static partial int GdipGetHemfFromMetafile( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef metafile, out IntPtr hEnhMetafile); + + [LibraryImport(LibraryName)] + internal static partial int GdipCreateMetafileFromStream(IntPtr stream, IntPtr* metafile); + + [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf16)] + internal static partial int GdipRecordMetafileStream(IntPtr stream, IntPtr referenceHdc, EmfType emfType, RectangleF* frameRect, MetafileFrameUnit frameUnit, string? description, IntPtr* metafile); + + [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf16)] + internal static partial int GdipRecordMetafileStream(IntPtr stream, IntPtr referenceHdc, EmfType emfType, IntPtr pframeRect, MetafileFrameUnit frameUnit, string? description, IntPtr* metafile); + + [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf16)] + internal static partial int GdipRecordMetafileStreamI(IntPtr stream, IntPtr referenceHdc, EmfType emfType, Rectangle* frameRect, MetafileFrameUnit frameUnit, string? description, IntPtr* metafile); + + [LibraryImport(LibraryName)] + internal static partial int GdipComment( +#if NET7_0_OR_GREATER + [MarshalUsing(typeof(HandleRefMarshaller))] +#endif + HandleRef graphics, int sizeData, byte[] data); + + [LibraryImport(LibraryName, StringMarshalling = StringMarshalling.Utf16)] + internal static partial int GdipCreateFontFromLogfontW(IntPtr hdc, ref Interop.User32.LOGFONT lf, out IntPtr font); + + [LibraryImport(LibraryName)] + internal static partial int GdipCreateBitmapFromStream(IntPtr stream, IntPtr* bitmap); + + [LibraryImport(LibraryName)] + internal static partial int GdipCreateBitmapFromStreamICM(IntPtr stream, IntPtr* bitmap); + } [StructLayout(LayoutKind.Sequential)] diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Graphics.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Graphics.Unix.cs deleted file mode 100644 index 6667baf90962b..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Graphics.Unix.cs +++ /dev/null @@ -1,571 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// System.Drawing.Graphics.cs -// -// Authors: -// Gonzalo Paniagua Javier (gonzalo@ximian.com) (stubbed out) -// Alexandre Pigolkine(pigolkine@gmx.de) -// Jordi Mas i Hernandez (jordi@ximian.com) -// Sebastien Pouliot -// -// Copyright (C) 2003 Ximian, Inc. (http://www.ximian.com) -// Copyright (C) 2004-2006 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// 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.Drawing.Drawing2D; -using System.Drawing.Imaging; -using System.Drawing.Internal; -using System.Drawing.Text; -using System.ComponentModel; -using System.Runtime.InteropServices; -using System.Text; -using Gdip = System.Drawing.SafeNativeMethods.Gdip; -using System.Runtime.Versioning; - -namespace System.Drawing -{ - public sealed partial class Graphics : MarshalByRefObject, IDisposable, IDeviceContext - { - internal IMacContext? maccontext; - private bool disposed; - private static float defDpiX; - private static float defDpiY; - private Metafile.MetafileHolder? _metafileHolder; - - internal Graphics(IntPtr nativeGraphics) => NativeGraphics = nativeGraphics; - - internal Graphics(IntPtr nativeGraphics, Image image) : this(nativeGraphics) - { - if (image is Metafile mf) - { - _metafileHolder = mf.AddMetafileHolder(); - } - } - - ~Graphics() - { - Dispose(); - } - - internal static float systemDpiX - { - get - { - if (defDpiX == 0) - { - Bitmap bmp = new Bitmap(1, 1); - Graphics g = Graphics.FromImage(bmp); - defDpiX = g.DpiX; - defDpiY = g.DpiY; - } - return defDpiX; - } - } - - internal static float systemDpiY - { - get - { - if (defDpiY == 0) - { - Bitmap bmp = new Bitmap(1, 1); - Graphics g = Graphics.FromImage(bmp); - defDpiX = g.DpiX; - defDpiY = g.DpiY; - } - return defDpiY; - } - } - - public void AddMetafileComment(byte[] data) - { - throw new NotImplementedException(); - } - - public GraphicsContainer BeginContainer() - { - int state; - int status = Gdip.GdipBeginContainer2(new HandleRef(this, NativeGraphics), out state); - Gdip.CheckStatus(status); - - return new GraphicsContainer(state); - } - - public GraphicsContainer BeginContainer(Rectangle dstrect, Rectangle srcrect, GraphicsUnit unit) - { - int state; - - int status = Gdip.GdipBeginContainerI(new HandleRef(this, NativeGraphics), ref dstrect, ref srcrect, unit, out state); - Gdip.CheckStatus(status); - - return new GraphicsContainer(state); - } - - public GraphicsContainer BeginContainer(RectangleF dstrect, RectangleF srcrect, GraphicsUnit unit) - { - int state; - - int status = Gdip.GdipBeginContainer(new HandleRef(this, NativeGraphics), ref dstrect, ref srcrect, unit, out state); - Gdip.CheckStatus(status); - - return new GraphicsContainer(state); - } - - public void CopyFromScreen(int sourceX, int sourceY, int destinationX, int destinationY, Size blockRegionSize, CopyPixelOperation copyPixelOperation) - { - if (!Enum.IsDefined(typeof(CopyPixelOperation), copyPixelOperation)) - throw new InvalidEnumArgumentException(string.Format("Enum argument value '{0}' is not valid for CopyPixelOperation", copyPixelOperation)); - - if (Gdip.UseX11Drawable) - { - CopyFromScreenX11(sourceX, sourceY, destinationX, destinationY, blockRegionSize, copyPixelOperation); - } - else - { - throw new PlatformNotSupportedException(); - } - } - - private void CopyFromScreenX11(int sourceX, int sourceY, int destinationX, int destinationY, Size blockRegionSize, CopyPixelOperation copyPixelOperation) - { - IntPtr window, image, defvisual, vPtr; - int AllPlanes = ~0, nitems = 0, pixel; - - if (copyPixelOperation != CopyPixelOperation.SourceCopy) - throw new NotImplementedException(SR.NotImplementedUnderX11); - - if (Gdip.Display == IntPtr.Zero) - { - Gdip.Display = LibX11Functions.XOpenDisplay(IntPtr.Zero); - } - - window = LibX11Functions.XRootWindow(Gdip.Display, 0); - defvisual = LibX11Functions.XDefaultVisual(Gdip.Display, 0); - XVisualInfo visual = default; - - /* Get XVisualInfo for this visual */ - visual.visualid = LibX11Functions.XVisualIDFromVisual(defvisual); - vPtr = LibX11Functions.XGetVisualInfo(Gdip.Display, 0x1 /* VisualIDMask */, ref visual, ref nitems); - visual = Marshal.PtrToStructure(vPtr)!; - image = LibX11Functions.XGetImage(Gdip.Display, window, sourceX, sourceY, blockRegionSize.Width, - blockRegionSize.Height, AllPlanes, 2 /* ZPixmap*/); - if (image == IntPtr.Zero) - { - string s = string.Format("XGetImage returned NULL when asked to for a {0}x{1} region block", - blockRegionSize.Width, blockRegionSize.Height); - throw new InvalidOperationException(s); - } - - Bitmap bmp = new Bitmap(blockRegionSize.Width, blockRegionSize.Height); - int red, blue, green; - int red_mask = (int)visual.red_mask; - int blue_mask = (int)visual.blue_mask; - int green_mask = (int)visual.green_mask; - for (int y = 0; y < blockRegionSize.Height; y++) - { - for (int x = 0; x < blockRegionSize.Width; x++) - { - pixel = LibX11Functions.XGetPixel(image, x, y); - - switch (visual.depth) - { - case 16: /* 16bbp pixel transformation */ - red = (int)((pixel & red_mask) >> 8) & 0xff; - green = (int)(((pixel & green_mask) >> 3)) & 0xff; - blue = (int)((pixel & blue_mask) << 3) & 0xff; - break; - case 24: - case 32: - red = (int)((pixel & red_mask) >> 16) & 0xff; - green = (int)(((pixel & green_mask) >> 8)) & 0xff; - blue = (int)((pixel & blue_mask)) & 0xff; - break; - default: - string text = string.Format("{0}bbp depth not supported.", visual.depth); - throw new NotImplementedException(text); - } - - bmp.SetPixel(x, y, Color.FromArgb(255, red, green, blue)); - } - } - - DrawImage(bmp, destinationX, destinationY); - bmp.Dispose(); - LibX11Functions.XDestroyImage(image); - LibX11Functions.XFree(vPtr); - } - - public void Dispose() - { - int status; - if (!disposed) - { - if (_nativeHdc != IntPtr.Zero) // avoid a handle leak. - { - ReleaseHdc(); - } - - if (!Gdip.UseX11Drawable) - { - Flush(); - if (maccontext != null) - maccontext.Release(); - } - - status = Gdip.GdipDeleteGraphics(new HandleRef(this, NativeGraphics)); - NativeGraphics = IntPtr.Zero; - Gdip.CheckStatus(status); - - if (_metafileHolder != null) - { - var mh = _metafileHolder; - _metafileHolder = null; - mh.GraphicsDisposed(); - } - - disposed = true; - } - - GC.SuppressFinalize(this); - } - - public void DrawBeziers(Pen pen!!, Point[] points!!) - { - int length = points.Length; - int status; - - if (length < 4) - return; - - for (int i = 0; i < length - 1; i += 3) - { - Point p1 = points[i]; - Point p2 = points[i + 1]; - Point p3 = points[i + 2]; - Point p4 = points[i + 3]; - - status = Gdip.GdipDrawBezier( - new HandleRef(this, NativeGraphics), new HandleRef(pen, pen.NativePen), - p1.X, p1.Y, p2.X, p2.Y, - p3.X, p3.Y, p4.X, p4.Y); - Gdip.CheckStatus(status); - } - } - - public void DrawBeziers(Pen pen!!, PointF[] points!!) - { - int length = points.Length; - int status; - - if (length < 4) - return; - - for (int i = 0; i < length - 1; i += 3) - { - PointF p1 = points[i]; - PointF p2 = points[i + 1]; - PointF p3 = points[i + 2]; - PointF p4 = points[i + 3]; - - status = Gdip.GdipDrawBezier( - new HandleRef(this, NativeGraphics), new HandleRef(pen, pen.NativePen), - p1.X, p1.Y, p2.X, p2.Y, - p3.X, p3.Y, p4.X, p4.Y); - Gdip.CheckStatus(status); - } - } - - public void DrawIcon(Icon icon!!, Rectangle targetRect) - { - DrawImage(icon.GetInternalBitmap(), targetRect); - } - - public void DrawIcon(Icon icon!!, int x, int y) - { - DrawImage(icon.GetInternalBitmap(), x, y); - } - - public void DrawIconUnstretched(Icon icon!!, Rectangle targetRect) - { - DrawImageUnscaled(icon.GetInternalBitmap(), targetRect); - } - - public void DrawLine(Pen pen!!, float x1, float y1, float x2, float y2) - { - if (!float.IsNaN(x1) && !float.IsNaN(y1) && - !float.IsNaN(x2) && !float.IsNaN(y2)) - { - int status = Gdip.GdipDrawLine(new HandleRef(this, NativeGraphics), new HandleRef(pen, pen.NativePen), x1, y1, x2, y2); - Gdip.CheckStatus(status); - } - } - - public void EndContainer(GraphicsContainer container!!) - { - int status = Gdip.GdipEndContainer(new HandleRef(this, NativeGraphics), container.nativeGraphicsContainer); - Gdip.CheckStatus(status); - } - - public void EnumerateMetafile(Metafile metafile, RectangleF destRect, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes? imageAttr) - { - throw new NotImplementedException(); - } - - public void EnumerateMetafile(Metafile metafile, Point destPoint, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes? imageAttr) - { - throw new NotImplementedException(); - } - - public void EnumerateMetafile(Metafile metafile, PointF destPoint, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes? imageAttr) - { - throw new NotImplementedException(); - } - - public void EnumerateMetafile(Metafile metafile, Point[] destPoints, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes? imageAttr) - { - throw new NotImplementedException(); - } - - public void EnumerateMetafile(Metafile metafile, PointF[] destPoints, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes? imageAttr) - { - throw new NotImplementedException(); - } - - public void EnumerateMetafile(Metafile metafile, Rectangle destRect, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes? imageAttr) - { - throw new NotImplementedException(); - } - - public void EnumerateMetafile(Metafile metafile, Point[] destPoints, Rectangle srcRect, GraphicsUnit unit, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes? imageAttr) - { - throw new NotImplementedException(); - } - - public void EnumerateMetafile(Metafile metafile, Rectangle destRect, Rectangle srcRect, GraphicsUnit unit, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes? imageAttr) - { - throw new NotImplementedException(); - } - - public void EnumerateMetafile(Metafile metafile, Point destPoint, Rectangle srcRect, GraphicsUnit unit, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes? imageAttr) - { - throw new NotImplementedException(); - } - - public void EnumerateMetafile(Metafile metafile, RectangleF destRect, RectangleF srcRect, GraphicsUnit unit, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes? imageAttr) - { - throw new NotImplementedException(); - } - - public void EnumerateMetafile(Metafile metafile, PointF[] destPoints, RectangleF srcRect, GraphicsUnit unit, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes? imageAttr) - { - throw new NotImplementedException(); - } - - public void EnumerateMetafile(Metafile metafile, PointF destPoint, RectangleF srcRect, GraphicsUnit unit, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes? imageAttr) - { - throw new NotImplementedException(); - } - - public void FillPath(Brush brush!!, GraphicsPath path!!) - { - int status = Gdip.GdipFillPath(NativeGraphics, brush.NativeBrush, path._nativePath); - Gdip.CheckStatus(status); - } - - public void FillRegion(Brush brush!!, Region region!!) - { - int status = (int)Gdip.GdipFillRegion(new HandleRef(this, NativeGraphics), new HandleRef(brush, brush.NativeBrush), new HandleRef(region, region.NativeRegion)); - Gdip.CheckStatus(status); - } - - private void FlushCore() => maccontext?.Synchronize(); - - [EditorBrowsable(EditorBrowsableState.Advanced)] - public static Graphics FromHdc(IntPtr hdc) - { - IntPtr graphics; - int status = Gdip.GdipCreateFromHDC(hdc, out graphics); - Gdip.CheckStatus(status); - return new Graphics(graphics); - } - - [EditorBrowsable(EditorBrowsableState.Advanced)] - public static Graphics FromHdc(IntPtr hdc, IntPtr hdevice) - { - throw new NotImplementedException(); - } - - [EditorBrowsable(EditorBrowsableState.Advanced)] - public static Graphics? FromHdcInternal(IntPtr hdc) - { - Gdip.Display = hdc; - return null; - } - - [EditorBrowsable(EditorBrowsableState.Advanced)] - public static Graphics FromHwnd(IntPtr hwnd) - { - IntPtr graphics; - - if (!Gdip.UseX11Drawable) - { - CarbonContext context = MacSupport.GetCGContextForView(hwnd); - Gdip.GdipCreateFromContext_macosx(context.ctx, context.width, context.height, out graphics); - - Graphics g = new Graphics(graphics); - g.maccontext = context; - - return g; - } - else - { - if (Gdip.Display == IntPtr.Zero) - { - Gdip.Display = LibX11Functions.XOpenDisplay(IntPtr.Zero); - if (Gdip.Display == IntPtr.Zero) - throw new NotSupportedException(SR.CouldNotOpenDisplay); - } - if (hwnd == IntPtr.Zero) - { - hwnd = LibX11Functions.XRootWindow(Gdip.Display, LibX11Functions.XDefaultScreen(Gdip.Display)); - } - - return FromXDrawable(hwnd, Gdip.Display); - } - } - - [EditorBrowsable(EditorBrowsableState.Advanced)] - public static Graphics FromHwndInternal(IntPtr hwnd) - { - return FromHwnd(hwnd); - } - - public static Graphics FromImage(Image image!!) - { - if ((image.PixelFormat & PixelFormat.Indexed) != 0) - throw new ArgumentException(SR.CannotCreateGraphics, nameof(image)); - - IntPtr graphics; - int status = Gdip.GdipGetImageGraphicsContext(image.nativeImage, out graphics); - Gdip.CheckStatus(status); - Graphics result = new Graphics(graphics, image); - - Rectangle rect = new Rectangle(0, 0, image.Width, image.Height); - Gdip.GdipSetVisibleClip_linux(result.NativeGraphics, ref rect); - - return result; - } - - internal static Graphics FromXDrawable(IntPtr drawable, IntPtr display) - { - IntPtr graphics; - - int s = Gdip.GdipCreateFromXDrawable_linux(drawable, display, out graphics); - Gdip.CheckStatus(s); - return new Graphics(graphics); - } - - public static IntPtr GetHalftonePalette() - { - throw new NotImplementedException(); - } - - public Color GetNearestColor(Color color) - { - int argb; - - int status = Gdip.GdipGetNearestColor(NativeGraphics, out argb); - Gdip.CheckStatus(status); - - return Color.FromArgb(argb); - } - - [EditorBrowsable(EditorBrowsableState.Never)] - public void ReleaseHdcInternal(IntPtr hdc) - { - int status = Gdip.InvalidParameter; - if (hdc == _nativeHdc) - { - status = Gdip.GdipReleaseDC(new HandleRef(this, NativeGraphics), new HandleRef(this, _nativeHdc)); - _nativeHdc = IntPtr.Zero; - } - Gdip.CheckStatus(status); - } - - public void Restore(GraphicsState gstate) - { - // the possible NRE thrown by gstate.nativeState match MS behaviour - int status = Gdip.GdipRestoreGraphics(NativeGraphics, (uint)gstate.nativeState); - Gdip.CheckStatus(status); - } - - public GraphicsState Save() - { - int status = Gdip.GdipSaveGraphics(new HandleRef(this, NativeGraphics), out int state); - Gdip.CheckStatus(status); - - return new GraphicsState((int)state); - } - - public RectangleF VisibleClipBounds - { - get - { - int status = Gdip.GdipGetVisibleClipBounds(new HandleRef(this, NativeGraphics), out RectangleF rect); - Gdip.CheckStatus(status); - - return rect; - } - } - - [EditorBrowsable(EditorBrowsableState.Never)] - [Obsolete(Obsoletions.GetContextInfoMessage, DiagnosticId = Obsoletions.GetContextInfoDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] - [SupportedOSPlatform("windows")] - public object GetContextInfo() - { - throw new NotImplementedException(); - } - -#if NETCOREAPP - [EditorBrowsable(EditorBrowsableState.Never)] - [SupportedOSPlatform("windows")] - public void GetContextInfo(out PointF offset) - { - throw new PlatformNotSupportedException(); - } - - [EditorBrowsable(EditorBrowsableState.Never)] - [SupportedOSPlatform("windows")] - public void GetContextInfo(out PointF offset, out Region? clip) - { - throw new PlatformNotSupportedException(); - } -#endif - - private static void CheckErrorStatus(int status) - { - Gdip.CheckStatus(status); - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Graphics.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Graphics.Windows.cs deleted file mode 100644 index 9660603292c2e..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Graphics.Windows.cs +++ /dev/null @@ -1,958 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Drawing.Drawing2D; -using System.Drawing.Imaging; -using System.Drawing.Internal; -using System.Globalization; -using System.Numerics; -using System.Runtime.ConstrainedExecution; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; -using Gdip = System.Drawing.SafeNativeMethods.Gdip; - -namespace System.Drawing -{ - /// - /// Encapsulates a GDI+ drawing surface. - /// - public sealed partial class Graphics : MarshalByRefObject, IDisposable, IDeviceContext - { -#if FINALIZATION_WATCH - static readonly TraceSwitch GraphicsFinalization = new TraceSwitch("GraphicsFinalization", "Tracks the creation and destruction of finalization"); - internal static string GetAllocationStack() { - if (GraphicsFinalization.TraceVerbose) { - return Environment.StackTrace; - } - else { - return "Enabled 'GraphicsFinalization' switch to see stack of allocation"; - } - } - private string allocationSite = Graphics.GetAllocationStack(); -#endif - - /// - /// The context state previous to the current Graphics context (the head of the stack). - /// We don't keep a GraphicsContext for the current context since it is available at any time from GDI+ and - /// we don't want to keep track of changes in it. - /// - private GraphicsContext? _previousContext; - - private static readonly object s_syncObject = new object(); - - // Object reference used for printing; it could point to a PrintPreviewGraphics to obtain the VisibleClipBounds, or - // a DeviceContext holding a printer DC. - private object? _printingHelper; - - // GDI+'s preferred HPALETTE. - private static IntPtr s_halftonePalette; - - // pointer back to the Image backing a specific graphic object - private Image? _backingImage; - - /// - /// Constructor to initialize this object from a native GDI+ Graphics pointer. - /// - private Graphics(IntPtr gdipNativeGraphics) - { - if (gdipNativeGraphics == IntPtr.Zero) - throw new ArgumentNullException(nameof(gdipNativeGraphics)); - - NativeGraphics = gdipNativeGraphics; - } - - /// - /// Creates a new instance of the class from the specified handle to a device context. - /// - [EditorBrowsable(EditorBrowsableState.Advanced)] - public static Graphics FromHdc(IntPtr hdc) - { - if (hdc == IntPtr.Zero) - throw new ArgumentNullException(nameof(hdc)); - - return FromHdcInternal(hdc); - } - - [EditorBrowsable(EditorBrowsableState.Advanced)] - public static Graphics FromHdcInternal(IntPtr hdc) - { - Gdip.CheckStatus(Gdip.GdipCreateFromHDC(hdc, out IntPtr nativeGraphics)); - return new Graphics(nativeGraphics); - } - - /// - /// Creates a new instance of the Graphics class from the specified handle to a device context and handle to a device. - /// - [EditorBrowsable(EditorBrowsableState.Advanced)] - public static Graphics FromHdc(IntPtr hdc, IntPtr hdevice) - { - Gdip.CheckStatus(Gdip.GdipCreateFromHDC2(hdc, hdevice, out IntPtr nativeGraphics)); - return new Graphics(nativeGraphics); - } - - /// - /// Creates a new instance of the class from a window handle. - /// - [EditorBrowsable(EditorBrowsableState.Advanced)] - public static Graphics FromHwnd(IntPtr hwnd) => FromHwndInternal(hwnd); - - [EditorBrowsable(EditorBrowsableState.Advanced)] - public static Graphics FromHwndInternal(IntPtr hwnd) - { - Gdip.CheckStatus(Gdip.GdipCreateFromHWND(hwnd, out IntPtr nativeGraphics)); - return new Graphics(nativeGraphics); - } - - /// - /// Creates an instance of the class from an existing . - /// - public static Graphics FromImage(Image image!!) - { - if ((image.PixelFormat & PixelFormat.Indexed) != 0) - throw new ArgumentException(SR.GdiplusCannotCreateGraphicsFromIndexedPixelFormat, nameof(image)); - - Gdip.CheckStatus(Gdip.GdipGetImageGraphicsContext( - new HandleRef(image, image.nativeImage), - out IntPtr nativeGraphics)); - - return new Graphics(nativeGraphics) { _backingImage = image }; - } - - [EditorBrowsable(EditorBrowsableState.Never)] - public void ReleaseHdcInternal(IntPtr hdc) - { - Gdip.CheckStatus(!Gdip.Initialized ? Gdip.Ok : - Gdip.GdipReleaseDC(new HandleRef(this, NativeGraphics), hdc)); - _nativeHdc = IntPtr.Zero; - } - - /// - /// Deletes this , and frees the memory allocated for it. - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - private void Dispose(bool disposing) - { -#if DEBUG && FINALIZATION_WATCH - if (!disposing && _nativeGraphics != IntPtr.Zero) - { - Debug.WriteLine("System.Drawing.Graphics: ***************************************************"); - Debug.WriteLine("System.Drawing.Graphics: Object Disposed through finalization:\n" + allocationSite); - } -#endif - while (_previousContext != null) - { - // Dispose entire stack. - GraphicsContext? context = _previousContext.Previous; - _previousContext.Dispose(); - _previousContext = context; - } - - if (NativeGraphics != IntPtr.Zero) - { - try - { - if (_nativeHdc != IntPtr.Zero) // avoid a handle leak. - { - ReleaseHdc(); - } - - if (PrintingHelper is DeviceContext printerDC) - { - printerDC.Dispose(); - _printingHelper = null; - } - -#if DEBUG - int status = !Gdip.Initialized ? Gdip.Ok : -#endif - Gdip.GdipDeleteGraphics(new HandleRef(this, NativeGraphics)); - -#if DEBUG - Debug.Assert(status == Gdip.Ok, $"GDI+ returned an error status: {status.ToString(CultureInfo.InvariantCulture)}"); -#endif - } - catch (Exception ex) when (!ClientUtils.IsSecurityOrCriticalException(ex)) - { - } - finally - { - NativeGraphics = IntPtr.Zero; - } - } - } - - ~Graphics() => Dispose(false); - - // Libgdiplus needs to synchronize a macOS context. Windows does not do anything. - partial void FlushCore(); - - /// - /// Represents an object used in connection with the printing API, it is used to hold a reference to a - /// PrintPreviewGraphics (fake graphics) or a printer DeviceContext (and maybe more in the future). - /// - internal object? PrintingHelper - { - get => _printingHelper; - set - { - Debug.Assert(_printingHelper == null, "WARNING: Overwritting the printing helper reference!"); - _printingHelper = value; - } - } - - /// - /// CopyPixels will perform a gdi "bitblt" operation to the source from the destination with the given size - /// and specified raster operation. - /// - public void CopyFromScreen(int sourceX, int sourceY, int destinationX, int destinationY, Size blockRegionSize, CopyPixelOperation copyPixelOperation) - { - switch (copyPixelOperation) - { - case CopyPixelOperation.Blackness: - case CopyPixelOperation.NotSourceErase: - case CopyPixelOperation.NotSourceCopy: - case CopyPixelOperation.SourceErase: - case CopyPixelOperation.DestinationInvert: - case CopyPixelOperation.PatInvert: - case CopyPixelOperation.SourceInvert: - case CopyPixelOperation.SourceAnd: - case CopyPixelOperation.MergePaint: - case CopyPixelOperation.MergeCopy: - case CopyPixelOperation.SourceCopy: - case CopyPixelOperation.SourcePaint: - case CopyPixelOperation.PatCopy: - case CopyPixelOperation.PatPaint: - case CopyPixelOperation.Whiteness: - case CopyPixelOperation.CaptureBlt: - case CopyPixelOperation.NoMirrorBitmap: - break; - default: - throw new InvalidEnumArgumentException(nameof(copyPixelOperation), (int)copyPixelOperation, typeof(CopyPixelOperation)); - } - - int destWidth = blockRegionSize.Width; - int destHeight = blockRegionSize.Height; - - IntPtr screenDC = Interop.User32.GetDC(IntPtr.Zero); - try - { - IntPtr targetDC = GetHdc(); - int result = Interop.Gdi32.BitBlt( - targetDC, - destinationX, - destinationY, - destWidth, - destHeight, - screenDC, - sourceX, - sourceY, - (Interop.Gdi32.RasterOp)copyPixelOperation); - - //a zero result indicates a win32 exception has been thrown - if (result == 0) - { - throw new Win32Exception(); - } - } - finally - { - Interop.User32.ReleaseDC(IntPtr.Zero, screenDC); - ReleaseHdc(); - } - } - - public Color GetNearestColor(Color color) - { - int nearest = color.ToArgb(); - Gdip.CheckStatus(Gdip.GdipGetNearestColor(new HandleRef(this, NativeGraphics), ref nearest)); - return Color.FromArgb(nearest); - } - - /// - /// Draws a line connecting the two specified points. - /// - public void DrawLine(Pen pen!!, float x1, float y1, float x2, float y2) - { - CheckErrorStatus(Gdip.GdipDrawLine(new HandleRef(this, NativeGraphics), new HandleRef(pen, pen.NativePen), x1, y1, x2, y2)); - } - - /// - /// Draws a series of cubic Bezier curves from an array of points. - /// - public unsafe void DrawBeziers(Pen pen!!, PointF[] points!!) - { - fixed (PointF* p = points) - { - CheckErrorStatus(Gdip.GdipDrawBeziers( - new HandleRef(this, NativeGraphics), - new HandleRef(pen, pen.NativePen), - p, points.Length)); - } - } - - /// - /// Draws a series of cubic Bezier curves from an array of points. - /// - public unsafe void DrawBeziers(Pen pen!!, Point[] points!!) - { - fixed (Point* p = points) - { - CheckErrorStatus(Gdip.GdipDrawBeziersI( - new HandleRef(this, NativeGraphics), - new HandleRef(pen, pen.NativePen), - p, - points.Length)); - } - } - - /// - /// Fills the interior of a path. - /// - public void FillPath(Brush brush!!, GraphicsPath path!!) - { - CheckErrorStatus(Gdip.GdipFillPath( - new HandleRef(this, NativeGraphics), - new HandleRef(brush, brush.NativeBrush), - new HandleRef(path, path._nativePath))); - } - - /// - /// Fills the interior of a . - /// - public void FillRegion(Brush brush!!, Region region!!) - { - CheckErrorStatus(Gdip.GdipFillRegion( - new HandleRef(this, NativeGraphics), - new HandleRef(brush, brush.NativeBrush), - new HandleRef(region, region.NativeRegion))); - } - - public void DrawIcon(Icon icon!!, int x, int y) - { - if (_backingImage != null) - { - // We don't call the icon directly because we want to stay in GDI+ all the time - // to avoid alpha channel interop issues between gdi and gdi+ - // so we do icon.ToBitmap() and then we call DrawImage. This is probably slower. - DrawImage(icon.ToBitmap(), x, y); - } - else - { - icon.Draw(this, x, y); - } - } - - /// - /// Draws this image to a graphics object. The drawing command originates on the graphics - /// object, but a graphics object generally has no idea how to render a given image. So, - /// it passes the call to the actual image. This version crops the image to the given - /// dimensions and allows the user to specify a rectangle within the image to draw. - /// - public void DrawIcon(Icon icon!!, Rectangle targetRect) - { - if (_backingImage != null) - { - // We don't call the icon directly because we want to stay in GDI+ all the time - // to avoid alpha channel interop issues between gdi and gdi+ - // so we do icon.ToBitmap() and then we call DrawImage. This is probably slower. - DrawImage(icon.ToBitmap(), targetRect); - } - else - { - icon.Draw(this, targetRect); - } - } - - /// - /// Draws this image to a graphics object. The drawing command originates on the graphics - /// object, but a graphics object generally has no idea how to render a given image. So, - /// it passes the call to the actual image. This version stretches the image to the given - /// dimensions and allows the user to specify a rectangle within the image to draw. - /// - public void DrawIconUnstretched(Icon icon!!, Rectangle targetRect) - { - if (_backingImage != null) - { - DrawImageUnscaled(icon.ToBitmap(), targetRect); - } - else - { - icon.DrawUnstretched(this, targetRect); - } - } - - public void EnumerateMetafile( - Metafile metafile, - PointF destPoint, - EnumerateMetafileProc callback, - IntPtr callbackData, - ImageAttributes? imageAttr) - { - Gdip.CheckStatus(Gdip.GdipEnumerateMetafileDestPoint( - new HandleRef(this, NativeGraphics), - new HandleRef(metafile, metafile?.nativeImage ?? IntPtr.Zero), - ref destPoint, - callback, - callbackData, - new HandleRef(imageAttr, imageAttr?.nativeImageAttributes ?? IntPtr.Zero))); - } - public void EnumerateMetafile( - Metafile metafile, - Point destPoint, - EnumerateMetafileProc callback, - IntPtr callbackData, - ImageAttributes? imageAttr) - { - Gdip.CheckStatus(Gdip.GdipEnumerateMetafileDestPointI( - new HandleRef(this, NativeGraphics), - new HandleRef(metafile, metafile?.nativeImage ?? IntPtr.Zero), - ref destPoint, - callback, - callbackData, - new HandleRef(imageAttr, imageAttr?.nativeImageAttributes ?? IntPtr.Zero))); - } - - public void EnumerateMetafile( - Metafile metafile, - RectangleF destRect, - EnumerateMetafileProc callback, - IntPtr callbackData, - ImageAttributes? imageAttr) - { - Gdip.CheckStatus(Gdip.GdipEnumerateMetafileDestRect( - new HandleRef(this, NativeGraphics), - new HandleRef(metafile, metafile?.nativeImage ?? IntPtr.Zero), - ref destRect, - callback, - callbackData, - new HandleRef(imageAttr, imageAttr?.nativeImageAttributes ?? IntPtr.Zero))); - } - - public void EnumerateMetafile( - Metafile metafile, - Rectangle destRect, - EnumerateMetafileProc callback, - IntPtr callbackData, - ImageAttributes? imageAttr) - { - Gdip.CheckStatus(Gdip.GdipEnumerateMetafileDestRectI( - new HandleRef(this, NativeGraphics), - new HandleRef(metafile, metafile?.nativeImage ?? IntPtr.Zero), - ref destRect, - callback, - callbackData, - new HandleRef(imageAttr, imageAttr?.nativeImageAttributes ?? IntPtr.Zero))); - } - - public unsafe void EnumerateMetafile( - Metafile metafile, - PointF[] destPoints!!, - EnumerateMetafileProc callback, - IntPtr callbackData, - ImageAttributes? imageAttr) - { - if (destPoints.Length != 3) - throw new ArgumentException(SR.GdiplusDestPointsInvalidParallelogram); - - fixed (PointF* p = destPoints) - { - Gdip.CheckStatus(Gdip.GdipEnumerateMetafileDestPoints( - new HandleRef(this, NativeGraphics), - new HandleRef(metafile, metafile?.nativeImage ?? IntPtr.Zero), - p, destPoints.Length, - callback, - callbackData, - new HandleRef(imageAttr, imageAttr?.nativeImageAttributes ?? IntPtr.Zero))); - } - } - - public unsafe void EnumerateMetafile( - Metafile metafile, - Point[] destPoints!!, - EnumerateMetafileProc callback, - IntPtr callbackData, - ImageAttributes? imageAttr) - { - if (destPoints.Length != 3) - throw new ArgumentException(SR.GdiplusDestPointsInvalidParallelogram); - - fixed (Point* p = destPoints) - { - Gdip.CheckStatus(Gdip.GdipEnumerateMetafileDestPointsI( - new HandleRef(this, NativeGraphics), - new HandleRef(metafile, metafile?.nativeImage ?? IntPtr.Zero), - p, destPoints.Length, - callback, - callbackData, - new HandleRef(imageAttr, imageAttr?.nativeImageAttributes ?? IntPtr.Zero))); - } - } - - public void EnumerateMetafile( - Metafile metafile, - PointF destPoint, - RectangleF srcRect, - GraphicsUnit unit, - EnumerateMetafileProc callback, - IntPtr callbackData, - ImageAttributes? imageAttr) - { - Gdip.CheckStatus(Gdip.GdipEnumerateMetafileSrcRectDestPoint( - new HandleRef(this, NativeGraphics), - new HandleRef(metafile, metafile?.nativeImage ?? IntPtr.Zero), - ref destPoint, - ref srcRect, - unit, - callback, - callbackData, - new HandleRef(imageAttr, imageAttr?.nativeImageAttributes ?? IntPtr.Zero))); - } - - public void EnumerateMetafile( - Metafile metafile, - Point destPoint, - Rectangle srcRect, - GraphicsUnit unit, - EnumerateMetafileProc callback, - IntPtr callbackData, - ImageAttributes? imageAttr) - { - Gdip.CheckStatus(Gdip.GdipEnumerateMetafileSrcRectDestPointI( - new HandleRef(this, NativeGraphics), - new HandleRef(metafile, metafile?.nativeImage ?? IntPtr.Zero), - ref destPoint, - ref srcRect, - unit, - callback, - callbackData, - new HandleRef(imageAttr, imageAttr?.nativeImageAttributes ?? IntPtr.Zero))); - } - - public void EnumerateMetafile( - Metafile metafile, - RectangleF destRect, - RectangleF srcRect, - GraphicsUnit unit, - EnumerateMetafileProc callback, - IntPtr callbackData, - ImageAttributes? imageAttr) - { - Gdip.CheckStatus(Gdip.GdipEnumerateMetafileSrcRectDestRect( - new HandleRef(this, NativeGraphics), - new HandleRef(metafile, metafile?.nativeImage ?? IntPtr.Zero), - ref destRect, - ref srcRect, - unit, - callback, - callbackData, - new HandleRef(imageAttr, imageAttr?.nativeImageAttributes ?? IntPtr.Zero))); - } - - public void EnumerateMetafile( - Metafile metafile, - Rectangle destRect, - Rectangle srcRect, - GraphicsUnit unit, - EnumerateMetafileProc callback, - IntPtr callbackData, - ImageAttributes? imageAttr) - { - Gdip.CheckStatus(Gdip.GdipEnumerateMetafileSrcRectDestRectI( - new HandleRef(this, NativeGraphics), - new HandleRef(metafile, metafile?.nativeImage ?? IntPtr.Zero), - ref destRect, - ref srcRect, - unit, - callback, - callbackData, - new HandleRef(imageAttr, imageAttr?.nativeImageAttributes ?? IntPtr.Zero))); - } - - public unsafe void EnumerateMetafile( - Metafile metafile, - PointF[] destPoints!!, - RectangleF srcRect, - GraphicsUnit unit, - EnumerateMetafileProc callback, - IntPtr callbackData, - ImageAttributes? imageAttr) - { - if (destPoints.Length != 3) - throw new ArgumentException(SR.GdiplusDestPointsInvalidParallelogram); - - fixed (PointF* p = destPoints) - { - Gdip.CheckStatus(Gdip.GdipEnumerateMetafileSrcRectDestPoints( - new HandleRef(this, NativeGraphics), - new HandleRef(metafile, metafile?.nativeImage ?? IntPtr.Zero), - p, destPoints.Length, - ref srcRect, - unit, - callback, - callbackData, - new HandleRef(imageAttr, imageAttr?.nativeImageAttributes ?? IntPtr.Zero))); - } - } - - public unsafe void EnumerateMetafile( - Metafile metafile, - Point[] destPoints!!, - Rectangle srcRect, - GraphicsUnit unit, - EnumerateMetafileProc callback, - IntPtr callbackData, - ImageAttributes? imageAttr) - { - if (destPoints.Length != 3) - throw new ArgumentException(SR.GdiplusDestPointsInvalidParallelogram); - - fixed (Point* p = destPoints) - { - Gdip.CheckStatus(Gdip.GdipEnumerateMetafileSrcRectDestPointsI( - new HandleRef(this, NativeGraphics), - new HandleRef(metafile, metafile?.nativeImage ?? IntPtr.Zero), - p, destPoints.Length, - ref srcRect, - unit, - callback, - callbackData, - new HandleRef(imageAttr, imageAttr?.nativeImageAttributes ?? IntPtr.Zero))); - } - } - - /// - /// Combines current Graphics context with all previous contexts. - /// When BeginContainer() is called, a copy of the current context is pushed into the GDI+ context stack, it keeps track of the - /// absolute clipping and transform but reset the public properties so it looks like a brand new context. - /// When Save() is called, a copy of the current context is also pushed in the GDI+ stack but the public clipping and transform - /// properties are not reset (cumulative). Consecutive Save context are ignored with the exception of the top one which contains - /// all previous information. - /// The return value is an object array where the first element contains the cumulative clip region and the second the cumulative - /// translate transform matrix. - /// WARNING: This method is for internal FX support only. - /// - [EditorBrowsable(EditorBrowsableState.Never)] -#if NETCOREAPP - [Obsolete(Obsoletions.GetContextInfoMessage, DiagnosticId = Obsoletions.GetContextInfoDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] -#endif - [SupportedOSPlatform("windows")] - public object GetContextInfo() - { - GetContextInfo(out Matrix3x2 cumulativeTransform, calculateClip: true, out Region? cumulativeClip); - return new object[] { cumulativeClip ?? new Region(), new Matrix(cumulativeTransform) }; - } - - private void GetContextInfo(out Matrix3x2 cumulativeTransform, bool calculateClip, out Region? cumulativeClip) - { - cumulativeClip = calculateClip ? GetRegionIfNotInfinite() : null; // Current context clip. - cumulativeTransform = TransformElements; // Current context transform. - Vector2 currentOffset = default; // Offset of current context. - Vector2 totalOffset = default; // Absolute coordinate offset of top context. - - GraphicsContext? context = _previousContext; - - if (!cumulativeTransform.IsIdentity) - { - currentOffset = cumulativeTransform.Translation; - } - - while (context is not null) - { - if (!context.TransformOffset.IsEmpty()) - { - cumulativeTransform.Translate(context.TransformOffset); - } - - if (!currentOffset.IsEmpty()) - { - // The location of the GDI+ clip region is relative to the coordinate origin after any translate transform - // has been applied. We need to intersect regions using the same coordinate origin relative to the previous - // context. - - // If we don't have a cumulative clip, we're infinite, and translation on infinite regions is a no-op. - cumulativeClip?.Translate(currentOffset.X, currentOffset.Y); - totalOffset.X += currentOffset.X; - totalOffset.Y += currentOffset.Y; - } - - // Context only stores clips if they are not infinite. Intersecting a clip with an infinite clip is a no-op. - if (calculateClip && context.Clip is not null) - { - // Intersecting an infinite clip with another is just a copy of the second clip. - if (cumulativeClip is null) - { - cumulativeClip = context.Clip; - } - else - { - cumulativeClip.Intersect(context.Clip); - } - } - - currentOffset = context.TransformOffset; - - // Ignore subsequent cumulative contexts. - do - { - context = context.Previous; - - if (context == null || !context.Next!.IsCumulative) - { - break; - } - } while (context.IsCumulative); - } - - if (!totalOffset.IsEmpty()) - { - // We need now to reset the total transform in the region so when calling Region.GetHRgn(Graphics) - // the HRegion is properly offset by GDI+ based on the total offset of the graphics object. - - // If we don't have a cumulative clip, we're infinite, and translation on infinite regions is a no-op. - cumulativeClip?.Translate(-totalOffset.X, -totalOffset.Y); - } - } - -#if NETCOREAPP - /// - /// Gets the cumulative offset. - /// - /// The cumulative offset. - [EditorBrowsable(EditorBrowsableState.Never)] - [SupportedOSPlatform("windows")] - public void GetContextInfo(out PointF offset) - { - GetContextInfo(out Matrix3x2 cumulativeTransform, calculateClip: false, out _); - Vector2 translation = cumulativeTransform.Translation; - offset = new PointF(translation.X, translation.Y); - } - - /// - /// Gets the cumulative offset and clip region. - /// - /// The cumulative offset. - /// The cumulative clip region or null if the clip region is infinite. - [EditorBrowsable(EditorBrowsableState.Never)] - [SupportedOSPlatform("windows")] - public void GetContextInfo(out PointF offset, out Region? clip) - { - GetContextInfo(out Matrix3x2 cumulativeTransform, calculateClip: true, out clip); - Vector2 translation = cumulativeTransform.Translation; - offset = new PointF(translation.X, translation.Y); - } -#endif - - public RectangleF VisibleClipBounds - { - get - { - if (PrintingHelper is PrintPreviewGraphics ppGraphics) - return ppGraphics.VisibleClipBounds; - - Gdip.CheckStatus(Gdip.GdipGetVisibleClipBounds(new HandleRef(this, NativeGraphics), out RectangleF rect)); - - return rect; - } - } - - /// - /// Saves the current context into the context stack. - /// - private void PushContext(GraphicsContext context) - { - Debug.Assert(context != null && context.State != 0, "GraphicsContext object is null or not valid."); - - if (_previousContext != null) - { - // Push context. - context.Previous = _previousContext; - _previousContext.Next = context; - } - _previousContext = context; - } - - /// - /// Pops all contexts from the specified one included. The specified context is becoming the current context. - /// - private void PopContext(int currentContextState) - { - Debug.Assert(_previousContext != null, "Trying to restore a context when the stack is empty"); - GraphicsContext? context = _previousContext; - - // Pop all contexts up the stack. - while (context != null) - { - if (context.State == currentContextState) - { - _previousContext = context.Previous; - - // This will dipose all context object up the stack. - context.Dispose(); - return; - } - context = context.Previous; - } - Debug.Fail("Warning: context state not found!"); - } - - public GraphicsState Save() - { - GraphicsContext context = new GraphicsContext(this); - int status = Gdip.GdipSaveGraphics(new HandleRef(this, NativeGraphics), out int state); - - if (status != Gdip.Ok) - { - context.Dispose(); - throw Gdip.StatusException(status); - } - - context.State = state; - context.IsCumulative = true; - PushContext(context); - - return new GraphicsState(state); - } - - public void Restore(GraphicsState gstate) - { - Gdip.CheckStatus(Gdip.GdipRestoreGraphics(new HandleRef(this, NativeGraphics), gstate.nativeState)); - PopContext(gstate.nativeState); - } - - public GraphicsContainer BeginContainer(RectangleF dstrect, RectangleF srcrect, GraphicsUnit unit) - { - GraphicsContext context = new GraphicsContext(this); - - int status = Gdip.GdipBeginContainer( - new HandleRef(this, NativeGraphics), ref dstrect, ref srcrect, unit, out int state); - - if (status != Gdip.Ok) - { - context.Dispose(); - throw Gdip.StatusException(status); - } - - context.State = state; - PushContext(context); - - return new GraphicsContainer(state); - } - - public GraphicsContainer BeginContainer() - { - GraphicsContext context = new GraphicsContext(this); - int status = Gdip.GdipBeginContainer2(new HandleRef(this, NativeGraphics), out int state); - - if (status != Gdip.Ok) - { - context.Dispose(); - throw Gdip.StatusException(status); - } - - context.State = state; - PushContext(context); - - return new GraphicsContainer(state); - } - - public void EndContainer(GraphicsContainer container!!) - { - Gdip.CheckStatus(Gdip.GdipEndContainer(new HandleRef(this, NativeGraphics), container.nativeGraphicsContainer)); - PopContext(container.nativeGraphicsContainer); - } - - public GraphicsContainer BeginContainer(Rectangle dstrect, Rectangle srcrect, GraphicsUnit unit) - { - GraphicsContext context = new GraphicsContext(this); - - int status = Gdip.GdipBeginContainerI( - new HandleRef(this, NativeGraphics), ref dstrect, ref srcrect, unit, out int state); - - if (status != Gdip.Ok) - { - context.Dispose(); - throw Gdip.StatusException(status); - } - - context.State = state; - PushContext(context); - - return new GraphicsContainer(state); - } - - public void AddMetafileComment(byte[] data!!) - { - Gdip.CheckStatus(Gdip.GdipComment(new HandleRef(this, NativeGraphics), data.Length, data)); - } - - public static IntPtr GetHalftonePalette() - { - if (s_halftonePalette == IntPtr.Zero) - { - lock (s_syncObject) - { - if (s_halftonePalette == IntPtr.Zero) - { - AppDomain.CurrentDomain.DomainUnload += OnDomainUnload; - AppDomain.CurrentDomain.ProcessExit += OnDomainUnload; - - s_halftonePalette = Gdip.GdipCreateHalftonePalette(); - } - } - } - return s_halftonePalette; - } - - // This is called from AppDomain.ProcessExit and AppDomain.DomainUnload. - private static void OnDomainUnload(object? sender, EventArgs e) - { - if (s_halftonePalette != IntPtr.Zero) - { - Interop.Gdi32.DeleteObject(s_halftonePalette); - s_halftonePalette = IntPtr.Zero; - } - } - - /// - /// GDI+ will return a 'generic error' with specific win32 last error codes when - /// a terminal server session has been closed, minimized, etc... We don't want - /// to throw when this happens, so we'll guard against this by looking at the - /// 'last win32 error code' and checking to see if it is either 1) access denied - /// or 2) proc not found and then ignore it. - /// - /// The problem is that when you lock the machine, the secure desktop is enabled and - /// rendering fails which is expected (since the app doesn't have permission to draw - /// on the secure desktop). Not sure if there's anything you can do, short of catching - /// the desktop switch message and absorbing all the exceptions that get thrown while - /// it's the secure desktop. - /// - private static void CheckErrorStatus(int status) - { - if (status == Gdip.Ok) - return; - - // Generic error from GDI+ can be GenericError or Win32Error. - if (status == Gdip.GenericError || status == Gdip.Win32Error) - { - int error = Marshal.GetLastWin32Error(); - if (error == SafeNativeMethods.ERROR_ACCESS_DENIED || error == SafeNativeMethods.ERROR_PROC_NOT_FOUND || - // Here, we'll check to see if we are in a terminal services session... - (((Interop.User32.GetSystemMetrics(NativeMethods.SM_REMOTESESSION) & 0x00000001) != 0) && (error == 0))) - { - return; - } - } - - // Legitimate error, throw our status exception. - throw Gdip.StatusException(status); - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Graphics.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Graphics.cs index 9bcc9e52f8a80..906672485951b 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Graphics.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Graphics.cs @@ -2,11 +2,15 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.ComponentModel; +using System.Diagnostics; using System.Drawing.Drawing2D; using System.Drawing.Imaging; +using System.Drawing.Internal; using System.Drawing.Text; +using System.Globalization; using System.Numerics; using System.Runtime.InteropServices; +using System.Runtime.Versioning; using Gdip = System.Drawing.SafeNativeMethods.Gdip; namespace System.Drawing @@ -14,8 +18,40 @@ namespace System.Drawing /// /// Encapsulates a GDI+ drawing surface. /// - public sealed partial class Graphics : MarshalByRefObject, IDisposable, IDeviceContext + public sealed class Graphics : MarshalByRefObject, IDisposable, IDeviceContext { +#if FINALIZATION_WATCH + static readonly TraceSwitch GraphicsFinalization = new TraceSwitch("GraphicsFinalization", "Tracks the creation and destruction of finalization"); + internal static string GetAllocationStack() { + if (GraphicsFinalization.TraceVerbose) { + return Environment.StackTrace; + } + else { + return "Enabled 'GraphicsFinalization' switch to see stack of allocation"; + } + } + private string allocationSite = Graphics.GetAllocationStack(); +#endif + + /// + /// The context state previous to the current Graphics context (the head of the stack). + /// We don't keep a GraphicsContext for the current context since it is available at any time from GDI+ and + /// we don't want to keep track of changes in it. + /// + private GraphicsContext? _previousContext; + + private static readonly object s_syncObject = new object(); + + // Object reference used for printing; it could point to a PrintPreviewGraphics to obtain the VisibleClipBounds, or + // a DeviceContext holding a printer DC. + private object? _printingHelper; + + // GDI+'s preferred HPALETTE. + private static IntPtr s_halftonePalette; + + // pointer back to the Image backing a specific graphic object + private Image? _backingImage; + /// /// Handle to native DC - obtained from the GDI+ graphics object. We need to cache it to implement /// IDeviceContext interface. @@ -41,6 +77,146 @@ public delegate bool EnumerateMetafileProc( IntPtr data, PlayRecordCallback callbackData); + /// + /// Constructor to initialize this object from a native GDI+ Graphics pointer. + /// + private Graphics(IntPtr gdipNativeGraphics) + { + if (gdipNativeGraphics == IntPtr.Zero) + throw new ArgumentNullException(nameof(gdipNativeGraphics)); + + NativeGraphics = gdipNativeGraphics; + } + + /// + /// Creates a new instance of the class from the specified handle to a device context. + /// + [EditorBrowsable(EditorBrowsableState.Advanced)] + public static Graphics FromHdc(IntPtr hdc) + { + if (hdc == IntPtr.Zero) + throw new ArgumentNullException(nameof(hdc)); + + return FromHdcInternal(hdc); + } + + [EditorBrowsable(EditorBrowsableState.Advanced)] + public static Graphics FromHdcInternal(IntPtr hdc) + { + Gdip.CheckStatus(Gdip.GdipCreateFromHDC(hdc, out IntPtr nativeGraphics)); + return new Graphics(nativeGraphics); + } + + /// + /// Creates a new instance of the Graphics class from the specified handle to a device context and handle to a device. + /// + [EditorBrowsable(EditorBrowsableState.Advanced)] + public static Graphics FromHdc(IntPtr hdc, IntPtr hdevice) + { + Gdip.CheckStatus(Gdip.GdipCreateFromHDC2(hdc, hdevice, out IntPtr nativeGraphics)); + return new Graphics(nativeGraphics); + } + + /// + /// Creates a new instance of the class from a window handle. + /// + [EditorBrowsable(EditorBrowsableState.Advanced)] + public static Graphics FromHwnd(IntPtr hwnd) => FromHwndInternal(hwnd); + + [EditorBrowsable(EditorBrowsableState.Advanced)] + public static Graphics FromHwndInternal(IntPtr hwnd) + { + Gdip.CheckStatus(Gdip.GdipCreateFromHWND(hwnd, out IntPtr nativeGraphics)); + return new Graphics(nativeGraphics); + } + + /// + /// Creates an instance of the class from an existing . + /// + public static Graphics FromImage(Image image) + { + ArgumentNullException.ThrowIfNull(image); + + if ((image.PixelFormat & PixelFormat.Indexed) != 0) + throw new ArgumentException(SR.GdiplusCannotCreateGraphicsFromIndexedPixelFormat, nameof(image)); + + Gdip.CheckStatus(Gdip.GdipGetImageGraphicsContext( + new HandleRef(image, image.nativeImage), + out IntPtr nativeGraphics)); + + return new Graphics(nativeGraphics) { _backingImage = image }; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public void ReleaseHdcInternal(IntPtr hdc) + { + Gdip.CheckStatus(!Gdip.Initialized ? Gdip.Ok : + Gdip.GdipReleaseDC(new HandleRef(this, NativeGraphics), hdc)); + _nativeHdc = IntPtr.Zero; + } + + /// + /// Deletes this , and frees the memory allocated for it. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { +#if DEBUG && FINALIZATION_WATCH + if (!disposing && _nativeGraphics != IntPtr.Zero) + { + Debug.WriteLine("System.Drawing.Graphics: ***************************************************"); + Debug.WriteLine("System.Drawing.Graphics: Object Disposed through finalization:\n" + allocationSite); + } +#endif + while (_previousContext != null) + { + // Dispose entire stack. + GraphicsContext? context = _previousContext.Previous; + _previousContext.Dispose(); + _previousContext = context; + } + + if (NativeGraphics != IntPtr.Zero) + { + try + { + if (_nativeHdc != IntPtr.Zero) // avoid a handle leak. + { + ReleaseHdc(); + } + + if (PrintingHelper is DeviceContext printerDC) + { + printerDC.Dispose(); + _printingHelper = null; + } + +#if DEBUG + int status = !Gdip.Initialized ? Gdip.Ok : +#endif + Gdip.GdipDeleteGraphics(new HandleRef(this, NativeGraphics)); + +#if DEBUG + Debug.Assert(status == Gdip.Ok, $"GDI+ returned an error status: {status.ToString(CultureInfo.InvariantCulture)}"); +#endif + } + catch (Exception ex) when (!ClientUtils.IsSecurityOrCriticalException(ex)) + { + } + finally + { + NativeGraphics = IntPtr.Zero; + } + } + } + + ~Graphics() => Dispose(false); + /// /// Handle to native GDI+ graphics object. This object is created on demand. /// @@ -405,13 +581,14 @@ public IntPtr GetHdc() public void Flush(FlushIntention intention) { Gdip.CheckStatus(Gdip.GdipFlush(new HandleRef(this, NativeGraphics), intention)); - FlushCore(); } public void SetClip(Graphics g) => SetClip(g, CombineMode.Replace); - public void SetClip(Graphics g!!, CombineMode combineMode) + public void SetClip(Graphics g, CombineMode combineMode) { + ArgumentNullException.ThrowIfNull(g); + Gdip.CheckStatus(Gdip.GdipSetClipGraphics( new HandleRef(this, NativeGraphics), new HandleRef(g, g.NativeGraphics), @@ -440,16 +617,20 @@ public void SetClip(RectangleF rect, CombineMode combineMode) public void SetClip(GraphicsPath path) => SetClip(path, CombineMode.Replace); - public void SetClip(GraphicsPath path!!, CombineMode combineMode) + public void SetClip(GraphicsPath path, CombineMode combineMode) { + ArgumentNullException.ThrowIfNull(path); + Gdip.CheckStatus(Gdip.GdipSetClipPath( new HandleRef(this, NativeGraphics), new HandleRef(path, path._nativePath), combineMode)); } - public void SetClip(Region region!!, CombineMode combineMode) + public void SetClip(Region region, CombineMode combineMode) { + ArgumentNullException.ThrowIfNull(region); + Gdip.CheckStatus(Gdip.GdipSetClipRegion( new HandleRef(this, NativeGraphics), new HandleRef(region, region.NativeRegion), @@ -472,8 +653,10 @@ public void IntersectClip(RectangleF rect) CombineMode.Intersect)); } - public void IntersectClip(Region region!!) + public void IntersectClip(Region region) { + ArgumentNullException.ThrowIfNull(region); + Gdip.CheckStatus(Gdip.GdipSetClipRegion( new HandleRef(this, NativeGraphics), new HandleRef(region, region.NativeRegion), @@ -488,8 +671,10 @@ public void ExcludeClip(Rectangle rect) CombineMode.Exclude)); } - public void ExcludeClip(Region region!!) + public void ExcludeClip(Region region) { + ArgumentNullException.ThrowIfNull(region); + Gdip.CheckStatus(Gdip.GdipSetClipRegion( new HandleRef(this, NativeGraphics), new HandleRef(region, region.NativeRegion), @@ -581,8 +766,10 @@ public void ResetTransform() /// /// Multiplies the that represents the world transform and . /// - public void MultiplyTransform(Matrix matrix!!, MatrixOrder order) + public void MultiplyTransform(Matrix matrix, MatrixOrder order) { + ArgumentNullException.ThrowIfNull(matrix); + // Multiplying the transform by a disposed matrix is a nop in GDI+, but throws // with the libgdiplus backend. Simulate a nop for compatability with GDI+. if (matrix.NativeMatrix == IntPtr.Zero) @@ -616,8 +803,10 @@ public void RotateTransform(float angle, MatrixOrder order) /// /// Draws an arc from the specified ellipse. /// - public void DrawArc(Pen pen!!, float x, float y, float width, float height, float startAngle, float sweepAngle) + public void DrawArc(Pen pen, float x, float y, float width, float height, float startAngle, float sweepAngle) { + ArgumentNullException.ThrowIfNull(pen); + CheckErrorStatus(Gdip.GdipDrawArc( new HandleRef(this, NativeGraphics), new HandleRef(pen, pen.NativePen), @@ -637,8 +826,10 @@ public void DrawArc(Pen pen, RectangleF rect, float startAngle, float sweepAngle /// /// Draws an arc from the specified ellipse. /// - public void DrawArc(Pen pen!!, int x, int y, int width, int height, int startAngle, int sweepAngle) + public void DrawArc(Pen pen, int x, int y, int width, int height, int startAngle, int sweepAngle) { + ArgumentNullException.ThrowIfNull(pen); + CheckErrorStatus(Gdip.GdipDrawArcI( new HandleRef(this, NativeGraphics), new HandleRef(pen, pen.NativePen), @@ -658,8 +849,10 @@ public void DrawArc(Pen pen, Rectangle rect, float startAngle, float sweepAngle) /// /// Draws a cubic bezier curve defined by four ordered pairs that represent points. /// - public void DrawBezier(Pen pen!!, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) + public void DrawBezier(Pen pen, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) { + ArgumentNullException.ThrowIfNull(pen); + CheckErrorStatus(Gdip.GdipDrawBezier( new HandleRef(this, NativeGraphics), new HandleRef(pen, pen.NativePen), x1, y1, x2, y2, x3, y3, x4, y4)); @@ -702,8 +895,10 @@ public void DrawRectangle(Pen pen, Rectangle rect) /// /// Draws the outline of the specified rectangle. /// - public void DrawRectangle(Pen pen!!, float x, float y, float width, float height) + public void DrawRectangle(Pen pen, float x, float y, float width, float height) { + ArgumentNullException.ThrowIfNull(pen); + CheckErrorStatus(Gdip.GdipDrawRectangle( new HandleRef(this, NativeGraphics), new HandleRef(pen, pen.NativePen), x, y, width, height)); @@ -712,8 +907,10 @@ public void DrawRectangle(Pen pen!!, float x, float y, float width, float height /// /// Draws the outline of the specified rectangle. /// - public void DrawRectangle(Pen pen!!, int x, int y, int width, int height) + public void DrawRectangle(Pen pen, int x, int y, int width, int height) { + ArgumentNullException.ThrowIfNull(pen); + CheckErrorStatus(Gdip.GdipDrawRectangleI( new HandleRef(this, NativeGraphics), new HandleRef(pen, pen.NativePen), x, y, width, height)); @@ -722,8 +919,11 @@ public void DrawRectangle(Pen pen!!, int x, int y, int width, int height) /// /// Draws the outlines of a series of rectangles. /// - public unsafe void DrawRectangles(Pen pen!!, RectangleF[] rects!!) + public unsafe void DrawRectangles(Pen pen, RectangleF[] rects) { + ArgumentNullException.ThrowIfNull(pen); + ArgumentNullException.ThrowIfNull(rects); + fixed (RectangleF* r = rects) { CheckErrorStatus(Gdip.GdipDrawRectangles( @@ -735,8 +935,11 @@ public unsafe void DrawRectangles(Pen pen!!, RectangleF[] rects!!) /// /// Draws the outlines of a series of rectangles. /// - public unsafe void DrawRectangles(Pen pen!!, Rectangle[] rects!!) + public unsafe void DrawRectangles(Pen pen, Rectangle[] rects) { + ArgumentNullException.ThrowIfNull(pen); + ArgumentNullException.ThrowIfNull(rects); + fixed (Rectangle* r = rects) { CheckErrorStatus(Gdip.GdipDrawRectanglesI( @@ -756,8 +959,10 @@ public void DrawEllipse(Pen pen, RectangleF rect) /// /// Draws the outline of an ellipse defined by a bounding rectangle. /// - public void DrawEllipse(Pen pen!!, float x, float y, float width, float height) + public void DrawEllipse(Pen pen, float x, float y, float width, float height) { + ArgumentNullException.ThrowIfNull(pen); + CheckErrorStatus(Gdip.GdipDrawEllipse( new HandleRef(this, NativeGraphics), new HandleRef(pen, pen.NativePen), @@ -775,8 +980,10 @@ public void DrawEllipse(Pen pen, Rectangle rect) /// /// Draws the outline of an ellipse defined by a bounding rectangle. /// - public void DrawEllipse(Pen pen!!, int x, int y, int width, int height) + public void DrawEllipse(Pen pen, int x, int y, int width, int height) { + ArgumentNullException.ThrowIfNull(pen); + CheckErrorStatus(Gdip.GdipDrawEllipseI( new HandleRef(this, NativeGraphics), new HandleRef(pen, pen.NativePen), @@ -794,8 +1001,10 @@ public void DrawPie(Pen pen, RectangleF rect, float startAngle, float sweepAngle /// /// Draws the outline of a pie section defined by an ellipse and two radial lines. /// - public void DrawPie(Pen pen!!, float x, float y, float width, float height, float startAngle, float sweepAngle) + public void DrawPie(Pen pen, float x, float y, float width, float height, float startAngle, float sweepAngle) { + ArgumentNullException.ThrowIfNull(pen); + CheckErrorStatus(Gdip.GdipDrawPie( new HandleRef(this, NativeGraphics), new HandleRef(pen, pen.NativePen), @@ -815,8 +1024,10 @@ public void DrawPie(Pen pen, Rectangle rect, float startAngle, float sweepAngle) /// /// Draws the outline of a pie section defined by an ellipse and two radial lines. /// - public void DrawPie(Pen pen!!, int x, int y, int width, int height, int startAngle, int sweepAngle) + public void DrawPie(Pen pen, int x, int y, int width, int height, int startAngle, int sweepAngle) { + ArgumentNullException.ThrowIfNull(pen); + CheckErrorStatus(Gdip.GdipDrawPieI( new HandleRef(this, NativeGraphics), new HandleRef(pen, pen.NativePen), @@ -828,8 +1039,11 @@ public void DrawPie(Pen pen!!, int x, int y, int width, int height, int startAng /// /// Draws the outline of a polygon defined by an array of points. /// - public unsafe void DrawPolygon(Pen pen!!, PointF[] points!!) + public unsafe void DrawPolygon(Pen pen, PointF[] points) { + ArgumentNullException.ThrowIfNull(pen); + ArgumentNullException.ThrowIfNull(points); + fixed (PointF* p = points) { CheckErrorStatus(Gdip.GdipDrawPolygon( @@ -841,8 +1055,11 @@ public unsafe void DrawPolygon(Pen pen!!, PointF[] points!!) /// /// Draws the outline of a polygon defined by an array of points. /// - public unsafe void DrawPolygon(Pen pen!!, Point[] points!!) + public unsafe void DrawPolygon(Pen pen, Point[] points) { + ArgumentNullException.ThrowIfNull(pen); + ArgumentNullException.ThrowIfNull(points); + fixed (Point* p = points) { CheckErrorStatus(Gdip.GdipDrawPolygonI( @@ -854,8 +1071,11 @@ public unsafe void DrawPolygon(Pen pen!!, Point[] points!!) /// /// Draws the lines and curves defined by a . /// - public void DrawPath(Pen pen!!, GraphicsPath path!!) + public void DrawPath(Pen pen, GraphicsPath path) { + ArgumentNullException.ThrowIfNull(pen); + ArgumentNullException.ThrowIfNull(path); + CheckErrorStatus(Gdip.GdipDrawPath( new HandleRef(this, NativeGraphics), new HandleRef(pen, pen.NativePen), @@ -865,8 +1085,11 @@ public void DrawPath(Pen pen!!, GraphicsPath path!!) /// /// Draws a curve defined by an array of points. /// - public unsafe void DrawCurve(Pen pen!!, PointF[] points!!) + public unsafe void DrawCurve(Pen pen, PointF[] points) { + ArgumentNullException.ThrowIfNull(pen); + ArgumentNullException.ThrowIfNull(points); + fixed (PointF* p = points) { CheckErrorStatus(Gdip.GdipDrawCurve( @@ -879,8 +1102,11 @@ public unsafe void DrawCurve(Pen pen!!, PointF[] points!!) /// /// Draws a curve defined by an array of points. /// - public unsafe void DrawCurve(Pen pen!!, PointF[] points!!, float tension) + public unsafe void DrawCurve(Pen pen, PointF[] points, float tension) { + ArgumentNullException.ThrowIfNull(pen); + ArgumentNullException.ThrowIfNull(points); + fixed (PointF* p = points) { CheckErrorStatus(Gdip.GdipDrawCurve2( @@ -899,8 +1125,11 @@ public void DrawCurve(Pen pen, PointF[] points, int offset, int numberOfSegments /// /// Draws a curve defined by an array of points. /// - public unsafe void DrawCurve(Pen pen!!, PointF[] points!!, int offset, int numberOfSegments, float tension) + public unsafe void DrawCurve(Pen pen, PointF[] points, int offset, int numberOfSegments, float tension) { + ArgumentNullException.ThrowIfNull(pen); + ArgumentNullException.ThrowIfNull(points); + fixed (PointF* p = points) { CheckErrorStatus(Gdip.GdipDrawCurve3( @@ -916,8 +1145,11 @@ public unsafe void DrawCurve(Pen pen!!, PointF[] points!!, int offset, int numbe /// /// Draws a curve defined by an array of points. /// - public unsafe void DrawCurve(Pen pen!!, Point[] points!!) + public unsafe void DrawCurve(Pen pen, Point[] points) { + ArgumentNullException.ThrowIfNull(pen); + ArgumentNullException.ThrowIfNull(points); + fixed (Point* p = points) { CheckErrorStatus(Gdip.GdipDrawCurveI( @@ -930,8 +1162,11 @@ public unsafe void DrawCurve(Pen pen!!, Point[] points!!) /// /// Draws a curve defined by an array of points. /// - public unsafe void DrawCurve(Pen pen!!, Point[] points!!, float tension) + public unsafe void DrawCurve(Pen pen, Point[] points, float tension) { + ArgumentNullException.ThrowIfNull(pen); + ArgumentNullException.ThrowIfNull(points); + fixed (Point* p = points) { CheckErrorStatus(Gdip.GdipDrawCurve2I( @@ -945,8 +1180,11 @@ public unsafe void DrawCurve(Pen pen!!, Point[] points!!, float tension) /// /// Draws a curve defined by an array of points. /// - public unsafe void DrawCurve(Pen pen!!, Point[] points!!, int offset, int numberOfSegments, float tension) + public unsafe void DrawCurve(Pen pen, Point[] points, int offset, int numberOfSegments, float tension) { + ArgumentNullException.ThrowIfNull(pen); + ArgumentNullException.ThrowIfNull(points); + fixed (Point* p = points) { CheckErrorStatus(Gdip.GdipDrawCurve3I( @@ -962,8 +1200,11 @@ public unsafe void DrawCurve(Pen pen!!, Point[] points!!, int offset, int number /// /// Draws a closed curve defined by an array of points. /// - public unsafe void DrawClosedCurve(Pen pen!!, PointF[] points!!) + public unsafe void DrawClosedCurve(Pen pen, PointF[] points) { + ArgumentNullException.ThrowIfNull(pen); + ArgumentNullException.ThrowIfNull(points); + fixed (PointF* p = points) { CheckErrorStatus(Gdip.GdipDrawClosedCurve( @@ -976,8 +1217,11 @@ public unsafe void DrawClosedCurve(Pen pen!!, PointF[] points!!) /// /// Draws a closed curve defined by an array of points. /// - public unsafe void DrawClosedCurve(Pen pen!!, PointF[] points!!, float tension, FillMode fillmode) + public unsafe void DrawClosedCurve(Pen pen, PointF[] points, float tension, FillMode fillmode) { + ArgumentNullException.ThrowIfNull(pen); + ArgumentNullException.ThrowIfNull(points); + fixed (PointF* p = points) { CheckErrorStatus(Gdip.GdipDrawClosedCurve2( @@ -991,8 +1235,11 @@ public unsafe void DrawClosedCurve(Pen pen!!, PointF[] points!!, float tension, /// /// Draws a closed curve defined by an array of points. /// - public unsafe void DrawClosedCurve(Pen pen!!, Point[] points!!) + public unsafe void DrawClosedCurve(Pen pen, Point[] points) { + ArgumentNullException.ThrowIfNull(pen); + ArgumentNullException.ThrowIfNull(points); + fixed (Point* p = points) { CheckErrorStatus(Gdip.GdipDrawClosedCurveI( @@ -1005,8 +1252,11 @@ public unsafe void DrawClosedCurve(Pen pen!!, Point[] points!!) /// /// Draws a closed curve defined by an array of points. /// - public unsafe void DrawClosedCurve(Pen pen!!, Point[] points!!, float tension, FillMode fillmode) + public unsafe void DrawClosedCurve(Pen pen, Point[] points, float tension, FillMode fillmode) { + ArgumentNullException.ThrowIfNull(pen); + ArgumentNullException.ThrowIfNull(points); + fixed (Point* p = points) { CheckErrorStatus(Gdip.GdipDrawClosedCurve2I( @@ -1036,8 +1286,10 @@ public void FillRectangle(Brush brush, RectangleF rect) /// /// Fills the interior of a rectangle with a . /// - public void FillRectangle(Brush brush!!, float x, float y, float width, float height) + public void FillRectangle(Brush brush, float x, float y, float width, float height) { + ArgumentNullException.ThrowIfNull(brush); + CheckErrorStatus(Gdip.GdipFillRectangle( new HandleRef(this, NativeGraphics), new HandleRef(brush, brush.NativeBrush), @@ -1055,8 +1307,10 @@ public void FillRectangle(Brush brush, Rectangle rect) /// /// Fills the interior of a rectangle with a . /// - public void FillRectangle(Brush brush!!, int x, int y, int width, int height) + public void FillRectangle(Brush brush, int x, int y, int width, int height) { + ArgumentNullException.ThrowIfNull(brush); + CheckErrorStatus(Gdip.GdipFillRectangleI( new HandleRef(this, NativeGraphics), new HandleRef(brush, brush.NativeBrush), @@ -1066,8 +1320,11 @@ public void FillRectangle(Brush brush!!, int x, int y, int width, int height) /// /// Fills the interiors of a series of rectangles with a . /// - public unsafe void FillRectangles(Brush brush!!, RectangleF[] rects!!) + public unsafe void FillRectangles(Brush brush, RectangleF[] rects) { + ArgumentNullException.ThrowIfNull(brush); + ArgumentNullException.ThrowIfNull(rects); + fixed (RectangleF* r = rects) { CheckErrorStatus(Gdip.GdipFillRectangles( @@ -1080,8 +1337,11 @@ public unsafe void FillRectangles(Brush brush!!, RectangleF[] rects!!) /// /// Fills the interiors of a series of rectangles with a . /// - public unsafe void FillRectangles(Brush brush!!, Rectangle[] rects!!) + public unsafe void FillRectangles(Brush brush, Rectangle[] rects) { + ArgumentNullException.ThrowIfNull(brush); + ArgumentNullException.ThrowIfNull(rects); + fixed (Rectangle* r = rects) { CheckErrorStatus(Gdip.GdipFillRectanglesI( @@ -1102,8 +1362,11 @@ public void FillPolygon(Brush brush, PointF[] points) /// /// Fills the interior of a polygon defined by an array of points. /// - public unsafe void FillPolygon(Brush brush!!, PointF[] points!!, FillMode fillMode) + public unsafe void FillPolygon(Brush brush, PointF[] points, FillMode fillMode) { + ArgumentNullException.ThrowIfNull(brush); + ArgumentNullException.ThrowIfNull(points); + fixed (PointF* p = points) { CheckErrorStatus(Gdip.GdipFillPolygon( @@ -1125,8 +1388,11 @@ public void FillPolygon(Brush brush, Point[] points) /// /// Fills the interior of a polygon defined by an array of points. /// - public unsafe void FillPolygon(Brush brush!!, Point[] points!!, FillMode fillMode) + public unsafe void FillPolygon(Brush brush, Point[] points, FillMode fillMode) { + ArgumentNullException.ThrowIfNull(brush); + ArgumentNullException.ThrowIfNull(points); + fixed (Point* p = points) { CheckErrorStatus(Gdip.GdipFillPolygonI( @@ -1148,8 +1414,10 @@ public void FillEllipse(Brush brush, RectangleF rect) /// /// Fills the interior of an ellipse defined by a bounding rectangle. /// - public void FillEllipse(Brush brush!!, float x, float y, float width, float height) + public void FillEllipse(Brush brush, float x, float y, float width, float height) { + ArgumentNullException.ThrowIfNull(brush); + CheckErrorStatus(Gdip.GdipFillEllipse( new HandleRef(this, NativeGraphics), new HandleRef(brush, brush.NativeBrush), @@ -1167,8 +1435,10 @@ public void FillEllipse(Brush brush, Rectangle rect) /// /// Fills the interior of an ellipse defined by a bounding rectangle. /// - public void FillEllipse(Brush brush!!, int x, int y, int width, int height) + public void FillEllipse(Brush brush, int x, int y, int width, int height) { + ArgumentNullException.ThrowIfNull(brush); + CheckErrorStatus(Gdip.GdipFillEllipseI( new HandleRef(this, NativeGraphics), new HandleRef(brush, brush.NativeBrush), @@ -1198,8 +1468,10 @@ public void FillPie(Brush brush, RectangleF rect, float startAngle, float sweepA /// /// Fills the interior of a pie section defined by an ellipse and two radial lines. /// - public void FillPie(Brush brush!!, float x, float y, float width, float height, float startAngle, float sweepAngle) + public void FillPie(Brush brush, float x, float y, float width, float height, float startAngle, float sweepAngle) { + ArgumentNullException.ThrowIfNull(brush); + CheckErrorStatus(Gdip.GdipFillPie( new HandleRef(this, NativeGraphics), new HandleRef(brush, brush.NativeBrush), @@ -1211,8 +1483,10 @@ public void FillPie(Brush brush!!, float x, float y, float width, float height, /// /// Fills the interior of a pie section defined by an ellipse and two radial lines. /// - public void FillPie(Brush brush!!, int x, int y, int width, int height, int startAngle, int sweepAngle) + public void FillPie(Brush brush, int x, int y, int width, int height, int startAngle, int sweepAngle) { + ArgumentNullException.ThrowIfNull(brush); + CheckErrorStatus(Gdip.GdipFillPieI( new HandleRef(this, NativeGraphics), new HandleRef(brush, brush.NativeBrush), @@ -1224,8 +1498,11 @@ public void FillPie(Brush brush!!, int x, int y, int width, int height, int star /// /// Fills the interior a closed curve defined by an array of points. /// - public unsafe void FillClosedCurve(Brush brush!!, PointF[] points!!) + public unsafe void FillClosedCurve(Brush brush, PointF[] points) { + ArgumentNullException.ThrowIfNull(brush); + ArgumentNullException.ThrowIfNull(points); + fixed (PointF* p = points) { CheckErrorStatus(Gdip.GdipFillClosedCurve( @@ -1243,8 +1520,10 @@ public void FillClosedCurve(Brush brush, PointF[] points, FillMode fillmode) FillClosedCurve(brush, points, fillmode, 0.5f); } - public unsafe void FillClosedCurve(Brush brush!!, PointF[] points!!, FillMode fillmode, float tension) + public unsafe void FillClosedCurve(Brush brush, PointF[] points, FillMode fillmode, float tension) { + ArgumentNullException.ThrowIfNull(points); + fixed (PointF* p = points) { CheckErrorStatus(Gdip.GdipFillClosedCurve2( @@ -1259,8 +1538,11 @@ public unsafe void FillClosedCurve(Brush brush!!, PointF[] points!!, FillMode fi /// /// Fills the interior a closed curve defined by an array of points. /// - public unsafe void FillClosedCurve(Brush brush!!, Point[] points!!) + public unsafe void FillClosedCurve(Brush brush, Point[] points) { + ArgumentNullException.ThrowIfNull(brush); + ArgumentNullException.ThrowIfNull(points); + fixed (Point* p = points) { CheckErrorStatus(Gdip.GdipFillClosedCurveI( @@ -1275,8 +1557,11 @@ public void FillClosedCurve(Brush brush, Point[] points, FillMode fillmode) FillClosedCurve(brush, points, fillmode, 0.5f); } - public unsafe void FillClosedCurve(Brush brush!!, Point[] points!!, FillMode fillmode, float tension) + public unsafe void FillClosedCurve(Brush brush, Point[] points, FillMode fillmode, float tension) { + ArgumentNullException.ThrowIfNull(brush); + ArgumentNullException.ThrowIfNull(points); + fixed (Point* p = points) { CheckErrorStatus(Gdip.GdipFillClosedCurve2I( @@ -1316,12 +1601,12 @@ public void DrawString(string? s, Font font, Brush brush, RectangleF layoutRecta DrawString(s, font, brush, layoutRectangle, null); } - public void DrawString(string? s, Font font, Brush brush!!, RectangleF layoutRectangle, StringFormat? format) + public void DrawString(string? s, Font font, Brush brush, RectangleF layoutRectangle, StringFormat? format) { + ArgumentNullException.ThrowIfNull(brush); if (string.IsNullOrEmpty(s)) return; - if (font == null) - throw new ArgumentNullException(nameof(font)); + ArgumentNullException.ThrowIfNull(font); CheckErrorStatus(Gdip.GdipDrawString( new HandleRef(this, NativeGraphics), @@ -1474,8 +1759,10 @@ public void DrawImage(Image image, PointF point) DrawImage(image, point.X, point.Y); } - public void DrawImage(Image image!!, float x, float y) + public void DrawImage(Image image, float x, float y) { + ArgumentNullException.ThrowIfNull(image); + int status = Gdip.GdipDrawImage( new HandleRef(this, NativeGraphics), new HandleRef(image, image.nativeImage), x, y); @@ -1489,8 +1776,10 @@ public void DrawImage(Image image, RectangleF rect) DrawImage(image, rect.X, rect.Y, rect.Width, rect.Height); } - public void DrawImage(Image image!!, float x, float y, float width, float height) + public void DrawImage(Image image, float x, float y, float width, float height) { + ArgumentNullException.ThrowIfNull(image); + int status = Gdip.GdipDrawImageRect( new HandleRef(this, NativeGraphics), new HandleRef(image, image.nativeImage), @@ -1506,8 +1795,10 @@ public void DrawImage(Image image, Point point) DrawImage(image, point.X, point.Y); } - public void DrawImage(Image image!!, int x, int y) + public void DrawImage(Image image, int x, int y) { + ArgumentNullException.ThrowIfNull(image); + int status = Gdip.GdipDrawImageI( new HandleRef(this, NativeGraphics), new HandleRef(image, image.nativeImage), @@ -1522,8 +1813,10 @@ public void DrawImage(Image image, Rectangle rect) DrawImage(image, rect.X, rect.Y, rect.Width, rect.Height); } - public void DrawImage(Image image!!, int x, int y, int width, int height) + public void DrawImage(Image image, int x, int y, int width, int height) { + ArgumentNullException.ThrowIfNull(image); + int status = Gdip.GdipDrawImageRectI( new HandleRef(this, NativeGraphics), new HandleRef(image, image.nativeImage), @@ -1554,8 +1847,10 @@ public void DrawImageUnscaled(Image image, int x, int y, int width, int height) DrawImage(image, x, y); } - public void DrawImageUnscaledAndClipped(Image image!!, Rectangle rect) + public void DrawImageUnscaledAndClipped(Image image, Rectangle rect) { + ArgumentNullException.ThrowIfNull(image); + int width = Math.Min(rect.Width, image.Width); int height = Math.Min(rect.Height, image.Height); @@ -1574,8 +1869,11 @@ public void DrawImageUnscaledAndClipped(Image image!!, Rectangle rect) // // @notes Perspective blt only works for bitmap images. - public unsafe void DrawImage(Image image!!, PointF[] destPoints!!) + public unsafe void DrawImage(Image image, PointF[] destPoints) { + ArgumentNullException.ThrowIfNull(image); + ArgumentNullException.ThrowIfNull(destPoints); + int count = destPoints.Length; if (count != 3 && count != 4) throw new ArgumentException(SR.GdiplusDestPointsInvalidLength); @@ -1592,8 +1890,11 @@ public unsafe void DrawImage(Image image!!, PointF[] destPoints!!) } } - public unsafe void DrawImage(Image image!!, Point[] destPoints!!) + public unsafe void DrawImage(Image image, Point[] destPoints) { + ArgumentNullException.ThrowIfNull(image); + ArgumentNullException.ThrowIfNull(destPoints); + int count = destPoints.Length; if (count != 3 && count != 4) throw new ArgumentException(SR.GdiplusDestPointsInvalidLength); @@ -1610,8 +1911,10 @@ public unsafe void DrawImage(Image image!!, Point[] destPoints!!) } } - public void DrawImage(Image image!!, float x, float y, RectangleF srcRect, GraphicsUnit srcUnit) + public void DrawImage(Image image, float x, float y, RectangleF srcRect, GraphicsUnit srcUnit) { + ArgumentNullException.ThrowIfNull(image); + int status = Gdip.GdipDrawImagePointRect( new HandleRef(this, NativeGraphics), new HandleRef(image, image.nativeImage), @@ -1623,8 +1926,10 @@ public void DrawImage(Image image!!, float x, float y, RectangleF srcRect, Graph CheckErrorStatus(status); } - public void DrawImage(Image image!!, int x, int y, Rectangle srcRect, GraphicsUnit srcUnit) + public void DrawImage(Image image, int x, int y, Rectangle srcRect, GraphicsUnit srcUnit) { + ArgumentNullException.ThrowIfNull(image); + int status = Gdip.GdipDrawImagePointRectI( new HandleRef(this, NativeGraphics), new HandleRef(image, image.nativeImage), @@ -1636,8 +1941,10 @@ public void DrawImage(Image image!!, int x, int y, Rectangle srcRect, GraphicsUn CheckErrorStatus(status); } - public void DrawImage(Image image!!, RectangleF destRect, RectangleF srcRect, GraphicsUnit srcUnit) + public void DrawImage(Image image, RectangleF destRect, RectangleF srcRect, GraphicsUnit srcUnit) { + ArgumentNullException.ThrowIfNull(image); + int status = Gdip.GdipDrawImageRectRect( new HandleRef(this, NativeGraphics), new HandleRef(image, image.nativeImage), @@ -1652,8 +1959,10 @@ public void DrawImage(Image image!!, RectangleF destRect, RectangleF srcRect, Gr CheckErrorStatus(status); } - public void DrawImage(Image image!!, Rectangle destRect, Rectangle srcRect, GraphicsUnit srcUnit) + public void DrawImage(Image image, Rectangle destRect, Rectangle srcRect, GraphicsUnit srcUnit) { + ArgumentNullException.ThrowIfNull(image); + int status = Gdip.GdipDrawImageRectRectI( new HandleRef(this, NativeGraphics), new HandleRef(image, image.nativeImage), @@ -1668,8 +1977,11 @@ public void DrawImage(Image image!!, Rectangle destRect, Rectangle srcRect, Grap CheckErrorStatus(status); } - public unsafe void DrawImage(Image image!!, PointF[] destPoints!!, RectangleF srcRect, GraphicsUnit srcUnit) + public unsafe void DrawImage(Image image, PointF[] destPoints, RectangleF srcRect, GraphicsUnit srcUnit) { + ArgumentNullException.ThrowIfNull(image); + ArgumentNullException.ThrowIfNull(destPoints); + int count = destPoints.Length; if (count != 3 && count != 4) throw new ArgumentException(SR.GdiplusDestPointsInvalidLength); @@ -1708,14 +2020,17 @@ public void DrawImage( } public unsafe void DrawImage( - Image image!!, - PointF[] destPoints!!, + Image image, + PointF[] destPoints, RectangleF srcRect, GraphicsUnit srcUnit, ImageAttributes? imageAttr, DrawImageAbort? callback, int callbackData) { + ArgumentNullException.ThrowIfNull(image); + ArgumentNullException.ThrowIfNull(destPoints); + int count = destPoints.Length; if (count != 3 && count != 4) throw new ArgumentException(SR.GdiplusDestPointsInvalidLength); @@ -1764,14 +2079,17 @@ public void DrawImage( } public unsafe void DrawImage( - Image image!!, - Point[] destPoints!!, + Image image, + Point[] destPoints, Rectangle srcRect, GraphicsUnit srcUnit, ImageAttributes? imageAttr, DrawImageAbort? callback, int callbackData) { + ArgumentNullException.ThrowIfNull(image); + ArgumentNullException.ThrowIfNull(destPoints); + int count = destPoints.Length; if (count != 3 && count != 4) throw new ArgumentException(SR.GdiplusDestPointsInvalidLength); @@ -1833,7 +2151,7 @@ public void DrawImage( } public void DrawImage( - Image image!!, + Image image, Rectangle destRect, float srcX, float srcY, @@ -1844,6 +2162,8 @@ public void DrawImage( DrawImageAbort? callback, IntPtr callbackData) { + ArgumentNullException.ThrowIfNull(image); + int status = Gdip.GdipDrawImageRectRect( new HandleRef(this, NativeGraphics), new HandleRef(image, image.nativeImage), @@ -1898,7 +2218,7 @@ public void DrawImage( } public void DrawImage( - Image image!!, + Image image, Rectangle destRect, int srcX, int srcY, @@ -1909,6 +2229,8 @@ public void DrawImage( DrawImageAbort? callback, IntPtr callbackData) { + ArgumentNullException.ThrowIfNull(image); + int status = Gdip.GdipDrawImageRectRectI( new HandleRef(this, NativeGraphics), new HandleRef(image, image.nativeImage), @@ -1934,8 +2256,11 @@ public void DrawLine(Pen pen, PointF pt1, PointF pt2) /// /// Draws a series of line segments that connect an array of points. /// - public unsafe void DrawLines(Pen pen!!, PointF[] points!!) + public unsafe void DrawLines(Pen pen, PointF[] points) { + ArgumentNullException.ThrowIfNull(pen); + ArgumentNullException.ThrowIfNull(points); + fixed (PointF* p = points) { CheckErrorStatus(Gdip.GdipDrawLines( @@ -1949,8 +2274,10 @@ public unsafe void DrawLines(Pen pen!!, PointF[] points!!) /// /// Draws a line connecting the two specified points. /// - public void DrawLine(Pen pen!!, int x1, int y1, int x2, int y2) + public void DrawLine(Pen pen, int x1, int y1, int x2, int y2) { + ArgumentNullException.ThrowIfNull(pen); + CheckErrorStatus(Gdip.GdipDrawLineI(new HandleRef(this, NativeGraphics), new HandleRef(pen, pen.NativePen), x1, y1, x2, y2)); } @@ -1965,8 +2292,11 @@ public void DrawLine(Pen pen, Point pt1, Point pt2) /// /// Draws a series of line segments that connect an array of points. /// - public unsafe void DrawLines(Pen pen!!, Point[] points!!) + public unsafe void DrawLines(Pen pen, Point[] points) { + ArgumentNullException.ThrowIfNull(pen); + ArgumentNullException.ThrowIfNull(points); + fixed (Point* p = points) { CheckErrorStatus(Gdip.GdipDrawLinesI( @@ -2192,8 +2522,10 @@ public void EnumerateMetafile( EnumerateMetafile(metafile, destPoints, srcRect, srcUnit, callback, callbackData, null); } - public unsafe void TransformPoints(CoordinateSpace destSpace, CoordinateSpace srcSpace, PointF[] pts!!) + public unsafe void TransformPoints(CoordinateSpace destSpace, CoordinateSpace srcSpace, PointF[] pts) { + ArgumentNullException.ThrowIfNull(pts); + fixed (PointF* p = pts) { Gdip.CheckStatus(Gdip.GdipTransformPoints( @@ -2205,8 +2537,10 @@ public unsafe void TransformPoints(CoordinateSpace destSpace, CoordinateSpace sr } } - public unsafe void TransformPoints(CoordinateSpace destSpace, CoordinateSpace srcSpace, Point[] pts!!) + public unsafe void TransformPoints(CoordinateSpace destSpace, CoordinateSpace srcSpace, Point[] pts) { + ArgumentNullException.ThrowIfNull(pts); + fixed (Point* p = pts) { Gdip.CheckStatus(Gdip.GdipTransformPointsI( @@ -2263,5 +2597,798 @@ private static void IgnoreMetafileErrors(Image image, ref int errorStatus) } } } + + /// + /// Represents an object used in connection with the printing API, it is used to hold a reference to a + /// PrintPreviewGraphics (fake graphics) or a printer DeviceContext (and maybe more in the future). + /// + internal object? PrintingHelper + { + get => _printingHelper; + set + { + Debug.Assert(_printingHelper == null, "WARNING: Overwritting the printing helper reference!"); + _printingHelper = value; + } + } + + /// + /// CopyPixels will perform a gdi "bitblt" operation to the source from the destination with the given size + /// and specified raster operation. + /// + public void CopyFromScreen(int sourceX, int sourceY, int destinationX, int destinationY, Size blockRegionSize, CopyPixelOperation copyPixelOperation) + { + switch (copyPixelOperation) + { + case CopyPixelOperation.Blackness: + case CopyPixelOperation.NotSourceErase: + case CopyPixelOperation.NotSourceCopy: + case CopyPixelOperation.SourceErase: + case CopyPixelOperation.DestinationInvert: + case CopyPixelOperation.PatInvert: + case CopyPixelOperation.SourceInvert: + case CopyPixelOperation.SourceAnd: + case CopyPixelOperation.MergePaint: + case CopyPixelOperation.MergeCopy: + case CopyPixelOperation.SourceCopy: + case CopyPixelOperation.SourcePaint: + case CopyPixelOperation.PatCopy: + case CopyPixelOperation.PatPaint: + case CopyPixelOperation.Whiteness: + case CopyPixelOperation.CaptureBlt: + case CopyPixelOperation.NoMirrorBitmap: + break; + default: + throw new InvalidEnumArgumentException(nameof(copyPixelOperation), (int)copyPixelOperation, typeof(CopyPixelOperation)); + } + + int destWidth = blockRegionSize.Width; + int destHeight = blockRegionSize.Height; + + IntPtr screenDC = Interop.User32.GetDC(IntPtr.Zero); + try + { + IntPtr targetDC = GetHdc(); + int result = Interop.Gdi32.BitBlt( + targetDC, + destinationX, + destinationY, + destWidth, + destHeight, + screenDC, + sourceX, + sourceY, + (Interop.Gdi32.RasterOp)copyPixelOperation); + + //a zero result indicates a win32 exception has been thrown + if (result == 0) + { + throw new Win32Exception(); + } + } + finally + { + Interop.User32.ReleaseDC(IntPtr.Zero, screenDC); + ReleaseHdc(); + } + } + + public Color GetNearestColor(Color color) + { + int nearest = color.ToArgb(); + Gdip.CheckStatus(Gdip.GdipGetNearestColor(new HandleRef(this, NativeGraphics), ref nearest)); + return Color.FromArgb(nearest); + } + + /// + /// Draws a line connecting the two specified points. + /// + public void DrawLine(Pen pen, float x1, float y1, float x2, float y2) + { + ArgumentNullException.ThrowIfNull(pen); + + CheckErrorStatus(Gdip.GdipDrawLine(new HandleRef(this, NativeGraphics), new HandleRef(pen, pen.NativePen), x1, y1, x2, y2)); + } + + /// + /// Draws a series of cubic Bezier curves from an array of points. + /// + public unsafe void DrawBeziers(Pen pen, PointF[] points) + { + ArgumentNullException.ThrowIfNull(pen); + ArgumentNullException.ThrowIfNull(points); + + fixed (PointF* p = points) + { + CheckErrorStatus(Gdip.GdipDrawBeziers( + new HandleRef(this, NativeGraphics), + new HandleRef(pen, pen.NativePen), + p, points.Length)); + } + } + + /// + /// Draws a series of cubic Bezier curves from an array of points. + /// + public unsafe void DrawBeziers(Pen pen, Point[] points) + { + ArgumentNullException.ThrowIfNull(pen); + ArgumentNullException.ThrowIfNull(points); + + fixed (Point* p = points) + { + CheckErrorStatus(Gdip.GdipDrawBeziersI( + new HandleRef(this, NativeGraphics), + new HandleRef(pen, pen.NativePen), + p, + points.Length)); + } + } + + /// + /// Fills the interior of a path. + /// + public void FillPath(Brush brush, GraphicsPath path) + { + ArgumentNullException.ThrowIfNull(brush); + ArgumentNullException.ThrowIfNull(path); + + CheckErrorStatus(Gdip.GdipFillPath( + new HandleRef(this, NativeGraphics), + new HandleRef(brush, brush.NativeBrush), + new HandleRef(path, path._nativePath))); + } + + /// + /// Fills the interior of a . + /// + public void FillRegion(Brush brush, Region region) + { + ArgumentNullException.ThrowIfNull(brush); + ArgumentNullException.ThrowIfNull(region); + + CheckErrorStatus(Gdip.GdipFillRegion( + new HandleRef(this, NativeGraphics), + new HandleRef(brush, brush.NativeBrush), + new HandleRef(region, region.NativeRegion))); + } + + public void DrawIcon(Icon icon, int x, int y) + { + ArgumentNullException.ThrowIfNull(icon); + + if (_backingImage != null) + { + // We don't call the icon directly because we want to stay in GDI+ all the time + // to avoid alpha channel interop issues between gdi and gdi+ + // so we do icon.ToBitmap() and then we call DrawImage. This is probably slower. + DrawImage(icon.ToBitmap(), x, y); + } + else + { + icon.Draw(this, x, y); + } + } + + /// + /// Draws this image to a graphics object. The drawing command originates on the graphics + /// object, but a graphics object generally has no idea how to render a given image. So, + /// it passes the call to the actual image. This version crops the image to the given + /// dimensions and allows the user to specify a rectangle within the image to draw. + /// + public void DrawIcon(Icon icon, Rectangle targetRect) + { + ArgumentNullException.ThrowIfNull(icon); + + if (_backingImage != null) + { + // We don't call the icon directly because we want to stay in GDI+ all the time + // to avoid alpha channel interop issues between gdi and gdi+ + // so we do icon.ToBitmap() and then we call DrawImage. This is probably slower. + DrawImage(icon.ToBitmap(), targetRect); + } + else + { + icon.Draw(this, targetRect); + } + } + + /// + /// Draws this image to a graphics object. The drawing command originates on the graphics + /// object, but a graphics object generally has no idea how to render a given image. So, + /// it passes the call to the actual image. This version stretches the image to the given + /// dimensions and allows the user to specify a rectangle within the image to draw. + /// + public void DrawIconUnstretched(Icon icon, Rectangle targetRect) + { + ArgumentNullException.ThrowIfNull(icon); + + if (_backingImage != null) + { + DrawImageUnscaled(icon.ToBitmap(), targetRect); + } + else + { + icon.DrawUnstretched(this, targetRect); + } + } + + public void EnumerateMetafile( + Metafile metafile, + PointF destPoint, + EnumerateMetafileProc callback, + IntPtr callbackData, + ImageAttributes? imageAttr) + { + Gdip.CheckStatus(Gdip.GdipEnumerateMetafileDestPoint( + new HandleRef(this, NativeGraphics), + new HandleRef(metafile, metafile?.nativeImage ?? IntPtr.Zero), + ref destPoint, + callback, + callbackData, + new HandleRef(imageAttr, imageAttr?.nativeImageAttributes ?? IntPtr.Zero))); + } + public void EnumerateMetafile( + Metafile metafile, + Point destPoint, + EnumerateMetafileProc callback, + IntPtr callbackData, + ImageAttributes? imageAttr) + { + Gdip.CheckStatus(Gdip.GdipEnumerateMetafileDestPointI( + new HandleRef(this, NativeGraphics), + new HandleRef(metafile, metafile?.nativeImage ?? IntPtr.Zero), + ref destPoint, + callback, + callbackData, + new HandleRef(imageAttr, imageAttr?.nativeImageAttributes ?? IntPtr.Zero))); + } + + public void EnumerateMetafile( + Metafile metafile, + RectangleF destRect, + EnumerateMetafileProc callback, + IntPtr callbackData, + ImageAttributes? imageAttr) + { + Gdip.CheckStatus(Gdip.GdipEnumerateMetafileDestRect( + new HandleRef(this, NativeGraphics), + new HandleRef(metafile, metafile?.nativeImage ?? IntPtr.Zero), + ref destRect, + callback, + callbackData, + new HandleRef(imageAttr, imageAttr?.nativeImageAttributes ?? IntPtr.Zero))); + } + + public void EnumerateMetafile( + Metafile metafile, + Rectangle destRect, + EnumerateMetafileProc callback, + IntPtr callbackData, + ImageAttributes? imageAttr) + { + Gdip.CheckStatus(Gdip.GdipEnumerateMetafileDestRectI( + new HandleRef(this, NativeGraphics), + new HandleRef(metafile, metafile?.nativeImage ?? IntPtr.Zero), + ref destRect, + callback, + callbackData, + new HandleRef(imageAttr, imageAttr?.nativeImageAttributes ?? IntPtr.Zero))); + } + + public unsafe void EnumerateMetafile( + Metafile metafile, + PointF[] destPoints, + EnumerateMetafileProc callback, + IntPtr callbackData, + ImageAttributes? imageAttr) + { + ArgumentNullException.ThrowIfNull(destPoints); + + if (destPoints.Length != 3) + throw new ArgumentException(SR.GdiplusDestPointsInvalidParallelogram); + + fixed (PointF* p = destPoints) + { + Gdip.CheckStatus(Gdip.GdipEnumerateMetafileDestPoints( + new HandleRef(this, NativeGraphics), + new HandleRef(metafile, metafile?.nativeImage ?? IntPtr.Zero), + p, destPoints.Length, + callback, + callbackData, + new HandleRef(imageAttr, imageAttr?.nativeImageAttributes ?? IntPtr.Zero))); + } + } + + public unsafe void EnumerateMetafile( + Metafile metafile, + Point[] destPoints, + EnumerateMetafileProc callback, + IntPtr callbackData, + ImageAttributes? imageAttr) + { + ArgumentNullException.ThrowIfNull(destPoints); + + if (destPoints.Length != 3) + throw new ArgumentException(SR.GdiplusDestPointsInvalidParallelogram); + + fixed (Point* p = destPoints) + { + Gdip.CheckStatus(Gdip.GdipEnumerateMetafileDestPointsI( + new HandleRef(this, NativeGraphics), + new HandleRef(metafile, metafile?.nativeImage ?? IntPtr.Zero), + p, destPoints.Length, + callback, + callbackData, + new HandleRef(imageAttr, imageAttr?.nativeImageAttributes ?? IntPtr.Zero))); + } + } + + public void EnumerateMetafile( + Metafile metafile, + PointF destPoint, + RectangleF srcRect, + GraphicsUnit unit, + EnumerateMetafileProc callback, + IntPtr callbackData, + ImageAttributes? imageAttr) + { + Gdip.CheckStatus(Gdip.GdipEnumerateMetafileSrcRectDestPoint( + new HandleRef(this, NativeGraphics), + new HandleRef(metafile, metafile?.nativeImage ?? IntPtr.Zero), + ref destPoint, + ref srcRect, + unit, + callback, + callbackData, + new HandleRef(imageAttr, imageAttr?.nativeImageAttributes ?? IntPtr.Zero))); + } + + public void EnumerateMetafile( + Metafile metafile, + Point destPoint, + Rectangle srcRect, + GraphicsUnit unit, + EnumerateMetafileProc callback, + IntPtr callbackData, + ImageAttributes? imageAttr) + { + Gdip.CheckStatus(Gdip.GdipEnumerateMetafileSrcRectDestPointI( + new HandleRef(this, NativeGraphics), + new HandleRef(metafile, metafile?.nativeImage ?? IntPtr.Zero), + ref destPoint, + ref srcRect, + unit, + callback, + callbackData, + new HandleRef(imageAttr, imageAttr?.nativeImageAttributes ?? IntPtr.Zero))); + } + + public void EnumerateMetafile( + Metafile metafile, + RectangleF destRect, + RectangleF srcRect, + GraphicsUnit unit, + EnumerateMetafileProc callback, + IntPtr callbackData, + ImageAttributes? imageAttr) + { + Gdip.CheckStatus(Gdip.GdipEnumerateMetafileSrcRectDestRect( + new HandleRef(this, NativeGraphics), + new HandleRef(metafile, metafile?.nativeImage ?? IntPtr.Zero), + ref destRect, + ref srcRect, + unit, + callback, + callbackData, + new HandleRef(imageAttr, imageAttr?.nativeImageAttributes ?? IntPtr.Zero))); + } + + public void EnumerateMetafile( + Metafile metafile, + Rectangle destRect, + Rectangle srcRect, + GraphicsUnit unit, + EnumerateMetafileProc callback, + IntPtr callbackData, + ImageAttributes? imageAttr) + { + Gdip.CheckStatus(Gdip.GdipEnumerateMetafileSrcRectDestRectI( + new HandleRef(this, NativeGraphics), + new HandleRef(metafile, metafile?.nativeImage ?? IntPtr.Zero), + ref destRect, + ref srcRect, + unit, + callback, + callbackData, + new HandleRef(imageAttr, imageAttr?.nativeImageAttributes ?? IntPtr.Zero))); + } + + public unsafe void EnumerateMetafile( + Metafile metafile, + PointF[] destPoints, + RectangleF srcRect, + GraphicsUnit unit, + EnumerateMetafileProc callback, + IntPtr callbackData, + ImageAttributes? imageAttr) + { + ArgumentNullException.ThrowIfNull(destPoints); + + if (destPoints.Length != 3) + throw new ArgumentException(SR.GdiplusDestPointsInvalidParallelogram); + + fixed (PointF* p = destPoints) + { + Gdip.CheckStatus(Gdip.GdipEnumerateMetafileSrcRectDestPoints( + new HandleRef(this, NativeGraphics), + new HandleRef(metafile, metafile?.nativeImage ?? IntPtr.Zero), + p, destPoints.Length, + ref srcRect, + unit, + callback, + callbackData, + new HandleRef(imageAttr, imageAttr?.nativeImageAttributes ?? IntPtr.Zero))); + } + } + + public unsafe void EnumerateMetafile( + Metafile metafile, + Point[] destPoints, + Rectangle srcRect, + GraphicsUnit unit, + EnumerateMetafileProc callback, + IntPtr callbackData, + ImageAttributes? imageAttr) + { + ArgumentNullException.ThrowIfNull(destPoints); + + if (destPoints.Length != 3) + throw new ArgumentException(SR.GdiplusDestPointsInvalidParallelogram); + + fixed (Point* p = destPoints) + { + Gdip.CheckStatus(Gdip.GdipEnumerateMetafileSrcRectDestPointsI( + new HandleRef(this, NativeGraphics), + new HandleRef(metafile, metafile?.nativeImage ?? IntPtr.Zero), + p, destPoints.Length, + ref srcRect, + unit, + callback, + callbackData, + new HandleRef(imageAttr, imageAttr?.nativeImageAttributes ?? IntPtr.Zero))); + } + } + + /// + /// Combines current Graphics context with all previous contexts. + /// When BeginContainer() is called, a copy of the current context is pushed into the GDI+ context stack, it keeps track of the + /// absolute clipping and transform but reset the public properties so it looks like a brand new context. + /// When Save() is called, a copy of the current context is also pushed in the GDI+ stack but the public clipping and transform + /// properties are not reset (cumulative). Consecutive Save context are ignored with the exception of the top one which contains + /// all previous information. + /// The return value is an object array where the first element contains the cumulative clip region and the second the cumulative + /// translate transform matrix. + /// WARNING: This method is for internal FX support only. + /// + [EditorBrowsable(EditorBrowsableState.Never)] +#if NETCOREAPP3_1_OR_GREATER + [Obsolete(Obsoletions.GetContextInfoMessage, DiagnosticId = Obsoletions.GetContextInfoDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif + [SupportedOSPlatform("windows")] + public object GetContextInfo() + { + GetContextInfo(out Matrix3x2 cumulativeTransform, calculateClip: true, out Region? cumulativeClip); + return new object[] { cumulativeClip ?? new Region(), new Matrix(cumulativeTransform) }; + } + + private void GetContextInfo(out Matrix3x2 cumulativeTransform, bool calculateClip, out Region? cumulativeClip) + { + cumulativeClip = calculateClip ? GetRegionIfNotInfinite() : null; // Current context clip. + cumulativeTransform = TransformElements; // Current context transform. + Vector2 currentOffset = default; // Offset of current context. + Vector2 totalOffset = default; // Absolute coordinate offset of top context. + + GraphicsContext? context = _previousContext; + + if (!cumulativeTransform.IsIdentity) + { + currentOffset = cumulativeTransform.Translation; + } + + while (context is not null) + { + if (!context.TransformOffset.IsEmpty()) + { + cumulativeTransform.Translate(context.TransformOffset); + } + + if (!currentOffset.IsEmpty()) + { + // The location of the GDI+ clip region is relative to the coordinate origin after any translate transform + // has been applied. We need to intersect regions using the same coordinate origin relative to the previous + // context. + + // If we don't have a cumulative clip, we're infinite, and translation on infinite regions is a no-op. + cumulativeClip?.Translate(currentOffset.X, currentOffset.Y); + totalOffset.X += currentOffset.X; + totalOffset.Y += currentOffset.Y; + } + + // Context only stores clips if they are not infinite. Intersecting a clip with an infinite clip is a no-op. + if (calculateClip && context.Clip is not null) + { + // Intersecting an infinite clip with another is just a copy of the second clip. + if (cumulativeClip is null) + { + cumulativeClip = context.Clip; + } + else + { + cumulativeClip.Intersect(context.Clip); + } + } + + currentOffset = context.TransformOffset; + + // Ignore subsequent cumulative contexts. + do + { + context = context.Previous; + + if (context == null || !context.Next!.IsCumulative) + { + break; + } + } while (context.IsCumulative); + } + + if (!totalOffset.IsEmpty()) + { + // We need now to reset the total transform in the region so when calling Region.GetHRgn(Graphics) + // the HRegion is properly offset by GDI+ based on the total offset of the graphics object. + + // If we don't have a cumulative clip, we're infinite, and translation on infinite regions is a no-op. + cumulativeClip?.Translate(-totalOffset.X, -totalOffset.Y); + } + } + +#if NETCOREAPP3_1_OR_GREATER + /// + /// Gets the cumulative offset. + /// + /// The cumulative offset. + [EditorBrowsable(EditorBrowsableState.Never)] + [SupportedOSPlatform("windows")] + public void GetContextInfo(out PointF offset) + { + GetContextInfo(out Matrix3x2 cumulativeTransform, calculateClip: false, out _); + Vector2 translation = cumulativeTransform.Translation; + offset = new PointF(translation.X, translation.Y); + } + + /// + /// Gets the cumulative offset and clip region. + /// + /// The cumulative offset. + /// The cumulative clip region or null if the clip region is infinite. + [EditorBrowsable(EditorBrowsableState.Never)] + [SupportedOSPlatform("windows")] + public void GetContextInfo(out PointF offset, out Region? clip) + { + GetContextInfo(out Matrix3x2 cumulativeTransform, calculateClip: true, out clip); + Vector2 translation = cumulativeTransform.Translation; + offset = new PointF(translation.X, translation.Y); + } +#endif + + public RectangleF VisibleClipBounds + { + get + { + if (PrintingHelper is PrintPreviewGraphics ppGraphics) + return ppGraphics.VisibleClipBounds; + + Gdip.CheckStatus(Gdip.GdipGetVisibleClipBounds(new HandleRef(this, NativeGraphics), out RectangleF rect)); + + return rect; + } + } + + /// + /// Saves the current context into the context stack. + /// + private void PushContext(GraphicsContext context) + { + Debug.Assert(context != null && context.State != 0, "GraphicsContext object is null or not valid."); + + if (_previousContext != null) + { + // Push context. + context.Previous = _previousContext; + _previousContext.Next = context; + } + _previousContext = context; + } + + /// + /// Pops all contexts from the specified one included. The specified context is becoming the current context. + /// + private void PopContext(int currentContextState) + { + Debug.Assert(_previousContext != null, "Trying to restore a context when the stack is empty"); + GraphicsContext? context = _previousContext; + + // Pop all contexts up the stack. + while (context != null) + { + if (context.State == currentContextState) + { + _previousContext = context.Previous; + + // This will dipose all context object up the stack. + context.Dispose(); + return; + } + context = context.Previous; + } + Debug.Fail("Warning: context state not found!"); + } + + public GraphicsState Save() + { + GraphicsContext context = new GraphicsContext(this); + int status = Gdip.GdipSaveGraphics(new HandleRef(this, NativeGraphics), out int state); + + if (status != Gdip.Ok) + { + context.Dispose(); + throw Gdip.StatusException(status); + } + + context.State = state; + context.IsCumulative = true; + PushContext(context); + + return new GraphicsState(state); + } + + public void Restore(GraphicsState gstate) + { + Gdip.CheckStatus(Gdip.GdipRestoreGraphics(new HandleRef(this, NativeGraphics), gstate.nativeState)); + PopContext(gstate.nativeState); + } + + public GraphicsContainer BeginContainer(RectangleF dstrect, RectangleF srcrect, GraphicsUnit unit) + { + GraphicsContext context = new GraphicsContext(this); + + int status = Gdip.GdipBeginContainer( + new HandleRef(this, NativeGraphics), ref dstrect, ref srcrect, unit, out int state); + + if (status != Gdip.Ok) + { + context.Dispose(); + throw Gdip.StatusException(status); + } + + context.State = state; + PushContext(context); + + return new GraphicsContainer(state); + } + + public GraphicsContainer BeginContainer() + { + GraphicsContext context = new GraphicsContext(this); + int status = Gdip.GdipBeginContainer2(new HandleRef(this, NativeGraphics), out int state); + + if (status != Gdip.Ok) + { + context.Dispose(); + throw Gdip.StatusException(status); + } + + context.State = state; + PushContext(context); + + return new GraphicsContainer(state); + } + + public void EndContainer(GraphicsContainer container) + { + ArgumentNullException.ThrowIfNull(container); + + Gdip.CheckStatus(Gdip.GdipEndContainer(new HandleRef(this, NativeGraphics), container.nativeGraphicsContainer)); + PopContext(container.nativeGraphicsContainer); + } + + public GraphicsContainer BeginContainer(Rectangle dstrect, Rectangle srcrect, GraphicsUnit unit) + { + GraphicsContext context = new GraphicsContext(this); + + int status = Gdip.GdipBeginContainerI( + new HandleRef(this, NativeGraphics), ref dstrect, ref srcrect, unit, out int state); + + if (status != Gdip.Ok) + { + context.Dispose(); + throw Gdip.StatusException(status); + } + + context.State = state; + PushContext(context); + + return new GraphicsContainer(state); + } + + public void AddMetafileComment(byte[] data) + { + ArgumentNullException.ThrowIfNull(data); + + Gdip.CheckStatus(Gdip.GdipComment(new HandleRef(this, NativeGraphics), data.Length, data)); + } + + public static IntPtr GetHalftonePalette() + { + if (s_halftonePalette == IntPtr.Zero) + { + lock (s_syncObject) + { + if (s_halftonePalette == IntPtr.Zero) + { + AppDomain.CurrentDomain.DomainUnload += OnDomainUnload; + AppDomain.CurrentDomain.ProcessExit += OnDomainUnload; + + s_halftonePalette = Gdip.GdipCreateHalftonePalette(); + } + } + } + return s_halftonePalette; + } + + // This is called from AppDomain.ProcessExit and AppDomain.DomainUnload. + private static void OnDomainUnload(object? sender, EventArgs e) + { + if (s_halftonePalette != IntPtr.Zero) + { + Interop.Gdi32.DeleteObject(s_halftonePalette); + s_halftonePalette = IntPtr.Zero; + } + } + + /// + /// GDI+ will return a 'generic error' with specific win32 last error codes when + /// a terminal server session has been closed, minimized, etc... We don't want + /// to throw when this happens, so we'll guard against this by looking at the + /// 'last win32 error code' and checking to see if it is either 1) access denied + /// or 2) proc not found and then ignore it. + /// + /// The problem is that when you lock the machine, the secure desktop is enabled and + /// rendering fails which is expected (since the app doesn't have permission to draw + /// on the secure desktop). Not sure if there's anything you can do, short of catching + /// the desktop switch message and absorbing all the exceptions that get thrown while + /// it's the secure desktop. + /// + private static void CheckErrorStatus(int status) + { + if (status == Gdip.Ok) + return; + + // Generic error from GDI+ can be GenericError or Win32Error. + if (status == Gdip.GenericError || status == Gdip.Win32Error) + { + int error = Marshal.GetLastWin32Error(); + if (error == SafeNativeMethods.ERROR_ACCESS_DENIED || error == SafeNativeMethods.ERROR_PROC_NOT_FOUND || + // Here, we'll check to see if we are in a terminal services session... + (((Interop.User32.GetSystemMetrics(NativeMethods.SM_REMOTESESSION) & 0x00000001) != 0) && (error == 0))) + { + return; + } + } + + // Legitimate error, throw our status exception. + throw Gdip.StatusException(status); + } } } diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Icon.Windows.COMWrappers.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Icon.ComWrappers.cs similarity index 100% rename from src/libraries/System.Drawing.Common/src/System/Drawing/Icon.Windows.COMWrappers.cs rename to src/libraries/System.Drawing.Common/src/System/Drawing/Icon.ComWrappers.cs diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Icon.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Icon.Unix.cs deleted file mode 100644 index 5b53e6924c751..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Icon.Unix.cs +++ /dev/null @@ -1,884 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// System.Drawing.Icon.cs -// -// Authors: -// Gary Barnett (gary.barnett.mono@gmail.com) -// Dennis Hayes (dennish@Raytek.com) -// Andreas Nahr (ClassDevelopment@A-SoftTech.com) -// Sanjay Gupta (gsanjay@novell.com) -// Peter Dennis Bartok (pbartok@novell.com) -// Sebastien Pouliot -// -// Copyright (C) 2002 Ximian, Inc. http://www.ximian.com -// Copyright (C) 2004-2008 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// 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.Collections; -using System.ComponentModel; -using System.Drawing.Imaging; -using System.IO; -using System.Reflection; -using System.Runtime.Serialization; -using System.Runtime.InteropServices; - -namespace System.Drawing -{ - [Editor("System.Drawing.Design.IconEditor, System.Drawing.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", - "System.Drawing.Design.UITypeEditor, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] - [TypeConverter(typeof(IconConverter))] - [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] - public sealed partial class Icon : MarshalByRefObject, ISerializable, ICloneable, IDisposable - { - // The PNG signature is specified at http://www.w3.org/TR/PNG/#5PNG-file-signature - private const uint PNGSignature1 = 137 + ('P' << 8) + ('N' << 16) + ('G' << 24); - private const uint PNGSignature2 = 13 + (10 << 8) + (26 << 16) + (10 << 24); - - [StructLayout(LayoutKind.Sequential)] - internal struct IconDirEntry - { - internal byte width; // Width of icon - internal byte height; // Height of icon - internal byte colorCount; // colors in icon - internal byte reserved; // Reserved - internal ushort planes; // Color Planes - internal ushort bitCount; // Bits per pixel - internal uint bytesInRes; // bytes in resource - internal uint imageOffset; // position in file - internal bool png; // for unsupported images (vista 256 png) - }; - - [StructLayout(LayoutKind.Sequential)] - internal struct IconDir - { - internal ushort idReserved; // Reserved - internal ushort idType; // resource type (1 for icons) - internal ushort idCount; // how many images? - internal IconDirEntry[] idEntries; // the entries for each image - }; - - [StructLayout(LayoutKind.Sequential)] - internal struct BitmapInfoHeader - { - internal uint biSize; - internal int biWidth; - internal int biHeight; - internal ushort biPlanes; - internal ushort biBitCount; - internal uint biCompression; - internal uint biSizeImage; - internal int biXPelsPerMeter; - internal int biYPelsPerMeter; - internal uint biClrUsed; - internal uint biClrImportant; - }; - - [StructLayout(LayoutKind.Sequential)] // added baseclass for non bmp image format support - internal abstract class ImageData - { - }; - - [StructLayout(LayoutKind.Sequential)] - internal sealed class IconImage : ImageData - { - internal BitmapInfoHeader iconHeader; //image header - internal uint[]? iconColors; //colors table - internal byte[]? iconXOR; // bits for XOR mask - internal byte[]? iconAND; //bits for AND mask - }; - - [StructLayout(LayoutKind.Sequential)] - internal sealed class IconDump : ImageData - { - internal byte[]? data; - }; - - private Size iconSize; - private IntPtr handle = IntPtr.Zero; - private IconDir iconDir; - private ushort id; - private ImageData[]? imageData; - private bool undisposable; - private bool disposed; - private Bitmap? bitmap; - - private Icon() - { - } - - private Icon(IntPtr handle) - { - this.handle = handle; - bitmap = Bitmap.FromHicon(handle); - iconSize = new Size(bitmap.Width, bitmap.Height); - bitmap = Bitmap.FromHicon(handle); - iconSize = new Size(bitmap.Width, bitmap.Height); - // FIXME: we need to convert the bitmap into an icon - undisposable = true; - } - - public Icon(Icon original, int width, int height) - : this(original, new Size(width, height)) - { - } - - public Icon(Icon original!!, Size size) - { - iconSize = size; - iconDir = original.iconDir; - - int count = iconDir.idCount; - if (count > 0) - { - imageData = original.imageData; - id = ushort.MaxValue; - - for (ushort i = 0; i < count; i++) - { - IconDirEntry ide = iconDir.idEntries[i]; - if (((ide.height == size.Height) || (ide.width == size.Width)) && !ide.png) - { - id = i; - break; - } - } - - // if a perfect match isn't found we look for the biggest icon *smaller* than specified - if (id == ushort.MaxValue) - { - int requested = Math.Min(size.Height, size.Width); - // previously best set to 1st image, as this might not be smallest changed loop to check all - IconDirEntry? best = null; - for (ushort i = 0; i < count; i++) - { - IconDirEntry ide = iconDir.idEntries[i]; - if (((ide.height < requested) || (ide.width < requested)) && !ide.png) - { - if (best == null) - { - best = ide; - id = i; - } - else if ((ide.height > best.Value.height) || (ide.width > best.Value.width)) - { - best = ide; - id = i; - } - } - } - } - - // last one, if nothing better can be found - if (id == ushort.MaxValue) - { - int i = count; - while (id == ushort.MaxValue && i > 0) - { - i--; - if (!iconDir.idEntries[i].png) - id = (ushort)i; - } - } - - if (id == ushort.MaxValue) - throw new ArgumentException(SR.NoValidIconImageFound, nameof(original)); - - iconSize.Height = iconDir.idEntries[id].height; - iconSize.Width = iconDir.idEntries[id].width; - } - else - { - iconSize.Height = size.Height; - iconSize.Width = size.Width; - } - - if (original.bitmap != null) - bitmap = (Bitmap)original.bitmap.Clone(); - } - - public Icon(Stream stream) : this(stream, 32, 32) - { - } - - public Icon(Stream stream, int width, int height) - { - InitFromStreamWithSize(stream, width, height); - } - - public Icon(string fileName) - { - using (FileStream fs = File.OpenRead(fileName)) - { - InitFromStreamWithSize(fs, 32, 32); - } - } - - public Icon(Type type, string resource!!) - { - // For compatibility with the .NET Framework - if (type == null) - throw new NullReferenceException(); - - using (Stream? s = type.Assembly.GetManifestResourceStream(type, resource)) - { - if (s == null) - { - throw new ArgumentException(null); - } - InitFromStreamWithSize(s, 32, 32); // 32x32 is default - } - } - - internal Icon(string resourceName, bool undisposable) - { - using (Stream? s = typeof(Icon).Assembly.GetManifestResourceStream(resourceName)) - { - if (s == null) - { - string msg = string.Format("Resource '{0}' was not found.", resourceName); - throw new FileNotFoundException(msg); - } - InitFromStreamWithSize(s, 32, 32); // 32x32 is default - } - this.undisposable = true; - } - - public Icon(Stream stream, Size size) : - this(stream, size.Width, size.Height) - { - } - - public Icon(string fileName, int width, int height) - { - using (FileStream fs = File.OpenRead(fileName)) - { - InitFromStreamWithSize(fs, width, height); - } - } - - public Icon(string fileName, Size size) - { - using (FileStream fs = File.OpenRead(fileName)) - { - InitFromStreamWithSize(fs, size.Width, size.Height); - } - } - - private Icon(SerializationInfo info, StreamingContext context) - { - byte[] iconData = (byte[])info.GetValue("IconData", typeof(byte[]))!; // Do not rename (binary serialization) - Size iconSize = (Size)info.GetValue("IconSize", typeof(Size))!; // Do not rename (binary serialization) - var dataStream = new MemoryStream(iconData); - - InitFromStreamWithSize(dataStream, iconSize.Width, iconSize.Height); - } - - void ISerializable.GetObjectData(SerializationInfo si, StreamingContext context) - { - MemoryStream ms = new MemoryStream(); - Save(ms); - si.AddValue("IconSize", this.Size, typeof(Size)); // Do not rename (binary serialization) - si.AddValue("IconData", ms.ToArray()); // Do not rename (binary serialization) - } - - public static Icon ExtractAssociatedIcon(string filePath!!) - { - if (string.IsNullOrEmpty(filePath)) - throw new ArgumentException(SR.NullOrEmptyPath, nameof(filePath)); - if (!File.Exists(filePath)) - throw new FileNotFoundException(SR.CouldntFindSpecifiedFile, filePath); - - return SystemIcons.WinLogo; - } - - public void Dispose() - { - // SystemIcons requires this - if (undisposable) - return; - - if (!disposed) - { - if (bitmap != null) - { - bitmap.Dispose(); - bitmap = null; - } - GC.SuppressFinalize(this); - } - disposed = true; - } - - public object Clone() - { - return new Icon(this, Size); - } - - public static Icon FromHandle(IntPtr handle) - { - if (handle == IntPtr.Zero) - throw new ArgumentException(null, nameof(handle)); - - return new Icon(handle); - } - - private static void SaveIconImage(BinaryWriter writer, IconImage ii) - { - BitmapInfoHeader bih = ii.iconHeader; - writer.Write(bih.biSize); - writer.Write(bih.biWidth); - writer.Write(bih.biHeight); - writer.Write(bih.biPlanes); - writer.Write(bih.biBitCount); - writer.Write(bih.biCompression); - writer.Write(bih.biSizeImage); - writer.Write(bih.biXPelsPerMeter); - writer.Write(bih.biYPelsPerMeter); - writer.Write(bih.biClrUsed); - writer.Write(bih.biClrImportant); - - //now write color table - int colCount = ii.iconColors!.Length; - for (int j = 0; j < colCount; j++) - writer.Write(ii.iconColors[j]); - - //now write XOR Mask - writer.Write(ii.iconXOR!); - - //now write AND Mask - writer.Write(ii.iconAND!); - } - - private static void SaveIconDump(BinaryWriter writer, IconDump id) - { - writer.Write(id.data!); - } - - private static void SaveIconDirEntry(BinaryWriter writer, IconDirEntry ide, uint offset) - { - writer.Write(ide.width); - writer.Write(ide.height); - writer.Write(ide.colorCount); - writer.Write(ide.reserved); - writer.Write(ide.planes); - writer.Write(ide.bitCount); - writer.Write(ide.bytesInRes); - writer.Write((offset == uint.MaxValue) ? ide.imageOffset : offset); - } - - private void SaveAll(BinaryWriter writer) - { - writer.Write(iconDir.idReserved); - writer.Write(iconDir.idType); - ushort count = iconDir.idCount; - writer.Write(count); - - for (int i = 0; i < (int)count; i++) - { - SaveIconDirEntry(writer, iconDir.idEntries[i], uint.MaxValue); - } - - for (int i = 0; i < (int)count; i++) - { - - //FIXME: HACK: 1 (out of the 8) vista type icons had additional bytes (value:0) - //between images. This fixes the issue, but perhaps shouldnt include in production? - while (writer.BaseStream.Length < iconDir.idEntries[i].imageOffset) - writer.Write((byte)0); - - if (imageData![i] is IconDump) - SaveIconDump(writer, (IconDump)imageData[i]); - else - SaveIconImage(writer, (IconImage)imageData[i]); - } - } - // TODO: check image not png (presently this method doesnt seem to be called unless width/height - // refer to image) - private void SaveBestSingleIcon(BinaryWriter writer, int width, int height) - { - writer.Write(iconDir.idReserved); - writer.Write(iconDir.idType); - writer.Write((ushort)1); - - // find best entry and save it - int best = 0; - int bitCount = 0; - for (int i = 0; i < iconDir.idCount; i++) - { - IconDirEntry ide = iconDir.idEntries[i]; - if ((width == ide.width) && (height == ide.height)) - { - if (ide.bitCount >= bitCount) - { - bitCount = ide.bitCount; - best = i; - } - } - } - - SaveIconDirEntry(writer, iconDir.idEntries[best], 22); - SaveIconImage(writer, (IconImage)imageData![best]); - } - - private unsafe void SaveBitmapAsIcon(BinaryWriter writer) - { - writer.Write((ushort)0); // idReserved must be 0 - writer.Write((ushort)1); // idType must be 1 - writer.Write((ushort)1); // only one icon - - // when transformed into a bitmap only a single image exists - IconDirEntry ide = default; - ide.width = (byte)bitmap!.Width; - ide.height = (byte)bitmap.Height; - ide.colorCount = 0; // 32 bbp == 0, for palette size - ide.reserved = 0; // always 0 - ide.planes = 0; - ide.bitCount = 32; - ide.imageOffset = 22; // 22 is the first icon position (for single icon files) - - BitmapInfoHeader bih = default; - bih.biSize = (uint)sizeof(BitmapInfoHeader); - bih.biWidth = bitmap.Width; - bih.biHeight = 2 * bitmap.Height; // include both XOR and AND images - bih.biPlanes = 1; - bih.biBitCount = 32; - bih.biCompression = 0; - bih.biSizeImage = 0; - bih.biXPelsPerMeter = 0; - bih.biYPelsPerMeter = 0; - bih.biClrUsed = 0; - bih.biClrImportant = 0; - - IconImage ii = new IconImage(); - ii.iconHeader = bih; - ii.iconColors = Array.Empty(); // no palette - int xor_size = (((bih.biBitCount * bitmap.Width + 31) & ~31) >> 3) * bitmap.Height; - ii.iconXOR = new byte[xor_size]; - int p = 0; - for (int y = bitmap.Height - 1; y >= 0; y--) - { - for (int x = 0; x < bitmap.Width; x++) - { - Color c = bitmap.GetPixel(x, y); - ii.iconXOR[p++] = c.B; - ii.iconXOR[p++] = c.G; - ii.iconXOR[p++] = c.R; - ii.iconXOR[p++] = c.A; - } - } - int and_line_size = (((Width + 31) & ~31) >> 3); // must be a multiple of 4 bytes - int and_size = and_line_size * bitmap.Height; - ii.iconAND = new byte[and_size]; - - ide.bytesInRes = (uint)(bih.biSize + xor_size + and_size); - - SaveIconDirEntry(writer, ide, uint.MaxValue); - SaveIconImage(writer, ii); - } - - private void Save(Stream outputStream, int width, int height) - { - BinaryWriter writer = new BinaryWriter(outputStream); - // if we have the icon information then save from this - if (iconDir.idEntries != null) - { - if ((width == -1) && (height == -1)) - SaveAll(writer); - else - SaveBestSingleIcon(writer, width, height); - } - else if (bitmap != null) - { - // if the icon was created from a bitmap then convert it - SaveBitmapAsIcon(writer); - } - writer.Flush(); - } - - public void Save(Stream outputStream) - { - if (outputStream == null) - throw new NullReferenceException(nameof(outputStream)); - - // save every icons available - Save(outputStream, -1, -1); - } - - internal Bitmap BuildBitmapOnWin32() - { - Bitmap bmp; - - if (imageData == null) - return new Bitmap(32, 32); - - IconImage ii = (IconImage)imageData[id]; - BitmapInfoHeader bih = ii.iconHeader; - int biHeight = bih.biHeight / 2; - - switch (bih.biBitCount) - { - case 1: - bmp = new Bitmap(bih.biWidth, biHeight, PixelFormat.Format1bppIndexed); - break; - case 4: - bmp = new Bitmap(bih.biWidth, biHeight, PixelFormat.Format4bppIndexed); - break; - case 8: - bmp = new Bitmap(bih.biWidth, biHeight, PixelFormat.Format8bppIndexed); - break; - case 24: - bmp = new Bitmap(bih.biWidth, biHeight, PixelFormat.Format24bppRgb); - break; - case 32: - bmp = new Bitmap(bih.biWidth, biHeight, PixelFormat.Format32bppArgb); - break; - default: - string msg = string.Format("Unexpected number of bits: {0}", bih.biBitCount); - throw new Exception(msg); - } - - if (bih.biBitCount < 24) - { - ColorPalette pal = bmp.Palette; // Managed palette - - for (int i = 0; i < ii.iconColors!.Length; i++) - { - pal.Entries[i] = Color.FromArgb((int)ii.iconColors[i] | unchecked((int)0xff000000)); - } - bmp.Palette = pal; - } - - int bytesPerLine = (int)((((bih.biWidth * bih.biBitCount) + 31) & ~31) >> 3); - BitmapData bits = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, bmp.PixelFormat); - - for (int y = 0; y < biHeight; y++) - { - Marshal.Copy(ii.iconXOR!, bytesPerLine * y, - (IntPtr)(bits.Scan0.ToInt64() + bits.Stride * (biHeight - 1 - y)), bytesPerLine); - } - - bmp.UnlockBits(bits); - - bmp = new Bitmap(bmp); // This makes a 32bpp image out of an indexed one - - // Apply the mask to make properly transparent - bytesPerLine = (int)((((bih.biWidth) + 31) & ~31) >> 3); - for (int y = 0; y < biHeight; y++) - { - for (int x = 0; x < bih.biWidth / 8; x++) - { - for (int bit = 7; bit >= 0; bit--) - { - if (((ii.iconAND![y * bytesPerLine + x] >> bit) & 1) != 0) - { - bmp.SetPixel(x * 8 + 7 - bit, biHeight - y - 1, Color.Transparent); - } - } - } - } - - return bmp; - } - - internal Bitmap GetInternalBitmap() - { - if (bitmap == null) - { - // Mono's libgdiplus doesn't require to keep the stream alive when loading images - using (MemoryStream ms = new MemoryStream()) - { - // save the current icon - Save(ms, Width, Height); - ms.Position = 0; - - // libgdiplus can now decode icons - bitmap = (Bitmap)Image.LoadFromStream(ms, false); - } - } - return bitmap; - } - - // note: all bitmaps are 32bits ARGB - no matter what the icon format (bitcount) was - public Bitmap ToBitmap() - { - if (disposed) - throw new ObjectDisposedException(SR.IconInstanceWasDisposed); - - // note: we can't return the original image because - // (a) we have no control over the bitmap instance we return (i.e. it could be disposed) - // (b) the palette, flags won't match MS results. See MonoTests.System.Drawing.Imaging.IconCodecTest. - // Image16 for the differences - return new Bitmap(GetInternalBitmap()); - } - - public override string ToString() - { - //is this correct, this is what returned by .Net - return ""; - } - - [Browsable(false)] - public IntPtr Handle - { - get - { - if (disposed) - { - throw new ObjectDisposedException(GetType().Name); - } - - // note: this handle doesn't survive the lifespan of the icon instance - if (handle == IntPtr.Zero) - { - handle = GetInternalBitmap().nativeImage; - } - return handle; - } - } - - [Browsable(false)] - public int Height - { - get - { - if (disposed) - { - throw new ObjectDisposedException(GetType().Name); - } - - return iconSize.Height; - } - } - - public Size Size - { - get - { - if (disposed) - { - throw new ObjectDisposedException(GetType().Name); - } - - return iconSize; - } - } - - [Browsable(false)] - public int Width - { - get - { - if (disposed) - { - throw new ObjectDisposedException(GetType().Name); - } - - return iconSize.Width; - } - } - - ~Icon() - { - Dispose(); - } - - private void InitFromStreamWithSize(Stream stream!!, int width, int height) - { - if (stream.Length == 0) - throw new ArgumentException(SR.Format(SR.InvalidPictureType, "picture", nameof(stream))); - - bool sizeObtained = false; - ushort dirEntryCount; - // Read the icon header - using (var reader = new BinaryReader(stream)) - { - iconDir.idReserved = reader.ReadUInt16(); - if (iconDir.idReserved != 0) //must be 0 - throw new ArgumentException(SR.Format(SR.InvalidPictureType, "picture", nameof(stream))); - - iconDir.idType = reader.ReadUInt16(); - if (iconDir.idType != 1) //must be 1 - throw new ArgumentException(SR.Format(SR.InvalidPictureType, "picture", nameof(stream))); - - dirEntryCount = reader.ReadUInt16(); - imageData = new ImageData[dirEntryCount]; - iconDir.idCount = dirEntryCount; - iconDir.idEntries = new IconDirEntry[dirEntryCount]; - // Now read in the IconDirEntry structures - for (int i = 0; i < dirEntryCount; i++) - { - var ide = new IconDirEntry - { - width = reader.ReadByte(), - height = reader.ReadByte(), - colorCount = reader.ReadByte(), - reserved = reader.ReadByte(), - planes = reader.ReadUInt16(), - bitCount = reader.ReadUInt16(), - bytesInRes = reader.ReadUInt32(), - imageOffset = reader.ReadUInt32() - }; - - // Vista 256x256 icons points directly to a PNG bitmap - // 256x256 icons are decoded as 0x0 (width and height are encoded as BYTE) - // We mark them as png and later on we just store the raw bytes to be able to save to a file. - ide.png = (ide.width == 0) && (ide.height == 0); - - iconDir.idEntries[i] = ide; - - if (!sizeObtained) - { - if (((ide.height == height) || (ide.width == width)) && !ide.png) - { - this.id = (ushort)i; - sizeObtained = true; - this.iconSize.Height = ide.height; - this.iconSize.Width = ide.width; - } - } - } - - // If we havent found the best match, return the one with the largest size. - if (!sizeObtained) - { - uint largestSize = 0; - for (int j = 0; j < dirEntryCount; j++) - { - if (iconDir.idEntries[j].bytesInRes >= largestSize && !iconDir.idEntries[j].png) - { - largestSize = iconDir.idEntries[j].bytesInRes; - this.id = (ushort)j; - this.iconSize.Height = iconDir.idEntries[j].height; - this.iconSize.Width = iconDir.idEntries[j].width; - } - } - } - - // Now read in the icon data - bool valid = false; - for (int j = 0; j < dirEntryCount; j++) - { - stream.Seek(iconDir.idEntries[j].imageOffset, SeekOrigin.Begin); - byte[] buffer = new byte[iconDir.idEntries[j].bytesInRes]; - stream.Read(buffer, 0, buffer.Length); - using (var bihReader = new BinaryReader(new MemoryStream(buffer))) - { - uint headerSize = bihReader.ReadUInt32(); - int headerWidth = bihReader.ReadInt32(); - - // Process PNG images into IconDump - if (iconDir.idEntries[j].png || (headerSize == PNGSignature1 && headerWidth == (int)PNGSignature2)) - { - IconDump id = new IconDump(); - id.data = buffer; - imageData[j] = id; - iconDir.idEntries[j].png = true; - continue; - } - - // We found a valid icon BMP entry. - valid = true; - - var bih = new BitmapInfoHeader - { - biSize = headerSize, - biWidth = headerWidth, - biHeight = bihReader.ReadInt32(), - biPlanes = bihReader.ReadUInt16(), - biBitCount = bihReader.ReadUInt16(), - biCompression = bihReader.ReadUInt32(), - biSizeImage = bihReader.ReadUInt32(), - biXPelsPerMeter = bihReader.ReadInt32(), - biYPelsPerMeter = bihReader.ReadInt32(), - biClrUsed = bihReader.ReadUInt32(), - biClrImportant = bihReader.ReadUInt32() - }; - var iidata = new IconImage - { - iconHeader = bih - }; - // Read the number of colors used and corresponding memory occupied by - // color table. Fill this memory chunk into rgbquad[] - int numColors; - switch (bih.biBitCount) - { - case 1: - numColors = 2; - break; - case 4: - numColors = 16; - break; - case 8: - numColors = 256; - break; - default: - numColors = 0; - break; - } - - iidata.iconColors = new uint[numColors]; - for (int i = 0; i < numColors; i++) - iidata.iconColors[i] = bihReader.ReadUInt32(); - - //XOR mask is immediately after ColorTable and its size is - //icon height* no. of bytes per line - - //icon height is half of BITMAPINFOHEADER.biHeight, since it contains - //both XOR as well as AND mask bytes - int iconHeight = bih.biHeight / 2; - - //bytes per line should be uint aligned - int numBytesPerLine = checked((((bih.biWidth * bih.biPlanes * bih.biBitCount) + 31) >> 5) << 2); - - //Determine the XOR array Size - int xorSize = checked(numBytesPerLine * iconHeight); - iidata.iconXOR = new byte[xorSize]; - int nread = bihReader.Read(iidata.iconXOR, 0, xorSize); - if (nread != xorSize) - { - throw new ArgumentException(SR.Format(SR.IconInvalidMaskLength, "XOR", xorSize, nread), nameof(stream)); - } - - //Determine the AND array size - numBytesPerLine = checked((((bih.biWidth) + 31) & ~31) >> 3); - int andSize = checked(numBytesPerLine * iconHeight); - iidata.iconAND = new byte[andSize]; - nread = bihReader.Read(iidata.iconAND, 0, andSize); - if (nread != andSize) - { - throw new ArgumentException(SR.Format(SR.IconInvalidMaskLength, "AND", andSize, nread), nameof(stream)); - } - - imageData[j] = iidata; - } - } - - // Throw error if no valid entries found - if (!valid) - throw new Win32Exception(SafeNativeMethods.ERROR_INVALID_PARAMETER, SR.Format(SR.InvalidPictureType, "picture", nameof(stream))); - } - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Icon.Windows.NoCOMWrappers.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Icon.Windows.NoCOMWrappers.cs deleted file mode 100644 index aa78cd03d8621..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Icon.Windows.NoCOMWrappers.cs +++ /dev/null @@ -1,115 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics; -using System.Drawing.Internal; -using System.IO; -using System.Runtime.InteropServices; -using System.Runtime.Serialization; - -namespace System.Drawing -{ - public sealed partial class Icon : MarshalByRefObject, ICloneable, IDisposable, ISerializable - { - public void Save(Stream outputStream) - { - if (_iconData != null) - { - ArgumentNullException.ThrowIfNull(outputStream); - outputStream.Write(_iconData, 0, _iconData.Length); - } - else - { - // Ideally, we would pick apart the icon using - // GetIconInfo, and then pull the individual bitmaps out, - // converting them to DIBS and saving them into the file. - // But, in the interest of simplicity, we just call to - // OLE to do it for us. - PICTDESC pictdesc = PICTDESC.CreateIconPICTDESC(Handle); - Guid g = typeof(IPicture).GUID; - IntPtr iPicturePtr = OleCreatePictureIndirect(pictdesc, ref g, false); - if (iPicturePtr != IntPtr.Zero) - { - IPicture picture = (IPicture)Marshal.GetObjectForIUnknown(iPicturePtr); - Marshal.Release(iPicturePtr); - try - { - ArgumentNullException.ThrowIfNull(outputStream); - picture.SaveAsFile(new GPStream(outputStream, makeSeekable: false), -1, out int temp); - } - finally - { - Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); - Marshal.ReleaseComObject(picture); - } - } - } - } - - [LibraryImport(Interop.Libraries.Oleaut32, PreserveSig = false)] - internal static partial IntPtr OleCreatePictureIndirect(in PICTDESC pictdesc, in Guid refiid, bool fOwn); - - [ComImport] - [Guid("7BF80980-BF32-101A-8BBB-00AA00300CAB")] - [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - internal interface IPicture - { - IntPtr GetHandle(); - - IntPtr GetHPal(); - - [return: MarshalAs(UnmanagedType.I2)] - short GetPictureType(); - - int GetWidth(); - - int GetHeight(); - - void Render(); - - void SetHPal([In] IntPtr phpal); - - IntPtr GetCurDC(); - - void SelectPicture([In] IntPtr hdcIn, - [Out, MarshalAs(UnmanagedType.LPArray)] int[] phdcOut, - [Out, MarshalAs(UnmanagedType.LPArray)] int[] phbmpOut); - - [return: MarshalAs(UnmanagedType.Bool)] - bool GetKeepOriginalFormat(); - - void SetKeepOriginalFormat([In, MarshalAs(UnmanagedType.Bool)] bool pfkeep); - - void PictureChanged(); - - [PreserveSig] - int SaveAsFile([In, MarshalAs(UnmanagedType.Interface)] Interop.Ole32.IStream pstm, - [In] int fSaveMemCopy, - [Out] out int pcbSize); - - int GetAttributes(); - - void SetHdc([In] IntPtr hdc); - } - - [StructLayout(LayoutKind.Sequential)] - internal struct PICTDESC - { - internal int cbSizeOfStruct; - public int picType; - internal IntPtr union1; - internal int union2; - internal int union3; - - public static PICTDESC CreateIconPICTDESC(IntPtr hicon) - { - return new PICTDESC() - { - cbSizeOfStruct = 12, - picType = Ole.PICTYPE_ICON, - union1 = hicon - }; - } - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Icon.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Icon.cs similarity index 98% rename from src/libraries/System.Drawing.Common/src/System/Drawing/Icon.Windows.cs rename to src/libraries/System.Drawing.Common/src/System/Drawing/Icon.cs index 885e2668c40f0..cb4c250cec555 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Icon.Windows.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Icon.cs @@ -82,8 +82,10 @@ public Icon(Icon original, Size size) : this(original, size.Width, size.Height) { } - public Icon(Icon original!!, int width, int height) : this() + public Icon(Icon original, int width, int height) : this() { + ArgumentNullException.ThrowIfNull(original); + _iconData = original._iconData; if (_iconData == null) @@ -97,8 +99,10 @@ public Icon(Icon original!!, int width, int height) : this() } } - public Icon(Type type, string resource!!) : this() + public Icon(Type type, string resource) : this() { + ArgumentNullException.ThrowIfNull(resource); + Stream? stream = type.Module.Assembly.GetManifestResourceStream(type, resource); if (stream == null) { @@ -118,8 +122,10 @@ public Icon(Stream stream, Size size) : this(stream, size.Width, size.Height) { } - public Icon(Stream stream!!, int width, int height) : this() + public Icon(Stream stream, int width, int height) : this() { + ArgumentNullException.ThrowIfNull(stream); + _iconData = new byte[(int)stream.Length]; stream.Read(_iconData, 0, _iconData.Length); Initialize(width, height); @@ -150,8 +156,9 @@ void ISerializable.GetObjectData(SerializationInfo si, StreamingContext context) public static Icon? ExtractAssociatedIcon(string filePath) => ExtractAssociatedIcon(filePath, 0); - private static unsafe Icon? ExtractAssociatedIcon(string filePath!!, int index) + private static unsafe Icon? ExtractAssociatedIcon(string filePath, int index) { + ArgumentNullException.ThrowIfNull(filePath); if (string.IsNullOrEmpty(filePath)) throw new ArgumentException(SR.NullOrEmptyPath, nameof(filePath)); diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Image.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Image.Unix.cs deleted file mode 100644 index 8879db8a8e9a3..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Image.Unix.cs +++ /dev/null @@ -1,333 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// System.Drawing.Image.cs -// -// Authors: Christian Meyer (Christian.Meyer@cs.tum.edu) -// Alexandre Pigolkine (pigolkine@gmx.de) -// Jordi Mas i Hernandez (jordi@ximian.com) -// Sanjay Gupta (gsanjay@novell.com) -// Ravindra (rkumar@novell.com) -// Sebastien Pouliot -// -// Copyright (C) 2002 Ximian, Inc. http://www.ximian.com -// Copyright (C) 2004, 2007 Novell, Inc (http://www.novell.com) -// Copyright (C) 2013 Kristof Ralovich, changes are available under the terms of the MIT X11 license -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// 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.Runtime.Serialization; -using System.Runtime.InteropServices; -using System.ComponentModel; -using System.Drawing.Imaging; -using System.IO; -using System.Reflection; -using Gdip = System.Drawing.SafeNativeMethods.Gdip; - -namespace System.Drawing -{ - public abstract partial class Image - { - // public methods - // static - - // See http://support.microsoft.com/default.aspx?scid=kb;en-us;831419 for performance discussion - public static Image FromStream(Stream stream, bool useEmbeddedColorManagement, bool validateImageData) - { - return LoadFromStream(stream, false); - } - - internal static Image LoadFromStream(Stream stream!!, bool keepAlive) - { - Image img = CreateImageObject(InitializeFromStream(stream)); - return img; - } - - private protected static IntPtr InitializeFromStream(Stream stream!!) - { - // Unix, with libgdiplus - // We use a custom API for this, because there's no easy way - // to get the Stream down to libgdiplus. So, we wrap the stream - // with a set of delegates. - GdiPlusStreamHelper sh = new GdiPlusStreamHelper(stream, seekToOrigin: true); - - int st = Gdip.GdipLoadImageFromDelegate_linux(sh.GetHeaderDelegate, sh.GetBytesDelegate, - sh.PutBytesDelegate, sh.SeekDelegate, sh.CloseDelegate, sh.SizeDelegate, out IntPtr imagePtr); - - // Since we're just passing to native code the delegates inside the wrapper, we need to keep sh alive - // to avoid the object being collected and therefore the delegates would be collected as well. - GC.KeepAlive(sh); - Gdip.CheckStatus(st); - return imagePtr; - } - - // non-static - public RectangleF GetBounds(ref GraphicsUnit pageUnit) - { - RectangleF source; - - int status = Gdip.GdipGetImageBounds(nativeImage, out source, ref pageUnit); - Gdip.CheckStatus(status); - - return source; - } - - public Image GetThumbnailImage(int thumbWidth, int thumbHeight, Image.GetThumbnailImageAbort? callback, IntPtr callbackData) - { - if ((thumbWidth <= 0) || (thumbHeight <= 0)) - throw new OutOfMemoryException(SR.InvalidThumbnailSize); - - Image ThumbNail = new Bitmap(thumbWidth, thumbHeight); - - using (Graphics g = Graphics.FromImage(ThumbNail)) - { - int status = Gdip.GdipDrawImageRectRectI( - new HandleRef(this, g.NativeGraphics), - new HandleRef(this, nativeImage), - 0, 0, thumbWidth, thumbHeight, - 0, 0, this.Width, this.Height, - GraphicsUnit.Pixel, - new HandleRef(this, IntPtr.Zero), null, - new HandleRef(this, IntPtr.Zero)); - - Gdip.CheckStatus(status); - } - - return ThumbNail; - } - - internal static ImageCodecInfo? FindEncoderForFormat(ImageFormat format) - { - ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders(); - ImageCodecInfo? encoder = null; - - if (format.Guid.Equals(ImageFormat.MemoryBmp.Guid)) - format = ImageFormat.Png; - - /* Look for the right encoder for our format*/ - for (int i = 0; i < encoders.Length; i++) - { - if (encoders[i].FormatID.Equals(format.Guid)) - { - encoder = encoders[i]; - break; - } - } - - return encoder; - } - - public void Save(string filename, ImageFormat format) - { - ImageCodecInfo? encoder = FindEncoderForFormat(format); - if (encoder == null) - { - // second chance - encoder = FindEncoderForFormat(RawFormat); - if (encoder == null) - { - string msg = string.Format("No codec available for saving format '{0}'.", format.Guid); - throw new ArgumentException(msg, nameof(format)); - } - } - Save(filename, encoder, null); - } - - public void Save(string filename!!, ImageCodecInfo encoder, EncoderParameters? encoderParams) - { - ThrowIfDirectoryDoesntExist(filename); - - int st; - Guid guid = encoder.Clsid; - - if (encoderParams == null) - { - st = Gdip.GdipSaveImageToFile(nativeImage, filename, ref guid, IntPtr.Zero); - } - else - { - IntPtr nativeEncoderParams = encoderParams.ConvertToMemory(); - st = Gdip.GdipSaveImageToFile(nativeImage, filename, ref guid, nativeEncoderParams); - Marshal.FreeHGlobal(nativeEncoderParams); - } - - Gdip.CheckStatus(st); - } - - private void Save(MemoryStream stream) - { - // Jpeg loses data, so we don't want to use it to serialize... - ImageFormat dest = RawFormat; - if (dest.Guid == ImageFormat.Jpeg.Guid) - dest = ImageFormat.Png; - - // If we don't find an Encoder (for things like Icon), we just switch back to PNG... - ImageCodecInfo codec = FindEncoderForFormat(dest) ?? FindEncoderForFormat(ImageFormat.Png)!; - - Save(stream, codec, null); - } - - public void Save(Stream stream, ImageFormat format) - { - ImageCodecInfo? encoder = FindEncoderForFormat(format); - - if (encoder == null) - throw new ArgumentException(SR.Format(SR.NoCodecAvailableForFormat, format.Guid)); - - Save(stream, encoder, null); - } - - public void Save(Stream stream, ImageCodecInfo encoder, EncoderParameters? encoderParams) - { - int st; - IntPtr nativeEncoderParams; - Guid guid = encoder.Clsid; - - if (encoderParams == null) - nativeEncoderParams = IntPtr.Zero; - else - nativeEncoderParams = encoderParams.ConvertToMemory(); - - try - { - GdiPlusStreamHelper sh = new GdiPlusStreamHelper(stream, seekToOrigin: false, makeSeekable: false); - st = Gdip.GdipSaveImageToDelegate_linux(nativeImage, sh.GetBytesDelegate, sh.PutBytesDelegate, - sh.SeekDelegate, sh.CloseDelegate, sh.SizeDelegate, ref guid, nativeEncoderParams); - - // Since we're just passing to native code the delegates inside the wrapper, we need to keep sh alive - // to avoid the object being collected and therefore the delegates would be collected as well. - GC.KeepAlive(sh); - } - finally - { - if (nativeEncoderParams != IntPtr.Zero) - Marshal.FreeHGlobal(nativeEncoderParams); - } - - Gdip.CheckStatus(st); - } - - public void SaveAdd(EncoderParameters encoderParams) - { - int st; - - IntPtr nativeEncoderParams = encoderParams.ConvertToMemory(); - st = Gdip.GdipSaveAdd(nativeImage, nativeEncoderParams); - Marshal.FreeHGlobal(nativeEncoderParams); - Gdip.CheckStatus(st); - } - - public void SaveAdd(Image image, EncoderParameters encoderParams) - { - int st; - - IntPtr nativeEncoderParams = encoderParams.ConvertToMemory(); - st = Gdip.GdipSaveAddImage(nativeImage, image.nativeImage, nativeEncoderParams); - Marshal.FreeHGlobal(nativeEncoderParams); - Gdip.CheckStatus(st); - } - - [Browsable(false)] - public ColorPalette Palette - { - get - { - return retrieveGDIPalette(); - } - set - { - storeGDIPalette(value); - } - } - - internal ColorPalette retrieveGDIPalette() - { - int bytes; - ColorPalette ret = new ColorPalette(); - - int st = Gdip.GdipGetImagePaletteSize(nativeImage, out bytes); - Gdip.CheckStatus(st); - IntPtr palette_data = Marshal.AllocHGlobal(bytes); - try - { - st = Gdip.GdipGetImagePalette(nativeImage, palette_data, bytes); - Gdip.CheckStatus(st); - ret.ConvertFromMemory(palette_data); - return ret; - } - - finally - { - Marshal.FreeHGlobal(palette_data); - } - } - - internal void storeGDIPalette(ColorPalette palette!!) - { - IntPtr palette_data = palette.ConvertToMemory(); - if (palette_data == IntPtr.Zero) - { - return; - } - - try - { - int st = Gdip.GdipSetImagePalette(nativeImage, palette_data); - Gdip.CheckStatus(st); - } - - finally - { - Marshal.FreeHGlobal(palette_data); - } - } - - protected virtual void Dispose(bool disposing) - { - if (nativeImage != IntPtr.Zero) - { - int status = Gdip.GdipDisposeImage(new HandleRef(this, nativeImage)); - // ... set nativeImage to null before (possibly) throwing an exception - nativeImage = IntPtr.Zero; - Gdip.CheckStatus(status); - } - } - - public object Clone() - { - IntPtr newimage; - int status = Gdip.GdipCloneImage(nativeImage, out newimage); - Gdip.CheckStatus(status); - - if (this is Bitmap) - return new Bitmap(newimage); - else - return new Metafile(newimage); - } - - internal static void ValidateImage(IntPtr bitmap) - { - // No validation is performed on Unix. - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Image.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Image.Windows.cs deleted file mode 100644 index 2e625f36e9b55..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Image.Windows.cs +++ /dev/null @@ -1,391 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Diagnostics; -using System.Drawing.Imaging; -using System.Drawing.Internal; -using System.Globalization; -using System.IO; -using System.Runtime.InteropServices; -using Gdip = System.Drawing.SafeNativeMethods.Gdip; - -namespace System.Drawing -{ - public abstract partial class Image - { -#if FINALIZATION_WATCH - private string allocationSite = Graphics.GetAllocationStack(); -#endif - - public static Image FromStream(Stream stream!!, bool useEmbeddedColorManagement, bool validateImageData) - { - IntPtr image = LoadGdipImageFromStream(new GPStream(stream), useEmbeddedColorManagement); - - if (validateImageData) - ValidateImage(image); - - Image img = CreateImageObject(image); - EnsureSave(img, null, stream); - return img; - } - - // Used for serialization - private IntPtr InitializeFromStream(Stream stream) - { - IntPtr image = LoadGdipImageFromStream(new GPStream(stream), useEmbeddedColorManagement: false); - ValidateImage(image); - - nativeImage = image; - - Gdip.CheckStatus(Gdip.GdipGetImageType(new HandleRef(this, nativeImage), out _)); - EnsureSave(this, null, stream); - return image; - } - - private static unsafe IntPtr LoadGdipImageFromStream(GPStream stream, bool useEmbeddedColorManagement) - { - using DrawingCom.IStreamWrapper streamWrapper = DrawingCom.GetComWrapper(stream); - - IntPtr image = IntPtr.Zero; - if (useEmbeddedColorManagement) - { - Gdip.CheckStatus(Gdip.GdipLoadImageFromStreamICM(streamWrapper.Ptr, &image)); - } - else - { - Gdip.CheckStatus(Gdip.GdipLoadImageFromStream(streamWrapper.Ptr, &image)); - } - return image; - } - - internal Image(IntPtr nativeImage) => SetNativeImage(nativeImage); - - /// - /// Creates an exact copy of this . - /// - public object Clone() - { - IntPtr cloneImage; - - Gdip.CheckStatus(Gdip.GdipCloneImage(new HandleRef(this, nativeImage), out cloneImage)); - ValidateImage(cloneImage); - - return CreateImageObject(cloneImage); - } - - protected virtual void Dispose(bool disposing) - { -#if FINALIZATION_WATCH - if (!disposing && nativeImage != IntPtr.Zero) - Debug.WriteLine("**********************\nDisposed through finalization:\n" + allocationSite); -#endif - if (nativeImage == IntPtr.Zero) - return; - - try - { -#if DEBUG - int status = !Gdip.Initialized ? Gdip.Ok : -#endif - Gdip.GdipDisposeImage(new HandleRef(this, nativeImage)); -#if DEBUG - Debug.Assert(status == Gdip.Ok, $"GDI+ returned an error status: {status.ToString(CultureInfo.InvariantCulture)}"); -#endif - } - catch (Exception ex) - { - if (ClientUtils.IsSecurityOrCriticalException(ex)) - { - throw; - } - - Debug.Fail("Exception thrown during Dispose: " + ex.ToString()); - } - finally - { - nativeImage = IntPtr.Zero; - } - } - - /// - /// Saves this to the specified file in the specified format. - /// - public void Save(string filename, ImageFormat format!!) - { - ImageCodecInfo? codec = format.FindEncoder(); - - if (codec == null) - codec = ImageFormat.Png.FindEncoder()!; - - Save(filename, codec, null); - } - - /// - /// Saves this to the specified file in the specified format and with the specified encoder parameters. - /// - public void Save(string filename!!, ImageCodecInfo encoder!!, EncoderParameters? encoderParams) - { - ThrowIfDirectoryDoesntExist(filename); - - IntPtr encoderParamsMemory = IntPtr.Zero; - - if (encoderParams != null) - { - _rawData = null; - encoderParamsMemory = encoderParams.ConvertToMemory(); - } - - try - { - Guid g = encoder.Clsid; - bool saved = false; - - if (_rawData != null) - { - ImageCodecInfo? rawEncoder = RawFormat.FindEncoder(); - if (rawEncoder != null && rawEncoder.Clsid == g) - { - using (FileStream fs = File.OpenWrite(filename)) - { - fs.Write(_rawData, 0, _rawData.Length); - saved = true; - } - } - } - - if (!saved) - { - Gdip.CheckStatus(Gdip.GdipSaveImageToFile( - new HandleRef(this, nativeImage), - filename, - ref g, - new HandleRef(encoderParams, encoderParamsMemory))); - } - } - finally - { - if (encoderParamsMemory != IntPtr.Zero) - { - Marshal.FreeHGlobal(encoderParamsMemory); - } - } - } - - private void Save(MemoryStream stream) - { - // Jpeg loses data, so we don't want to use it to serialize... - ImageFormat dest = RawFormat; - if (dest.Guid == ImageFormat.Jpeg.Guid) - dest = ImageFormat.Png; - - // If we don't find an Encoder (for things like Icon), we just switch back to PNG... - ImageCodecInfo codec = dest.FindEncoder() ?? ImageFormat.Png.FindEncoder()!; - - Save(stream, codec, null); - } - - /// - /// Saves this to the specified stream in the specified format. - /// - public void Save(Stream stream, ImageFormat format!!) - { - ImageCodecInfo codec = format.FindEncoder()!; - Save(stream, codec, null); - } - - /// - /// Saves this to the specified stream in the specified format. - /// - public void Save(Stream stream!!, ImageCodecInfo encoder!!, EncoderParameters? encoderParams) - { - IntPtr encoderParamsMemory = IntPtr.Zero; - - if (encoderParams != null) - { - _rawData = null; - encoderParamsMemory = encoderParams.ConvertToMemory(); - } - - try - { - Guid g = encoder.Clsid; - bool saved = false; - - if (_rawData != null) - { - ImageCodecInfo? rawEncoder = RawFormat.FindEncoder(); - if (rawEncoder != null && rawEncoder.Clsid == g) - { - stream.Write(_rawData, 0, _rawData.Length); - saved = true; - } - } - - if (!saved) - { - using DrawingCom.IStreamWrapper streamWrapper = DrawingCom.GetComWrapper(new GPStream(stream, makeSeekable: false)); - unsafe - { - Gdip.CheckStatus(Gdip.GdipSaveImageToStream( - new HandleRef(this, nativeImage), - streamWrapper.Ptr, - &g, - new HandleRef(encoderParams, encoderParamsMemory))); - } - } - } - finally - { - if (encoderParamsMemory != IntPtr.Zero) - { - Marshal.FreeHGlobal(encoderParamsMemory); - } - } - } - - /// - /// Adds an to this . - /// - public void SaveAdd(EncoderParameters? encoderParams) - { - IntPtr encoder = IntPtr.Zero; - if (encoderParams != null) - encoder = encoderParams.ConvertToMemory(); - - _rawData = null; - - try - { - Gdip.CheckStatus(Gdip.GdipSaveAdd(new HandleRef(this, nativeImage), new HandleRef(encoderParams, encoder))); - } - finally - { - if (encoder != IntPtr.Zero) - { - Marshal.FreeHGlobal(encoder); - } - } - } - - /// - /// Adds an to the specified . - /// - public void SaveAdd(Image image!!, EncoderParameters? encoderParams) - { - IntPtr encoder = IntPtr.Zero; - if (encoderParams != null) - encoder = encoderParams.ConvertToMemory(); - - _rawData = null; - - try - { - Gdip.CheckStatus(Gdip.GdipSaveAddImage( - new HandleRef(this, nativeImage), - new HandleRef(image, image.nativeImage), - new HandleRef(encoderParams, encoder))); - } - finally - { - if (encoder != IntPtr.Zero) - { - Marshal.FreeHGlobal(encoder); - } - } - } - - /// - /// Gets a bounding rectangle in the specified units for this . - /// - public RectangleF GetBounds(ref GraphicsUnit pageUnit) - { - Gdip.CheckStatus(Gdip.GdipGetImageBounds(new HandleRef(this, nativeImage), out RectangleF bounds, out pageUnit)); - return bounds; - } - - /// - /// Gets or sets the color palette used for this . - /// - [Browsable(false)] - public ColorPalette Palette - { - get - { - Gdip.CheckStatus(Gdip.GdipGetImagePaletteSize(new HandleRef(this, nativeImage), out int size)); - - // "size" is total byte size: - // sizeof(ColorPalette) + (pal->Count-1)*sizeof(ARGB) - - ColorPalette palette = new ColorPalette(size); - - // Memory layout is: - // UINT Flags - // UINT Count - // ARGB Entries[size] - - IntPtr memory = Marshal.AllocHGlobal(size); - try - { - Gdip.CheckStatus(Gdip.GdipGetImagePalette(new HandleRef(this, nativeImage), memory, size)); - palette.ConvertFromMemory(memory); - } - finally - { - Marshal.FreeHGlobal(memory); - } - - return palette; - } - set - { - IntPtr memory = value.ConvertToMemory(); - - try - { - Gdip.CheckStatus(Gdip.GdipSetImagePalette(new HandleRef(this, nativeImage), memory)); - } - finally - { - if (memory != IntPtr.Zero) - { - Marshal.FreeHGlobal(memory); - } - } - } - } - - // Thumbnail support - - /// - /// Returns the thumbnail for this . - /// - public Image GetThumbnailImage(int thumbWidth, int thumbHeight, GetThumbnailImageAbort? callback, IntPtr callbackData) - { - IntPtr thumbImage; - - Gdip.CheckStatus(Gdip.GdipGetImageThumbnail( - new HandleRef(this, nativeImage), - thumbWidth, - thumbHeight, - out thumbImage, - callback, - callbackData)); - - return CreateImageObject(thumbImage); - } - - internal static void ValidateImage(IntPtr image) - { - try - { - Gdip.CheckStatus(Gdip.GdipImageForceValidation(image)); - } - catch - { - Gdip.GdipDisposeImage(image); - throw; - } - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Image.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Image.cs index c84a286c0df1b..cc4c37999206f 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Image.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Image.cs @@ -5,6 +5,8 @@ using System.ComponentModel; using System.Diagnostics; using System.Drawing.Imaging; +using System.Drawing.Internal; +using System.Globalization; using System.IO; using System.Runtime.InteropServices; using System.Runtime.Serialization; @@ -21,8 +23,12 @@ namespace System.Drawing [Serializable] [System.Runtime.CompilerServices.TypeForwardedFrom("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] [TypeConverter(typeof(ImageConverter))] - public abstract partial class Image : MarshalByRefObject, IDisposable, ICloneable, ISerializable + public abstract class Image : MarshalByRefObject, IDisposable, ICloneable, ISerializable { +#if FINALIZATION_WATCH + private string allocationSite = Graphics.GetAllocationStack(); +#endif + // The signature of this delegate is incorrect. The signature of the corresponding // native callback function is: // extern "C" { @@ -134,6 +140,51 @@ public static Image FromFile(string filename, bool useEmbeddedColorManagement) public static Image FromStream(Stream stream, bool useEmbeddedColorManagement) => FromStream(stream, useEmbeddedColorManagement, true); + public static Image FromStream(Stream stream, bool useEmbeddedColorManagement, bool validateImageData) + { + ArgumentNullException.ThrowIfNull(stream); + + IntPtr image = LoadGdipImageFromStream(new GPStream(stream), useEmbeddedColorManagement); + + if (validateImageData) + ValidateImage(image); + + Image img = CreateImageObject(image); + EnsureSave(img, null, stream); + return img; + } + + // Used for serialization + private IntPtr InitializeFromStream(Stream stream) + { + IntPtr image = LoadGdipImageFromStream(new GPStream(stream), useEmbeddedColorManagement: false); + ValidateImage(image); + + nativeImage = image; + + Gdip.CheckStatus(Gdip.GdipGetImageType(new HandleRef(this, nativeImage), out _)); + EnsureSave(this, null, stream); + return image; + } + + private static unsafe IntPtr LoadGdipImageFromStream(GPStream stream, bool useEmbeddedColorManagement) + { + using DrawingCom.IStreamWrapper streamWrapper = DrawingCom.GetComWrapper(stream); + + IntPtr image = IntPtr.Zero; + if (useEmbeddedColorManagement) + { + Gdip.CheckStatus(Gdip.GdipLoadImageFromStreamICM(streamWrapper.Ptr, &image)); + } + else + { + Gdip.CheckStatus(Gdip.GdipLoadImageFromStream(streamWrapper.Ptr, &image)); + } + return image; + } + + internal Image(IntPtr nativeImage) => SetNativeImage(nativeImage); + /// /// Cleans up Windows resources for this . /// @@ -148,11 +199,257 @@ public void Dispose() /// ~Image() => Dispose(false); + /// + /// Creates an exact copy of this . + /// + public object Clone() + { + IntPtr cloneImage; + + Gdip.CheckStatus(Gdip.GdipCloneImage(new HandleRef(this, nativeImage), out cloneImage)); + ValidateImage(cloneImage); + + return CreateImageObject(cloneImage); + } + + protected virtual void Dispose(bool disposing) + { +#if FINALIZATION_WATCH + if (!disposing && nativeImage != IntPtr.Zero) + Debug.WriteLine("**********************\nDisposed through finalization:\n" + allocationSite); +#endif + if (nativeImage == IntPtr.Zero) + return; + + try + { +#if DEBUG + int status = !Gdip.Initialized ? Gdip.Ok : +#endif + Gdip.GdipDisposeImage(new HandleRef(this, nativeImage)); +#if DEBUG + Debug.Assert(status == Gdip.Ok, $"GDI+ returned an error status: {status.ToString(CultureInfo.InvariantCulture)}"); +#endif + } + catch (Exception ex) + { + if (ClientUtils.IsSecurityOrCriticalException(ex)) + { + throw; + } + + Debug.Fail("Exception thrown during Dispose: " + ex.ToString()); + } + finally + { + nativeImage = IntPtr.Zero; + } + } + /// /// Saves this to the specified file. /// public void Save(string filename) => Save(filename, RawFormat); + /// + /// Saves this to the specified file in the specified format. + /// + public void Save(string filename, ImageFormat format) + { + ArgumentNullException.ThrowIfNull(format); + + ImageCodecInfo? codec = format.FindEncoder(); + + if (codec == null) + codec = ImageFormat.Png.FindEncoder()!; + + Save(filename, codec, null); + } + + /// + /// Saves this to the specified file in the specified format and with the specified encoder parameters. + /// + public void Save(string filename, ImageCodecInfo encoder, EncoderParameters? encoderParams) + { + ArgumentNullException.ThrowIfNull(filename); + ArgumentNullException.ThrowIfNull(encoder); + ThrowIfDirectoryDoesntExist(filename); + + IntPtr encoderParamsMemory = IntPtr.Zero; + + if (encoderParams != null) + { + _rawData = null; + encoderParamsMemory = encoderParams.ConvertToMemory(); + } + + try + { + Guid g = encoder.Clsid; + bool saved = false; + + if (_rawData != null) + { + ImageCodecInfo? rawEncoder = RawFormat.FindEncoder(); + if (rawEncoder != null && rawEncoder.Clsid == g) + { + using (FileStream fs = File.OpenWrite(filename)) + { + fs.Write(_rawData, 0, _rawData.Length); + saved = true; + } + } + } + + if (!saved) + { + Gdip.CheckStatus(Gdip.GdipSaveImageToFile( + new HandleRef(this, nativeImage), + filename, + ref g, + new HandleRef(encoderParams, encoderParamsMemory))); + } + } + finally + { + if (encoderParamsMemory != IntPtr.Zero) + { + Marshal.FreeHGlobal(encoderParamsMemory); + } + } + } + + private void Save(MemoryStream stream) + { + // Jpeg loses data, so we don't want to use it to serialize... + ImageFormat dest = RawFormat; + if (dest.Guid == ImageFormat.Jpeg.Guid) + dest = ImageFormat.Png; + + // If we don't find an Encoder (for things like Icon), we just switch back to PNG... + ImageCodecInfo codec = dest.FindEncoder() ?? ImageFormat.Png.FindEncoder()!; + + Save(stream, codec, null); + } + + /// + /// Saves this to the specified stream in the specified format. + /// + public void Save(Stream stream, ImageFormat format) + { + ArgumentNullException.ThrowIfNull(format); + + ImageCodecInfo codec = format.FindEncoder()!; + Save(stream, codec, null); + } + + /// + /// Saves this to the specified stream in the specified format. + /// + public void Save(Stream stream, ImageCodecInfo encoder, EncoderParameters? encoderParams) + { + ArgumentNullException.ThrowIfNull(stream); + ArgumentNullException.ThrowIfNull(encoder); + + IntPtr encoderParamsMemory = IntPtr.Zero; + + if (encoderParams != null) + { + _rawData = null; + encoderParamsMemory = encoderParams.ConvertToMemory(); + } + + try + { + Guid g = encoder.Clsid; + bool saved = false; + + if (_rawData != null) + { + ImageCodecInfo? rawEncoder = RawFormat.FindEncoder(); + if (rawEncoder != null && rawEncoder.Clsid == g) + { + stream.Write(_rawData, 0, _rawData.Length); + saved = true; + } + } + + if (!saved) + { + using DrawingCom.IStreamWrapper streamWrapper = DrawingCom.GetComWrapper(new GPStream(stream, makeSeekable: false)); + unsafe + { + Gdip.CheckStatus(Gdip.GdipSaveImageToStream( + new HandleRef(this, nativeImage), + streamWrapper.Ptr, + &g, + new HandleRef(encoderParams, encoderParamsMemory))); + } + } + } + finally + { + if (encoderParamsMemory != IntPtr.Zero) + { + Marshal.FreeHGlobal(encoderParamsMemory); + } + } + } + + /// + /// Adds an to this . + /// + public void SaveAdd(EncoderParameters? encoderParams) + { + IntPtr encoder = IntPtr.Zero; + if (encoderParams != null) + encoder = encoderParams.ConvertToMemory(); + + _rawData = null; + + try + { + Gdip.CheckStatus(Gdip.GdipSaveAdd(new HandleRef(this, nativeImage), new HandleRef(encoderParams, encoder))); + } + finally + { + if (encoder != IntPtr.Zero) + { + Marshal.FreeHGlobal(encoder); + } + } + } + + /// + /// Adds an to the specified . + /// + public void SaveAdd(Image image, EncoderParameters? encoderParams) + { + ArgumentNullException.ThrowIfNull(image); + + IntPtr encoder = IntPtr.Zero; + + if (encoderParams != null) + encoder = encoderParams.ConvertToMemory(); + + _rawData = null; + + try + { + Gdip.CheckStatus(Gdip.GdipSaveAddImage( + new HandleRef(this, nativeImage), + new HandleRef(image, image.nativeImage), + new HandleRef(encoderParams, encoder))); + } + finally + { + if (encoder != IntPtr.Zero) + { + Marshal.FreeHGlobal(encoder); + } + } + } + private static void ThrowIfDirectoryDoesntExist(string filename) { var directoryPart = System.IO.Path.GetDirectoryName(filename); @@ -358,6 +655,99 @@ public unsafe PropertyItem[] PropertyItems } } + /// + /// Gets a bounding rectangle in the specified units for this . + /// + public RectangleF GetBounds(ref GraphicsUnit pageUnit) + { + Gdip.CheckStatus(Gdip.GdipGetImageBounds(new HandleRef(this, nativeImage), out RectangleF bounds, out pageUnit)); + return bounds; + } + + /// + /// Gets or sets the color palette used for this . + /// + [Browsable(false)] + public ColorPalette Palette + { + get + { + Gdip.CheckStatus(Gdip.GdipGetImagePaletteSize(new HandleRef(this, nativeImage), out int size)); + + // "size" is total byte size: + // sizeof(ColorPalette) + (pal->Count-1)*sizeof(ARGB) + + ColorPalette palette = new ColorPalette(size); + + // Memory layout is: + // UINT Flags + // UINT Count + // ARGB Entries[size] + + IntPtr memory = Marshal.AllocHGlobal(size); + try + { + Gdip.CheckStatus(Gdip.GdipGetImagePalette(new HandleRef(this, nativeImage), memory, size)); + palette.ConvertFromMemory(memory); + } + finally + { + Marshal.FreeHGlobal(memory); + } + + return palette; + } + set + { + IntPtr memory = value.ConvertToMemory(); + + try + { + Gdip.CheckStatus(Gdip.GdipSetImagePalette(new HandleRef(this, nativeImage), memory)); + } + finally + { + if (memory != IntPtr.Zero) + { + Marshal.FreeHGlobal(memory); + } + } + } + } + + // Thumbnail support + + /// + /// Returns the thumbnail for this . + /// + public Image GetThumbnailImage(int thumbWidth, int thumbHeight, GetThumbnailImageAbort? callback, IntPtr callbackData) + { + IntPtr thumbImage; + + Gdip.CheckStatus(Gdip.GdipGetImageThumbnail( + new HandleRef(this, nativeImage), + thumbWidth, + thumbHeight, + out thumbImage, + callback, + callbackData)); + + return CreateImageObject(thumbImage); + } + + internal static void ValidateImage(IntPtr image) + { + try + { + Gdip.CheckStatus(Gdip.GdipImageForceValidation(image)); + } + catch + { + Gdip.GdipDisposeImage(image); + throw; + } + } + /// /// Returns the number of frames of the given dimension. /// diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/BitmapData.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/BitmapData.Unix.cs deleted file mode 100644 index 6712074587dc1..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/BitmapData.Unix.cs +++ /dev/null @@ -1,67 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// System.Drawing.Imaging.BitmapData.cs -// -// Author: -// Miguel de Icaza (miguel@ximian.com) -// Vladimir Vukicevic (vladimir@pobox.com) -// -// (C) 2002 Ximian, Inc. http://www.ximian.com -// Copyright (C) 2004, 2006 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// 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.Runtime.InteropServices; - -namespace System.Drawing.Imaging -{ - // MUST BE KEPT IN SYNC WITH gdip.h in libgdiplus! - // The first 6 fields MUST also match MS definition - [StructLayout(LayoutKind.Sequential)] - public sealed partial class BitmapData - { - private int _width; - private int _height; - private int _stride; - private PixelFormat _pixelFormat; - private IntPtr _scan0; - private int _reserved; -#pragma warning disable 169 - // *** Warning *** don't depend on those fields in managed - // code as they won't exists when using MS - // GDI+ - private IntPtr palette; - private int property_count; - private IntPtr property; - private float dpi_horz; - private float dpi_vert; - private int image_flags; - private int left; - private int top; - private int x; - private int y; - private int transparent; - // *** Warning *** -#pragma warning restore 169 - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/BitmapData.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/BitmapData.Windows.cs deleted file mode 100644 index 24aa75ea4f648..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/BitmapData.Windows.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.InteropServices; - -namespace System.Drawing.Imaging -{ - /// - /// Specifies the attributes of a bitmap image. - /// - [StructLayout(LayoutKind.Sequential)] - public sealed partial class BitmapData - { - private int _width; - private int _height; - private int _stride; - private PixelFormat _pixelFormat; - private IntPtr _scan0; - private int _reserved; - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/BitmapData.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/BitmapData.cs index 4817da34d12e7..4e6a97984269a 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/BitmapData.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/BitmapData.cs @@ -6,8 +6,19 @@ namespace System.Drawing.Imaging { - public partial class BitmapData + /// + /// Specifies the attributes of a bitmap image. + /// + [StructLayout(LayoutKind.Sequential)] + public sealed class BitmapData { + private int _width; + private int _height; + private int _stride; + private PixelFormat _pixelFormat; + private IntPtr _scan0; + private int _reserved; + /// /// Specifies the pixel width of the . /// diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/MetaHeader.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/MetaHeader.Unix.cs deleted file mode 100644 index d0ef6065bdde4..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/MetaHeader.Unix.cs +++ /dev/null @@ -1,143 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// System.Drawing.Imaging.MetaHeader.cs -// -// Authors: -// Everaldo Canuto (everaldo.canuto@bol.com.br) -// Andreas Nahr (ClassDevelopment@A-SoftTech.com) -// Dennis Hayes (dennish@raytek.com) -// Sebastien Pouliot -// -// (C) 2002 Ximian, Inc. http://www.ximian.com -// Copyright (C) 2004, 2006-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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// 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.Runtime.InteropServices; - -namespace System.Drawing.Imaging -{ - - [StructLayout(LayoutKind.Sequential, Pack = 2)] - internal struct WmfMetaHeader - { - // field order match: http://wvware.sourceforge.net/caolan/ora-wmf.html - // for WMFHEAD structure - public short file_type; - public short header_size; - public short version; - // this is unaligned and fails on the SPARC architecture (see bug #81254 for details) - // public int file_size; - public ushort file_size_low; - public ushort file_size_high; - public short num_of_objects; - public int max_record_size; - public short num_of_params; - } - - [StructLayout(LayoutKind.Sequential)] - public sealed class MetaHeader - { - - private WmfMetaHeader wmf; - - public MetaHeader() - { - } - - internal MetaHeader(WmfMetaHeader header) - { - wmf.file_type = header.file_type; - wmf.header_size = header.header_size; - wmf.version = header.version; - wmf.file_size_low = header.file_size_low; - wmf.file_size_high = header.file_size_high; - wmf.num_of_objects = header.num_of_objects; - wmf.max_record_size = header.max_record_size; - wmf.num_of_params = header.num_of_params; - } - - - public short HeaderSize - { - get { return wmf.header_size; } - set { wmf.header_size = value; } - } - - public int MaxRecord - { - get { return wmf.max_record_size; } - set { wmf.max_record_size = value; } - } - - public short NoObjects - { - get { return wmf.num_of_objects; } - set { wmf.num_of_objects = value; } - } - - public short NoParameters - { - get { return wmf.num_of_params; } - set { wmf.num_of_params = value; } - } - - public int Size - { - get - { - if (BitConverter.IsLittleEndian) - return (wmf.file_size_high << 16) | wmf.file_size_low; - else - return (wmf.file_size_low << 16) | wmf.file_size_high; - } - set - { - if (BitConverter.IsLittleEndian) - { - wmf.file_size_high = (ushort)(value >> 16); - wmf.file_size_low = (ushort)value; - } - else - { - wmf.file_size_high = (ushort)value; - wmf.file_size_low = (ushort)(value >> 16); - } - } - } - - public short Type - { - get { return wmf.file_type; } - set { wmf.file_type = value; } - } - - public short Version - { - get { return wmf.version; } - set { wmf.version = value; } - } - - internal WmfMetaHeader GetNativeValue() => wmf; - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/MetaHeader.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/MetaHeader.cs similarity index 100% rename from src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/MetaHeader.Windows.cs rename to src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/MetaHeader.cs diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/Metafile.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/Metafile.Unix.cs deleted file mode 100644 index cca9e7cd64cfc..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/Metafile.Unix.cs +++ /dev/null @@ -1,343 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// System.Drawing.Imaging.Metafile.cs -// -// Authors: -// Christian Meyer, eMail: Christian.Meyer@cs.tum.edu -// Dennis Hayes (dennish@raytek.com) -// Sebastien Pouliot -// -// (C) 2002 Ximian, Inc. http://www.ximian.com -// Copyright (C) 2004,2006-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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// 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.IO; -using System.Reflection; -using System.ComponentModel; -using System.Diagnostics; -using System.Runtime.InteropServices; -using Gdip = System.Drawing.SafeNativeMethods.Gdip; -using System.Runtime.Serialization; - -namespace System.Drawing.Imaging -{ - public sealed partial class Metafile : Image - { - // Non-null if a graphics instance was created using - // Graphics.FromImage(this) The metadata holder is responsible for - // freeing the nativeImage if the Metadata instance is disposed before - // the Graphics instance. - private MetafileHolder? _metafileHolder; - - // A class responsible for disposing of the native Metafile instance - // if it needs to outlive the managed Metafile instance. - // - // The following are both legal with win32 GDI+: - // Metafile mf = ...; // get a metafile instance - // Graphics g = Graphics.FromImage(mf); // get a graphics instance - // g.Dispose(); mf.Dispose(); // dispose of the graphics instance first - // OR - // mf.Dispose(); g.Dispose(); // dispose of the metafile instance first - // - // ligbgdiplus has a bug where disposing of the metafile instance first will - // trigger a use of freed memory when the graphics instance is disposed, which - // could lead to crashes when the native memory is reused. - // - // The metafile holder is designed to take ownership of the native metafile image - // when the managed Metafile instance is disposed while a Graphics instance is still - // not disposed (ie the second code pattern above) and to keep the native image alive until the graphics - // instance is disposed. - // - // Note that the following throws, so we only ever need to keep track of one Graphics - // instance at a time: - // Metafile mf = ...; // get a metafile instance - // Graphics g = Graphics.FromImage(mf); - // Graphics g2 = Graphics.FromImage(mf); // throws OutOfMemoryException on GDI+ on Win32 - internal sealed class MetafileHolder : IDisposable - { - private bool _disposed; - private IntPtr _nativeImage; - - - internal bool Disposed { get => _disposed; } - internal MetafileHolder() - { - _disposed = false; - _nativeImage = IntPtr.Zero; - } - - ~MetafileHolder() => Dispose(false); - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - internal void Dispose(bool disposing) - { - if (!_disposed) - { - IntPtr nativeImage = _nativeImage; - _nativeImage = IntPtr.Zero; - _disposed = true; - if (nativeImage != IntPtr.Zero) - { - int status = Gdip.GdipDisposeImage(nativeImage); - Gdip.CheckStatus(status); - } - } - } - - internal void MetafileDisposed(IntPtr nativeImage) - { - _nativeImage = nativeImage; - } - - internal void GraphicsDisposed() - { - Dispose(); - } - } - - internal MetafileHolder? AddMetafileHolder() - { - // If _metafileHolder is not null and hasn't been disposed yet, there's already a graphics instance associated with - // this metafile, the native code will return an error status. - if (_metafileHolder != null && !_metafileHolder.Disposed) - return null; - _metafileHolder = new MetafileHolder(); - return _metafileHolder; - } - - // Usually called when cloning images that need to have - // not only the handle saved, but also the underlying stream - // (when using MS GDI+ and IStream we must ensure the stream stays alive for all the life of the Image) - internal Metafile(IntPtr ptr, Stream stream) => SetNativeImage(ptr); - - public Metafile(Stream stream!!) - { - // With libgdiplus we use a custom API for this, because there's no easy way - // to get the Stream down to libgdiplus. So, we wrap the stream with a set of delegates. - GdiPlusStreamHelper sh = new GdiPlusStreamHelper(stream, seekToOrigin: false); - int status = Gdip.GdipCreateMetafileFromDelegate_linux(sh.GetHeaderDelegate, sh.GetBytesDelegate, - sh.PutBytesDelegate, sh.SeekDelegate, sh.CloseDelegate, sh.SizeDelegate, out nativeImage); - - // Since we're just passing to native code the delegates inside the wrapper, we need to keep sh alive - // to avoid the object being collected and therefore the delegates would be collected as well. - GC.KeepAlive(sh); - Gdip.CheckStatus(status); - } - - public Metafile(IntPtr hmetafile, WmfPlaceableFileHeader wmfHeader) - { - int status = Gdip.GdipCreateMetafileFromEmf(hmetafile, false, out nativeImage); - Gdip.CheckStatus(status); - } - - public Metafile(IntPtr referenceHdc, EmfType emfType, string? description) : - this(referenceHdc, default(RectangleF), MetafileFrameUnit.GdiCompatible, emfType, description) - { - } - - public Metafile(Stream stream, IntPtr referenceHdc, EmfType type, string? description) : - this(stream, referenceHdc, default(RectangleF), MetafileFrameUnit.GdiCompatible, type, description) - { - } - - public Metafile(string fileName, IntPtr referenceHdc, EmfType type, string? description) : - this(fileName, referenceHdc, default(RectangleF), MetafileFrameUnit.GdiCompatible, type, description) - { - } - - public Metafile(IntPtr referenceHdc, Rectangle frameRect, MetafileFrameUnit frameUnit, EmfType type, - string? desc) - { - int status = Gdip.GdipRecordMetafileI(referenceHdc, type, ref frameRect, frameUnit, - desc, out nativeImage); - Gdip.CheckStatus(status); - } - - public Metafile(Stream stream, IntPtr referenceHdc, Rectangle frameRect, MetafileFrameUnit frameUnit, - EmfType type, string? description) - { - if (stream == null) - throw new NullReferenceException(nameof(stream)); - - // With libgdiplus we use a custom API for this, because there's no easy way - // to get the Stream down to libgdiplus. So, we wrap the stream with a set of delegates. - GdiPlusStreamHelper sh = new GdiPlusStreamHelper(stream, seekToOrigin: false); - int status = Gdip.GdipRecordMetafileFromDelegateI_linux(sh.GetHeaderDelegate, sh.GetBytesDelegate, - sh.PutBytesDelegate, sh.SeekDelegate, sh.CloseDelegate, sh.SizeDelegate, referenceHdc, - type, ref frameRect, frameUnit, description, out nativeImage); - - // Since we're just passing to native code the delegates inside the wrapper, we need to keep sh alive - // to avoid the object being collected and therefore the delegates would be collected as well. - GC.KeepAlive(sh); - Gdip.CheckStatus(status); - } - - public Metafile(Stream stream, IntPtr referenceHdc, RectangleF frameRect, MetafileFrameUnit frameUnit, - EmfType type, string? description) - { - if (stream == null) - throw new NullReferenceException(nameof(stream)); - - // With libgdiplus we use a custom API for this, because there's no easy way - // to get the Stream down to libgdiplus. So, we wrap the stream with a set of delegates. - GdiPlusStreamHelper sh = new GdiPlusStreamHelper(stream, seekToOrigin: false); - int status = Gdip.GdipRecordMetafileFromDelegate_linux(sh.GetHeaderDelegate, sh.GetBytesDelegate, - sh.PutBytesDelegate, sh.SeekDelegate, sh.CloseDelegate, sh.SizeDelegate, referenceHdc, - type, ref frameRect, frameUnit, description, out nativeImage); - - // Since we're just passing to native code the delegates inside the wrapper, we need to keep sh alive - // to avoid the object being collected and therefore the delegates would be collected as well. - GC.KeepAlive(sh); - Gdip.CheckStatus(status); - } - - public Metafile(string fileName, IntPtr referenceHdc, Rectangle frameRect, MetafileFrameUnit frameUnit, - EmfType type, string? description) - { - // Called in order to emulate exception behavior from .NET Framework related to invalid file paths. - Path.GetFullPath(fileName); - - int status = Gdip.GdipRecordMetafileFileNameI(fileName, referenceHdc, type, ref frameRect, - frameUnit, description, out nativeImage); - Gdip.CheckStatus(status); - } - - protected override void Dispose(bool disposing) - { - if (_metafileHolder != null && !_metafileHolder.Disposed) - { - // There's a graphics instance created from this Metafile, - // transfer responsibility for disposing the nativeImage to the - // MetafileHolder - _metafileHolder.MetafileDisposed(nativeImage); - _metafileHolder = null; - nativeImage = IntPtr.Zero; - } - - base.Dispose(disposing); - } - - // methods - - public IntPtr GetHenhmetafile() - { - return nativeImage; - } - - public MetafileHeader GetMetafileHeader() - { - IntPtr header = Marshal.AllocHGlobal(Marshal.SizeOf()); - try - { - int status = Gdip.GdipGetMetafileHeaderFromMetafile(nativeImage, header); - Gdip.CheckStatus(status); - return new MetafileHeader(header); - } - finally - { - Marshal.FreeHGlobal(header); - } - } - - public static MetafileHeader GetMetafileHeader(IntPtr henhmetafile) - { - IntPtr header = Marshal.AllocHGlobal(Marshal.SizeOf()); - try - { - int status = Gdip.GdipGetMetafileHeaderFromEmf(henhmetafile, header); - Gdip.CheckStatus(status); - return new MetafileHeader(header); - } - finally - { - Marshal.FreeHGlobal(header); - } - } - - public static MetafileHeader GetMetafileHeader(Stream stream) - { - if (stream == null) - throw new NullReferenceException(nameof(stream)); - - IntPtr header = Marshal.AllocHGlobal(Marshal.SizeOf()); - try - { - // With libgdiplus we use a custom API for this, because there's no easy way - // to get the Stream down to libgdiplus. So, we wrap the stream with a set of delegates. - GdiPlusStreamHelper sh = new GdiPlusStreamHelper(stream, seekToOrigin: false); - int status = Gdip.GdipGetMetafileHeaderFromDelegate_linux(sh.GetHeaderDelegate, - sh.GetBytesDelegate, sh.PutBytesDelegate, sh.SeekDelegate, sh.CloseDelegate, - sh.SizeDelegate, header); - - // Since we're just passing to native code the delegates inside the wrapper, we need to keep sh alive - // to avoid the object being collected and therefore the delegates would be collected as well. - GC.KeepAlive(sh); - Gdip.CheckStatus(status); - return new MetafileHeader(header); - } - finally - { - Marshal.FreeHGlobal(header); - } - } - - public static MetafileHeader GetMetafileHeader(string fileName) - { - // Called in order to emulate exception behavior from .NET Framework related to invalid file paths. - Path.GetFullPath(fileName); - - IntPtr header = Marshal.AllocHGlobal(Marshal.SizeOf()); - try - { - int status = Gdip.GdipGetMetafileHeaderFromFile(fileName, header); - Gdip.CheckStatus(status); - return new MetafileHeader(header); - } - finally - { - Marshal.FreeHGlobal(header); - } - } - - public static MetafileHeader GetMetafileHeader(IntPtr hmetafile, WmfPlaceableFileHeader wmfHeader) - { - IntPtr header = Marshal.AllocHGlobal(Marshal.SizeOf()); - try - { - int status = Gdip.GdipGetMetafileHeaderFromEmf(hmetafile, header); - Gdip.CheckStatus(status); - return new MetafileHeader(header); - } - finally - { - Marshal.FreeHGlobal(header); - } - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/Metafile.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/Metafile.Windows.cs deleted file mode 100644 index 43e48a864f39a..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/Metafile.Windows.cs +++ /dev/null @@ -1,385 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Internal; -using System.IO; -using System.Runtime.InteropServices; -using Gdip = System.Drawing.SafeNativeMethods.Gdip; - -namespace System.Drawing.Imaging -{ - /// - /// Defines a graphic metafile. A metafile contains records that describe a sequence of graphics operations that - /// can be recorded and played back. - /// - public sealed partial class Metafile : Image - { - /// - /// Initializes a new instance of the class from the specified handle and - /// . - /// - public Metafile(IntPtr hmetafile, WmfPlaceableFileHeader wmfHeader) : - this(hmetafile, wmfHeader, false) - { - } - - /// - /// Initializes a new instance of the class from the specified stream. - /// - public unsafe Metafile(Stream stream!!) - { - using DrawingCom.IStreamWrapper streamWrapper = DrawingCom.GetComWrapper(new GPStream(stream)); - - IntPtr metafile = IntPtr.Zero; - Gdip.CheckStatus(Gdip.GdipCreateMetafileFromStream(streamWrapper.Ptr, &metafile)); - - SetNativeImage(metafile); - } - - /// - /// Initializes a new instance of the class from the specified handle to a device context. - /// - public Metafile(IntPtr referenceHdc, EmfType emfType, string? description) - { - Gdip.CheckStatus(Gdip.GdipRecordMetafile( - referenceHdc, - emfType, - IntPtr.Zero, - MetafileFrameUnit.GdiCompatible, - description, - out IntPtr metafile)); - - SetNativeImage(metafile); - } - - /// - /// Initializes a new instance of the class from the specified device context, bounded - /// by the specified rectangle. - /// - public Metafile(IntPtr referenceHdc, Rectangle frameRect, MetafileFrameUnit frameUnit, EmfType type, string? desc) - { - IntPtr metafile; - - if (frameRect.IsEmpty) - { - Gdip.CheckStatus(Gdip.GdipRecordMetafile( - referenceHdc, - type, - IntPtr.Zero, - MetafileFrameUnit.GdiCompatible, - desc, - out metafile)); - } - else - { - Gdip.CheckStatus(Gdip.GdipRecordMetafileI( - referenceHdc, - type, - ref frameRect, - frameUnit, - desc, - out metafile)); - } - - SetNativeImage(metafile); - } - - /// - /// Initializes a new instance of the class with the specified filename. - /// - public Metafile(string fileName, IntPtr referenceHdc, EmfType type, string? description) - { - // Called in order to emulate exception behavior from .NET Framework related to invalid file paths. - Path.GetFullPath(fileName); - - Gdip.CheckStatus(Gdip.GdipRecordMetafileFileName( - fileName, - referenceHdc, - type, - IntPtr.Zero, - MetafileFrameUnit.GdiCompatible, - description, - out IntPtr metafile)); - - SetNativeImage(metafile); - } - - /// - /// Initializes a new instance of the class with the specified filename. - /// - public Metafile(string fileName, IntPtr referenceHdc, Rectangle frameRect, MetafileFrameUnit frameUnit, EmfType type, string? description) - { - // Called in order to emulate exception behavior from .NET Framework related to invalid file paths. - Path.GetFullPath(fileName); - - IntPtr metafile; - - if (frameRect.IsEmpty) - { - Gdip.CheckStatus(Gdip.GdipRecordMetafileFileName( - fileName, - referenceHdc, - type, - IntPtr.Zero, - frameUnit, - description, - out metafile)); - } - else - { - Gdip.CheckStatus(Gdip.GdipRecordMetafileFileNameI( - fileName, - referenceHdc, - type, - ref frameRect, - frameUnit, - description, - out metafile)); - } - - SetNativeImage(metafile); - } - - /// - /// Initializes a new instance of the class from the specified data stream. - /// - public unsafe Metafile(Stream stream, IntPtr referenceHdc, EmfType type, string? description) - { - using DrawingCom.IStreamWrapper streamWrapper = DrawingCom.GetComWrapper(new GPStream(stream)); - - IntPtr metafile = IntPtr.Zero; - Gdip.CheckStatus(Gdip.GdipRecordMetafileStream( - streamWrapper.Ptr, - referenceHdc, - type, - IntPtr.Zero, - MetafileFrameUnit.GdiCompatible, - description, - &metafile)); - - SetNativeImage(metafile); - } - - /// - /// Initializes a new instance of the class with the specified filename. - /// - public unsafe Metafile(Stream stream, IntPtr referenceHdc, RectangleF frameRect, MetafileFrameUnit frameUnit, EmfType type, string? description) - { - using DrawingCom.IStreamWrapper streamWrapper = DrawingCom.GetComWrapper(new GPStream(stream)); - - IntPtr metafile = IntPtr.Zero; - Gdip.CheckStatus(Gdip.GdipRecordMetafileStream( - streamWrapper.Ptr, - referenceHdc, - type, - &frameRect, - frameUnit, - description, - &metafile)); - - SetNativeImage(metafile); - } - - /// - /// Initializes a new instance of the class with the specified filename. - /// - public unsafe Metafile(Stream stream, IntPtr referenceHdc, Rectangle frameRect, MetafileFrameUnit frameUnit, EmfType type, string? description) - { - using DrawingCom.IStreamWrapper streamWrapper = DrawingCom.GetComWrapper(new GPStream(stream)); - - IntPtr metafile = IntPtr.Zero; - if (frameRect.IsEmpty) - { - Gdip.CheckStatus(Gdip.GdipRecordMetafileStream( - streamWrapper.Ptr, - referenceHdc, - type, - IntPtr.Zero, - frameUnit, - description, - &metafile)); - } - else - { - Gdip.CheckStatus(Gdip.GdipRecordMetafileStreamI( - streamWrapper.Ptr, - referenceHdc, - type, - &frameRect, - frameUnit, - description, - &metafile)); - } - - SetNativeImage(metafile); - } - - /// - /// Returns the associated with the specified . - /// - public static MetafileHeader GetMetafileHeader(IntPtr hmetafile, WmfPlaceableFileHeader wmfHeader) - { - MetafileHeader header = new MetafileHeader - { - wmf = new MetafileHeaderWmf() - }; - - Gdip.CheckStatus(Gdip.GdipGetMetafileHeaderFromWmf(hmetafile, wmfHeader, header.wmf)); - return header; - } - - /// - /// Returns the associated with the specified . - /// - public static MetafileHeader GetMetafileHeader(IntPtr henhmetafile) - { - MetafileHeader header = new MetafileHeader - { - emf = new MetafileHeaderEmf() - }; - - Gdip.CheckStatus(Gdip.GdipGetMetafileHeaderFromEmf(henhmetafile, header.emf)); - return header; - } - - /// - /// Returns the associated with the specified . - /// - public static MetafileHeader GetMetafileHeader(string fileName) - { - // Called in order to emulate exception behavior from .NET Framework related to invalid file paths. - Path.GetFullPath(fileName); - - MetafileHeader header = new MetafileHeader(); - - IntPtr memory = Marshal.AllocHGlobal(Marshal.SizeOf()); - - try - { - Gdip.CheckStatus(Gdip.GdipGetMetafileHeaderFromFile(fileName, memory)); - - int[] type = new int[] { 0 }; - - Marshal.Copy(memory, type, 0, 1); - - MetafileType metafileType = (MetafileType)type[0]; - - if (metafileType == MetafileType.Wmf || - metafileType == MetafileType.WmfPlaceable) - { - // WMF header - header.wmf = Marshal.PtrToStructure(memory)!; - header.emf = null; - } - else - { - // EMF header - header.wmf = null; - header.emf = Marshal.PtrToStructure(memory)!; - } - } - finally - { - Marshal.FreeHGlobal(memory); - } - - return header; - } - - /// - /// Returns the associated with the specified . - /// - public static MetafileHeader GetMetafileHeader(Stream stream) - { - MetafileHeader header; - - IntPtr memory = Marshal.AllocHGlobal(Marshal.SizeOf()); - - try - { - using DrawingCom.IStreamWrapper streamWrapper = DrawingCom.GetComWrapper(new GPStream(stream)); - Gdip.CheckStatus(Gdip.GdipGetMetafileHeaderFromStream(streamWrapper.Ptr, memory)); - - int[] type = new int[] { 0 }; - - Marshal.Copy(memory, type, 0, 1); - - MetafileType metafileType = (MetafileType)type[0]; - - header = new MetafileHeader(); - - if (metafileType == MetafileType.Wmf || - metafileType == MetafileType.WmfPlaceable) - { - // WMF header - header.wmf = Marshal.PtrToStructure(memory)!; - header.emf = null; - } - else - { - // EMF header - header.wmf = null; - header.emf = Marshal.PtrToStructure(memory)!; - } - } - finally - { - Marshal.FreeHGlobal(memory); - } - - return header; - } - - /// - /// Returns the associated with this . - /// - public MetafileHeader GetMetafileHeader() - { - MetafileHeader header; - - IntPtr memory = Marshal.AllocHGlobal(Marshal.SizeOf()); - - try - { - Gdip.CheckStatus(Gdip.GdipGetMetafileHeaderFromMetafile(new HandleRef(this, nativeImage), memory)); - - int[] type = new int[] { 0 }; - - Marshal.Copy(memory, type, 0, 1); - - MetafileType metafileType = (MetafileType)type[0]; - - header = new MetafileHeader(); - - if (metafileType == MetafileType.Wmf || - metafileType == MetafileType.WmfPlaceable) - { - // WMF header - header.wmf = Marshal.PtrToStructure(memory)!; - header.emf = null; - } - else - { - // EMF header - header.wmf = null; - header.emf = Marshal.PtrToStructure(memory)!; - } - } - finally - { - Marshal.FreeHGlobal(memory); - } - - return header; - } - - /// - /// Returns a Windows handle to an enhanced . - /// - public IntPtr GetHenhmetafile() - { - Gdip.CheckStatus(Gdip.GdipGetHemfFromMetafile(new HandleRef(this, nativeImage), out IntPtr hEmf)); - return hEmf; - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/Metafile.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/Metafile.cs index d551e5ac9102e..577761e242fd0 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/Metafile.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/Metafile.cs @@ -3,6 +3,7 @@ using System.IO; using System.ComponentModel; +using System.Drawing.Internal; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; @@ -18,7 +19,7 @@ namespace System.Drawing.Imaging "System.Drawing.Design.UITypeEditor, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] [Serializable] [TypeForwardedFrom("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] - public sealed partial class Metafile : Image + public sealed class Metafile : Image { // GDI+ doesn't handle filenames over MAX_PATH very well private const int MaxPath = 260; @@ -301,6 +302,208 @@ public Metafile(Stream stream, IntPtr referenceHdc, Rectangle frameRect, Metafil { } + /// + /// Initializes a new instance of the class from the specified handle and + /// . + /// + public Metafile(IntPtr hmetafile, WmfPlaceableFileHeader wmfHeader) : + this(hmetafile, wmfHeader, false) + { + } + + /// + /// Initializes a new instance of the class from the specified stream. + /// + public unsafe Metafile(Stream stream) + { + ArgumentNullException.ThrowIfNull(stream); + + using DrawingCom.IStreamWrapper streamWrapper = DrawingCom.GetComWrapper(new GPStream(stream)); + + IntPtr metafile = IntPtr.Zero; + Gdip.CheckStatus(Gdip.GdipCreateMetafileFromStream(streamWrapper.Ptr, &metafile)); + + SetNativeImage(metafile); + } + + /// + /// Initializes a new instance of the class from the specified handle to a device context. + /// + public Metafile(IntPtr referenceHdc, EmfType emfType, string? description) + { + Gdip.CheckStatus(Gdip.GdipRecordMetafile( + referenceHdc, + emfType, + IntPtr.Zero, + MetafileFrameUnit.GdiCompatible, + description, + out IntPtr metafile)); + + SetNativeImage(metafile); + } + + /// + /// Initializes a new instance of the class from the specified device context, bounded + /// by the specified rectangle. + /// + public Metafile(IntPtr referenceHdc, Rectangle frameRect, MetafileFrameUnit frameUnit, EmfType type, string? desc) + { + IntPtr metafile; + + if (frameRect.IsEmpty) + { + Gdip.CheckStatus(Gdip.GdipRecordMetafile( + referenceHdc, + type, + IntPtr.Zero, + MetafileFrameUnit.GdiCompatible, + desc, + out metafile)); + } + else + { + Gdip.CheckStatus(Gdip.GdipRecordMetafileI( + referenceHdc, + type, + ref frameRect, + frameUnit, + desc, + out metafile)); + } + + SetNativeImage(metafile); + } + + /// + /// Initializes a new instance of the class with the specified filename. + /// + public Metafile(string fileName, IntPtr referenceHdc, EmfType type, string? description) + { + // Called in order to emulate exception behavior from .NET Framework related to invalid file paths. + Path.GetFullPath(fileName); + + Gdip.CheckStatus(Gdip.GdipRecordMetafileFileName( + fileName, + referenceHdc, + type, + IntPtr.Zero, + MetafileFrameUnit.GdiCompatible, + description, + out IntPtr metafile)); + + SetNativeImage(metafile); + } + + /// + /// Initializes a new instance of the class with the specified filename. + /// + public Metafile(string fileName, IntPtr referenceHdc, Rectangle frameRect, MetafileFrameUnit frameUnit, EmfType type, string? description) + { + // Called in order to emulate exception behavior from .NET Framework related to invalid file paths. + Path.GetFullPath(fileName); + + IntPtr metafile; + + if (frameRect.IsEmpty) + { + Gdip.CheckStatus(Gdip.GdipRecordMetafileFileName( + fileName, + referenceHdc, + type, + IntPtr.Zero, + frameUnit, + description, + out metafile)); + } + else + { + Gdip.CheckStatus(Gdip.GdipRecordMetafileFileNameI( + fileName, + referenceHdc, + type, + ref frameRect, + frameUnit, + description, + out metafile)); + } + + SetNativeImage(metafile); + } + + /// + /// Initializes a new instance of the class from the specified data stream. + /// + public unsafe Metafile(Stream stream, IntPtr referenceHdc, EmfType type, string? description) + { + using DrawingCom.IStreamWrapper streamWrapper = DrawingCom.GetComWrapper(new GPStream(stream)); + + IntPtr metafile = IntPtr.Zero; + Gdip.CheckStatus(Gdip.GdipRecordMetafileStream( + streamWrapper.Ptr, + referenceHdc, + type, + IntPtr.Zero, + MetafileFrameUnit.GdiCompatible, + description, + &metafile)); + + SetNativeImage(metafile); + } + + /// + /// Initializes a new instance of the class with the specified filename. + /// + public unsafe Metafile(Stream stream, IntPtr referenceHdc, RectangleF frameRect, MetafileFrameUnit frameUnit, EmfType type, string? description) + { + using DrawingCom.IStreamWrapper streamWrapper = DrawingCom.GetComWrapper(new GPStream(stream)); + + IntPtr metafile = IntPtr.Zero; + Gdip.CheckStatus(Gdip.GdipRecordMetafileStream( + streamWrapper.Ptr, + referenceHdc, + type, + &frameRect, + frameUnit, + description, + &metafile)); + + SetNativeImage(metafile); + } + + /// + /// Initializes a new instance of the class with the specified filename. + /// + public unsafe Metafile(Stream stream, IntPtr referenceHdc, Rectangle frameRect, MetafileFrameUnit frameUnit, EmfType type, string? description) + { + using DrawingCom.IStreamWrapper streamWrapper = DrawingCom.GetComWrapper(new GPStream(stream)); + + IntPtr metafile = IntPtr.Zero; + if (frameRect.IsEmpty) + { + Gdip.CheckStatus(Gdip.GdipRecordMetafileStream( + streamWrapper.Ptr, + referenceHdc, + type, + IntPtr.Zero, + frameUnit, + description, + &metafile)); + } + else + { + Gdip.CheckStatus(Gdip.GdipRecordMetafileStreamI( + streamWrapper.Ptr, + referenceHdc, + type, + &frameRect, + frameUnit, + description, + &metafile)); + } + + SetNativeImage(metafile); + } + private Metafile(SerializationInfo info, StreamingContext context) : base(info, context) { } @@ -326,5 +529,173 @@ public void PlayRecord(EmfPlusRecordType recordType, int flags, int dataSize, by dataSize, data)); } + + /// + /// Returns the associated with the specified . + /// + public static MetafileHeader GetMetafileHeader(IntPtr hmetafile, WmfPlaceableFileHeader wmfHeader) + { + MetafileHeader header = new MetafileHeader + { + wmf = new MetafileHeaderWmf() + }; + + Gdip.CheckStatus(Gdip.GdipGetMetafileHeaderFromWmf(hmetafile, wmfHeader, header.wmf)); + return header; + } + + /// + /// Returns the associated with the specified . + /// + public static MetafileHeader GetMetafileHeader(IntPtr henhmetafile) + { + MetafileHeader header = new MetafileHeader + { + emf = new MetafileHeaderEmf() + }; + + Gdip.CheckStatus(Gdip.GdipGetMetafileHeaderFromEmf(henhmetafile, header.emf)); + return header; + } + + /// + /// Returns the associated with the specified . + /// + public static MetafileHeader GetMetafileHeader(string fileName) + { + // Called in order to emulate exception behavior from .NET Framework related to invalid file paths. + Path.GetFullPath(fileName); + + MetafileHeader header = new MetafileHeader(); + + IntPtr memory = Marshal.AllocHGlobal(Marshal.SizeOf()); + + try + { + Gdip.CheckStatus(Gdip.GdipGetMetafileHeaderFromFile(fileName, memory)); + + int[] type = new int[] { 0 }; + + Marshal.Copy(memory, type, 0, 1); + + MetafileType metafileType = (MetafileType)type[0]; + + if (metafileType == MetafileType.Wmf || + metafileType == MetafileType.WmfPlaceable) + { + // WMF header + header.wmf = Marshal.PtrToStructure(memory)!; + header.emf = null; + } + else + { + // EMF header + header.wmf = null; + header.emf = Marshal.PtrToStructure(memory)!; + } + } + finally + { + Marshal.FreeHGlobal(memory); + } + + return header; + } + + /// + /// Returns the associated with the specified . + /// + public static MetafileHeader GetMetafileHeader(Stream stream) + { + MetafileHeader header; + + IntPtr memory = Marshal.AllocHGlobal(Marshal.SizeOf()); + + try + { + using DrawingCom.IStreamWrapper streamWrapper = DrawingCom.GetComWrapper(new GPStream(stream)); + Gdip.CheckStatus(Gdip.GdipGetMetafileHeaderFromStream(streamWrapper.Ptr, memory)); + + int[] type = new int[] { 0 }; + + Marshal.Copy(memory, type, 0, 1); + + MetafileType metafileType = (MetafileType)type[0]; + + header = new MetafileHeader(); + + if (metafileType == MetafileType.Wmf || + metafileType == MetafileType.WmfPlaceable) + { + // WMF header + header.wmf = Marshal.PtrToStructure(memory)!; + header.emf = null; + } + else + { + // EMF header + header.wmf = null; + header.emf = Marshal.PtrToStructure(memory)!; + } + } + finally + { + Marshal.FreeHGlobal(memory); + } + + return header; + } + + /// + /// Returns the associated with this . + /// + public MetafileHeader GetMetafileHeader() + { + MetafileHeader header; + + IntPtr memory = Marshal.AllocHGlobal(Marshal.SizeOf()); + + try + { + Gdip.CheckStatus(Gdip.GdipGetMetafileHeaderFromMetafile(new HandleRef(this, nativeImage), memory)); + + int[] type = new int[] { 0 }; + + Marshal.Copy(memory, type, 0, 1); + + MetafileType metafileType = (MetafileType)type[0]; + + header = new MetafileHeader(); + + if (metafileType == MetafileType.Wmf || + metafileType == MetafileType.WmfPlaceable) + { + // WMF header + header.wmf = Marshal.PtrToStructure(memory)!; + header.emf = null; + } + else + { + // EMF header + header.wmf = null; + header.emf = Marshal.PtrToStructure(memory)!; + } + } + finally + { + Marshal.FreeHGlobal(memory); + } + + return header; + } + + /// + /// Returns a Windows handle to an enhanced . + /// + public IntPtr GetHenhmetafile() + { + Gdip.CheckStatus(Gdip.GdipGetHemfFromMetafile(new HandleRef(this, nativeImage), out IntPtr hEmf)); + return hEmf; + } } } diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/MetafileHeader.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/MetafileHeader.Unix.cs deleted file mode 100644 index 2770f04c159f6..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/MetafileHeader.Unix.cs +++ /dev/null @@ -1,219 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// System.Drawing.Imaging.MetafileHeader.cs -// -// Author: Everaldo Canuto -// eMail: everaldo.canuto@bol.com.br -// Dennis Hayes (dennish@raytek.com) -// -// (C) 2002 Ximian, Inc. http://www.ximian.com -// Copyright (C) 2004, 2006 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// 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.Drawing.Drawing2D; -using System.Runtime.InteropServices; - -namespace System.Drawing.Imaging -{ - - [StructLayout(LayoutKind.Sequential, Pack = 2)] - internal struct EnhMetafileHeader - { - public int type; - public int size; - public Rectangle bounds; - public Rectangle frame; - public int signature; - public int version; - public int bytes; - public int records; - public short handles; - public short reserved; - public int description; - public int off_description; - public int palette_entires; - public Size device; - public Size millimeters; - } - - // hack: keep public type as Sequential while making it possible to get the required union - [StructLayout(LayoutKind.Explicit)] - internal struct MonoMetafileHeader - { - [FieldOffset(0)] - public MetafileType type; - [FieldOffset(4)] - public int size; - [FieldOffset(8)] - public int version; - [FieldOffset(12)] - public int emf_plus_flags; - [FieldOffset(16)] - public float dpi_x; - [FieldOffset(20)] - public float dpi_y; - [FieldOffset(24)] - public int x; - [FieldOffset(28)] - public int y; - [FieldOffset(32)] - public int width; - [FieldOffset(36)] - public int height; - [FieldOffset(40)] - public WmfMetaHeader wmf_header; - [FieldOffset(40)] - public EnhMetafileHeader emf_header; - [FieldOffset(128)] - public int emfplus_header_size; - [FieldOffset(132)] - public int logical_dpi_x; - [FieldOffset(136)] - public int logical_dpi_y; - } - - [StructLayout(LayoutKind.Sequential)] - public sealed class MetafileHeader - { - - private MonoMetafileHeader header; - - //constructor - - internal MetafileHeader(IntPtr henhmetafile) - { - Marshal.PtrToStructure(henhmetafile, this); - } - - // methods - - public bool IsDisplay() - { - return false; - } - - public bool IsEmf() - { - return (Type == MetafileType.Emf); - } - - public bool IsEmfOrEmfPlus() - { - return (Type >= MetafileType.Emf); - } - - public bool IsEmfPlus() - { - return (Type >= MetafileType.EmfPlusOnly); - } - - public bool IsEmfPlusDual() - { - return (Type == MetafileType.EmfPlusDual); - } - - public bool IsEmfPlusOnly() - { - return (Type == MetafileType.EmfPlusOnly); - } - - public bool IsWmf() - { - return (Type <= MetafileType.WmfPlaceable); - } - - public bool IsWmfPlaceable() - { - return (Type == MetafileType.WmfPlaceable); - } - - // properties - - public Rectangle Bounds - { - get - { - if (this.MetafileSize == 0) - { - // GDI+ compatibility; - return default; - } - - return new Rectangle(header.x, header.y, header.width, header.height); - } - } - - public float DpiX - { - get { return header.dpi_x; } - } - - public float DpiY - { - get { return header.dpi_y; } - } - - public int EmfPlusHeaderSize - { - get { return header.emfplus_header_size; } - } - - public int LogicalDpiX - { - get { return header.logical_dpi_x; } - } - - public int LogicalDpiY - { - get { return header.logical_dpi_y; } - } - - public int MetafileSize - { - get { return header.size; } - } - - public MetafileType Type - { - get { return header.type; } - } - - public int Version - { - get { return header.version; } - } - - // note: this always returns a new instance (where we can change - // properties even if they don't seems to affect anything) - public MetaHeader WmfHeader - { - get - { - if (IsWmf()) - return new MetaHeader(header.wmf_header); - throw new ArgumentException(SR.Format(SR.AvailableOnlyOnWMF, nameof(WmfHeader))); - } - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/MetafileHeader.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/MetafileHeader.cs similarity index 100% rename from src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/MetafileHeader.Windows.cs rename to src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/MetafileHeader.cs diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Internal/GPStream.COMWrappers.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Internal/GPStream.ComWrappers.cs similarity index 100% rename from src/libraries/System.Drawing.Common/src/System/Drawing/Internal/GPStream.COMWrappers.cs rename to src/libraries/System.Drawing.Common/src/System/Drawing/Internal/GPStream.ComWrappers.cs diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Internal/GPStream.NoCOMWrappers.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Internal/GPStream.NoCOMWrappers.cs deleted file mode 100644 index 0c4e56ef8d685..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Internal/GPStream.NoCOMWrappers.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Buffers; - -namespace System.Drawing.Internal -{ - internal sealed partial class GPStream : Interop.Ole32.IStream - { - public Interop.Ole32.IStream Clone() - { - // The cloned object should have the same current "position" - return new GPStream(_dataStream) - { - _virtualPosition = _virtualPosition - }; - } - - public unsafe void CopyTo(Interop.Ole32.IStream pstm, ulong cb, ulong* pcbRead, ulong* pcbWritten) - { - byte[] buffer = ArrayPool.Shared.Rent(4096); - - ulong remaining = cb; - ulong totalWritten = 0; - ulong totalRead = 0; - - fixed (byte* b = buffer) - { - while (remaining > 0) - { - uint read = remaining < (ulong)buffer.Length ? (uint)remaining : (uint)buffer.Length; - Read(b, read, &read); - remaining -= read; - totalRead += read; - - if (read == 0) - { - break; - } - - uint written; - pstm.Write(b, read, &written); - totalWritten += written; - } - } - - ArrayPool.Shared.Return(buffer); - - if (pcbRead != null) - *pcbRead = totalRead; - - if (pcbWritten != null) - *pcbWritten = totalWritten; - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Internal/GPStream.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Internal/GPStream.cs index 4758abd0ec59a..524be173b52cf 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Internal/GPStream.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Internal/GPStream.cs @@ -129,8 +129,13 @@ public void SetSize(ulong value) _dataStream.SetLength(checked((long)value)); } - public unsafe void Stat(Interop.Ole32.STATSTG* pstatstg!!, Interop.Ole32.STATFLAG grfStatFlag) + public unsafe void Stat(Interop.Ole32.STATSTG* pstatstg, Interop.Ole32.STATFLAG grfStatFlag) { + if (pstatstg == null) + { + throw new ArgumentNullException(nameof(pstatstg)); + } + *pstatstg = new Interop.Ole32.STATSTG { cbSize = (ulong)_dataStream.Length, diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Internal/SystemColorTracker.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Internal/SystemColorTracker.cs index 8645b31c10cfd..150ba75e0a1b9 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Internal/SystemColorTracker.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Internal/SystemColorTracker.cs @@ -1,10 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.ComponentModel; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Runtime.InteropServices; using Microsoft.Win32; namespace System.Drawing.Internal @@ -39,7 +36,6 @@ internal static void Add(ISystemColorTracker obj) if (!addedTracker) { - Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); addedTracker = true; SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(OnUserPreferenceChanged); } @@ -132,8 +128,6 @@ private static void GarbageCollectList() private static void OnUserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e) { - Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); - // Update pens and brushes if (e.Category == UserPreferenceCategory.Color) { diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/LibX11Functions.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/LibX11Functions.cs deleted file mode 100644 index ffd594d014bad..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/LibX11Functions.cs +++ /dev/null @@ -1,64 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// Originally in System.Drawing.gdipFunctions.cs - -using System.Runtime.InteropServices; - -namespace System.Drawing -{ - internal static partial class LibX11Functions - { - // Some special X11 stuff - [LibraryImport("libX11", EntryPoint = "XOpenDisplay")] - internal static partial IntPtr XOpenDisplay(IntPtr display); - - [LibraryImport("libX11", EntryPoint = "XCloseDisplay")] - internal static partial int XCloseDisplay(IntPtr display); - - [LibraryImport("libX11", EntryPoint = "XRootWindow")] - internal static partial IntPtr XRootWindow(IntPtr display, int screen); - - [LibraryImport("libX11", EntryPoint = "XDefaultScreen")] - internal static partial int XDefaultScreen(IntPtr display); - - [LibraryImport("libX11", EntryPoint = "XDefaultDepth")] - internal static partial uint XDefaultDepth(IntPtr display, int screen); - - [LibraryImport("libX11", EntryPoint = "XGetImage")] - internal static partial IntPtr XGetImage(IntPtr display, IntPtr drawable, int src_x, int src_y, int width, int height, int pane, int format); - - [LibraryImport("libX11", EntryPoint = "XGetPixel")] - internal static partial int XGetPixel(IntPtr image, int x, int y); - - [LibraryImport("libX11", EntryPoint = "XDestroyImage")] - internal static partial int XDestroyImage(IntPtr image); - - [LibraryImport("libX11", EntryPoint = "XDefaultVisual")] - internal static partial IntPtr XDefaultVisual(IntPtr display, int screen); - - [LibraryImport("libX11", EntryPoint = "XGetVisualInfo")] - internal static partial IntPtr XGetVisualInfo(IntPtr display, int vinfo_mask, ref XVisualInfo vinfo_template, ref int nitems); - - [LibraryImport("libX11", EntryPoint = "XVisualIDFromVisual")] - internal static partial IntPtr XVisualIDFromVisual(IntPtr visual); - - [LibraryImport("libX11", EntryPoint = "XFree")] - internal static partial void XFree(IntPtr data); - } - - [StructLayout(LayoutKind.Sequential)] - internal struct XVisualInfo - { - internal IntPtr visual; - internal IntPtr visualid; - internal int screen; - internal uint depth; - internal int klass; - internal IntPtr red_mask; - internal IntPtr green_mask; - internal IntPtr blue_mask; - internal int colormap_size; - internal int bits_per_rgb; - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/LibraryResolver.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/LibraryResolver.cs deleted file mode 100644 index cb4bdf3c73b35..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/LibraryResolver.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Drawing.Printing; -using System.Reflection; -using System.Runtime.InteropServices; - -namespace System.Drawing -{ - internal static class LibraryResolver - { - static LibraryResolver() - { - NativeLibrary.SetDllImportResolver(Assembly.GetExecutingAssembly(), DllImportResolver); - } - - private static IntPtr DllImportResolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath) - { - if (libraryName == LibcupsNative.LibraryName) - return LibcupsNative.LoadLibcups(); - if (libraryName == SafeNativeMethods.Gdip.LibraryName) - return SafeNativeMethods.Gdip.LoadNativeLibrary(); - - return IntPtr.Zero; - } - - internal static void EnsureRegistered() - { - if (!LocalAppContextSwitches.EnableUnixSupport) - throw new PlatformNotSupportedException(SR.PlatformNotSupported_Unix); - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/LocalAppContextSwitches.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/LocalAppContextSwitches.Unix.cs deleted file mode 100644 index 73f23a56410b4..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/LocalAppContextSwitches.Unix.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.CompilerServices; - -namespace System -{ - internal static partial class LocalAppContextSwitches - { - public static bool EnableUnixSupport - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => false; - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/LocalAppContextSwitches.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/LocalAppContextSwitches.cs similarity index 100% rename from src/libraries/System.Drawing.Common/src/System/Drawing/LocalAppContextSwitches.Windows.cs rename to src/libraries/System.Drawing.Common/src/System/Drawing/LocalAppContextSwitches.cs diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/MarshallingHelpers.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/MarshallingHelpers.cs deleted file mode 100644 index 7c265b7ef9233..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/MarshallingHelpers.cs +++ /dev/null @@ -1,75 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// Authors: -// Alexandre Pigolkine (pigolkine@gmx.de) -// Jordi Mas i Hernandez (jordi@ximian.com) -// Sanjay Gupta (gsanjay@novell.com) -// Ravindra (rkumar@novell.com) -// Peter Dennis Bartok (pbartok@novell.com) -// Sebastien Pouliot -// -// 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// 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.Runtime.InteropServices; - -namespace System.Drawing -{ - internal static unsafe class MarshallingHelpers - { - // Copies a Ptr to an array of Points and releases the memory - public static void FromUnManagedMemoryToPointI(IntPtr ptr, Point[] pts) - { - var sourceSpan = new Span((void*)ptr, pts.Length); - sourceSpan.CopyTo(new Span(pts)); - Marshal.FreeHGlobal(ptr); - } - - // Copies a Ptr to an array of Points and releases the memory - public static void FromUnManagedMemoryToPoint(IntPtr ptr, PointF[] pts) - { - var sourceSpan = new Span((void*)ptr, pts.Length); - sourceSpan.CopyTo(new Span(pts)); - Marshal.FreeHGlobal(ptr); - } - - // Copies an array of Points to unmanaged memory - public static IntPtr FromPointToUnManagedMemoryI(Point[] pts) - { - IntPtr dest = Marshal.AllocHGlobal(sizeof(Point) * pts.Length); - var destinationSpan = new Span((void*)dest, pts.Length); - pts.CopyTo(destinationSpan); - return dest; - } - - // Copies an array of Points to unmanaged memory - public static IntPtr FromPointToUnManagedMemory(PointF[] pts) - { - IntPtr dest = Marshal.AllocHGlobal(sizeof(PointF) * pts.Length); - var destinationSpan = new Span((void*)dest, pts.Length); - pts.CopyTo(destinationSpan); - return dest; - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Pen.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Pen.Unix.cs deleted file mode 100644 index 42a552112e650..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Pen.Unix.cs +++ /dev/null @@ -1,80 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Drawing2D; -using System.Runtime.InteropServices; -using Gdip = System.Drawing.SafeNativeMethods.Gdip; - -namespace System.Drawing -{ - public partial class Pen - { - // libgdiplus does not implement GdipGetPenCustomEndCap, so we cache the last-known value here. - // Note that this value is not necessarily in sync with the true native value of this property, - // as it could have been set outside of the CustomEndCap property on this type. - private CustomLineCap? _cachedEndCap; - - /// - /// Gets or sets a custom cap style to use at the beginning of lines drawn with this . - /// - public CustomLineCap CustomStartCap - { - get - { - IntPtr lineCap; - int status = Gdip.GdipGetPenCustomStartCap(new HandleRef(this, NativePen), out lineCap); - Gdip.CheckStatus(status); - if (lineCap == IntPtr.Zero) - { - throw new ArgumentException(SR.GdiplusInvalidParameter); - } - - return CustomLineCap.CreateCustomLineCapObject(lineCap); - } - set - { - if (_immutable) - { - throw new ArgumentException(SR.Format(SR.CantChangeImmutableObjects, nameof(Pen))); - } - - int status = Gdip.GdipSetPenCustomStartCap(new HandleRef(this, NativePen), - new HandleRef(value, (value == null) ? IntPtr.Zero : value.nativeCap)); - Gdip.CheckStatus(status); - } - } - - /// - /// Gets or sets a custom cap style to use at the end of lines drawn with this . - /// - public CustomLineCap CustomEndCap - { - get - { - // If the CustomEndCap has never been set, this accessor should throw. - if (_cachedEndCap == null) - { - throw new ArgumentException(SR.GdiplusInvalidParameter); - } - - return _cachedEndCap; - } - set - { - if (_immutable) - { - throw new ArgumentException(SR.Format(SR.CantChangeImmutableObjects, nameof(Pen))); - } - - // Windows GDI+ clones the CustomLineCap before storing it in the Pen. - CustomLineCap? clone = value == null ? null : (CustomLineCap)value.Clone(); - - int status = Gdip.GdipSetPenCustomEndCap( - new HandleRef(this, NativePen), - new HandleRef(clone, (clone == null) ? IntPtr.Zero : clone.nativeCap)); - Gdip.CheckStatus(status); - _cachedEndCap = clone; - } - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Pen.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Pen.Windows.cs deleted file mode 100644 index 6c295fe9b0033..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Pen.Windows.cs +++ /dev/null @@ -1,64 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Drawing2D; -using System.Runtime.InteropServices; -using Gdip = System.Drawing.SafeNativeMethods.Gdip; - -namespace System.Drawing -{ - public partial class Pen - { - /// - /// Gets or sets a custom cap style to use at the beginning of lines drawn with this . - /// - public CustomLineCap CustomStartCap - { - get - { - IntPtr lineCap; - int status = Gdip.GdipGetPenCustomStartCap(new HandleRef(this, NativePen), out lineCap); - Gdip.CheckStatus(status); - - return CustomLineCap.CreateCustomLineCapObject(lineCap); - } - set - { - if (_immutable) - { - throw new ArgumentException(SR.Format(SR.CantChangeImmutableObjects, nameof(Pen))); - } - - int status = Gdip.GdipSetPenCustomStartCap(new HandleRef(this, NativePen), - new HandleRef(value, (value == null) ? IntPtr.Zero : value.nativeCap)); - Gdip.CheckStatus(status); - } - } - - /// - /// Gets or sets a custom cap style to use at the end of lines drawn with this . - /// - public CustomLineCap CustomEndCap - { - get - { - IntPtr lineCap; - int status = Gdip.GdipGetPenCustomEndCap(new HandleRef(this, NativePen), out lineCap); - Gdip.CheckStatus(status); - return CustomLineCap.CreateCustomLineCapObject(lineCap); - } - set - { - if (_immutable) - { - throw new ArgumentException(SR.Format(SR.CantChangeImmutableObjects, nameof(Pen))); - } - - int status = Gdip.GdipSetPenCustomEndCap( - new HandleRef(this, NativePen), - new HandleRef(value, (value == null) ? IntPtr.Zero : value.nativeCap)); - Gdip.CheckStatus(status); - } - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Pen.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Pen.cs index 2f953d2250c22..dceda4189f6e1 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Pen.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Pen.cs @@ -14,12 +14,7 @@ namespace System.Drawing /// /// Defines an object used to draw lines and curves. /// - public sealed partial class Pen : MarshalByRefObject, ICloneable, IDisposable -#pragma warning disable SA1001 -#if FEATURE_SYSTEM_EVENTS - , ISystemColorTracker -#endif -#pragma warning restore SA1001 + public sealed class Pen : MarshalByRefObject, ICloneable, IDisposable, ISystemColorTracker { #if FINALIZATION_WATCH private string _allocationSite = Graphics.GetAllocationStack(); @@ -57,7 +52,7 @@ public Pen(Color color, float width) { _color = color; - IntPtr pen = IntPtr.Zero; + IntPtr pen; int status = Gdip.GdipCreatePen1(color.ToArgb(), width, (int)GraphicsUnit.World, @@ -66,12 +61,10 @@ public Pen(Color color, float width) SetNativePen(pen); -#if FEATURE_SYSTEM_EVENTS if (_color.IsSystemColor) { SystemColorTracker.Add(this); } -#endif } /// @@ -84,8 +77,10 @@ public Pen(Brush brush) : this(brush, (float)1.0) /// /// Initializes a new instance of the class with the specified and width. /// - public Pen(Brush brush!!, float width) + public Pen(Brush brush, float width) { + ArgumentNullException.ThrowIfNull(brush); + IntPtr pen; int status = Gdip.GdipCreatePen2(new HandleRef(brush, brush.NativeBrush), width, @@ -299,6 +294,58 @@ public LineCap EndCap } } + /// + /// Gets or sets a custom cap style to use at the beginning of lines drawn with this . + /// + public CustomLineCap CustomStartCap + { + get + { + IntPtr lineCap; + int status = Gdip.GdipGetPenCustomStartCap(new HandleRef(this, NativePen), out lineCap); + Gdip.CheckStatus(status); + + return CustomLineCap.CreateCustomLineCapObject(lineCap); + } + set + { + if (_immutable) + { + throw new ArgumentException(SR.Format(SR.CantChangeImmutableObjects, nameof(Pen))); + } + + int status = Gdip.GdipSetPenCustomStartCap(new HandleRef(this, NativePen), + new HandleRef(value, (value == null) ? IntPtr.Zero : value.nativeCap)); + Gdip.CheckStatus(status); + } + } + + /// + /// Gets or sets a custom cap style to use at the end of lines drawn with this . + /// + public CustomLineCap CustomEndCap + { + get + { + IntPtr lineCap; + int status = Gdip.GdipGetPenCustomEndCap(new HandleRef(this, NativePen), out lineCap); + Gdip.CheckStatus(status); + return CustomLineCap.CreateCustomLineCapObject(lineCap); + } + set + { + if (_immutable) + { + throw new ArgumentException(SR.Format(SR.CantChangeImmutableObjects, nameof(Pen))); + } + + int status = Gdip.GdipSetPenCustomEndCap( + new HandleRef(this, NativePen), + new HandleRef(value, (value == null) ? IntPtr.Zero : value.nativeCap)); + Gdip.CheckStatus(status); + } + } + /// /// Gets or sets the cap style used at the beginning or end of dashed lines drawn with this . /// @@ -579,20 +626,16 @@ public Color Color if (value != _color) { -#if FEATURE_SYSTEM_EVENTS Color oldColor = _color; -#endif _color = value; InternalSetColor(value); -#if FEATURE_SYSTEM_EVENTS // NOTE: We never remove pens from the active list, so if someone is // changing their pen colors a lot, this could be a problem. if (value.IsSystemColor && !oldColor.IsSystemColor) { SystemColorTracker.Add(this); } -#endif } } } @@ -862,7 +905,6 @@ public float[] CompoundArray } } -#if FEATURE_SYSTEM_EVENTS void ISystemColorTracker.OnSystemColorChanged() { if (NativePen != IntPtr.Zero) @@ -870,6 +912,5 @@ void ISystemColorTracker.OnSystemColorChanged() InternalSetColor(_color); } } -#endif } } diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/LibcupsNative.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/LibcupsNative.cs deleted file mode 100644 index 463d105735d56..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/LibcupsNative.cs +++ /dev/null @@ -1,67 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.InteropServices; -using System.Text; - -namespace System.Drawing.Printing -{ - internal static partial class LibcupsNative - { - internal const string LibraryName = "libcups"; - - static LibcupsNative() - { - LibraryResolver.EnsureRegistered(); - } - - internal static IntPtr LoadLibcups() - { - // We allow both "libcups.so" and "libcups.so.2" to be loaded. - if (!NativeLibrary.TryLoad("libcups.so", out IntPtr lib)) - { - NativeLibrary.TryLoad("libcups.so.2", out lib); - } - - return lib; - } - - [LibraryImport(LibraryName)] - internal static partial int cupsGetDests(ref IntPtr dests); - - [LibraryImport(LibraryName)] - internal static partial void cupsFreeDests(int num_dests, IntPtr dests); - - [LibraryImport(LibraryName)] - internal static partial IntPtr cupsTempFd(sbyte[] sb, int len); - - [LibraryImport(LibraryName)] - internal static partial IntPtr cupsGetDefault(); - - [LibraryImport(LibraryName)] - internal static partial int cupsPrintFile( - [MarshalAs(UnmanagedType.LPUTF8Str)] string printer, - [MarshalAs(UnmanagedType.LPUTF8Str)] string filename, - [MarshalAs(UnmanagedType.LPUTF8Str)] string title, - int num_options, - IntPtr options); - - [LibraryImport(LibraryName)] - internal static partial IntPtr cupsGetPPD([MarshalAs(UnmanagedType.LPUTF8Str)] string printer); - - [LibraryImport(LibraryName)] - internal static partial IntPtr ppdOpenFile([MarshalAs(UnmanagedType.LPUTF8Str)] string filename); - - [LibraryImport(LibraryName)] - internal static partial IntPtr ppdFindOption(IntPtr ppd_file, [MarshalAs(UnmanagedType.LPUTF8Str)] string keyword); - - [LibraryImport(LibraryName)] - internal static partial void ppdClose(IntPtr ppd); - - [LibraryImport(LibraryName)] - internal static partial int cupsParseOptions([MarshalAs(UnmanagedType.LPUTF8Str)] string arg, int number_of_options, ref IntPtr options); - - [LibraryImport(LibraryName)] - internal static partial void cupsFreeOptions(int number_options, IntPtr options); - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/MarginsConverter.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/MarginsConverter.cs index feb3eabbadc54..42266a7e178ef 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/MarginsConverter.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/MarginsConverter.cs @@ -91,8 +91,10 @@ public override bool CanConvertTo(ITypeDescriptorContext? context, [NotNullWhen( /// type is string. If this cannot convert to the desitnation type, this will /// throw a NotSupportedException. /// - public override object? ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType!!) + public override object? ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType) { + ArgumentNullException.ThrowIfNull(destinationType); + if (value is Margins margins) { if (destinationType == typeof(string)) @@ -140,8 +142,10 @@ public override bool CanConvertTo(ITypeDescriptorContext? context, [NotNullWhen( /// for the object. This is useful for objects that are immutable, but still /// want to provide changable properties. /// - public override object CreateInstance(ITypeDescriptorContext? context, IDictionary propertyValues!!) + public override object CreateInstance(ITypeDescriptorContext? context, IDictionary propertyValues) { + ArgumentNullException.ThrowIfNull(propertyValues); + object? left = propertyValues["Left"]; object? right = propertyValues["Right"]; object? top = propertyValues["Top"]; diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PageSettings.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PageSettings.Unix.cs deleted file mode 100644 index a79fb02f0a283..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PageSettings.Unix.cs +++ /dev/null @@ -1,261 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// System.Drawing.PageSettings.cs -// -// Authors: -// Dennis Hayes (dennish@Raytek.com) -// Herve Poussineau (hpoussineau@fr.st) -// Andreas Nahr (ClassDevelopment@A-SoftTech.com) -// -// (C) 2002 Ximian, Inc -// - -// -// Copyright (C) 2004 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// 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.Runtime.InteropServices; - -namespace System.Drawing.Printing -{ - [Serializable] - public class PageSettings : ICloneable - { - internal bool color; - internal bool landscape; - internal PaperSize paperSize; - internal PaperSource paperSource; - internal PrinterResolution printerResolution; - - // create a new default Margins object (is 1 inch for all margins) - private Margins margins = new Margins(); -#pragma warning disable 649 - private float hardMarginX; - private float hardMarginY; - private RectangleF printableArea; - private PrinterSettings printerSettings = null!; -#pragma warning restore 649 - - public PageSettings() : this(new PrinterSettings()) - { - } - - public PageSettings(PrinterSettings printerSettings) - { - PrinterSettings = printerSettings; - - this.color = printerSettings.DefaultPageSettings.color; - this.landscape = printerSettings.DefaultPageSettings.landscape; - this.paperSize = printerSettings.DefaultPageSettings.paperSize; - this.paperSource = printerSettings.DefaultPageSettings.paperSource; - this.printerResolution = printerSettings.DefaultPageSettings.printerResolution; - } - - // used by PrinterSettings.DefaultPageSettings - internal PageSettings(PrinterSettings printerSettings, bool color, bool landscape, PaperSize paperSize, PaperSource paperSource, PrinterResolution printerResolution) - { - PrinterSettings = printerSettings; - this.color = color; - this.landscape = landscape; - this.paperSize = paperSize; - this.paperSource = paperSource; - this.printerResolution = printerResolution; - } - - //props - public Rectangle Bounds - { - get - { - int width = this.paperSize.Width; - int height = this.paperSize.Height; - - width -= this.margins.Left + this.margins.Right; - height -= this.margins.Top + this.margins.Bottom; - - if (this.landscape) - { - // swap width and height - int tmp = width; - width = height; - height = tmp; - } - return new Rectangle(this.margins.Left, this.margins.Top, width, height); - } - } - - public bool Color - { - get - { - if (!this.printerSettings.IsValid) - throw new InvalidPrinterException(this.printerSettings); - return color; - } - set - { - color = value; - } - } - - public bool Landscape - { - get - { - if (!this.printerSettings.IsValid) - throw new InvalidPrinterException(this.printerSettings); - return landscape; - } - set - { - landscape = value; - } - } - - public Margins Margins - { - get - { - if (!this.printerSettings.IsValid) - throw new InvalidPrinterException(this.printerSettings); - return margins; - } - set - { - margins = value; - } - } - - public PaperSize PaperSize - { - get - { - if (!this.printerSettings.IsValid) - throw new InvalidPrinterException(this.printerSettings); - return paperSize; - } - set - { - if (value != null) - paperSize = value; - } - } - - public PaperSource PaperSource - { - get - { - if (!this.printerSettings.IsValid) - throw new InvalidPrinterException(this.printerSettings); - return paperSource; - } - set - { - if (value != null) - paperSource = value; - } - } - - public PrinterResolution PrinterResolution - { - get - { - if (!this.printerSettings.IsValid) - throw new InvalidPrinterException(this.printerSettings); - return printerResolution; - } - set - { - if (value != null) - printerResolution = value; - } - } - - public PrinterSettings PrinterSettings - { - get - { - return printerSettings; - } - set - { - printerSettings = value; - } - } - public float HardMarginX - { - get - { - return hardMarginX; - } - } - - public float HardMarginY - { - get - { - return hardMarginY; - } - } - - public RectangleF PrintableArea - { - get - { - return printableArea; - } - } - - - public object Clone() - { - // We do a deep copy - PrinterResolution pres = new PrinterResolution(this.printerResolution.Kind, this.printerResolution.X, this.printerResolution.Y); - PaperSource psource = new PaperSource(this.paperSource.Kind, this.paperSource.SourceName); - PaperSize psize = new PaperSize(this.paperSize.PaperName, this.paperSize.Width, this.paperSize.Height); - psize.RawKind = (int)this.paperSize.Kind; - - PageSettings ps = new PageSettings(this.printerSettings, this.color, this.landscape, - psize, psource, pres); - ps.Margins = (Margins)this.margins.Clone(); - return ps; - } - - - public void CopyToHdevmode(IntPtr hdevmode) - { - throw new NotImplementedException(); - } - - - public void SetHdevmode(IntPtr hdevmode) - { - throw new NotImplementedException(); - } - - public override string ToString() => - $"[{nameof(PageSettings)}: {nameof(Color)}={color}, {nameof(Landscape)}={landscape}, {nameof(Margins)}={margins}, {nameof(PaperSize)}={paperSize}, {nameof(PaperSource)}={paperSource}, {nameof(PrinterResolution)}={printerResolution}]"; - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PageSettings.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PageSettings.cs similarity index 100% rename from src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PageSettings.Windows.cs rename to src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PageSettings.cs diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PreviewPrintController.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PreviewPrintController.Unix.cs deleted file mode 100644 index d8d59bf3a9adc..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PreviewPrintController.Unix.cs +++ /dev/null @@ -1,78 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// System.Drawing.PreviewPrintController.cs -// -// Author: -// Dennis Hayes (dennish@Raytek.com) -// -// (C) 2002 Ximian, Inc -// - -// -// Copyright (C) 2004 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace System.Drawing.Printing -{ - public partial class PreviewPrintController : PrintController - { - public override void OnEndPage(PrintDocument document, PrintPageEventArgs e) - { - } - - public override void OnStartPrint(PrintDocument document, PrintEventArgs e) - { - if (!document.PrinterSettings.IsValid) - { - throw new InvalidPrinterException(document.PrinterSettings); - } - - foreach (PreviewPageInfo? pi in _list) - { - pi!.Image.Dispose(); - } - - _list.Clear(); - } - - public override void OnEndPrint(PrintDocument document, PrintEventArgs e) - { - } - - public override Graphics OnStartPage(PrintDocument document, PrintPageEventArgs e) - { - Image image = new Bitmap(e.PageSettings.PaperSize.Width, e.PageSettings.PaperSize.Height); - - PreviewPageInfo info = new PreviewPageInfo(image, new Size(e.PageSettings.PaperSize.Width, - e.PageSettings.PaperSize.Height)); - - _list.Add(info); - - Graphics g = Graphics.FromImage(info.Image); - g.FillRectangle(new SolidBrush(Color.White), new Rectangle(new Point(0, 0), new Size(image.Width, image.Height))); - - return g; - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PreviewPrintController.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PreviewPrintController.Windows.cs deleted file mode 100644 index 464b4118c646e..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PreviewPrintController.Windows.cs +++ /dev/null @@ -1,124 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Drawing2D; -using System.Drawing.Imaging; -using System.Drawing.Internal; -using System.Drawing.Text; -using System.Runtime.InteropServices; - -namespace System.Drawing.Printing -{ - /// - /// A PrintController which "prints" to a series of images. - /// - public partial class PreviewPrintController : PrintController - { - private Graphics? _graphics; - private DeviceContext? _dc; - - /// - /// Implements StartPrint for generating print preview information. - /// - public override void OnStartPrint(PrintDocument document, PrintEventArgs e) - { - base.OnStartPrint(document, e); - - if (!document.PrinterSettings.IsValid) - { - throw new InvalidPrinterException(document.PrinterSettings); - } - - // We need a DC as a reference; we don't actually draw on it. - // We make sure to reuse the same one to improve performance. - _dc = document.PrinterSettings.CreateInformationContext(_modeHandle!); - } - - /// - /// Implements StartEnd for generating print preview information. - /// - public override Graphics OnStartPage(PrintDocument document, PrintPageEventArgs e) - { - base.OnStartPage(document, e); - - if (e.CopySettingsToDevMode) - { - e.PageSettings.CopyToHdevmode(_modeHandle!); - } - - Size size = e.PageBounds.Size; - - // Metafile framing rectangles apparently use hundredths of mm as their unit of measurement, - // instead of the GDI+ standard hundredth of an inch. - Size metafileSize = PrinterUnitConvert.Convert(size, PrinterUnit.Display, PrinterUnit.HundredthsOfAMillimeter); - - // Create a Metafile which accepts only GDI+ commands since we are the ones creating - // and using this ... - // Framework creates a dual-mode EMF for each page in the preview. - // When these images are displayed in preview, - // they are added to the dual-mode EMF. However, - // GDI+ breaks during this process if the image - // is sufficiently large and has more than 254 colors. - // This code path can easily be avoided by requesting - // an EmfPlusOnly EMF.. - Metafile metafile = new Metafile(_dc!.Hdc, new Rectangle(0, 0, metafileSize.Width, metafileSize.Height), MetafileFrameUnit.GdiCompatible, EmfType.EmfPlusOnly); - - PreviewPageInfo info = new PreviewPageInfo(metafile, size); - _list.Add(info); - PrintPreviewGraphics printGraphics = new PrintPreviewGraphics(document, e); - _graphics = Graphics.FromImage(metafile); - - if (document.OriginAtMargins) - { - // Adjust the origin of the graphics object to be at the - // user-specified margin location - int dpiX = Interop.Gdi32.GetDeviceCaps(new HandleRef(_dc, _dc.Hdc), Interop.Gdi32.DeviceCapability.LOGPIXELSX); - int dpiY = Interop.Gdi32.GetDeviceCaps(new HandleRef(_dc, _dc.Hdc), Interop.Gdi32.DeviceCapability.LOGPIXELSY); - int hardMarginX_DU = Interop.Gdi32.GetDeviceCaps(new HandleRef(_dc, _dc.Hdc), Interop.Gdi32.DeviceCapability.PHYSICALOFFSETX); - int hardMarginY_DU = Interop.Gdi32.GetDeviceCaps(new HandleRef(_dc, _dc.Hdc), Interop.Gdi32.DeviceCapability.PHYSICALOFFSETY); - float hardMarginX = hardMarginX_DU * 100f / dpiX; - float hardMarginY = hardMarginY_DU * 100f / dpiY; - - _graphics.TranslateTransform(-hardMarginX, -hardMarginY); - _graphics.TranslateTransform(document.DefaultPageSettings.Margins.Left, document.DefaultPageSettings.Margins.Top); - } - - _graphics.PrintingHelper = printGraphics; - - if (UseAntiAlias) - { - _graphics.TextRenderingHint = TextRenderingHint.AntiAlias; - _graphics.SmoothingMode = SmoothingMode.AntiAlias; - } - return _graphics; - } - - /// - /// Implements EndPage for generating print preview information. - /// - public override void OnEndPage(PrintDocument document, PrintPageEventArgs e) - { - if (_graphics != null) - { - _graphics.Dispose(); - _graphics = null; - } - - base.OnEndPage(document, e); - } - - /// - /// Implements EndPrint for generating print preview information. - /// - public override void OnEndPrint(PrintDocument document, PrintEventArgs e) - { - if (_dc != null) - { - _dc.Dispose(); - _dc = null; - } - - base.OnEndPrint(document, e); - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PreviewPrintController.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PreviewPrintController.cs index da9243bf62eab..c387b338626ff 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PreviewPrintController.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PreviewPrintController.cs @@ -2,12 +2,21 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections; +using System.Drawing.Drawing2D; using System.Drawing.Imaging; +using System.Drawing.Internal; +using System.Drawing.Text; +using System.Runtime.InteropServices; namespace System.Drawing.Printing { - public partial class PreviewPrintController : PrintController + /// + /// A PrintController which "prints" to a series of images. + /// + public class PreviewPrintController : PrintController { + private Graphics? _graphics; + private DeviceContext? _dc; private readonly IList _list = new ArrayList(); public override bool IsPreview => true; @@ -20,5 +29,109 @@ public PreviewPageInfo[] GetPreviewPageInfo() _list.CopyTo(temp, 0); return temp; } + + /// + /// Implements StartPrint for generating print preview information. + /// + public override void OnStartPrint(PrintDocument document, PrintEventArgs e) + { + base.OnStartPrint(document, e); + + if (!document.PrinterSettings.IsValid) + { + throw new InvalidPrinterException(document.PrinterSettings); + } + + // We need a DC as a reference; we don't actually draw on it. + // We make sure to reuse the same one to improve performance. + _dc = document.PrinterSettings.CreateInformationContext(_modeHandle!); + } + + /// + /// Implements StartEnd for generating print preview information. + /// + public override Graphics OnStartPage(PrintDocument document, PrintPageEventArgs e) + { + base.OnStartPage(document, e); + + if (e.CopySettingsToDevMode) + { + e.PageSettings.CopyToHdevmode(_modeHandle!); + } + + Size size = e.PageBounds.Size; + + // Metafile framing rectangles apparently use hundredths of mm as their unit of measurement, + // instead of the GDI+ standard hundredth of an inch. + Size metafileSize = PrinterUnitConvert.Convert(size, PrinterUnit.Display, PrinterUnit.HundredthsOfAMillimeter); + + // Create a Metafile which accepts only GDI+ commands since we are the ones creating + // and using this ... + // Framework creates a dual-mode EMF for each page in the preview. + // When these images are displayed in preview, + // they are added to the dual-mode EMF. However, + // GDI+ breaks during this process if the image + // is sufficiently large and has more than 254 colors. + // This code path can easily be avoided by requesting + // an EmfPlusOnly EMF.. + Metafile metafile = new Metafile(_dc!.Hdc, new Rectangle(0, 0, metafileSize.Width, metafileSize.Height), MetafileFrameUnit.GdiCompatible, EmfType.EmfPlusOnly); + + PreviewPageInfo info = new PreviewPageInfo(metafile, size); + _list.Add(info); + PrintPreviewGraphics printGraphics = new PrintPreviewGraphics(document, e); + _graphics = Graphics.FromImage(metafile); + + if (document.OriginAtMargins) + { + // Adjust the origin of the graphics object to be at the + // user-specified margin location + int dpiX = Interop.Gdi32.GetDeviceCaps(new HandleRef(_dc, _dc.Hdc), Interop.Gdi32.DeviceCapability.LOGPIXELSX); + int dpiY = Interop.Gdi32.GetDeviceCaps(new HandleRef(_dc, _dc.Hdc), Interop.Gdi32.DeviceCapability.LOGPIXELSY); + int hardMarginX_DU = Interop.Gdi32.GetDeviceCaps(new HandleRef(_dc, _dc.Hdc), Interop.Gdi32.DeviceCapability.PHYSICALOFFSETX); + int hardMarginY_DU = Interop.Gdi32.GetDeviceCaps(new HandleRef(_dc, _dc.Hdc), Interop.Gdi32.DeviceCapability.PHYSICALOFFSETY); + float hardMarginX = hardMarginX_DU * 100f / dpiX; + float hardMarginY = hardMarginY_DU * 100f / dpiY; + + _graphics.TranslateTransform(-hardMarginX, -hardMarginY); + _graphics.TranslateTransform(document.DefaultPageSettings.Margins.Left, document.DefaultPageSettings.Margins.Top); + } + + _graphics.PrintingHelper = printGraphics; + + if (UseAntiAlias) + { + _graphics.TextRenderingHint = TextRenderingHint.AntiAlias; + _graphics.SmoothingMode = SmoothingMode.AntiAlias; + } + return _graphics; + } + + /// + /// Implements EndPage for generating print preview information. + /// + public override void OnEndPage(PrintDocument document, PrintPageEventArgs e) + { + if (_graphics != null) + { + _graphics.Dispose(); + _graphics = null; + } + + base.OnEndPage(document, e); + } + + /// + /// Implements EndPrint for generating print preview information. + /// + public override void OnEndPrint(PrintDocument document, PrintEventArgs e) + { + if (_dc != null) + { + _dc.Dispose(); + _dc = null; + } + + base.OnEndPrint(document, e); + } } } diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintController.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintController.Unix.cs deleted file mode 100644 index cab9cb86a8f90..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintController.Unix.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// System.Drawing.PrintController.cs -// -// Author: -// Dennis Hayes (dennish@Raytek.com) -// -// (C) 2002 Ximian, Inc -// Copyright (C) 2004, 2006 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace System.Drawing.Printing -{ - public abstract partial class PrintController - { - public virtual void OnStartPrint(PrintDocument document, PrintEventArgs e) - { - } - - public virtual void OnEndPrint(PrintDocument document, PrintEventArgs e) - { - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintController.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintController.Windows.cs deleted file mode 100644 index e089027bf6067..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintController.Windows.cs +++ /dev/null @@ -1,259 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics; -using System.Runtime.InteropServices; - -namespace System.Drawing.Printing -{ - /// - /// Controls how a document is printed. - /// - public abstract partial class PrintController - { - /// - /// Represents a SafeHandle for a Printer's Device Mode struct handle (DEVMODE) - /// - /// - /// DEVMODEs are pretty expensive, so we cache one here and share it - /// with the Standard and Preview print controllers. - /// - internal sealed class SafeDeviceModeHandle : SafeHandle - { - public SafeDeviceModeHandle() : base(IntPtr.Zero, ownsHandle: true) - { - } - - internal SafeDeviceModeHandle(IntPtr handle) : base(IntPtr.Zero, ownsHandle: true) - { - SetHandle(handle); - } - - public override bool IsInvalid => handle == IntPtr.Zero; - - /// - /// Specifies how to free the handle. - /// The boolean returned should be true for success and false if the runtime - /// should fire a SafeHandleCriticalFailure MDA (CustomerDebugProbe) if that - /// MDA is enabled. - /// - protected override bool ReleaseHandle() - { - if (!IsInvalid) - { - Interop.Kernel32.GlobalFree(new HandleRef(this, handle)); - } - - handle = IntPtr.Zero; - return true; - } - - public static implicit operator IntPtr(SafeDeviceModeHandle handle) - { - return (handle == null) ? IntPtr.Zero : handle.handle; - } - - public static explicit operator SafeDeviceModeHandle(IntPtr handle) - { - return new SafeDeviceModeHandle(handle); - } - } - - private protected SafeDeviceModeHandle? _modeHandle; - - /// - /// If you have nested PrintControllers, this method won't get called on the inner one. - /// Add initialization code to StartPrint or StartPage instead. - /// - internal void Print(PrintDocument document) - { - // Get the PrintAction for this event - PrintAction printAction; - if (IsPreview) - { - printAction = PrintAction.PrintToPreview; - } - else - { - printAction = document.PrinterSettings.PrintToFile ? PrintAction.PrintToFile : PrintAction.PrintToPrinter; - } - - // Check that user has permission to print to this particular printer - PrintEventArgs printEvent = new PrintEventArgs(printAction); - document.OnBeginPrint(printEvent); - if (printEvent.Cancel) - { - document.OnEndPrint(printEvent); - return; - } - - OnStartPrint(document, printEvent); - if (printEvent.Cancel) - { - document.OnEndPrint(printEvent); - OnEndPrint(document, printEvent); - return; - } - - bool canceled = true; - - try - { - // To enable optimization of the preview dialog, add the following to the config file: - // - // - // - // - canceled = LocalAppContextSwitches.OptimizePrintPreview ? PrintLoopOptimized(document) : PrintLoop(document); - } - finally - { - try - { - document.OnEndPrint(printEvent); - printEvent.Cancel = canceled | printEvent.Cancel; - } - finally - { - OnEndPrint(document, printEvent); - } - } - } - - /// - /// Returns true if print was aborted. - /// - /// - /// If you have nested PrintControllers, this method won't get called on the inner one - /// Add initialization code to StartPrint or StartPage instead. - /// - private bool PrintLoop(PrintDocument document) - { - QueryPageSettingsEventArgs queryEvent = new QueryPageSettingsEventArgs((PageSettings)document.DefaultPageSettings.Clone()); - while (true) - { - document.OnQueryPageSettings(queryEvent); - if (queryEvent.Cancel) - { - return true; - } - - PrintPageEventArgs pageEvent = CreatePrintPageEvent(queryEvent.PageSettings); - Graphics? graphics = OnStartPage(document, pageEvent); - pageEvent.SetGraphics(graphics); - - try - { - document.OnPrintPage(pageEvent); - OnEndPage(document, pageEvent); - } - finally - { - pageEvent.Dispose(); - } - - if (pageEvent.Cancel) - { - return true; - } - else if (!pageEvent.HasMorePages) - { - return false; - } - } - } - - private bool PrintLoopOptimized(PrintDocument document) - { - PrintPageEventArgs? pageEvent = null; - PageSettings documentPageSettings = (PageSettings)document.DefaultPageSettings.Clone(); - QueryPageSettingsEventArgs queryEvent = new QueryPageSettingsEventArgs(documentPageSettings); - while (true) - { - queryEvent.PageSettingsChanged = false; - document.OnQueryPageSettings(queryEvent); - if (queryEvent.Cancel) - { - return true; - } - - if (!queryEvent.PageSettingsChanged) - { - // QueryPageSettings event handler did not change the page settings, - // thus we use default page settings from the document object. - if (pageEvent == null) - { - pageEvent = CreatePrintPageEvent(queryEvent.PageSettings); - } - else - { - // This is not the first page and the settings had not changed since the previous page, - // thus don't re-apply them. - pageEvent.CopySettingsToDevMode = false; - } - - Graphics? graphics = OnStartPage(document, pageEvent); - pageEvent.SetGraphics(graphics); - } - else - { - // Page settings were customized, so use the customized ones in the start page event. - pageEvent = CreatePrintPageEvent(queryEvent.PageSettings); - Graphics? graphics = OnStartPage(document, pageEvent); - pageEvent.SetGraphics(graphics); - } - - try - { - document.OnPrintPage(pageEvent); - OnEndPage(document, pageEvent); - } - finally - { - pageEvent.Graphics!.Dispose(); - pageEvent.SetGraphics(null); - } - - if (pageEvent.Cancel) - { - return true; - } - else if (!pageEvent.HasMorePages) - { - return false; - } - } - } - - private PrintPageEventArgs CreatePrintPageEvent(PageSettings pageSettings) - { - Debug.Assert((_modeHandle != null), "modeHandle is null. Someone must have forgot to call base.StartPrint"); - - - Rectangle pageBounds = pageSettings.GetBounds(_modeHandle); - Rectangle marginBounds = new Rectangle(pageSettings.Margins.Left, - pageSettings.Margins.Top, - pageBounds.Width - (pageSettings.Margins.Left + pageSettings.Margins.Right), - pageBounds.Height - (pageSettings.Margins.Top + pageSettings.Margins.Bottom)); - - PrintPageEventArgs pageEvent = new PrintPageEventArgs(null, marginBounds, pageBounds, pageSettings); - return pageEvent; - } - - /// - /// When overridden in a derived class, begins the control sequence of when and how to print a document. - /// - public virtual void OnStartPrint(PrintDocument document, PrintEventArgs e) - { - _modeHandle = (SafeDeviceModeHandle)document.PrinterSettings.GetHdevmode(document.DefaultPageSettings); - } - - /// - /// When overridden in a derived class, completes the control sequence of when and how to print a document. - /// - public virtual void OnEndPrint(PrintDocument document, PrintEventArgs e) - { - _modeHandle?.Close(); - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintController.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintController.cs index e84ed4c2fe187..2fe1e955f1218 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintController.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintController.cs @@ -1,10 +1,66 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics; +using System.Runtime.InteropServices; + namespace System.Drawing.Printing { - public abstract partial class PrintController + /// + /// Controls how a document is printed. + /// + public abstract class PrintController { + /// + /// Represents a SafeHandle for a Printer's Device Mode struct handle (DEVMODE) + /// + /// + /// DEVMODEs are pretty expensive, so we cache one here and share it + /// with the Standard and Preview print controllers. + /// + internal sealed class SafeDeviceModeHandle : SafeHandle + { + public SafeDeviceModeHandle() : base(IntPtr.Zero, ownsHandle: true) + { + } + + internal SafeDeviceModeHandle(IntPtr handle) : base(IntPtr.Zero, ownsHandle: true) + { + SetHandle(handle); + } + + public override bool IsInvalid => handle == IntPtr.Zero; + + /// + /// Specifies how to free the handle. + /// The boolean returned should be true for success and false if the runtime + /// should fire a SafeHandleCriticalFailure MDA (CustomerDebugProbe) if that + /// MDA is enabled. + /// + protected override bool ReleaseHandle() + { + if (!IsInvalid) + { + Interop.Kernel32.GlobalFree(new HandleRef(this, handle)); + } + + handle = IntPtr.Zero; + return true; + } + + public static implicit operator IntPtr(SafeDeviceModeHandle handle) + { + return (handle == null) ? IntPtr.Zero : handle.handle; + } + + public static explicit operator SafeDeviceModeHandle(IntPtr handle) + { + return new SafeDeviceModeHandle(handle); + } + } + + private protected SafeDeviceModeHandle? _modeHandle; + protected PrintController() { } @@ -25,5 +81,200 @@ protected PrintController() public virtual void OnEndPage(PrintDocument document, PrintPageEventArgs e) { } + + /// + /// If you have nested PrintControllers, this method won't get called on the inner one. + /// Add initialization code to StartPrint or StartPage instead. + /// + internal void Print(PrintDocument document) + { + // Get the PrintAction for this event + PrintAction printAction; + if (IsPreview) + { + printAction = PrintAction.PrintToPreview; + } + else + { + printAction = document.PrinterSettings.PrintToFile ? PrintAction.PrintToFile : PrintAction.PrintToPrinter; + } + + // Check that user has permission to print to this particular printer + PrintEventArgs printEvent = new PrintEventArgs(printAction); + document.OnBeginPrint(printEvent); + if (printEvent.Cancel) + { + document.OnEndPrint(printEvent); + return; + } + + OnStartPrint(document, printEvent); + if (printEvent.Cancel) + { + document.OnEndPrint(printEvent); + OnEndPrint(document, printEvent); + return; + } + + bool canceled = true; + + try + { + // To enable optimization of the preview dialog, add the following to the config file: + // + // + // + // + canceled = LocalAppContextSwitches.OptimizePrintPreview ? PrintLoopOptimized(document) : PrintLoop(document); + } + finally + { + try + { + document.OnEndPrint(printEvent); + printEvent.Cancel = canceled | printEvent.Cancel; + } + finally + { + OnEndPrint(document, printEvent); + } + } + } + + /// + /// Returns true if print was aborted. + /// + /// + /// If you have nested PrintControllers, this method won't get called on the inner one + /// Add initialization code to StartPrint or StartPage instead. + /// + private bool PrintLoop(PrintDocument document) + { + QueryPageSettingsEventArgs queryEvent = new QueryPageSettingsEventArgs((PageSettings)document.DefaultPageSettings.Clone()); + while (true) + { + document.OnQueryPageSettings(queryEvent); + if (queryEvent.Cancel) + { + return true; + } + + PrintPageEventArgs pageEvent = CreatePrintPageEvent(queryEvent.PageSettings); + Graphics? graphics = OnStartPage(document, pageEvent); + pageEvent.SetGraphics(graphics); + + try + { + document.OnPrintPage(pageEvent); + OnEndPage(document, pageEvent); + } + finally + { + pageEvent.Dispose(); + } + + if (pageEvent.Cancel) + { + return true; + } + else if (!pageEvent.HasMorePages) + { + return false; + } + } + } + + private bool PrintLoopOptimized(PrintDocument document) + { + PrintPageEventArgs? pageEvent = null; + PageSettings documentPageSettings = (PageSettings)document.DefaultPageSettings.Clone(); + QueryPageSettingsEventArgs queryEvent = new QueryPageSettingsEventArgs(documentPageSettings); + while (true) + { + queryEvent.PageSettingsChanged = false; + document.OnQueryPageSettings(queryEvent); + if (queryEvent.Cancel) + { + return true; + } + + if (!queryEvent.PageSettingsChanged) + { + // QueryPageSettings event handler did not change the page settings, + // thus we use default page settings from the document object. + if (pageEvent == null) + { + pageEvent = CreatePrintPageEvent(queryEvent.PageSettings); + } + else + { + // This is not the first page and the settings had not changed since the previous page, + // thus don't re-apply them. + pageEvent.CopySettingsToDevMode = false; + } + + Graphics? graphics = OnStartPage(document, pageEvent); + pageEvent.SetGraphics(graphics); + } + else + { + // Page settings were customized, so use the customized ones in the start page event. + pageEvent = CreatePrintPageEvent(queryEvent.PageSettings); + Graphics? graphics = OnStartPage(document, pageEvent); + pageEvent.SetGraphics(graphics); + } + + try + { + document.OnPrintPage(pageEvent); + OnEndPage(document, pageEvent); + } + finally + { + pageEvent.Graphics!.Dispose(); + pageEvent.SetGraphics(null); + } + + if (pageEvent.Cancel) + { + return true; + } + else if (!pageEvent.HasMorePages) + { + return false; + } + } + } + + private PrintPageEventArgs CreatePrintPageEvent(PageSettings pageSettings) + { + Debug.Assert((_modeHandle != null), "modeHandle is null. Someone must have forgot to call base.StartPrint"); + + + Rectangle pageBounds = pageSettings.GetBounds(_modeHandle); + Rectangle marginBounds = new Rectangle(pageSettings.Margins.Left, + pageSettings.Margins.Top, + pageBounds.Width - (pageSettings.Margins.Left + pageSettings.Margins.Right), + pageBounds.Height - (pageSettings.Margins.Top + pageSettings.Margins.Bottom)); + + PrintPageEventArgs pageEvent = new PrintPageEventArgs(null, marginBounds, pageBounds, pageSettings); + return pageEvent; + } + + /// + /// When overridden in a derived class, begins the control sequence of when and how to print a document. + /// + public virtual void OnStartPrint(PrintDocument document, PrintEventArgs e) + { + _modeHandle = (SafeDeviceModeHandle)document.PrinterSettings.GetHdevmode(document.DefaultPageSettings); + } + + /// + /// When overridden in a derived class, completes the control sequence of when and how to print a document. + /// + public virtual void OnEndPrint(PrintDocument document, PrintEventArgs e) + { + _modeHandle?.Close(); + } } } diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintDocument.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintDocument.Unix.cs deleted file mode 100644 index 2d3306ed8a2f6..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintDocument.Unix.cs +++ /dev/null @@ -1,233 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// System.Drawing.PrintDocument.cs -// -// Authors: -// Dennis Hayes (dennish@Raytek.com) -// Herve Poussineau (hpoussineau@fr.st) -// Andreas Nahr (ClassDevelopment@A-SoftTech.com) -// -// (C) 2002 Ximian, Inc -// - -// -// Copyright (C) 2004 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// 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.ComponentModel; - -namespace System.Drawing.Printing -{ - [DefaultProperty("DocumentName"), DefaultEvent("PrintPage")] - public class PrintDocument : System.ComponentModel.Component - { - private PageSettings defaultpagesettings; - private PrinterSettings printersettings; - private PrintController printcontroller; - private string documentname; - private bool originAtMargins; // .NET V1.1 Beta - - public PrintDocument() - { - documentname = "document"; //offical default. - printersettings = new PrinterSettings(); // use default values - defaultpagesettings = (PageSettings)printersettings.DefaultPageSettings.Clone(); - printcontroller = new StandardPrintController(); - } - - // properties - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - [Browsable(false)] - [SRDescription("The settings for the current page.")] - public PageSettings DefaultPageSettings - { - get - { - return defaultpagesettings; - } - set - { - defaultpagesettings = value; - } - } - - // Name of the document, not the file! - [DefaultValue("document")] - [SRDescription("The name of the document.")] - public string DocumentName - { - get - { - return documentname; - } - set - { - documentname = value; - } - } - - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - [Browsable(false)] - [SRDescription("The print controller object.")] - public PrintController PrintController - { - get - { - return printcontroller; - } - set - { - printcontroller = value; - } - } - - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - [Browsable(false)] - [SRDescription("The current settings for the active printer.")] - public PrinterSettings PrinterSettings - { - get - { - return printersettings; - } - set - { - printersettings = value == null ? new PrinterSettings() : value; - } - } - - [DefaultValue(false)] - [SRDescription("Determines if the origin is set at the specified margins.")] - public bool OriginAtMargins - { - get - { - return originAtMargins; - } - set - { - originAtMargins = value; - } - } - - // methods - public void Print() - { - PrintEventArgs printArgs = new PrintEventArgs(); - this.OnBeginPrint(printArgs); - if (printArgs.Cancel) - return; - PrintController.OnStartPrint(this, printArgs); - if (printArgs.Cancel) - return; - - Graphics? g = null; - - if (printArgs.GraphicsContext != null) - { - g = Graphics.FromHdc(printArgs.GraphicsContext.Hdc); - printArgs.GraphicsContext.Graphics = g; - } - - // while there are more pages - PrintPageEventArgs printPageArgs; - do - { - QueryPageSettingsEventArgs queryPageSettingsArgs = new QueryPageSettingsEventArgs( - (DefaultPageSettings.Clone() as PageSettings)!); - OnQueryPageSettings(queryPageSettingsArgs); - - PageSettings pageSettings = queryPageSettingsArgs.PageSettings; - printPageArgs = new PrintPageEventArgs( - g, - pageSettings.Bounds, - new Rectangle(0, 0, pageSettings.PaperSize.Width, pageSettings.PaperSize.Height), - pageSettings); - - // TODO: We should create a graphics context for each page since they can have diferent paper - // size, orientation, etc. We use a single graphic for now to keep Cairo using a single PDF file. - - printPageArgs.GraphicsContext = printArgs.GraphicsContext; - Graphics? pg = PrintController.OnStartPage(this, printPageArgs); - - // assign Graphics in printPageArgs - printPageArgs.SetGraphics(pg); - - if (!printPageArgs.Cancel) - this.OnPrintPage(printPageArgs); - - PrintController.OnEndPage(this, printPageArgs); - if (printPageArgs.Cancel) - break; - } while (printPageArgs.HasMorePages); - - this.OnEndPrint(printArgs); - PrintController.OnEndPrint(this, printArgs); - } - - public override string ToString() => $"[PrintDocument {this.DocumentName}]"; - - // events - protected virtual void OnBeginPrint(PrintEventArgs e) - { - //fire the event - if (BeginPrint != null) - BeginPrint(this, e); - } - - protected virtual void OnEndPrint(PrintEventArgs e) - { - //fire the event - if (EndPrint != null) - EndPrint(this, e); - } - - protected virtual void OnPrintPage(PrintPageEventArgs e) - { - //fire the event - if (PrintPage != null) - PrintPage(this, e); - } - - protected virtual void OnQueryPageSettings(QueryPageSettingsEventArgs e) - { - //fire the event - if (QueryPageSettings != null) - QueryPageSettings(this, e); - } - - [SRDescription("Raised when printing begins")] - public event PrintEventHandler? BeginPrint; - - [SRDescription("Raised when printing ends")] - public event PrintEventHandler? EndPrint; - - [SRDescription("Raised when printing of a new page begins")] - public event PrintPageEventHandler? PrintPage; - - [SRDescription("Raised before printing of a new page begins")] - public event QueryPageSettingsEventHandler? QueryPageSettings; - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintDocument.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintDocument.cs similarity index 100% rename from src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintDocument.Windows.cs rename to src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintDocument.cs diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintEventArgs.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintEventArgs.Unix.cs deleted file mode 100644 index 4fca5d1418aa6..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintEventArgs.Unix.cs +++ /dev/null @@ -1,67 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// System.Drawing.PrintEventArgs.cs -// -// Author: -// Dennis Hayes (dennish@Raytek.com) -// -// (C) 2002 Ximian, Inc -// - -// -// Copyright (C) 2004 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// 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; -//NOTE: Complete! Aparently just a redifiniton of CancleEventArgs specific to Printing. -namespace System.Drawing.Printing -{ - /// - /// Summary description for PrintEventArgs. - /// - public class PrintEventArgs : System.ComponentModel.CancelEventArgs - { - private GraphicsPrinter? graphics_context; - private PrintAction action; - - public PrintEventArgs() - { - } - - internal PrintEventArgs(PrintAction action) - { - this.action = action; - } - - public PrintAction PrintAction - { - get { return action; } - } - - internal GraphicsPrinter? GraphicsContext - { - get { return graphics_context; } - set { graphics_context = value; } - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintEventArgs.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintEventArgs.cs similarity index 100% rename from src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintEventArgs.Windows.cs rename to src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintEventArgs.cs diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintPageEventArgs.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintPageEventArgs.Unix.cs deleted file mode 100644 index 969ee8a474a03..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintPageEventArgs.Unix.cs +++ /dev/null @@ -1,124 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// System.Drawing.PrintPageEventArgs.cs -// -// Author: -// Dennis Hayes (dennish@Raytek.com) -// Herve Poussineau (hpoussineau@fr.st) -// -// (C) 2002 Ximian, Inc -// - -// -// Copyright (C) 2004 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// 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; -namespace System.Drawing.Printing -{ - /// - /// Summary description for PrintPageEventArgs. - /// - public class PrintPageEventArgs : EventArgs - { - private bool cancel; - private Graphics? graphics; - private bool hasmorePages; - private Rectangle marginBounds; - private Rectangle pageBounds; - private PageSettings pageSettings; - private GraphicsPrinter? graphics_context; - - public PrintPageEventArgs(Graphics? graphics, Rectangle marginBounds, - Rectangle pageBounds, PageSettings pageSettings) - { - this.graphics = graphics; - this.marginBounds = marginBounds; - this.pageBounds = pageBounds; - this.pageSettings = pageSettings; - } - public bool Cancel - { - get - { - return cancel; - } - set - { - cancel = value; - } - } - public Graphics? Graphics - { - get - { - return graphics; - } - } - public bool HasMorePages - { - get - { - return hasmorePages; - } - set - { - hasmorePages = value; - } - } - public Rectangle MarginBounds - { - get - { - return marginBounds; - } - } - public Rectangle PageBounds - { - get - { - return pageBounds; - } - } - public PageSettings PageSettings - { - get - { - return pageSettings; - } - } - - // used in PrintDocument.Print() - internal void SetGraphics(Graphics? g) - { - graphics = g; - } - - internal GraphicsPrinter? GraphicsContext - { - get { return graphics_context; } - set { graphics_context = value; } - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintPageEventArgs.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintPageEventArgs.cs similarity index 100% rename from src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintPageEventArgs.Windows.cs rename to src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintPageEventArgs.cs diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrinterSettings.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrinterSettings.Unix.cs deleted file mode 100644 index 4043ec7221345..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrinterSettings.Unix.cs +++ /dev/null @@ -1,554 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// System.Drawing.PrinterSettings.cs -// -// Authors: -// Dennis Hayes (dennish@Raytek.com) -// Herve Poussineau (hpoussineau@fr.st) -// Andreas Nahr (ClassDevelopment@A-SoftTech.com) -// -// (C) 2002 Ximian, Inc -// Copyright (C) 2004,2006 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// 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.Runtime.InteropServices; -using System.Collections; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Drawing.Imaging; - -namespace System.Drawing.Printing -{ - [Serializable] - public class PrinterSettings : ICloneable - { - private string printer_name; - private string? print_filename; - private short copies; - private int maximum_page; - private int minimum_page; - private int from_page; - private int to_page; - private bool collate; - private PrintRange print_range; - internal int maximum_copies; - internal bool can_duplex; - internal bool supports_color; - internal int landscape_angle; - private bool print_tofile; - internal PrinterSettings.PrinterResolutionCollection? printer_resolutions; - internal PrinterSettings.PaperSizeCollection? paper_sizes; - internal PrinterSettings.PaperSourceCollection? paper_sources; - private PageSettings? default_pagesettings; - private Duplex duplex; - internal bool is_plotter; - - internal NameValueCollection? printer_capabilities; // this stores a list of all the printer options. Used only in cups, but might come in handy on win too. - - public PrinterSettings() - { - printer_name = PrintingServices.DefaultPrinter; - ResetToDefaults(); - PrintingServices.LoadPrinterSettings(printer_name, this); - } - - private void ResetToDefaults() - { - printer_resolutions = null; - paper_sizes = null; - paper_sources = null; - default_pagesettings = null; - maximum_page = 9999; - copies = 1; - collate = true; - } - - //properties - - public bool CanDuplex - { - get { return can_duplex; } - } - - public bool Collate - { - get { return collate; } - set { collate = value; } - } - - public short Copies - { - get { return copies; } - set - { - if (value < 0) - throw new ArgumentException(SR.Format(SR.ValueLessThenZero, nameof(Copies))); - - copies = value; - } - } - - public PageSettings DefaultPageSettings - { - get - { - if (default_pagesettings == null) - { - default_pagesettings = new PageSettings(this, - SupportsColor, - false, - // Real defaults are set by LoadPrinterSettings - new PaperSize("A4", 827, 1169), - new PaperSource(PaperSourceKind.FormSource, "Tray"), - new PrinterResolution(PrinterResolutionKind.Medium, 200, 200)); - } - - return default_pagesettings; - } - } - - public Duplex Duplex - { - get { return this.duplex; } - set { this.duplex = value; } - } - - public int FromPage - { - get { return from_page; } - set - { - if (value < 0) - throw new ArgumentException(SR.Format(SR.ValueLessThenZero, nameof(FromPage))); - - from_page = value; - } - } - - public static PrinterSettings.StringCollection InstalledPrinters - { - get { return PrintingServices.InstalledPrinters; } - } - - public bool IsDefaultPrinter - { - get { return (printer_name == PrintingServices.DefaultPrinter); } - } - - public bool IsPlotter - { - get { return is_plotter; } - } - - public bool IsValid - { - get { return PrintingServices.IsPrinterValid(this.printer_name); } - } - - public int LandscapeAngle - { - get { return landscape_angle; } - } - - public int MaximumCopies - { - get { return maximum_copies; } - } - - public int MaximumPage - { - get { return maximum_page; } - set - { - // This not documented but behaves like MinimumPage - if (value < 0) - throw new ArgumentException(SR.Format(SR.ValueLessThenZero, nameof(MaximumPage))); - - maximum_page = value; - } - } - - public int MinimumPage - { - get { return minimum_page; } - set - { - if (value < 0) - throw new ArgumentException(SR.Format(SR.ValueLessThenZero, nameof(MinimumPage))); - - minimum_page = value; - } - } - - public PrinterSettings.PaperSizeCollection? PaperSizes - { - get - { - if (!this.IsValid) - throw new InvalidPrinterException(this); - - return paper_sizes; - } - } - - public PrinterSettings.PaperSourceCollection? PaperSources - { - get - { - if (!this.IsValid) - throw new InvalidPrinterException(this); - - return paper_sources; - } - } - public string? PrintFileName - { - get { return print_filename; } - set { print_filename = value; } - } - public string PrinterName - { - get { return printer_name; } - set - { - if (printer_name == value) - return; - - printer_name = value; - PrintingServices.LoadPrinterSettings(printer_name, this); - } - } - - public PrinterSettings.PrinterResolutionCollection PrinterResolutions - { - get - { - if (!this.IsValid) - throw new InvalidPrinterException(this); - - if (printer_resolutions == null) - { - printer_resolutions = new PrinterSettings.PrinterResolutionCollection(Array.Empty()); - PrintingServices.LoadPrinterResolutions(printer_name, this); - } - - return printer_resolutions; - } - } - - public PrintRange PrintRange - { - get { return print_range; } - set - { - if (value != PrintRange.AllPages && value != PrintRange.Selection && - value != PrintRange.SomePages) - throw new InvalidEnumArgumentException(SR.Format(SR.ValueNotOneOfValues, nameof(PrintRange), nameof(PrintRange))); - - print_range = value; - } - } - - public bool PrintToFile - { - get { return print_tofile; } - set { print_tofile = value; } - } - - public bool SupportsColor - { - get { return supports_color; } - } - - public int ToPage - { - get { return to_page; } - set - { - if (value < 0) - throw new ArgumentException(SR.Format(SR.ValueLessThenZero, nameof(ToPage))); - - to_page = value; - } - } - - internal NameValueCollection PrinterCapabilities - { - get - { - if (this.printer_capabilities == null) - this.printer_capabilities = new NameValueCollection(); - return this.printer_capabilities; - } - } - - //methods - public object Clone() - { - PrinterSettings ps = new PrinterSettings(); - return ps; - } - - public Graphics CreateMeasurementGraphics() - { - throw new NotImplementedException(); - } - - public Graphics CreateMeasurementGraphics(bool honorOriginAtMargins) - { - throw new NotImplementedException(); - } - - public Graphics CreateMeasurementGraphics(PageSettings pageSettings) - { - throw new NotImplementedException(); - } - - public Graphics CreateMeasurementGraphics(PageSettings pageSettings, bool honorOriginAtMargins) - { - throw new NotImplementedException(); - } - - public IntPtr GetHdevmode() - { - throw new NotImplementedException(); - } - - public IntPtr GetHdevmode(PageSettings pageSettings) - { - throw new NotImplementedException(); - } - - public IntPtr GetHdevnames() - { - throw new NotImplementedException(); - } - - public bool IsDirectPrintingSupported(Image image) - { - throw new NotImplementedException(); - } - - public bool IsDirectPrintingSupported(ImageFormat imageFormat) - { - throw new NotImplementedException(); - } - - public void SetHdevmode(IntPtr hdevmode) - { - throw new NotImplementedException(); - } - - public void SetHdevnames(IntPtr hdevnames) - { - throw new NotImplementedException(); - } - - public override string ToString() => $"Printer [PrinterSettings {printer_name} Copies={copies} Collate={collate} Duplex={can_duplex} FromPage={from_page} LandscapeAngle={landscape_angle} MaximumCopies={maximum_copies} OutputPort= ToPage={to_page}]"; - - // Public subclasses - #region Public Subclasses - - - public class PaperSourceCollection : ICollection, IEnumerable - { - private ArrayList _PaperSources = new ArrayList(); - - public PaperSourceCollection(PaperSource[] array) - { - foreach (PaperSource ps in array) - _PaperSources.Add(ps); - } - - public int Count { get { return _PaperSources.Count; } } - int ICollection.Count { get { return _PaperSources.Count; } } - bool ICollection.IsSynchronized { get { return false; } } - object ICollection.SyncRoot { get { return this; } } - [EditorBrowsable(EditorBrowsableState.Never)] - public int Add(PaperSource? paperSource) { return _PaperSources.Add(paperSource); } - public void CopyTo(PaperSource[] paperSources, int index) { throw new NotImplementedException(); } - - public virtual PaperSource? this[int index] - { - get { return _PaperSources[index] as PaperSource; } - } - - IEnumerator IEnumerable.GetEnumerator() - { - return _PaperSources.GetEnumerator(); - } - - public IEnumerator GetEnumerator() - { - return _PaperSources.GetEnumerator(); - } - - void ICollection.CopyTo(Array array, int index) - { - _PaperSources.CopyTo(array, index); - } - - internal void Clear() - { - _PaperSources.Clear(); - } - - } - - public class PaperSizeCollection : ICollection, IEnumerable - { - private ArrayList _PaperSizes = new ArrayList(); - - public PaperSizeCollection(PaperSize[] array) - { - foreach (PaperSize ps in array) - _PaperSizes.Add(ps); - } - - public int Count { get { return _PaperSizes.Count; } } - int ICollection.Count { get { return _PaperSizes.Count; } } - bool ICollection.IsSynchronized { get { return false; } } - object ICollection.SyncRoot { get { return this; } } - [EditorBrowsable(EditorBrowsableState.Never)] - public int Add(PaperSize? paperSize) { return _PaperSizes.Add(paperSize); } - public void CopyTo(PaperSize[] paperSizes, int index) { throw new NotImplementedException(); } - - public virtual PaperSize? this[int index] - { - get { return _PaperSizes[index] as PaperSize; } - } - - IEnumerator IEnumerable.GetEnumerator() - { - return _PaperSizes.GetEnumerator(); - } - - public IEnumerator GetEnumerator() - { - return _PaperSizes.GetEnumerator(); - } - - void ICollection.CopyTo(Array array, int index) - { - _PaperSizes.CopyTo(array, index); - } - - internal void Clear() - { - _PaperSizes.Clear(); - } - } - - public class PrinterResolutionCollection : ICollection, IEnumerable - { - private ArrayList _PrinterResolutions = new ArrayList(); - - public PrinterResolutionCollection(PrinterResolution[] array) - { - foreach (PrinterResolution pr in array) - _PrinterResolutions.Add(pr); - } - - public int Count { get { return _PrinterResolutions.Count; } } - int ICollection.Count { get { return _PrinterResolutions.Count; } } - bool ICollection.IsSynchronized { get { return false; } } - object ICollection.SyncRoot { get { return this; } } - [EditorBrowsable(EditorBrowsableState.Never)] - public int Add(PrinterResolution? printerResolution) { return _PrinterResolutions.Add(printerResolution); } - public void CopyTo(PrinterResolution[] printerResolutions, int index) { throw new NotImplementedException(); } - - public virtual PrinterResolution? this[int index] - { - get { return _PrinterResolutions[index] as PrinterResolution; } - } - - IEnumerator IEnumerable.GetEnumerator() - { - return _PrinterResolutions.GetEnumerator(); - } - - public IEnumerator GetEnumerator() - { - return _PrinterResolutions.GetEnumerator(); - } - - void ICollection.CopyTo(Array array, int index) - { - _PrinterResolutions.CopyTo(array, index); - } - - internal void Clear() - { - _PrinterResolutions.Clear(); - } - } - - public class StringCollection : ICollection, IEnumerable - { - private ArrayList _Strings = new ArrayList(); - - public StringCollection(string[] array) - { - foreach (string s in array) - _Strings.Add(s); - } - - public int Count { get { return _Strings.Count; } } - int ICollection.Count { get { return _Strings.Count; } } - bool ICollection.IsSynchronized { get { return false; } } - object ICollection.SyncRoot { get { return this; } } - - public virtual string this[int index] - { - get { return (_Strings[index] as string)!; } - } - [EditorBrowsable(EditorBrowsableState.Never)] - public int Add(string value) { return _Strings.Add(value); } - public void CopyTo(string[] strings, int index) { throw new NotImplementedException(); } - - IEnumerator IEnumerable.GetEnumerator() - { - return _Strings.GetEnumerator(); - } - - public IEnumerator GetEnumerator() - { - return _Strings.GetEnumerator(); - } - - void ICollection.CopyTo(Array array, int index) - { - _Strings.CopyTo(array, index); - } - } - - #endregion - /* - void GetPrintDialogInfo (string printer_name, ref string port, ref string type, ref string status, ref string comment) - { - printing_services.GetPrintDialogInfo (printer_name, ref port, ref type, ref status, ref comment); - } - */ - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrinterSettings.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrinterSettings.cs similarity index 99% rename from src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrinterSettings.Windows.cs rename to src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrinterSettings.cs index c71ab7985cc2e..a4de17eeedbfe 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrinterSettings.Windows.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrinterSettings.cs @@ -15,7 +15,7 @@ namespace System.Drawing.Printing /// /// Information about how a document should be printed, including which printer to print it on. /// - public partial class PrinterSettings : ICloneable + public class PrinterSettings : ICloneable { // All read/write data is stored in managed code, and whenever we need to call Win32, // we create new DEVMODE and DEVNAMES structures. We don't store device capabilities, diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintingServices.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintingServices.Unix.cs deleted file mode 100644 index e40a4a643fc9a..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintingServices.Unix.cs +++ /dev/null @@ -1,1072 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// Copyright (C) 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -// Author: -// -// Jordi Mas i Hernandez, jordimash@gmail.com -// - -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.IO; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading; -using Gdip = System.Drawing.SafeNativeMethods.Gdip; - -namespace System.Drawing.Printing -{ - /// - /// This class is designed to cache the values retrieved by the - /// native printing services, as opposed to GlobalPrintingServices, which - /// doesn't cache any values. - /// - internal static class PrintingServices - { - #region Private Fields - - private static readonly bool s_cupsInitialized = CheckCupsInstalled(); - private static readonly Hashtable s_docInfo = Hashtable.Synchronized(new Hashtable()); - private static Tuple>? s_printers; // cached default printer name and collection of all printers from cups - - #endregion - - #region Properties - - internal static PrinterSettings.StringCollection InstalledPrinters - { - get - { - Volatile.Write(ref s_printers, null); // clear cache to match Windows behavior - - var list = new PrinterSettings.StringCollection(Array.Empty()); - - foreach (KeyValuePair key in EnsurePrintersInitialized().Item2) - { - list.Add(key.Key); - } - - return list; - } - } - - internal static string DefaultPrinter => EnsurePrintersInitialized().Item1; - - #endregion - - - #region Methods - - /// - /// Do a cups call to check if it is installed - /// - private static bool CheckCupsInstalled() - { - try - { - LibcupsNative.cupsGetDefault(); - } - catch (DllNotFoundException) - { - System.Diagnostics.Debug.WriteLine("libcups not found. To have printing support, you need cups installed"); - return false; - } - - return true; - } - - /// - /// Open the printer's PPD file - /// - /// Printer name, returned from cupsGetDests - private static IntPtr OpenPrinter(string printer) - { - try - { - IntPtr ptr = LibcupsNative.cupsGetPPD(printer); - string ppd_filename = Marshal.PtrToStringAnsi(ptr)!; - IntPtr ppd_handle = LibcupsNative.ppdOpenFile(ppd_filename); - return ppd_handle; - } - catch (Exception) - { - System.Diagnostics.Debug.WriteLine("There was an error opening the printer {0}. Please check your cups installation."); - } - return IntPtr.Zero; - } - - /// - /// Close the printer file - /// - /// PPD handle - private static void ClosePrinter(ref IntPtr handle) - { - try - { - if (handle != IntPtr.Zero) - LibcupsNative.ppdClose(handle); - } - finally - { - handle = IntPtr.Zero; - } - } - - private static int OpenDests(ref IntPtr ptr) - { - try - { - return LibcupsNative.cupsGetDests(ref ptr); - } - catch - { - ptr = IntPtr.Zero; - } - return 0; - } - - private static void CloseDests(ref IntPtr ptr, int count) - { - try - { - if (ptr != IntPtr.Zero) - LibcupsNative.cupsFreeDests(count, ptr); - } - finally - { - ptr = IntPtr.Zero; - } - } - - /// - /// Checks if a printer has a valid PPD file. - /// - /// Printer name - internal static bool IsPrinterValid(string printer) => - s_cupsInitialized && - !string.IsNullOrEmpty(printer) && - EnsurePrintersInitialized().Item2.ContainsKey(printer); - - /// - /// Loads the printer settings and initializes the PrinterSettings and PageSettings fields - /// - /// Printer name - /// PrinterSettings object to initialize - internal static void LoadPrinterSettings(string printer, PrinterSettings settings) - { - if (!s_cupsInitialized || string.IsNullOrEmpty(printer)) - return; - - Dictionary printers = EnsurePrintersInitialized().Item2; - - if (!printers.TryGetValue(printer, out SysPrn.Printer? p)) - return; - - PrinterSettings? currentSettings = p.Settings; - if (currentSettings != null) - { - settings.can_duplex = currentSettings.can_duplex; - settings.is_plotter = currentSettings.is_plotter; - settings.landscape_angle = currentSettings.landscape_angle; - settings.maximum_copies = currentSettings.maximum_copies; - settings.paper_sizes = currentSettings.paper_sizes; - settings.paper_sources = currentSettings.paper_sources; - settings.printer_capabilities = currentSettings.printer_capabilities; - settings.printer_resolutions = currentSettings.printer_resolutions; - settings.supports_color = currentSettings.supports_color; - return; - } - - settings.PrinterCapabilities.Clear(); - - IntPtr dests = IntPtr.Zero, ptr, ptr_printer, ppd_handle; - string name = string.Empty; - CUPS_DESTS printer_dest; - PPD_FILE ppd; - int ret = 0, cups_dests_size; - NameValueCollection options, paper_names, paper_sources; - - try - { - ret = OpenDests(ref dests); - if (ret == 0) - return; - - cups_dests_size = Marshal.SizeOf(); - ptr = dests; - for (int i = 0; i < ret; i++) - { - ptr_printer = (IntPtr)Marshal.ReadIntPtr(ptr); - if (Marshal.PtrToStringAnsi(ptr_printer)!.Equals(printer)) - { - name = printer; - break; - } - ptr = (IntPtr)((long)ptr + cups_dests_size); - } - - if (!name.Equals(printer)) - { - return; - } - - ppd_handle = OpenPrinter(printer); - if (ppd_handle == IntPtr.Zero) - return; - - printer_dest = Marshal.PtrToStructure(ptr)!; - options = new NameValueCollection(); - paper_names = new NameValueCollection(); - paper_sources = new NameValueCollection(); - string? defsize; - string? defsource; - LoadPrinterOptions(printer_dest.options, printer_dest.num_options, ppd_handle, options, - paper_names, out defsize, - paper_sources, out defsource); - - if (settings.paper_sizes == null) - settings.paper_sizes = new PrinterSettings.PaperSizeCollection(Array.Empty()); - else - settings.paper_sizes.Clear(); - - if (settings.paper_sources == null) - settings.paper_sources = new PrinterSettings.PaperSourceCollection(Array.Empty()); - else - settings.paper_sources.Clear(); - - settings.DefaultPageSettings.PaperSource = LoadPrinterPaperSources(settings, defsource, paper_sources)!; - settings.DefaultPageSettings.PaperSize = LoadPrinterPaperSizes(ppd_handle, settings, defsize, paper_names); - LoadPrinterResolutionsAndDefault(printer, settings, ppd_handle); - - ppd = Marshal.PtrToStructure(ppd_handle)!; - settings.landscape_angle = ppd.landscape; - settings.supports_color = (ppd.color_device == 0) ? false : true; - settings.can_duplex = options["Duplex"] != null; - - ClosePrinter(ref ppd_handle); - - p.Settings = settings; - } - finally - { - CloseDests(ref dests, ret); - } - } - - /// - /// Loads the global options of a printer plus the paper types and trays supported, - /// and sets the default paper size and source tray. - /// - /// The options field of a printer's CUPS_DESTS structure - /// The number of options of the printer - /// A ppd handle for the printer, returned by ppdOpen - /// The list of options - /// A list of types of paper (PageSize) - /// The default paper size, set by LoadOptionList - /// A list of trays(InputSlot) - /// The default source tray, set by LoadOptionList - private static void LoadPrinterOptions(IntPtr options, int numOptions, IntPtr ppd, - NameValueCollection list, - NameValueCollection paper_names, out string? defsize, - NameValueCollection paper_sources, out string? defsource) - { - CUPS_OPTIONS cups_options; - string? option_name, option_value; - int cups_size = Marshal.SizeOf(); - - LoadOptionList(ppd, "PageSize", paper_names, out defsize); - LoadOptionList(ppd, "InputSlot", paper_sources, out defsource); - - for (int j = 0; j < numOptions; j++) - { - cups_options = Marshal.PtrToStructure(options)!; - option_name = Marshal.PtrToStringAnsi(cups_options.name); - option_value = Marshal.PtrToStringAnsi(cups_options.val); - - if (option_name == "PageSize") - defsize = option_value; - else if (option_name == "InputSlot") - defsource = option_value; -#if PrintDebug - Console.WriteLine("{0} = {1}", option_name, option_value); -#endif - - list.Add(option_name, option_value); - - options = (IntPtr)((long)options + cups_size); - } - } - - /// - /// Loads the global options of a printer. - /// - /// The options field of a printer's CUPS_DESTS structure - /// The number of options of the printer - private static NameValueCollection LoadPrinterOptions(IntPtr options, int numOptions) - { - CUPS_OPTIONS cups_options; - string? option_name, option_value; - int cups_size = Marshal.SizeOf(); - NameValueCollection list = new NameValueCollection(); - for (int j = 0; j < numOptions; j++) - { - cups_options = Marshal.PtrToStructure(options)!; - option_name = Marshal.PtrToStringAnsi(cups_options.name); - option_value = Marshal.PtrToStringAnsi(cups_options.val); - -#if PrintDebug - Console.WriteLine("{0} = {1}", option_name, option_value); -#endif - - list.Add(option_name, option_value); - - options = (IntPtr)((long)options + cups_size); - } - return list; - } - - /// - /// Loads a printer's options (selection of paper sizes, paper sources, etc) - /// and sets the default option from the selected list. - /// - /// Printer ppd file handle - /// Name of the option group to load - /// List of loaded options - /// The default option from the loaded options list - private static void LoadOptionList(IntPtr ppd, string option_name, NameValueCollection list, out string? defoption) - { - - IntPtr ptr = IntPtr.Zero; - PPD_OPTION ppd_option; - PPD_CHOICE choice; - int choice_size = Marshal.SizeOf(); - defoption = null; - - ptr = LibcupsNative.ppdFindOption(ppd, option_name); - if (ptr != IntPtr.Zero) - { - ppd_option = Marshal.PtrToStructure(ptr)!; -#if PrintDebug - Console.WriteLine (" OPTION key:{0} def:{1} text: {2}", ppd_option.keyword, ppd_option.defchoice, ppd_option.text); -#endif - defoption = ppd_option.defchoice; - ptr = ppd_option.choices; - for (int c = 0; c < ppd_option.num_choices; c++) - { - choice = Marshal.PtrToStructure(ptr)!; - list.Add(choice.choice, choice.text); -#if PrintDebug - Console.WriteLine (" choice:{0} - text: {1}", choice.choice, choice.text); -#endif - - ptr = (IntPtr)((long)ptr + choice_size); - } - } - } - - /// - /// Loads a printer's available resolutions - /// - /// Printer name - /// PrinterSettings object to fill - internal static void LoadPrinterResolutions(string printer, PrinterSettings settings) - { - IntPtr ppd_handle = OpenPrinter(printer); - if (ppd_handle == IntPtr.Zero) - return; - - LoadPrinterResolutionsAndDefault(printer, settings, ppd_handle); - - ClosePrinter(ref ppd_handle); - } - - /// - /// Create a PrinterResolution from a string Resolution that is set in the PPD option. - /// An example of Resolution is "600x600dpi" or "600dpi". Returns null if malformed or "Unknown". - /// - private static PrinterResolution? ParseResolution(string? resolution) - { - if (string.IsNullOrEmpty(resolution)) - return null; - - int dpiIndex = resolution.IndexOf("dpi", StringComparison.Ordinal); - if (dpiIndex == -1) - { - // Resolution is "Unknown" or unparsable - return null; - } - resolution = resolution.Substring(0, dpiIndex); - - int x_resolution, y_resolution; - try - { - if (resolution.Contains('x')) - { - string[] resolutions = resolution.Split('x'); - x_resolution = Convert.ToInt32(resolutions[0]); - y_resolution = Convert.ToInt32(resolutions[1]); - } - else - { - x_resolution = Convert.ToInt32(resolution); - y_resolution = x_resolution; - } - } - catch (Exception) - { - return null; - } - - return new PrinterResolution(PrinterResolutionKind.Custom, x_resolution, y_resolution); - } - - /// - /// Loads a printer's paper sizes. Returns the default PaperSize, and fills a list of paper_names for use in dialogues - /// - /// PPD printer file handle - /// PrinterSettings object to fill - /// Default paper size, from the global options of the printer - /// List of available paper sizes that gets filled - private static PaperSize LoadPrinterPaperSizes(IntPtr ppd_handle, PrinterSettings settings, - string? def_size, NameValueCollection paper_names) - { - IntPtr ptr; - string real_name; - PPD_FILE ppd; - PPD_SIZE size; - PaperSize ps; - - PaperSize defsize = new PaperSize(GetPaperKind(827, 1169), "A4", 827, 1169); - ppd = Marshal.PtrToStructure(ppd_handle)!; - ptr = ppd.sizes; - float w, h; - for (int i = 0; i < ppd.num_sizes; i++) - { - size = Marshal.PtrToStructure(ptr)!; - real_name = paper_names[size.name]!; - w = size.width * 100 / 72; - h = size.length * 100 / 72; - PaperKind kind = GetPaperKind((int)w, (int)h); - ps = new PaperSize(kind, real_name, (int)w, (int)h); - ps.RawKind = (int)kind; - if (def_size == ps.Kind.ToString()) - defsize = ps; - settings.paper_sizes!.Add(ps); - ptr = (IntPtr)((long)ptr + Marshal.SizeOf()); - } - - return defsize; - - } - - /// - /// Loads a printer's paper sources (trays). Returns the default PaperSource, and fills a list of paper_sources for use in dialogues - /// - /// PrinterSettings object to fill - /// Default paper source, from the global options of the printer - /// List of available paper sizes that gets filled - private static PaperSource? LoadPrinterPaperSources(PrinterSettings settings, string? def_source, - NameValueCollection paper_sources) - { - PaperSourceKind kind; - PaperSource? defsource = null; - foreach (string? source in paper_sources) - { - switch (source) - { - case "Auto": - kind = PaperSourceKind.AutomaticFeed; - break; - case "Standard": - kind = PaperSourceKind.AutomaticFeed; - break; - case "Tray": - kind = PaperSourceKind.AutomaticFeed; - break; - case "Envelope": - kind = PaperSourceKind.Envelope; - break; - case "Manual": - kind = PaperSourceKind.Manual; - break; - default: - kind = PaperSourceKind.Custom; - break; - } - settings.paper_sources!.Add(new PaperSource(kind, paper_sources[source]!)); - if (def_source == source) - defsource = settings.paper_sources[settings.paper_sources.Count - 1]; - } - - if (defsource == null && settings.paper_sources!.Count > 0) - return settings.paper_sources[0]; - return defsource; - } - - /// - /// Sets the available resolutions and default resolution from a - /// printer's PPD file into settings. - /// - private static void LoadPrinterResolutionsAndDefault(string printer, - PrinterSettings settings, IntPtr ppd_handle) - { - if (settings.printer_resolutions == null) - settings.printer_resolutions = new PrinterSettings.PrinterResolutionCollection(Array.Empty()); - else - settings.printer_resolutions.Clear(); - - var printer_resolutions = new NameValueCollection(); - string? defresolution; - LoadOptionList(ppd_handle, "Resolution", printer_resolutions, out defresolution); - foreach (var resolution in printer_resolutions.Keys) - { - var new_resolution = ParseResolution(resolution!.ToString()); - settings.PrinterResolutions.Add(new_resolution); - } - - var default_resolution = ParseResolution(defresolution); - - if (default_resolution == null) - default_resolution = ParseResolution("300dpi")!; - if (printer_resolutions.Count == 0) - settings.PrinterResolutions.Add(default_resolution); - - settings.DefaultPageSettings.PrinterResolution = default_resolution; - } - - /// - /// - private static Tuple> EnsurePrintersInitialized() => - LazyInitializer.EnsureInitialized(ref s_printers, () => - { - string defaultPrinterName = string.Empty; - var printers = new Dictionary(); - - if (s_cupsInitialized) - { - IntPtr dests = IntPtr.Zero; - int n_printers = 0; - - try - { - n_printers = OpenDests(ref dests); - - IntPtr ptr_printers = dests; - for (int i = 0; i < n_printers; i++) - { - var printer = Marshal.PtrToStructure(ptr_printers)!; - string name = Marshal.PtrToStringAnsi(printer.name)!; - - if (printer.is_default == 1 || - string.IsNullOrEmpty(defaultPrinterName)) - { - defaultPrinterName = name; - } - - NameValueCollection options = LoadPrinterOptions(printer.options, printer.num_options); - - string status; - int.TryParse(options["printer-state"], out int state); - switch (state) - { - case 4: - status = "Printing"; - break; - case 5: - status = "Stopped"; - break; - default: - status = "Ready"; - break; - } - - string comment = options["printer-comment"] as string ?? string.Empty; - - printers.Add(name, new SysPrn.Printer(string.Empty, string.Empty, status, comment)); - ptr_printers = (IntPtr)((long)ptr_printers + Marshal.SizeOf()); - } - } - finally - { - CloseDests(ref dests, n_printers); - } - } - - return Tuple.Create(defaultPrinterName, printers); - }); - - /// - /// Gets a printer's settings for use in the print dialogue - /// - /// - /// - /// - /// - /// - internal static void GetPrintDialogInfo(string printer, ref string port, ref string type, ref string status, ref string comment) - { - int count = 0, state = -1; - bool found = false; - CUPS_DESTS cups_dests; - IntPtr dests = IntPtr.Zero, ptr_printers, ptr_printer; - int cups_dests_size = Marshal.SizeOf(); - - if (!s_cupsInitialized) - return; - - try - { - count = OpenDests(ref dests); - - if (count == 0) - return; - - ptr_printers = dests; - - for (int i = 0; i < count; i++) - { - ptr_printer = (IntPtr)Marshal.ReadIntPtr(ptr_printers); - if (Marshal.PtrToStringAnsi(ptr_printer)!.Equals(printer)) - { - found = true; - break; - } - ptr_printers = (IntPtr)((long)ptr_printers + cups_dests_size); - } - - if (!found) - return; - - cups_dests = Marshal.PtrToStructure(ptr_printers)!; - - NameValueCollection options = LoadPrinterOptions(cups_dests.options, cups_dests.num_options); - - if (options["printer-state"] is string printerState) - state = int.Parse(printerState); - - if (options["printer-comment"] is string printerComment) - comment = printerComment; - - switch (state) - { - case 4: - status = "Printing"; - break; - case 5: - status = "Stopped"; - break; - default: - status = "Ready"; - break; - } - } - finally - { - CloseDests(ref dests, count); - } - } - - /// - /// Returns the appropriate PaperKind for the width and height - /// - /// - /// - private static PaperKind GetPaperKind(int width, int height) - { - if (width == 827 && height == 1169) - return PaperKind.A4; - if (width == 583 && height == 827) - return PaperKind.A5; - if (width == 717 && height == 1012) - return PaperKind.B5; - if (width == 693 && height == 984) - return PaperKind.B5Envelope; - if (width == 638 && height == 902) - return PaperKind.C5Envelope; - if (width == 449 && height == 638) - return PaperKind.C6Envelope; - if (width == 1700 && height == 2200) - return PaperKind.CSheet; - if (width == 433 && height == 866) - return PaperKind.DLEnvelope; - if (width == 2200 && height == 3400) - return PaperKind.DSheet; - if (width == 3400 && height == 4400) - return PaperKind.ESheet; - if (width == 725 && height == 1050) - return PaperKind.Executive; - if (width == 850 && height == 1300) - return PaperKind.Folio; - if (width == 850 && height == 1200) - return PaperKind.GermanStandardFanfold; - if (width == 1700 && height == 1100) - return PaperKind.Ledger; - if (width == 850 && height == 1400) - return PaperKind.Legal; - if (width == 927 && height == 1500) - return PaperKind.LegalExtra; - if (width == 850 && height == 1100) - return PaperKind.Letter; - if (width == 927 && height == 1200) - return PaperKind.LetterExtra; - if (width == 850 && height == 1269) - return PaperKind.LetterPlus; - if (width == 387 && height == 750) - return PaperKind.MonarchEnvelope; - if (width == 387 && height == 887) - return PaperKind.Number9Envelope; - if (width == 413 && height == 950) - return PaperKind.Number10Envelope; - if (width == 450 && height == 1037) - return PaperKind.Number11Envelope; - if (width == 475 && height == 1100) - return PaperKind.Number12Envelope; - if (width == 500 && height == 1150) - return PaperKind.Number14Envelope; - if (width == 363 && height == 650) - return PaperKind.PersonalEnvelope; - if (width == 1000 && height == 1100) - return PaperKind.Standard10x11; - if (width == 1000 && height == 1400) - return PaperKind.Standard10x14; - if (width == 1100 && height == 1700) - return PaperKind.Standard11x17; - if (width == 1200 && height == 1100) - return PaperKind.Standard12x11; - if (width == 1500 && height == 1100) - return PaperKind.Standard15x11; - if (width == 900 && height == 1100) - return PaperKind.Standard9x11; - if (width == 550 && height == 850) - return PaperKind.Statement; - if (width == 1100 && height == 1700) - return PaperKind.Tabloid; - if (width == 1487 && height == 1100) - return PaperKind.USStandardFanfold; - - return PaperKind.Custom; - } - - #endregion - - #region Print job methods - - private static string? tmpfile; - - /// - /// Gets a pointer to an options list parsed from the printer's current settings, to use when setting up the printing job - /// - /// - /// - /// - internal static int GetCupsOptions(PrinterSettings printer_settings, PageSettings page_settings, out IntPtr options) - { - options = IntPtr.Zero; - - PaperSize size = page_settings.PaperSize; - int width = size.Width * 72 / 100; - int height = size.Height * 72 / 100; - - var sb = new StringBuilder(); - sb.Append("copies=").Append(printer_settings.Copies).Append(' ') - .Append("Collate=").Append(printer_settings.Collate).Append(' ') - .Append("ColorModel=").Append(page_settings.Color ? "Color" : "Black").Append(' ') - .Append("PageSize=Custom.").Append(width).Append('x').Append(height).Append(' ') - .Append("landscape=").Append(page_settings.Landscape); - - if (printer_settings.CanDuplex) - { - if (printer_settings.Duplex == Duplex.Simplex) - { - sb.Append(" Duplex=None"); - } - else - { - sb.Append(" Duplex=DuplexNoTumble"); - } - } - - return LibcupsNative.cupsParseOptions(sb.ToString(), 0, ref options); - } - - internal static bool StartDoc(GraphicsPrinter gr, string doc_name, string output_file) - { - DOCINFO doc = (DOCINFO)s_docInfo[gr.Hdc]!; - doc.title = doc_name; - return true; - } - - internal static bool EndDoc(GraphicsPrinter gr) - { - DOCINFO doc = (DOCINFO)s_docInfo[gr.Hdc]!; - - gr.Graphics!.Dispose(); // Dispose object to force surface finish - - IntPtr options; - int options_count = GetCupsOptions(doc.settings, doc.default_page_settings, out options); - - LibcupsNative.cupsPrintFile(doc.settings.PrinterName, doc.filename, doc.title, options_count, options); - LibcupsNative.cupsFreeOptions(options_count, options); - s_docInfo.Remove(gr.Hdc); - if (tmpfile != null) - { - try - { File.Delete(tmpfile); } - catch { } - } - return true; - } - - internal static bool StartPage(GraphicsPrinter gr) - { - return true; - } - - internal static bool EndPage(GraphicsPrinter gr) - { - Gdip.GdipGetPostScriptSavePage(gr.Hdc); - return true; - } - - // Unfortunately, PrinterSettings and PageSettings couldn't be referencing each other, - // thus we need to pass them separately - internal static IntPtr CreateGraphicsContext(PrinterSettings settings, PageSettings default_page_settings) - { - IntPtr graphics = IntPtr.Zero; - string? name; - if (!settings.PrintToFile) - { - sbyte[] buffer = new sbyte[1024]; - int length = buffer.Length; - LibcupsNative.cupsTempFd(buffer, length); - unsafe - { - fixed (sbyte* ptr = buffer) - { - tmpfile = name = new string(ptr); - } - } - } - else - name = settings.PrintFileName!; - - PaperSize psize = default_page_settings.PaperSize; - int width, height; - if (default_page_settings.Landscape) - { // Swap in case of landscape - width = psize.Height; - height = psize.Width; - } - else - { - width = psize.Width; - height = psize.Height; - } - - Gdip.GdipGetPostScriptGraphicsContext(name, - width * 72 / 100, - height * 72 / 100, - default_page_settings.PrinterResolution.X, - default_page_settings.PrinterResolution.Y, ref graphics); - - DOCINFO doc = default; - doc.filename = name; - doc.settings = settings; - doc.default_page_settings = default_page_settings; - s_docInfo.Add(graphics, doc); - - return graphics; - } - - #endregion - -#pragma warning disable 649 - #region Struct - public struct DOCINFO - { - public PrinterSettings settings; - public PageSettings default_page_settings; - public string title; - public string filename; - } - - public struct PPD_SIZE - { - public int marked; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 42)] - public string name; - public float width; - public float length; - public float left; - public float bottom; - public float right; - public float top; - } - - public struct PPD_GROUP - { - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 40)] - public string text; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 42)] - public string name; - public int num_options; - public IntPtr options; - public int num_subgroups; - public IntPtr subgrups; - } - - public struct PPD_OPTION - { - public byte conflicted; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 41)] - public string keyword; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 41)] - public string defchoice; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 81)] - public string text; - public int ui; - public int section; - public float order; - public int num_choices; - public IntPtr choices; - } - - public struct PPD_CHOICE - { - public byte marked; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 41)] - public string choice; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 81)] - public string text; - public IntPtr code; - public IntPtr option; - } - - public struct PPD_FILE - { - public int language_level; - public int color_device; - public int variable_sizes; - public int accurate_screens; - public int contone_only; - public int landscape; - public int model_number; - public int manual_copies; - public int throughput; - public int colorspace; - public IntPtr patches; - public int num_emulations; - public IntPtr emulations; - public IntPtr jcl_begin; - public IntPtr jcl_ps; - public IntPtr jcl_end; - public IntPtr lang_encoding; - public IntPtr lang_version; - public IntPtr modelname; - public IntPtr ttrasterizer; - public IntPtr manufacturer; - public IntPtr product; - public IntPtr nickname; - public IntPtr shortnickname; - public int num_groups; - public IntPtr groups; - public int num_sizes; - public IntPtr sizes; - - /* There is more data after this that we are not using*/ - } - - - public struct CUPS_OPTIONS - { - public IntPtr name; - public IntPtr val; - } - - public struct CUPS_DESTS - { - public IntPtr name; - public IntPtr instance; - public int is_default; - public int num_options; - public IntPtr options; - } - - #endregion -#pragma warning restore 649 - internal static void LoadDefaultResolutions(PrinterSettings.PrinterResolutionCollection col) - { - col.Add(new PrinterResolution(PrinterResolutionKind.High, (int)PrinterResolutionKind.High, -1)); - col.Add(new PrinterResolution(PrinterResolutionKind.Medium, (int)PrinterResolutionKind.Medium, -1)); - col.Add(new PrinterResolution(PrinterResolutionKind.Low, (int)PrinterResolutionKind.Low, -1)); - col.Add(new PrinterResolution(PrinterResolutionKind.Draft, (int)PrinterResolutionKind.Draft, -1)); - } - } - - internal static class SysPrn - { - internal static void GetPrintDialogInfo(string printer, ref string port, ref string type, ref string status, ref string comment) - { - PrintingServices.GetPrintDialogInfo(printer, ref port, ref type, ref status, ref comment); - } - - internal sealed class Printer - { - public readonly string Comment; - public readonly string Port; - public readonly string Type; - public readonly string Status; - public PrinterSettings? Settings; - - public Printer(string port, string type, string status, string comment) - { - Port = port; - Type = type; - Status = status; - Comment = comment; - } - } - } - - internal sealed class GraphicsPrinter - { - private Graphics? graphics; - private IntPtr hDC; - - internal GraphicsPrinter(Graphics? gr, IntPtr dc) - { - graphics = gr; - hDC = dc; - } - - internal Graphics? Graphics - { - get { return graphics; } - set { graphics = value; } - } - internal IntPtr Hdc { get { return hDC; } } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/StandardPrintController.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/StandardPrintController.Unix.cs deleted file mode 100644 index 625429566e485..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/StandardPrintController.Unix.cs +++ /dev/null @@ -1,71 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// System.Drawing.StandardPrintController.cs -// -// Author: -// Dennis Hayes (dennish@Raytek.com) -// Herve Poussineau (hpoussineau@fr.st) -// Jordi Mas i Hernandez (jordimash@gmail.com) -// -// (C) 2002 Ximian, Inc -// - -// -// Copyright (C) 2004 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// 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; - -namespace System.Drawing.Printing -{ - public class StandardPrintController : PrintController - { - public StandardPrintController() - { - } - - public override void OnEndPage(PrintDocument document, PrintPageEventArgs e) - { - PrintingServices.EndPage(e.GraphicsContext!); - } - - public override void OnStartPrint(PrintDocument document, PrintEventArgs e) - { - IntPtr dc = PrintingServices.CreateGraphicsContext(document.PrinterSettings, document.DefaultPageSettings); - e.GraphicsContext = new GraphicsPrinter(null, dc); - PrintingServices.StartDoc(e.GraphicsContext, document.DocumentName, string.Empty); - } - - public override void OnEndPrint(PrintDocument document, PrintEventArgs e) - { - PrintingServices.EndDoc(e.GraphicsContext!); - } - - public override Graphics? OnStartPage(PrintDocument document, PrintPageEventArgs e) - { - PrintingServices.StartPage(e.GraphicsContext!); - return e.Graphics; - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Region.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Region.Unix.cs deleted file mode 100644 index cca9d5bec201b..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Region.Unix.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Drawing2D; -using System.Drawing.Internal; -using System.Runtime.InteropServices; -using Gdip = System.Drawing.SafeNativeMethods.Gdip; - -namespace System.Drawing -{ - public partial class Region - { - public void ReleaseHrgn(IntPtr regionHandle) - { - if (regionHandle == IntPtr.Zero) - { - throw new ArgumentNullException(nameof(regionHandle)); - } - - // for libgdiplus HRGN == GpRegion*, and we check the return code - int status = Gdip.GdipDeleteRegion(new HandleRef(this, regionHandle)); - Gdip.CheckStatus(status); - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Region.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Region.Windows.cs deleted file mode 100644 index 2c38f3d021982..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Region.Windows.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Drawing.Drawing2D; -using System.Drawing.Internal; -using System.Runtime.InteropServices; - -namespace System.Drawing -{ - public partial class Region - { - public void ReleaseHrgn(IntPtr regionHandle) - { - if (regionHandle == IntPtr.Zero) - { - throw new ArgumentNullException(nameof(regionHandle)); - } - - Interop.Gdi32.DeleteObject(new HandleRef(this, regionHandle)); - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Region.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Region.cs index 50eb520a9c1af..f7ff48efb3dd1 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Region.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Region.cs @@ -10,7 +10,7 @@ namespace System.Drawing { - public sealed partial class Region : MarshalByRefObject, IDisposable + public sealed class Region : MarshalByRefObject, IDisposable { #if FINALIZATION_WATCH private string allocationSite = Graphics.GetAllocationStack(); @@ -36,14 +36,18 @@ public Region(Rectangle rect) SetNativeRegion(region); } - public Region(GraphicsPath path!!) + public Region(GraphicsPath path) { + ArgumentNullException.ThrowIfNull(path); + Gdip.CheckStatus(Gdip.GdipCreateRegionPath(new HandleRef(path, path._nativePath), out IntPtr region)); SetNativeRegion(region); } - public Region(RegionData rgnData!!) + public Region(RegionData rgnData) { + ArgumentNullException.ThrowIfNull(rgnData); + Gdip.CheckStatus(Gdip.GdipCreateRegionRgnData( rgnData.Data, rgnData.Data.Length, @@ -73,6 +77,15 @@ public Region Clone() Gdip.CheckStatus(Gdip.GdipCloneRegion(new HandleRef(this, NativeRegion), out IntPtr region)); return new Region(region); } + public void ReleaseHrgn(IntPtr regionHandle) + { + if (regionHandle == IntPtr.Zero) + { + throw new ArgumentNullException(nameof(regionHandle)); + } + + Interop.Gdi32.DeleteObject(new HandleRef(this, regionHandle)); + } public void Dispose() { @@ -130,13 +143,17 @@ public void Intersect(Rectangle rect) Gdip.CheckStatus(Gdip.GdipCombineRegionRectI(new HandleRef(this, NativeRegion), ref rect, CombineMode.Intersect)); } - public void Intersect(GraphicsPath path!!) + public void Intersect(GraphicsPath path) { + ArgumentNullException.ThrowIfNull(path); + Gdip.CheckStatus(Gdip.GdipCombineRegionPath(new HandleRef(this, NativeRegion), new HandleRef(path, path._nativePath), CombineMode.Intersect)); } - public void Intersect(Region region!!) + public void Intersect(Region region) { + ArgumentNullException.ThrowIfNull(region); + Gdip.CheckStatus(Gdip.GdipCombineRegionRegion(new HandleRef(this, NativeRegion), new HandleRef(region, region.NativeRegion), CombineMode.Intersect)); } @@ -150,13 +167,17 @@ public void Union(Rectangle rect) Gdip.CheckStatus(Gdip.GdipCombineRegionRectI(new HandleRef(this, NativeRegion), ref rect, CombineMode.Union)); } - public void Union(GraphicsPath path!!) + public void Union(GraphicsPath path) { + ArgumentNullException.ThrowIfNull(path); + Gdip.CheckStatus(Gdip.GdipCombineRegionPath(new HandleRef(this, NativeRegion), new HandleRef(path, path._nativePath), CombineMode.Union)); } - public void Union(Region region!!) + public void Union(Region region) { + ArgumentNullException.ThrowIfNull(region); + Gdip.CheckStatus(Gdip.GdipCombineRegionRegion(new HandleRef(this, NativeRegion), new HandleRef(region, region.NativeRegion), CombineMode.Union)); } @@ -170,13 +191,17 @@ public void Xor(Rectangle rect) Gdip.CheckStatus(Gdip.GdipCombineRegionRectI(new HandleRef(this, NativeRegion), ref rect, CombineMode.Xor)); } - public void Xor(GraphicsPath path!!) + public void Xor(GraphicsPath path) { + ArgumentNullException.ThrowIfNull(path); + Gdip.CheckStatus(Gdip.GdipCombineRegionPath(new HandleRef(this, NativeRegion), new HandleRef(path, path._nativePath), CombineMode.Xor)); } - public void Xor(Region region!!) + public void Xor(Region region) { + ArgumentNullException.ThrowIfNull(region); + Gdip.CheckStatus(Gdip.GdipCombineRegionRegion(new HandleRef(this, NativeRegion), new HandleRef(region, region.NativeRegion), CombineMode.Xor)); } @@ -190,16 +215,20 @@ public void Exclude(Rectangle rect) Gdip.CheckStatus(Gdip.GdipCombineRegionRectI(new HandleRef(this, NativeRegion), ref rect, CombineMode.Exclude)); } - public void Exclude(GraphicsPath path!!) + public void Exclude(GraphicsPath path) { + ArgumentNullException.ThrowIfNull(path); + Gdip.CheckStatus(Gdip.GdipCombineRegionPath( new HandleRef(this, NativeRegion), new HandleRef(path, path._nativePath), CombineMode.Exclude)); } - public void Exclude(Region region!!) + public void Exclude(Region region) { + ArgumentNullException.ThrowIfNull(region); + Gdip.CheckStatus(Gdip.GdipCombineRegionRegion( new HandleRef(this, NativeRegion), new HandleRef(region, region.NativeRegion), @@ -216,13 +245,17 @@ public void Complement(Rectangle rect) Gdip.CheckStatus(Gdip.GdipCombineRegionRectI(new HandleRef(this, NativeRegion), ref rect, CombineMode.Complement)); } - public void Complement(GraphicsPath path!!) + public void Complement(GraphicsPath path) { + ArgumentNullException.ThrowIfNull(path); + Gdip.CheckStatus(Gdip.GdipCombineRegionPath(new HandleRef(this, NativeRegion), new HandleRef(path, path._nativePath), CombineMode.Complement)); } - public void Complement(Region region!!) + public void Complement(Region region) { + ArgumentNullException.ThrowIfNull(region); + Gdip.CheckStatus(Gdip.GdipCombineRegionRegion(new HandleRef(this, NativeRegion), new HandleRef(region, region.NativeRegion), CombineMode.Complement)); } @@ -236,39 +269,52 @@ public void Translate(int dx, int dy) Gdip.CheckStatus(Gdip.GdipTranslateRegionI(new HandleRef(this, NativeRegion), dx, dy)); } - public void Transform(Matrix matrix!!) + public void Transform(Matrix matrix) { + ArgumentNullException.ThrowIfNull(matrix); + Gdip.CheckStatus(Gdip.GdipTransformRegion( new HandleRef(this, NativeRegion), new HandleRef(matrix, matrix.NativeMatrix))); } - public RectangleF GetBounds(Graphics g!!) + public RectangleF GetBounds(Graphics g) { + ArgumentNullException.ThrowIfNull(g); + Gdip.CheckStatus(Gdip.GdipGetRegionBounds(new HandleRef(this, NativeRegion), new HandleRef(g, g.NativeGraphics), out RectangleF bounds)); return bounds; } - public IntPtr GetHrgn(Graphics g!!) + public IntPtr GetHrgn(Graphics g) { + ArgumentNullException.ThrowIfNull(g); + Gdip.CheckStatus(Gdip.GdipGetRegionHRgn(new HandleRef(this, NativeRegion), new HandleRef(g, g.NativeGraphics), out IntPtr hrgn)); return hrgn; } - public bool IsEmpty(Graphics g!!) + public bool IsEmpty(Graphics g) { + ArgumentNullException.ThrowIfNull(g); + Gdip.CheckStatus(Gdip.GdipIsEmptyRegion(new HandleRef(this, NativeRegion), new HandleRef(g, g.NativeGraphics), out int isEmpty)); return isEmpty != 0; } - public bool IsInfinite(Graphics g!!) + public bool IsInfinite(Graphics g) { + ArgumentNullException.ThrowIfNull(g); + Gdip.CheckStatus(Gdip.GdipIsInfiniteRegion(new HandleRef(this, NativeRegion), new HandleRef(g, g.NativeGraphics), out int isInfinite)); return isInfinite != 0; } - public bool Equals(Region region!!, Graphics g!!) + public bool Equals(Region region, Graphics g) { + ArgumentNullException.ThrowIfNull(region); + ArgumentNullException.ThrowIfNull(g); + Gdip.CheckStatus(Gdip.GdipIsEqualRegion(new HandleRef(this, NativeRegion), new HandleRef(region, region.NativeRegion), new HandleRef(g, g.NativeGraphics), out int isEqual)); return isEqual != 0; } @@ -351,8 +397,10 @@ public bool IsVisible(Rectangle rect, Graphics? g) return isVisible != 0; } - public unsafe RectangleF[] GetRegionScans(Matrix matrix!!) + public unsafe RectangleF[] GetRegionScans(Matrix matrix) { + ArgumentNullException.ThrowIfNull(matrix); + Gdip.CheckStatus(Gdip.GdipGetRegionScansCount( new HandleRef(this, NativeRegion), out int count, diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/SolidBrush.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/SolidBrush.cs index 6ff77667eae7b..d19d983688d99 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/SolidBrush.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/SolidBrush.cs @@ -2,21 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Drawing.Internal; using System.Runtime.InteropServices; using Gdip = System.Drawing.SafeNativeMethods.Gdip; namespace System.Drawing { -#if FEATURE_SYSTEM_EVENTS - using System.Drawing.Internal; -#endif - - public sealed class SolidBrush : Brush -#pragma warning disable SA1001 -#if FEATURE_SYSTEM_EVENTS - , ISystemColorTracker -#endif -#pragma warning restore SA1001 + public sealed class SolidBrush : Brush, ISystemColorTracker { // GDI+ doesn't understand system colors, so we need to cache the value here. private Color _color = Color.Empty; @@ -26,18 +18,16 @@ public SolidBrush(Color color) { _color = color; - IntPtr nativeBrush = IntPtr.Zero; + IntPtr nativeBrush; int status = Gdip.GdipCreateSolidFill(_color.ToArgb(), out nativeBrush); Gdip.CheckStatus(status); SetNativeBrushInternal(nativeBrush); -#if FEATURE_SYSTEM_EVENTS if (_color.IsSystemColor) { SystemColorTracker.Add(this); } -#endif } internal SolidBrush(Color color, bool immutable) : this(color) @@ -101,19 +91,15 @@ public Color Color if (_color != value) { -#if FEATURE_SYSTEM_EVENTS Color oldColor = _color; -#endif InternalSetColor(value); -#if FEATURE_SYSTEM_EVENTS // NOTE: We never remove brushes from the active list, so if someone is // changing their brush colors a lot, this could be a problem. if (value.IsSystemColor && !oldColor.IsSystemColor) { SystemColorTracker.Add(this); } -#endif } } } @@ -127,7 +113,6 @@ private void InternalSetColor(Color value) _color = value; } -#if FEATURE_SYSTEM_EVENTS void ISystemColorTracker.OnSystemColorChanged() { if (NativeBrush != IntPtr.Zero) @@ -135,6 +120,5 @@ void ISystemColorTracker.OnSystemColorChanged() InternalSetColor(_color); } } -#endif } } diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/StringFormat.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/StringFormat.cs index fc910b3ce9589..be9245ae46ea1 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/StringFormat.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/StringFormat.cs @@ -53,8 +53,10 @@ public StringFormat(StringFormatFlags options, int language) /// Initializes a new instance of the class from the specified /// existing . /// - public StringFormat(StringFormat format!!) + public StringFormat(StringFormat format) { + ArgumentNullException.ThrowIfNull(format); + int status = Gdip.GdipCloneStringFormat(new HandleRef(format, format.nativeFormat), out nativeFormat); if (status != Gdip.Ok) diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/SystemFonts.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/SystemFonts.Unix.cs deleted file mode 100644 index 73f6308325d52..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/SystemFonts.Unix.cs +++ /dev/null @@ -1,77 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// Copyright (C) 2005, 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -// Authors: -// Jordi Mas i Hernandez -// Sebastien Pouliot -// - - -namespace System.Drawing -{ - - public static partial class SystemFonts - { - public static Font CaptionFont - { - get { return new Font("Microsoft Sans Serif", 11, "CaptionFont"); } - } - - public static Font DefaultFont - { - get { return new Font("Microsoft Sans Serif", 8.25f, "DefaultFont"); } - } - - public static Font DialogFont - { - get { return new Font("Tahoma", 8, "DialogFont"); } - } - - public static Font IconTitleFont - { - get { return new Font("Microsoft Sans Serif", 11, "IconTitleFont"); } - } - - public static Font MenuFont - { - get { return new Font("Microsoft Sans Serif", 11, "MenuFont"); } - } - - public static Font MessageBoxFont - { - get { return new Font("Microsoft Sans Serif", 11, "MessageBoxFont"); } - } - - public static Font SmallCaptionFont - { - get { return new Font("Microsoft Sans Serif", 11, "SmallCaptionFont"); } - } - - public static Font StatusFont - { - get { return new Font("Microsoft Sans Serif", 11, "StatusFont"); } - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/SystemFonts.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/SystemFonts.Windows.cs deleted file mode 100644 index 67ec943025754..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/SystemFonts.Windows.cs +++ /dev/null @@ -1,253 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics; -using System.IO; -using System.Runtime.InteropServices; - -namespace System.Drawing -{ - public static partial class SystemFonts - { - private static unsafe bool GetNonClientMetrics(out Interop.User32.NONCLIENTMETRICS metrics) - { - metrics = new Interop.User32.NONCLIENTMETRICS { cbSize = (uint)sizeof(Interop.User32.NONCLIENTMETRICS) }; - fixed (void* m = &metrics) - { - return Interop.User32.SystemParametersInfoW(Interop.User32.SystemParametersAction.SPI_GETNONCLIENTMETRICS, metrics.cbSize, m, 0); - } - } - - public static Font? CaptionFont - { - get - { - Font? captionFont = null; - - if (GetNonClientMetrics(out Interop.User32.NONCLIENTMETRICS metrics)) - { - captionFont = GetFontFromData(metrics.lfCaptionFont); - captionFont.SetSystemFontName(nameof(CaptionFont)); - } - - return captionFont; - } - } - - public static Font? SmallCaptionFont - { - get - { - Font? smcaptionFont = null; - - if (GetNonClientMetrics(out Interop.User32.NONCLIENTMETRICS metrics)) - { - smcaptionFont = GetFontFromData(metrics.lfSmCaptionFont); - smcaptionFont.SetSystemFontName(nameof(SmallCaptionFont)); - } - - return smcaptionFont; - } - } - - public static Font? MenuFont - { - get - { - Font? menuFont = null; - - if (GetNonClientMetrics(out Interop.User32.NONCLIENTMETRICS metrics)) - { - menuFont = GetFontFromData(metrics.lfMenuFont); - menuFont.SetSystemFontName(nameof(MenuFont)); - } - - return menuFont; - } - } - - public static Font? StatusFont - { - get - { - Font? statusFont = null; - - if (GetNonClientMetrics(out Interop.User32.NONCLIENTMETRICS metrics)) - { - statusFont = GetFontFromData(metrics.lfStatusFont); - statusFont.SetSystemFontName(nameof(StatusFont)); - } - - return statusFont; - } - } - - public static Font? MessageBoxFont - { - get - { - Font? messageBoxFont = null; - - if (GetNonClientMetrics(out Interop.User32.NONCLIENTMETRICS metrics)) - { - messageBoxFont = GetFontFromData(metrics.lfMessageFont); - messageBoxFont.SetSystemFontName(nameof(MessageBoxFont)); - } - - return messageBoxFont; - } - } - - private static bool IsCriticalFontException(Exception ex) - { - return !( - // In any of these cases we'll handle the exception. - ex is ExternalException || - ex is ArgumentException || - ex is OutOfMemoryException || // GDI+ throws this one for many reasons other than actual OOM. - ex is InvalidOperationException || - ex is NotImplementedException || - ex is FileNotFoundException); - } - - public static unsafe Font? IconTitleFont - { - get - { - Font? iconTitleFont = null; - - Interop.User32.LOGFONT itfont = default; - if (Interop.User32.SystemParametersInfoW(Interop.User32.SystemParametersAction.SPI_GETICONTITLELOGFONT, (uint)sizeof(Interop.User32.LOGFONT), &itfont, 0)) - { - iconTitleFont = GetFontFromData(itfont); - iconTitleFont.SetSystemFontName(nameof(IconTitleFont)); - } - - return iconTitleFont; - } - } - - public static Font DefaultFont - { - get - { - Font? defaultFont = null; - - // For Arabic systems, always return Tahoma 8. - if ((ushort)Interop.Kernel32.GetSystemDefaultLCID() == 0x0001) - { - try - { - defaultFont = new Font("Tahoma", 8); - } - catch (Exception ex) when (!IsCriticalFontException(ex)) { } - } - - // First try DEFAULT_GUI. - if (defaultFont == null) - { - IntPtr handle = Interop.Gdi32.GetStockObject(Interop.Gdi32.StockObject.DEFAULT_GUI_FONT); - try - { - using (Font fontInWorldUnits = Font.FromHfont(handle)) - { - defaultFont = FontInPoints(fontInWorldUnits); - } - } - catch (ArgumentException) - { - // This can happen in theory if we end up pulling a non-TrueType font - } - } - - // If DEFAULT_GUI didn't work, try Tahoma. - if (defaultFont == null) - { - try - { - defaultFont = new Font("Tahoma", 8); - } - catch (ArgumentException) - { - } - } - - // Use GenericSansSerif as a last resort - this will always work. - if (defaultFont == null) - { - defaultFont = new Font(FontFamily.GenericSansSerif, 8); - } - - if (defaultFont.Unit != GraphicsUnit.Point) - { - defaultFont = FontInPoints(defaultFont); - } - - Debug.Assert(defaultFont != null, "defaultFont wasn't set."); - - defaultFont.SetSystemFontName(nameof(DefaultFont)); - return defaultFont; - } - } - - public static Font DialogFont - { - get - { - Font? dialogFont = null; - - if ((ushort)Interop.Kernel32.GetSystemDefaultLCID() == 0x0011) - { - // Always return DefaultFont for Japanese cultures. - dialogFont = DefaultFont; - } - else - { - try - { - // Use MS Shell Dlg 2, 8pt for anything other than Japanese. - dialogFont = new Font("MS Shell Dlg 2", 8); - } - catch (ArgumentException) - { - // This can happen in theory if we end up pulling a non-TrueType font - } - } - - if (dialogFont == null) - { - dialogFont = DefaultFont; - } - else if (dialogFont.Unit != GraphicsUnit.Point) - { - dialogFont = FontInPoints(dialogFont); - } - - // For Japanese cultures, SystemFonts.DefaultFont returns a new Font object every time it is invoked. - // So for Japanese we return the DefaultFont with its SystemFontName set to DialogFont. - dialogFont!.SetSystemFontName(nameof(DialogFont)); - return dialogFont; - } - } - - private static Font FontInPoints(Font font) - { - return new Font(font.FontFamily, font.SizeInPoints, font.Style, GraphicsUnit.Point, font.GdiCharSet, font.GdiVerticalFont); - } - - private static Font GetFontFromData(Interop.User32.LOGFONT logFont) - { - Font? font = null; - try - { - font = Font.FromLogFont(ref logFont); - } - catch (Exception ex) when (!IsCriticalFontException(ex)) { } - - return - font == null ? DefaultFont : - font.Unit != GraphicsUnit.Point ? FontInPoints(font) : - font; - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/SystemFonts.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/SystemFonts.cs index 1f119c4fc2494..c250081117f39 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/SystemFonts.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/SystemFonts.cs @@ -7,7 +7,7 @@ namespace System.Drawing { - public static partial class SystemFonts + public static class SystemFonts { public static Font? GetFontByName(string systemFontName) { @@ -46,5 +46,246 @@ public static partial class SystemFonts return null; } + + private static unsafe bool GetNonClientMetrics(out Interop.User32.NONCLIENTMETRICS metrics) + { + metrics = new Interop.User32.NONCLIENTMETRICS { cbSize = (uint)sizeof(Interop.User32.NONCLIENTMETRICS) }; + fixed (void* m = &metrics) + { + return Interop.User32.SystemParametersInfoW(Interop.User32.SystemParametersAction.SPI_GETNONCLIENTMETRICS, metrics.cbSize, m, 0); + } + } + + public static Font? CaptionFont + { + get + { + Font? captionFont = null; + + if (GetNonClientMetrics(out Interop.User32.NONCLIENTMETRICS metrics)) + { + captionFont = GetFontFromData(metrics.lfCaptionFont); + captionFont.SetSystemFontName(nameof(CaptionFont)); + } + + return captionFont; + } + } + + public static Font? SmallCaptionFont + { + get + { + Font? smcaptionFont = null; + + if (GetNonClientMetrics(out Interop.User32.NONCLIENTMETRICS metrics)) + { + smcaptionFont = GetFontFromData(metrics.lfSmCaptionFont); + smcaptionFont.SetSystemFontName(nameof(SmallCaptionFont)); + } + + return smcaptionFont; + } + } + + public static Font? MenuFont + { + get + { + Font? menuFont = null; + + if (GetNonClientMetrics(out Interop.User32.NONCLIENTMETRICS metrics)) + { + menuFont = GetFontFromData(metrics.lfMenuFont); + menuFont.SetSystemFontName(nameof(MenuFont)); + } + + return menuFont; + } + } + + public static Font? StatusFont + { + get + { + Font? statusFont = null; + + if (GetNonClientMetrics(out Interop.User32.NONCLIENTMETRICS metrics)) + { + statusFont = GetFontFromData(metrics.lfStatusFont); + statusFont.SetSystemFontName(nameof(StatusFont)); + } + + return statusFont; + } + } + + public static Font? MessageBoxFont + { + get + { + Font? messageBoxFont = null; + + if (GetNonClientMetrics(out Interop.User32.NONCLIENTMETRICS metrics)) + { + messageBoxFont = GetFontFromData(metrics.lfMessageFont); + messageBoxFont.SetSystemFontName(nameof(MessageBoxFont)); + } + + return messageBoxFont; + } + } + + private static bool IsCriticalFontException(Exception ex) + { + return !( + // In any of these cases we'll handle the exception. + ex is ExternalException || + ex is ArgumentException || + ex is OutOfMemoryException || // GDI+ throws this one for many reasons other than actual OOM. + ex is InvalidOperationException || + ex is NotImplementedException || + ex is FileNotFoundException); + } + + public static unsafe Font? IconTitleFont + { + get + { + Font? iconTitleFont = null; + + Interop.User32.LOGFONT itfont = default; + if (Interop.User32.SystemParametersInfoW(Interop.User32.SystemParametersAction.SPI_GETICONTITLELOGFONT, (uint)sizeof(Interop.User32.LOGFONT), &itfont, 0)) + { + iconTitleFont = GetFontFromData(itfont); + iconTitleFont.SetSystemFontName(nameof(IconTitleFont)); + } + + return iconTitleFont; + } + } + + public static Font DefaultFont + { + get + { + Font? defaultFont = null; + + // For Arabic systems, always return Tahoma 8. + if ((ushort)Interop.Kernel32.GetSystemDefaultLCID() == 0x0001) + { + try + { + defaultFont = new Font("Tahoma", 8); + } + catch (Exception ex) when (!IsCriticalFontException(ex)) { } + } + + // First try DEFAULT_GUI. + if (defaultFont == null) + { + IntPtr handle = Interop.Gdi32.GetStockObject(Interop.Gdi32.StockObject.DEFAULT_GUI_FONT); + try + { + using (Font fontInWorldUnits = Font.FromHfont(handle)) + { + defaultFont = FontInPoints(fontInWorldUnits); + } + } + catch (ArgumentException) + { + // This can happen in theory if we end up pulling a non-TrueType font + } + } + + // If DEFAULT_GUI didn't work, try Tahoma. + if (defaultFont == null) + { + try + { + defaultFont = new Font("Tahoma", 8); + } + catch (ArgumentException) + { + } + } + + // Use GenericSansSerif as a last resort - this will always work. + if (defaultFont == null) + { + defaultFont = new Font(FontFamily.GenericSansSerif, 8); + } + + if (defaultFont.Unit != GraphicsUnit.Point) + { + defaultFont = FontInPoints(defaultFont); + } + + Debug.Assert(defaultFont != null, "defaultFont wasn't set."); + + defaultFont.SetSystemFontName(nameof(DefaultFont)); + return defaultFont; + } + } + + public static Font DialogFont + { + get + { + Font? dialogFont = null; + + if ((ushort)Interop.Kernel32.GetSystemDefaultLCID() == 0x0011) + { + // Always return DefaultFont for Japanese cultures. + dialogFont = DefaultFont; + } + else + { + try + { + // Use MS Shell Dlg 2, 8pt for anything other than Japanese. + dialogFont = new Font("MS Shell Dlg 2", 8); + } + catch (ArgumentException) + { + // This can happen in theory if we end up pulling a non-TrueType font + } + } + + if (dialogFont == null) + { + dialogFont = DefaultFont; + } + else if (dialogFont.Unit != GraphicsUnit.Point) + { + dialogFont = FontInPoints(dialogFont); + } + + // For Japanese cultures, SystemFonts.DefaultFont returns a new Font object every time it is invoked. + // So for Japanese we return the DefaultFont with its SystemFontName set to DialogFont. + dialogFont!.SetSystemFontName(nameof(DialogFont)); + return dialogFont; + } + } + + private static Font FontInPoints(Font font) + { + return new Font(font.FontFamily, font.SizeInPoints, font.Style, GraphicsUnit.Point, font.GdiCharSet, font.GdiVerticalFont); + } + + private static Font GetFontFromData(Interop.User32.LOGFONT logFont) + { + Font? font = null; + try + { + font = Font.FromLogFont(ref logFont); + } + catch (Exception ex) when (!IsCriticalFontException(ex)) { } + + return + font == null ? DefaultFont : + font.Unit != GraphicsUnit.Point ? FontInPoints(font) : + font; + } } } diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/SystemIcons.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/SystemIcons.Unix.cs deleted file mode 100644 index 4ddc93c2c9d95..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/SystemIcons.Unix.cs +++ /dev/null @@ -1,117 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// System.Drawing.SystemIcons.cs -// -// Authors: -// Dennis Hayes (dennish@Raytek.com) -// Andreas Nahr (ClassDevelopment@A-SoftTech.com) -// Sebastien Pouliot -// -// (C) 2002 Ximian, Inc -// Copyright (C) 2004, 2006 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace System.Drawing -{ - public static class SystemIcons - { - private const int Application_Winlogo = 0; - private const int Asterisk_Information = 1; - private const int Error_Hand = 2; - private const int Exclamation_Warning = 3; - private const int Question_ = 4; - private const int Shield_ = 5; - - // we minimize the # of icons to load since most of them are duplicates - // we use an internal .ctor to ensure the SystemIcons can't de disposed - private static readonly Icon[] icons = new Icon[6] - { - // TODO: Decide which icons to use for this. - new Icon("placeholder.ico", undisposable:true), // Application_Winlogo - new Icon("placeholder.ico", undisposable:true), // Asterisk_Information - new Icon("placeholder.ico", undisposable:true), // Error_Hand - new Icon("placeholder.ico", undisposable:true), // Exclamation_Warning - new Icon("placeholder.ico", undisposable:true), // Question_ - new Icon("placeholder.ico", undisposable:true), // Shield_ - }; - - // note: same as WinLogo (for Mono) - public static Icon Application - { - get { return icons[Application_Winlogo]; } - } - - // note: same as Information - public static Icon Asterisk - { - get { return icons[Asterisk_Information]; } - } - - // note: same as Hand - public static Icon Error - { - get { return icons[Error_Hand]; } - } - - // same as Warning - public static Icon Exclamation - { - get { return icons[Exclamation_Warning]; } - } - - // note: same as Error - public static Icon Hand - { - get { return icons[Error_Hand]; } - } - - // note: same as Asterisk - public static Icon Information - { - get { return icons[Asterisk_Information]; } - } - - public static Icon Question - { - get { return icons[Question_]; } - } - - // note: same as Exclamation - public static Icon Warning - { - get { return icons[Exclamation_Warning]; } - } - - // note: same as Application (for Mono) - public static Icon WinLogo - { - get { return icons[Application_Winlogo]; } - } - - public static Icon Shield - { - get { return icons[Shield_]; } - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/SystemIcons.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/SystemIcons.cs similarity index 100% rename from src/libraries/System.Drawing.Common/src/System/Drawing/SystemIcons.Windows.cs rename to src/libraries/System.Drawing.Common/src/System/Drawing/SystemIcons.cs diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Text/PrivateFontCollection.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Text/PrivateFontCollection.Unix.cs deleted file mode 100644 index 51e27912e286e..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Text/PrivateFontCollection.Unix.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Text -{ - public partial class PrivateFontCollection - { - // There is no GDI on Unix, only libgdiplus, so this is a no-op. - partial void GdiAddFontFile(string filename); - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Text/PrivateFontCollection.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Text/PrivateFontCollection.Windows.cs deleted file mode 100644 index 533cb1ebc8e79..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Text/PrivateFontCollection.Windows.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Drawing.Text -{ - public partial class PrivateFontCollection - { - private static void GdiAddFontFile(string filename) - { - Interop.Gdi32.AddFontFile(filename); - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Text/PrivateFontCollection.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Text/PrivateFontCollection.cs index 3a43631f526f2..6d61b4e5af593 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Text/PrivateFontCollection.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Text/PrivateFontCollection.cs @@ -12,7 +12,7 @@ namespace System.Drawing.Text /// /// Encapsulates a collection of objects. /// - public sealed partial class PrivateFontCollection : FontCollection + public sealed class PrivateFontCollection : FontCollection { /// /// Initializes a new instance of the class. @@ -83,8 +83,6 @@ public void AddFontFile(string filename) Gdip.CheckStatus(status); // Register private font with GDI as well so pure GDI-based controls (TextBox, Button for instance) can access it. - // This is a no-op on Unix which has GDI+ (libgdiplus), not GDI; and we don't have System.Windows.Forms - // on Unix. GdiAddFontFile(filename); } @@ -95,5 +93,10 @@ public void AddMemoryFont(IntPtr memory, int length) { Gdip.CheckStatus(Gdip.GdipPrivateAddMemoryFont(new HandleRef(this, _nativeFontCollection), memory, length)); } + + private static void GdiAddFontFile(string filename) + { + Interop.Gdi32.AddFontFile(filename); + } } } diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/TextureBrush.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/TextureBrush.cs index 9835d63d78ca1..14ac17ed03d0a 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/TextureBrush.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/TextureBrush.cs @@ -22,8 +22,10 @@ public TextureBrush(Image bitmap) : this(bitmap, WrapMode.Tile) { } - public TextureBrush(Image image!!, WrapMode wrapMode) + public TextureBrush(Image image, WrapMode wrapMode) { + ArgumentNullException.ThrowIfNull(image); + if (wrapMode < WrapMode.Tile || wrapMode > WrapMode.Clamp) { throw new InvalidEnumArgumentException(nameof(wrapMode), unchecked((int)wrapMode), typeof(WrapMode)); @@ -38,8 +40,10 @@ public TextureBrush(Image image!!, WrapMode wrapMode) SetNativeBrushInternal(brush); } - public TextureBrush(Image image!!, WrapMode wrapMode, RectangleF dstRect) + public TextureBrush(Image image, WrapMode wrapMode, RectangleF dstRect) { + ArgumentNullException.ThrowIfNull(image); + if (wrapMode < WrapMode.Tile || wrapMode > WrapMode.Clamp) { throw new InvalidEnumArgumentException(nameof(wrapMode), unchecked((int)wrapMode), typeof(WrapMode)); @@ -58,8 +62,10 @@ public TextureBrush(Image image!!, WrapMode wrapMode, RectangleF dstRect) SetNativeBrushInternal(brush); } - public TextureBrush(Image image!!, WrapMode wrapMode, Rectangle dstRect) + public TextureBrush(Image image, WrapMode wrapMode, Rectangle dstRect) { + ArgumentNullException.ThrowIfNull(image); + if (wrapMode < WrapMode.Tile || wrapMode > WrapMode.Clamp) { throw new InvalidEnumArgumentException(nameof(wrapMode), unchecked((int)wrapMode), typeof(WrapMode)); @@ -80,8 +86,10 @@ public TextureBrush(Image image!!, WrapMode wrapMode, Rectangle dstRect) public TextureBrush(Image image, RectangleF dstRect) : this(image, dstRect, null) { } - public TextureBrush(Image image!!, RectangleF dstRect, ImageAttributes? imageAttr) + public TextureBrush(Image image, RectangleF dstRect, ImageAttributes? imageAttr) { + ArgumentNullException.ThrowIfNull(image); + IntPtr brush; int status = Gdip.GdipCreateTextureIA(new HandleRef(image, image.nativeImage), new HandleRef(imageAttr, (imageAttr == null) ? @@ -98,8 +106,10 @@ public TextureBrush(Image image!!, RectangleF dstRect, ImageAttributes? imageAtt public TextureBrush(Image image, Rectangle dstRect) : this(image, dstRect, null) { } - public TextureBrush(Image image!!, Rectangle dstRect, ImageAttributes? imageAttr) + public TextureBrush(Image image, Rectangle dstRect, ImageAttributes? imageAttr) { + ArgumentNullException.ThrowIfNull(image); + IntPtr brush; int status = Gdip.GdipCreateTextureIAI(new HandleRef(image, image.nativeImage), new HandleRef(imageAttr, (imageAttr == null) ? @@ -193,8 +203,10 @@ public void ResetTransform() public void MultiplyTransform(Matrix matrix) => MultiplyTransform(matrix, MatrixOrder.Prepend); - public void MultiplyTransform(Matrix matrix!!, MatrixOrder order) + public void MultiplyTransform(Matrix matrix, MatrixOrder order) { + ArgumentNullException.ThrowIfNull(matrix); + // Multiplying the transform by a disposed matrix is a nop in GDI+, but throws // with the libgdiplus backend. Simulate a nop for compatability with GDI+. if (matrix.NativeMatrix == IntPtr.Zero) diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/ToolboxBitmapAttribute.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/ToolboxBitmapAttribute.Unix.cs deleted file mode 100644 index 5bb7a2f9fb03b..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/ToolboxBitmapAttribute.Unix.cs +++ /dev/null @@ -1,152 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// System.Drawing.ToolboxBitmapAttribute.cs -// -// Authors: -// Dennis Hayes (dennish@Raytek.com) -// Andreas Nahr (ClassDevelopment@A-SoftTech.com) -// -// Copyright (C) 2002 Ximian, Inc. http://www.ximian.com -// Copyright (C) 2004 Novell, Inc. http://www.novell.com -// - -// -// Copyright (C) 2004 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// 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.Diagnostics.CodeAnalysis; -using System.Reflection; - -namespace System.Drawing -{ - [AttributeUsage(AttributeTargets.Class)] - public class ToolboxBitmapAttribute : Attribute - { - private Image? smallImage; - private Image? bigImage; - public static readonly ToolboxBitmapAttribute Default = new ToolboxBitmapAttribute(); - - private ToolboxBitmapAttribute() - { - } - - public ToolboxBitmapAttribute(string imageFile) - { - } - - public ToolboxBitmapAttribute(Type t) - { - smallImage = GetImageFromResource(t, null, false); - } - - public ToolboxBitmapAttribute(Type t, string name) - { - smallImage = GetImageFromResource(t, name, false); - } - - public override bool Equals([NotNullWhen(true)] object? value) - { - if (!(value is ToolboxBitmapAttribute)) - return false; - if (value == this) - return true; - return ((ToolboxBitmapAttribute)value).smallImage == this.smallImage; - } - - public override int GetHashCode() - { - return (smallImage!.GetHashCode() ^ bigImage!.GetHashCode()); - } - - public Image? GetImage(object component) - { - return GetImage(component.GetType(), null, false); - } - - public Image? GetImage(object component, bool large) - { - return GetImage(component.GetType(), null, large); - } - - public Image? GetImage(Type type) - { - return GetImage(type, null, false); - } - - public Image? GetImage(Type type, bool large) - { - return GetImage(type, null, large); - } - - public Image? GetImage(Type type, string? imgName, bool large) - { - if (smallImage == null) - smallImage = GetImageFromResource(type, imgName, false); - - if (large) - { - if (bigImage == null) - bigImage = new Bitmap(smallImage!, 32, 32); - return bigImage; - } - else - return smallImage; - } - - public static Image? GetImageFromResource(Type t, string? imageName, bool large) - { - Bitmap bitmap; - if (imageName == null) - imageName = t.Name + ".bmp"; - - try - { - using (System.IO.Stream? s = t.Assembly.GetManifestResourceStream(t.Namespace + "." + imageName)) - { - if (s == null) - { - return null; - } - else - { - bitmap = new Bitmap(s, false); - } - } - - //FIXME: thrown too easily - //if (bitmap.Width != 16 || bitmap.Height != 16) - // throw new Exception ("ToolboxBitmap must be 16x16 pixels"); - - if (large) - return new Bitmap(bitmap, 32, 32); - return bitmap; - } - catch - { - return null; - } - } - } -} diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/macFunctions.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/macFunctions.cs deleted file mode 100644 index 4d810dc336eca..0000000000000 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/macFunctions.cs +++ /dev/null @@ -1,323 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// System.Drawing.carbonFunctions.cs -// -// Authors: -// Geoff Norton (gnorton@customerdna.com> -// -// Copyright (C) 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// 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.Collections; -using System.Runtime.InteropServices; - -namespace System.Drawing -{ - internal static partial class MacSupport - { - internal static readonly Hashtable contextReference = new Hashtable(); - internal static readonly object lockobj = new object(); - - internal static CocoaContext GetCGContextForNSView(IntPtr handle) - { - IntPtr graphicsContext = intptr_objc_msgSend(objc_getClass("NSGraphicsContext"), sel_registerName("currentContext")); - IntPtr ctx = intptr_objc_msgSend(graphicsContext, sel_registerName("graphicsPort")); - - CGContextSaveGState(ctx); - - Rect_objc_msgSend_stret(out Rect bounds, handle, sel_registerName("bounds")); - - var isFlipped = bool_objc_msgSend(handle, sel_registerName("isFlipped")); - if (isFlipped) - { - CGContextTranslateCTM(ctx, bounds.origin.x, bounds.size.height); - CGContextScaleCTM(ctx, 1.0f, -1.0f); - } - - return new CocoaContext(ctx, (int)bounds.size.width, (int)bounds.size.height); - } - - internal static CarbonContext GetCGContextForView(IntPtr handle) - { - IntPtr context = IntPtr.Zero; - IntPtr port; - IntPtr window; - - window = GetControlOwner(handle); - - if (handle == IntPtr.Zero || window == IntPtr.Zero) - { - // FIXME: Can we actually get a CGContextRef for the desktop? this makes context IntPtr.Zero - port = GetQDGlobalsThePort(); - CreateCGContextForPort(port, ref context); - - Rect desktop_bounds = CGDisplayBounds(CGMainDisplayID()); - - return new CarbonContext(port, context, (int)desktop_bounds.size.width, (int)desktop_bounds.size.height); - } - - QDRect window_bounds = default(QDRect); - Rect view_bounds = default(Rect); - - port = GetWindowPort(window); - - context = GetContext(port); - - GetWindowBounds(window, 32, ref window_bounds); - - HIViewGetBounds(handle, ref view_bounds); - - HIViewConvertRect(ref view_bounds, handle, IntPtr.Zero); - - if (view_bounds.size.height < 0) - view_bounds.size.height = 0; - if (view_bounds.size.width < 0) - view_bounds.size.width = 0; - - CGContextTranslateCTM(context, view_bounds.origin.x, (window_bounds.bottom - window_bounds.top) - (view_bounds.origin.y + view_bounds.size.height)); - - // Create the original rect path and clip to it - Rect rc_clip = new Rect(0, 0, view_bounds.size.width, view_bounds.size.height); - - CGContextSaveGState(context); - - CGContextBeginPath(context); - CGContextAddRect(context, rc_clip); - CGContextClosePath(context); - CGContextClip(context); - - return new CarbonContext(port, context, (int)view_bounds.size.width, (int)view_bounds.size.height); - } - - internal static IntPtr GetContext(IntPtr port) - { - IntPtr context = IntPtr.Zero; - - lock (lockobj) - { -#if FALSE - if (contextReference [port] != null) { - CreateCGContextForPort (port, ref context); - } else { - QDBeginCGContext (port, ref context); - contextReference [port] = context; - } -#else - CreateCGContextForPort(port, ref context); -#endif - } - - return context; - } - - internal static void ReleaseContext(IntPtr port, IntPtr context) - { - CGContextRestoreGState(context); - - lock (lockobj) - { -#if FALSE - if (contextReference [port] != null && context == (IntPtr) contextReference [port]) { - QDEndCGContext (port, ref context); - contextReference [port] = null; - } else { - CFRelease (context); - } -#else - CFRelease(context); -#endif - } - } - - #region Cocoa Methods - [LibraryImport("libobjc.dylib")] - public static partial IntPtr objc_getClass([MarshalAs(UnmanagedType.LPUTF8Str)] string className); - [LibraryImport("libobjc.dylib", EntryPoint = "objc_msgSend")] - public static partial IntPtr intptr_objc_msgSend(IntPtr basePtr, IntPtr selector); - [LibraryImport("libobjc.dylib", EntryPoint = "objc_msgSend_stret")] - public static partial void Rect_objc_msgSend_stret(out Rect arect, IntPtr basePtr, IntPtr selector); - [LibraryImport("libobjc.dylib", EntryPoint = "objc_msgSend")] - [return:MarshalAs(UnmanagedType.U1)] - public static partial bool bool_objc_msgSend(IntPtr handle, IntPtr selector); - [LibraryImport("libobjc.dylib")] - public static partial IntPtr sel_registerName([MarshalAs(UnmanagedType.LPUTF8Str)] string selectorName); - #endregion - - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial IntPtr CGMainDisplayID(); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial Rect CGDisplayBounds(IntPtr display); - - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial int HIViewGetBounds(IntPtr vHnd, ref Rect r); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial int HIViewConvertRect(ref Rect r, IntPtr a, IntPtr b); - - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial IntPtr GetControlOwner(IntPtr aView); - - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial int GetWindowBounds(IntPtr wHnd, uint reg, ref QDRect rect); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial IntPtr GetWindowPort(IntPtr hWnd); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial IntPtr GetQDGlobalsThePort(); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial void CreateCGContextForPort(IntPtr port, ref IntPtr context); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial void CFRelease(IntPtr context); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial void QDBeginCGContext(IntPtr port, ref IntPtr context); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial void QDEndCGContext(IntPtr port, ref IntPtr context); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial int CGContextClipToRect(IntPtr context, Rect clip); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial int CGContextClipToRects(IntPtr context, Rect[] clip_rects, int count); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial void CGContextTranslateCTM(IntPtr context, float tx, float ty); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial void CGContextScaleCTM(IntPtr context, float x, float y); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial void CGContextFlush(IntPtr context); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial void CGContextSynchronize(IntPtr context); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial IntPtr CGPathCreateMutable(); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial void CGPathAddRects(IntPtr path, IntPtr _void, Rect[] rects, int count); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial void CGPathAddRect(IntPtr path, IntPtr _void, Rect rect); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial void CGContextAddRects(IntPtr context, Rect[] rects, int count); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial void CGContextAddRect(IntPtr context, Rect rect); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial void CGContextBeginPath(IntPtr context); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial void CGContextClosePath(IntPtr context); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial void CGContextAddPath(IntPtr context, IntPtr path); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial void CGContextClip(IntPtr context); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial void CGContextEOClip(IntPtr context); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial void CGContextEOFillPath(IntPtr context); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial void CGContextSaveGState(IntPtr context); - [LibraryImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")] - internal static partial void CGContextRestoreGState(IntPtr context); - } - - internal struct CGSize - { - public float width; - public float height; - } - - internal struct CGPoint - { - public float x; - public float y; - } - - internal struct Rect - { - public Rect(float x, float y, float width, float height) - { - this.origin.x = x; - this.origin.y = y; - this.size.width = width; - this.size.height = height; - } - - public CGPoint origin; - public CGSize size; - } - - internal struct QDRect - { - public short top; - public short left; - public short bottom; - public short right; - } - - internal struct CarbonContext : IMacContext - { - public IntPtr port; - public IntPtr ctx; - public int width; - public int height; - - public CarbonContext(IntPtr port, IntPtr ctx, int width, int height) - { - this.port = port; - this.ctx = ctx; - this.width = width; - this.height = height; - } - - public void Synchronize() - { - MacSupport.CGContextSynchronize(ctx); - } - - public void Release() - { - MacSupport.ReleaseContext(port, ctx); - } - } - - internal struct CocoaContext : IMacContext - { - public IntPtr ctx; - public int width; - public int height; - - public CocoaContext(IntPtr ctx, int width, int height) - { - this.ctx = ctx; - this.width = width; - this.height = height; - } - - public void Synchronize() - { - MacSupport.CGContextSynchronize(ctx); - } - - public void Release() - { - MacSupport.CGContextRestoreGState(ctx); - } - } - - internal interface IMacContext - { - void Synchronize(); - void Release(); - } -} diff --git a/src/libraries/System.Drawing.Common/tests/BitmapTests.cs b/src/libraries/System.Drawing.Common/tests/BitmapTests.cs index 0b15dfc7821ca..e4322e65f4373 100644 --- a/src/libraries/System.Drawing.Common/tests/BitmapTests.cs +++ b/src/libraries/System.Drawing.Common/tests/BitmapTests.cs @@ -45,18 +45,6 @@ public static IEnumerable Ctor_FilePath_TestData() yield return new object[] { "16x16_nonindexed_24bit.png", 16, 16, PixelFormat.Format24bppRgb, ImageFormat.Png }; } - [PlatformSpecific(TestPlatforms.AnyUnix)] - [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] - public void UnixSupportDisabledThrows() - { - RemoteExecutor.Invoke(() => - { - AppContext.SetSwitch("System.Drawing.EnableUnixSupport", false); - TypeInitializationException exception = Assert.Throws(() => new Bitmap(100, 100)); - Assert.IsType(exception.InnerException); - }).Dispose(); - } - [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Ctor_FilePath_TestData))] public void Ctor_FilePath(string filename, int width, int height, PixelFormat pixelFormat, ImageFormat rawFormat) @@ -201,7 +189,6 @@ public void Ctor_Width_Height(int width, int height) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(10, 10, PixelFormat.Format1bppIndexed)] [InlineData(10, 10, PixelFormat.Format8bppIndexed)] @@ -236,7 +223,6 @@ public static IEnumerable Ctor_Width_Height_Stride_PixelFormat_Scan0_T yield return new object[] { 1, 1, 1, PixelFormat.Format1bppIndexed, IntPtr.Zero }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Ctor_Width_Height_Stride_PixelFormat_Scan0_TestData))] public void Ctor_Width_Height_Stride_PixelFormat_Scan0(int width, int height, int stride, PixelFormat pixelFormat, IntPtr scan0) @@ -250,7 +236,6 @@ public void Ctor_Width_Height_Stride_PixelFormat_Scan0(int width, int height, in } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(-1)] [InlineData(0)] @@ -266,7 +251,6 @@ public void Ctor_InvalidWidth_ThrowsArgumentException(int width) AssertExtensions.Throws(null, () => new Bitmap(width, 1, 0, PixelFormat.Format16bppArgb1555, IntPtr.Zero)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(-1)] [InlineData(0)] @@ -299,7 +283,6 @@ public void Ctor_InvalidPixelFormat_ThrowsArgumentException(PixelFormat format) AssertExtensions.Throws(null, () => new Bitmap(1, 1, 0, format, IntPtr.Zero)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Ctor_InvalidScan0_ThrowsArgumentException() { @@ -321,7 +304,6 @@ public static IEnumerable Image_TestData() yield return new object[] { new Bitmap(Helpers.GetTestBitmapPath("16x16_nonindexed_24bit.png")), 32, 48 }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Image_TestData))] public void Ctor_Width_Height_Graphics(Bitmap image, int width, int height) @@ -361,7 +343,6 @@ public void Ctor_NullImageWithoutSize_ThrowsNullReferenceException() Assert.Throws(() => new Bitmap((Image)null)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Image_TestData))] public void Ctor_Image_Width_Height(Image image, int width, int height) @@ -375,7 +356,6 @@ public void Ctor_Image_Width_Height(Image image, int width, int height) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Image_TestData))] public void Ctor_Size(Image image, int width, int height) @@ -415,7 +395,6 @@ public static IEnumerable Clone_TestData() yield return new object[] { new Bitmap(3, 3, PixelFormat.Format64bppPArgb), new Rectangle(1, 1, 1, 1), PixelFormat.Format16bppRgb565 }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Clone_TestData))] public void Clone_Rectangle_ReturnsExpected(Bitmap bitmap, Rectangle rectangle, PixelFormat targetFormat) @@ -454,7 +433,6 @@ public void Clone_Rectangle_ReturnsExpected(Bitmap bitmap, Rectangle rectangle, } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Clone_TestData))] public void Clone_RectangleF_ReturnsExpected(Bitmap bitmap, Rectangle rectangle, PixelFormat format) @@ -476,7 +454,6 @@ public void Clone_RectangleF_ReturnsExpected(Bitmap bitmap, Rectangle rectangle, } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(0, 1)] [InlineData(1, 0)] @@ -489,7 +466,6 @@ public void Clone_ZeroWidthOrHeightRect_ThrowsArgumentException(int width, int h } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(0, 0, 4, 1)] [InlineData(0, 0, 1, 4)] @@ -506,7 +482,6 @@ public void Clone_InvalidRect_ThrowsOutOfMemoryException(int x, int y, int width } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(PixelFormat.Max)] [InlineData(PixelFormat.Indexed)] @@ -525,7 +500,6 @@ public void Clone_InvalidPixelFormat_ThrowsOutOfMemoryException(PixelFormat form } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Clone_GrayscaleFormat_ThrowsOutOfMemoryException() { @@ -559,7 +533,6 @@ public void Clone_Disposed_ThrowsArgumentException() AssertExtensions.Throws(null, () => bitmap.Clone(new RectangleF(0, 0, 1, 1), PixelFormat.Format32bppArgb)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetFrameCount_NewBitmap_ReturnsZero() { @@ -581,7 +554,6 @@ public void GetFrameCount_Disposed_ThrowsArgumentException() AssertExtensions.Throws(null, () => bitmap.GetFrameCount(FrameDimension.Page)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(-1)] [InlineData(0)] @@ -651,7 +623,6 @@ public void GetPixel_InvalidY_ThrowsArgumentOutOfRangeException(int y) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetPixel_GrayScalePixelFormat_ThrowsArgumentException() { @@ -677,7 +648,6 @@ public static IEnumerable GetHbitmap_TestData() yield return new object[] { new Bitmap(512, 512, PixelFormat.Format16bppRgb555), 512, 512 }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(GetHbitmap_TestData))] public void GetHbitmap_FromHbitmap_ReturnsExpected(Bitmap bitmap, int width, int height) @@ -719,7 +689,6 @@ public void GetHbitmap_FromHbitmap_ReturnsExpected(Bitmap bitmap, int width, int } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(1, 1)] [InlineData(short.MaxValue, 1)] @@ -741,7 +710,6 @@ public void GetHbitmap_Disposed_ThrowsArgumentException() AssertExtensions.Throws(null, () => bitmap.GetHbitmap()); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void FromHbitmap_InvalidHandle_ThrowsExternalException() { @@ -785,7 +753,6 @@ public static IEnumerable FromHicon_TestData() yield return new object[] { new Bitmap(512, 512, PixelFormat.Format16bppRgb555).GetHicon(), 512, 512 }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(FromHicon_TestData))] public Bitmap GetHicon_FromHicon_ReturnsExpected(IntPtr handle, int width, int height) @@ -803,7 +770,6 @@ public Bitmap GetHicon_FromHicon_ReturnsExpected(IntPtr handle, int width, int h return result; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetHicon_Grayscale_ThrowsArgumentException() { @@ -823,7 +789,6 @@ public void GetHicon_Disposed_ThrowsArgumentException() } [ConditionalFact(Helpers.IsDrawingSupported)] - [PlatformSpecific(TestPlatforms.Windows)] [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "In .NET Framework we use GDI 1.0")] public void SaveWmfAsPngDoesntChangeImageBoundaries() { @@ -857,7 +822,6 @@ public void SaveWmfAsPngDoesntChangeImageBoundaries() } // This test causes an AV on Linux - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void FromHicon_InvalidHandle_ThrowsArgumentException() { @@ -865,7 +829,6 @@ public void FromHicon_InvalidHandle_ThrowsArgumentException() AssertExtensions.Throws(null, () => Bitmap.FromHicon((IntPtr)10)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void FromHicon_1bppIcon_ThrowsArgumentException() { @@ -875,7 +838,6 @@ public void FromHicon_1bppIcon_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void FromResource_InvalidHandle_ThrowsArgumentException() { @@ -883,7 +845,6 @@ public void FromResource_InvalidHandle_ThrowsArgumentException() AssertExtensions.Throws(null, () => Bitmap.FromResource((IntPtr)10, "Name")); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void FromResource_InvalidBitmapName_ThrowsArgumentException() { @@ -891,7 +852,6 @@ public void FromResource_InvalidBitmapName_ThrowsArgumentException() AssertExtensions.Throws(null, () => Bitmap.FromResource((IntPtr)10, "Name")); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void MakeTransparent_NoColorWithMatches_SetsMatchingPixelsToTransparent() { @@ -930,7 +890,6 @@ public void MakeTransparent_NoColorWithMatches_SetsMatchingPixelsToTransparent() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void MakeTransparent_CustomColorExists_SetsMatchingPixelsToTransparent() { @@ -1003,7 +962,6 @@ public void MakeTransparent_Disposed_ThrowsArgumentException() AssertExtensions.Throws(null, () => bitmap.MakeTransparent(Color.Red)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ActiveIssue("https://github.com/dotnet/runtime/issues/22629", TargetFrameworkMonikers.NetFramework)] [ActiveIssue("https://github.com/dotnet/runtime/issues/26247", TestPlatforms.Windows)] [ConditionalFact(Helpers.IsDrawingSupported)] @@ -1073,7 +1031,6 @@ public void SetPixel_InvalidY_ThrowsArgumentOutOfRangeException(int y) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void SetPixel_GrayScalePixelFormat_ThrowsArgumentException() { @@ -1117,7 +1074,6 @@ public void SetResolution_InvalidXDpi_ThrowsArgumentException(float xDpi) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(-1)] [InlineData(0)] @@ -1140,25 +1096,6 @@ public void SetResolution_Disposed_ThrowsArgumentException() AssertExtensions.Throws(null, () => bitmap.SetResolution(1, 1)); } - public static IEnumerable LockBits_NotUnix_TestData() - { - Bitmap bitmap() => new Bitmap(2, 2, PixelFormat.Format32bppArgb); - yield return new object[] { bitmap(), new Rectangle(1, 1, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb, 8, 1 }; - yield return new object[] { bitmap(), new Rectangle(1, 1, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb, 8, 3 }; - yield return new object[] { bitmap(), new Rectangle(1, 1, 1, 1), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb, 8, 2 }; - - yield return new object[] { bitmap(), new Rectangle(1, 1, 1, 1), ImageLockMode.ReadOnly - 1, PixelFormat.Format32bppArgb, 8, 0 }; - - yield return new object[] { bitmap(), new Rectangle(0, 0, 2, 2), ImageLockMode.WriteOnly, PixelFormat.Format16bppGrayScale, 4, 65538 }; - - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format32bppRgb), new Rectangle(0, 0, 100, 100), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed, 100, 65537 }; - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format32bppRgb), new Rectangle(0, 0, 100, 100), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed, 100, 65539 }; - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format32bppRgb), new Rectangle(0, 0, 100, 100), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed, 100, 65538 }; - - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format8bppIndexed), new Rectangle(0, 0, 100, 100), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb, 300, 65539 }; - yield return new object[] { new Bitmap(100, 100, PixelFormat.Format8bppIndexed), new Rectangle(0, 0, 100, 100), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb, 300, 65538 }; - } - public static IEnumerable LockBits_TestData() { Bitmap bitmap() => new Bitmap(2, 2, PixelFormat.Format32bppArgb); @@ -1192,26 +1129,27 @@ public static IEnumerable LockBits_TestData() yield return new object[] { new Bitmap(184, 184, PixelFormat.Format1bppIndexed), new Rectangle(0, 0, 184, 184), ImageLockMode.ReadOnly, PixelFormat.Format1bppIndexed, 24, 1 }; yield return new object[] { new Bitmap(184, 184, PixelFormat.Format1bppIndexed), new Rectangle(0, 0, 184, 184), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed, 24, 3 }; yield return new object[] { new Bitmap(184, 184, PixelFormat.Format1bppIndexed), new Rectangle(0, 0, 184, 184), ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed, 24, 2 }; + + yield return new object[] { bitmap(), new Rectangle(1, 1, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb, 8, 1 }; + yield return new object[] { bitmap(), new Rectangle(1, 1, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb, 8, 3 }; + yield return new object[] { bitmap(), new Rectangle(1, 1, 1, 1), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb, 8, 2 }; + + yield return new object[] { bitmap(), new Rectangle(1, 1, 1, 1), ImageLockMode.ReadOnly - 1, PixelFormat.Format32bppArgb, 8, 0 }; + + yield return new object[] { bitmap(), new Rectangle(0, 0, 2, 2), ImageLockMode.WriteOnly, PixelFormat.Format16bppGrayScale, 4, 65538 }; + + yield return new object[] { new Bitmap(100, 100, PixelFormat.Format32bppRgb), new Rectangle(0, 0, 100, 100), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed, 100, 65537 }; + yield return new object[] { new Bitmap(100, 100, PixelFormat.Format32bppRgb), new Rectangle(0, 0, 100, 100), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed, 100, 65539 }; + yield return new object[] { new Bitmap(100, 100, PixelFormat.Format32bppRgb), new Rectangle(0, 0, 100, 100), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed, 100, 65538 }; + + yield return new object[] { new Bitmap(100, 100, PixelFormat.Format8bppIndexed), new Rectangle(0, 0, 100, 100), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb, 300, 65539 }; + yield return new object[] { new Bitmap(100, 100, PixelFormat.Format8bppIndexed), new Rectangle(0, 0, 100, 100), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb, 300, 65538 }; } [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsDrawingSupported), nameof(PlatformDetection.IsNotArm64Process))] // [ActiveIssue("https://github.com/dotnet/runtime/issues/28859")] [ActiveIssue("https://github.com/dotnet/runtime/issues/30565", TestPlatforms.Windows)] [MemberData(nameof(LockBits_TestData))] public void LockBits_Invoke_Success(Bitmap bitmap, Rectangle rectangle, ImageLockMode lockMode, PixelFormat pixelFormat, int expectedStride, int expectedReserved) - { - Do_LockBits_Invoke_Success(bitmap, rectangle, lockMode, pixelFormat, expectedStride, expectedReserved); - } - - // This test causes an AV on Unix - [ActiveIssue("https://github.com/dotnet/runtime/issues/30565", TestPlatforms.AnyUnix)] - [ConditionalTheory(Helpers.IsDrawingSupported)] - [MemberData(nameof(LockBits_NotUnix_TestData))] - public void LockBits_Invoke_Success_NotUnix(Bitmap bitmap, Rectangle rectangle, ImageLockMode lockMode, PixelFormat pixelFormat, int expectedStride, int expectedReserved) - { - Do_LockBits_Invoke_Success(bitmap, rectangle, lockMode, pixelFormat, expectedStride, expectedReserved); - } - - private void Do_LockBits_Invoke_Success(Bitmap bitmap, Rectangle rectangle, ImageLockMode lockMode, PixelFormat pixelFormat, int expectedStride, int expectedReserved) { try { @@ -1224,7 +1162,6 @@ private void Do_LockBits_Invoke_Success(Bitmap bitmap, Rectangle rectangle, Imag if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // "Reserved" is documented as "Reserved. Do not use.", so it's not clear whether we actually need to test this in any unit tests. - // Additionally, the values are not consistent across Windows (GDI+) and Unix (libgdiplus) Assert.Equal(expectedReserved, data.Reserved); } @@ -1301,7 +1238,6 @@ public void LockBits_InvalidPixelFormat_ThrowsArgumentException(PixelFormat form } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void LockBits_ReadOnlyGrayscale_ThrowsArgumentException() { @@ -1318,7 +1254,6 @@ public void LockBits_ReadOnlyGrayscale_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData((ImageLockMode)(-1))] [InlineData(ImageLockMode.UserInputBuffer + 1)] @@ -1362,7 +1297,6 @@ public void LockBits_AlreadyLocked_ThrowsInvalidOperationException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(0, -1)] [InlineData(0, 2)] @@ -1455,7 +1389,6 @@ public void Size_Disposed_ThrowsArgumentException() AssertExtensions.Throws(null, () => bitmap.Size); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(PixelFormat.Format16bppArgb1555)] [InlineData(PixelFormat.Format16bppRgb555)] @@ -1624,7 +1557,6 @@ public void Palette_Get_ReturnsExpected(PixelFormat pixelFormat, int[] expectedE } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Palette_SetNull_ThrowsNullReferenceException() { diff --git a/src/libraries/System.Drawing.Common/tests/BufferedGraphicsContextTests.cs b/src/libraries/System.Drawing.Common/tests/BufferedGraphicsContextTests.cs index 5c85156fb3979..b8c7d27ab11d7 100644 --- a/src/libraries/System.Drawing.Common/tests/BufferedGraphicsContextTests.cs +++ b/src/libraries/System.Drawing.Common/tests/BufferedGraphicsContextTests.cs @@ -17,7 +17,6 @@ public void Ctor_Default() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Allocate_ValidTargetGraphics_Success() { @@ -60,7 +59,6 @@ public void Allocate_LargeRectWithTargetGraphics_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Allocate_ValidTargetHdc_Success() { @@ -133,7 +131,6 @@ public void Allocate_LargeRectWithTargetHdc_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [Fact] public void Allocate_InvalidHdc_ThrowsArgumentException() { @@ -143,7 +140,6 @@ public void Allocate_InvalidHdc_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Allocate_NullGraphicsZeroSize_Success() { @@ -154,7 +150,6 @@ public void Allocate_NullGraphicsZeroSize_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Allocate_NullGraphicsNonZeroSize_ThrowsArgumentNullException() { @@ -165,7 +160,6 @@ public void Allocate_NullGraphicsNonZeroSize_ThrowsArgumentNullException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Allocate_DisposedGraphics_ThrowsArgumentException() { @@ -181,7 +175,6 @@ public void Allocate_DisposedGraphics_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Allocate_BusyGraphics_ThrowsInvalidOperationException() { @@ -263,7 +256,6 @@ public void Finalize_Invoke_Success() GC.WaitForPendingFinalizers(); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Dispose_BusyAndValidated_ThrowsInvalidOperationException() { @@ -278,7 +270,6 @@ public void Dispose_BusyAndValidated_ThrowsInvalidOperationException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Dispose_BusyAndInvalidated_ThrowsInvalidOperationException() { diff --git a/src/libraries/System.Drawing.Common/tests/BufferedGraphicsTests.cs b/src/libraries/System.Drawing.Common/tests/BufferedGraphicsTests.cs index de5d15ed02cb9..ba2bd821ce7bb 100644 --- a/src/libraries/System.Drawing.Common/tests/BufferedGraphicsTests.cs +++ b/src/libraries/System.Drawing.Common/tests/BufferedGraphicsTests.cs @@ -41,7 +41,6 @@ public void Dispose_ActualMultipleTimes_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Render_ParameterlessWithTargetGraphics_Success() { @@ -68,7 +67,6 @@ public void Render_ParameterlessWithTargetGraphics_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Render_ParameterlessWithNullTargetGraphics_Success() { @@ -94,7 +92,6 @@ public void Render_ParameterlessWithNullTargetGraphics_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Render_TargetGraphics_Success() { @@ -135,7 +132,6 @@ public void Render_NullGraphics_Nop() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Render_InvalidTargetDC_Nop() { diff --git a/src/libraries/System.Drawing.Common/tests/Drawing2D/CustomLineCapTests.cs b/src/libraries/System.Drawing.Common/tests/Drawing2D/CustomLineCapTests.cs index 1956c99369984..17ca9acea9f61 100644 --- a/src/libraries/System.Drawing.Common/tests/Drawing2D/CustomLineCapTests.cs +++ b/src/libraries/System.Drawing.Common/tests/Drawing2D/CustomLineCapTests.cs @@ -69,7 +69,6 @@ public void Ctor_InvalidLineCap_ReturnsFlat(LineCap baseCap) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Ctor_FillPath_Incomplete_ThrowsArgumentException() { @@ -80,7 +79,6 @@ public void Ctor_FillPath_Incomplete_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Ctor_FillPath_DoesNotCrossYAxis_ThrowsNotImplementedException() { diff --git a/src/libraries/System.Drawing.Common/tests/Drawing2D/GraphicsPathIteratorTests.cs b/src/libraries/System.Drawing.Common/tests/Drawing2D/GraphicsPathIteratorTests.cs index 45ae21bbe2ec1..b4cce1cb635a5 100644 --- a/src/libraries/System.Drawing.Common/tests/Drawing2D/GraphicsPathIteratorTests.cs +++ b/src/libraries/System.Drawing.Common/tests/Drawing2D/GraphicsPathIteratorTests.cs @@ -63,7 +63,6 @@ public void Ctor_NullPath_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void NextSubpath_PathFigureNotClosed_ReturnsExpeced() { @@ -87,7 +86,6 @@ public void NextSubpath_PathFigureClosed_ReturnsExpeced() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void NextSubpath_NullPath_ReturnsExpected() { @@ -98,7 +96,6 @@ public void NextSubpath_NullPath_ReturnsExpected() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void NextSubpath_FigureNotClosed_ReturnsExpected() { @@ -239,7 +236,6 @@ public void HasCurve_ReturnsExpected() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Rewind_Success() { diff --git a/src/libraries/System.Drawing.Common/tests/Drawing2D/GraphicsPathTests.cs b/src/libraries/System.Drawing.Common/tests/Drawing2D/GraphicsPathTests.cs index 2edf80cd4f73b..8003d9d703584 100644 --- a/src/libraries/System.Drawing.Common/tests/Drawing2D/GraphicsPathTests.cs +++ b/src/libraries/System.Drawing.Common/tests/Drawing2D/GraphicsPathTests.cs @@ -374,7 +374,6 @@ public void AddLines_ZeroPoints_ThrowsArgumentException() AssertExtensions.Throws("points", null, () => new GraphicsPath().AddLines(new PointF[0])); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void AddArc_Values_Success() { @@ -397,7 +396,6 @@ public void AddArc_Values_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void AddArc_Rectangle_Success() { @@ -527,7 +525,6 @@ public void AddBeziers_InvalidFloatPointsLength_ThrowsArgumentException(PointF[] } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void AddCurve_TwoPoints_Success() { @@ -546,7 +543,6 @@ public void AddCurve_TwoPoints_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void AddCurve_TwoPointsWithTension_Success() { @@ -723,7 +719,6 @@ public void AddCurve_OffsetTooLarge_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void AddClosedCurve_Points_Success() { @@ -763,7 +758,6 @@ public void AddClosedCurve_SamePoints_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void AddClosedCurve_Tension_Success() { @@ -998,7 +992,6 @@ public void AddEllipse_ZeroWidthHeight_Success(int width, int height) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void AddPie_Rectangle_Success() { @@ -1011,7 +1004,6 @@ public void AddPie_Rectangle_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void AddPie_Values_Success() { @@ -1040,7 +1032,6 @@ public void AddPie_ZeroWidthHeight_ThrowsArgumentException(int width, int height } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void AddPolygon_Points_Success() { @@ -1056,7 +1047,6 @@ public void AddPolygon_Points_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void AddPolygon_SamePoints_Success() { @@ -1212,7 +1202,6 @@ public void AddString_NegativeSize_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void AddString_StringFormat_Success() { @@ -1542,7 +1531,6 @@ public void Warp_WarpModeInvalid_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Warp_RectangleEmpty_Success() { @@ -1910,7 +1898,6 @@ public void StartClose_AddRectangles() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void StartClose_AddString() { @@ -1929,7 +1916,6 @@ public void StartClose_AddString() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Widen_Pen_Success() { @@ -1978,7 +1964,6 @@ public void Widen_PenNull_ThrowsArgumentNullException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Widen_MatrixNull_Success() { @@ -1992,7 +1977,6 @@ public void Widen_MatrixNull_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Widen_MatrixEmpty_Success() { @@ -2016,7 +2000,6 @@ public static IEnumerable Widen_PenSmallWidth_TestData() yield return new object[] { new Rectangle(1, 1, 2, 2), 1.1f, new RectangleF(0.45f, 0.45f, 3.10f, 3.10f) }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Widen_PenSmallWidth_TestData))] public void Widen_Pen_SmallWidth_Succes( @@ -2112,14 +2095,12 @@ public void IsOutlineVisible_RectangleWithoutGraphics_ReturnsExpected() AssertIsOutlineVisibleRectangle(null); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void IsVisible_RectangleWithoutGraphics_ReturnsExpected() { AssertIsVisibleRectangle(null); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void IsVisible_RectangleWithGraphics_ReturnsExpected() { @@ -2285,7 +2266,6 @@ public void Reverse_Rectangles_Succes() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Reverse_Pie_Succes() { @@ -2323,7 +2303,6 @@ public void Reverse_EllipseRectangle_Succes() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Reverse_String_Succes() { diff --git a/src/libraries/System.Drawing.Common/tests/Drawing2D/LinearGradientBrushTests.cs b/src/libraries/System.Drawing.Common/tests/Drawing2D/LinearGradientBrushTests.cs index a672c41398b47..d60b0e5b439ea 100644 --- a/src/libraries/System.Drawing.Common/tests/Drawing2D/LinearGradientBrushTests.cs +++ b/src/libraries/System.Drawing.Common/tests/Drawing2D/LinearGradientBrushTests.cs @@ -42,7 +42,6 @@ public void Ctor_PointF_PointF_Color_Color(Point point1, Point point2, Color col } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Ctor_PointF_PointF_Color_Color_FloatRanges() { diff --git a/src/libraries/System.Drawing.Common/tests/Drawing2D/MatrixTests.cs b/src/libraries/System.Drawing.Common/tests/Drawing2D/MatrixTests.cs index e014299b88bef..d5bc5e5424b05 100644 --- a/src/libraries/System.Drawing.Common/tests/Drawing2D/MatrixTests.cs +++ b/src/libraries/System.Drawing.Common/tests/Drawing2D/MatrixTests.cs @@ -468,7 +468,6 @@ public static IEnumerable Rotate_TestData() yield return new object[] { new Matrix(10, 20, 30, 40, 50, 60), float.NegativeInfinity, PointF.Empty, MatrixOrder.Append, new float[] { float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN }, null, false }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Rotate_TestData))] public void Rotate_Matrix_Success(Matrix matrix, float angle, PointF point, MatrixOrder order, float[] expectedElements, float[] expectedElementsRotateAt, bool isIdentity) diff --git a/src/libraries/System.Drawing.Common/tests/FontFamilyTests.cs b/src/libraries/System.Drawing.Common/tests/FontFamilyTests.cs index cf6287420d3b1..c3790bf806bc0 100644 --- a/src/libraries/System.Drawing.Common/tests/FontFamilyTests.cs +++ b/src/libraries/System.Drawing.Common/tests/FontFamilyTests.cs @@ -9,7 +9,6 @@ namespace System.Drawing.Tests { public class FontFamilyTests { - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(GenericFontFamilies.Serif - 1, "Courier New")] // Value is outside the enum range. [InlineData(GenericFontFamilies.Monospace + 1, "Courier New")] // Value is outside the enum range. @@ -24,7 +23,6 @@ public void Ctor_GenericFamily(GenericFontFamilies genericFamily, string expecte } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData("Courier New", "Courier New")] [InlineData("Microsoft Sans Serif", "Microsoft Sans Serif")] @@ -38,7 +36,6 @@ public void Ctor_Name(string name, string expectedName) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Ctor_Name_FontCollection() { @@ -53,7 +50,6 @@ public void Ctor_Name_FontCollection() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(null)] [InlineData("NoSuchFont")] @@ -84,7 +80,6 @@ public static IEnumerable Equals_TestData() yield return new object[] { FontFamily.GenericSansSerif, null, false }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Equals_TestData))] public void Equals_Object_ReturnsExpected(FontFamily fontFamily, object other, bool expected) @@ -103,7 +98,6 @@ public void Equals_Object_ReturnsExpected(FontFamily fontFamily, object other, b // This will fail on any platform we use libgdiplus, with any // installed system fonts whose name is longer than 31 chars. // macOS 10.15+ ships out of the box with a problem font - [ActiveIssue("https://github.com/dotnet/runtime/issues/40937", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Families_Get_ReturnsExpected() { @@ -134,7 +128,6 @@ public void Families_Get_ReturnsExpected() #pragma warning restore 0618 } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GenericMonospace_Get_ReturnsExpected() { @@ -148,7 +141,6 @@ public void GenericMonospace_Get_ReturnsExpected() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GenericSansSerif_Get_ReturnsExpected() { @@ -162,7 +154,6 @@ public void GenericSansSerif_Get_ReturnsExpected() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GenericSerif_Get_ReturnsExpected() { @@ -184,7 +175,6 @@ public void GetFamilies_NullGraphics_ThrowsArgumentNullException() #pragma warning restore 0618 } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetHashCode_Invoke_ReturnsNameHashCode() { @@ -205,7 +195,6 @@ public static IEnumerable FontStyle_TestData() yield return new object[] { FontStyle.Strikeout + 1 }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(FontStyle_TestData))] public void FontFamilyProperties_CustomFont_ReturnsExpected(FontStyle style) @@ -225,7 +214,6 @@ public void FontFamilyProperties_CustomFont_ReturnsExpected(FontStyle style) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void IsStyleAvailable_Disposed_ThrowsArgumentException() { @@ -235,7 +223,6 @@ public void IsStyleAvailable_Disposed_ThrowsArgumentException() AssertExtensions.Throws(null, () => fontFamily.IsStyleAvailable(FontStyle.Italic)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetEmHeight_Disposed_ThrowsArgumentException() { @@ -247,7 +234,6 @@ public void GetEmHeight_Disposed_ThrowsArgumentException() private const int FrenchLCID = 1036; - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(-1, "Code New Roman")] [InlineData(0, "Code New Roman")] @@ -267,7 +253,6 @@ public void GetName_LanguageCode_ReturnsExpected(int languageCode, string expect } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetName_Disposed_ThrowsArgumentException() { @@ -277,7 +262,6 @@ public void GetName_Disposed_ThrowsArgumentException() AssertExtensions.Throws(null, () => fontFamily.GetName(0)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetCellAscent_Disposed_ThrowsArgumentException() { @@ -287,7 +271,6 @@ public void GetCellAscent_Disposed_ThrowsArgumentException() AssertExtensions.Throws(null, () => fontFamily.GetCellAscent(FontStyle.Italic)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetCellDescent_Disposed_ThrowsArgumentException() { @@ -297,7 +280,6 @@ public void GetCellDescent_Disposed_ThrowsArgumentException() AssertExtensions.Throws(null, () => fontFamily.GetCellDescent(FontStyle.Italic)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetLineSpacing_Disposed_ThrowsArgumentException() { @@ -307,7 +289,6 @@ public void GetLineSpacing_Disposed_ThrowsArgumentException() AssertExtensions.Throws(null, () => fontFamily.GetLineSpacing(FontStyle.Italic)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Dispose_MultipleTimes_Nop() { diff --git a/src/libraries/System.Drawing.Common/tests/FontTests.cs b/src/libraries/System.Drawing.Common/tests/FontTests.cs index 4cf0c6e690b50..d61c626e88a2f 100644 --- a/src/libraries/System.Drawing.Common/tests/FontTests.cs +++ b/src/libraries/System.Drawing.Common/tests/FontTests.cs @@ -323,7 +323,6 @@ public void Ctor_FamilyName_Size_Style_Unit_GdiCharSet_GdiVerticalFont(FontFamil } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Ctor_FamilyNamePrefixedWithAtSign_StripsSign() { @@ -382,7 +381,6 @@ public void Ctor_DisposedFamily_ThrowsArgumentException() AssertExtensions.Throws(null, () => new Font(family, 10, FontStyle.Italic, GraphicsUnit.Display, 10, gdiVerticalFont: true)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(-1)] [InlineData(0)] @@ -445,7 +443,6 @@ public void Clone_Invoke_ReturnsExpected() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Clone_DisposedFont_ThrowsArgumentException() { @@ -464,11 +461,7 @@ public static IEnumerable Equals_TestData() var font = new Font(family, 10, FontStyle.Bold, GraphicsUnit.Inch, 10, gdiVerticalFont: true); yield return new object[] { font, font, true }; - // [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] - if (PlatformDetection.IsWindows) - { - yield return new object[] { font.Clone(), new Font(family, 10, FontStyle.Bold, GraphicsUnit.Inch, 10, gdiVerticalFont: true), false }; - } + yield return new object[] { font.Clone(), new Font(family, 10, FontStyle.Bold, GraphicsUnit.Inch, 10, gdiVerticalFont: true), false }; yield return new object[] { font.Clone(), new Font(family, 9, FontStyle.Bold, GraphicsUnit.Inch, 10, gdiVerticalFont: true), false }; yield return new object[] { font.Clone(), new Font(family, 10, FontStyle.Italic, GraphicsUnit.Millimeter, 10, gdiVerticalFont: true), false }; yield return new object[] { font.Clone(), new Font(family, 10, FontStyle.Bold, GraphicsUnit.Inch, 9, gdiVerticalFont: true), false }; @@ -503,14 +496,12 @@ public void Equals_Other_ReturnsExpected(Font font, object other, bool expected) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void FromHdc_ZeroHdc_ThrowsArgumentException() { AssertExtensions.Throws(null, () => Font.FromHdc(IntPtr.Zero)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void FromHdc_GraphicsHdc_ThrowsArgumentException() { @@ -529,7 +520,6 @@ public void FromHdc_GraphicsHdc_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void FromHfont_Zero_ThrowsArgumentException() { @@ -561,7 +551,6 @@ public void GetHeight_Graphics_ReturnsExpected() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(0, 0)] [InlineData(-1, -0.1571995)] @@ -619,7 +608,6 @@ public void GetHeight_Disposed_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(FontStyle.Bold, int.MinValue, 0)] [InlineData(FontStyle.Bold, -2147483099, 0)] @@ -657,7 +645,6 @@ public void FromLogFont_ValidLogFont_ReturnsExpected(FontStyle fontStyle, int we } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void FromLogFont_NullLogFont_ThrowsArgumentNullException() { @@ -685,7 +672,6 @@ public void FromLogFont_NullLogFont_ThrowsArgumentNullException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void FromLogFont_InvalidLogFont_ThrowsArgumentException() { @@ -706,7 +692,6 @@ public void FromLogFont_InvalidLogFont_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void FromLogFont_UnblittableStruct() { @@ -809,7 +794,6 @@ public void ToLogFont_Invoke_ReturnsExpected(FontStyle fontStyle, byte gdiCharSe } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(TextRenderingHint.SystemDefault)] [InlineData(TextRenderingHint.AntiAlias)] @@ -904,7 +888,6 @@ public class LOGFONT public string lfFaceName; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void ToHfont_SimpleFont_Roundtrips() { @@ -920,7 +903,6 @@ public void ToHfont_SimpleFont_Roundtrips() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void ToHfont_ComplicatedFont_DoesNotRoundtrip() { diff --git a/src/libraries/System.Drawing.Common/tests/GdiPlusHandlesTests.cs b/src/libraries/System.Drawing.Common/tests/GdiPlusHandlesTests.cs index 5b66bae38beee..85c580f89ac74 100644 --- a/src/libraries/System.Drawing.Common/tests/GdiPlusHandlesTests.cs +++ b/src/libraries/System.Drawing.Common/tests/GdiPlusHandlesTests.cs @@ -9,7 +9,6 @@ namespace System.Drawing.Tests { - [PlatformSpecific(TestPlatforms.Windows)] public static class GdiPlusHandlesTests { public static bool IsDrawingAndRemoteExecutorSupported => Helpers.GetIsDrawingSupported() && RemoteExecutor.IsSupported; diff --git a/src/libraries/System.Drawing.Common/tests/GdiplusTests.cs b/src/libraries/System.Drawing.Common/tests/GdiplusTests.cs deleted file mode 100644 index 869f67af1622e..0000000000000 --- a/src/libraries/System.Drawing.Common/tests/GdiplusTests.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Xunit; - -namespace System.Drawing.Tests -{ - public class GdiplusTests - { - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsOSX))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/49111", typeof(PlatformDetection), nameof(PlatformDetection.IsMacOsAppleSilicon))] - public void IsAtLeastLibgdiplus6() - { - Assert.True(Helpers.GetIsWindowsOrAtLeastLibgdiplus6()); - } - } -} diff --git a/src/libraries/System.Drawing.Common/tests/GraphicsTests.Core.cs b/src/libraries/System.Drawing.Common/tests/GraphicsTests.Core.cs index d691cd23ff9df..4e8d23033fd86 100644 --- a/src/libraries/System.Drawing.Common/tests/GraphicsTests.Core.cs +++ b/src/libraries/System.Drawing.Common/tests/GraphicsTests.Core.cs @@ -23,7 +23,6 @@ public void TransformElements_SetNonInvertibleMatrix_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void TransformElements_GetSetWhenBusy_ThrowsInvalidOperationException() { @@ -103,7 +102,6 @@ public void DrawRectangle_DisposedPen_ThrowsArgumentException_Core() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawRectangle_Busy_ThrowsInvalidOperationException_Core() { @@ -163,7 +161,6 @@ public void FillPie_DisposedPen_ThrowsArgumentException_Core() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void FillPie_ZeroWidth_ThrowsArgumentException_Core() { @@ -176,7 +173,6 @@ public void FillPie_ZeroWidth_ThrowsArgumentException_Core() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void FillPie_ZeroHeight_ThrowsArgumentException_Core() { @@ -189,7 +185,6 @@ public void FillPie_ZeroHeight_ThrowsArgumentException_Core() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void FillPie_Busy_ThrowsInvalidOperationException_Core() { diff --git a/src/libraries/System.Drawing.Common/tests/GraphicsTests.cs b/src/libraries/System.Drawing.Common/tests/GraphicsTests.cs index c99ad88ea40ae..c9b7bb62d5391 100644 --- a/src/libraries/System.Drawing.Common/tests/GraphicsTests.cs +++ b/src/libraries/System.Drawing.Common/tests/GraphicsTests.cs @@ -12,7 +12,6 @@ namespace System.Drawing.Tests { public partial class GraphicsTests { - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetHdc_FromHdc_Roundtrips() { @@ -36,7 +35,6 @@ public void GetHdc_FromHdc_Roundtrips() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetHdc_SameImage_ReturnsSame() { @@ -56,7 +54,6 @@ public void GetHdc_SameImage_ReturnsSame() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetHdc_NotReleased_ThrowsInvalidOperationException() { @@ -75,7 +72,6 @@ public void GetHdc_NotReleased_ThrowsInvalidOperationException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetHdc_Disposed_ThrowsObjectDisposedException() { @@ -97,7 +93,6 @@ public static IEnumerable FromHdc_TestData() yield return new object[] { Helpers.GetDC(foregroundWindow) }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ActiveIssue("https://github.com/dotnet/runtime/issues/51097", typeof(PlatformDetection), nameof(PlatformDetection.IsArm64Process), nameof(PlatformDetection.IsWindows10OrLater))] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(FromHdc_TestData))] @@ -110,7 +105,6 @@ public void FromHdc_ValidHdc_ReturnsExpected(IntPtr hdc) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ActiveIssue("https://github.com/dotnet/runtime/issues/51097", typeof(PlatformDetection), nameof(PlatformDetection.IsArm64Process), nameof(PlatformDetection.IsWindows10OrLater))] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(FromHdc_TestData))] @@ -123,7 +117,6 @@ public void FromHdc_ValidHdcWithContext_ReturnsExpected(IntPtr hdc) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ActiveIssue("https://github.com/dotnet/runtime/issues/51097", typeof(PlatformDetection), nameof(PlatformDetection.IsArm64Process), nameof(PlatformDetection.IsWindows10OrLater))] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(FromHdc_TestData))] @@ -136,28 +129,24 @@ public void FromHdcInternal_GetDC_ReturnsExpected(IntPtr hdc) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void FromHdc_ZeroHdc_ThrowsArgumentNullException() { AssertExtensions.Throws("hdc", () => Graphics.FromHdc(IntPtr.Zero)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void FromHdcInternal_ZeroHdc_ThrowsOutOfMemoryException() { Assert.Throws(() => Graphics.FromHdcInternal(IntPtr.Zero)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void FromHdc_ZeroHdc_ThrowsOutOfMemoryException() { Assert.Throws(() => Graphics.FromHdc(IntPtr.Zero, (IntPtr)10)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void FromHdc_InvalidHdc_ThrowsOutOfMemoryException() { @@ -165,7 +154,6 @@ public void FromHdc_InvalidHdc_ThrowsOutOfMemoryException() Assert.Throws(() => Graphics.FromHwndInternal((IntPtr)10)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void ReleaseHdc_ValidHdc_ResetsHdc() { @@ -189,7 +177,6 @@ public void ReleaseHdc_ValidHdc_ResetsHdc() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void ReleaseHdc_NoSuchHdc_ResetsHdc() { @@ -206,7 +193,6 @@ public void ReleaseHdc_NoSuchHdc_ResetsHdc() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void ReleaseHdc_OtherGraphicsHdc_Success() { @@ -239,7 +225,6 @@ public void ReleaseHdc_NoHdc_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void ReleaseHdc_Disposed_ThrowsObjectDisposedException() { @@ -260,7 +245,6 @@ public static IEnumerable Hwnd_TestData() yield return new object[] { Helpers.GetForegroundWindow() }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ActiveIssue("https://github.com/dotnet/runtime/issues/51097", typeof(PlatformDetection), nameof(PlatformDetection.IsArm64Process), nameof(PlatformDetection.IsWindows10OrLater))] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Hwnd_TestData))] @@ -273,7 +257,6 @@ public void FromHwnd_ValidHwnd_ReturnsExpected(IntPtr hWnd) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ActiveIssue("https://github.com/dotnet/runtime/issues/51097", typeof(PlatformDetection), nameof(PlatformDetection.IsArm64Process), nameof(PlatformDetection.IsWindows10OrLater))] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Hwnd_TestData))] @@ -286,7 +269,6 @@ public void FromHwndInternal_ValidHwnd_ReturnsExpected(IntPtr hWnd) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void FromHwnd_InvalidHwnd_ThrowsOutOfMemoryException() { @@ -294,7 +276,6 @@ public void FromHwnd_InvalidHwnd_ThrowsOutOfMemoryException() Assert.Throws(() => Graphics.FromHdcInternal((IntPtr)10)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(PixelFormat.Format16bppRgb555)] [InlineData(PixelFormat.Format16bppRgb565)] @@ -314,7 +295,6 @@ public void FromImage_Bitmap_Success(PixelFormat format) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void FromImage_NullImage_ThrowsArgumentNullException() { @@ -353,7 +333,6 @@ public void FromImage_Metafile_ThrowsOutOfMemoryException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(PixelFormat.Format16bppArgb1555)] [InlineData(PixelFormat.Format16bppGrayScale)] @@ -371,7 +350,6 @@ public static IEnumerable CompositingMode_TestData() yield return new object[] { CompositingMode.SourceOver, Color.FromArgb(220, 185, 185, 185) }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(CompositingMode_TestData))] public void CompositingMode_Set_GetReturnsExpected(CompositingMode mode, Color expectedOverlap) @@ -414,7 +392,6 @@ public void CompositingMode_SetInvalid_ThrowsInvalidEnumArgumentException(Compos } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void CompositingMode_GetSetWhenBusy_ThrowsInvalidOperationException() { @@ -473,7 +450,6 @@ public static IEnumerable CompositingQuality_TestData() yield return new object[] { CompositingQuality.HighQuality, gammaCorrectedColors }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(CompositingQuality_TestData))] public void CompositingQuality_Set_GetReturnsExpected(CompositingQuality quality, Color[][] expectedIntersectionColor) @@ -508,7 +484,6 @@ public void CompositingQuality_SetInvalid_ThrowsInvalidEnumArgumentException(Com } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void CompositingQuality_GetSetWhenBusy_ThrowsInvalidOperationException() { @@ -571,7 +546,6 @@ public void Dispose_MultipleTimesWithHdc_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DpiX_GetWhenBusy_ThrowsInvalidOperationException() { @@ -602,7 +576,6 @@ public void DpiX_GetWhenDisposed_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DpiY_GetWhenBusy_ThrowsInvalidOperationException() { @@ -654,7 +627,6 @@ public void Flush_MultipleTimes_Success(FlushIntention intention) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Flush_Busy_ThrowsInvalidOperationException() { @@ -728,7 +700,6 @@ public void InterpolationMode_SetToInvalid_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void InterpolationMode_GetSetWhenBusy_ThrowsInvalidOperationException() { @@ -790,7 +761,6 @@ public void PageScale_SetInvalid_ThrowsArgumentException(float pageScale) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void PageScale_GetSetWhenBusy_ThrowsInvalidOperationException() { @@ -862,7 +832,6 @@ public void PageUnit_SetWorld_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void PageUnit_GetSetWhenBusy_ThrowsInvalidOperationException() { @@ -933,7 +902,6 @@ public void PixelOffsetMode_SetToInvalid_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void PixelOffsetMode_GetSetWhenBusy_ThrowsInvalidOperationException() { @@ -1004,7 +972,6 @@ public static IEnumerable RenderingOrigin_TestData() yield return new object[] { new Point(3, 3), allEmpty }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(RenderingOrigin_TestData))] public void RenderingOrigin_SetToCustom_RendersExpected(Point renderingOrigin, Color[][] expectedRendering) @@ -1023,7 +990,6 @@ public void RenderingOrigin_SetToCustom_RendersExpected(Point renderingOrigin, C } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void RenderingOrigin_GetSetWhenBusy_ThrowsInvalidOperationException() { @@ -1094,7 +1060,6 @@ public void SmoothingMode_SetToInvalid_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void SmoothingMode_GetSetWhenBusy_ThrowsInvalidOperationException() { @@ -1153,7 +1118,6 @@ public void TextContrast_SetInvalid_ThrowsArgumentException(int textContrast) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void TextContrast_GetSetWhenBusy_ThrowsInvalidOperationException() { @@ -1215,7 +1179,6 @@ public void TextRenderingHint_SetInvalid_ThrowsInvalidEnumArgumentException(Text } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void TextRenderingHint_GetSetWhenBusy_ThrowsInvalidOperationException() { @@ -1248,7 +1211,6 @@ public void TextRenderingHint_GetSetWhenDisposed_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Transform_SetValid_GetReturnsExpected() { @@ -1311,7 +1273,6 @@ public void Transform_SetNonInvertibleMatrix_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Transform_GetSetWhenBusy_ThrowsInvalidOperationException() { @@ -1361,7 +1322,6 @@ public void ResetTransform_Invoke_SetsTransformToIdentity() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void ResetTransform_Busy_ThrowsInvalidOperationException() { @@ -1479,7 +1439,6 @@ public void MultiplyTransform_InvalidOrder_ThrowsArgumentException(MatrixOrder o } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void MultiplyTransform_Busy_ThrowsInvalidOperationException() { @@ -1567,7 +1526,6 @@ public void TranslateTransform_InvalidOrder_ThrowsArgumentException(MatrixOrder } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void TranslateTransform_Busy_ThrowsInvalidOperationException() { @@ -1661,7 +1619,6 @@ public void ScaleTransform_InvalidOrder_ThrowsArgumentException(MatrixOrder orde } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void ScaleTransform_Busy_ThrowsInvalidOperationException() { @@ -1748,7 +1705,6 @@ public void RotateTransform_InvalidOrder_ThrowsArgumentException(MatrixOrder ord } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void RotateTransform_Busy_ThrowsInvalidOperationException() { @@ -1793,7 +1749,6 @@ public static IEnumerable CopyFromScreen_TestData() } [ActiveIssue("https://github.com/dotnet/runtime/issues/23375")] - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(CopyFromScreen_TestData))] public void CopyFromScreen_OutOfRange_DoesNotAffectGraphics(int sourceX, int sourceY, int destinationX, int destinationY, Size size) @@ -1811,7 +1766,6 @@ public void CopyFromScreen_OutOfRange_DoesNotAffectGraphics(int sourceX, int sou } [ActiveIssue("https://github.com/dotnet/runtime/issues/23375")] - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(0, 0, 0, 0, 10, 10)] [InlineData(0, 0, 0, 0, int.MaxValue, int.MaxValue)] @@ -1869,7 +1823,6 @@ public static IEnumerable CopyPixelOperation_TestData() } [ActiveIssue("https://github.com/dotnet/runtime/issues/23375")] - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(CopyPixelOperation_TestData))] public void CopyFromScreen_IntsAndValidCopyPixelOperation_Success(CopyPixelOperation copyPixelOperation) @@ -1884,7 +1837,6 @@ public void CopyFromScreen_IntsAndValidCopyPixelOperation_Success(CopyPixelOpera } [ActiveIssue("https://github.com/dotnet/runtime/issues/23375")] - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(CopyPixelOperation_TestData))] public void CopyFromScreen_PointsAndValidCopyPixelOperation_Success(CopyPixelOperation copyPixelOperation) @@ -1899,7 +1851,6 @@ public void CopyFromScreen_PointsAndValidCopyPixelOperation_Success(CopyPixelOpe } [ActiveIssue("https://github.com/dotnet/runtime/issues/23375")] - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(CopyPixelOperation.NoMirrorBitmap + 1)] [InlineData(CopyPixelOperation.Blackness - 1)] @@ -1929,7 +1880,6 @@ public void CopyFromScreen_InvalidCopyPixelOperation_ThrowsInvalidEnumArgumentEx } [ActiveIssue("https://github.com/dotnet/runtime/issues/23375")] - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void CopyFromScreen_Busy_ThrowsInvalidOperationException() { @@ -1952,7 +1902,6 @@ public void CopyFromScreen_Busy_ThrowsInvalidOperationException() } [ActiveIssue("https://github.com/dotnet/runtime/issues/23375")] - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void CopyFromScreen_Disposed_ThrowsArgumentException() { @@ -2019,7 +1968,6 @@ public static IEnumerable TransformPoints_TestData() }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(TransformPoints_TestData))] public void TransformPoints_Points_Success(CoordinateSpace destSpace, CoordinateSpace srcSpace, Point[] points, Point[] expected) @@ -2087,7 +2035,6 @@ public static IEnumerable TransformPointFs_TestData() }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(TransformPointFs_TestData))] public void TransformPoints_PointFs_Success(CoordinateSpace destSpace, CoordinateSpace srcSpace, PointF[] points, PointF[] expected) @@ -2104,7 +2051,6 @@ public void TransformPoints_PointFs_Success(CoordinateSpace destSpace, Coordinat } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(CoordinateSpace.Device)] [InlineData(CoordinateSpace.World)] @@ -2123,7 +2069,6 @@ public void TransformPoints_PointsAndSameCoordinateSpace_DoesNothing(CoordinateS } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(CoordinateSpace.Device)] [InlineData(CoordinateSpace.World)] @@ -2142,7 +2087,6 @@ public void TransformPoints_PointFsAndSameCoordinateSpace_DoesNothing(Coordinate } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(CoordinateSpace.World - 1)] [InlineData(CoordinateSpace.Device + 1)] @@ -2156,7 +2100,6 @@ public void TransformPoints_InvalidDestSpace_ThrowsArgumentException(CoordinateS } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(CoordinateSpace.World - 1)] [InlineData(CoordinateSpace.Device + 1)] @@ -2181,7 +2124,6 @@ public void TransformPoints_NullPoints_ThrowsArgumentNullException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void TransformPoints_EmptyPoints_ThrowsArgumentException() { @@ -2193,7 +2135,6 @@ public void TransformPoints_EmptyPoints_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void TransformPoints_Busy_ThrowsInvalidOperationException() { @@ -2213,7 +2154,6 @@ public void TransformPoints_Busy_ThrowsInvalidOperationException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void TransformPoints_Disposed_ThrowsArgumentException() { @@ -2233,7 +2173,6 @@ public static IEnumerable GetNearestColor_TestData() yield return new object[] { PixelFormat.Format16bppRgb555, Color.Red, Color.FromArgb(255, 248, 0, 0) }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(GetNearestColor_TestData))] public void GetNearestColor_Color_ReturnsExpected(PixelFormat pixelFormat, Color color, Color expected) @@ -2245,7 +2184,6 @@ public void GetNearestColor_Color_ReturnsExpected(PixelFormat pixelFormat, Color } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetNearestColor_Busy_ThrowsInvalidOperationException() { @@ -2264,7 +2202,6 @@ public void GetNearestColor_Busy_ThrowsInvalidOperationException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetNearestColor_Disposed_ThrowsArgumentException() { @@ -2277,7 +2214,6 @@ public void GetNearestColor_Disposed_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawArc_NullPen_ThrowsArgumentNullException() { @@ -2291,7 +2227,6 @@ public void DrawArc_NullPen_ThrowsArgumentNullException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawArc_DisposedPen_ThrowsArgumentException() { @@ -2308,7 +2243,6 @@ public void DrawArc_DisposedPen_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawArc_ZeroWidth_ThrowsArgumentException() { @@ -2323,7 +2257,6 @@ public void DrawArc_ZeroWidth_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawArc_ZeroHeight_ThrowsArgumentException() { @@ -2338,7 +2271,6 @@ public void DrawArc_ZeroHeight_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawArc_Busy_ThrowsInvalidOperationException() { @@ -2361,7 +2293,6 @@ public void DrawArc_Busy_ThrowsInvalidOperationException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawArc_Disposed_ThrowsArgumentException() { @@ -2405,7 +2336,6 @@ public void DrawRectangle_DisposedPen_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawRectangle_Busy_ThrowsInvalidOperationException() { @@ -2491,7 +2421,6 @@ public void DrawRectangles_EmptyRectangles_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawRectangles_Busy_ThrowsInvalidOperationException() { @@ -2556,7 +2485,6 @@ public void DrawEllipse_DisposedPen_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawEllipse_Busy_ThrowsInvalidOperationException() { @@ -2624,7 +2552,6 @@ public void DrawPie_DisposedPen_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawPie_ZeroWidth_ThrowsArgumentException() { @@ -2639,7 +2566,6 @@ public void DrawPie_ZeroWidth_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawPie_ZeroHeight_ThrowsArgumentException() { @@ -2654,7 +2580,6 @@ public void DrawPie_ZeroHeight_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawPie_Busy_ThrowsInvalidOperationException() { @@ -2744,7 +2669,6 @@ public void DrawPolygon_InvalidPointsLength_ThrowsArgumentException(int length) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawPolygon_Busy_ThrowsInvalidOperationException() { @@ -2829,7 +2753,6 @@ public void DrawPath_DisposedPath_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawPath_Busy_ThrowsInvalidOperationException() { @@ -2935,7 +2858,6 @@ public void DrawCurve_InvalidPointsLength_ThrowsArgumentException(int length) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(4, -1, 4)] [InlineData(4, 0, -1)] @@ -2954,7 +2876,6 @@ public void DrawCurve_InvalidOffsetCount_ThrowsArgumentException(int length, int } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawCurve_Busy_ThrowsInvalidOperationException() { @@ -3059,7 +2980,6 @@ public void DrawClosedCurve_InvalidPointsLength_ThrowsArgumentException(int leng } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawClosedCurve_Busy_ThrowsInvalidOperationException() { @@ -3125,7 +3045,6 @@ public void FillPie_DisposedPen_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void FillPie_ZeroWidth_ThrowsArgumentException() { @@ -3139,7 +3058,6 @@ public void FillPie_ZeroWidth_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void FillPie_ZeroHeight_ThrowsArgumentException() { @@ -3153,7 +3071,6 @@ public void FillPie_ZeroHeight_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void FillPie_Busy_ThrowsInvalidOperationException() { @@ -3210,7 +3127,6 @@ public void Clear_Color_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Clear_Busy_ThrowsInvalidOperationException() { @@ -3243,7 +3159,6 @@ public void Clear_Disposed_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawString_DefaultFont_Succeeds() { @@ -3255,7 +3170,6 @@ public void DrawString_DefaultFont_Succeeds() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawString_CompositingModeSourceCopy_ThrowsArgumentException() { diff --git a/src/libraries/System.Drawing.Common/tests/Graphics_DrawBezierTests.cs b/src/libraries/System.Drawing.Common/tests/Graphics_DrawBezierTests.cs index c822db2a9d15b..8fecb6ce39ef4 100644 --- a/src/libraries/System.Drawing.Common/tests/Graphics_DrawBezierTests.cs +++ b/src/libraries/System.Drawing.Common/tests/Graphics_DrawBezierTests.cs @@ -142,7 +142,6 @@ public void DrawBeziers_NullPen_ThrowsArgumentNullException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawBeziers_DisposedPen_ThrowsArgumentException() { @@ -169,7 +168,6 @@ public void DrawBeziers_NullPoints_ThrowsArgumentNullException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawBeziers_EmptyPoints_ThrowsArgumentException() { @@ -182,7 +180,6 @@ public void DrawBeziers_EmptyPoints_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawBeziers_Busy_ThrowsInvalidOperationException() { @@ -203,7 +200,6 @@ public void DrawBeziers_Busy_ThrowsInvalidOperationException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawBeziers_Disposed_ThrowsArgumentException() { diff --git a/src/libraries/System.Drawing.Common/tests/Graphics_DrawLineTests.cs b/src/libraries/System.Drawing.Common/tests/Graphics_DrawLineTests.cs index e25d506eb84b9..a8ec9af5194e7 100644 --- a/src/libraries/System.Drawing.Common/tests/Graphics_DrawLineTests.cs +++ b/src/libraries/System.Drawing.Common/tests/Graphics_DrawLineTests.cs @@ -68,7 +68,6 @@ public void DrawLine_DisposedPen_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawLine_Busy_ThrowsInvalidOperationException() { @@ -158,7 +157,6 @@ public void DrawLines_InvalidPointsLength_ThrowsArgumentException(int length) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DrawLines_Busy_ThrowsInvalidOperationException() { diff --git a/src/libraries/System.Drawing.Common/tests/IconTests.cs b/src/libraries/System.Drawing.Common/tests/IconTests.cs index 7a415016e4262..82086c4e427e6 100644 --- a/src/libraries/System.Drawing.Common/tests/IconTests.cs +++ b/src/libraries/System.Drawing.Common/tests/IconTests.cs @@ -49,13 +49,6 @@ public void Ctor_FilePath(string name) } } - [Fact] - [PlatformSpecific(TestPlatforms.AnyUnix)] - public void Unix_OverflowException_CorruptIcon() - { - Assert.Throws(() => new Icon(Helpers.GetTestBitmapPath("overflowicon.ico"))); - } - public static IEnumerable Size_TestData() { // Normal size @@ -76,7 +69,6 @@ public static IEnumerable Size_TestData() yield return new object[] { "256x256_one_entry_32bit.ico", new Size(int.MaxValue, int.MaxValue), new Size(256, 256) }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Size_TestData))] public void Ctor_FilePath_Width_Height(string fileName, Size size, Size expectedSize) @@ -89,7 +81,6 @@ public void Ctor_FilePath_Width_Height(string fileName, Size size, Size expected } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Size_TestData))] public void Ctor_FilePath_Size(string fileName, Size size, Size expectedSize) @@ -122,7 +113,6 @@ public void Ctor_Stream() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Size_TestData))] public void Ctor_Stream_Width_Height(string fileName, Size size, Size expectedSize) @@ -136,7 +126,6 @@ public void Ctor_Stream_Width_Height(string fileName, Size size, Size expectedSi } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Size_TestData))] public void Ctor_Stream_Size(string fileName, Size size, Size expectedSize) @@ -215,7 +204,6 @@ public static IEnumerable Ctor_InvalidBytesInStream_TestData() yield return new object[] { new byte[] { 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, typeof(Win32Exception) }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Ctor_InvalidBytesInStream_TestData))] public void Ctor_InvalidBytesInStream_ThrowsException(byte[] bytes, Type exceptionType) @@ -229,7 +217,6 @@ public void Ctor_InvalidBytesInStream_ThrowsException(byte[] bytes, Type excepti } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Size_TestData))] public void Ctor_Icon_Width_Height(string fileName, Size size, Size expectedSize) @@ -244,7 +231,6 @@ public void Ctor_Icon_Width_Height(string fileName, Size size, Size expectedSize } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Size_TestData))] public void Ctor_Icon_Size(string fileName, Size size, Size expectedSize) @@ -333,7 +319,6 @@ public void Dispose_IconData_DestroysHandle() Assert.Throws(() => icon.Handle); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Dispose_OwnsHandle_DestroysHandle() { @@ -384,7 +369,6 @@ public void ExtractAssociatedIcon_FilePath_Success() ExtractAssociatedIcon_FilePath_Success_Helper(Helpers.GetTestBitmapPath("48x48_multiple_entries_4bit.ico")); } - [PlatformSpecific(TestPlatforms.Windows)] // UNC [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Fix for https://github.com/dotnet/runtime/issues/28220")] [ConditionalFact(Helpers.IsDrawingSupported)] public void ExtractAssociatedIcon_UNCFilePath_Success() @@ -418,7 +402,6 @@ private void ExtractAssociatedIcon_FilePath_Success_Helper(string filePath) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void ExtractAssociatedIcon_NonFilePath_ThrowsFileNotFound() { @@ -498,7 +481,6 @@ public void Save_NullOutputStreamIconData_ThrowsNullReferenceException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] [ActiveIssue("https://github.com/dotnet/runtime/issues/47759", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] public void Save_NullOutputStreamNoIconData_ThrowsArgumentNullException() @@ -512,7 +494,6 @@ public void Save_NullOutputStreamNoIconData_ThrowsArgumentNullException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Save_ClosedOutputStreamIconData_ThrowsException() { @@ -525,7 +506,6 @@ public void Save_ClosedOutputStreamIconData_ThrowsException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ActiveIssue("https://github.com/dotnet/runtime/issues/47759", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Save_ClosedOutputStreamNoIconData() @@ -549,7 +529,6 @@ public void Save_ClosedOutputStreamNoIconData() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Save_NoIconDataOwnsHandleAndDisposed_ThrowsObjectDisposedException() { @@ -609,7 +588,6 @@ public void ToBitmap_BitmapIconFromHandle_ReturnsExpected() private const string DontSupportPngFramesInIcons = "Switch.System.Drawing.DontSupportPngFramesInIcons"; - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ActiveIssue("https://github.com/dotnet/runtime/issues/55655", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] [ConditionalFact(Helpers.IsDrawingSupported)] public void ToBitmap_PngIconSupportedInSwitches_Success() @@ -647,7 +625,6 @@ void VerifyPng() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ActiveIssue("https://github.com/dotnet/runtime/issues/55655", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] [ConditionalFact(Helpers.IsDrawingSupported)] public void ToBitmap_PngIconNotSupportedInSwitches_ThrowsArgumentOutOfRangeException() @@ -841,42 +818,17 @@ public void CorrectColorDepthExtracted() Assert.Equal(new Size(32, 32), bitmap.Size); int expectedBitDepth; - if (!PlatformDetection.IsWindows) - { - // The Unix implementation currently doesn't try to match the display, - // it will just pick the highest color depth when creating the bitmap. - // (see SaveBestSingleIcon()). - expectedBitDepth = 32; - } - else - { - string fieldName = PlatformDetection.IsNetFramework ? "bitDepth" : "s_bitDepth"; - FieldInfo fi = typeof(Icon).GetField(fieldName, BindingFlags.Static | BindingFlags.NonPublic); - expectedBitDepth = (int)fi.GetValue(null); - } + string fieldName = PlatformDetection.IsNetFramework ? "bitDepth" : "s_bitDepth"; + FieldInfo fi = typeof(Icon).GetField(fieldName, BindingFlags.Static | BindingFlags.NonPublic); + expectedBitDepth = (int)fi.GetValue(null); // If the first icon entry was picked, the color would be black: 0xFF000000? switch (expectedBitDepth) { case 32: - if (!PlatformDetection.IsWindows) - { - // libgdiplus on Unix doesn't natively support ARGB32 format. It - // uses the Cairo library which represents the bitmaps as PARGB32 - // with individual channels premultiplied with the alpha channel. - // When converting back and forth it results in slight loss of - // precision so allow both original and rounded values here. - uint color = (uint)bitmap.GetPixel(0, 0).ToArgb(); - Assert.True(color == 0x879EE532u || color == 0x879EE431u, color.ToString("x")); - color = (uint)bitmap.GetPixel(0, 31).ToArgb(); - Assert.True(color == 0x661CD8B7u || color == 0x661BD7B6u, color.ToString("x")); - } - else - { - Assert.Equal(0x879EE532u, (uint)bitmap.GetPixel(0, 0).ToArgb()); - Assert.Equal(0x661CD8B7u, (uint)bitmap.GetPixel(0, 31).ToArgb()); - } + Assert.Equal(0x879EE532u, (uint)bitmap.GetPixel(0, 0).ToArgb()); + Assert.Equal(0x661CD8B7u, (uint)bitmap.GetPixel(0, 31).ToArgb()); break; case 16: case 8: diff --git a/src/libraries/System.Drawing.Common/tests/ImageTests.cs b/src/libraries/System.Drawing.Common/tests/ImageTests.cs index 00d37e7520df8..cfd315a96cdb0 100644 --- a/src/libraries/System.Drawing.Common/tests/ImageTests.cs +++ b/src/libraries/System.Drawing.Common/tests/ImageTests.cs @@ -23,7 +23,6 @@ public class ImageTests private const int PropertyTagTypeASCII = 2; private const int PropertyTagTypeShort = 3; - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [Fact] public void PropertyIdList_GetBitmapJpg_Success() { @@ -41,7 +40,6 @@ public void PropertyIdList_GetEmptyMemoryBitmap_ReturnsExpected() Assert.Same(bitmap.PropertyIdList, bitmap.PropertyIdList); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [Fact] public void PropertyItems_GetBitmapJpg_Success() { @@ -102,7 +100,6 @@ public void PropertyItems_GetEmptyMemoryBitmap_ReturnsExpected() Assert.Same(bitmap.PropertyItems, bitmap.PropertyItems); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [Fact] public void GetPropertyItem_InvokeExistsBitmapBmp_Success() { @@ -134,7 +131,6 @@ public void GetPropertyItem_NoSuchPropertyItemEmptyImageBitmapBmp_ThrowsArgument AssertExtensions.Throws(null, () => bitmap.GetPropertyItem(propid)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [Fact] public void RemovePropertyItem_InvokeMemoryBitmap_Success() { @@ -151,19 +147,18 @@ public void RemovePropertyItem_InvokeMemoryBitmap_Success() Assert.Equal(new int[] { PropertyTagChrominanceTable, PropertyTagLuminanceTable }, bitmap.PropertyIdList); AssertExtensions.Throws(null, () => bitmap.GetPropertyItem(PropertyTagExifUserComment)); AssertExtensions.Throws(null, () => bitmap.RemovePropertyItem(PropertyTagExifUserComment)); - + bitmap.RemovePropertyItem(PropertyTagLuminanceTable); Assert.Equal(new int[] { PropertyTagChrominanceTable }, bitmap.PropertyIdList); AssertExtensions.Throws(null, () => bitmap.GetPropertyItem(PropertyTagLuminanceTable)); AssertExtensions.Throws(null, () => bitmap.RemovePropertyItem(PropertyTagLuminanceTable)); - + bitmap.RemovePropertyItem(PropertyTagChrominanceTable); Assert.Empty(bitmap.PropertyIdList); AssertExtensions.Throws(null, () => bitmap.GetPropertyItem(PropertyTagChrominanceTable)); Assert.Throws(() => bitmap.RemovePropertyItem(PropertyTagChrominanceTable)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [Fact] public void RemovePropertyItem_InvokeBitmapJpg_Success() { @@ -172,19 +167,18 @@ public void RemovePropertyItem_InvokeBitmapJpg_Success() Assert.Equal(new int[] { PropertyTagChrominanceTable, PropertyTagLuminanceTable }, bitmap.PropertyIdList); AssertExtensions.Throws(null, () => bitmap.GetPropertyItem(PropertyTagExifUserComment)); AssertExtensions.Throws(null, () => bitmap.RemovePropertyItem(PropertyTagExifUserComment)); - + bitmap.RemovePropertyItem(PropertyTagLuminanceTable); Assert.Equal(new int[] { PropertyTagChrominanceTable }, bitmap.PropertyIdList); AssertExtensions.Throws(null, () => bitmap.GetPropertyItem(PropertyTagLuminanceTable)); AssertExtensions.Throws(null, () => bitmap.RemovePropertyItem(PropertyTagLuminanceTable)); - + bitmap.RemovePropertyItem(PropertyTagChrominanceTable); Assert.Empty(bitmap.PropertyIdList); AssertExtensions.Throws(null, () => bitmap.GetPropertyItem(PropertyTagChrominanceTable)); Assert.Throws(() => bitmap.RemovePropertyItem(PropertyTagChrominanceTable)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [Theory] [InlineData(0)] [InlineData(1)] @@ -195,7 +189,6 @@ public void RemovePropertyItem_NoSuchPropertyItemEmptyMemoryBitmap_ThrowsExterna Assert.Throws(() => bitmap.RemovePropertyItem(propid)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [Theory] [InlineData(0)] [InlineData(1)] @@ -205,8 +198,7 @@ public void RemovePropertyItem_NoSuchPropertyItemEmptyImageBitmapBmp_ThrowsExter using var bitmap = new Bitmap(Helpers.GetTestBitmapPath("almogaver1bit.bmp")); Assert.Throws(() => bitmap.RemovePropertyItem(propid)); } - - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] + [Theory] [InlineData(0)] [InlineData(1)] @@ -221,11 +213,10 @@ public void RemovePropertyItem_NoSuchPropertyNotEmptyMemoryBitmap_ThrowsArgument bitmap.SetPropertyItem(item1); bitmap.SetPropertyItem(item2); bitmap.SetPropertyItem(item3); - + AssertExtensions.Throws(null, () => bitmap.RemovePropertyItem(propid)); } - - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] + [Theory] [InlineData(0)] [InlineData(1)] @@ -236,7 +227,6 @@ public void RemovePropertyItem_NoSuchPropertyNotEmptyBitmapJpg_ThrowsArgumentExc AssertExtensions.Throws(null, () => bitmap.RemovePropertyItem(propid)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [Theory] [InlineData(0)] [InlineData(1)] @@ -279,7 +269,7 @@ public void SetPropertyItem_InvokeMemoryBitmap_Success(int propid) Assert.Equal(10, items[1].Len); Assert.Equal(PropertyTagTypeASCII, items[1].Type); Assert.Equal("New Value\0", Encoding.ASCII.GetString(items[1].Value)); - + // Set same. bitmap.SetPropertyItem(item); @@ -296,7 +286,6 @@ public void SetPropertyItem_InvokeMemoryBitmap_Success(int propid) Assert.Equal("New Value\0", Encoding.ASCII.GetString(items[1].Value)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [Theory] [InlineData(0)] [InlineData(1)] @@ -324,13 +313,13 @@ public void SetPropertyItem_InvokeBitmapJpg_Success(int propid) Assert.Equal(PropertyTagTypeShort, items[1].Type); Assert.Equal(new byte[] { - 0x16, 0x00, 0x17, 0x00, 0x1F, 0x00, 0x3E, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x17, - 0x00, 0x1B, 0x00, 0x22, 0x00, 0x57, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x1F, - 0x00, 0x22, 0x00, 0x49, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x3E, - 0x00, 0x57, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, + 0x16, 0x00, 0x17, 0x00, 0x1F, 0x00, 0x3E, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x17, + 0x00, 0x1B, 0x00, 0x22, 0x00, 0x57, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x1F, + 0x00, 0x22, 0x00, 0x49, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x3E, + 0x00, 0x57, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, + 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, + 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, + 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00 }, items[1].Value); Assert.Equal(PropertyTagLuminanceTable, items[2].Id); @@ -338,13 +327,13 @@ public void SetPropertyItem_InvokeBitmapJpg_Success(int propid) Assert.Equal(PropertyTagTypeShort, items[2].Type); Assert.Equal(new byte[] { - 0x15, 0x00, 0x0E, 0x00, 0x0D, 0x00, 0x15, 0x00, 0x1F, 0x00, 0x34, 0x00, 0x43, 0x00, 0x50, 0x00, 0x0F, - 0x00, 0x0F, 0x00, 0x12, 0x00, 0x19, 0x00, 0x22, 0x00, 0x4C, 0x00, 0x4F, 0x00, 0x48, 0x00, 0x12, - 0x00, 0x11, 0x00, 0x15, 0x00, 0x1F, 0x00, 0x34, 0x00, 0x4B, 0x00, 0x5B, 0x00, 0x49, 0x00, 0x12, - 0x00, 0x16, 0x00, 0x1D, 0x00, 0x26, 0x00, 0x43, 0x00, 0x72, 0x00, 0x69, 0x00, 0x51, 0x00, 0x17, - 0x00, 0x1D, 0x00, 0x30, 0x00, 0x49, 0x00, 0x59, 0x00, 0x8F, 0x00, 0x87, 0x00, 0x65, 0x00, 0x1F, - 0x00, 0x2E, 0x00, 0x48, 0x00, 0x54, 0x00, 0x6A, 0x00, 0x89, 0x00, 0x95, 0x00, 0x79, 0x00, 0x40, - 0x00, 0x54, 0x00, 0x66, 0x00, 0x72, 0x00, 0x87, 0x00, 0x9F, 0x00, 0x9E, 0x00, 0x85, 0x00, 0x5F, + 0x15, 0x00, 0x0E, 0x00, 0x0D, 0x00, 0x15, 0x00, 0x1F, 0x00, 0x34, 0x00, 0x43, 0x00, 0x50, 0x00, 0x0F, + 0x00, 0x0F, 0x00, 0x12, 0x00, 0x19, 0x00, 0x22, 0x00, 0x4C, 0x00, 0x4F, 0x00, 0x48, 0x00, 0x12, + 0x00, 0x11, 0x00, 0x15, 0x00, 0x1F, 0x00, 0x34, 0x00, 0x4B, 0x00, 0x5B, 0x00, 0x49, 0x00, 0x12, + 0x00, 0x16, 0x00, 0x1D, 0x00, 0x26, 0x00, 0x43, 0x00, 0x72, 0x00, 0x69, 0x00, 0x51, 0x00, 0x17, + 0x00, 0x1D, 0x00, 0x30, 0x00, 0x49, 0x00, 0x59, 0x00, 0x8F, 0x00, 0x87, 0x00, 0x65, 0x00, 0x1F, + 0x00, 0x2E, 0x00, 0x48, 0x00, 0x54, 0x00, 0x6A, 0x00, 0x89, 0x00, 0x95, 0x00, 0x79, 0x00, 0x40, + 0x00, 0x54, 0x00, 0x66, 0x00, 0x72, 0x00, 0x87, 0x00, 0x9F, 0x00, 0x9E, 0x00, 0x85, 0x00, 0x5F, 0x00, 0x79, 0x00, 0x7D, 0x00, 0x81, 0x00, 0x93, 0x00, 0x84, 0x00, 0x87, 0x00, 0x82, 0x00, }, items[2].Value); @@ -367,13 +356,13 @@ public void SetPropertyItem_InvokeBitmapJpg_Success(int propid) Assert.Equal(PropertyTagTypeShort, items[1].Type); Assert.Equal(new byte[] { - 0x16, 0x00, 0x17, 0x00, 0x1F, 0x00, 0x3E, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x17, - 0x00, 0x1B, 0x00, 0x22, 0x00, 0x57, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x1F, - 0x00, 0x22, 0x00, 0x49, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x3E, - 0x00, 0x57, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, + 0x16, 0x00, 0x17, 0x00, 0x1F, 0x00, 0x3E, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x17, + 0x00, 0x1B, 0x00, 0x22, 0x00, 0x57, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x1F, + 0x00, 0x22, 0x00, 0x49, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x3E, + 0x00, 0x57, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, + 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, + 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, + 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00 }, items[1].Value); Assert.Equal(PropertyTagLuminanceTable, items[2].Id); @@ -381,13 +370,13 @@ public void SetPropertyItem_InvokeBitmapJpg_Success(int propid) Assert.Equal(PropertyTagTypeShort, items[2].Type); Assert.Equal(new byte[] { - 0x15, 0x00, 0x0E, 0x00, 0x0D, 0x00, 0x15, 0x00, 0x1F, 0x00, 0x34, 0x00, 0x43, 0x00, 0x50, 0x00, 0x0F, - 0x00, 0x0F, 0x00, 0x12, 0x00, 0x19, 0x00, 0x22, 0x00, 0x4C, 0x00, 0x4F, 0x00, 0x48, 0x00, 0x12, - 0x00, 0x11, 0x00, 0x15, 0x00, 0x1F, 0x00, 0x34, 0x00, 0x4B, 0x00, 0x5B, 0x00, 0x49, 0x00, 0x12, - 0x00, 0x16, 0x00, 0x1D, 0x00, 0x26, 0x00, 0x43, 0x00, 0x72, 0x00, 0x69, 0x00, 0x51, 0x00, 0x17, - 0x00, 0x1D, 0x00, 0x30, 0x00, 0x49, 0x00, 0x59, 0x00, 0x8F, 0x00, 0x87, 0x00, 0x65, 0x00, 0x1F, - 0x00, 0x2E, 0x00, 0x48, 0x00, 0x54, 0x00, 0x6A, 0x00, 0x89, 0x00, 0x95, 0x00, 0x79, 0x00, 0x40, - 0x00, 0x54, 0x00, 0x66, 0x00, 0x72, 0x00, 0x87, 0x00, 0x9F, 0x00, 0x9E, 0x00, 0x85, 0x00, 0x5F, + 0x15, 0x00, 0x0E, 0x00, 0x0D, 0x00, 0x15, 0x00, 0x1F, 0x00, 0x34, 0x00, 0x43, 0x00, 0x50, 0x00, 0x0F, + 0x00, 0x0F, 0x00, 0x12, 0x00, 0x19, 0x00, 0x22, 0x00, 0x4C, 0x00, 0x4F, 0x00, 0x48, 0x00, 0x12, + 0x00, 0x11, 0x00, 0x15, 0x00, 0x1F, 0x00, 0x34, 0x00, 0x4B, 0x00, 0x5B, 0x00, 0x49, 0x00, 0x12, + 0x00, 0x16, 0x00, 0x1D, 0x00, 0x26, 0x00, 0x43, 0x00, 0x72, 0x00, 0x69, 0x00, 0x51, 0x00, 0x17, + 0x00, 0x1D, 0x00, 0x30, 0x00, 0x49, 0x00, 0x59, 0x00, 0x8F, 0x00, 0x87, 0x00, 0x65, 0x00, 0x1F, + 0x00, 0x2E, 0x00, 0x48, 0x00, 0x54, 0x00, 0x6A, 0x00, 0x89, 0x00, 0x95, 0x00, 0x79, 0x00, 0x40, + 0x00, 0x54, 0x00, 0x66, 0x00, 0x72, 0x00, 0x87, 0x00, 0x9F, 0x00, 0x9E, 0x00, 0x85, 0x00, 0x5F, 0x00, 0x79, 0x00, 0x7D, 0x00, 0x81, 0x00, 0x93, 0x00, 0x84, 0x00, 0x87, 0x00, 0x82, 0x00, }, items[2].Value); Assert.Equal(propid, items[3].Id); @@ -410,13 +399,13 @@ public void SetPropertyItem_InvokeBitmapJpg_Success(int propid) Assert.Equal(PropertyTagTypeShort, items[1].Type); Assert.Equal(new byte[] { - 0x16, 0x00, 0x17, 0x00, 0x1F, 0x00, 0x3E, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x17, - 0x00, 0x1B, 0x00, 0x22, 0x00, 0x57, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x1F, - 0x00, 0x22, 0x00, 0x49, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x3E, - 0x00, 0x57, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, - 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, + 0x16, 0x00, 0x17, 0x00, 0x1F, 0x00, 0x3E, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x17, + 0x00, 0x1B, 0x00, 0x22, 0x00, 0x57, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x1F, + 0x00, 0x22, 0x00, 0x49, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x3E, + 0x00, 0x57, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, + 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, + 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, + 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00 }, items[1].Value); Assert.Equal(PropertyTagLuminanceTable, items[2].Id); @@ -424,13 +413,13 @@ public void SetPropertyItem_InvokeBitmapJpg_Success(int propid) Assert.Equal(PropertyTagTypeShort, items[2].Type); Assert.Equal(new byte[] { - 0x15, 0x00, 0x0E, 0x00, 0x0D, 0x00, 0x15, 0x00, 0x1F, 0x00, 0x34, 0x00, 0x43, 0x00, 0x50, 0x00, 0x0F, - 0x00, 0x0F, 0x00, 0x12, 0x00, 0x19, 0x00, 0x22, 0x00, 0x4C, 0x00, 0x4F, 0x00, 0x48, 0x00, 0x12, - 0x00, 0x11, 0x00, 0x15, 0x00, 0x1F, 0x00, 0x34, 0x00, 0x4B, 0x00, 0x5B, 0x00, 0x49, 0x00, 0x12, - 0x00, 0x16, 0x00, 0x1D, 0x00, 0x26, 0x00, 0x43, 0x00, 0x72, 0x00, 0x69, 0x00, 0x51, 0x00, 0x17, - 0x00, 0x1D, 0x00, 0x30, 0x00, 0x49, 0x00, 0x59, 0x00, 0x8F, 0x00, 0x87, 0x00, 0x65, 0x00, 0x1F, - 0x00, 0x2E, 0x00, 0x48, 0x00, 0x54, 0x00, 0x6A, 0x00, 0x89, 0x00, 0x95, 0x00, 0x79, 0x00, 0x40, - 0x00, 0x54, 0x00, 0x66, 0x00, 0x72, 0x00, 0x87, 0x00, 0x9F, 0x00, 0x9E, 0x00, 0x85, 0x00, 0x5F, + 0x15, 0x00, 0x0E, 0x00, 0x0D, 0x00, 0x15, 0x00, 0x1F, 0x00, 0x34, 0x00, 0x43, 0x00, 0x50, 0x00, 0x0F, + 0x00, 0x0F, 0x00, 0x12, 0x00, 0x19, 0x00, 0x22, 0x00, 0x4C, 0x00, 0x4F, 0x00, 0x48, 0x00, 0x12, + 0x00, 0x11, 0x00, 0x15, 0x00, 0x1F, 0x00, 0x34, 0x00, 0x4B, 0x00, 0x5B, 0x00, 0x49, 0x00, 0x12, + 0x00, 0x16, 0x00, 0x1D, 0x00, 0x26, 0x00, 0x43, 0x00, 0x72, 0x00, 0x69, 0x00, 0x51, 0x00, 0x17, + 0x00, 0x1D, 0x00, 0x30, 0x00, 0x49, 0x00, 0x59, 0x00, 0x8F, 0x00, 0x87, 0x00, 0x65, 0x00, 0x1F, + 0x00, 0x2E, 0x00, 0x48, 0x00, 0x54, 0x00, 0x6A, 0x00, 0x89, 0x00, 0x95, 0x00, 0x79, 0x00, 0x40, + 0x00, 0x54, 0x00, 0x66, 0x00, 0x72, 0x00, 0x87, 0x00, 0x9F, 0x00, 0x9E, 0x00, 0x85, 0x00, 0x5F, 0x00, 0x79, 0x00, 0x7D, 0x00, 0x81, 0x00, 0x93, 0x00, 0x84, 0x00, 0x87, 0x00, 0x82, 0x00, }, items[2].Value); Assert.Equal(propid, items[3].Id); @@ -439,7 +428,6 @@ public void SetPropertyItem_InvokeBitmapJpg_Success(int propid) Assert.Equal("New Value\0", Encoding.ASCII.GetString(items[3].Value)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [Theory] [InlineData(0)] [InlineData(1)] @@ -482,7 +470,7 @@ public void SetPropertyItem_InvokeBitmapBmp_Success(int propid) Assert.Equal(10, items[1].Len); Assert.Equal(PropertyTagTypeASCII, items[1].Type); Assert.Equal("New Value\0", Encoding.ASCII.GetString(items[1].Value)); - + // Set same. bitmap.SetPropertyItem(item); @@ -509,7 +497,6 @@ public static IEnumerable InvalidBytes_TestData() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [Theory] [MemberData(nameof(InvalidBytes_TestData))] public void FromFile_InvalidBytes_ThrowsOutOfMemoryException(byte[] bytes) @@ -564,7 +551,6 @@ public void FromFile_NoSuchFile_ThrowsFileNotFoundException() Assert.Throws(() => Image.FromFile("NoSuchFile", useEmbeddedColorManagement: true)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ActiveIssue("https://github.com/dotnet/runtime/issues/34591", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] [Theory] [MemberData(nameof(InvalidBytes_TestData))] @@ -664,7 +650,6 @@ public static IEnumerable GetEncoderParameterList_ReturnsExpected_Test #endif } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(GetEncoderParameterList_ReturnsExpected_TestData))] public void GetEncoderParameterList_ReturnsExpected(ImageFormat format, Guid[] expectedParameters) diff --git a/src/libraries/System.Drawing.Common/tests/Imaging/ImageAttributesTests.cs b/src/libraries/System.Drawing.Common/tests/Imaging/ImageAttributesTests.cs index a1ab8d1c241bd..270216af7c304 100644 --- a/src/libraries/System.Drawing.Common/tests/Imaging/ImageAttributesTests.cs +++ b/src/libraries/System.Drawing.Common/tests/Imaging/ImageAttributesTests.cs @@ -67,7 +67,6 @@ public void Ctor_Default_Success() imageAttr.Dispose(); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] // Causes a crash on libgdiplus. [ConditionalFact(Helpers.IsDrawingSupported)] public void Clone_Success() { @@ -521,7 +520,6 @@ public void SetColorMatrices_InvalidFlags_ThrowsArgumentException(ColorMatrixFla } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void SetThreshold_Threshold_Success() { @@ -536,7 +534,6 @@ public void SetThreshold_Threshold_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(ColorAdjustType_TestData))] public void SetThreshold_ThresholdType_Success(ColorAdjustType type) @@ -553,7 +550,6 @@ public void SetThreshold_ThresholdType_Success(ColorAdjustType type) } [ConditionalTheory(Helpers.IsDrawingSupported)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [MemberData(nameof(ColorAdjustTypeI_TestData))] public void SetThreshold_ThresholdTypeI_Success(ColorAdjustType type) { @@ -568,7 +564,6 @@ public void SetThreshold_ThresholdTypeI_Success(ColorAdjustType type) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void SetThreshold_Disposed_ThrowsArgumentException() { @@ -578,7 +573,6 @@ public void SetThreshold_Disposed_ThrowsArgumentException() AssertExtensions.Throws(null, () => imageAttr.SetThreshold(0.5f)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] public void SetThreshold_InvalidType_ThrowsArgumentException(ColorAdjustType type) @@ -589,7 +583,6 @@ public void SetThreshold_InvalidType_ThrowsArgumentException(ColorAdjustType typ } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void ClearThreshold_Success() { @@ -605,7 +598,6 @@ public void ClearThreshold_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(ColorAdjustType_AllTypesAllowed_TestData))] public void ClearThreshold_ThresholdTypeI_Success(ColorAdjustType type) @@ -622,7 +614,6 @@ public void ClearThreshold_ThresholdTypeI_Success(ColorAdjustType type) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void ClearThreshold_Disposed_ThrowsArgumentException() { @@ -632,7 +623,6 @@ public void ClearThreshold_Disposed_ThrowsArgumentException() AssertExtensions.Throws(null, () => imageAttr.ClearThreshold(ColorAdjustType.Default)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] public void ClearThreshold_InvalidTypes_ThrowsArgumentException(ColorAdjustType type) @@ -643,7 +633,6 @@ public void ClearThreshold_InvalidTypes_ThrowsArgumentException(ColorAdjustType } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void SetGamma_Gamma_Success() { @@ -658,7 +647,6 @@ public void SetGamma_Gamma_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(ColorAdjustType_TestData))] public void SetGamma_GammaType_Success(ColorAdjustType type) @@ -674,7 +662,6 @@ public void SetGamma_GammaType_Success(ColorAdjustType type) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(ColorAdjustTypeI_TestData))] public void SetGamma_GammaTypeI_Success(ColorAdjustType type) @@ -746,7 +733,6 @@ public void ClearGamma_InvalidTypes_ThrowsArgumentException(ColorAdjustType type } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void SetNoOp_Success() { @@ -763,7 +749,6 @@ public void SetNoOp_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(ColorAdjustType_AllTypesAllowed_TestData))] public void SetNoOp_Type_Success(ColorAdjustType type) @@ -820,7 +805,6 @@ public void ClearNoOp_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(ColorAdjustType_TestData))] public void ClearNoOp_Type_Success(ColorAdjustType type) @@ -859,7 +843,6 @@ public void ClearNoOp_TypeI_Success(ColorAdjustType type) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void ClearNoOp_Disposed_ThrowsArgumentException() { @@ -1012,7 +995,6 @@ public static IEnumerable SetOutputChannel_ColorChannelFlag_TestData() yield return new object[] { ColorChannelFlag.ColorChannelY, Color.FromArgb(255, 100, 100, 100), Color.FromArgb(255, 207, 207, 207) }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(SetOutputChannel_ColorChannelFlag_TestData))] public void SetOutputChannel_Flag_Success(ColorChannelFlag flag, Color actualColor, Color expectedColor) @@ -1041,7 +1023,6 @@ public static IEnumerable SetOutputChannel_ColorChannelFlagType_TestDa yield return new object[] { ColorChannelFlag.ColorChannelY, ColorAdjustType.Bitmap, Color.FromArgb(255, 100, 100, 100), Color.FromArgb(255, 207, 207, 207) }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(SetOutputChannel_ColorChannelFlagType_TestData))] public void SetOutputChannel_FlagType_Success(ColorChannelFlag flag, ColorAdjustType type, Color actualColor, Color expectedColor) @@ -1074,7 +1055,6 @@ public static IEnumerable SetOutputChannel_ColorChannelFlagTypeI_TestD yield return new object[] { ColorChannelFlag.ColorChannelY, ColorAdjustType.Text, Color.FromArgb(255, 100, 100, 100) }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(SetOutputChannel_ColorChannelFlagTypeI_TestData))] public void SetOutputChannel_FlagTypeI_Success(ColorChannelFlag flag, ColorAdjustType type, Color color) @@ -1091,7 +1071,6 @@ public void SetOutputChannel_FlagTypeI_Success(ColorChannelFlag flag, ColorAdjus } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void SetOutputChannel_Disposed_ThrowsArgumentException() { @@ -1102,7 +1081,6 @@ public void SetOutputChannel_Disposed_ThrowsArgumentException() AssertExtensions.Throws(null, () => imageAttr.SetOutputChannel(ColorChannelFlag.ColorChannelY, ColorAdjustType.Default)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] public void SetOutputChannel_InvalidTypes_ThrowsArgumentException(ColorAdjustType type) @@ -1122,7 +1100,6 @@ public static IEnumerable SetOutputChannel_InvalidColorChannelFlags_Te yield return new object[] { (ColorChannelFlag)int.MaxValue }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(SetOutputChannel_InvalidColorChannelFlags_TestData))] public void SetOutputChannel_InvalidFlags_ThrowsArgumentException(ColorChannelFlag flag) @@ -1134,7 +1111,6 @@ public void SetOutputChannel_InvalidFlags_ThrowsArgumentException(ColorChannelFl } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void ClearOutputChannel_Success() { @@ -1151,7 +1127,6 @@ public void ClearOutputChannel_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(ColorAdjustType_AllTypesAllowed_TestData))] public void ClearOutputChannel_Type_Success(ColorAdjustType type) @@ -1169,7 +1144,6 @@ public void ClearOutputChannel_Type_Success(ColorAdjustType type) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void ClearOutputChannel_Disposed_ThrowsArgumentException() { @@ -1180,7 +1154,6 @@ public void ClearOutputChannel_Disposed_ThrowsArgumentException() AssertExtensions.Throws(null, () => imageAttr.ClearOutputChannel(ColorAdjustType.Default)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] public void ClearOutputChannel_InvalidTypes_ThrowsArgumentException(ColorAdjustType type) @@ -1191,7 +1164,6 @@ public void ClearOutputChannel_InvalidTypes_ThrowsArgumentException(ColorAdjustT } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void SetOutputChannelColorProfile_Name_Success() { @@ -1207,7 +1179,6 @@ public void SetOutputChannelColorProfile_Name_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void SetOutputChannelColorProfile_Disposed_ThrowsArgumentException() { @@ -1241,7 +1212,6 @@ public void SetOutputChannelColorProfile_InvalidPath_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void SetOutputChannelColorProfile_InvalidPath_ThrowsOutOfMemoryException() { @@ -1252,7 +1222,6 @@ public void SetOutputChannelColorProfile_InvalidPath_ThrowsOutOfMemoryException( } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void SetOutputChannelColorProfile_InvalidPath_ThrowsPathTooLongException() { @@ -1264,7 +1233,6 @@ public void SetOutputChannelColorProfile_InvalidPath_ThrowsPathTooLongException( } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] public void SetOutputChannelColorProfile_InvalidTypes_ThrowsArgumentException(ColorAdjustType type) @@ -1275,7 +1243,6 @@ public void SetOutputChannelColorProfile_InvalidTypes_ThrowsArgumentException(Co } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void ClearOutputChannelColorProfile_Success() { @@ -1293,7 +1260,6 @@ public void ClearOutputChannelColorProfile_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(ColorAdjustType_AllTypesAllowed_TestData))] public void ClearOutputChannelColorProfile_Type_Success(ColorAdjustType type) @@ -1312,7 +1278,6 @@ public void ClearOutputChannelColorProfile_Type_Success(ColorAdjustType type) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void ClearOutputChannelColorProfile_Disposed_ThrowsArgumentException() { @@ -1323,7 +1288,6 @@ public void ClearOutputChannelColorProfile_Disposed_ThrowsArgumentException() AssertExtensions.Throws(null, () => imageAttr.ClearOutputChannelColorProfile(ColorAdjustType.Default)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] public void ClearOutputChannelColorProfile_InvalidTypes_ThrowsArgumentException(ColorAdjustType type) @@ -1416,7 +1380,6 @@ public void SetRemapTable_NullMapMeber_ThrowsNullReferenceException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void SetRemapTable_EmptyMap_ThrowsArgumentException() { @@ -1426,7 +1389,6 @@ public void SetRemapTable_EmptyMap_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void ClearRemapTable_Success() { @@ -1442,7 +1404,6 @@ public void ClearRemapTable_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(ColorAdjustType_AllTypesAllowed_TestData))] public void ClearRemapTable_Type_Success(ColorAdjustType type) @@ -1490,7 +1451,6 @@ public void SetWrapMode_Disposed_ThrowsArgumentException() AssertExtensions.Throws(null, () => imageAttr.SetWrapMode(WrapMode.Clamp, Color.Black, true)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetAdjustedPalette_Disposed_ThrowsArgumentException() { @@ -1512,7 +1472,6 @@ public void GetAdjustedPalette_NullPallete_ThrowsNullReferenceException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(ColorAdjustType_InvalidTypes_TestData))] public void GetAdjustedPalette_InvalidTypes_ThrowsArgumentException(ColorAdjustType type) diff --git a/src/libraries/System.Drawing.Common/tests/Imaging/MetafileTests.cs b/src/libraries/System.Drawing.Common/tests/Imaging/MetafileTests.cs index ef466a33c0d40..7560251c49f51 100644 --- a/src/libraries/System.Drawing.Common/tests/Imaging/MetafileTests.cs +++ b/src/libraries/System.Drawing.Common/tests/Imaging/MetafileTests.cs @@ -43,7 +43,6 @@ public void Ctor_IntPtrZero_ThrowsArgumentException() AssertExtensions.Throws(null, () => new Metafile(IntPtr.Zero, false)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Ctor_IntPtrToWmf_ThrowsExternalException() { @@ -112,7 +111,6 @@ public void Ctor_NullStream_ThrowsArgumentException() AssertExtensions.Throws("stream", null, () => new Metafile((Stream)null)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] [ActiveIssue("https://github.com/dotnet/runtime/issues/34591", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] public void Ctor_EmptyStream_ThrowsExternalException() @@ -192,7 +190,6 @@ public void Ctor_IntPtrEmfTypeString_Success(string description) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(InvalidPath_TestData))] public void Ctor_ZeroPointerEmfTypeInvalidString_ThrowsArgumentException(string description) @@ -966,7 +963,6 @@ public void Static_GetMetafileHeader_NullStream_ThrowsNullReferenceException() Assert.Throws(() => Metafile.GetMetafileHeader((Stream)null)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] [ActiveIssue("https://github.com/dotnet/runtime/issues/34591", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] public void Static_GetMetafileHeader_EmptyStream_ArgumentException() @@ -1007,7 +1003,6 @@ public void GetHenhmetafile_ReturnsExpected() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetHenhmetafile_Disposed_ThrowsArgumentException() { diff --git a/src/libraries/System.Drawing.Common/tests/Imaging/PropertyItemTests.cs b/src/libraries/System.Drawing.Common/tests/Imaging/PropertyItemTests.cs index 5dccc82bdfb70..80928f786682e 100644 --- a/src/libraries/System.Drawing.Common/tests/Imaging/PropertyItemTests.cs +++ b/src/libraries/System.Drawing.Common/tests/Imaging/PropertyItemTests.cs @@ -10,7 +10,6 @@ public class PropertyItemTests { private const int PropertyTagLuminanceTable = 0x5090; - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(1)] [InlineData(0)] @@ -23,7 +22,6 @@ public void Id_Set_GetReturnsExpected(int value) Assert.Equal(value, item.Id); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(1)] [InlineData(0)] @@ -36,7 +34,6 @@ public void Len_Set_GetReturnsExpected(int value) Assert.Equal(value, item.Len); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(1)] [InlineData(0)] @@ -56,7 +53,6 @@ public static IEnumerable Value_Set_TestData() yield return new object[] { new byte[] { 1, 2, 3 } }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Value_Set_TestData))] public void Value_Set_GetReturnsExpected(byte[] value) @@ -74,14 +70,13 @@ public static IEnumerable Properties_TestData() yield return new object[] { 0, 0, 0, new byte[0] }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Properties_TestData))] public void Properties_SetValues_ReturnsExpected(int id, int len, short type, byte[] value) { using var image = new Bitmap(Helpers.GetTestBitmapPath("16x16_nonindexed_24bit.png")); using Image clone = (Image)image.Clone(); - + PropertyItem[] propItems = clone.PropertyItems; PropertyItem propItem = propItems[0]; Assert.Equal(771, propItem.Id); diff --git a/src/libraries/System.Drawing.Common/tests/Printing/PageSettingsTests.cs b/src/libraries/System.Drawing.Common/tests/Printing/PageSettingsTests.cs index a48f6fe8ce9bf..fe2757cfc35e8 100644 --- a/src/libraries/System.Drawing.Common/tests/Printing/PageSettingsTests.cs +++ b/src/libraries/System.Drawing.Common/tests/Printing/PageSettingsTests.cs @@ -34,7 +34,6 @@ namespace System.Drawing.Printing.Tests public class PageSettingsTests { - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.WindowsRS3OrEarlier)] // RS4 failures: https://github.com/dotnet/runtime/issues/26247 public void Clone_Success() { diff --git a/src/libraries/System.Drawing.Common/tests/Printing/PreviewPrintControllerTests.cs b/src/libraries/System.Drawing.Common/tests/Printing/PreviewPrintControllerTests.cs index db2b7d2a50c27..df90ef59fc13d 100644 --- a/src/libraries/System.Drawing.Common/tests/Printing/PreviewPrintControllerTests.cs +++ b/src/libraries/System.Drawing.Common/tests/Printing/PreviewPrintControllerTests.cs @@ -109,7 +109,6 @@ public void OnStartPrint_InvokeWithDocument_Success(PrintEventArgs e) } [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.IsDrawingSupported)] - [PlatformSpecific(TestPlatforms.Windows)] public void OnStartPrint_InvokeMultipleTimes_Success() { using (var document = new PrintDocument()) @@ -132,7 +131,6 @@ public void OnStartPrint_InvokeNullDocument_ThrowsNullReferenceException() [Theory] [MemberData(nameof(PrintEventArgs_TestData))] - [PlatformSpecific(TestPlatforms.Windows)] [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Fixed a NullReferenceException")] public void OnEndPrint_InvokeWithoutStarting_Nop(PrintEventArgs e) { diff --git a/src/libraries/System.Drawing.Common/tests/Printing/PrintControllerTests.cs b/src/libraries/System.Drawing.Common/tests/Printing/PrintControllerTests.cs index 392bdca060239..6544f51cd7d01 100644 --- a/src/libraries/System.Drawing.Common/tests/Printing/PrintControllerTests.cs +++ b/src/libraries/System.Drawing.Common/tests/Printing/PrintControllerTests.cs @@ -92,7 +92,6 @@ public void OnStartPrint_InvokeWithDocumentSeveralTimes_Success(PrintEventArgs e } [Fact] - [PlatformSpecific(TestPlatforms.Windows)] // In Unix is a no-op public void OnStartPrint_InvokeNullDocument_ThrowsNullReferenceException() { var controller = new SubPrintController(); diff --git a/src/libraries/System.Drawing.Common/tests/Printing/PrintDocumentTests.cs b/src/libraries/System.Drawing.Common/tests/Printing/PrintDocumentTests.cs index cda608a2e4832..64bff89aaa013 100644 --- a/src/libraries/System.Drawing.Common/tests/Printing/PrintDocumentTests.cs +++ b/src/libraries/System.Drawing.Common/tests/Printing/PrintDocumentTests.cs @@ -37,7 +37,6 @@ public class PrintDocumentTests } }; - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported, Helpers.WindowsRS3OrEarlier)] // RS4 failures: https://github.com/dotnet/runtime/issues/26247 public void Ctor_Default_Success() { @@ -49,7 +48,6 @@ public void Ctor_Default_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported, Helpers.WindowsRS3OrEarlier)] // RS4 failures: https://github.com/dotnet/runtime/issues/26247 public void DefaultPageSettings_SetValue_ReturnsExpected() { @@ -65,7 +63,6 @@ public void DefaultPageSettings_SetValue_ReturnsExpected() [ConditionalFact(Helpers.IsDrawingSupported)] [ActiveIssue("https://github.com/dotnet/runtime/issues/30221")] - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] public void DefaultPageSettings_Null_ReturnsExpected() { using (var document = new PrintDocument()) @@ -87,7 +84,6 @@ public void DocumentName_SetValue_ReturnsExpected(string documentName) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void DocumentName_Null_ReturnsExpected() { @@ -110,7 +106,6 @@ public void OriginAtMargins_SetValue_ReturnsExpected(bool originAtMargins) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void PrintController_SetValue_ReturnsExpected() { @@ -125,7 +120,6 @@ public void PrintController_SetValue_ReturnsExpected() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.IsDrawingSupported, Helpers.WindowsRS3OrEarlier)] // RS4 failures: https://github.com/dotnet/runtime/issues/26247 public void PrinterSettings_SetValue_ReturnsExpected() { @@ -149,7 +143,6 @@ public void PrinterSettings_SetValue_ReturnsExpected() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.IsDrawingSupported, Helpers.WindowsRS3OrEarlier)] // RS4 failures: https://github.com/dotnet/runtime/issues/26247 public void BeginPrint_SetValue_ReturnsExpected() { @@ -170,7 +163,6 @@ public void BeginPrint_SetValue_ReturnsExpected() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ActiveIssue("https://github.com/dotnet/runtime/issues/26428")] [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.IsDrawingSupported)] public void EndPrint_SetValue_ReturnsExpected() @@ -192,7 +184,6 @@ public void EndPrint_SetValue_ReturnsExpected() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ActiveIssue("https://github.com/dotnet/runtime/issues/26428")] [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.IsDrawingSupported)] public void PrintPage_SetValue_ReturnsExpected() @@ -214,7 +205,6 @@ public void PrintPage_SetValue_ReturnsExpected() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.IsDrawingSupported, Helpers.WindowsRS3OrEarlier)] // RS4 failures: https://github.com/dotnet/runtime/issues/26247 public void QueryPageSettings_SetValue_ReturnsExpected() { diff --git a/src/libraries/System.Drawing.Common/tests/Printing/PrinterSettingsTests.cs b/src/libraries/System.Drawing.Common/tests/Printing/PrinterSettingsTests.cs index 0a2fae6c0fd9d..91f90397f8b56 100644 --- a/src/libraries/System.Drawing.Common/tests/Printing/PrinterSettingsTests.cs +++ b/src/libraries/System.Drawing.Common/tests/Printing/PrinterSettingsTests.cs @@ -43,7 +43,6 @@ public void Ctor_Default_Success() Assert.NotNull(printerSettings.DefaultPageSettings); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.IsDrawingSupported)] public void CanDuplex_ReturnsExpected() { @@ -119,7 +118,6 @@ public void Duplex_SetValue_ReturnsExpected(Duplex duplex) Assert.Equal(duplex, printerSettings.Duplex); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(Duplex.Default - 1)] [InlineData(Duplex.Horizontal + 1)] @@ -182,7 +180,6 @@ public void IsPlotter_ReturnsExpected() } [ConditionalFact(Helpers.IsDrawingSupported)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] public void IsValid_ReturnsExpected() { var printerSettings = new PrinterSettings() @@ -279,7 +276,6 @@ public void PrintFileName_SetValue_ReturnsExpected() Assert.Equal(printFileName, printerSettings.PrintFileName); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [Fact] public void PrintFileName_Null_ThrowsArgumentNullException() { @@ -287,7 +283,6 @@ public void PrintFileName_Null_ThrowsArgumentNullException() AssertExtensions.Throws(null, () => printerSettings.PrintFileName = null); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [Fact] public void PrintFileName_Empty_ThrowsArgumentNullException() { @@ -295,7 +290,6 @@ public void PrintFileName_Empty_ThrowsArgumentNullException() AssertExtensions.Throws(string.Empty, () => printerSettings.PrintFileName = string.Empty); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.IsDrawingSupported)] public void PaperSizes_ReturnsExpected() { @@ -303,7 +297,6 @@ public void PaperSizes_ReturnsExpected() Assert.NotNull(printerSettings.PaperSizes); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.IsDrawingSupported)] public void PaperSources_ReturnsExpected() { @@ -311,7 +304,6 @@ public void PaperSources_ReturnsExpected() Assert.NotNull(printerSettings.PaperSources); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [Theory] [InlineData(PrintRange.AllPages)] [InlineData(PrintRange.CurrentPage)] @@ -350,7 +342,6 @@ public void PrintToFile_SetValue_ReturnsExpected() Assert.Equal(printToFile, printerSettings.PrintToFile); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [Theory] [InlineData("")] [InlineData("My printer")] @@ -364,7 +355,6 @@ public void PrinterName_SetValue_ReturnsExpected(string printerName) Assert.Equal(printerName, printerSettings.PrinterName); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.IsDrawingSupported)] public void PrinterName_Null_ReturnsExpected() { @@ -376,7 +366,6 @@ public void PrinterName_Null_ReturnsExpected() Assert.NotNull(printerSettings.PrinterName); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.IsDrawingSupported)] public void PrinterResolutions_ReturnsExpected() { @@ -390,7 +379,6 @@ public static IEnumerable IsDirectPrintingSupported_ImageFormatSupport yield return new object[] { ImageFormat.Png }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.AnyInstalledPrinters, Helpers.IsDrawingSupported)] [MemberData(nameof(IsDirectPrintingSupported_ImageFormatSupported_TestData))] public void IsDirectPrintingSupported_ImageFormatSupported_ReturnsExpected(ImageFormat imageFormat) @@ -411,7 +399,6 @@ public static IEnumerable IsDirectPrintingSupported_ImageFormatNotSupp yield return new object[] { ImageFormat.Bmp }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [Theory] [MemberData(nameof(IsDirectPrintingSupported_ImageFormatNotSupported_TestData))] public void IsDirectPrintingSupported_ImageFormatNotSupported_ReturnsExpected(ImageFormat imageFormat) @@ -420,7 +407,6 @@ public void IsDirectPrintingSupported_ImageFormatNotSupported_ReturnsExpected(Im Assert.False(printerSettings.IsDirectPrintingSupported(imageFormat)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void IsDirectPrintingSupported_ImageNotSupported_ReturnsExpected() { @@ -431,7 +417,6 @@ public void IsDirectPrintingSupported_ImageNotSupported_ReturnsExpected() } } - [PlatformSpecific(TestPlatforms.Windows)] [ConditionalFact(typeof(PrinterSettingsTests), nameof(CanTestSetHdevmode_IntPtr_Success))] public void SupportsColor_ReturnsExpected() { @@ -471,7 +456,6 @@ public void Clone_Success() Assert.False(ReferenceEquals(clone, printerSettings)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.IsDrawingSupported, Helpers.WindowsRS3OrEarlier)] // RS4 failures: https://github.com/dotnet/runtime/issues/26247 public void CreateMeasurementGraphics_Default_ReturnsExpected() { @@ -486,7 +470,6 @@ public void CreateMeasurementGraphics_Default_ReturnsExpected() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.IsDrawingSupported, Helpers.WindowsRS3OrEarlier)] // RS4 failures: https://github.com/dotnet/runtime/issues/26247 public void CreateMeasurementGraphics_Bool_ReturnsExpected() { @@ -499,7 +482,6 @@ public void CreateMeasurementGraphics_Bool_ReturnsExpected() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.IsDrawingSupported, Helpers.WindowsRS3OrEarlier)] // RS4 failures: https://github.com/dotnet/runtime/issues/26247 public void CreateMeasurementGraphics_PageSettings_ReturnsExpected() { @@ -515,7 +497,6 @@ public void CreateMeasurementGraphics_PageSettings_ReturnsExpected() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.AnyInstalledPrinters, Helpers.IsDrawingSupported, Helpers.WindowsRS3OrEarlier)] // RS4 failures: https://github.com/dotnet/runtime/issues/26247 public void CreateMeasurementGraphics_PageSettingsBool_ReturnsExpected() { @@ -529,7 +510,6 @@ public void CreateMeasurementGraphics_PageSettingsBool_ReturnsExpected() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported, Helpers.WindowsRS3OrEarlier)] // RS4 failures: https://github.com/dotnet/runtime/issues/26247 public void CreateMeasurementGraphics_Null_ThrowsNullReferenceException() { @@ -538,7 +518,6 @@ public void CreateMeasurementGraphics_Null_ThrowsNullReferenceException() Assert.Throws(() => printerSettings.CreateMeasurementGraphics(null, true)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetHdevmode_ReturnsExpected() { @@ -549,7 +528,6 @@ public void GetHdevmode_ReturnsExpected() Assert.NotEqual(IntPtr.Zero, handle); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetHdevmode_PageSettings_ReturnsExpected() { @@ -561,7 +539,6 @@ public void GetHdevmode_PageSettings_ReturnsExpected() Assert.NotEqual(IntPtr.Zero, handle); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetHdevmode_Null_ThrowsNullReferenceException() { @@ -569,7 +546,6 @@ public void GetHdevmode_Null_ThrowsNullReferenceException() Assert.Throws(() => printerSettings.GetHdevmode(null)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetHdevnames_ReturnsExpected() { @@ -580,7 +556,6 @@ public void GetHdevnames_ReturnsExpected() Assert.NotEqual(IntPtr.Zero, handle); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(typeof(PrinterSettingsTests), nameof(CanTestSetHdevmode_IntPtr_Success))] public void SetHdevmode_IntPtr_Success() { @@ -617,7 +592,6 @@ private static string GetNameOfTestPrinterSuitableForDevModeTesting() "Microsoft XPS Document Writer", // Backup for older Windows }; - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetHdevmode_Zero_ThrowsArgumentException() { @@ -625,7 +599,6 @@ public void GetHdevmode_Zero_ThrowsArgumentException() AssertExtensions.Throws(null, () => printerSettings.SetHdevmode(IntPtr.Zero)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void SetHdevnames_IntPtr_Success() { @@ -636,7 +609,6 @@ public void SetHdevnames_IntPtr_Success() Assert.Equal(newPrinterSettings.PrinterName, printerSettings.PrinterName); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void ToString_ReturnsExpected() { diff --git a/src/libraries/System.Drawing.Common/tests/RegionTests.cs b/src/libraries/System.Drawing.Common/tests/RegionTests.cs index 3cc9baf750980..33276c2473d26 100644 --- a/src/libraries/System.Drawing.Common/tests/RegionTests.cs +++ b/src/libraries/System.Drawing.Common/tests/RegionTests.cs @@ -51,7 +51,6 @@ public void Ctor_Default() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(-1, -2, -3, -4, true)] [InlineData(0, 0, 0, 0, true)] @@ -68,7 +67,6 @@ public void Ctor_Rectangle(int x, int y, int width, int height, bool isEmpty) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(1, 2, 3, float.NegativeInfinity, true)] [InlineData(-1, -2, -3, -4, true)] @@ -139,7 +137,6 @@ public void Ctor_NullRegionData_ThrowsArgumentNullException() AssertExtensions.Throws("rgnData", () => new Region((RegionData)null)); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(0)] [InlineData(1)] @@ -155,7 +152,6 @@ public void Ctor_InvalidRegionData_ThrowsExternalException(int dataLength) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Ctor_EmptyGraphicsPath_ThrowsExternalException() { @@ -178,7 +174,6 @@ public void Ctor_NullDataInRegionData_ThrowsNullReferenceException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Ctor_GraphicsPath() { @@ -242,7 +237,6 @@ public static IEnumerable Ctor_InfiniteGraphicsPath_TestData() yield return new object[] { path6, true }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Ctor_InfiniteGraphicsPath_TestData))] public void Ctor_InfiniteGraphicsPath_IsInfinite(GraphicsPath path, bool isInfinite) @@ -454,7 +448,6 @@ public void Complement_DisposedRegion_ThrowsArgumentException() AssertExtensions.Throws(null, () => new Region().Complement(CreateDisposedRegion())); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Complement_SameRegion_ThrowsInvalidOperationException() { @@ -522,7 +515,6 @@ public void Complement_GraphicsPath_Success(Region region, RectangleF[] rectangl } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/23784", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Complement_GraphicsPathWithMultipleRectangles_Success() { @@ -636,7 +628,6 @@ static Region Empty() yield return new object[] { new Region(graphics1), new Region(graphics6), false }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Equals_TestData))] public void Equals_Valid_ReturnsExpected(Region region, Region other, bool expected) @@ -898,7 +889,6 @@ public void Exclude_DisposedRegion_ThrowsArgumentException() AssertExtensions.Throws(null, () => new Region().Exclude(CreateDisposedRegion())); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Exclude_SameRegion_ThrowsInvalidOperationException() { @@ -908,7 +898,6 @@ public void Exclude_SameRegion_ThrowsInvalidOperationException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Exclude_TestData))] public void Exclude_Rectangle_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) @@ -927,7 +916,6 @@ public void Exclude_Rectangle_Success(Region region, RectangleF[] rectangles, Re } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Exclude_TestData))] public void Exclude_RectangleF_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) @@ -946,7 +934,6 @@ public void Exclude_RectangleF_Success(Region region, RectangleF[] rectangles, R } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Exclude_TestData))] public void Exclude_GraphicsPath_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) @@ -1059,7 +1046,6 @@ public void GetHrgn_Empty_ReturnsNonZero() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetHrgn_NullGraphics_ThrowsArgumentNullException() { @@ -1117,7 +1103,6 @@ public void GetRegionData_Disposed_ThrowsArgumentException() AssertExtensions.Throws(null, () => CreateDisposedRegion().GetRegionData()); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetRegionScans_CustomMatrix_TransformsRegionScans() { @@ -1151,7 +1136,6 @@ public void GetRegionScans_Disposed_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetRegionScans_DisposedMatrix_ThrowsArgumentException() { @@ -1237,7 +1221,6 @@ public static IEnumerable Intersect_TestData() }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Intersect_TestData))] public void Intersect_Region_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) @@ -1287,7 +1270,6 @@ public void Intersect_DisposedRegion_ThrowsArgumentException() AssertExtensions.Throws(null, () => new Region().Intersect(CreateDisposedRegion())); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Intersect_SameRegion_ThrowsInvalidOperationException() { @@ -1361,7 +1343,6 @@ public void Intersect_InfiniteRegionWithSmallerRectangleF_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Intersect_TestData))] public void Intersect_GraphicsPath_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) @@ -1836,7 +1817,6 @@ public static IEnumerable Union_TestData() }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Union_TestData))] public void Union_Region_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) @@ -1858,7 +1838,6 @@ public void Union_Region_Success(Region region, RectangleF[] rectangles, Rectang } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Union_InfiniteRegion_Success() { @@ -1890,7 +1869,6 @@ public void Union_DisposedRegion_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Union_SameRegion_ThrowsInvalidOperationException() { @@ -2158,7 +2136,6 @@ public void Translate_Infinity_Nop() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(float.MaxValue)] [InlineData(float.MinValue)] @@ -2244,7 +2221,6 @@ public static IEnumerable Xor_TestData() }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Xor_TestData))] public void Xor_Region_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) @@ -2303,7 +2279,6 @@ public void Xor_DisposedRegion_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Xor_SameRegion_ThrowsInvalidOperationException() { @@ -2313,7 +2288,6 @@ public void Xor_SameRegion_ThrowsInvalidOperationException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Xor_TestData))] public void Xor_Rectangle_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) @@ -2332,7 +2306,6 @@ public void Xor_Rectangle_Success(Region region, RectangleF[] rectangles, Rectan } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Xor_TestData))] public void Xor_RectangleF_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) @@ -2351,7 +2324,6 @@ public void Xor_RectangleF_Success(Region region, RectangleF[] rectangles, Recta } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Xor_TestData))] public void Xor_GraphicsPath_Success(Region region, RectangleF[] rectangles, RectangleF[] expectedScans) diff --git a/src/libraries/System.Drawing.Common/tests/StringFormatTests.cs b/src/libraries/System.Drawing.Common/tests/StringFormatTests.cs index 3b6ee755cc8f0..af72c0952e2c4 100644 --- a/src/libraries/System.Drawing.Common/tests/StringFormatTests.cs +++ b/src/libraries/System.Drawing.Common/tests/StringFormatTests.cs @@ -135,7 +135,6 @@ public void Clone_Disposed_ThrowsArgumentException() AssertExtensions.Throws(null, () => format.Clone()); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(0, StringDigitSubstitute.None, 0)] [InlineData(EnglishLanguageCode, StringDigitSubstitute.Traditional, EnglishLanguageCode)] diff --git a/src/libraries/System.Drawing.Common/tests/System.Drawing.Common.Tests.csproj b/src/libraries/System.Drawing.Common/tests/System.Drawing.Common.Tests.csproj index 58fe9b144c8fd..7b437679f7ae9 100644 --- a/src/libraries/System.Drawing.Common/tests/System.Drawing.Common.Tests.csproj +++ b/src/libraries/System.Drawing.Common/tests/System.Drawing.Common.Tests.csproj @@ -24,7 +24,6 @@ - diff --git a/src/libraries/System.Drawing.Common/tests/System/Drawing/FontConverterTests.cs b/src/libraries/System.Drawing.Common/tests/System/Drawing/FontConverterTests.cs index 110a85199997a..63c35baa39f52 100644 --- a/src/libraries/System.Drawing.Common/tests/System/Drawing/FontConverterTests.cs +++ b/src/libraries/System.Drawing.Common/tests/System/Drawing/FontConverterTests.cs @@ -50,7 +50,7 @@ public void TestConvertFrom(string input, string expectedName, float expectedSiz FontConverter converter = new FontConverter(); Font font = (Font)converter.ConvertFrom(input); - // Unix fonts + // Unix fonts Assert.Equal(expectedName, font.Name); Assert.Equal(expectedSize, font.Size); Assert.Equal(expectedUnits, font.Unit); @@ -115,7 +115,7 @@ public void GetFontPropsSorted() public static TheoryData TestConvertFormData() { - var data = PlatformDetection.IsWindows ? + var data = new TheoryData() { { $"Courier New", "Courier New", 8.25f, GraphicsUnit.Point, FontStyle.Regular }, @@ -136,33 +136,17 @@ public static TheoryData TestCon { $"Arial{s_Separator} 10{s_Separator} style=12", "Arial", 10f, GraphicsUnit.Point, FontStyle.Underline | FontStyle.Strikeout }, { $"Courier New{s_Separator} Style=Bold", "Courier New", 8.25f, GraphicsUnit.Point, FontStyle.Bold }, // FullFramework style keyword is case sensitive. { $"11px{s_Separator} Style=Bold", "Microsoft Sans Serif", 8.25f, GraphicsUnit.Point, FontStyle.Bold} - } - : new TheoryData() - { - // Unix has different fonts installed, let's use a default one. - { FontFamily.GenericSansSerif.Name, FontFamily.GenericSansSerif.Name, 8.25f, GraphicsUnit.Point, FontStyle.Regular }, - { $"{FontFamily.GenericSansSerif.Name}{s_Separator} 11", FontFamily.GenericSansSerif.Name, 11f, GraphicsUnit.Point, FontStyle.Regular }, - { $"{FontFamily.GenericSansSerif.Name}{s_Separator} 11 px", FontFamily.GenericSansSerif.Name, 11f, GraphicsUnit.Pixel, FontStyle.Regular }, - { $"{FontFamily.GenericSansSerif.Name}{s_Separator} 11 px{s_Separator} style=Regular", FontFamily.GenericSansSerif.Name, 11f, GraphicsUnit.Pixel, FontStyle.Regular }, - { $"{FontFamily.GenericSansSerif.Name}{s_Separator} style=Bold", FontFamily.GenericSansSerif.Name, 8.25f, GraphicsUnit.Point, FontStyle.Bold }, - { $"{FontFamily.GenericSansSerif.Name}{s_Separator} 11 px{s_Separator} style=Bold{s_Separator} Italic", FontFamily.GenericSansSerif.Name, 11f, GraphicsUnit.Pixel, FontStyle.Bold | FontStyle.Italic }, - { $"{FontFamily.GenericSansSerif.Name}{s_Separator} 11 px{s_Separator} style=Regular, Italic", FontFamily.GenericSansSerif.Name, 11f, GraphicsUnit.Pixel, FontStyle.Regular | FontStyle.Italic }, - { $"{FontFamily.GenericSansSerif.Name}{s_Separator} 11 px{s_Separator} style=Bold{s_Separator} Italic{s_Separator} Strikeout", FontFamily.GenericSansSerif.Name, 11f, GraphicsUnit.Pixel, FontStyle.Bold | FontStyle.Italic | FontStyle.Strikeout }, - { $"{FontFamily.GenericSansSerif.Name}{s_Separator} Style=Bold", FontFamily.GenericSansSerif.Name, 8.25f, GraphicsUnit.Point, FontStyle.Bold }, // FullFramework style keyword is case sensitive. }; - if (PlatformDetection.IsWindows) + // FullFramework disregards all arguments if the font name is an empty string. + // Empty string is not an installed font on Windows 7, windows 8 and some versions of windows 10. + if (EmptyFontPresent) { - // FullFramework disregards all arguments if the font name is an empty string. - // Empty string is not an installed font on Windows 7, windows 8 and some versions of windows 10. - if (EmptyFontPresent) - { - data.Add($"{s_Separator} 10{s_Separator} style=bold", "", 10f, GraphicsUnit.Point, FontStyle.Bold); - } - else - { - data.Add($"{s_Separator} 10{s_Separator} style=bold", "Microsoft Sans Serif", 10f, GraphicsUnit.Point, FontStyle.Bold); - } + data.Add($"{s_Separator} 10{s_Separator} style=bold", "", 10f, GraphicsUnit.Point, FontStyle.Bold); + } + else + { + data.Add($"{s_Separator} 10{s_Separator} style=bold", "Microsoft Sans Serif", 10f, GraphicsUnit.Point, FontStyle.Bold); } return data; diff --git a/src/libraries/System.Drawing.Common/tests/SystemFontsTests.cs b/src/libraries/System.Drawing.Common/tests/SystemFontsTests.cs index 683aa64731059..3de82ba7fd09b 100644 --- a/src/libraries/System.Drawing.Common/tests/SystemFontsTests.cs +++ b/src/libraries/System.Drawing.Common/tests/SystemFontsTests.cs @@ -103,7 +103,6 @@ public static IEnumerable SystemFonts_WindowsNames_TestData() return fonts.ToTestData(); } - [PlatformSpecific(TestPlatforms.Windows)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(SystemFonts_WindowsNames_TestData))] public void SystemFont_Get_ReturnsExpected_WindowsNames(Func getFont, string systemFontName, string windowsFontName) diff --git a/src/libraries/System.Drawing.Common/tests/Text/PrivateFontCollectionTests.cs b/src/libraries/System.Drawing.Common/tests/Text/PrivateFontCollectionTests.cs index ad3d385a072b5..df88f339ab340 100644 --- a/src/libraries/System.Drawing.Common/tests/Text/PrivateFontCollectionTests.cs +++ b/src/libraries/System.Drawing.Common/tests/Text/PrivateFontCollectionTests.cs @@ -77,7 +77,6 @@ public void AddFontFile_SamePathMultipleTimes_FamiliesContainsOnlyOneFont() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void AddFontFile_SameNameMultipleTimes_FamiliesContainsFirstFontOnly() { @@ -101,7 +100,6 @@ public void AddFontFile_SameNameMultipleTimes_FamiliesContainsFirstFontOnly() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void AddFontFile_NullFileName_ThrowsArgumentNullException() { @@ -158,7 +156,6 @@ public void AddFontFile_Directory_ThrowsFileNotFoundException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void AddFontFile_Disposed_ThrowsArgumentException() { @@ -200,7 +197,6 @@ public void AddMemoryFont_ZeroMemory_ThrowsArgumentException() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(0)] [InlineData(-1)] @@ -229,7 +225,6 @@ public void AddMemoryFont_InvalidLength_ThrowsArgumentException(int length) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void AddMemoryFont_Disposed_ThrowsArgumentException() { diff --git a/src/libraries/System.Drawing.Common/tests/TextureBrushTests.cs b/src/libraries/System.Drawing.Common/tests/TextureBrushTests.cs index 533b5bc8a631b..a7159c2271eaa 100644 --- a/src/libraries/System.Drawing.Common/tests/TextureBrushTests.cs +++ b/src/libraries/System.Drawing.Common/tests/TextureBrushTests.cs @@ -17,7 +17,6 @@ public static IEnumerable Ctor_Bitmap_TestData() yield return new object[] { new Metafile(Helpers.GetTestBitmapPath("telescope_01.wmf")), PixelFormat.Format32bppArgb, new Size(490, 654) }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Ctor_Bitmap_TestData))] public void Ctor_Bitmap(Image bitmap, PixelFormat expectedPixelFormat, Size expectedSize) @@ -41,7 +40,6 @@ public void Ctor_Bitmap(Image bitmap, PixelFormat expectedPixelFormat, Size expe } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void Ctor_BitmapFromIconHandle_Success() { @@ -64,7 +62,6 @@ public static IEnumerable Ctor_Image_WrapMode_TestData() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Ctor_Image_WrapMode_TestData))] public void Ctor_Image_WrapMode(Image image, WrapMode wrapMode, PixelFormat expectedPixelFormat, Size expectedSize) @@ -94,7 +91,6 @@ public static IEnumerable Ctor_Image_Rectangle_TestData() yield return new object[] { new Bitmap(10, 10), new Rectangle(5, 5, 5, 5) }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Ctor_Image_Rectangle_TestData))] public void Ctor_Image_Rectangle(Image image, Rectangle rectangle) @@ -118,7 +114,6 @@ public void Ctor_Image_Rectangle(Image image, Rectangle rectangle) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Ctor_Image_Rectangle_TestData))] public void Ctor_Image_RectangleF(Image image, Rectangle rectangle) @@ -154,7 +149,6 @@ public static IEnumerable Ctor_Image_WrapMode_Rectangle_TestData() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Ctor_Image_WrapMode_Rectangle_TestData))] public void Ctor_Image_WrapMode_Rectangle(Image image, WrapMode wrapMode, Rectangle rectangle) @@ -178,7 +172,6 @@ public void Ctor_Image_WrapMode_Rectangle(Image image, WrapMode wrapMode, Rectan } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Ctor_Image_WrapMode_Rectangle_TestData))] public void Ctor_Image_WrapMode_RectangleF(Image image, WrapMode wrapMode, Rectangle rectangle) @@ -215,7 +208,6 @@ public static IEnumerable Ctor_Image_Rectangle_ImageAttributes_TestDat } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Ctor_Image_Rectangle_ImageAttributes_TestData))] public void Ctor_Image_Rectangle_ImageAttributes(Image image, Rectangle rectangle, ImageAttributes attributes, WrapMode expectedWrapMode) @@ -240,7 +232,6 @@ public void Ctor_Image_Rectangle_ImageAttributes(Image image, Rectangle rectangl } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Ctor_Image_Rectangle_ImageAttributes_TestData))] public void Ctor_Image_RectangleF_ImageAttributes(Image image, Rectangle rectangle, ImageAttributes attributes, WrapMode expectedWrapMode) @@ -449,7 +440,6 @@ public void MultiplyTransform_DisposedMatrix_Nop() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(MatrixOrder.Prepend - 1)] [InlineData(MatrixOrder.Append + 1)] @@ -841,7 +831,6 @@ public void WrapMode_Tile_ReturnsExpected() }); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void WrapMode_TileFlipX_ReturnsExpected() { @@ -858,7 +847,6 @@ public void WrapMode_TileFlipX_ReturnsExpected() }); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void WrapMode_TileFlipY_ReturnsExpected() { @@ -875,7 +863,6 @@ public void WrapMode_TileFlipY_ReturnsExpected() }); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void WrapMode_TileFlipXY_ReturnsExpected() { diff --git a/src/libraries/System.Drawing.Common/tests/ToolboxBitmapAttributeTests.cs b/src/libraries/System.Drawing.Common/tests/ToolboxBitmapAttributeTests.cs index 7e4bd87d8741e..8d9e4187aba14 100644 --- a/src/libraries/System.Drawing.Common/tests/ToolboxBitmapAttributeTests.cs +++ b/src/libraries/System.Drawing.Common/tests/ToolboxBitmapAttributeTests.cs @@ -44,7 +44,6 @@ public static IEnumerable Ctor_FileName_TestData() yield return new object[] { Helpers.GetTestBitmapPath("invalid.ico"), new Size(0, 0) }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Ctor_FileName_TestData))] [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)] @@ -65,7 +64,6 @@ public void Ctor_FileName(string fileName, Size size) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(null, -1, -1)] [InlineData(typeof(ClassWithNoNamespace), -1, -1)] @@ -87,7 +85,6 @@ public void Ctor_Type(Type type, int width, int height) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [InlineData(null, null, -1, -1)] [InlineData(null, "invalid.ico", -1, -1)] @@ -134,7 +131,6 @@ public void GetImage_TypeFileNameBool_ReturnsExpected(string fileName, int width } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetImage_NullComponent_ReturnsNull() { @@ -159,7 +155,6 @@ public void GetImage_Component_ReturnsExpected() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void GetImage_Default_ReturnsExpected() { @@ -176,7 +171,6 @@ public void GetImage_Default_ReturnsExpected() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Logical name with no extension is not supported in .NET Framework")] [InlineData(typeof(Icon_toolboxBitmapAttributeTest), 256, 256)] @@ -205,7 +199,6 @@ public static IEnumerable Equals_TestData() yield return new object[] { ToolboxBitmapAttribute.Default, null, false }; } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalTheory(Helpers.IsDrawingSupported)] [MemberData(nameof(Equals_TestData))] public void Equals_Other_ReturnsExpected(ToolboxBitmapAttribute attribute, object other, bool expected) diff --git a/src/libraries/System.Drawing.Common/tests/mono/System.Drawing.Imaging/IconCodecTests.cs b/src/libraries/System.Drawing.Common/tests/mono/System.Drawing.Imaging/IconCodecTests.cs index 0517b9472586a..c202d49454a10 100644 --- a/src/libraries/System.Drawing.Common/tests/mono/System.Drawing.Imaging/IconCodecTests.cs +++ b/src/libraries/System.Drawing.Common/tests/mono/System.Drawing.Imaging/IconCodecTests.cs @@ -61,26 +61,12 @@ public void Image16() } } - [PlatformSpecific(TestPlatforms.AnyUnix)] - [ConditionalFact(Helpers.RecentGdiplusIsAvailable)] - public void Image16_PaletteEntries_Unix() - { - string sInFile = Helpers.GetTestBitmapPath("16x16_one_entry_4bit.ico"); - using (Image image = Image.FromFile(sInFile)) - { - // The values are inconsistent across Windows & Unix: GDI+ returns 0, libgdiplus returns 16. - Assert.Equal(16, image.Palette.Entries.Length); - } - } - - [PlatformSpecific(TestPlatforms.Windows)] [ConditionalFact(Helpers.IsDrawingSupported)] - public void Image16_PaletteEntries_Windows() + public void Image16_PaletteEntries() { string sInFile = Helpers.GetTestBitmapPath("16x16_one_entry_4bit.ico"); using (Image image = Image.FromFile(sInFile)) { - // The values are inconsistent across Windows & Unix: GDI+ returns 0, libgdiplus returns 16. Assert.Equal(0, image.Palette.Entries.Length); } } @@ -119,43 +105,13 @@ public void Bitmap16Features() } } - [PlatformSpecific(TestPlatforms.AnyUnix)] - [ConditionalFact(Helpers.IsDrawingSupported)] - public void Bitmap16Features_Palette_Entries_Unix() - { - string sInFile = Helpers.GetTestBitmapPath("48x48_multiple_entries_4bit.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - // These values are inconsistent across Windows & Unix: 0 on Windows, 16 on Unix - Assert.Equal(16, bmp.Palette.Entries.Length); - Assert.Equal(-16777216, bmp.Palette.Entries[0].ToArgb()); - Assert.Equal(-16777216, bmp.Palette.Entries[1].ToArgb()); - Assert.Equal(-16744448, bmp.Palette.Entries[2].ToArgb()); - Assert.Equal(-8355840, bmp.Palette.Entries[3].ToArgb()); - Assert.Equal(-16777088, bmp.Palette.Entries[4].ToArgb()); - Assert.Equal(-8388480, bmp.Palette.Entries[5].ToArgb()); - Assert.Equal(-16744320, bmp.Palette.Entries[6].ToArgb()); - Assert.Equal(-4144960, bmp.Palette.Entries[7].ToArgb()); - Assert.Equal(-8355712, bmp.Palette.Entries[8].ToArgb()); - Assert.Equal(-65536, bmp.Palette.Entries[9].ToArgb()); - Assert.Equal(-16711936, bmp.Palette.Entries[10].ToArgb()); - Assert.Equal(-256, bmp.Palette.Entries[11].ToArgb()); - Assert.Equal(-16776961, bmp.Palette.Entries[12].ToArgb()); - Assert.Equal(-65281, bmp.Palette.Entries[13].ToArgb()); - Assert.Equal(-16711681, bmp.Palette.Entries[14].ToArgb()); - Assert.Equal(-1, bmp.Palette.Entries[15].ToArgb()); - } - } - - [PlatformSpecific(TestPlatforms.Windows)] [ConditionalFact(Helpers.IsDrawingSupported)] [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Flaky - ArgumentException")] - public void Bitmap16Features_Palette_Entries_Windows() + public void Bitmap16Features_Palette_Entries() { string sInFile = Helpers.GetTestBitmapPath("48x48_multiple_entries_4bit.ico"); using (Bitmap bmp = new Bitmap(sInFile)) { - // These values are inconsistent across Windows & Unix: 0 on Windows, 16 on Unix Assert.Equal(0, bmp.Palette.Entries.Length); } } @@ -306,43 +262,12 @@ public void Bitmap32Features() } } - [PlatformSpecific(TestPlatforms.AnyUnix)] - [ConditionalFact(Helpers.RecentGdiplusIsAvailable)] - public void Bitmap32Features_PaletteEntries_Unix() - { - string sInFile = Helpers.GetTestBitmapPath("VisualPng.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - // These values areinconsistent across Windows & Unix: 0 on Windows, 16 on Unix - Assert.Equal(16, bmp.Palette.Entries.Length); - - Assert.Equal(-16777216, bmp.Palette.Entries[0].ToArgb()); - Assert.Equal(-8388608, bmp.Palette.Entries[1].ToArgb()); - Assert.Equal(-16744448, bmp.Palette.Entries[2].ToArgb()); - Assert.Equal(-8355840, bmp.Palette.Entries[3].ToArgb()); - Assert.Equal(-16777088, bmp.Palette.Entries[4].ToArgb()); - Assert.Equal(-8388480, bmp.Palette.Entries[5].ToArgb()); - Assert.Equal(-16744320, bmp.Palette.Entries[6].ToArgb()); - Assert.Equal(-4144960, bmp.Palette.Entries[7].ToArgb()); - Assert.Equal(-8355712, bmp.Palette.Entries[8].ToArgb()); - Assert.Equal(-65536, bmp.Palette.Entries[9].ToArgb()); - Assert.Equal(-16711936, bmp.Palette.Entries[10].ToArgb()); - Assert.Equal(-256, bmp.Palette.Entries[11].ToArgb()); - Assert.Equal(-16776961, bmp.Palette.Entries[12].ToArgb()); - Assert.Equal(-65281, bmp.Palette.Entries[13].ToArgb()); - Assert.Equal(-16711681, bmp.Palette.Entries[14].ToArgb()); - Assert.Equal(-1, bmp.Palette.Entries[15].ToArgb()); - } - } - - [PlatformSpecific(TestPlatforms.Windows)] [ConditionalFact(Helpers.IsDrawingSupported)] - public void Bitmap32Features_PaletteEntries_Windows() + public void Bitmap32Features_PaletteEntries() { string sInFile = Helpers.GetTestBitmapPath("VisualPng.ico"); using (Bitmap bmp = new Bitmap(sInFile)) { - // These values areinconsistent across Windows & Unix: 0 on Windows, 16 on Unix Assert.Equal(0, bmp.Palette.Entries.Length); } } @@ -550,28 +475,12 @@ public void Bitmap48Features() } } - [PlatformSpecific(TestPlatforms.AnyUnix)] - [ConditionalFact(Helpers.RecentGdiplusIsAvailable)] - public void Bitmap48Features_Palette_Entries_Unix() - { - string sInFile = Helpers.GetTestBitmapPath("48x48_one_entry_1bit.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - // These values are inconsistent across Windows & Unix: 0 on Windows, 16 on Unix - Assert.Equal(2, bmp.Palette.Entries.Length); - Assert.Equal(-16777216, bmp.Palette.Entries[0].ToArgb()); - Assert.Equal(-1, bmp.Palette.Entries[1].ToArgb()); - } - } - - [PlatformSpecific(TestPlatforms.Windows)] [ConditionalFact(Helpers.IsDrawingSupported)] - public void Bitmap48Features_Palette_Entries_Windows() + public void Bitmap48Features_Palette_Entries() { string sInFile = Helpers.GetTestBitmapPath("48x48_one_entry_1bit.ico"); using (Bitmap bmp = new Bitmap(sInFile)) { - // These values are inconsistent across Windows & Unix: 0 on Windows, 16 on Unix Assert.Equal(0, bmp.Palette.Entries.Length); } } @@ -796,26 +705,12 @@ public void Bitmap64Features() } } - [PlatformSpecific(TestPlatforms.AnyUnix)] - [ConditionalFact(Helpers.RecentGdiplusIsAvailable)] - public void Bitmap64Features_Palette_Entries_Unix() - { - string sInFile = Helpers.GetTestBitmapPath("64x64_one_entry_8bit.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - // This value is inconsistent across Windows & Unix: 0 on Windows, 256 on Unix - Assert.Equal(256, bmp.Palette.Entries.Length); - } - } - - [PlatformSpecific(TestPlatforms.Windows)] [ConditionalFact(Helpers.IsDrawingSupported)] - public void Bitmap64Features_Palette_Entries_Windows() + public void Bitmap64Features_Palette_Entries() { string sInFile = Helpers.GetTestBitmapPath("64x64_one_entry_8bit.ico"); using (Bitmap bmp = new Bitmap(sInFile)) { - // This value is inconsistent across Windows & Unix: 0 on Windows, 256 on Unix Assert.Equal(0, bmp.Palette.Entries.Length); } } @@ -1076,26 +971,12 @@ public void Bitmap96Features() } } - [PlatformSpecific(TestPlatforms.AnyUnix)] - [ConditionalFact(Helpers.RecentGdiplusIsAvailable)] - public void Bitmap96Features_Palette_Entries_Unix() - { - string sInFile = Helpers.GetTestBitmapPath("96x96_one_entry_8bit.ico"); - using (Bitmap bmp = new Bitmap(sInFile)) - { - // This value is inconsistent across Unix and Windows. - Assert.Equal(256, bmp.Palette.Entries.Length); - } - } - - [PlatformSpecific(TestPlatforms.Windows)] [ConditionalFact(Helpers.RecentGdiplusIsAvailable)] - public void Bitmap96Features_Palette_Entries_Windows() + public void Bitmap96Features_Palette_Entries() { string sInFile = Helpers.GetTestBitmapPath("96x96_one_entry_8bit.ico"); using (Bitmap bmp = new Bitmap(sInFile)) { - // This value is inconsistent across Unix and Windows. Assert.Equal(0, bmp.Palette.Entries.Length); } } diff --git a/src/libraries/System.Drawing.Common/tests/mono/System.Drawing.Imaging/PngCodecTests.cs b/src/libraries/System.Drawing.Common/tests/mono/System.Drawing.Imaging/PngCodecTests.cs index 15faf3b734f9f..15e010457040f 100644 --- a/src/libraries/System.Drawing.Common/tests/mono/System.Drawing.Imaging/PngCodecTests.cs +++ b/src/libraries/System.Drawing.Common/tests/mono/System.Drawing.Imaging/PngCodecTests.cs @@ -37,7 +37,6 @@ namespace MonoTests.System.Drawing.Imaging { - [ActiveIssue("https://github.com/dotnet/runtime/issues/23691", TestPlatforms.AnyUnix)] public class PngCodecTest { private bool IsArm64Process() diff --git a/src/libraries/System.Drawing.Common/tests/mono/System.Drawing.Imaging/TiffCodecTests.cs b/src/libraries/System.Drawing.Common/tests/mono/System.Drawing.Imaging/TiffCodecTests.cs index c402cf880d7a5..bee5e8681213c 100644 --- a/src/libraries/System.Drawing.Common/tests/mono/System.Drawing.Imaging/TiffCodecTests.cs +++ b/src/libraries/System.Drawing.Common/tests/mono/System.Drawing.Imaging/TiffCodecTests.cs @@ -65,7 +65,6 @@ public void Bitmap32bitsFeatures() /* Checks bitmap features on a known 32bbp bitmap */ [ConditionalFact(Helpers.IsDrawingSupported)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] public void Bitmap32bitsPixelFormat() { string sInFile = Helpers.GetTestBitmapPath("almogaver32bits.tif"); diff --git a/src/libraries/System.Drawing.Common/tests/mono/System.Drawing/BitmapTests.cs b/src/libraries/System.Drawing.Common/tests/mono/System.Drawing/BitmapTests.cs index 65153f320c73b..8328924f36f91 100644 --- a/src/libraries/System.Drawing.Common/tests/mono/System.Drawing/BitmapTests.cs +++ b/src/libraries/System.Drawing.Common/tests/mono/System.Drawing/BitmapTests.cs @@ -45,8 +45,6 @@ namespace MonoTests.System.Drawing { - - [SkipOnCoreClr("https://github.com/dotnet/runtime/issues/37082", TestPlatforms.AnyUnix, ~RuntimeConfiguration.Release)] public class TestBitmap { @@ -506,34 +504,6 @@ public void Rotate() } } - // Rotate 1- and 4-bit bitmaps in different ways and check the - // resulting pixels using MD5 - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsDrawingSupported), nameof(PlatformDetection.IsNotArm64Process))] // [ActiveIssue("https://github.com/dotnet/runtime/issues/28859")] - [InlineData("1bit.png", RotateFlipType.Rotate180FlipNone, "64AE60858A02228F7B1B18C7812FB683")] - [InlineData("1bit.png", RotateFlipType.Rotate180FlipX, "353E937CFF31B1BF6C3DD0A031ACB54D")] - [InlineData("1bit.png", RotateFlipType.Rotate180FlipXY, "A4DAF507C92BDE10626BC7B34FEFE5D1")] - [InlineData("1bit.png", RotateFlipType.Rotate180FlipY, "23947CE822C1DDE6BEA69C01F8D0D984")] - [InlineData("1bit.png", RotateFlipType.Rotate270FlipNone, "E96D3390938350F9DE2608C436442452")] - [InlineData("1bit.png", RotateFlipType.Rotate270FlipX, "AEA18A770A845E25B6A8CE28DD6DCB2E")] - [InlineData("1bit.png", RotateFlipType.Rotate270FlipXY, "C0975EAFD2FC1CC9CC7AF20B92FC9F15")] - [InlineData("1bit.png", RotateFlipType.Rotate270FlipY, "BE45F685BDEBD7079AA1B2CBA467234E")] - [InlineData("4bit.png", RotateFlipType.Rotate180FlipNone, "27CF5E9CE70BE9EBC47FB996721B95DC")] - [InlineData("4bit.png", RotateFlipType.Rotate180FlipX, "05A77EDDCDF20D5B0AC0169E95D7D778")] - [InlineData("4bit.png", RotateFlipType.Rotate180FlipXY, "3CC874B571902366AACED5D619E87D85")] - [InlineData("4bit.png", RotateFlipType.Rotate180FlipY, "545876C99ACF833E69FBFFBF4360345D")] - [InlineData("4bit.png", RotateFlipType.Rotate270FlipNone, "A919CCB8F97CAD7DC1F01026D11A5D15")] - [InlineData("4bit.png", RotateFlipType.Rotate270FlipX, "B6B6245796C836923ABAABDF368B2983")] - [InlineData("4bit.png", RotateFlipType.Rotate270FlipXY, "8DE25C7E1BE4A3B535DB5D83198D83E3")] - [InlineData("4bit.png", RotateFlipType.Rotate270FlipY, "5DB56687757CDEFC52D89C77CA92239B")] - [PlatformSpecific(TestPlatforms.AnyUnix)] - public void Rotate1bit4bit(string file, RotateFlipType type, string md5) - { - using (Bitmap bmp = new Bitmap(Helpers.GetTestBitmapPath(file))) - { - Assert.Equal(md5, RotateIndexedBmp(bmp, type)); - } - } - private Bitmap CreateBitmap(int width, int height, PixelFormat fmt) { Bitmap bmp = new Bitmap(width, height, fmt); diff --git a/src/libraries/System.Drawing.Common/tests/mono/System.Drawing/GraphicsTests.cs b/src/libraries/System.Drawing.Common/tests/mono/System.Drawing/GraphicsTests.cs index a274b13d74120..f8db0a5f10a2b 100644 --- a/src/libraries/System.Drawing.Common/tests/mono/System.Drawing/GraphicsTests.cs +++ b/src/libraries/System.Drawing.Common/tests/mono/System.Drawing/GraphicsTests.cs @@ -3152,7 +3152,6 @@ public void FillPath_Arcs() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22221", TestPlatforms.AnyUnix)] [ConditionalFact(Helpers.IsDrawingSupported)] public void TransformPoints() { diff --git a/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs b/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs index f239ccb1a53ab..676850c9d2960 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs @@ -1185,13 +1185,13 @@ public static IEnumerable SerializableObjects() yield return new object[] { new Size(10, 45), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABNTeXN0ZW0uRHJhd2luZy5TaXplAgAAAAV3aWR0aAZoZWlnaHQAAAgIAgAAAAoAAAAtAAAACw==", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABNTeXN0ZW0uRHJhd2luZy5TaXplAgAAAAV3aWR0aAZoZWlnaHQAAAgIAgAAAAoAAAAtAAAACw==", TargetFrameworkMoniker.netfx461) } }; yield return new object[] { new SizeF(10.2f, 45.8f), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABRTeXN0ZW0uRHJhd2luZy5TaXplRgIAAAAFd2lkdGgGaGVpZ2h0AAALCwIAAAAzMyNBMzM3Qgs=", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABRTeXN0ZW0uRHJhd2luZy5TaXplRgIAAAAFd2lkdGgGaGVpZ2h0AAALCwIAAAAzMyNBMzM3Qgs=", TargetFrameworkMoniker.netfx461) } }; - yield return new object[] { GraphicsUnit.Pixel, new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABtTeXN0ZW0uRHJhd2luZy5HcmFwaGljc1VuaXQBAAAAB3ZhbHVlX18ACAIAAAACAAAACw==", TargetFrameworkMoniker.netcoreapp21), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABtTeXN0ZW0uRHJhd2luZy5HcmFwaGljc1VuaXQBAAAAB3ZhbHVlX18ACAIAAAACAAAACw==", TargetFrameworkMoniker.netfx461) } }; - yield return new object[] { ContentAlignment.BottomCenter, new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAAB9TeXN0ZW0uRHJhd2luZy5Db250ZW50QWxpZ25tZW50AQAAAAd2YWx1ZV9fAAgCAAAAAAIAAAs=", TargetFrameworkMoniker.netcoreapp21), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAAB9TeXN0ZW0uRHJhd2luZy5Db250ZW50QWxpZ25tZW50AQAAAAd2YWx1ZV9fAAgCAAAAAAIAAAs=", TargetFrameworkMoniker.netfx461) } }; - yield return new object[] { LinearGradientMode.BackwardDiagonal, new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAACtTeXN0ZW0uRHJhd2luZy5EcmF3aW5nMkQuTGluZWFyR3JhZGllbnRNb2RlAQAAAAd2YWx1ZV9fAAgCAAAAAwAAAAs=", TargetFrameworkMoniker.netcoreapp21), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAACtTeXN0ZW0uRHJhd2luZy5EcmF3aW5nMkQuTGluZWFyR3JhZGllbnRNb2RlAQAAAAd2YWx1ZV9fAAgCAAAAAwAAAAs=", TargetFrameworkMoniker.netfx461) } }; - yield return new object[] { FontStyle.Bold, new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABhTeXN0ZW0uRHJhd2luZy5Gb250U3R5bGUBAAAAB3ZhbHVlX18ACAIAAAABAAAACw==", TargetFrameworkMoniker.netcoreapp21), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABhTeXN0ZW0uRHJhd2luZy5Gb250U3R5bGUBAAAAB3ZhbHVlX18ACAIAAAABAAAACw==", TargetFrameworkMoniker.netfx461) } }; // Drawing is not supported on all platforms if (PlatformDetection.IsDrawingSupported) { + yield return new object[] { GraphicsUnit.Pixel, new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABtTeXN0ZW0uRHJhd2luZy5HcmFwaGljc1VuaXQBAAAAB3ZhbHVlX18ACAIAAAACAAAACw==", TargetFrameworkMoniker.netcoreapp21), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABtTeXN0ZW0uRHJhd2luZy5HcmFwaGljc1VuaXQBAAAAB3ZhbHVlX18ACAIAAAACAAAACw==", TargetFrameworkMoniker.netfx461) } }; + yield return new object[] { ContentAlignment.BottomCenter, new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAAB9TeXN0ZW0uRHJhd2luZy5Db250ZW50QWxpZ25tZW50AQAAAAd2YWx1ZV9fAAgCAAAAAAIAAAs=", TargetFrameworkMoniker.netcoreapp21), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAAB9TeXN0ZW0uRHJhd2luZy5Db250ZW50QWxpZ25tZW50AQAAAAd2YWx1ZV9fAAgCAAAAAAIAAAs=", TargetFrameworkMoniker.netfx461) } }; + yield return new object[] { LinearGradientMode.BackwardDiagonal, new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAACtTeXN0ZW0uRHJhd2luZy5EcmF3aW5nMkQuTGluZWFyR3JhZGllbnRNb2RlAQAAAAd2YWx1ZV9fAAgCAAAAAwAAAAs=", TargetFrameworkMoniker.netcoreapp21), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAACtTeXN0ZW0uRHJhd2luZy5EcmF3aW5nMkQuTGluZWFyR3JhZGllbnRNb2RlAQAAAAd2YWx1ZV9fAAgCAAAAAwAAAAs=", TargetFrameworkMoniker.netfx461) } }; + yield return new object[] { FontStyle.Bold, new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABhTeXN0ZW0uRHJhd2luZy5Gb250U3R5bGUBAAAAB3ZhbHVlX18ACAIAAAABAAAACw==", TargetFrameworkMoniker.netcoreapp21), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABhTeXN0ZW0uRHJhd2luZy5Gb250U3R5bGUBAAAAB3ZhbHVlX18ACAIAAAABAAAACw==", TargetFrameworkMoniker.netfx461) } }; yield return new object[] { new Font("coreFxAwesomeFont", 8.5f, FontStyle.Strikeout, GraphicsUnit.Pixel), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABNTeXN0ZW0uRHJhd2luZy5Gb250BAAAAAROYW1lBFNpemUFU3R5bGUEVW5pdAEABAQLGFN5c3RlbS5EcmF3aW5nLkZvbnRTdHlsZQIAAAAbU3lzdGVtLkRyYXdpbmcuR3JhcGhpY3NVbml0AgAAAAIAAAAGAwAAABFjb3JlRnhBd2Vzb21lRm9udAAACEEF/P///xhTeXN0ZW0uRHJhd2luZy5Gb250U3R5bGUBAAAAB3ZhbHVlX18ACAIAAAAIAAAABfv///8bU3lzdGVtLkRyYXdpbmcuR3JhcGhpY3NVbml0AQAAAAd2YWx1ZV9fAAgCAAAAAgAAAAs=", TargetFrameworkMoniker.netcoreapp30), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABNTeXN0ZW0uRHJhd2luZy5Gb250BAAAAAROYW1lBFNpemUFU3R5bGUEVW5pdAEABAQLGFN5c3RlbS5EcmF3aW5nLkZvbnRTdHlsZQIAAAAbU3lzdGVtLkRyYXdpbmcuR3JhcGhpY3NVbml0AgAAAAIAAAAGAwAAABFjb3JlRnhBd2Vzb21lRm9udAAACEEF/P///xhTeXN0ZW0uRHJhd2luZy5Gb250U3R5bGUBAAAAB3ZhbHVlX18ACAIAAAAIAAAABfv///8bU3lzdGVtLkRyYXdpbmcuR3JhcGhpY3NVbml0AQAAAAd2YWx1ZV9fAAgCAAAAAgAAAAs=", TargetFrameworkMoniker.netfx461) } }; }