From b1fbcd0ccd38680d45e8b04929f8b03dcbe2d63a Mon Sep 17 00:00:00 2001 From: Eliot Jones Date: Mon, 8 Jan 2018 21:58:07 +0000 Subject: [PATCH] support type 1 normal fonts and fix bug with fetching resource dictionary --- .../Parser/FontDictionaryAccessHelper.cs | 2 +- .../Fonts/Parser/Handlers/Type1FontHandler.cs | 3 +- src/UglyToad.Pdf/Fonts/Simple/Type1Font.cs | 86 +++++++++++++++++++ ...ReflectionGraphicsStateOperationFactory.cs | 7 ++ src/UglyToad.Pdf/Parser/PageFactory.cs | 3 +- 5 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 src/UglyToad.Pdf/Fonts/Simple/Type1Font.cs diff --git a/src/UglyToad.Pdf/Fonts/Parser/FontDictionaryAccessHelper.cs b/src/UglyToad.Pdf/Fonts/Parser/FontDictionaryAccessHelper.cs index d227edf5..c49aa985 100644 --- a/src/UglyToad.Pdf/Fonts/Parser/FontDictionaryAccessHelper.cs +++ b/src/UglyToad.Pdf/Fonts/Parser/FontDictionaryAccessHelper.cs @@ -78,7 +78,7 @@ return descriptor.FontName; } - throw new InvalidFontFormatException($"Could not find a name for this TrueType font {dictionary}."); + throw new InvalidFontFormatException($"Could not find a name for this font {dictionary}."); } } } diff --git a/src/UglyToad.Pdf/Fonts/Parser/Handlers/Type1FontHandler.cs b/src/UglyToad.Pdf/Fonts/Parser/Handlers/Type1FontHandler.cs index c0e11d49..ebdccab1 100644 --- a/src/UglyToad.Pdf/Fonts/Parser/Handlers/Type1FontHandler.cs +++ b/src/UglyToad.Pdf/Fonts/Parser/Handlers/Type1FontHandler.cs @@ -1,6 +1,5 @@ namespace UglyToad.Pdf.Fonts.Parser.Handlers { - using System; using Cmap; using ContentStream; using Cos; @@ -71,7 +70,7 @@ Encoding encoding = encodingReader.Read(dictionary, reader, isLenientParsing, descriptor); - return new TrueTypeSimpleFont(name, firstCharacter, lastCharacter, widths, descriptor, toUnicodeCMap, encoding); + return new Type1Font(name, firstCharacter, lastCharacter, widths, descriptor, encoding, toUnicodeCMap); } } } diff --git a/src/UglyToad.Pdf/Fonts/Simple/Type1Font.cs b/src/UglyToad.Pdf/Fonts/Simple/Type1Font.cs new file mode 100644 index 00000000..8e344f86 --- /dev/null +++ b/src/UglyToad.Pdf/Fonts/Simple/Type1Font.cs @@ -0,0 +1,86 @@ +namespace UglyToad.Pdf.Fonts.Simple +{ + using Cmap; + using Composite; + using Core; + using Cos; + using Encodings; + using Geometry; + using IO; + + /// + /// TODO: implement this properly if you find a Type 1 font in the wild. + /// + internal class Type1Font : IFont + { + private readonly int firstChar; + private readonly int lastChar; + private readonly decimal[] widths; + private readonly FontDescriptor fontDescriptor; + private readonly Encoding encoding; + private readonly ToUnicodeCMap toUnicodeCMap; + private readonly TransformationMatrix fontMatrix = TransformationMatrix.FromValues(0.001m, 0, 0, 0.001m, 0, 0); + + public CosName Name { get; } + + public bool IsVertical { get; } = false; + + public Type1Font(CosName name, int firstChar, int lastChar, decimal[] widths, FontDescriptor fontDescriptor, Encoding encoding, CMap toUnicodeCMap) + { + this.firstChar = firstChar; + this.lastChar = lastChar; + this.widths = widths; + this.fontDescriptor = fontDescriptor; + this.encoding = encoding; + this.toUnicodeCMap = new ToUnicodeCMap(toUnicodeCMap); + Name = name; + } + + public int ReadCharacterCode(IInputBytes bytes, out int codeLength) + { + codeLength = 1; + return bytes.CurrentByte; + } + + public bool TryGetUnicode(int characterCode, out string value) + { + if (toUnicodeCMap.CanMapToUnicode) + { + return toUnicodeCMap.TryGet(characterCode, out value); + } + + value = null; + + if (encoding == null) + { + return false; + } + + var name = encoding.GetName(characterCode); + + value = GlyphList.AdobeGlyphList.NameToUnicode(name); + + return true; + } + + public PdfVector GetDisplacement(int characterCode) + { + return fontMatrix.Transform(new PdfVector(GetWidth(characterCode), 0)); + } + + public decimal GetWidth(int characterCode) + { + if (characterCode < firstChar || characterCode > lastChar) + { + return 250; + } + + return widths[characterCode - firstChar]; + } + + public TransformationMatrix GetFontMatrix() + { + return fontMatrix; + } + } +} diff --git a/src/UglyToad.Pdf/Graphics/ReflectionGraphicsStateOperationFactory.cs b/src/UglyToad.Pdf/Graphics/ReflectionGraphicsStateOperationFactory.cs index 7b60097c..d859f7bc 100644 --- a/src/UglyToad.Pdf/Graphics/ReflectionGraphicsStateOperationFactory.cs +++ b/src/UglyToad.Pdf/Graphics/ReflectionGraphicsStateOperationFactory.cs @@ -133,6 +133,13 @@ namespace UglyToad.Pdf.Graphics } else if (parameter.ParameterType == typeof(decimal[])) { + if (operands[offset] is ArrayToken arr) + { + arguments.Add(arr.Data.OfType().Select(x => x.Data).ToArray()); + offset++; + continue; + } + var array = new List(); while (offset < operands.Count && operands[offset] is NumericToken numeric) { diff --git a/src/UglyToad.Pdf/Parser/PageFactory.cs b/src/UglyToad.Pdf/Parser/PageFactory.cs index 30d82512..edc3de91 100644 --- a/src/UglyToad.Pdf/Parser/PageFactory.cs +++ b/src/UglyToad.Pdf/Parser/PageFactory.cs @@ -189,8 +189,7 @@ if (resources is CosObject resourceObject) { - var resourceDictionary = - pdfObjectParser.Parse(resourceObject.ToIndirectReference(), reader, isLenientParsing); + var resourceDictionary = DirectObjectFinder.Find(resourceObject, pdfObjectParser, reader, isLenientParsing); if (resourceDictionary is PdfDictionary resolvedDictionary) {