Esempio n. 1
0
        private CMap ReadEncoding(DictionaryToken dictionary, out bool isCMapPredefined)
        {
            isCMapPredefined = false;
            CMap result = default(CMap);

            if (dictionary.TryGet(NameToken.Encoding, out var value))
            {
                if (value is NameToken encodingName)
                {
                    var cmap = cMapCache.Get(encodingName.Data);

                    result = cmap ?? throw new InvalidOperationException("Missing CMap for " + encodingName.Data);

                    isCMapPredefined = true;
                }
                else if (value is StreamToken stream)
                {
                    var decoded = stream.Decode(filterProvider);

                    var cmap = cMapCache.Parse(new ByteArrayInputBytes(decoded), false);

                    result = cmap ?? throw new InvalidOperationException("Could not read CMap for " + dictionary);
                }
                else
                {
                    throw new InvalidOperationException("Could not read the encoding, expected a name or a stream but got a: " + value.GetType().Name);
                }
            }

            return(result);
        }
Esempio n. 2
0
        private CMap ReadEncoding(DictionaryToken dictionary, out bool isCMapPredefined)
        {
            isCMapPredefined = false;
            CMap result;

            if (dictionary.TryGet(NameToken.Encoding, scanner, out NameToken encodingName))
            {
                var cmap = CMapCache.Get(encodingName.Data);

                result = cmap ?? throw new InvalidOperationException($"Missing CMap named {encodingName.Data}.");

                isCMapPredefined = true;
            }
            else if (dictionary.TryGet(NameToken.Encoding, scanner, out StreamToken stream))
            {
                var decoded = stream.Decode(filterProvider);

                var cmap = CMapCache.Parse(new ByteArrayInputBytes(decoded));

                result = cmap ?? throw new InvalidOperationException($"Could not read CMap from stream in the dictionary: {dictionary}");
            }
            else
            {
                throw new InvalidOperationException(
                          $"Could not read the encoding, expected a name or a stream but it was not found in the dictionary: {dictionary}");
            }

            return(result);
        }
Esempio n. 3
0
        public IFont Generate(DictionaryToken dictionary, bool isLenientParsing)
        {
            var baseFont = dictionary.GetNameOrDefault(NameToken.BaseFont);

            var cMap = ReadEncoding(dictionary, out var isCMapPredefined);

            ICidFont cidFont;

            if (TryGetFirstDescendant(dictionary, out var descendantObject))
            {
                DictionaryToken descendantFontDictionary;

                if (descendantObject is IndirectReferenceToken obj)
                {
                    var parsed = DirectObjectFinder.Get<DictionaryToken>(obj, scanner);

                    descendantFontDictionary = parsed;
                }
                else
                {
                    descendantFontDictionary = (DictionaryToken) descendantObject;
                }

                cidFont = ParseDescendant(descendantFontDictionary, isLenientParsing);
            }
            else
            {
                throw new InvalidFontFormatException("No descendant font dictionary was declared for this Type 0 font. This dictionary should contain the CIDFont for the Type 0 font. " + dictionary);
            }

            var (ucs2CMap, isChineseJapaneseOrKorean) = GetUcs2CMap(dictionary, isCMapPredefined, cidFont);

            CMap toUnicodeCMap = null;
            if (dictionary.ContainsKey(NameToken.ToUnicode))
            {
                var toUnicodeValue = dictionary.Data[NameToken.ToUnicode];

                if (DirectObjectFinder.TryGet<StreamToken>(toUnicodeValue, scanner, out var toUnicodeStream))
                {
                    var decodedUnicodeCMap = toUnicodeStream?.Decode(filterProvider);

                    if (decodedUnicodeCMap != null)
                    {
                        toUnicodeCMap = CMapCache.Parse(new ByteArrayInputBytes(decodedUnicodeCMap), isLenientParsing);
                    }
                }
                else if (DirectObjectFinder.TryGet<NameToken>(toUnicodeValue, scanner, out var toUnicodeName))
                {
                    toUnicodeCMap = CMapCache.Get(toUnicodeName.Data);
                }
                else
                {
                    throw new PdfDocumentFormatException($"Invalid type of toUnicode CMap encountered. Got: {toUnicodeValue}.");
                }
            }

            var font = new Type0Font(baseFont, cidFont, cMap, toUnicodeCMap, ucs2CMap, isChineseJapaneseOrKorean);

            return font;
        }
Esempio n. 4
0
        private static (CMap, bool isChineseJapaneseOrKorean) GetUcs2CMap(DictionaryToken dictionary, bool isCMapPredefined, ICidFont cidFont)
        {
            if (!isCMapPredefined)
            {
                return(null, false);
            }

            /*
             * If the font is a composite font that uses one of the predefined CMaps except Identity–H and Identity–V or whose descendant
             * CIDFont uses the Adobe-GB1, Adobe-CNS1, Adobe-Japan1, or Adobe-Korea1 character collection use a UCS2 CMap.
             */

            var encodingName = dictionary.GetNameOrDefault(NameToken.Encoding);

            if (encodingName == null)
            {
                return(null, false);
            }

            var isChineseJapaneseOrKorean = false;

            if (cidFont != null && string.Equals(cidFont.SystemInfo.Registry, "Adobe", StringComparison.OrdinalIgnoreCase))
            {
                isChineseJapaneseOrKorean = string.Equals(cidFont.SystemInfo.Ordering, "GB1", StringComparison.OrdinalIgnoreCase) ||
                                            string.Equals(cidFont.SystemInfo.Ordering, "CNS1", StringComparison.OrdinalIgnoreCase) ||
                                            string.Equals(cidFont.SystemInfo.Ordering, "Japan1", StringComparison.OrdinalIgnoreCase) ||
                                            string.Equals(cidFont.SystemInfo.Ordering, "Korea1", StringComparison.OrdinalIgnoreCase);
            }


            var isPredefinedIdentityMap = encodingName.Equals(NameToken.IdentityH) || encodingName.Equals(NameToken.IdentityV);

            if (isPredefinedIdentityMap && !isChineseJapaneseOrKorean)
            {
                return(null, false);
            }

            if (!isChineseJapaneseOrKorean)
            {
                return(null, false);
            }

            var fullCmapName   = cidFont.SystemInfo.ToString();
            var nonUnicodeCMap = CMapCache.Get(fullCmapName);

            if (nonUnicodeCMap == null)
            {
                return(null, true);
            }

            var unicodeCMapName = $"{nonUnicodeCMap.Info.Registry}-{nonUnicodeCMap.Info.Ordering}-UCS2";

            return(CMapCache.Get(unicodeCMapName), true);
        }