/// <summary>
/// Sets the path on this element and all child elements. Uses the state
/// object to track the state of the drawing
/// </summary>
/// <param name="state">State of the drawing operation</param>
/// <param name="doMeasurements">If true, calculate and apply text length adjustments.</param>
private void SetPath(TextDrawingState state, bool doMeasurements)
{
TextDrawingState origState = null;
bool alignOnBaseline = state.BaselinePath != null && (this.TextAnchor == SvgTextAnchor.Middle || this.TextAnchor == SvgTextAnchor.End);
if (doMeasurements)
{
if (this.TextLength != SvgUnit.None)
{
origState = state.Clone();
}
else if (alignOnBaseline)
{
origState = state.Clone();
state.BaselinePath = null;
}
}
foreach (var node in GetContentNodes())
{
SvgTextBase textNode = node as SvgTextBase;
if (textNode == null)
{
if (!string.IsNullOrEmpty(node.Content))
{
state.DrawString(PrepareText(node.Content));
}
}
else
{
TextDrawingState newState = new TextDrawingState(state, textNode);
textNode.SetPath(newState);
state.NumChars += newState.NumChars;
state.Current = newState.Current;
}
}
var path = state.GetPath() ?? new GraphicsPath();
// Apply any text length adjustments
if (doMeasurements)
{
if (this.TextLength != SvgUnit.None)
{
var specLength = this.TextLength.ToDeviceValue(state.Renderer, UnitRenderingType.Horizontal, this);
var actLength = state.TextBounds.Width;
var diff = (actLength - specLength);
if (Math.Abs(diff) > 1.5)
{
if (this.LengthAdjust == SvgTextLengthAdjust.Spacing)
{
if (this.X.Count < 2)
{
var numCharDiff = state.NumChars - origState.NumChars - 1;
if (numCharDiff != 0)
{
origState.LetterSpacingAdjust = -1 * diff / numCharDiff;
SetPath(origState, false);
return;
}
}
}
else
{
using (var matrix = new Matrix())
{
matrix.Translate(-1 * state.TextBounds.X, 0, MatrixOrder.Append);
matrix.Scale(specLength / actLength, 1, MatrixOrder.Append);
matrix.Translate(state.TextBounds.X, 0, MatrixOrder.Append);
path.Transform(matrix);
}
}
}
}
else if (alignOnBaseline)
{
var bounds = path.GetBounds();
if (this.TextAnchor == SvgTextAnchor.Middle)
{
origState.StartOffsetAdjust = -1 * bounds.Width / 2;
}
else
{
origState.StartOffsetAdjust = -1 * bounds.Width;
}
SetPath(origState, false);
return;
}
}
_path = path;
this.IsPathDirty = false;
}