Commit 0860e3de authored by Tebjan Halm's avatar Tebjan Halm Committed by GitHub
Browse files

Merge pull request #282 from mrbean-bremen/master

Add transform to bounds calculation in path based objects
parents f6622b55 3f1da2c7
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Xml;
using System.Web.UI.WebControls;
using System.ComponentModel;
namespace Svg namespace Svg
{ {
...@@ -13,7 +6,7 @@ namespace Svg ...@@ -13,7 +6,7 @@ namespace Svg
/// An SVG element to render circles to the document. /// An SVG element to render circles to the document.
/// </summary> /// </summary>
[SvgElement("circle")] [SvgElement("circle")]
public class SvgCircle : SvgVisualElement public class SvgCircle : SvgPathBasedElement
{ {
private GraphicsPath _path; private GraphicsPath _path;
...@@ -75,15 +68,6 @@ namespace Svg ...@@ -75,15 +68,6 @@ namespace Svg
} }
} }
/// <summary>
/// Gets the bounds of the circle.
/// </summary>
/// <value>The rectangular bounds of the circle.</value>
public override RectangleF Bounds
{
get { return this.Path(null).GetBounds(); }
}
/// <summary> /// <summary>
/// Gets the <see cref="GraphicsPath"/> representing this element. /// Gets the <see cref="GraphicsPath"/> representing this element.
/// </summary> /// </summary>
......
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Xml;
using System.ComponentModel;
namespace Svg namespace Svg
{ {
...@@ -12,7 +6,7 @@ namespace Svg ...@@ -12,7 +6,7 @@ namespace Svg
/// Represents and SVG ellipse element. /// Represents and SVG ellipse element.
/// </summary> /// </summary>
[SvgElement("ellipse")] [SvgElement("ellipse")]
public class SvgEllipse : SvgVisualElement public class SvgEllipse : SvgPathBasedElement
{ {
private SvgUnit _radiusX; private SvgUnit _radiusX;
private SvgUnit _radiusY; private SvgUnit _radiusY;
...@@ -80,15 +74,6 @@ namespace Svg ...@@ -80,15 +74,6 @@ namespace Svg
} }
} }
/// <summary>
/// Gets the bounds of the element.
/// </summary>
/// <value>The bounds.</value>
public override RectangleF Bounds
{
get { return this.Path(null).GetBounds(); }
}
/// <summary> /// <summary>
/// Gets the <see cref="GraphicsPath"/> for this element. /// Gets the <see cref="GraphicsPath"/> for this element.
/// </summary> /// </summary>
......
using System; using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using Svg.ExtensionMethods; using Svg.ExtensionMethods;
...@@ -12,7 +9,7 @@ namespace Svg ...@@ -12,7 +9,7 @@ namespace Svg
/// Represents and SVG line element. /// Represents and SVG line element.
/// </summary> /// </summary>
[SvgElement("line")] [SvgElement("line")]
public class SvgLine : SvgVisualElement public class SvgLine : SvgPathBasedElement
{ {
private SvgUnit _startX; private SvgUnit _startX;
private SvgUnit _startY; private SvgUnit _startY;
...@@ -186,11 +183,6 @@ namespace Svg ...@@ -186,11 +183,6 @@ namespace Svg
return result; return result;
} }
public override System.Drawing.RectangleF Bounds
{
get { return this.Path(null).GetBounds(); }
}
public override SvgElement DeepCopy() public override SvgElement DeepCopy()
{ {
return DeepCopy<SvgLine>(); return DeepCopy<SvgLine>();
......
using System.Drawing.Drawing2D;
namespace Svg
{
/// <summary>
/// Represents an element that is using a GraphicsPath as rendering base.
/// </summary>
public abstract class SvgPathBasedElement : SvgVisualElement
{
public override System.Drawing.RectangleF Bounds
{
get
{
var path = this.Path(null);
if (Transforms != null && Transforms.Count > 0)
{
path = (GraphicsPath)path.Clone();
path.Transform(Transforms.GetMatrix());
}
return path.GetBounds();
}
}
}
}
using System; using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Diagnostics; using System.Diagnostics;
using Svg.ExtensionMethods; using Svg.ExtensionMethods;
using Svg.Pathing;
namespace Svg namespace Svg
{ {
...@@ -13,7 +9,7 @@ namespace Svg ...@@ -13,7 +9,7 @@ namespace Svg
/// SvgPolygon defines a closed shape consisting of a set of connected straight line segments. /// SvgPolygon defines a closed shape consisting of a set of connected straight line segments.
/// </summary> /// </summary>
[SvgElement("polygon")] [SvgElement("polygon")]
public class SvgPolygon : SvgVisualElement public class SvgPolygon : SvgPathBasedElement
{ {
private GraphicsPath _path; private GraphicsPath _path;
...@@ -136,12 +132,6 @@ namespace Svg ...@@ -136,12 +132,6 @@ namespace Svg
return result; return result;
} }
public override RectangleF Bounds
{
get { return this.Path(null).GetBounds(); }
}
public override SvgElement DeepCopy() public override SvgElement DeepCopy()
{ {
return DeepCopy<SvgPolygon>(); return DeepCopy<SvgPolygon>();
......
using System; using System;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using Svg.Transforms;
namespace Svg namespace Svg
{ {
...@@ -9,7 +8,7 @@ namespace Svg ...@@ -9,7 +8,7 @@ namespace Svg
/// Represents an SVG rectangle that could also have rounded edges. /// Represents an SVG rectangle that could also have rounded edges.
/// </summary> /// </summary>
[SvgElement("rect")] [SvgElement("rect")]
public class SvgRectangle : SvgVisualElement public class SvgRectangle : SvgPathBasedElement
{ {
private SvgUnit _cornerRadiusX; private SvgUnit _cornerRadiusX;
private SvgUnit _cornerRadiusY; private SvgUnit _cornerRadiusY;
...@@ -168,15 +167,6 @@ namespace Svg ...@@ -168,15 +167,6 @@ namespace Svg
} }
} }
/// <summary>
/// Gets the bounds of the element.
/// </summary>
/// <value>The bounds.</value>
public override RectangleF Bounds
{
get { return Path(null).GetBounds(); }
}
/// <summary> /// <summary>
/// Gets the <see cref="GraphicsPath"/> for this element. /// Gets the <see cref="GraphicsPath"/> for this element.
/// </summary> /// </summary>
......
...@@ -89,6 +89,7 @@ ...@@ -89,6 +89,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Basic Shapes\SvgImage.cs" /> <Compile Include="Basic Shapes\SvgImage.cs" />
<Compile Include="Basic Shapes\SvgPathBasedElement.cs" />
<Compile Include="Basic Shapes\SvgVisualElement.cs" /> <Compile Include="Basic Shapes\SvgVisualElement.cs" />
<Compile Include="Basic Shapes\SvgCircle.cs" /> <Compile Include="Basic Shapes\SvgCircle.cs" />
<Compile Include="Basic Shapes\SvgEllipse.cs" /> <Compile Include="Basic Shapes\SvgEllipse.cs" />
......
using System; using System.Linq;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Svg.Pathing; using Svg.Pathing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
namespace Svg namespace Svg
{ {
[SvgElement("glyph")] [SvgElement("glyph")]
public class SvgGlyph : SvgVisualElement public class SvgGlyph : SvgPathBasedElement
{ {
private GraphicsPath _path; private GraphicsPath _path;
...@@ -79,15 +76,6 @@ namespace Svg ...@@ -79,15 +76,6 @@ namespace Svg
return _path; return _path;
} }
/// <summary>
/// Gets the bounds of the element.
/// </summary>
/// <value>The bounds.</value>
public override System.Drawing.RectangleF Bounds
{
get { return this.Path(null).GetBounds(); }
}
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="SvgGlyph"/> class. /// Initializes a new instance of the <see cref="SvgGlyph"/> class.
/// </summary> /// </summary>
......
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Drawing;
namespace Svg.UnitTests
{
/// <summary>
/// Test class to test bounds for elements without vs. with transformations
/// (see issue 281). Only some basic elements are tested - this should be sufficient
/// to verify the functionality for all path-based elements.
/// </summary>
[TestClass]
public class BoundsTests : SvgTestHelper
{
private const string BoundsTestSvg = "Issue281_Bounds.BoundsTest.svg";
private static SvgDocument testDocument;
[TestMethod]
public void TestLineBounds()
{
// x1="10" x2="30" y1="20" y2="40", default line thickness is 1
AssertEqualBounds("line", 9.5f, 19.5f, 21, 21);
// additional translation(5, 5)
AssertEqualBounds("line-xlate", 14.5f, 24.5f, 21, 21);
// additional rotation(180) and translation(-50, 0)
AssertEqualBounds("line-xform", 19.5f, -40.5f, 21, 21);
}
[TestMethod]
public void TestRectangleBounds()
{
// x="10" y="30" width="10" height="20"
AssertEqualBounds("rect", 9.5f, 29.5f, 10.5f, 20.5f);
// additional translation(10, 10)
AssertEqualBounds("rect-xlate", 19.5f, 39.5f, 10.5f, 20.5f);
// additional rotation(90)
AssertEqualBounds("rect-rot", -50, 9.5f, 20.5f, 10.5f);
}
[TestMethod]
public void TestGroupBounds()
{
// all lines from TestLineBounds()
AssertEqualBounds("lines", 9.5f, 29.5f, 10.5f, 20.5f);
// all reactangles from TestRectangleBounds()
AssertEqualBounds("rects", 19.5f, 39.5f, 10.5f, 20.5f);
}
private void AssertEqualBounds(string elementId, float x, float y, float width, float height)
{
const float Epsilon = 0.01f;
var element = GetElement(elementId);
var elementBounds = element.Bounds;
Assert.AreEqual(x, elementBounds.X, Epsilon);
Assert.AreEqual(y, elementBounds.Y, Epsilon);
Assert.AreEqual(width, elementBounds.Width, Epsilon);
Assert.AreEqual(height, elementBounds.Height, Epsilon);
}
private SvgVisualElement GetElement(string elementId)
{
if (testDocument == null)
{
testDocument = OpenSvg(GetXMLDocFromResource(GetFullResourceString(BoundsTestSvg)));
}
return testDocument.GetElementById<SvgVisualElement>(elementId);
}
}
}
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" viewBox="0 0 100 100" enable-background="new 0 0 34.06945 33.11168" xml:space="preserve" id="svg2">
<defs id="defs30"/>
<g id="lines">
<line id="line" x1="10" x2="30" y1="20" y2="40" />
<line id="line-xlate" x1="10" x2="30" y1="20" y2="40" transform="translate(5, 5)" />
<line id="line-xform" x1="10" x2="30" y1="20" y2="40" transform="rotate(180), translate(-50, 0)" />
</g>
<g id="rects">
<rect id="rect" x="10" y="30" width="10" height="20" />
<rect id="rect-xlate" x="10" y="30" width="10" height="20" transform="translate(10, 10)" />
<rect id="rect-rot" x="10" y="30" width="10" height="20" transform="rotate(90)" />
</g>
</svg>
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
</CodeAnalysisDependentAssemblyPaths> </CodeAnalysisDependentAssemblyPaths>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="BoundsTests.cs" />
<Compile Include="CssQueryTest.cs" /> <Compile Include="CssQueryTest.cs" />
<Compile Include="LargeEmbeddedImageTest.cs" /> <Compile Include="LargeEmbeddedImageTest.cs" />
<Compile Include="MarkerEndTest.cs" /> <Compile Include="MarkerEndTest.cs" />
...@@ -95,6 +96,9 @@ ...@@ -95,6 +96,9 @@
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Resources\Issue_TextElement\Text.svg" /> <EmbeddedResource Include="Resources\Issue_TextElement\Text.svg" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\Issue281_Bounds\BoundsTest.svg" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.
......
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