From 936e17b723c5eca856548b0a7ebf23e00064798f Mon Sep 17 00:00:00 2001 From: Eliot Jones Date: Sat, 17 Nov 2018 16:23:17 +0000 Subject: [PATCH] #6 add debugging code for inspecting svgs of generated cff glyphs fix small bugs --- .../Integration/PigProductionHandbookTests.cs | 5 +- .../CharStrings/LazyType2Command.cs | 2 + .../CharStrings/Type2CharStringParser.cs | 2 + .../CharStrings/Type2CharStrings.cs | 61 +++++++++++++++++-- .../CompactFontFormatIndividualFontParser.cs | 10 +++ 5 files changed, 75 insertions(+), 5 deletions(-) diff --git a/src/UglyToad.PdfPig.Tests/Integration/PigProductionHandbookTests.cs b/src/UglyToad.PdfPig.Tests/Integration/PigProductionHandbookTests.cs index 1366de46..dcc2b490 100644 --- a/src/UglyToad.PdfPig.Tests/Integration/PigProductionHandbookTests.cs +++ b/src/UglyToad.PdfPig.Tests/Integration/PigProductionHandbookTests.cs @@ -16,7 +16,10 @@ [Fact] public void CanReadContent() { - using (var document = PdfDocument.Open(GetFilename())) + using (var document = PdfDocument.Open(GetFilename(), new ParsingOptions + { + UseLenientParsing = false + })) { var page = document.GetPage(1); diff --git a/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CharStrings/LazyType2Command.cs b/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CharStrings/LazyType2Command.cs index cc26cbf7..bdf8694a 100644 --- a/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CharStrings/LazyType2Command.cs +++ b/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CharStrings/LazyType2Command.cs @@ -42,6 +42,8 @@ public PdfPoint CurrentLocation { get; set; } = new PdfPoint(0, 0); + public decimal? Width { get; set; } + public void AddRelativeHorizontalLine(decimal dx) { AddRelativeLine(dx, 0); diff --git a/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CharStrings/Type2CharStringParser.cs b/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CharStrings/Type2CharStringParser.cs index a70d434f..ab6550d8 100644 --- a/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CharStrings/Type2CharStringParser.cs +++ b/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CharStrings/Type2CharStringParser.cs @@ -332,6 +332,8 @@ ctx.AddRelativeBezierCurve(dx1, dy1, dx2, dy2, 0, dy3); } + + ctx.Stack.Clear(); }) }, { 27, new LazyType2Command("hhcurveto", ctx => diff --git a/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CharStrings/Type2CharStrings.cs b/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CharStrings/Type2CharStrings.cs index 3f23ca7b..09d4ea3f 100644 --- a/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CharStrings/Type2CharStrings.cs +++ b/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CharStrings/Type2CharStrings.cs @@ -43,16 +43,69 @@ return glyph; } - private static CharacterPath Run(CommandSequence sequence) + public static CharacterPath Run(CommandSequence sequence) { var context = new Type2BuildCharContext(); + + var hasRunStackClearingCommand = false; foreach (var command in sequence.Commands) { - //command.Match(x => context.Stack.Push(x), - // x => x.Run(context)); + command.Match(x => context.Stack.Push(x), + x => + { + 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 (x.Name) + { + case "hstem": + case "hstemhm": + case "vstemhm": + case "vstem": + { + var oddArgCount = context.Stack.Length % 2 != 0; + if (oddArgCount) + { + context.Width = context.Stack.PopBottom(); + } + break; + } + case "hmoveto": + case "vmoveto": + SetWidthFromArgumentsIfPresent(context, 1); + break; + case "rmoveto": + SetWidthFromArgumentsIfPresent(context, 2); + break; + case "cntrmask": + case "hintmask": + case "endchar:": + SetWidthFromArgumentsIfPresent(context, 0); + break; + default: + hasRunStackClearingCommand = false; + break; + + } + + } + x.Run(context); + }); } - throw new NotImplementedException(); + return context.Path; + } + + private static void SetWidthFromArgumentsIfPresent(Type2BuildCharContext context, int expectedArgumentLength) + { + if (context.Stack.Length > expectedArgumentLength) + { + context.Width = context.Stack.PopBottom(); + } } public class CommandSequence diff --git a/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CompactFontFormatIndividualFontParser.cs b/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CompactFontFormatIndividualFontParser.cs index 58b5af4c..2c305c53 100644 --- a/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CompactFontFormatIndividualFontParser.cs +++ b/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CompactFontFormatIndividualFontParser.cs @@ -2,6 +2,7 @@ { using System; using System.Collections.Generic; + using System.Diagnostics; using System.Linq; using Charsets; using CharStrings; @@ -147,6 +148,15 @@ throw new ArgumentOutOfRangeException($"Unexpected CharString type in CFF font: {topDictionary.CharStringType}."); } + if (Debugger.IsAttached) + { + foreach (var pair in charStrings.CharStrings) + { + var path = Type2CharStrings.Run(pair.Value); + var svg = path.ToFullSvg(); + } + } + return new CompactFontFormatFont(topDictionary, privateDictionary, charset, Union.Two(charStrings)); }