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
/// <summary>
/// Gets the bounds of the circle.
/// </summary>
/// <value>The rectangular bounds of the circle.</value>
public override RectangleF Bounds
/// <returns>The rectangular bounds of the circle.</returns>
public override RectangleF CalculateBounds()
{
get { return this.Path(null).GetBounds(); }
return this.Path(null).GetBounds();
}
/// <summary>
......
......@@ -92,10 +92,10 @@ namespace Svg
/// <summary>
/// Gets the bounds of the element.
/// </summary>
/// <value>The bounds.</value>
public override RectangleF Bounds
/// <returns>The bounds.</returns>
public override RectangleF CalculateBounds()
{
get { return this.Path(null).GetBounds(); }
return this.Path(null).GetBounds();
}
/// <summary>
......
......@@ -83,12 +83,12 @@ namespace Svg
/// <summary>
/// Gets the bounds of the element.
/// </summary>
/// <value>The bounds.</value>
public override RectangleF Bounds
/// <returns>The bounds.</returns>
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),
this.Height.ToDeviceValue(null, UnitRenderingType.Vertical, this))); }
this.Height.ToDeviceValue(null, UnitRenderingType.Vertical, this)));
}
/// <summary>
......
......@@ -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()
......
......@@ -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();
}
......
......@@ -165,10 +165,10 @@ namespace Svg
/// <summary>
/// Gets the bounds of the element.
/// </summary>
/// <value>The bounds.</value>
public override RectangleF Bounds
/// <returns>The bounds.</returns>
public override RectangleF CalculateBounds()
{
get { return Path(null).GetBounds(); }
return Path(null).GetBounds();
}
/// <summary>
......
......@@ -19,27 +19,11 @@ namespace Svg
/// </summary>
public abstract GraphicsPath Path(ISvgRenderer renderer);
PointF ISvgBoundable.Location
{
get
{
return Bounds.Location;
}
}
SizeF ISvgBoundable.Size
{
get
{
return Bounds.Size;
}
}
/// <summary>
/// Gets the bounds of the element.
/// </summary>
/// <value>The bounds.</value>
public abstract RectangleF Bounds { get; }
/// <returns>The bounds.</returns>
public abstract RectangleF CalculateBounds();
/// <summary>
/// Gets the associated <see cref="SvgClipPath"/> if one has been specified.
......
......@@ -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);
......
......@@ -15,28 +15,9 @@ namespace Svg
/// </summary>
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;
......@@ -190,9 +171,7 @@ namespace Svg
/// Gets the <see cref="GraphicsPath"/> for this element.
/// </summary>
/// <value></value>
public GraphicsPath Path
{
get
public GraphicsPath CreatePath()
{
var path = new GraphicsPath();
......@@ -200,17 +179,16 @@ namespace Svg
return path;
}
}
/// <summary>
/// Gets the bounds of the svg element.
/// </summary>
/// <value>The bounds.</value>
public RectangleF Bounds
/// <returns>The bounds.</returns>
public RectangleF CalculateBounds()
{
get
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
}
}
......
......@@ -21,13 +21,11 @@ namespace Svg
/// <summary>
/// Gets the bounds of the element.
/// </summary>
/// <value>The bounds.</value>
public override System.Drawing.RectangleF Bounds
{
get
/// <returns>The bounds.</returns>
public override RectangleF CalculateBounds()
{
var r = new RectangleF();
foreach(var c in this.Children)
foreach (var c in this.Children)
{
if (c is SvgVisualElement)
{
......@@ -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
if (r.IsEmpty)
{
r = ((SvgVisualElement)c).Bounds;
r = ((SvgVisualElement) c).CalculateBounds();
}
else
{
var childBounds = ((SvgVisualElement)c).Bounds;
var childBounds = ((SvgVisualElement) c).CalculateBounds();
if (!childBounds.IsEmpty)
{
r = RectangleF.Union(r, childBounds);
......@@ -50,7 +48,6 @@ namespace Svg
return r;
}
}
protected override bool Renderable { get { return false; } }
......
......@@ -25,10 +25,8 @@ namespace Svg
/// <summary>
/// Gets the bounds of the element.
/// </summary>
/// <value>The bounds.</value>
public override System.Drawing.RectangleF Bounds
{
get
/// <returns>The bounds.</returns>
public override RectangleF CalculateBounds()
{
var r = new RectangleF();
foreach (var c in this.Children)
......@@ -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
if (r.IsEmpty)
{
r = ((SvgVisualElement)c).Bounds;
r = ((SvgVisualElement) c).CalculateBounds();
}
else
{
var childBounds = ((SvgVisualElement)c).Bounds;
var childBounds = ((SvgVisualElement) c).CalculateBounds();
if (!childBounds.IsEmpty)
{
r = RectangleF.Union(r, childBounds);
......@@ -54,7 +52,6 @@ namespace Svg
return r;
}
}
/// <summary>
/// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object.
......
......@@ -48,9 +48,7 @@ namespace Svg.Document_Structure
/// Gets the bounds of the element.
/// </summary>
/// <value>The bounds.</value>
public override System.Drawing.RectangleF Bounds
{
get
public override System.Drawing.RectangleF CalculateBounds()
{
var r = new RectangleF();
foreach (var c in this.Children)
......@@ -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
if (r.IsEmpty)
{
r = ((SvgVisualElement)c).Bounds;
r = ((SvgVisualElement)c).CalculateBounds();
}
else
{
var childBounds = ((SvgVisualElement)c).Bounds;
var childBounds = ((SvgVisualElement)c).CalculateBounds();
if (!childBounds.IsEmpty)
{
r = RectangleF.Union(r, childBounds);
......@@ -76,7 +74,6 @@ namespace Svg.Document_Structure
return r;
}
}
protected override bool Renderable { get { return false; } }
......
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; } }
......
......@@ -25,10 +25,8 @@ namespace Svg
/// <summary>
/// Gets the bounds of the element.
/// </summary>
/// <value>The bounds.</value>
public override System.Drawing.RectangleF Bounds
{
get
/// <returns>The bounds.</returns>
public override RectangleF CalculateBounds()
{
var r = new RectangleF();
foreach (var c in this.Children)
......@@ -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
if (r.IsEmpty)
{
r = ((SvgVisualElement)c).Bounds;
r = ((SvgVisualElement) c).CalculateBounds();
}
else
{
var childBounds = ((SvgVisualElement)c).Bounds;
var childBounds = ((SvgVisualElement) c).CalculateBounds();
if (!childBounds.IsEmpty)
{
r = RectangleF.Union(r, childBounds);
......@@ -54,7 +52,6 @@ namespace Svg
return r;
}
}
protected override bool Renderable { get { return false; } }
......
......@@ -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;
}
}
}
......@@ -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
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
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 =
......
......@@ -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);
......
......@@ -95,16 +95,13 @@ namespace Svg
return null;
}
public override System.Drawing.RectangleF Bounds
{
get
public override RectangleF CalculateBounds()
{
var path = this.Path(null);
if (path != null)
return path.GetBounds();
return new System.Drawing.RectangleF();
}
}
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