示例#1
0
        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));
        }
示例#2
0
        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));
        }
示例#3
0
        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));
        }