/// <inheritdoc /> public override string ToString() { var stringBuilder = new StringBuilder(); for (var i = -1; i < Values.Count; i++) { if (i >= 0) { var value = Values[i]; stringBuilder.AppendLine(value.ToString("N", CultureInfo.InvariantCulture)); } foreach (var identifier in GetCommandsAt(i + 1)) { stringBuilder.AppendLine(Type2CharStringParser.GetCommand(identifier).Name); } } return(stringBuilder.ToString()); }
private static Type2Glyph Run(CommandSequence sequence, double defaultWidthX, double nominalWidthX) { var context = new Type2BuildCharContext(); var hasRunStackClearingCommand = false; for (var i = -1; i < sequence.Values.Count; i++) { if (i >= 0) { var value = sequence.Values[i]; context.Stack.Push(value); } foreach (var commandIdentifier in sequence.GetCommandsAt(i + 1)) { var command = Type2CharStringParser.GetCommand(commandIdentifier); var isOnlyCommand = sequence.Values.Count + sequence.CommandIdentifiers.Count == 1; if (!hasRunStackClearingCommand) { /* * The first stack-clearing operator, which must be one of hstem, hstemhm, vstem, vstemhm, cntrmask, hintmask, hmoveto, vmoveto, * rmoveto, or endchar, takes an additional argument — the width (as described earlier), which may be expressed as zero or one numeric argument. */ hasRunStackClearingCommand = true; switch (command.Name) { case "hstem": case "hstemhm": case "vstemhm": case "vstem": { var oddArgCount = context.Stack.Length % 2 != 0; if (oddArgCount) { context.Width = nominalWidthX + context.Stack.PopBottom(); } break; } case "hmoveto": case "vmoveto": SetWidthFromArgumentsIfPresent(context, nominalWidthX, 1); break; case "rmoveto": SetWidthFromArgumentsIfPresent(context, nominalWidthX, 2); break; case "cntrmask": case "hintmask": SetWidthFromArgumentsIfPresent(context, nominalWidthX, 0); break; case "endchar": if (isOnlyCommand) { context.Width = defaultWidthX; } else { SetWidthFromArgumentsIfPresent(context, nominalWidthX, 0); } break; default: hasRunStackClearingCommand = false; break; } } command.Run(context); } } return(new Type2Glyph(context.Path, context.Width)); }