Table of Contents

Class Metafile

Namespace
Egami.Metafiles
Assembly
Egami.Metafiles.dll

A Windows metafile, WMF, EMF or EMF+ (and their gzip forms WMZ and EMZ), read and checked; its records stay internal (design question 3). The size facts come from the header: an EMF's frame, a placeable WMF's box and units per inch, or a plain WMF's window extent at 96 DPI. A metafile is immutable and safe to read from many threads.

public sealed class Metafile
Inheritance
Metafile
Inherited Members

Examples

// WMF, EMF and EMF+ alike, and the gzip forms WMZ and EMZ.
Metafile chart = Metafile.Load(path);
Console.WriteLine($"{chart.Kind}, {chart.Size.X} by {chart.Size.Y} points");

// At twice the screen's resolution, over white; text uses the installed fonts.
using Raster<Rgba8> image = chart.Rasterize<Rgba8>(new MetafileRenderOptions
{
    Dpi = 192,
    Background = new RgbaF32(1, 1, 1, 1),
});
image.Save(output);

Properties

Description

Gets an EMF's description (the application, then the picture's name, on separate lines), or null.

public string? Description { get; }

Property Value

string

Dpi

Gets the resolution of the units the picture was recorded in: an EMF's reference device in pixels per inch, a placeable WMF's units per inch, or 96 for a plain WMF.

public Vector2 Dpi { get; }

Property Value

Vector2

Frame

Gets the picture's frame in points: an EMF's frame rectangle (its origin may be away from zero), a placeable WMF's box, or a plain WMF's window extent from zero.

public RectF Frame { get; }

Property Value

RectF

Kind

Gets what the file holds.

public MetafileKind Kind { get; }

Property Value

MetafileKind

Size

Gets the picture's size in points (1/72 inch), the size Word and PowerPoint give it.

public Vector2 Size { get; }

Property Value

Vector2

Warnings

Gets what the load skipped or assumed, such as a record that runs past the end of the file.

public IReadOnlyList<EgamiDiagnostic> Warnings { get; }

Property Value

IReadOnlyList<EgamiDiagnostic>

Methods

Draw(Canvas, RectF?, MetafileRenderOptions?)

Draws the picture on a canvas: in points from the canvas's origin (the frame's corner there), or with its frame stretched to box exactly, as Word stretches a picture to its frame. Drawing calls only the public canvas API, so a raster canvas, a PDF page, SvgCanvas or a PictureRecorder receive the same calls. It never throws on content: what it cannot draw is skipped and reported to the context's diagnostics.

public void Draw(Canvas canvas, RectF? box = null, MetafileRenderOptions? options = null)

Parameters

canvas Canvas

The canvas.

box RectF?

The rectangle to stretch the frame to, in the canvas's coordinates, or null.

options MetafileRenderOptions

Fonts, antialiasing and playback, or null for the defaults.

Examples

Metafile picture = Metafile.Load(path);

// The frame is stretched to the box, as Word stretches a picture to its frame. The same calls draw on a PDF page.
using Raster<Rgba8> page = Raster.Create<Rgba8>(400, 300);
using RasterCanvas<Rgba8> canvas = page.CreateCanvas();
canvas.Clear(new RgbaF32(1, 1, 1, 1));
picture.Draw(canvas, new RectF(50, 50, 300, 200));

Load(Stream, MetafileLoadOptions?)

Reads a WMF, EMF, WMZ or EMZ stream from its current position to its end.

public static Metafile Load(Stream stream, MetafileLoadOptions? options = null)

Parameters

stream Stream

The stream; it is read to its end and left open.

options MetafileLoadOptions

How to read it, or null for the defaults.

Returns

Metafile

The metafile.

Examples

// Untrusted files: the context's limits bound the file size and what EMZ and WMZ inflate to; a record that runs past
// the end is skipped with a warning, and what came before it plays.
MetafileLoadOptions options = new()
{
    Context = EgamiContext.Default with { Limits = SafetyLimits.Default with { MaxTotalBytes = 16 << 20 } },
};
Metafile picture = Metafile.Load(new MemoryStream(bytes), options);
if (picture.Kind is MetafileKind.EmfPlusDual or MetafileKind.EmfPlusOnly)
{
    Console.WriteLine("Drawn by its EMF+ records, as GDI+ draws it.");
}

Exceptions

CorruptDataException

The data is no WMF or EMF file, or its header is broken.

LimitExceededException

The data, or an EMZ or WMZ stream once inflated, is larger than the context's MaxTotalBytes.

Load(ReadOnlyMemory<byte>, MetafileLoadOptions?)

Reads WMF, EMF, WMZ or EMZ bytes, such as a picture taken out of a Word or PowerPoint file.

public static Metafile Load(ReadOnlyMemory<byte> data, MetafileLoadOptions? options = null)

Parameters

data ReadOnlyMemory<byte>

The file's bytes; they are copied, so the memory can be reused once this returns.

options MetafileLoadOptions

How to read it, or null for the defaults.

Returns

Metafile

The metafile.

Examples

// A picture taken out of a document, already in memory: no stream needed.
Metafile picture = Metafile.Load(bytes);
using Raster<Rgba8> page = Raster.Create<Rgba8>(200, 150);
using RasterCanvas<Rgba8> canvas = page.CreateCanvas();
picture.Draw(canvas, new RectF(0, 0, 200, 150));

Exceptions

CorruptDataException

The data is no WMF or EMF file, or its header is broken.

LimitExceededException

The data, or EMZ or WMZ data once inflated, is larger than the context's MaxTotalBytes.

Load(string, MetafileLoadOptions?)

Reads a .wmf, .emf, .wmz or .emz file.

public static Metafile Load(string path, MetafileLoadOptions? options = null)

Parameters

path string

The file.

options MetafileLoadOptions

How to read it, or null for the defaults.

Returns

Metafile

The metafile.

Examples

// WMF, EMF and EMF+ alike, and the gzip forms WMZ and EMZ.
Metafile chart = Metafile.Load(path);
Console.WriteLine($"{chart.Kind}, {chart.Size.X} by {chart.Size.Y} points");

// At twice the screen's resolution, over white; text uses the installed fonts.
using Raster<Rgba8> image = chart.Rasterize<Rgba8>(new MetafileRenderOptions
{
    Dpi = 192,
    Background = new RgbaF32(1, 1, 1, 1),
});
image.Save(output);

Exceptions

CorruptDataException

The file is no WMF or EMF file, or its header is broken.

LimitExceededException

The file, or an EMZ or WMZ file once inflated, is larger than the context's MaxTotalBytes.

Rasterize<TPixel>(MetafileRenderOptions?)

Draws the picture into a new raster: at its size at Dpi (96 by default), or at a target width and/or height (the other side keeps the aspect ratio), over Background.

public Raster<TPixel> Rasterize<TPixel>(MetafileRenderOptions? options = null) where TPixel : unmanaged, IPixelType<TPixel>

Parameters

options MetafileRenderOptions

The size, background, fonts and playback, or null for the defaults.

Returns

Raster<TPixel>

The raster.

Type Parameters

TPixel

The pixel type of the raster.

Examples

// WMF, EMF and EMF+ alike, and the gzip forms WMZ and EMZ.
Metafile chart = Metafile.Load(path);
Console.WriteLine($"{chart.Kind}, {chart.Size.X} by {chart.Size.Y} points");

// At twice the screen's resolution, over white; text uses the installed fonts.
using Raster<Rgba8> image = chart.Rasterize<Rgba8>(new MetafileRenderOptions
{
    Dpi = 192,
    Background = new RgbaF32(1, 1, 1, 1),
});
image.Save(output);

Exceptions

LimitExceededException

The raster would break the context's size limits.