From 1b8cb43fa11c4b8f159797fdcc7d591dd01dedb4 Mon Sep 17 00:00:00 2001 From: Dan Backes Date: Wed, 10 Sep 2014 12:54:02 -0500 Subject: [PATCH] Performance Improvement - Because querying the Bounds property of an ISvgBoundable or SvgVisualElement is expensive, we introduced an ImmutableBoundable that is used by the SvgRenderer. This class stores the bounds of the supplied ISvgBoundable so that multiple queries for the bounds do not hamper performance when rendering. - Converted the Bounds property on ISvgBoundable and SvgVisualElement to a CalculateBounds method to indicate that it is an expensive operation that returns a new value each time it is called. - Removed redundant ISvgBoundable Location and Size properties. - Fixed a bug in SvgFragment.Path property by converting it to a method that indicates it returns a new GraphicsPath instance when called and by disposing of that instance in CalculateBounds. There are many more instances of GraphicsPath not being disposed in the code base but we did not address that here. --- Source/Basic Shapes/SvgCircle.cs | 6 +-- Source/Basic Shapes/SvgEllipse.cs | 6 +-- Source/Basic Shapes/SvgImage.cs | 30 ++++++------- Source/Basic Shapes/SvgLine.cs | 4 +- Source/Basic Shapes/SvgPolygon.cs | 4 +- Source/Basic Shapes/SvgRectangle.cs | 6 +-- Source/Basic Shapes/SvgVisualElement.cs | 20 +-------- Source/DataTypes/SvgUnit.cs | 6 +-- Source/Document Structure/SvgFragment.cs | 52 +++++++--------------- Source/Document Structure/SvgGroup.cs | 39 ++++++++-------- Source/Document Structure/SvgSwitch.cs | 37 +++++++-------- Source/Document Structure/SvgSymbol.cs | 35 +++++++-------- Source/Document Structure/SvgUse.cs | 5 ++- Source/Extensibility/SvgForeignObject.cs | 37 +++++++-------- Source/Painting/GenericBoundable.cs | 14 +----- Source/Painting/ISvgBoundable.cs | 15 +------ Source/Painting/ImmutableBoundable.cs | 19 ++++++++ Source/Painting/SvgGradientServer.cs | 2 +- Source/Painting/SvgLinearGradientServer.cs | 4 +- Source/Painting/SvgMarker.cs | 13 +++--- Source/Painting/SvgRadialGradientServer.cs | 2 +- Source/Paths/SvgPath.cs | 6 +-- Source/Rendering/SvgRenderer.cs | 2 +- Source/Svg.csproj | 1 + Source/SvgElement.cs | 2 +- Source/Text/SvgGlyph.cs | 6 +-- Source/Text/SvgTextBase.cs | 29 ++++-------- 27 files changed, 167 insertions(+), 235 deletions(-) create mode 100644 Source/Painting/ImmutableBoundable.cs diff --git a/Source/Basic Shapes/SvgCircle.cs b/Source/Basic Shapes/SvgCircle.cs index d3fbb6d..411ed38 100644 --- a/Source/Basic Shapes/SvgCircle.cs +++ b/Source/Basic Shapes/SvgCircle.cs @@ -78,10 +78,10 @@ namespace Svg /// /// Gets the bounds of the circle. /// - /// The rectangular bounds of the circle. - public override RectangleF Bounds + /// The rectangular bounds of the circle. + public override RectangleF CalculateBounds() { - get { return this.Path(null).GetBounds(); } + return this.Path(null).GetBounds(); } /// diff --git a/Source/Basic Shapes/SvgEllipse.cs b/Source/Basic Shapes/SvgEllipse.cs index 0ab1d8e..479e749 100644 --- a/Source/Basic Shapes/SvgEllipse.cs +++ b/Source/Basic Shapes/SvgEllipse.cs @@ -92,10 +92,10 @@ namespace Svg /// /// Gets the bounds of the element. /// - /// The bounds. - public override RectangleF Bounds + /// The bounds. + public override RectangleF CalculateBounds() { - get { return this.Path(null).GetBounds(); } + return this.Path(null).GetBounds(); } /// diff --git a/Source/Basic Shapes/SvgImage.cs b/Source/Basic Shapes/SvgImage.cs index 6b4ddb9..4122288 100644 --- a/Source/Basic Shapes/SvgImage.cs +++ b/Source/Basic Shapes/SvgImage.cs @@ -76,21 +76,21 @@ namespace Svg { get { return this.Attributes.GetAttribute("href"); } set { this.Attributes["href"] = value; } - } - - - - /// - /// Gets the bounds of the element. - /// - /// The bounds. - public override RectangleF Bounds - { - get { return new RectangleF(this.Location.ToDeviceValue(null, this), - new SizeF(this.Width.ToDeviceValue(null, UnitRenderingType.Horizontal, this), - this.Height.ToDeviceValue(null, UnitRenderingType.Vertical, this))); } - } - + } + + + + /// + /// Gets the bounds of the element. + /// + /// The bounds. + public override RectangleF CalculateBounds() + { + return new RectangleF(this.Location.ToDeviceValue(null, this), + new SizeF(this.Width.ToDeviceValue(null, UnitRenderingType.Horizontal, this), + this.Height.ToDeviceValue(null, UnitRenderingType.Vertical, this))); + } + /// /// Gets the for this element. /// diff --git a/Source/Basic Shapes/SvgLine.cs b/Source/Basic Shapes/SvgLine.cs index 301a8de..809833f 100644 --- a/Source/Basic Shapes/SvgLine.cs +++ b/Source/Basic Shapes/SvgLine.cs @@ -171,9 +171,9 @@ namespace Svg return result; } - public override System.Drawing.RectangleF Bounds + public override RectangleF CalculateBounds() { - get { return this.Path(null).GetBounds(); } + return this.Path(null).GetBounds(); } public override SvgElement DeepCopy() diff --git a/Source/Basic Shapes/SvgPolygon.cs b/Source/Basic Shapes/SvgPolygon.cs index 4d5563b..e7d407e 100644 --- a/Source/Basic Shapes/SvgPolygon.cs +++ b/Source/Basic Shapes/SvgPolygon.cs @@ -130,9 +130,9 @@ namespace Svg return result; } - public override RectangleF Bounds + public override RectangleF CalculateBounds() { - get { return this.Path(null).GetBounds(); } + return this.Path(null).GetBounds(); } diff --git a/Source/Basic Shapes/SvgRectangle.cs b/Source/Basic Shapes/SvgRectangle.cs index c468556..08a7f00 100644 --- a/Source/Basic Shapes/SvgRectangle.cs +++ b/Source/Basic Shapes/SvgRectangle.cs @@ -165,10 +165,10 @@ namespace Svg /// /// Gets the bounds of the element. /// - /// The bounds. - public override RectangleF Bounds + /// The bounds. + public override RectangleF CalculateBounds() { - get { return Path(null).GetBounds(); } + return Path(null).GetBounds(); } /// diff --git a/Source/Basic Shapes/SvgVisualElement.cs b/Source/Basic Shapes/SvgVisualElement.cs index a1f87cb..8cd6cee 100644 --- a/Source/Basic Shapes/SvgVisualElement.cs +++ b/Source/Basic Shapes/SvgVisualElement.cs @@ -19,27 +19,11 @@ namespace Svg /// public abstract GraphicsPath Path(ISvgRenderer renderer); - PointF ISvgBoundable.Location - { - get - { - return Bounds.Location; - } - } - - SizeF ISvgBoundable.Size - { - get - { - return Bounds.Size; - } - } - /// /// Gets the bounds of the element. /// - /// The bounds. - public abstract RectangleF Bounds { get; } + /// The bounds. + public abstract RectangleF CalculateBounds(); /// /// Gets the associated if one has been specified. diff --git a/Source/DataTypes/SvgUnit.cs b/Source/DataTypes/SvgUnit.cs index f5a8f12..d98fa79 100644 --- a/Source/DataTypes/SvgUnit.cs +++ b/Source/DataTypes/SvgUnit.cs @@ -149,7 +149,7 @@ namespace Svg break; } - System.Drawing.SizeF size = boundable.Bounds.Size; + System.Drawing.SizeF size = boundable.CalculateBounds().Size; switch (renderType) { @@ -157,13 +157,13 @@ namespace Svg _deviceValue = (size.Width / 100) * value; break; case UnitRenderingType.HorizontalOffset: - _deviceValue = (size.Width / 100) * value + boundable.Location.X; + _deviceValue = (size.Width / 100) * value + boundable.CalculateBounds().Location.X; break; case UnitRenderingType.Vertical: _deviceValue = (size.Height / 100) * value; break; case UnitRenderingType.VerticalOffset: - _deviceValue = (size.Height / 100) * value + boundable.Location.Y; + _deviceValue = (size.Height / 100) * value + boundable.CalculateBounds().Location.Y; break; default: _deviceValue = (float)(Math.Sqrt(Math.Pow(size.Width, 2) + Math.Pow(size.Height, 2)) / Math.Sqrt(2) * value / 100.0); diff --git a/Source/Document Structure/SvgFragment.cs b/Source/Document Structure/SvgFragment.cs index 6233669..70e6215 100644 --- a/Source/Document Structure/SvgFragment.cs +++ b/Source/Document Structure/SvgFragment.cs @@ -15,28 +15,9 @@ namespace Svg /// public static readonly Uri Namespace = new Uri("http://www.w3.org/2000/svg"); - PointF ISvgBoundable.Location + RectangleF ISvgBoundable.CalculateBounds() { - get - { - return PointF.Empty; - } - } - - SizeF ISvgBoundable.Size - { - get - { - return GetDimensions(); - } - } - - RectangleF ISvgBoundable.Bounds - { - get - { - return new RectangleF(((ISvgBoundable)this).Location, ((ISvgBoundable)this).Size); - } + return new RectangleF(PointF.Empty, GetDimensions()); } private SvgUnit _x; @@ -185,32 +166,29 @@ namespace Svg break; } } - + /// /// Gets the for this element. /// /// - public GraphicsPath Path + public GraphicsPath CreatePath() { - get - { - var path = new GraphicsPath(); + var path = new GraphicsPath(); - AddPaths(this, path); - - return path; - } + AddPaths(this, path); + + return path; } - + /// /// Gets the bounds of the svg element. /// - /// The bounds. - public RectangleF Bounds - { - get + /// The bounds. + public RectangleF CalculateBounds() + { + using (var path = CreatePath()) { - return this.Path.GetBounds(); + return path.GetBounds(); } } @@ -242,7 +220,7 @@ namespace Svg } else { - bounds = this.Bounds; //do just one call to the recursive bounds property + bounds = this.CalculateBounds(); //do just one call to the expensive bounds calculation method } } diff --git a/Source/Document Structure/SvgGroup.cs b/Source/Document Structure/SvgGroup.cs index 63889c6..2c63822 100644 --- a/Source/Document Structure/SvgGroup.cs +++ b/Source/Document Structure/SvgGroup.cs @@ -21,35 +21,32 @@ namespace Svg /// /// Gets the bounds of the element. /// - /// The bounds. - public override System.Drawing.RectangleF Bounds + /// The bounds. + public override RectangleF CalculateBounds() { - get - { - var r = new RectangleF(); - foreach(var c in this.Children) + var r = new RectangleF(); + foreach (var c in this.Children) + { + if (c is SvgVisualElement) { - if (c is SvgVisualElement) + // First it should check if rectangle is empty or it will return the wrong Bounds. + // This is because when the Rectangle is Empty, the Union method adds as if the first values where X=0, Y=0 + if (r.IsEmpty) { - // First it should check if rectangle is empty or it will return the wrong Bounds. - // This is because when the Rectangle is Empty, the Union method adds as if the first values where X=0, Y=0 - if (r.IsEmpty) - { - r = ((SvgVisualElement)c).Bounds; - } - else + r = ((SvgVisualElement) c).CalculateBounds(); + } + else + { + var childBounds = ((SvgVisualElement) c).CalculateBounds(); + if (!childBounds.IsEmpty) { - var childBounds = ((SvgVisualElement)c).Bounds; - if (!childBounds.IsEmpty) - { - r = RectangleF.Union(r, childBounds); - } + r = RectangleF.Union(r, childBounds); } } } - - return r; } + + return r; } protected override bool Renderable { get { return false; } } diff --git a/Source/Document Structure/SvgSwitch.cs b/Source/Document Structure/SvgSwitch.cs index d07dabb..beab5c0 100644 --- a/Source/Document Structure/SvgSwitch.cs +++ b/Source/Document Structure/SvgSwitch.cs @@ -25,35 +25,32 @@ namespace Svg /// /// Gets the bounds of the element. /// - /// The bounds. - public override System.Drawing.RectangleF Bounds + /// The bounds. + public override RectangleF CalculateBounds() { - get + var r = new RectangleF(); + foreach (var c in this.Children) { - var r = new RectangleF(); - foreach (var c in this.Children) + if (c is SvgVisualElement) { - if (c is SvgVisualElement) + // First it should check if rectangle is empty or it will return the wrong Bounds. + // This is because when the Rectangle is Empty, the Union method adds as if the first values where X=0, Y=0 + if (r.IsEmpty) { - // First it should check if rectangle is empty or it will return the wrong Bounds. - // This is because when the Rectangle is Empty, the Union method adds as if the first values where X=0, Y=0 - if (r.IsEmpty) - { - r = ((SvgVisualElement)c).Bounds; - } - else + r = ((SvgVisualElement) c).CalculateBounds(); + } + else + { + var childBounds = ((SvgVisualElement) c).CalculateBounds(); + if (!childBounds.IsEmpty) { - var childBounds = ((SvgVisualElement)c).Bounds; - if (!childBounds.IsEmpty) - { - r = RectangleF.Union(r, childBounds); - } + r = RectangleF.Union(r, childBounds); } } } - - return r; } + + return r; } /// diff --git a/Source/Document Structure/SvgSymbol.cs b/Source/Document Structure/SvgSymbol.cs index 97661f9..3211fe9 100644 --- a/Source/Document Structure/SvgSymbol.cs +++ b/Source/Document Structure/SvgSymbol.cs @@ -48,34 +48,31 @@ namespace Svg.Document_Structure /// Gets the bounds of the element. /// /// The bounds. - public override System.Drawing.RectangleF Bounds + public override System.Drawing.RectangleF CalculateBounds() { - get + var r = new RectangleF(); + foreach (var c in this.Children) { - var r = new RectangleF(); - foreach (var c in this.Children) + if (c is SvgVisualElement) { - if (c is SvgVisualElement) + // First it should check if rectangle is empty or it will return the wrong Bounds. + // This is because when the Rectangle is Empty, the Union method adds as if the first values where X=0, Y=0 + if (r.IsEmpty) { - // First it should check if rectangle is empty or it will return the wrong Bounds. - // This is because when the Rectangle is Empty, the Union method adds as if the first values where X=0, Y=0 - if (r.IsEmpty) - { - r = ((SvgVisualElement)c).Bounds; - } - else + r = ((SvgVisualElement)c).CalculateBounds(); + } + else + { + var childBounds = ((SvgVisualElement)c).CalculateBounds(); + if (!childBounds.IsEmpty) { - var childBounds = ((SvgVisualElement)c).Bounds; - if (!childBounds.IsEmpty) - { - r = RectangleF.Union(r, childBounds); - } + r = RectangleF.Union(r, childBounds); } } } - - return r; } + + return r; } protected override bool Renderable { get { return false; } } diff --git a/Source/Document Structure/SvgUse.cs b/Source/Document Structure/SvgUse.cs index 3ed957d..487c352 100644 --- a/Source/Document Structure/SvgUse.cs +++ b/Source/Document Structure/SvgUse.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Drawing; using System.Text; using System.Web; using System.Xml; @@ -61,9 +62,9 @@ namespace Svg return (element != null) ? element.Path(renderer) : null; } - public override System.Drawing.RectangleF Bounds + public override RectangleF CalculateBounds() { - get { return new System.Drawing.RectangleF(); } + return new System.Drawing.RectangleF(); } protected override bool Renderable { get { return false; } } diff --git a/Source/Extensibility/SvgForeignObject.cs b/Source/Extensibility/SvgForeignObject.cs index dd19031..84a98ea 100644 --- a/Source/Extensibility/SvgForeignObject.cs +++ b/Source/Extensibility/SvgForeignObject.cs @@ -25,35 +25,32 @@ namespace Svg /// /// Gets the bounds of the element. /// - /// The bounds. - public override System.Drawing.RectangleF Bounds + /// The bounds. + public override RectangleF CalculateBounds() { - get + var r = new RectangleF(); + foreach (var c in this.Children) { - var r = new RectangleF(); - foreach (var c in this.Children) + if (c is SvgVisualElement) { - if (c is SvgVisualElement) + // First it should check if rectangle is empty or it will return the wrong Bounds. + // This is because when the Rectangle is Empty, the Union method adds as if the first values where X=0, Y=0 + if (r.IsEmpty) { - // First it should check if rectangle is empty or it will return the wrong Bounds. - // This is because when the Rectangle is Empty, the Union method adds as if the first values where X=0, Y=0 - if (r.IsEmpty) - { - r = ((SvgVisualElement)c).Bounds; - } - else + r = ((SvgVisualElement) c).CalculateBounds(); + } + else + { + var childBounds = ((SvgVisualElement) c).CalculateBounds(); + if (!childBounds.IsEmpty) { - var childBounds = ((SvgVisualElement)c).Bounds; - if (!childBounds.IsEmpty) - { - r = RectangleF.Union(r, childBounds); - } + r = RectangleF.Union(r, childBounds); } } } - - return r; } + + return r; } protected override bool Renderable { get { return false; } } diff --git a/Source/Painting/GenericBoundable.cs b/Source/Painting/GenericBoundable.cs index 5073d9d..8f52527 100644 --- a/Source/Painting/GenericBoundable.cs +++ b/Source/Painting/GenericBoundable.cs @@ -19,19 +19,9 @@ namespace Svg _rect = new RectangleF(x, y, width, height); } - public System.Drawing.PointF Location + public RectangleF CalculateBounds() { - get { return _rect.Location; } - } - - public System.Drawing.SizeF Size - { - get { return _rect.Size; } - } - - public System.Drawing.RectangleF Bounds - { - get { return _rect; } + return _rect; } } } diff --git a/Source/Painting/ISvgBoundable.cs b/Source/Painting/ISvgBoundable.cs index 7bbb609..1d4917b 100644 --- a/Source/Painting/ISvgBoundable.cs +++ b/Source/Painting/ISvgBoundable.cs @@ -4,19 +4,6 @@ namespace Svg { public interface ISvgBoundable { - PointF Location - { - get; - } - - SizeF Size - { - get; - } - - RectangleF Bounds - { - get; - } + RectangleF CalculateBounds(); } } \ No newline at end of file diff --git a/Source/Painting/ImmutableBoundable.cs b/Source/Painting/ImmutableBoundable.cs new file mode 100644 index 0000000..8c2a1ef --- /dev/null +++ b/Source/Painting/ImmutableBoundable.cs @@ -0,0 +1,19 @@ +using System.Drawing; + +namespace Svg +{ + internal sealed class ImmutableBoundable : ISvgBoundable + { + private readonly RectangleF bounds; + + public ImmutableBoundable(ISvgBoundable boundable) + { + bounds = boundable.CalculateBounds(); + } + + public RectangleF CalculateBounds() + { + return bounds; + } + } +} \ No newline at end of file diff --git a/Source/Painting/SvgGradientServer.cs b/Source/Painting/SvgGradientServer.cs index 37a1179..a142e77 100644 --- a/Source/Painting/SvgGradientServer.cs +++ b/Source/Painting/SvgGradientServer.cs @@ -178,7 +178,7 @@ namespace Svg for (int i = 0; i < colourBlends; i++) { var currentStop = this.Stops[radial ? this.Stops.Count - 1 - actualStops : actualStops]; - var boundWidth = renderer.GetBoundable().Bounds.Width; + var boundWidth = renderer.GetBoundable().CalculateBounds().Width; mergedOpacity = opacity * currentStop.GetOpacity(); position = diff --git a/Source/Painting/SvgLinearGradientServer.cs b/Source/Painting/SvgLinearGradientServer.cs index e373aae..45f8577 100644 --- a/Source/Painting/SvgLinearGradientServer.cs +++ b/Source/Painting/SvgLinearGradientServer.cs @@ -191,7 +191,7 @@ namespace Svg private LinePoints PointsToMove(ISvgBoundable boundable, PointF specifiedStart, PointF specifiedEnd) { - var bounds = boundable.Bounds; + var bounds = boundable.CalculateBounds(); if (specifiedStart.X == specifiedEnd.X) { return (bounds.Top < specifiedStart.Y && specifiedStart.Y < bounds.Bottom ? LinePoints.Start : LinePoints.None) | @@ -227,7 +227,7 @@ namespace Svg return new GradientPoints(specifiedStart, specifiedEnd); } - var bounds = boundable.Bounds; + var bounds = boundable.CalculateBounds(); var effectiveStart = specifiedStart; var effectiveEnd = specifiedEnd; var intersectionPoints = CandidateIntersections(bounds, specifiedStart, specifiedEnd); diff --git a/Source/Painting/SvgMarker.cs b/Source/Painting/SvgMarker.cs index dac9f1c..4580755 100644 --- a/Source/Painting/SvgMarker.cs +++ b/Source/Painting/SvgMarker.cs @@ -95,15 +95,12 @@ namespace Svg return null; } - public override System.Drawing.RectangleF Bounds + public override RectangleF CalculateBounds() { - get - { - var path = this.Path(null); - if (path != null) - return path.GetBounds(); - return new System.Drawing.RectangleF(); - } + var path = this.Path(null); + if (path != null) + return path.GetBounds(); + return new System.Drawing.RectangleF(); } public override SvgElement DeepCopy() diff --git a/Source/Painting/SvgRadialGradientServer.cs b/Source/Painting/SvgRadialGradientServer.cs index 981a51f..c88b9a4 100644 --- a/Source/Painting/SvgRadialGradientServer.cs +++ b/Source/Painting/SvgRadialGradientServer.cs @@ -127,7 +127,7 @@ namespace Svg using (var transform = EffectiveGradientTransform) { - var bounds = renderer.GetBoundable().Bounds; + var bounds = renderer.GetBoundable().CalculateBounds(); transform.Translate(bounds.X, bounds.Y, MatrixOrder.Prepend); if (this.GradientUnits == SvgCoordinateUnits.ObjectBoundingBox) { diff --git a/Source/Paths/SvgPath.cs b/Source/Paths/SvgPath.cs index cb0858f..d793a54 100644 --- a/Source/Paths/SvgPath.cs +++ b/Source/Paths/SvgPath.cs @@ -114,10 +114,10 @@ namespace Svg /// /// Gets the bounds of the element. /// - /// The bounds. - public override System.Drawing.RectangleF Bounds + /// The bounds. + public override RectangleF CalculateBounds() { - get { return this.Path(null).GetBounds(); } + return this.Path(null).GetBounds(); } /// diff --git a/Source/Rendering/SvgRenderer.cs b/Source/Rendering/SvgRenderer.cs index 6d5fbde..f27ba40 100644 --- a/Source/Rendering/SvgRenderer.cs +++ b/Source/Rendering/SvgRenderer.cs @@ -18,7 +18,7 @@ namespace Svg public void SetBoundable(ISvgBoundable boundable) { - _boundables.Push(boundable); + _boundables.Push(new ImmutableBoundable(boundable)); } public ISvgBoundable GetBoundable() { diff --git a/Source/Svg.csproj b/Source/Svg.csproj index ea132a1..bde727d 100644 --- a/Source/Svg.csproj +++ b/Source/Svg.csproj @@ -109,6 +109,7 @@ + diff --git a/Source/SvgElement.cs b/Source/SvgElement.cs index b1dee4d..c91870c 100644 --- a/Source/SvgElement.cs +++ b/Source/SvgElement.cs @@ -1162,4 +1162,4 @@ namespace Svg void Render(ISvgRenderer renderer); } -} \ No newline at end of file +} diff --git a/Source/Text/SvgGlyph.cs b/Source/Text/SvgGlyph.cs index bd1045b..7418102 100644 --- a/Source/Text/SvgGlyph.cs +++ b/Source/Text/SvgGlyph.cs @@ -91,10 +91,10 @@ namespace Svg /// /// Gets the bounds of the element. /// - /// The bounds. - public override System.Drawing.RectangleF Bounds + /// The bounds. + public override System.Drawing.RectangleF CalculateBounds() { - get { return this.Path(null).GetBounds(); } + return this.Path(null).GetBounds(); } /// diff --git a/Source/Text/SvgTextBase.cs b/Source/Text/SvgTextBase.cs index 83df4de..1020e98 100644 --- a/Source/Text/SvgTextBase.cs +++ b/Source/Text/SvgTextBase.cs @@ -227,18 +227,15 @@ namespace Svg /// /// Gets the bounds of the element. /// - /// The bounds. - public override System.Drawing.RectangleF Bounds + /// The bounds. + public override RectangleF CalculateBounds() { - get + var path = this.Path(null); + foreach (var elem in this.Children.OfType()) { - var path = this.Path(null); - foreach (var elem in this.Children.OfType()) - { - path.AddPath(elem.Path(null), false); - } - return path.GetBounds(); + path.AddPath(elem.Path(null), false); } + return path.GetBounds(); } /// @@ -495,19 +492,9 @@ namespace Svg _width = width; } - public PointF Location - { - get { return PointF.Empty; } - } - - public SizeF Size - { - get { return new SizeF(_width, _font.Size); } - } - - public RectangleF Bounds + public RectangleF CalculateBounds() { - get { return new RectangleF(this.Location, this.Size); } + return new RectangleF(PointF.Empty, new SizeF(_width, _font.Size)); } } -- GitLab