Commit 7a704170 authored by davescriven's avatar davescriven
Browse files

- Fixed #6324: SvgElement.PushTransforms and ViewBox - not necessarily related...

- Fixed #6324: SvgElement.PushTransforms and ViewBox - not necessarily related to ViewBox but every   element was 'resetting' the current graphics transform if the element contained it's own transform. This 
  was a very small fix for a large problem (SvgElement.PushTransforms Matrix transformMatrix = new   Matrix(); changed to Matrix transformMatrix = renderer.Transform; in order to inherit the current   transform.)
- Fixed #6344: Parsing document incorrectly parents elements when it encounters empty nodes which are   in a different namespace. Empty nodes are now ignored and current nodes are closed as required. We'll 
  see how this fix goes.
- Fixed #6381: Units in inches are incorrectly parsed as millimeters - problem was caused by some   copy/paste work.
- Graphics has been replaced by SvgRenderer. This is essentially a wrapper around graphics but will allow
  custom svg related properties in the future when needed.
- Removed ISvgRenderer: A concrete implementation is suitable.
- SvgElement.ElementName has been changed to non-virtual and is set by the parser instead of the   developer having to specify it when developing the class.
- Added more XML API documentation.
parent b12621e2
...@@ -24,7 +24,7 @@ namespace Svg ...@@ -24,7 +24,7 @@ namespace Svg
// If it's pointing to a paint server // If it's pointing to a paint server
if (string.IsNullOrEmpty(value) || value.ToLower().Trim() == "none") if (string.IsNullOrEmpty(value) || value.ToLower().Trim() == "none")
{ {
return SvgPaintServer.None; return new SvgColourServer(Color.Transparent);
} }
else if (value.IndexOf("url(#") > -1) else if (value.IndexOf("url(#") > -1)
{ {
......
...@@ -74,7 +74,7 @@ namespace Svg ...@@ -74,7 +74,7 @@ namespace Svg
float height = this._height.ToDeviceValue(renderingElement, true); float height = this._height.ToDeviceValue(renderingElement, true);
Bitmap image = new Bitmap((int)width, (int)height); Bitmap image = new Bitmap((int)width, (int)height);
using (Graphics graphics = Graphics.FromImage(image)) using (SvgRenderer renderer = SvgRenderer.FromImage(image))
{ {
Matrix patternMatrix = new Matrix(); Matrix patternMatrix = new Matrix();
...@@ -93,17 +93,17 @@ namespace Svg ...@@ -93,17 +93,17 @@ namespace Svg
patternMatrix.Scale(this.Width.ToDeviceValue() / this.ViewBox.Width, this.Height.ToDeviceValue() / this.ViewBox.Height); patternMatrix.Scale(this.Width.ToDeviceValue() / this.ViewBox.Width, this.Height.ToDeviceValue() / this.ViewBox.Height);
} }
graphics.Transform = patternMatrix; renderer.Transform = patternMatrix;
graphics.CompositingQuality = CompositingQuality.HighQuality; renderer.CompositingQuality = CompositingQuality.HighQuality;
graphics.SmoothingMode = SmoothingMode.AntiAlias; renderer.SmoothingMode = SmoothingMode.AntiAlias;
graphics.PixelOffsetMode = PixelOffsetMode.Half; renderer.PixelOffsetMode = PixelOffsetMode.Half;
foreach (SvgElement child in this.Children) foreach (SvgElement child in this.Children)
{ {
child.RenderElement(graphics); child.RenderElement(renderer);
} }
graphics.Save(); renderer.Save();
} }
TextureBrush textureBrush = new TextureBrush(image); TextureBrush textureBrush = new TextureBrush(image);
......
...@@ -50,14 +50,6 @@ namespace Svg ...@@ -50,14 +50,6 @@ namespace Svg
{ {
} }
/// <summary>
/// Gets the name of the element.
/// </summary>
protected override string ElementName
{
get { return "radialGradient"; }
}
public override Brush GetBrush(SvgGraphicsElement renderingElement, float opacity) public override Brush GetBrush(SvgGraphicsElement renderingElement, float opacity)
{ {
GraphicsPath path = new GraphicsPath(); GraphicsPath path = new GraphicsPath();
......
...@@ -10,13 +10,18 @@ using Svg.Pathing; ...@@ -10,13 +10,18 @@ using Svg.Pathing;
namespace Svg namespace Svg
{ {
[Serializable()] /// <summary>
/// Represents an SVG path element.
/// </summary>
public class SvgPath : SvgGraphicsElement public class SvgPath : SvgGraphicsElement
{ {
private SvgPathSegmentList _pathData; private SvgPathSegmentList _pathData;
private GraphicsPath _path; private GraphicsPath _path;
private int _pathLength; private int _pathLength;
/// <summary>
/// Gets or sets a <see cref="SvgPathSegmentList"/> of path data.
/// </summary>
[SvgAttribute("d")] [SvgAttribute("d")]
public SvgPathSegmentList PathData public SvgPathSegmentList PathData
{ {
...@@ -29,6 +34,9 @@ namespace Svg ...@@ -29,6 +34,9 @@ namespace Svg
} }
} }
/// <summary>
/// Gets or sets the length of the path.
/// </summary>
[SvgAttribute("pathLength")] [SvgAttribute("pathLength")]
public int PathLength public int PathLength
{ {
...@@ -63,21 +71,26 @@ namespace Svg ...@@ -63,21 +71,26 @@ namespace Svg
this.IsPathDirty = true; this.IsPathDirty = true;
} }
/// <summary>
/// Gets or sets a value to determine if anti-aliasing should occur when the element is being rendered.
/// </summary>
protected override bool RequiresSmoothRendering protected override bool RequiresSmoothRendering
{ {
get { return true; } get { return true; }
} }
/// <summary>
/// Gets the bounds of the element.
/// </summary>
/// <value>The bounds.</value>
public override System.Drawing.RectangleF Bounds public override System.Drawing.RectangleF Bounds
{ {
get { return this.Path.GetBounds(); } get { return this.Path.GetBounds(); }
} }
protected override string ElementName /// <summary>
{ /// Initializes a new instance of the <see cref="SvgPath"/> class.
get { return "path"; } /// </summary>
}
public SvgPath() public SvgPath()
{ {
this._pathData = new SvgPathSegmentList(); this._pathData = new SvgPathSegmentList();
......
...@@ -11,10 +11,16 @@ namespace Svg ...@@ -11,10 +11,16 @@ namespace Svg
{ {
internal class SvgPathBuilder : TypeConverter internal class SvgPathBuilder : TypeConverter
{ {
/// <summary>
/// Parses the specified string into a collection of path segments.
/// </summary>
/// <param name="path">A <see cref="string"/> containing path data.</param>
public static SvgPathSegmentList Parse(string path) public static SvgPathSegmentList Parse(string path)
{ {
if (string.IsNullOrEmpty(path)) if (string.IsNullOrEmpty(path))
{
throw new ArgumentNullException("path"); throw new ArgumentNullException("path");
}
var segments = new SvgPathSegmentList(); var segments = new SvgPathSegmentList();
...@@ -119,9 +125,9 @@ namespace Svg ...@@ -119,9 +125,9 @@ namespace Svg
} }
} }
} }
catch catch (Exception exc)
{ {
Trace.TraceError("Error parsing path \"{0}\".", path); Trace.TraceError("Error parsing path \"{0}\": {1}", path, exc.Message);
} }
return segments; return segments;
......
...@@ -90,7 +90,7 @@ ...@@ -90,7 +90,7 @@
<Compile Include="Filter Effects\SvgFilterPrimitive.cs" /> <Compile Include="Filter Effects\SvgFilterPrimitive.cs" />
<Compile Include="Filter Effects\SvgGaussianBlur.cs" /> <Compile Include="Filter Effects\SvgGaussianBlur.cs" />
<Compile Include="Filter Effects\SvgMerge.cs" /> <Compile Include="Filter Effects\SvgMerge.cs" />
<Compile Include="ISvgRenderer.cs" /> <Compile Include="SvgRenderer.cs" />
<Compile Include="Painting\SvgColourConverter.cs" /> <Compile Include="Painting\SvgColourConverter.cs" />
<Compile Include="Painting\SvgGradientSpreadMethod.cs" /> <Compile Include="Painting\SvgGradientSpreadMethod.cs" />
<Compile Include="SvgDtdResolver.cs" /> <Compile Include="SvgDtdResolver.cs" />
......
...@@ -25,9 +25,10 @@ namespace Svg ...@@ -25,9 +25,10 @@ namespace Svg
/// <summary> /// <summary>
/// Gets the name of the element. /// Gets the name of the element.
/// </summary> /// </summary>
protected virtual string ElementName protected internal string ElementName
{ {
get { return this._elementName; } get { return this._elementName; }
internal set { this._elementName = value; }
} }
/// <summary> /// <summary>
...@@ -67,7 +68,6 @@ namespace Svg ...@@ -67,7 +68,6 @@ namespace Svg
/// <summary> /// <summary>
/// Gets a value to determine whether the element has children. /// Gets a value to determine whether the element has children.
/// </summary> /// </summary>
/// <returns></returns>
public virtual bool HasChildren() public virtual bool HasChildren()
{ {
return (this.Children.Count > 0); return (this.Children.Count > 0);
...@@ -123,9 +123,13 @@ namespace Svg ...@@ -123,9 +123,13 @@ namespace Svg
} }
} }
protected internal virtual void PushTransforms(Graphics graphics) /// <summary>
/// Applies the required transforms to <see cref="SvgRenderer"/>.
/// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> to be transformed.</param>
protected internal virtual void PushTransforms(SvgRenderer renderer)
{ {
_graphicsMatrix = graphics.Transform; _graphicsMatrix = renderer.Transform;
// Return if there are no transforms // Return if there are no transforms
if (this.Transforms == null || this.Transforms.Count == 0) if (this.Transforms == null || this.Transforms.Count == 0)
...@@ -133,30 +137,42 @@ namespace Svg ...@@ -133,30 +137,42 @@ namespace Svg
return; return;
} }
Matrix transformMatrix = new Matrix(); Matrix transformMatrix = renderer.Transform;
foreach (SvgTransform transformation in this.Transforms) foreach (SvgTransform transformation in this.Transforms)
{ {
transformMatrix.Multiply(transformation.Matrix); transformMatrix.Multiply(transformation.Matrix);
} }
graphics.Transform = transformMatrix; renderer.Transform = transformMatrix;
} }
protected internal virtual void PopTransforms(Graphics graphics) /// <summary>
/// Removes any previously applied transforms from the specified <see cref="SvgRenderer"/>.
/// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> that should have transforms removed.</param>
protected internal virtual void PopTransforms(SvgRenderer renderer)
{ {
graphics.Transform = _graphicsMatrix; renderer.Transform = _graphicsMatrix;
_graphicsMatrix = null; _graphicsMatrix = null;
} }
void ISvgTransformable.PushTransforms(Graphics graphics) /// <summary>
/// Applies the required transforms to <see cref="SvgRenderer"/>.
/// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> to be transformed.</param>
void ISvgTransformable.PushTransforms(SvgRenderer renderer)
{ {
this.PushTransforms(graphics); this.PushTransforms(renderer);
} }
void ISvgTransformable.PopTransforms(Graphics graphics) /// <summary>
/// Removes any previously applied transforms from the specified <see cref="SvgRenderer"/>.
/// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> that should have transforms removed.</param>
void ISvgTransformable.PopTransforms(SvgRenderer renderer)
{ {
this.PopTransforms(graphics); this.PopTransforms(renderer);
} }
/// <summary> /// <summary>
...@@ -200,22 +216,22 @@ namespace Svg ...@@ -200,22 +216,22 @@ namespace Svg
} }
} }
protected virtual void ElementAdded(SvgElement child, int index) protected virtual void AddElement(SvgElement child, int index)
{ {
} }
internal void OnElementAdded(SvgElement child, int index) internal void OnElementAdded(SvgElement child, int index)
{ {
this.ElementAdded(child, index); this.AddElement(child, index);
} }
protected virtual void ElementRemoved(SvgElement child) protected virtual void RemoveElement(SvgElement child)
{ {
} }
internal void OnElementRemoved(SvgElement child) internal void OnElementRemoved(SvgElement child)
{ {
this.ElementRemoved(child); this.RemoveElement(child);
} }
/// <summary> /// <summary>
...@@ -228,9 +244,13 @@ namespace Svg ...@@ -228,9 +244,13 @@ namespace Svg
this._elementName = string.Empty; this._elementName = string.Empty;
} }
public void RenderElement(Graphics graphics) /// <summary>
/// Renders this element to the <see cref="SvgRenderer"/>.
/// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> that the element should use to render itself.</param>
public void RenderElement(SvgRenderer renderer)
{ {
this.Render(graphics); this.Render(renderer);
} }
public void WriteElement(XmlTextWriter writer) public void WriteElement(XmlTextWriter writer)
...@@ -279,29 +299,43 @@ namespace Svg ...@@ -279,29 +299,43 @@ namespace Svg
} }
/// <summary> /// <summary>
/// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object. /// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="SvgRenderer"/> object.
/// </summary> /// </summary>
/// <param name="graphics">The <see cref="Graphics"/> object to render to.</param> /// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param>
protected virtual void Render(Graphics graphics) protected virtual void Render(SvgRenderer renderer)
{ {
this.PushTransforms(graphics); this.PushTransforms(renderer);
this.RenderContents(graphics); this.RenderChildren(renderer);
this.PopTransforms(graphics); this.PopTransforms(renderer);
} }
protected virtual void RenderContents(Graphics graphics) /// <summary>
/// Renders the children of this <see cref="SvgElement"/>.
/// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> to render the child <see cref="SvgElement"/>s to.</param>
protected virtual void RenderChildren(SvgRenderer renderer)
{ {
foreach (SvgElement element in this.Children) foreach (SvgElement element in this.Children)
{ {
element.Render(graphics); element.Render(renderer);
} }
} }
void ISvgElement.Render(Graphics graphics) /// <summary>
/// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="SvgRenderer"/> object.
/// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param>
void ISvgElement.Render(SvgRenderer renderer)
{ {
this.Render(graphics); this.Render(renderer);
} }
/// <summary>
/// Creates a new object that is a copy of the current instance.
/// </summary>
/// <returns>
/// A new object that is a copy of this instance.
/// </returns>
public virtual object Clone() public virtual object Clone()
{ {
return this.MemberwiseClone(); return this.MemberwiseClone();
...@@ -310,6 +344,6 @@ namespace Svg ...@@ -310,6 +344,6 @@ namespace Svg
internal interface ISvgElement internal interface ISvgElement
{ {
void Render(Graphics graphics); void Render(SvgRenderer renderer);
} }
} }
\ No newline at end of file
...@@ -35,6 +35,8 @@ namespace Svg ...@@ -35,6 +35,8 @@ namespace Svg
SvgFragment fragment; SvgFragment fragment;
string elementName = reader.LocalName; string elementName = reader.LocalName;
Trace.TraceInformation("Begin CreateElement: {0}", elementName);
// Parse element // Parse element
switch (elementName) switch (elementName)
{ {
...@@ -64,9 +66,13 @@ namespace Svg ...@@ -64,9 +66,13 @@ namespace Svg
break; break;
case "svg": case "svg":
if (!fragmentIsDocument) if (!fragmentIsDocument)
{
fragment = new SvgFragment(); fragment = new SvgFragment();
}
else else
{
fragment = new SvgDocument(); fragment = new SvgDocument();
}
createdElement = (fragmentIsDocument) ? (SvgDocument)fragment : fragment; createdElement = (fragmentIsDocument) ? (SvgDocument)fragment : fragment;
break; break;
...@@ -99,16 +105,25 @@ namespace Svg ...@@ -99,16 +105,25 @@ namespace Svg
break; break;
default: default:
// Do nothing - unsupported // Do nothing - unsupported
return null; createdElement = null;
break;
} }
if (createdElement != null)
{
createdElement.ElementName = elementName;
SetAttributes(createdElement, reader, document); SetAttributes(createdElement, reader, document);
}
Trace.TraceInformation("End CreateElement");
return createdElement; return createdElement;
} }
private static void SetAttributes(SvgElement element, XmlTextReader reader, SvgDocument document) private static void SetAttributes(SvgElement element, XmlTextReader reader, SvgDocument document)
{ {
Trace.TraceInformation("Begin SetAttributes");
string[] styles = null; string[] styles = null;
string[] style = null; string[] style = null;
int i = 0; int i = 0;
...@@ -136,11 +151,13 @@ namespace Svg ...@@ -136,11 +151,13 @@ namespace Svg
SetPropertyValue(element, reader.LocalName, reader.Value, document); SetPropertyValue(element, reader.LocalName, reader.Value, document);
} }
Trace.TraceInformation("End SetAttributes");
} }
private static void SetPropertyValue(SvgElement element, string attributeName, string attributeValue, SvgDocument document) private static void SetPropertyValue(SvgElement element, string attributeName, string attributeValue, SvgDocument document)
{ {
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(element.GetType(), new SvgAttributeAttribute[] { new SvgAttributeAttribute(attributeName) }); var properties = TypeDescriptor.GetProperties(element.GetType(), new SvgAttributeAttribute[] { new SvgAttributeAttribute(attributeName) });
PropertyDescriptor descriptor = null; PropertyDescriptor descriptor = null;
TypeConverter converter = null; TypeConverter converter = null;
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
namespace Svg
{
public sealed class SvgRenderer : IDisposable
{
private Graphics _innerGraphics;
/// <summary>
/// Initializes a new instance of the <see cref="SvgRenderer"/> class.
/// </summary>
private SvgRenderer()
{
}
/// <summary>
/// Creates a new <see cref="SvgRenderer"/> from the specified <see cref="Image"/>.
/// </summary>
/// <param name="image"><see cref="Image"/> from which to create the new <see cref="SvgRenderer"/>.</param>
public static SvgRenderer FromImage(Image image)
{
SvgRenderer renderer = new SvgRenderer();
renderer._innerGraphics = Graphics.FromImage(image);
return renderer;
}
public void FillPath(Brush brush, GraphicsPath path)
{
this._innerGraphics.FillPath(brush, path);
}
public void DrawPath(Pen pen, GraphicsPath path)
{
this._innerGraphics.DrawPath(pen, path);
}
public void TranslateTransform(float dx, float dy, MatrixOrder order)
{
this._innerGraphics.TranslateTransform(dx, dy, order);
}
public void TranslateTransform(float dx, float dy)
{
this.TranslateTransform(dx, dy, MatrixOrder.Append);
}
public void ScaleTransform(float sx, float sy, MatrixOrder order)
{
this._innerGraphics.ScaleTransform(sx, sy, order);
}
public void ScaleTransform(float sx, float sy)
{
this.ScaleTransform(sx, sy, MatrixOrder.Append);
}
public SmoothingMode SmoothingMode
{
get { return this._innerGraphics.SmoothingMode; }
set { this._innerGraphics.SmoothingMode = value; }
}
public PixelOffsetMode PixelOffsetMode
{
get { return this._innerGraphics.PixelOffsetMode; }
set { this._innerGraphics.PixelOffsetMode = value; }
}
public CompositingQuality CompositingQuality
{
get { return this._innerGraphics.CompositingQuality; }
set { this._innerGraphics.CompositingQuality = value; }
}
public TextRenderingHint TextRenderingHint
{
get { return this._innerGraphics.TextRenderingHint; }
set { this._innerGraphics.TextRenderingHint = value; }
}
public int TextContrast
{
get { return this._innerGraphics.TextContrast; }
set { this._innerGraphics.TextContrast = value; }
}
public Matrix Transform
{
get { return this._innerGraphics.Transform; }
set { this._innerGraphics.Transform = value; }
}
public void Save()
{
this._innerGraphics.Save();
}
public void Dispose()
{
this._innerGraphics.Dispose();
}
}
}
\ No newline at end of file
...@@ -21,7 +21,7 @@ namespace Svg ...@@ -21,7 +21,7 @@ namespace Svg
private Font _font; private Font _font;
private GraphicsPath _path; private GraphicsPath _path;
private SvgTextAnchor _textAnchor = SvgTextAnchor.Start; private SvgTextAnchor _textAnchor = SvgTextAnchor.Start;
private static readonly Graphics _stringMeasure; private static readonly SvgRenderer _stringMeasure;
/// <summary> /// <summary>
/// Initializes the <see cref="SvgText"/> class. /// Initializes the <see cref="SvgText"/> class.
...@@ -29,7 +29,7 @@ namespace Svg ...@@ -29,7 +29,7 @@ namespace Svg
static SvgText() static SvgText()
{ {
Bitmap bitmap = new Bitmap(1, 1); Bitmap bitmap = new Bitmap(1, 1);
_stringMeasure = Graphics.FromImage(bitmap); _stringMeasure = SvgRenderer.FromImage(bitmap);
_stringMeasure.TextRenderingHint = TextRenderingHint.AntiAlias; _stringMeasure.TextRenderingHint = TextRenderingHint.AntiAlias;
} }
...@@ -189,16 +189,16 @@ namespace Svg ...@@ -189,16 +189,16 @@ namespace Svg
/// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object. /// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object.
/// </summary> /// </summary>
/// <param name="graphics">The <see cref="Graphics"/> object to render to.</param> /// <param name="graphics">The <see cref="Graphics"/> object to render to.</param>
protected override void Render(Graphics graphics) protected override void Render(SvgRenderer renderer)
{ {
base.Render(graphics); base.Render(renderer);
} }
static private int MeasureString(Graphics graphics, string text, Font font) static private int MeasureString(SvgRenderer renderer, string text, Font font)
{ {
GraphicsPath p = new GraphicsPath(); GraphicsPath p = new GraphicsPath();
p.AddString(text, font.FontFamily, 0, font.Size, new PointF(0.0f, 0.0f), StringFormat.GenericTypographic); p.AddString(text, font.FontFamily, 0, font.Size, new PointF(0.0f, 0.0f), StringFormat.GenericTypographic);
p.Transform(graphics.Transform); p.Transform(renderer.Transform);
return (int)(p.GetBounds().Width + 1.0f); return (int)(p.GetBounds().Width + 1.0f);
} }
...@@ -214,6 +214,10 @@ namespace Svg ...@@ -214,6 +214,10 @@ namespace Svg
if (_path == null || this.IsPathDirty && !string.IsNullOrEmpty(this.Text)) if (_path == null || this.IsPathDirty && !string.IsNullOrEmpty(this.Text))
{ {
float fontSize = this.FontSize.ToDeviceValue(this); float fontSize = this.FontSize.ToDeviceValue(this);
if (fontSize == 0.0f)
{
fontSize = 1.0f;
}
int stringWidth; int stringWidth;
PointF location = PointF.Empty; PointF location = PointF.Empty;
...@@ -267,9 +271,12 @@ namespace Svg ...@@ -267,9 +271,12 @@ namespace Svg
} }
} }
else else
{
if (!string.IsNullOrEmpty(this.Text))
{ {
_path.AddString(this.Text, this._font.FontFamily, 0, fontSize, location, StringFormat.GenericTypographic); _path.AddString(this.Text, this._font.FontFamily, 0, fontSize, location, StringFormat.GenericTypographic);
} }
}
_path.CloseFigure(); _path.CloseFigure();
this.IsPathDirty = false; this.IsPathDirty = false;
......
...@@ -8,10 +8,24 @@ using Svg.Transforms; ...@@ -8,10 +8,24 @@ using Svg.Transforms;
namespace Svg namespace Svg
{ {
/// <summary>
/// Represents and element that may be transformed.
/// </summary>
public interface ISvgTransformable public interface ISvgTransformable
{ {
/// <summary>
/// Gets or sets an <see cref="SvgTransformCollection"/> of element transforms.
/// </summary>
SvgTransformCollection Transforms { get; set; } SvgTransformCollection Transforms { get; set; }
void PushTransforms(Graphics graphics); /// <summary>
void PopTransforms(Graphics graphics); /// Applies the required transforms to <see cref="SvgRenderer"/>.
/// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> to be transformed.</param>
void PushTransforms(SvgRenderer renderer);
/// <summary>
/// Removes any previously applied transforms from the specified <see cref="SvgRenderer"/>.
/// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> that should have transforms removed.</param>
void PopTransforms(SvgRenderer renderer);
} }
} }
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment