Class SvgDocument
An SVG document: an editable element tree read from an .svg or .svgz file, which saves back to SVG and draws through Egami.Drawing's canvas.
public sealed class SvgDocument
- Inheritance
-
SvgDocument
- Inherited Members
Examples
// .svg and .svgz alike; nothing outside the file is opened unless a resolver allows it.
SvgDocument document = SvgDocument.Load(path);
Console.WriteLine($"{document.Title}: {document.Root.Descendants().Count()} elements");
// What a lenient load skipped is in Warnings, and in the context's diagnostics.
foreach (EgamiDiagnostic warning in document.Warnings)
{
Console.WriteLine($"{warning.Id}: {warning.Message}");
}
Remarks
Loading is lenient, as browsers and resvg read SVG: what cannot be used is skipped and reported through the context's diagnostics, and the rest is kept. Strict throws instead. Nothing outside the file is opened unless Resolver allows it.
Constructors
SvgDocument(SvgElement, SvgLoadOptions?)
Initializes a new instance of the SvgDocument class around a root element made in code.
public SvgDocument(SvgElement root, SvgLoadOptions? options = null)
Parameters
rootSvgElementThe root, an
svgelement without a parent or another document.optionsSvgLoadOptionsHow references, units and limits work, or null for the defaults.
Examples
// A document made in code: an svg root and its content.
SvgElement root = new("svg");
root.Attributes["viewBox"] = "0 0 100 100";
SvgElement circle = new("circle");
circle.Attributes["cx"] = "50";
circle.Attributes["cy"] = "50";
circle.Attributes["r"] = "40";
root.Children.Add(circle);
SvgDocument document = new(root);
Exceptions
- ArgumentException
rootalready has a parent or a document.
Properties
Description
Gets the text of the root's first desc child, or null.
public string? Description { get; }
Property Value
Options
Gets the options the document was loaded with.
public SvgLoadOptions Options { get; }
Property Value
RenderTree
Gets the render tree: the elements resolved for drawing (styles applied, units in pixels, use expanded, shapes as paths), in the document's pixels (Size). It is built at load and again on first use after an edit; what an edit leaves undrawable is reported to the context's diagnostics then. It is immutable and safe to read from many threads.
public SvgGroup RenderTree { get; }
Property Value
Examples
// The resolved tree: groups, paths with their paints and strokes, images; styles applied and units in pixels.
static void Walk(SvgNode node, int depth)
{
string what = node switch
{
SvgPath path => $"path {path.Path.Bounds} fill {path.Fill}",
SvgGroup group => $"group of {group.Children.Count}",
SvgImage image => $"image {image.Destination}",
_ => node.GetType().Name,
};
Console.WriteLine($"{new string(' ', depth * 2)}{node.Id} {what} opacity {node.Opacity}");
if (node is SvgGroup g)
{
foreach (SvgNode child in g.Children)
{
Walk(child, depth + 1);
}
}
}
Walk(document.RenderTree, 0);
Root
Gets the root svg element.
public SvgElement Root { get; }
Property Value
Size
Gets the document's size in pixels: the root's width and height, a percentage (or a missing side) taken of the viewBox, or of 100 by 100 when there is no viewBox, as resvg sizes documents. Physical units use Dpi.
public Vector2 Size { get; }
Property Value
Title
Gets the text of the root's first title child, or null.
public string? Title { get; }
Property Value
ViewBox
Gets the root's viewBox, or null when it has none (or an invalid one).
public RectF? ViewBox { get; }
Property Value
Warnings
Gets what the load skipped, as also sent to the context's diagnostics; empty for a document made in code.
public IReadOnlyList<EgamiDiagnostic> Warnings { get; }
Property Value
Methods
Draw(Canvas, RectF?, SvgRenderOptions?)
Draws the document on a canvas: at its own size from the canvas's origin, or fitted into box by the
root's preserveAspectRatio. 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.
public void Draw(Canvas canvas, RectF? box = null, SvgRenderOptions? options = null)
Parameters
canvasCanvasThe canvas.
boxRectF?The rectangle to fit the document into, in the canvas's coordinates, or null.
optionsSvgRenderOptionsLanguages, text as paths and filter scale, or null for the defaults.
Examples
// Fitted into a box by the root's preserveAspectRatio; a PDF page or SvgCanvas receives the same calls.
document.Draw(canvas, new RectF(10, 10, 180, 180));
// One element of a sprite sheet, fitted into its own box.
document.Draw(canvas, "body", new RectF(200, 10, 48, 48));
Draw(Canvas, string, RectF?, SvgRenderOptions?)
Draws one element and what it holds, such as a symbol or g of a sprite sheet: fitted into
box (a symbol's viewBox, else the element's bounding box, centered and scaled to fit), or, without a
box, in the coordinates of its parent.
public void Draw(Canvas canvas, string id, RectF? box = null, SvgRenderOptions? options = null)
Parameters
canvasCanvasThe canvas.
idstringThe element's id.
boxRectF?The rectangle to fit the element into, or null.
optionsSvgRenderOptionsLanguages, text as paths and filter scale, or null for the defaults.
Examples
// Fitted into a box by the root's preserveAspectRatio; a PDF page or SvgCanvas receives the same calls.
document.Draw(canvas, new RectF(10, 10, 180, 180));
// One element of a sprite sheet, fitted into its own box.
document.Draw(canvas, "body", new RectF(200, 10, 48, 48));
Exceptions
- ArgumentException
No element has the id.
FindById(string)
Finds the element with an id; the first in file order when several share it.
public SvgElement? FindById(string id)
Parameters
idstringThe id, without a
#.
Returns
- SvgElement
The element, or null.
Load(Stream, SvgLoadOptions?)
Reads an .svg or .svgz stream from its current position.
public static SvgDocument Load(Stream stream, SvgLoadOptions? options = null)
Parameters
streamStreamThe stream; it is read to the end of the document and left open.
optionsSvgLoadOptionsHow to read it, or null for the defaults.
Returns
- SvgDocument
The document.
Examples
// Images, style sheets and fonts the file refers to open only through a resolver; data: URIs always work.
var options = new SvgLoadOptions
{
Resolver = SvgResolvers.SameDirectory(folder),
Dpi = 96,
Context = EgamiContext.Default with { Limits = SafetyLimits.Default with { MaxTotalBytes = 64L << 20 } },
};
SvgDocument document = SvgDocument.Parse(Icon, options);
Exceptions
- SvgException
The data is not well-formed XML, is not SVG, breaks a limit, or, in strict mode, has an error.
- LimitExceededException
The data is larger than the context's MaxTotalBytes.
Load(string, SvgLoadOptions?)
Reads an .svg or .svgz file.
public static SvgDocument Load(string path, SvgLoadOptions? options = null)
Parameters
pathstringThe file. Relative references resolve against its folder (they open only through a resolver).
optionsSvgLoadOptionsHow to read it, or null for the defaults.
Returns
- SvgDocument
The document.
Examples
// .svg and .svgz alike; nothing outside the file is opened unless a resolver allows it.
SvgDocument document = SvgDocument.Load(path);
Console.WriteLine($"{document.Title}: {document.Root.Descendants().Count()} elements");
// What a lenient load skipped is in Warnings, and in the context's diagnostics.
foreach (EgamiDiagnostic warning in document.Warnings)
{
Console.WriteLine($"{warning.Id}: {warning.Message}");
}
Exceptions
- SvgException
The file is not well-formed XML, is not SVG, breaks a limit, or, in strict mode, has an error.
- LimitExceededException
The file is larger than the context's MaxTotalBytes.
Parse(string, SvgLoadOptions?)
Reads SVG text.
public static SvgDocument Parse(string text, SvgLoadOptions? options = null)
Parameters
textstringThe SVG markup.
optionsSvgLoadOptionsHow to read it, or null for the defaults.
Returns
- SvgDocument
The document.
Examples
// Strict turns everything a lenient load would skip into an exception with the line and column.
try
{
SvgDocument.Parse("<svg>\n <rect width='10' height='10'/>\n</svg>", new SvgLoadOptions { Strict = true });
}
catch (SvgException e)
{
Console.WriteLine($"Line {e.Line}, column {e.Column}: {e.Problem}");
}
Exceptions
- SvgException
The text is not well-formed XML, is not SVG, breaks a limit, or, in strict mode, has an error.
Rasterize<TPixel>(SvgRenderOptions?)
Draws the document into a new raster: at its own size times Scale, or at a target width and/or height (the other side keeps the aspect ratio), over Background.
public Raster<TPixel> Rasterize<TPixel>(SvgRenderOptions? options = null) where TPixel : unmanaged, IPixelType<TPixel>
Parameters
optionsSvgRenderOptionsThe size, background and canvas options, or null for the defaults.
Returns
- Raster<TPixel>
The raster.
Type Parameters
TPixelThe pixel type of the raster.
Examples
// At the document's own size, scaled, or at a target width (the height keeps the aspect ratio).
using Raster<Rgba8> icon = document.Rasterize<Rgba8>();
using Raster<Rgba8> large = document.Rasterize<Rgba8>(new SvgRenderOptions { Width = 512 });
using Raster<Rgba8> onWhite = document.Rasterize<Rgba8>(new SvgRenderOptions { Scale = 2, Background = new RgbaF32(1, 1, 1, 1) });
Exceptions
- LimitExceededException
The raster would break the context's size limits.
Save(Stream, SvgSaveOptions?)
Writes the document as SVG: the element tree with everything read from the file (unknown elements, foreign namespaces, comments, the DOCTYPE), so a load and save without edits keeps the document's meaning; attribute order and whitespace inside tags may change, and entities are written out.
public void Save(Stream stream, SvgSaveOptions? options = null)
Parameters
streamStreamThe stream to write to; it is left open.
optionsSvgSaveOptions
Examples
// Numbers and paths set in code are written with Precision decimals; what was read keeps its text.
document.FindById("body")!.Attributes.Set("width", 17.666666);
document.Save(path, new SvgSaveOptions { Precision = 2, Gzip = true });
using var stream = new MemoryStream();
document.Save(stream);
Save(string, SvgSaveOptions?)
Writes the document to a file, as Save(Stream, SvgSaveOptions?) does.
public void Save(string path, SvgSaveOptions? options = null)
Parameters
pathstringThe file; it is replaced if it exists. Use Gzip for .svgz.
optionsSvgSaveOptions
Examples
// Numbers and paths set in code are written with Precision decimals; what was read keeps its text.
document.FindById("body")!.Attributes.Set("width", 17.666666);
document.Save(path, new SvgSaveOptions { Precision = 2, Gzip = true });
using var stream = new MemoryStream();
document.Save(stream);