Commit 46e375e4 authored by Eric Domke's avatar Eric Domke
Browse files

Bug Fixes

- Fixing path parsing algorithm to deal with nuanced arc cases and
hopefully improve performance
- Attempts at better memory management
- Working toward getting symbols to render correctly
parent 7c70bd11
...@@ -45,14 +45,14 @@ namespace Svg ...@@ -45,14 +45,14 @@ namespace Svg
public IList<System.Drawing.RectangleF> MeasureCharacters(ISvgRenderer renderer, string text) public IList<System.Drawing.RectangleF> MeasureCharacters(ISvgRenderer renderer, string text)
{ {
var result = new List<RectangleF>(); var result = new List<RectangleF>();
GetPath(renderer, text, result, false); using (var path = GetPath(renderer, text, result, false)) { }
return result; return result;
} }
public System.Drawing.SizeF MeasureString(ISvgRenderer renderer, string text) public System.Drawing.SizeF MeasureString(ISvgRenderer renderer, string text)
{ {
var result = new List<RectangleF>(); var result = new List<RectangleF>();
GetPath(renderer, text, result, true); using (var path = GetPath(renderer, text, result, true)) { }
var nonEmpty = result.Where(r => r != RectangleF.Empty); var nonEmpty = result.Where(r => r != RectangleF.Empty);
if (!nonEmpty.Any()) return SizeF.Empty; if (!nonEmpty.Any()) return SizeF.Empty;
return new SizeF(nonEmpty.Last().Right - nonEmpty.First().Left, Ascent(renderer)); return new SizeF(nonEmpty.Last().Right - nonEmpty.First().Left, Ascent(renderer));
...@@ -63,12 +63,14 @@ namespace Svg ...@@ -63,12 +63,14 @@ namespace Svg
var textPath = GetPath(renderer, text, null, false); var textPath = GetPath(renderer, text, null, false);
if (textPath.PointCount > 0) if (textPath.PointCount > 0)
{ {
var translate = new Matrix(); using (var translate = new Matrix())
{
translate.Translate(location.X, location.Y); translate.Translate(location.X, location.Y);
textPath.Transform(translate); textPath.Transform(translate);
path.AddPath(textPath, false); path.AddPath(textPath, false);
} }
} }
}
private GraphicsPath GetPath(ISvgRenderer renderer, string text, IList<RectangleF> ranges, bool measureSpaces) private GraphicsPath GetPath(ISvgRenderer renderer, string text, IList<RectangleF> ranges, bool measureSpaces)
{ {
...@@ -99,6 +101,7 @@ namespace Svg ...@@ -99,6 +101,7 @@ namespace Svg
scaleMatrix.Scale(_emScale, -1 * _emScale, MatrixOrder.Append); scaleMatrix.Scale(_emScale, -1 * _emScale, MatrixOrder.Append);
scaleMatrix.Translate(xPos, ascent, MatrixOrder.Append); scaleMatrix.Translate(xPos, ascent, MatrixOrder.Append);
path.Transform(scaleMatrix); path.Transform(scaleMatrix);
scaleMatrix.Dispose();
bounds = path.GetBounds(); bounds = path.GetBounds();
if (ranges != null) if (ranges != null)
...@@ -126,5 +129,11 @@ namespace Svg ...@@ -126,5 +129,11 @@ namespace Svg
if (_glyphs == null) _glyphs = _font.Descendants().OfType<SvgGlyph>().ToDictionary(g => g.Unicode ?? g.GlyphName ?? g.ID); if (_glyphs == null) _glyphs = _font.Descendants().OfType<SvgGlyph>().ToDictionary(g => g.Unicode ?? g.GlyphName ?? g.ID);
if (_kerning == null) _kerning = _font.Descendants().OfType<SvgKern>().ToDictionary(k => k.Glyph1 + "|" + k.Glyph2); if (_kerning == null) _kerning = _font.Descendants().OfType<SvgKern>().ToDictionary(k => k.Glyph1 + "|" + k.Glyph2);
} }
public void Dispose()
{
_glyphs = null;
_kerning = null;
}
} }
} }
...@@ -376,7 +376,8 @@ namespace Svg ...@@ -376,7 +376,8 @@ namespace Svg
} }
else else
{ {
var matrix = new Matrix(); using (var matrix = new Matrix())
{
matrix.Translate(-1 * bounds.X, 0, MatrixOrder.Append); matrix.Translate(-1 * bounds.X, 0, MatrixOrder.Append);
matrix.Scale(specLength / actLength, 1, MatrixOrder.Append); matrix.Scale(specLength / actLength, 1, MatrixOrder.Append);
matrix.Translate(bounds.X, 0, MatrixOrder.Append); matrix.Translate(bounds.X, 0, MatrixOrder.Append);
...@@ -384,6 +385,7 @@ namespace Svg ...@@ -384,6 +385,7 @@ namespace Svg
} }
} }
} }
}
else if (alignOnBaseline) else if (alignOnBaseline)
{ {
var bounds = path.GetBounds(); var bounds = path.GetBounds();
...@@ -575,8 +577,9 @@ namespace Svg ...@@ -575,8 +577,9 @@ namespace Svg
// Get any defined anchors // Get any defined anchors
var xAnchors = GetValues(value.Length, e => e._x, UnitRenderingType.HorizontalOffset); var xAnchors = GetValues(value.Length, e => e._x, UnitRenderingType.HorizontalOffset);
var yAnchors = GetValues(value.Length, e => e._y, UnitRenderingType.VerticalOffset); var yAnchors = GetValues(value.Length, e => e._y, UnitRenderingType.VerticalOffset);
var font = this.Element.GetFont(this.Renderer); using (var font = this.Element.GetFont(this.Renderer))
var fontBaselineHeight = this.Renderer.FontBaselineOffset(font); {
var fontBaselineHeight = font.Ascent(this.Renderer);
PathStatistics pathStats = null; PathStatistics pathStats = null;
var pathScale = 1.0; var pathScale = 1.0;
if (BaselinePath != null) if (BaselinePath != null)
...@@ -701,7 +704,7 @@ namespace Svg ...@@ -701,7 +704,7 @@ namespace Svg
if (rotations.LastOrDefault() != 0.0f || pathStats != null) lastIndividualChar = value.Length; if (rotations.LastOrDefault() != 0.0f || pathStats != null) lastIndividualChar = value.Length;
if (lastIndividualChar > renderChar) if (lastIndividualChar > renderChar)
{ {
var charBounds = this.Renderer.MeasureCharacters(value.Substring(renderChar, Math.Min(lastIndividualChar + 1, value.Length) - renderChar), font); var charBounds = font.MeasureCharacters(this.Renderer, value.Substring(renderChar, Math.Min(lastIndividualChar + 1, value.Length) - renderChar));
PointF pathPoint; PointF pathPoint;
float rotation; float rotation;
float halfWidth; float halfWidth;
...@@ -717,7 +720,7 @@ namespace Svg ...@@ -717,7 +720,7 @@ namespace Svg
else else
{ {
xPos = Math.Max(xPos, 0); xPos = Math.Max(xPos, 0);
halfWidth = charBounds[i-renderChar].Width / 2; halfWidth = charBounds[i - renderChar].Width / 2;
if (pathStats.OffsetOnPath(xPos + halfWidth)) if (pathStats.OffsetOnPath(xPos + halfWidth))
{ {
pathStats.LocationAngleAtOffset(xPos + halfWidth, out pathPoint, out rotation); pathStats.LocationAngleAtOffset(xPos + halfWidth, out pathPoint, out rotation);
...@@ -747,7 +750,7 @@ namespace Svg ...@@ -747,7 +750,7 @@ namespace Svg
(yOffsets.Count > lastIndividualChar ? yOffsets[lastIndividualChar] : 0); (yOffsets.Count > lastIndividualChar ? yOffsets[lastIndividualChar] : 0);
DrawStringOnCurrPath(value.Substring(lastIndividualChar), font, new PointF(xPos, yPos), DrawStringOnCurrPath(value.Substring(lastIndividualChar), font, new PointF(xPos, yPos),
fontBaselineHeight, rotations.LastOrDefault()); fontBaselineHeight, rotations.LastOrDefault());
var bounds = this.Renderer.MeasureString(value.Substring(lastIndividualChar), font); var bounds = font.MeasureString(this.Renderer, value.Substring(lastIndividualChar));
xPos += bounds.Width; xPos += bounds.Width;
} }
...@@ -756,6 +759,7 @@ namespace Svg ...@@ -756,6 +759,7 @@ namespace Svg
// Undo any baseline shift. This is not persisted, unlike normal vertical offsets. // Undo any baseline shift. This is not persisted, unlike normal vertical offsets.
this.Current = new PointF(xPos, yPos - baselineShift); this.Current = new PointF(xPos, yPos - baselineShift);
} }
}
private void DrawStringOnCurrPath(string value, IFontDefn font, PointF location, float fontBaselineHeight, float rotation) private void DrawStringOnCurrPath(string value, IFontDefn font, PointF location, float fontBaselineHeight, float rotation)
{ {
...@@ -764,13 +768,15 @@ namespace Svg ...@@ -764,13 +768,15 @@ namespace Svg
font.AddStringToPath(this.Renderer, drawPath, value, new PointF(location.X, location.Y - fontBaselineHeight)); font.AddStringToPath(this.Renderer, drawPath, value, new PointF(location.X, location.Y - fontBaselineHeight));
if (rotation != 0.0f && drawPath.PointCount > 0) if (rotation != 0.0f && drawPath.PointCount > 0)
{ {
var matrix = new Matrix(); using (var matrix = new Matrix())
{
matrix.Translate(-1 * location.X, -1 * location.Y, MatrixOrder.Append); matrix.Translate(-1 * location.X, -1 * location.Y, MatrixOrder.Append);
matrix.Rotate(rotation, MatrixOrder.Append); matrix.Rotate(rotation, MatrixOrder.Append);
matrix.Translate(location.X, location.Y, MatrixOrder.Append); matrix.Translate(location.X, location.Y, MatrixOrder.Append);
drawPath.Transform(matrix); drawPath.Transform(matrix);
_currPath.AddPath(drawPath, false); _currPath.AddPath(drawPath, false);
} }
}
} }
...@@ -830,13 +836,15 @@ namespace Svg ...@@ -830,13 +836,15 @@ namespace Svg
if (xOffset != 0) if (xOffset != 0)
{ {
var matrix = new Matrix(); using (var matrix = new Matrix())
{
matrix.Translate(xOffset, 0); matrix.Translate(xOffset, 0);
foreach (var path in _anchoredPaths) foreach (var path in _anchoredPaths)
{ {
path.Transform(matrix); path.Transform(matrix);
} }
} }
}
_anchoredPaths.Clear(); _anchoredPaths.Clear();
_xAnchor = float.MinValue; _xAnchor = float.MinValue;
......
...@@ -27,7 +27,7 @@ namespace Svg.Transforms ...@@ -27,7 +27,7 @@ namespace Svg.Transforms
{ {
get get
{ {
System.Drawing.Drawing2D.Matrix matrix = new System.Drawing.Drawing2D.Matrix(); var matrix = new System.Drawing.Drawing2D.Matrix();
matrix.Scale(this.X, this.Y); matrix.Scale(this.X, this.Y);
return matrix; return matrix;
} }
......
...@@ -32,6 +32,7 @@ namespace SvgW3CTestRunner ...@@ -32,6 +32,7 @@ namespace SvgW3CTestRunner
var fileName = lstFiles.SelectedItem.ToString(); var fileName = lstFiles.SelectedItem.ToString();
try try
{ {
Debug.Print(fileName);
var doc = SvgDocument.Open(_svgBasePath + fileName); var doc = SvgDocument.Open(_svgBasePath + fileName);
if (fileName.StartsWith("__")) if (fileName.StartsWith("__"))
{ {
......
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