public IFont Generate(DictionaryToken dictionary, bool isLenientParsing) { var firstCharacter = FontDictionaryAccessHelper.GetFirstCharacter(dictionary); var widths = FontDictionaryAccessHelper.GetWidths(pdfScanner, dictionary, isLenientParsing); var descriptor = FontDictionaryAccessHelper.GetFontDescriptor(pdfScanner, fontDescriptorFactory, dictionary, isLenientParsing); // TODO: use the parsed font fully. var font = ParseTrueTypeFont(descriptor); var name = FontDictionaryAccessHelper.GetName(pdfScanner, dictionary, descriptor, isLenientParsing); CMap toUnicodeCMap = null; if (dictionary.TryGet(NameToken.ToUnicode, out var toUnicodeObj)) { var toUnicode = DirectObjectFinder.Get <StreamToken>(toUnicodeObj, pdfScanner); var decodedUnicodeCMap = toUnicode.Decode(filterProvider); if (decodedUnicodeCMap != null) { toUnicodeCMap = cMapCache.Parse(new ByteArrayInputBytes(decodedUnicodeCMap), isLenientParsing); } } Encoding encoding = encodingReader.Read(dictionary, isLenientParsing, descriptor); return(new TrueTypeSimpleFont(name, descriptor, toUnicodeCMap, encoding, font, firstCharacter, widths)); }
public IFont Generate(DictionaryToken dictionary) { var boundingBox = GetBoundingBox(dictionary); var fontMatrix = GetFontMatrix(dictionary); var firstCharacter = FontDictionaryAccessHelper.GetFirstCharacter(dictionary); var lastCharacter = FontDictionaryAccessHelper.GetLastCharacter(dictionary); var widths = FontDictionaryAccessHelper.GetWidths(scanner, dictionary); Encoding encoding = encodingReader.Read(dictionary); CMap toUnicodeCMap = null; if (dictionary.TryGet(NameToken.ToUnicode, out var toUnicodeObj)) { var toUnicode = DirectObjectFinder.Get <StreamToken>(toUnicodeObj, scanner); var decodedUnicodeCMap = toUnicode?.Decode(filterProvider); if (decodedUnicodeCMap != null) { toUnicodeCMap = CMapCache.Parse(new ByteArrayInputBytes(decodedUnicodeCMap)); } } return(new Type3Font(NameToken.Type3, boundingBox, fontMatrix, encoding, firstCharacter, lastCharacter, widths, toUnicodeCMap)); }
public IFont Generate(DictionaryToken dictionary, bool isLenientParsing) { var usingStandard14Only = !dictionary.ContainsKey(NameToken.FirstChar) || !dictionary.ContainsKey(NameToken.Widths); if (usingStandard14Only) { // TODO: some fonts combine standard 14 font with other metrics. if (!dictionary.TryGet(NameToken.BaseFont, out var baseFontToken) || !(baseFontToken is NameToken standard14Name)) { throw new InvalidFontFormatException($"The Type 1 font did not contain a first character entry but also did not reference a standard 14 font: {dictionary}"); } var metrics = Standard14.GetAdobeFontMetrics(standard14Name.Data); return(new Type1Standard14Font(metrics)); } var firstCharacter = FontDictionaryAccessHelper.GetFirstCharacter(dictionary); var lastCharacter = FontDictionaryAccessHelper.GetLastCharacter(dictionary); var widths = FontDictionaryAccessHelper.GetWidths(pdfScanner, dictionary, isLenientParsing); var descriptor = FontDictionaryAccessHelper.GetFontDescriptor(pdfScanner, fontDescriptorFactory, dictionary, isLenientParsing); var font = ParseType1Font(descriptor, isLenientParsing); var name = FontDictionaryAccessHelper.GetName(pdfScanner, dictionary, descriptor, isLenientParsing); CMap toUnicodeCMap = null; if (dictionary.TryGet(NameToken.ToUnicode, out var toUnicodeObj)) { var toUnicode = DirectObjectFinder.Get <StreamToken>(toUnicodeObj, pdfScanner); var decodedUnicodeCMap = toUnicode?.Decode(filterProvider); if (decodedUnicodeCMap != null) { toUnicodeCMap = cMapCache.Parse(new ByteArrayInputBytes(decodedUnicodeCMap), isLenientParsing); } } Encoding encoding = encodingReader.Read(dictionary, isLenientParsing, descriptor); if (encoding == null && font?.Encoding.Count > 0) { encoding = new BuiltInEncoding(font.Encoding); } return(new Type1FontSimple(name, firstCharacter, lastCharacter, widths, descriptor, encoding, toUnicodeCMap)); }
public IFont Generate(DictionaryToken dictionary, bool isLenientParsing) { if (!dictionary.TryGetOptionalTokenDirect(NameToken.FirstChar, pdfScanner, out NumericToken firstCharacterToken) || !dictionary.TryGet <IToken>(NameToken.FontDescriptor, pdfScanner, out _) || !dictionary.TryGet(NameToken.Widths, out IToken _)) { if (!dictionary.TryGetOptionalTokenDirect(NameToken.BaseFont, pdfScanner, out NameToken baseFont)) { throw new InvalidFontFormatException($"The provided TrueType font dictionary did not contain a /FirstChar or a /BaseFont entry: {dictionary}."); } // Can use the AFM descriptor despite not being Type 1! var standard14Font = Standard14.GetAdobeFontMetrics(baseFont.Data); if (standard14Font == null) { throw new InvalidFontFormatException($"The provided TrueType font dictionary did not have a /FirstChar and did not match a Standard 14 font: {dictionary}."); } var fileSystemFont = systemFontFinder.GetTrueTypeFont(baseFont.Data); var thisEncoding = encodingReader.Read(dictionary, isLenientParsing); if (thisEncoding == null) { thisEncoding = new AdobeFontMetricsEncoding(standard14Font); } int? firstChar = null; double[] widthsOverride = null; if (dictionary.TryGet(NameToken.FirstChar, pdfScanner, out firstCharacterToken)) { firstChar = firstCharacterToken.Int; } if (dictionary.TryGet(NameToken.Widths, pdfScanner, out ArrayToken widthsArray)) { widthsOverride = widthsArray.Data.OfType <NumericToken>() .Select(x => x.Double).ToArray(); } return(new TrueTypeStandard14FallbackSimpleFont(baseFont, standard14Font, thisEncoding, fileSystemFont, new TrueTypeStandard14FallbackSimpleFont.MetricOverrides(firstChar, widthsOverride))); } var firstCharacter = firstCharacterToken.Int; var widths = FontDictionaryAccessHelper.GetWidths(pdfScanner, dictionary, isLenientParsing); var descriptor = FontDictionaryAccessHelper.GetFontDescriptor(pdfScanner, fontDescriptorFactory, dictionary, isLenientParsing); 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); CMap toUnicodeCMap = null; if (dictionary.TryGet(NameToken.ToUnicode, out var toUnicodeObj)) { var toUnicode = DirectObjectFinder.Get <StreamToken>(toUnicodeObj, pdfScanner); var decodedUnicodeCMap = toUnicode.Decode(filterProvider); if (decodedUnicodeCMap != null) { toUnicodeCMap = CMapCache.Parse(new ByteArrayInputBytes(decodedUnicodeCMap), isLenientParsing); } } Encoding encoding = encodingReader.Read(dictionary, isLenientParsing, descriptor); if (encoding == null && font?.TableRegister?.CMapTable != null && font.TableRegister.PostScriptTable?.GlyphNames != null) { var postscript = font.TableRegister.PostScriptTable; // Synthesize an encoding var fakeEncoding = new Dictionary <int, string>(); for (var i = 0; i < 256; i++) { if (font.TableRegister.CMapTable.TryGetGlyphIndex(i, out var index)) { string glyphName; if (index >= 0 && index < postscript.GlyphNames.Count) { glyphName = postscript.GlyphNames[index]; } else { glyphName = index.ToString(); } fakeEncoding[i] = glyphName; } } encoding = new BuiltInEncoding(fakeEncoding); } return(new TrueTypeSimpleFont(name, descriptor, toUnicodeCMap, encoding, font, firstCharacter, widths)); }
public IFont Generate(DictionaryToken dictionary) { var usingStandard14Only = !dictionary.ContainsKey(NameToken.FirstChar) || !dictionary.ContainsKey(NameToken.Widths); if (usingStandard14Only) { // TODO: some fonts combine standard 14 font with other metrics. if (!dictionary.TryGet(NameToken.BaseFont, out var baseFontToken) || !(baseFontToken is NameToken standard14Name)) { throw new InvalidFontFormatException($"The Type 1 font did not contain a first character entry but also did not reference a standard 14 font: {dictionary}"); } var metrics = Standard14.GetAdobeFontMetrics(standard14Name.Data); if (metrics != null) { var overrideEncoding = encodingReader.Read(dictionary); return(new Type1Standard14Font(metrics, overrideEncoding)); } } int firstCharacter, lastCharacter; double[] widths; if (!usingStandard14Only) { firstCharacter = FontDictionaryAccessHelper.GetFirstCharacter(dictionary); lastCharacter = FontDictionaryAccessHelper.GetLastCharacter(dictionary); widths = FontDictionaryAccessHelper.GetWidths(pdfScanner, dictionary); } else { firstCharacter = 0; lastCharacter = 0; widths = EmptyArray <double> .Instance; } if (!dictionary.TryGet(NameToken.FontDescriptor, out var _)) { if (dictionary.TryGet(NameToken.BaseFont, out var baseFontToken) && DirectObjectFinder.TryGet(baseFontToken, pdfScanner, out NameToken baseFontName)) { var metrics = Standard14.GetAdobeFontMetrics(baseFontName.Data); var overrideEncoding = encodingReader.Read(dictionary); return(new Type1Standard14Font(metrics, overrideEncoding)); } } var descriptor = FontDictionaryAccessHelper.GetFontDescriptor(pdfScanner, dictionary); var font = ParseFontProgram(descriptor); var name = FontDictionaryAccessHelper.GetName(pdfScanner, dictionary, descriptor); CMap toUnicodeCMap = null; if (dictionary.TryGet(NameToken.ToUnicode, out var toUnicodeObj)) { var toUnicode = DirectObjectFinder.Get <StreamToken>(toUnicodeObj, pdfScanner); var decodedUnicodeCMap = toUnicode?.Decode(filterProvider, pdfScanner); if (decodedUnicodeCMap != null) { toUnicodeCMap = CMapCache.Parse(new ByteArrayInputBytes(decodedUnicodeCMap)); } } var fromFont = default(Encoding); if (font != null) { if (font.TryGetFirst(out var t1Font)) { fromFont = t1Font.Encoding != null ? new BuiltInEncoding(t1Font.Encoding) : default(Encoding); } else if (font.TryGetSecond(out var cffFont)) { fromFont = cffFont.FirstFont?.Encoding; } } var encoding = encodingReader.Read(dictionary, descriptor, fromFont); if (encoding == null && font != null && font.TryGetFirst(out var t1FontReplacment)) { encoding = new BuiltInEncoding(t1FontReplacment.Encoding); } return(new Type1FontSimple(name, firstCharacter, lastCharacter, widths, descriptor, encoding, toUnicodeCMap, font)); }