From 1a003b2d877928cae5467e6a285373402e65a010 Mon Sep 17 00:00:00 2001 From: HeinrichAD Date: Sun, 3 Jan 2016 12:42:33 +0100 Subject: [PATCH] Maker rendering does not get right position. As long as the functions AdjustForViewBoxWidth and AdjustForViewBoxHeight are not fully developed pay attention that the ViewBox width and height will not mismatch the positions of the marker element then one of them are zero. This changes are based on Issue #212 from mater. Add: Quick solution to avoid ViewBox width or height zero calculation. Add: UnitTests --- Source/Painting/SvgMarker.cs | 31 ++++-- Tests/Svg.UnitTests/MarkerEndTest.cs | 96 +++++++++++++++++++ .../Issue212_MakerEnd/OperatingPlan.svg | 34 +++++++ Tests/Svg.UnitTests/Svg.UnitTests.csproj | 4 + 4 files changed, 158 insertions(+), 7 deletions(-) create mode 100644 Tests/Svg.UnitTests/MarkerEndTest.cs create mode 100644 Tests/Svg.UnitTests/Resources/Issue212_MakerEnd/OperatingPlan.svg diff --git a/Source/Painting/SvgMarker.cs b/Source/Painting/SvgMarker.cs index 6d5de60..1e42b3e 100644 --- a/Source/Painting/SvgMarker.cs +++ b/Source/Painting/SvgMarker.cs @@ -133,9 +133,14 @@ namespace Svg /// public void RenderMarker(ISvgRenderer pRenderer, SvgVisualElement pOwner, PointF pRefPoint, PointF pMarkerPoint1, PointF pMarkerPoint2) { - float xDiff = pMarkerPoint2.X - pMarkerPoint1.X; - float yDiff = pMarkerPoint2.Y - pMarkerPoint1.Y; - float fAngle1 = (float)(Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI); + float fAngle1 = 0f; + if (Orient.IsAuto) + { + // Only calculate this if needed. + float xDiff = pMarkerPoint2.X - pMarkerPoint1.X; + float yDiff = pMarkerPoint2.Y - pMarkerPoint1.Y; + fAngle1 = (float)(Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI); + } RenderPart2(fAngle1, pRenderer, pOwner, pRefPoint); } @@ -184,10 +189,22 @@ namespace Svg switch (MarkerUnits) { case SvgMarkerUnits.StrokeWidth: - transMatrix.Translate(AdjustForViewBoxWidth(-RefX.ToDeviceValue(pRenderer, UnitRenderingType.Horizontal, this) * - pOwner.StrokeWidth.ToDeviceValue(pRenderer, UnitRenderingType.Other, this)), - AdjustForViewBoxHeight(-RefY.ToDeviceValue(pRenderer, UnitRenderingType.Vertical, this) * - pOwner.StrokeWidth.ToDeviceValue(pRenderer, UnitRenderingType.Other, this))); + if (ViewBox.Width > 0 && ViewBox.Height > 0) + { + transMatrix.Translate(AdjustForViewBoxWidth(-RefX.ToDeviceValue(pRenderer, UnitRenderingType.Horizontal, this) * + pOwner.StrokeWidth.ToDeviceValue(pRenderer, UnitRenderingType.Other, this)), + AdjustForViewBoxHeight(-RefY.ToDeviceValue(pRenderer, UnitRenderingType.Vertical, this) * + pOwner.StrokeWidth.ToDeviceValue(pRenderer, UnitRenderingType.Other, this))); + } + else + { + // SvgMarkerUnits.UserSpaceOnUse + // TODO: We know this isn't correct. + // But use this until the TODOs from AdjustForViewBoxWidth and AdjustForViewBoxHeight are done. + // MORE see Unit Test "MakerEndTest.TestArrowCodeCreation()" + transMatrix.Translate(-RefX.ToDeviceValue(pRenderer, UnitRenderingType.Horizontal, this), + -RefY.ToDeviceValue(pRenderer, UnitRenderingType.Vertical, this)); + } break; case SvgMarkerUnits.UserSpaceOnUse: transMatrix.Translate(-RefX.ToDeviceValue(pRenderer, UnitRenderingType.Horizontal, this), diff --git a/Tests/Svg.UnitTests/MarkerEndTest.cs b/Tests/Svg.UnitTests/MarkerEndTest.cs new file mode 100644 index 0000000..bbef2e7 --- /dev/null +++ b/Tests/Svg.UnitTests/MarkerEndTest.cs @@ -0,0 +1,96 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Svg.DataTypes; +using System; +using System.Diagnostics; +using System.Drawing; +using System.IO; + +namespace Svg.UnitTests +{ + [TestClass] + public class MarkerEndTest : SvgTestHelper + { + + protected override string TestResource { get { return GetFullResourceString("Issue212_MakerEnd.OperatingPlan.svg"); } } + protected override int ExpectedSize { get { return 5410; } } + + + [TestMethod] + public void TestOperatingPlanRendering() + { + LoadSvg(GetXMLDocFromResource()); + } + + + [TestMethod] + public void TestArrowCodeCreation() + { + const int width = 50; + const int height = 50; + + var document = new SvgDocument() + { + ID = "svgMap", + ViewBox = new SvgViewBox(0, 0, width, height) + }; + + var defsElement = new SvgDefinitionList() { ID = "defsMap" }; + document.Children.Add(defsElement); + + var groupElement = new SvgGroup() { ID = "gMap" }; + document.Children.Add(groupElement); + + var arrowPath = new SvgPath() + { + ID = "pathMarkerArrow", + Fill = new SvgColourServer(Color.Black), + PathData = SvgPathBuilder.Parse(@"M0,0 L4,2 L0,4 L1,2 z") + }; + + var arrowMarker = new SvgMarker() + { + ID = "markerArrow", + MarkerUnits = SvgMarkerUnits.StrokeWidth, + MarkerWidth = 5, + MarkerHeight = 5, + RefX = 3, + RefY = 2, + Orient = new SvgOrient() { IsAuto = true }, + Children = { arrowPath } + }; + + defsElement.Children.Add(arrowMarker); + + var line = new SvgLine() + { + ID = "lineLinkedPoint", + StartX = 0, + StartY = 15, + EndX = 35, + EndY = 35, + Stroke = new SvgColourServer(Color.Black), + StrokeWidth = 3, + MarkerEnd = new Uri(string.Format("url(#{0})", arrowMarker.ID), UriKind.Relative) + }; + + groupElement.Children.Add(line); + + var svgXml = document.GetXML(); + var img = document.Draw(); + + var file = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + File.WriteAllText(file + ".svg", svgXml); + img.Save(file + ".png"); + Debug.WriteLine(string.Format("Svg saved to '{0}'", file)); + + Debugger.Break(); + + // Remove + var svg = new FileInfo(file + ".svg"); + if (svg.Exists) svg.Delete(); + var png = new FileInfo(file + ".png"); + if (png.Exists) png.Delete(); + } + + } +} diff --git a/Tests/Svg.UnitTests/Resources/Issue212_MakerEnd/OperatingPlan.svg b/Tests/Svg.UnitTests/Resources/Issue212_MakerEnd/OperatingPlan.svg new file mode 100644 index 0000000..6b58da5 --- /dev/null +++ b/Tests/Svg.UnitTests/Resources/Issue212_MakerEnd/OperatingPlan.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tests/Svg.UnitTests/Svg.UnitTests.csproj b/Tests/Svg.UnitTests/Svg.UnitTests.csproj index d4956f7..4a424cb 100644 --- a/Tests/Svg.UnitTests/Svg.UnitTests.csproj +++ b/Tests/Svg.UnitTests/Svg.UnitTests.csproj @@ -55,6 +55,7 @@ + @@ -77,6 +78,9 @@ + + +