Commit 13132300 authored by Tebjan Halm's avatar Tebjan Halm
Browse files

Merge pull request #97 from articulate/BoundsPerformance

Performance Improvement
parents a653b4a4 1b8cb43f
...@@ -78,10 +78,10 @@ namespace Svg ...@@ -78,10 +78,10 @@ namespace Svg
/// <summary> /// <summary>
/// Gets the bounds of the circle. /// Gets the bounds of the circle.
/// </summary> /// </summary>
/// <value>The rectangular bounds of the circle.</value> /// <returns>The rectangular bounds of the circle.</returns>
public override RectangleF Bounds public override RectangleF CalculateBounds()
{ {
get { return this.Path(null).GetBounds(); } return this.Path(null).GetBounds();
} }
/// <summary> /// <summary>
......
...@@ -92,10 +92,10 @@ namespace Svg ...@@ -92,10 +92,10 @@ namespace Svg
/// <summary> /// <summary>
/// Gets the bounds of the element. /// Gets the bounds of the element.
/// </summary> /// </summary>
/// <value>The bounds.</value> /// <returns>The bounds.</returns>
public override RectangleF Bounds public override RectangleF CalculateBounds()
{ {
get { return this.Path(null).GetBounds(); } return this.Path(null).GetBounds();
} }
/// <summary> /// <summary>
......
...@@ -83,12 +83,12 @@ namespace Svg ...@@ -83,12 +83,12 @@ namespace Svg
/// <summary> /// <summary>
/// Gets the bounds of the element. /// Gets the bounds of the element.
/// </summary> /// </summary>
/// <value>The bounds.</value> /// <returns>The bounds.</returns>
public override RectangleF Bounds public override RectangleF CalculateBounds()
{ {
get { return new RectangleF(this.Location.ToDeviceValue(null, this), return new RectangleF(this.Location.ToDeviceValue(null, this),
new SizeF(this.Width.ToDeviceValue(null, UnitRenderingType.Horizontal, this), new SizeF(this.Width.ToDeviceValue(null, UnitRenderingType.Horizontal, this),
this.Height.ToDeviceValue(null, UnitRenderingType.Vertical, this))); } this.Height.ToDeviceValue(null, UnitRenderingType.Vertical, this)));
} }
/// <summary> /// <summary>
......
...@@ -171,9 +171,9 @@ namespace Svg ...@@ -171,9 +171,9 @@ namespace Svg
return result; 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() public override SvgElement DeepCopy()
......
...@@ -130,9 +130,9 @@ namespace Svg ...@@ -130,9 +130,9 @@ namespace Svg
return result; return result;
} }
public override RectangleF Bounds public override RectangleF CalculateBounds()
{ {
get { return this.Path(null).GetBounds(); } return this.Path(null).GetBounds();
} }
......
...@@ -165,10 +165,10 @@ namespace Svg ...@@ -165,10 +165,10 @@ namespace Svg
/// <summary> /// <summary>
/// Gets the bounds of the element. /// Gets the bounds of the element.
/// </summary> /// </summary>
/// <value>The bounds.</value> /// <returns>The bounds.</returns>
public override RectangleF Bounds public override RectangleF CalculateBounds()
{ {
get { return Path(null).GetBounds(); } return Path(null).GetBounds();
} }
/// <summary> /// <summary>
......
...@@ -19,27 +19,11 @@ namespace Svg ...@@ -19,27 +19,11 @@ namespace Svg
/// </summary> /// </summary>
public abstract GraphicsPath Path(ISvgRenderer renderer); public abstract GraphicsPath Path(ISvgRenderer renderer);
PointF ISvgBoundable.Location
{
get
{
return Bounds.Location;
}
}
SizeF ISvgBoundable.Size
{
get
{
return Bounds.Size;
}
}
/// <summary> /// <summary>
/// Gets the bounds of the element. /// Gets the bounds of the element.
/// </summary> /// </summary>
/// <value>The bounds.</value> /// <returns>The bounds.</returns>
public abstract RectangleF Bounds { get; } public abstract RectangleF CalculateBounds();
/// <summary> /// <summary>
/// Gets the associated <see cref="SvgClipPath"/> if one has been specified. /// Gets the associated <see cref="SvgClipPath"/> if one has been specified.
......
...@@ -149,7 +149,7 @@ namespace Svg ...@@ -149,7 +149,7 @@ namespace Svg
break; break;
} }
System.Drawing.SizeF size = boundable.Bounds.Size; System.Drawing.SizeF size = boundable.CalculateBounds().Size;
switch (renderType) switch (renderType)
{ {
...@@ -157,13 +157,13 @@ namespace Svg ...@@ -157,13 +157,13 @@ namespace Svg
_deviceValue = (size.Width / 100) * value; _deviceValue = (size.Width / 100) * value;
break; break;
case UnitRenderingType.HorizontalOffset: case UnitRenderingType.HorizontalOffset:
_deviceValue = (size.Width / 100) * value + boundable.Location.X; _deviceValue = (size.Width / 100) * value + boundable.CalculateBounds().Location.X;
break; break;
case UnitRenderingType.Vertical: case UnitRenderingType.Vertical:
_deviceValue = (size.Height / 100) * value; _deviceValue = (size.Height / 100) * value;
break; break;
case UnitRenderingType.VerticalOffset: case UnitRenderingType.VerticalOffset:
_deviceValue = (size.Height / 100) * value + boundable.Location.Y; _deviceValue = (size.Height / 100) * value + boundable.CalculateBounds().Location.Y;
break; break;
default: default:
_deviceValue = (float)(Math.Sqrt(Math.Pow(size.Width, 2) + Math.Pow(size.Height, 2)) / Math.Sqrt(2) * value / 100.0); _deviceValue = (float)(Math.Sqrt(Math.Pow(size.Width, 2) + Math.Pow(size.Height, 2)) / Math.Sqrt(2) * value / 100.0);
......
...@@ -15,28 +15,9 @@ namespace Svg ...@@ -15,28 +15,9 @@ namespace Svg
/// </summary> /// </summary>
public static readonly Uri Namespace = new Uri("http://www.w3.org/2000/svg"); public static readonly Uri Namespace = new Uri("http://www.w3.org/2000/svg");
PointF ISvgBoundable.Location RectangleF ISvgBoundable.CalculateBounds()
{ {
get return new RectangleF(PointF.Empty, GetDimensions());
{
return PointF.Empty;
}
}
SizeF ISvgBoundable.Size
{
get
{
return GetDimensions();
}
}
RectangleF ISvgBoundable.Bounds
{
get
{
return new RectangleF(((ISvgBoundable)this).Location, ((ISvgBoundable)this).Size);
}
} }
private SvgUnit _x; private SvgUnit _x;
...@@ -190,9 +171,7 @@ namespace Svg ...@@ -190,9 +171,7 @@ namespace Svg
/// Gets the <see cref="GraphicsPath"/> for this element. /// Gets the <see cref="GraphicsPath"/> for this element.
/// </summary> /// </summary>
/// <value></value> /// <value></value>
public GraphicsPath Path public GraphicsPath CreatePath()
{
get
{ {
var path = new GraphicsPath(); var path = new GraphicsPath();
...@@ -200,17 +179,16 @@ namespace Svg ...@@ -200,17 +179,16 @@ namespace Svg
return path; return path;
} }
}
/// <summary> /// <summary>
/// Gets the bounds of the svg element. /// Gets the bounds of the svg element.
/// </summary> /// </summary>
/// <value>The bounds.</value> /// <returns>The bounds.</returns>
public RectangleF Bounds public RectangleF CalculateBounds()
{ {
get using (var path = CreatePath())
{ {
return this.Path.GetBounds(); return path.GetBounds();
} }
} }
...@@ -242,7 +220,7 @@ namespace Svg ...@@ -242,7 +220,7 @@ namespace Svg
} }
else 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
} }
} }
......
...@@ -21,13 +21,11 @@ namespace Svg ...@@ -21,13 +21,11 @@ namespace Svg
/// <summary> /// <summary>
/// Gets the bounds of the element. /// Gets the bounds of the element.
/// </summary> /// </summary>
/// <value>The bounds.</value> /// <returns>The bounds.</returns>
public override System.Drawing.RectangleF Bounds public override RectangleF CalculateBounds()
{
get
{ {
var r = new RectangleF(); var r = new RectangleF();
foreach(var c in this.Children) foreach (var c in this.Children)
{ {
if (c is SvgVisualElement) if (c is SvgVisualElement)
{ {
...@@ -35,11 +33,11 @@ namespace Svg ...@@ -35,11 +33,11 @@ namespace Svg
// This is because when the Rectangle is Empty, the Union method adds as if the first values where X=0, Y=0 // 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) if (r.IsEmpty)
{ {
r = ((SvgVisualElement)c).Bounds; r = ((SvgVisualElement) c).CalculateBounds();
} }
else else
{ {
var childBounds = ((SvgVisualElement)c).Bounds; var childBounds = ((SvgVisualElement) c).CalculateBounds();
if (!childBounds.IsEmpty) if (!childBounds.IsEmpty)
{ {
r = RectangleF.Union(r, childBounds); r = RectangleF.Union(r, childBounds);
...@@ -50,7 +48,6 @@ namespace Svg ...@@ -50,7 +48,6 @@ namespace Svg
return r; return r;
} }
}
protected override bool Renderable { get { return false; } } protected override bool Renderable { get { return false; } }
......
...@@ -25,10 +25,8 @@ namespace Svg ...@@ -25,10 +25,8 @@ namespace Svg
/// <summary> /// <summary>
/// Gets the bounds of the element. /// Gets the bounds of the element.
/// </summary> /// </summary>
/// <value>The bounds.</value> /// <returns>The bounds.</returns>
public override System.Drawing.RectangleF Bounds public override RectangleF CalculateBounds()
{
get
{ {
var r = new RectangleF(); var r = new RectangleF();
foreach (var c in this.Children) foreach (var c in this.Children)
...@@ -39,11 +37,11 @@ namespace Svg ...@@ -39,11 +37,11 @@ namespace Svg
// This is because when the Rectangle is Empty, the Union method adds as if the first values where X=0, Y=0 // 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) if (r.IsEmpty)
{ {
r = ((SvgVisualElement)c).Bounds; r = ((SvgVisualElement) c).CalculateBounds();
} }
else else
{ {
var childBounds = ((SvgVisualElement)c).Bounds; var childBounds = ((SvgVisualElement) c).CalculateBounds();
if (!childBounds.IsEmpty) if (!childBounds.IsEmpty)
{ {
r = RectangleF.Union(r, childBounds); r = RectangleF.Union(r, childBounds);
...@@ -54,7 +52,6 @@ namespace Svg ...@@ -54,7 +52,6 @@ namespace Svg
return r; return r;
} }
}
/// <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="Graphics"/> object.
......
...@@ -48,9 +48,7 @@ namespace Svg.Document_Structure ...@@ -48,9 +48,7 @@ namespace Svg.Document_Structure
/// Gets the bounds of the element. /// Gets the bounds of the element.
/// </summary> /// </summary>
/// <value>The bounds.</value> /// <value>The bounds.</value>
public override System.Drawing.RectangleF Bounds public override System.Drawing.RectangleF CalculateBounds()
{
get
{ {
var r = new RectangleF(); var r = new RectangleF();
foreach (var c in this.Children) foreach (var c in this.Children)
...@@ -61,11 +59,11 @@ namespace Svg.Document_Structure ...@@ -61,11 +59,11 @@ namespace Svg.Document_Structure
// This is because when the Rectangle is Empty, the Union method adds as if the first values where X=0, Y=0 // 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) if (r.IsEmpty)
{ {
r = ((SvgVisualElement)c).Bounds; r = ((SvgVisualElement)c).CalculateBounds();
} }
else else
{ {
var childBounds = ((SvgVisualElement)c).Bounds; var childBounds = ((SvgVisualElement)c).CalculateBounds();
if (!childBounds.IsEmpty) if (!childBounds.IsEmpty)
{ {
r = RectangleF.Union(r, childBounds); r = RectangleF.Union(r, childBounds);
...@@ -76,7 +74,6 @@ namespace Svg.Document_Structure ...@@ -76,7 +74,6 @@ namespace Svg.Document_Structure
return r; return r;
} }
}
protected override bool Renderable { get { return false; } } protected override bool Renderable { get { return false; } }
......
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing;
using System.Text; using System.Text;
using System.Web; using System.Web;
using System.Xml; using System.Xml;
...@@ -61,9 +62,9 @@ namespace Svg ...@@ -61,9 +62,9 @@ namespace Svg
return (element != null) ? element.Path(renderer) : null; 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; } } protected override bool Renderable { get { return false; } }
......
...@@ -25,10 +25,8 @@ namespace Svg ...@@ -25,10 +25,8 @@ namespace Svg
/// <summary> /// <summary>
/// Gets the bounds of the element. /// Gets the bounds of the element.
/// </summary> /// </summary>
/// <value>The bounds.</value> /// <returns>The bounds.</returns>
public override System.Drawing.RectangleF Bounds public override RectangleF CalculateBounds()
{
get
{ {
var r = new RectangleF(); var r = new RectangleF();
foreach (var c in this.Children) foreach (var c in this.Children)
...@@ -39,11 +37,11 @@ namespace Svg ...@@ -39,11 +37,11 @@ namespace Svg
// This is because when the Rectangle is Empty, the Union method adds as if the first values where X=0, Y=0 // 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) if (r.IsEmpty)
{ {
r = ((SvgVisualElement)c).Bounds; r = ((SvgVisualElement) c).CalculateBounds();
} }
else else
{ {
var childBounds = ((SvgVisualElement)c).Bounds; var childBounds = ((SvgVisualElement) c).CalculateBounds();
if (!childBounds.IsEmpty) if (!childBounds.IsEmpty)
{ {
r = RectangleF.Union(r, childBounds); r = RectangleF.Union(r, childBounds);
...@@ -54,7 +52,6 @@ namespace Svg ...@@ -54,7 +52,6 @@ namespace Svg
return r; return r;
} }
}
protected override bool Renderable { get { return false; } } protected override bool Renderable { get { return false; } }
......
...@@ -19,19 +19,9 @@ namespace Svg ...@@ -19,19 +19,9 @@ namespace Svg
_rect = new RectangleF(x, y, width, height); _rect = new RectangleF(x, y, width, height);
} }
public System.Drawing.PointF Location public RectangleF CalculateBounds()
{ {
get { return _rect.Location; } return _rect;
}
public System.Drawing.SizeF Size
{
get { return _rect.Size; }
}
public System.Drawing.RectangleF Bounds
{
get { return _rect; }
} }
} }
} }
...@@ -4,19 +4,6 @@ namespace Svg ...@@ -4,19 +4,6 @@ namespace Svg
{ {
public interface ISvgBoundable public interface ISvgBoundable
{ {
PointF Location RectangleF CalculateBounds();
{
get;
}
SizeF Size
{
get;
}
RectangleF Bounds
{
get;
}
} }
} }
\ No newline at end of file
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
...@@ -178,7 +178,7 @@ namespace Svg ...@@ -178,7 +178,7 @@ namespace Svg
for (int i = 0; i < colourBlends; i++) for (int i = 0; i < colourBlends; i++)
{ {
var currentStop = this.Stops[radial ? this.Stops.Count - 1 - actualStops : actualStops]; 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(); mergedOpacity = opacity * currentStop.GetOpacity();
position = position =
......
...@@ -191,7 +191,7 @@ namespace Svg ...@@ -191,7 +191,7 @@ namespace Svg
private LinePoints PointsToMove(ISvgBoundable boundable, PointF specifiedStart, PointF specifiedEnd) private LinePoints PointsToMove(ISvgBoundable boundable, PointF specifiedStart, PointF specifiedEnd)
{ {
var bounds = boundable.Bounds; var bounds = boundable.CalculateBounds();
if (specifiedStart.X == specifiedEnd.X) if (specifiedStart.X == specifiedEnd.X)
{ {
return (bounds.Top < specifiedStart.Y && specifiedStart.Y < bounds.Bottom ? LinePoints.Start : LinePoints.None) | return (bounds.Top < specifiedStart.Y && specifiedStart.Y < bounds.Bottom ? LinePoints.Start : LinePoints.None) |
...@@ -227,7 +227,7 @@ namespace Svg ...@@ -227,7 +227,7 @@ namespace Svg
return new GradientPoints(specifiedStart, specifiedEnd); return new GradientPoints(specifiedStart, specifiedEnd);
} }
var bounds = boundable.Bounds; var bounds = boundable.CalculateBounds();
var effectiveStart = specifiedStart; var effectiveStart = specifiedStart;
var effectiveEnd = specifiedEnd; var effectiveEnd = specifiedEnd;
var intersectionPoints = CandidateIntersections(bounds, specifiedStart, specifiedEnd); var intersectionPoints = CandidateIntersections(bounds, specifiedStart, specifiedEnd);
......
...@@ -95,16 +95,13 @@ namespace Svg ...@@ -95,16 +95,13 @@ namespace Svg
return null; return null;
} }
public override System.Drawing.RectangleF Bounds public override RectangleF CalculateBounds()
{
get
{ {
var path = this.Path(null); var path = this.Path(null);
if (path != null) if (path != null)
return path.GetBounds(); return path.GetBounds();
return new System.Drawing.RectangleF(); return new System.Drawing.RectangleF();
} }
}
public override SvgElement DeepCopy() public override SvgElement DeepCopy()
{ {
......
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