diff --git a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/CloseSubpath.cs b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/CloseSubpath.cs index 8abe0429..795eefda 100644 --- a/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/CloseSubpath.cs +++ b/src/UglyToad.PdfPig/Graphics/Operations/PathConstruction/CloseSubpath.cs @@ -29,7 +29,7 @@ /// public void Run(IOperationContext operationContext) { - operationContext.CurrentPath.ClosePath(); + operationContext.CurrentPath?.ClosePath(); } /// diff --git a/src/UglyToad.PdfPig/Parser/PdfDocumentFactory.cs b/src/UglyToad.PdfPig/Parser/PdfDocumentFactory.cs index 86ed1667..7ee84823 100644 --- a/src/UglyToad.PdfPig/Parser/PdfDocumentFactory.cs +++ b/src/UglyToad.PdfPig/Parser/PdfDocumentFactory.cs @@ -122,10 +122,13 @@ var cidFontFactory = new CidFontFactory(pdfScanner, fontDescriptorFactory, filterProvider); var encodingReader = new EncodingReader(pdfScanner); + var type1Handler = new Type1FontHandler(pdfScanner, filterProvider, fontDescriptorFactory, encodingReader); + var fontFactory = new FontFactory(log, new Type0FontHandler(cidFontFactory, filterProvider, pdfScanner), - new TrueTypeFontHandler(log, pdfScanner, filterProvider, fontDescriptorFactory, encodingReader, new SystemFontFinder()), - new Type1FontHandler(pdfScanner, filterProvider, fontDescriptorFactory, encodingReader), + new TrueTypeFontHandler(log, pdfScanner, filterProvider, fontDescriptorFactory, encodingReader, new SystemFontFinder(), + type1Handler), + type1Handler, new Type3FontHandler(pdfScanner, filterProvider, encodingReader)); var resourceContainer = new ResourceStore(pdfScanner, fontFactory); diff --git a/src/UglyToad.PdfPig/PdfFonts/Parser/Handlers/TrueTypeFontHandler.cs b/src/UglyToad.PdfPig/PdfFonts/Parser/Handlers/TrueTypeFontHandler.cs index a2efd52c..f36655c8 100644 --- a/src/UglyToad.PdfPig/PdfFonts/Parser/Handlers/TrueTypeFontHandler.cs +++ b/src/UglyToad.PdfPig/PdfFonts/Parser/Handlers/TrueTypeFontHandler.cs @@ -8,11 +8,13 @@ using Filters; using Fonts; using Fonts.AdobeFontMetrics; + using Fonts.CompactFontFormat; using Fonts.Encodings; using Fonts.Standard14Fonts; using Fonts.SystemFonts; using Fonts.TrueType; using Fonts.TrueType.Parser; + using Fonts.Type1; using Logging; using Parts; using PdfPig.Parser.Parts; @@ -29,17 +31,20 @@ private readonly FontDescriptorFactory fontDescriptorFactory; private readonly IEncodingReader encodingReader; private readonly ISystemFontFinder systemFontFinder; + private readonly IFontHandler type1FontHandler; public TrueTypeFontHandler(ILog log, IPdfTokenScanner pdfScanner, IFilterProvider filterProvider, FontDescriptorFactory fontDescriptorFactory, IEncodingReader encodingReader, - ISystemFontFinder systemFontFinder) + ISystemFontFinder systemFontFinder, + IFontHandler type1FontHandler) { this.log = log; this.filterProvider = filterProvider; this.fontDescriptorFactory = fontDescriptorFactory; this.encodingReader = encodingReader; this.systemFontFinder = systemFontFinder; + this.type1FontHandler = type1FontHandler; this.pdfScanner = pdfScanner; } @@ -95,7 +100,12 @@ var descriptor = FontDictionaryAccessHelper.GetFontDescriptor(pdfScanner, fontDescriptorFactory, dictionary, isLenientParsing); - var font = ParseTrueTypeFont(descriptor); + var font = ParseTrueTypeFont(descriptor, out var actualHandler); + + if (font == null && actualHandler != null) + { + return actualHandler.Generate(dictionary, isLenientParsing); + } var name = FontDictionaryAccessHelper.GetName(pdfScanner, dictionary, descriptor, isLenientParsing); @@ -113,7 +123,7 @@ } Encoding encoding = encodingReader.Read(dictionary, isLenientParsing, descriptor); - + if (encoding == null && font?.TableRegister?.CMapTable != null && font.TableRegister.PostScriptTable?.GlyphNames != null) { @@ -145,8 +155,10 @@ return new TrueTypeSimpleFont(name, descriptor, toUnicodeCMap, encoding, font, firstCharacter, widths); } - private TrueTypeFont ParseTrueTypeFont(FontDescriptor descriptor) + private TrueTypeFont ParseTrueTypeFont(FontDescriptor descriptor, out IFontHandler actualHandler) { + actualHandler = null; + if (descriptor.FontFile == null) { try @@ -158,23 +170,41 @@ { log.Error($"Failed finding system font by name: {descriptor.FontName}.", ex); } - // TODO: check if this font is present on the host OS. See: FileSystemFontProvider.java - return null; - } - if (descriptor.FontFile.FileType != DescriptorFontFile.FontFileType.TrueType) - { - throw new InvalidFontFormatException( - $"Expected a TrueType font in the TrueType font descriptor, instead it was {descriptor.FontFile.FileType}."); + return null; } try { - var fontFileStream = DirectObjectFinder.Get(descriptor.FontFile.ObjectKey, pdfScanner); - + var fontFile = fontFileStream.Decode(filterProvider); + if (descriptor.FontFile.FileType == DescriptorFontFile.FontFileType.FromSubtype) + { + var shouldThrow = true; + + if (fontFileStream.StreamDictionary.TryGet(NameToken.Subtype, pdfScanner, out NameToken subTypeName)) + { + if (subTypeName == NameToken.Type1C) + { + actualHandler = type1FontHandler; + return null; + } + + if (subTypeName == NameToken.OpenType) + { + shouldThrow = false; + } + } + + if (shouldThrow) + { + throw new InvalidFontFormatException( + $"Expected a TrueType font in the TrueType font descriptor, instead it was {descriptor.FontFile.FileType}."); + } + } + var font = TrueTypeFontParser.Parse(new TrueTypeDataBytes(new ByteArrayInputBytes(fontFile))); return font;