Add more complete metafile support to System.Drawing
- Dominant language
- C#
- Stars
- 4.9k
- Forks
- 1.1k
- Avg merge
- 1d 13m
- Merged PRs (30d)
- 85
Description
### Background
System.Drawing lacks certain functionality related to metafiles that is exposed in GDI+.
`ConvertToEmfPlus` converts the data stored in the `Metafile` to EMF+ or EMF+ Dual records (depending on `emfType`). A `Graphics` object is passed to configure antialiasing, interpolation, etc. `ConvertToEmfPlus` will preserve any EMF records in the metafile, instead of round-tripping through EMF+. Different overloads can overwrite the current `Metafile`, or save to a file or stream. A boolean is returned, indicating whether all records were converted losslessly. This bool can be `false`, even if the method completes without error.
`EmfToWmfBits` converts an EMF metafile to a WMF metafile. It lets you specify a GDI mapping mode and some miscellaneous flags (which do not have very descriptive names). It appears to just be a wrapper over [`GetWinMetaFileBits`](https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-getwinmetafilebits), but it is technically part of the API surface.
`DownLevelRasterizationLimit` controls the DPI of certain brush bitmaps that are stored in the metafile. By default, any bitmaps recorded into the metafile are saved at 96 DPI. If this property is set to 0, the DPI of the device context handle that the metafile was opened with is used. This is helpful for controlling the file size of the resultant metafile.
This proposal is one of many to add missing GDI+ 1.1 functionality to `System.Drawing`.
### API Proposal
See the documentation for:
- [Metafile::ConvertToEmfPlus](https://docs.microsoft.com/en-us/windows/win32/api/gdiplusheaders/nf-gdiplusheaders-metafile-converttoemfplus(constgraphics_outint_emftype_constwchar))
- [Metafile::EmfToWmfBits](https://docs.microsoft.com/en-us/windows/win32/api/gdiplusheaders/nf-gdiplusheaders-metafile-emftowmfbits)
- [EmfToWmfBitsFlags](https://docs.microsoft.com/en-us/windows/win32/api/gdiplusenums/ne-gdiplusenums-emftowmfbitsflags)
- [Mapping Modes](https://docs.microsoft.com/en-us/windows/win32/gdi/mapping-modes-and-translations)
- [Metafile::SetDownLevelRasterizationLimit](https://docs.microsoft.com/en-us/windows/win32/api/gdiplusheaders/nf-gdiplusheaders-metafile-setdownlevelrasterizationlimit)
```diff
namespace System.Drawing.Imaging
{
public sealed class Metafile : Image
{
+ public void ConvertToEmfPlus(Graphics graphics, EmfType emfType, string? description, out bool conversionSuccessful);
+ public void ConvertToEmfPlus(Graphics graphics, string fileName, EmfType emfType, string? description, out bool conversionSuccessful);
+ public void ConvertToEmfPlus(Graphics graphics, Stream stream, EmfType emfType, string? description, out bool conversionSuccessful);
+ public static byte[] EmfToWmfBits(IntPtr henhmetafile, MapMode mapMode, EmfToWmfBitsFlags flags);
+ public int DownLevelRasterizationLimit { get; set; }
}
+ [Flags]
+ public enum EmfToWmfBitsFlags
+ {
+ None = 0x0,
+ EmbedEmf = 0x1,
+ IncludePlaceable = 0x2,
+ NoXorClip = 0x4
+ }
+ public enum MapMode
+ {
+ Anisotropic,
+ HiEnglish,
+ HiMetric,
+ Isotropic,
+ LoEnglish,
+ LoMetric,
+ Text,
+ Twips
+ }
}
```
#### Other additions
These enum values represent new features in GDI+ 1.1.
```diff
namespace System.Drawing.Drawing2D
{
public enum SmoothingMode
{
+ AntiAlias8x8,
+ AntiAlias8x4 = AntiAlias
}
}
namespace System.Drawing.Imaging
{
public enum EncoderValue
{
+ ColorTypeGray,
+ ColorTypeRGB
}
public enum EmfPlusRecordType
{
+ StrokeFillPath,
+ SerializableObject,
+ SetTSGraphics,
+ SetTSClip
}
}
```
This requires changes to libgdiplus in order to support it on non-Windows platforms.
Contributor guide
Assessment
This issue has not been assessed yet.