Commit 835d2cfd authored by H1Gdev's avatar H1Gdev Committed by mrbean-bremen
Browse files

Fix: adjustment is wrong in lengthAdjust='spacingAndGlyphs' (#373)

- Fix: adjustment is wrong in lengthAdjust='spacingAndGlyphs'.
- Add test images.
parent a75538ee
...@@ -342,9 +342,8 @@ namespace Svg ...@@ -342,9 +342,8 @@ namespace Svg
{ {
if (this.TextLength != SvgUnit.None) if (this.TextLength != SvgUnit.None)
{ {
var bounds = path.GetBounds();
var specLength = this.TextLength.ToDeviceValue(state.Renderer, UnitRenderingType.Horizontal, this); var specLength = this.TextLength.ToDeviceValue(state.Renderer, UnitRenderingType.Horizontal, this);
var actLength = bounds.Width; var actLength = state.TextBounds.Width;
var diff = (actLength - specLength); var diff = (actLength - specLength);
if (Math.Abs(diff) > 1.5) if (Math.Abs(diff) > 1.5)
{ {
...@@ -358,9 +357,9 @@ namespace Svg ...@@ -358,9 +357,9 @@ namespace Svg
{ {
using (var matrix = new Matrix()) using (var matrix = new Matrix())
{ {
matrix.Translate(-1 * bounds.X, 0, MatrixOrder.Append); matrix.Translate(-1 * state.TextBounds.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(state.TextBounds.X, 0, MatrixOrder.Append);
path.Transform(matrix); path.Transform(matrix);
} }
} }
...@@ -504,6 +503,7 @@ namespace Svg ...@@ -504,6 +503,7 @@ namespace Svg
public GraphicsPath BaselinePath { get; set; } public GraphicsPath BaselinePath { get; set; }
public PointF Current { get; set; } public PointF Current { get; set; }
public RectangleF TextBounds { get; set; }
public SvgTextBase Element { get; set; } public SvgTextBase Element { get; set; }
public float LetterSpacingAdjust { get; set; } public float LetterSpacingAdjust { get; set; }
public int NumChars { get; set; } public int NumChars { get; set; }
...@@ -517,6 +517,7 @@ namespace Svg ...@@ -517,6 +517,7 @@ namespace Svg
this.Element = element; this.Element = element;
this.Renderer = renderer; this.Renderer = renderer;
this.Current = PointF.Empty; this.Current = PointF.Empty;
this.TextBounds = RectangleF.Empty;
_xAnchor = 0; _xAnchor = 0;
this.BaselinePath = element.GetBaselinePath(renderer); this.BaselinePath = element.GetBaselinePath(renderer);
_authorPathLength = element.GetAuthorPathLength(); _authorPathLength = element.GetAuthorPathLength();
...@@ -527,6 +528,7 @@ namespace Svg ...@@ -527,6 +528,7 @@ namespace Svg
this.Renderer = parent.Renderer; this.Renderer = parent.Renderer;
this.Parent = parent; this.Parent = parent;
this.Current = parent.Current; this.Current = parent.Current;
this.TextBounds = parent.TextBounds;
this.BaselinePath = element.GetBaselinePath(parent.Renderer) ?? parent.BaselinePath; this.BaselinePath = element.GetBaselinePath(parent.Renderer) ?? parent.BaselinePath;
var currPathLength = element.GetAuthorPathLength(); var currPathLength = element.GetAuthorPathLength();
_authorPathLength = currPathLength == 0 ? parent._authorPathLength : currPathLength; _authorPathLength = currPathLength == 0 ? parent._authorPathLength : currPathLength;
...@@ -545,6 +547,7 @@ namespace Svg ...@@ -545,6 +547,7 @@ namespace Svg
result.BaselinePath = this.BaselinePath; result.BaselinePath = this.BaselinePath;
result._xAnchor = this._xAnchor; result._xAnchor = this._xAnchor;
result.Current = this.Current; result.Current = this.Current;
result.TextBounds = this.TextBounds;
result.Element = this.Element; result.Element = this.Element;
result.NumChars = this.NumChars; result.NumChars = this.NumChars;
result.Parent = this.Parent; result.Parent = this.Parent;
...@@ -652,6 +655,7 @@ namespace Svg ...@@ -652,6 +655,7 @@ namespace Svg
this.Renderer.PopBoundable(); this.Renderer.PopBoundable();
} }
var xTextStart = Current.X;
// NOTE: Assuming a horizontal left-to-right font // NOTE: Assuming a horizontal left-to-right font
// Render absolutely positioned items in the horizontal direction // Render absolutely positioned items in the horizontal direction
var yPos = Current.Y; var yPos = Current.Y;
...@@ -662,6 +666,7 @@ namespace Svg ...@@ -662,6 +666,7 @@ namespace Svg
EnsurePath(); EnsurePath();
yPos = (yAnchors.Count > i ? yAnchors[i] : yPos) + (yOffsets.Count > i ? yOffsets[i] : 0); yPos = (yAnchors.Count > i ? yAnchors[i] : yPos) + (yOffsets.Count > i ? yOffsets[i] : 0);
xTextStart = xTextStart.Equals(Current.X) ? _xAnchor : xTextStart;
DrawStringOnCurrPath(value[i].ToString(), font, new PointF(_xAnchor, yPos), DrawStringOnCurrPath(value[i].ToString(), font, new PointF(_xAnchor, yPos),
fontBaselineHeight, (rotations.Count > i ? rotations[i] : rotations.LastOrDefault())); fontBaselineHeight, (rotations.Count > i ? rotations[i] : rotations.LastOrDefault()));
} }
...@@ -694,6 +699,7 @@ namespace Svg ...@@ -694,6 +699,7 @@ namespace Svg
yPos = (yAnchors.Count > i ? yAnchors[i] : yPos) + (yOffsets.Count > i ? yOffsets[i] : 0); yPos = (yAnchors.Count > i ? yAnchors[i] : yPos) + (yOffsets.Count > i ? yOffsets[i] : 0);
if (pathStats == null) if (pathStats == null)
{ {
xTextStart = xTextStart.Equals(Current.X) ? xPos : xTextStart;
DrawStringOnCurrPath(value[i].ToString(), font, new PointF(xPos, yPos), DrawStringOnCurrPath(value[i].ToString(), font, new PointF(xPos, yPos),
fontBaselineHeight, (rotations.Count > i ? rotations[i] : rotations.LastOrDefault())); fontBaselineHeight, (rotations.Count > i ? rotations[i] : rotations.LastOrDefault()));
} }
...@@ -706,6 +712,7 @@ namespace Svg ...@@ -706,6 +712,7 @@ namespace Svg
pathStats.LocationAngleAtOffset(xPos + halfWidth, out pathPoint, out rotation); pathStats.LocationAngleAtOffset(xPos + halfWidth, out pathPoint, out rotation);
pathPoint = new PointF((float)(pathPoint.X - halfWidth * Math.Cos(rotation * Math.PI / 180) - (float)pathScale * yPos * Math.Sin(rotation * Math.PI / 180)), pathPoint = new PointF((float)(pathPoint.X - halfWidth * Math.Cos(rotation * Math.PI / 180) - (float)pathScale * yPos * Math.Sin(rotation * Math.PI / 180)),
(float)(pathPoint.Y - halfWidth * Math.Sin(rotation * Math.PI / 180) + (float)pathScale * yPos * Math.Cos(rotation * Math.PI / 180))); (float)(pathPoint.Y - halfWidth * Math.Sin(rotation * Math.PI / 180) + (float)pathScale * yPos * Math.Cos(rotation * Math.PI / 180)));
xTextStart = xTextStart.Equals(Current.X) ? pathPoint.X : xTextStart;
DrawStringOnCurrPath(value[i].ToString(), font, pathPoint, fontBaselineHeight, rotation); DrawStringOnCurrPath(value[i].ToString(), font, pathPoint, fontBaselineHeight, rotation);
} }
} }
...@@ -728,6 +735,7 @@ namespace Svg ...@@ -728,6 +735,7 @@ namespace Svg
xPos += (xOffsets.Count > lastIndividualChar ? xOffsets[lastIndividualChar] : 0); xPos += (xOffsets.Count > lastIndividualChar ? xOffsets[lastIndividualChar] : 0);
yPos = (yAnchors.Count > lastIndividualChar ? yAnchors[lastIndividualChar] : yPos) + yPos = (yAnchors.Count > lastIndividualChar ? yAnchors[lastIndividualChar] : yPos) +
(yOffsets.Count > lastIndividualChar ? yOffsets[lastIndividualChar] : 0); (yOffsets.Count > lastIndividualChar ? yOffsets[lastIndividualChar] : 0);
xTextStart = xTextStart.Equals(Current.X) ? xPos : xTextStart;
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 = font.MeasureString(this.Renderer, value.Substring(lastIndividualChar)); var bounds = font.MeasureString(this.Renderer, value.Substring(lastIndividualChar));
...@@ -738,6 +746,7 @@ namespace Svg ...@@ -738,6 +746,7 @@ namespace Svg
NumChars += value.Length; NumChars += value.Length;
// 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);
this.TextBounds = new RectangleF(xTextStart, 0, this.Current.X - xTextStart, 0);
} }
} }
......
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="34" height="48" xml:space="preserve">
<line fill="none" stroke="#000" stroke-width="2" stroke-miterlimit="2" x1="1" x2="1" y1="0" y2="48"/>
<line fill="none" stroke="#000" stroke-width="2" stroke-miterlimit="2" x1="33" x2="33" y1="0" y2="48"/>
<text x="2" y="15" fill="#000" font-family="Meiryo, メイリオ, sans-serif" font-size="14" textLength="30" lengthAdjust="spacingAndGlyphs">AB</text>
<text x="2" y="30" fill="#000" font-family="Meiryo, メイリオ, sans-serif" font-size="14" textLength="30" lengthAdjust="spacingAndGlyphs">あい</text>
<text x="2" y="45" fill="#000" font-family="Meiryo, メイリオ, sans-serif" font-size="14" textLength="30" lengthAdjust="spacingAndGlyphs">(あ</text>
</svg>
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