Example #1
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;
        }
Example #2
0
        public void LoadResourceDictionary(DictionaryToken resourceDictionary, bool isLenientParsing)
        {
            if (resourceDictionary.TryGet(NameToken.Font, out var fontBase))
            {
                var fontDictionary = DirectObjectFinder.Get <DictionaryToken>(fontBase, scanner);

                LoadFontDictionary(fontDictionary, isLenientParsing);
            }

            if (resourceDictionary.TryGet(NameToken.Xobject, out var xobjectBase))
            {
                var xobjectDictionary = DirectObjectFinder.Get <DictionaryToken>(xobjectBase, scanner);

                foreach (var pair in xobjectDictionary.Data)
                {
                    if (!(pair.Value is IndirectReferenceToken reference))
                    {
                        throw new InvalidOperationException($"Expected the XObject dictionary value for key /{pair.Key} to be an indirect reference, instead got: {pair.Value}.");
                    }

                    currentResourceState[NameToken.Create(pair.Key)] = reference.Data;
                }
            }

            if (resourceDictionary.TryGet(NameToken.ExtGState, scanner, out DictionaryToken extGStateDictionaryToken))
            {
                foreach (var pair in extGStateDictionaryToken.Data)
                {
                    var name  = NameToken.Create(pair.Key);
                    var state = DirectObjectFinder.Get <DictionaryToken>(pair.Value, scanner);

                    extendedGraphicsStates[name] = state;
                }
            }
        }
Example #3
0
        private ICidFontProgram ReadDescriptorFile(FontDescriptor descriptor)
        {
            if (descriptor?.FontFile == null)
            {
                return(null);
            }

            var fontFileStream = DirectObjectFinder.Get <StreamToken>(descriptor.FontFile.ObjectKey, pdfScanner);

            if (fontFileStream == null)
            {
                return(null);
            }

            var fontFile = fontFileStream.Decode(filterProvider);

            switch (descriptor.FontFile.FileType)
            {
            case DescriptorFontFile.FontFileType.TrueType:
                var input = new TrueTypeDataBytes(new ByteArrayInputBytes(fontFile));
                return(trueTypeFontParser.Parse(input));

            default:
                throw new NotSupportedException("Currently only TrueType fonts are supported.");
            }
        }
Example #4
0
        private TrueTypeFontProgram ParseTrueTypeFont(FontDescriptor descriptor)
        {
            if (descriptor?.FontFile == null)
            {
                // 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}.");
            }

            try
            {
                var fontFileStream = DirectObjectFinder.Get <StreamToken>(descriptor.FontFile.ObjectKey, pdfScanner);

                var fontFile = fontFileStream.Decode(filterProvider);

                var font = trueTypeFontParser.Parse(new TrueTypeDataBytes(new ByteArrayInputBytes(fontFile)));

                return(font);
            }
            catch (Exception ex)
            {
                log.Error("Could not parse the TrueType font.", ex);

                return(null);
            }
        }
Example #5
0
        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));
        }
Example #6
0
        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));
        }
Example #7
0
        private Encoding ReadEncodingDictionary(DictionaryToken encodingDictionary, Encoding fontEncoding)
        {
            Encoding baseEncoding;

            if (encodingDictionary.TryGet(NameToken.BaseEncoding, out var baseEncodingToken) && baseEncodingToken is NameToken baseEncodingName)
            {
                if (!Encoding.TryGetNamedEncoding(baseEncodingName, out baseEncoding))
                {
                    throw new InvalidFontFormatException($"No encoding found with name {baseEncodingName} to use as base encoding.");
                }
            }
            else
            {
                // TODO: This isn't true for non-symbolic fonts or latin fonts (based on OS?) see section 5.5.5
                baseEncoding = fontEncoding ?? StandardEncoding.Instance;
            }

            if (!encodingDictionary.TryGet(NameToken.Differences, out var differencesBase))
            {
                return(baseEncoding);
            }

            var differenceArray = DirectObjectFinder.Get <ArrayToken>(differencesBase, pdfScanner);

            var differences = ProcessDifferences(differenceArray);

            var newEncoding = new DifferenceBasedEncoding(baseEncoding, differences);

            return(newEncoding);
        }
Example #8
0
        private static DictionaryToken ParseTrailer(CrossReferenceTable crossReferenceTable, bool isLenientParsing, IPdfTokenScanner pdfTokenScanner,
                                                    out EncryptionDictionary encryptionDictionary)
        {
            encryptionDictionary = null;

            if (crossReferenceTable.Trailer.EncryptionToken != null)
            {
                if (!DirectObjectFinder.TryGet(crossReferenceTable.Trailer.EncryptionToken, pdfTokenScanner, out DictionaryToken encryptionDictionaryToken))
                {
                    throw new PdfDocumentFormatException($"Unrecognized encryption token in trailer: {crossReferenceTable.Trailer.EncryptionToken}.");
                }

                encryptionDictionary = EncryptionDictionaryFactory.Read(encryptionDictionaryToken, pdfTokenScanner);

                //throw new NotSupportedException("Cannot currently parse a document using encryption: " + crossReferenceTable.Trailer.EncryptionToken);
            }

            var rootDictionary = DirectObjectFinder.Get <DictionaryToken>(crossReferenceTable.Trailer.Root, pdfTokenScanner);

            if (!rootDictionary.ContainsKey(NameToken.Type) && isLenientParsing)
            {
                rootDictionary = rootDictionary.With(NameToken.Type, NameToken.Catalog);
            }

            return(rootDictionary);
        }
        public static decimal[] GetWidths(IPdfTokenScanner pdfScanner, DictionaryToken dictionary, bool isLenientParsing)
        {
            if (!dictionary.TryGet(NameToken.Widths, out var token))
            {
                throw new InvalidFontFormatException($"No widths array found for the font: {dictionary}.");
            }

            var widthArray = DirectObjectFinder.Get <ArrayToken>(token, pdfScanner);

            var result = new decimal[widthArray.Data.Count];

            for (int i = 0; i < widthArray.Data.Count; i++)
            {
                var arrayToken = widthArray.Data[i];

                if (!(arrayToken is NumericToken number))
                {
                    throw new InvalidFontFormatException($"Token which was not a number found in the widths array: {arrayToken}.");
                }

                result[i] = number.Data;
            }

            return(result);
        }
Example #10
0
        // This method is a basically a copy of the method UglyToad.PdfPig.Parser.PdfDocumentFactory.ParseTrailer()
        private static DictionaryToken ParseCatalog(CrossReferenceTable crossReferenceTable,
                                                    IPdfTokenScanner pdfTokenScanner,
                                                    out EncryptionDictionary encryptionDictionary)
        {
            encryptionDictionary = null;

            if (crossReferenceTable.Trailer.EncryptionToken != null)
            {
                if (!DirectObjectFinder.TryGet(crossReferenceTable.Trailer.EncryptionToken, pdfTokenScanner,
                                               out DictionaryToken encryptionDictionaryToken))
                {
                    throw new PdfDocumentFormatException($"Unrecognized encryption token in trailer: {crossReferenceTable.Trailer.EncryptionToken}.");
                }

                encryptionDictionary = EncryptionDictionaryFactory.Read(encryptionDictionaryToken, pdfTokenScanner);
            }

            var rootDictionary = DirectObjectFinder.Get <DictionaryToken>(crossReferenceTable.Trailer.Root, pdfTokenScanner);

            if (!rootDictionary.ContainsKey(NameToken.Type))
            {
                rootDictionary = rootDictionary.With(NameToken.Type, NameToken.Catalog);
            }

            return(rootDictionary);
        }
        private void LoadFontDictionary(DictionaryToken fontDictionary, bool isLenientParsing)
        {
            foreach (var pair in fontDictionary.Data)
            {
                if (!(pair.Value is IndirectReferenceToken objectKey))
                {
                    if (isLenientParsing)
                    {
                        continue;
                    }

                    throw new InvalidOperationException($"The font with name {pair.Key} did not link to an object key. Value was: {pair.Value}.");
                }

                var reference = objectKey.Data;

                currentResourceState[NameToken.Create(pair.Key)] = reference;

                if (loadedFonts.ContainsKey(reference))
                {
                    continue;
                }

                var fontObject = DirectObjectFinder.Get <DictionaryToken>(objectKey, scanner);

                if (fontObject == null)
                {
                    throw new InvalidOperationException($"Could not retrieve the font with name: {pair.Key} which should have been object {objectKey}");
                }

                loadedFonts[reference] = fontFactory.Get(fontObject, isLenientParsing);
            }
        }
Example #12
0
        public bool FindPage(DictionaryToken currentPageDictionary, int soughtPageNumber, List <int> pageNumbersObserved, PageTreeMembers pageTreeMembers)
        {
            var type = currentPageDictionary.GetNameOrDefault(NameToken.Type);

            if (type?.Equals(NameToken.Page) == true)
            {
                var pageNumber = GetNextPageNumber(pageNumbersObserved);

                bool found = pageNumber == soughtPageNumber;

                locatedPages[pageNumber] = currentPageDictionary;
                pageNumbersObserved.Add(pageNumber);

                return(found);
            }

            if (type?.Equals(NameToken.Pages) != true)
            {
                log.Warn("Did not find the expected type (Page or Pages) in dictionary: " + currentPageDictionary);

                return(false);
            }

            if (currentPageDictionary.TryGet(NameToken.MediaBox, out var token))
            {
                var mediaBox = DirectObjectFinder.Get <ArrayToken>(token, pdfScanner);

                pageTreeMembers.MediaBox = new MediaBox(new PdfRectangle(mediaBox.GetNumeric(0).Data,
                                                                         mediaBox.GetNumeric(1).Data,
                                                                         mediaBox.GetNumeric(2).Data,
                                                                         mediaBox.GetNumeric(3).Data));
            }

            if (!currentPageDictionary.TryGet(NameToken.Kids, out var kids) ||
                !(kids is ArrayToken kidsArray))
            {
                return(false);
            }

            pageFactory.LoadResources(currentPageDictionary, isLenientParsing);

            bool childFound = false;

            foreach (var kid in kidsArray.Data)
            {
                // todo: exit early
                var child = DirectObjectFinder.Get <DictionaryToken>(kid, pdfScanner);

                var thisPageMatches = FindPage(child, soughtPageNumber, pageNumbersObserved, pageTreeMembers);

                if (thisPageMatches)
                {
                    childFound = true;
                    break;
                }
            }

            return(childFound);
        }
Example #13
0
        private ICidFontProgram ReadDescriptorFile(FontDescriptor descriptor)
        {
            if (descriptor?.FontFile == null)
            {
                return(null);
            }

            var fontFileStream = DirectObjectFinder.Get <StreamToken>(descriptor.FontFile.ObjectKey, pdfScanner);

            if (fontFileStream == null)
            {
                return(null);
            }

            var fontFile = fontFileStream.Decode(filterProvider);

            switch (descriptor.FontFile.FileType)
            {
            case DescriptorFontFile.FontFileType.TrueType:
                var input = new TrueTypeDataBytes(new ByteArrayInputBytes(fontFile));
                return(trueTypeFontParser.Parse(input));

            case DescriptorFontFile.FontFileType.FromSubtype:
            {
                if (!DirectObjectFinder.TryGet(descriptor.FontFile.ObjectKey, pdfScanner, out StreamToken str))
                {
                    throw new NotSupportedException("Cannot read CID font from subtype.");
                }

                if (!str.StreamDictionary.TryGet(NameToken.Subtype, out NameToken subtypeName))
                {
                    throw new PdfDocumentFormatException($"The font file stream did not contain a subtype entry: {str.StreamDictionary}.");
                }

                if (subtypeName == NameToken.CidFontType0C)
                {
                    var bytes = str.Decode(filterProvider);
                    var font  = compactFontFormatParser.Parse(new CompactFontFormatData(bytes));
                    return(font);
                }

                if (subtypeName == NameToken.Type1C)
                {
                }
                else if (subtypeName == NameToken.OpenType)
                {
                }
                else
                {
                    throw new PdfDocumentFormatException($"Unexpected subtype for CID font: {subtypeName}.");
                }

                throw new NotSupportedException("Cannot read CID font from subtype.");
            }

            default:
                throw new NotSupportedException("Currently only TrueType fonts are supported.");
            }
        }
        public StreamToken GetXObject(NameToken name)
        {
            var reference = currentResourceState[name];

            var stream = DirectObjectFinder.Get <StreamToken>(new IndirectReferenceToken(reference), scanner);

            return(stream);
        }
Example #15
0
        public void LoadResourceDictionary(DictionaryToken resourceDictionary, bool isLenientParsing)
        {
            if (resourceDictionary.TryGet(NameToken.Font, out var fontBase))
            {
                var fontDictionary = DirectObjectFinder.Get <DictionaryToken>(fontBase, scanner);

                LoadFontDictionary(fontDictionary, isLenientParsing);
            }
        }
Example #16
0
        public void LoadResources(DictionaryToken dictionary, bool isLenientParsing)
        {
            if (!dictionary.TryGet(NameToken.Resources, out var token))
            {
                return;
            }

            var resources = DirectObjectFinder.Get <DictionaryToken>(token, pdfScanner);

            resourceStore.LoadResourceDictionary(resources, isLenientParsing);
        }
Example #17
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));
        }
Example #18
0
        public void GetTokenCanFollowMultipleReferenceLinks()
        {
            var reference1 = new IndirectReference(7, 0);
            var reference2 = new IndirectReference(9, 0);

            scanner.Objects[reference1] = new ObjectToken(10, reference1, new IndirectReferenceToken(reference2));
            scanner.Objects[reference2] = new ObjectToken(12, reference2, new NumericToken(69));

            var result = DirectObjectFinder.Get <NumericToken>(new IndirectReferenceToken(reference1), scanner);

            Assert.Equal(69, result.Int);
        }
Example #19
0
        public void GetThrowsOnInvalidArray()
        {
            var reference = new IndirectReference(10, 0);

            scanner.Objects[reference] = new ObjectToken(10, reference, new ArrayToken(new[]
            {
                new NumericToken(5), new NumericToken(6), new NumericToken(0)
            }));

            Action action = () => DirectObjectFinder.Get <StringToken>(reference, scanner);

            Assert.Throws <PdfDocumentFormatException>(action);
        }
Example #20
0
        private TransformationMatrix GetFontMatrix(DictionaryToken dictionary)
        {
            if (!dictionary.TryGet(NameToken.FontMatrix, out var matrixObject))
            {
                throw new InvalidFontFormatException($"No font matrix found: {dictionary}.");
            }

            var matrixArray = DirectObjectFinder.Get <ArrayToken>(matrixObject, scanner);

            return(TransformationMatrix.FromValues(matrixArray.GetNumeric(0).Double, matrixArray.GetNumeric(1).Double,
                                                   matrixArray.GetNumeric(2).Double, matrixArray.GetNumeric(3).Double, matrixArray.GetNumeric(4).Double,
                                                   matrixArray.GetNumeric(5).Double));
        }
Example #21
0
        internal static T Get <T>(this DictionaryToken dictionary, NameToken name, IPdfTokenScanner scanner) where T : IToken
        {
            if (!dictionary.TryGet(name, out var token) || !(token is T typedToken))
            {
                if (!(token is IndirectReferenceToken indirectReference))
                {
                    throw new PdfDocumentFormatException($"Dictionary does not contain token with name {name} of type {typeof(T).Name}.");
                }

                typedToken = DirectObjectFinder.Get <T>(indirectReference, scanner);
            }

            return(typedToken);
        }
        public static FontDescriptor GetFontDescriptor(IPdfTokenScanner pdfScanner, FontDescriptorFactory fontDescriptorFactory, DictionaryToken dictionary,
                                                       bool isLenientParsing)
        {
            if (!dictionary.TryGet(NameToken.FontDescriptor, out var obj))
            {
                throw new InvalidFontFormatException($"No font descriptor indirect reference found in the TrueType font: {dictionary}.");
            }

            var parsed = DirectObjectFinder.Get <DictionaryToken>(obj, pdfScanner);

            var descriptor = fontDescriptorFactory.Generate(parsed, pdfScanner, isLenientParsing);

            return(descriptor);
        }
Example #23
0
        public T Get <T>(NameToken name, IPdfTokenScanner scanner) where T : IToken
        {
            if (!TryGet(name, out var token) || !(token is T typedToken))
            {
                if (!(token is IndirectReferenceToken indirectReference))
                {
                    throw new InvalidOperationException($"Dictionary does not contain token with name {name} of type {typeof(T).Name}.");
                }

                typedToken = DirectObjectFinder.Get <T>(indirectReference, scanner);
            }

            return(typedToken);
        }
Example #24
0
        private static (IndirectReference, DictionaryToken) ParseTrailer(CrossReferenceTable crossReferenceTable, bool isLenientParsing, IPdfTokenScanner pdfTokenScanner,
                                                                         out EncryptionDictionary encryptionDictionary)
        {
            encryptionDictionary = GetEncryptionDictionary(crossReferenceTable, pdfTokenScanner);

            var rootDictionary = DirectObjectFinder.Get <DictionaryToken>(crossReferenceTable.Trailer.Root, pdfTokenScanner);

            if (!rootDictionary.ContainsKey(NameToken.Type) && isLenientParsing)
            {
                rootDictionary = rootDictionary.With(NameToken.Type, NameToken.Catalog);
            }

            return(crossReferenceTable.Trailer.Root, rootDictionary);
        }
Example #25
0
        private bool TryGetFontDescriptor(DictionaryToken dictionary, out DictionaryToken descriptorDictionary)
        {
            descriptorDictionary = null;

            if (!dictionary.TryGet(NameToken.FontDesc, out var baseValue))
            {
                return(false);
            }

            var descriptor = DirectObjectFinder.Get <DictionaryToken>(baseValue, pdfScanner);

            descriptorDictionary = descriptor;

            return(true);
        }
Example #26
0
        public void GetReturnsSingleItemFromArray()
        {
            var reference = new IndirectReference(10, 0);

            const string expected = "Goopy";

            scanner.Objects[reference] = new ObjectToken(10, reference, new ArrayToken(new []
            {
                new StringToken(expected)
            }));

            var result = DirectObjectFinder.Get <StringToken>(reference, scanner);

            Assert.Equal(expected, result.Data);
        }
        /// <summary>
        /// Convert the file trailer dictionary into a <see cref="DocumentInformation"/> instance.
        /// </summary>
        public static DocumentInformation Create(IPdfTokenScanner pdfTokenScanner, TrailerDictionary trailer, bool isLenientParsing)
        {
            if (!trailer.Info.HasValue)
            {
                return(DocumentInformation.Default);
            }

            var token = DirectObjectFinder.Get <IToken>(trailer.Info.Value, pdfTokenScanner);

            if (token is DictionaryToken infoParsed)
            {
                var title        = GetEntryOrDefault(infoParsed, NameToken.Title);
                var author       = GetEntryOrDefault(infoParsed, NameToken.Author);
                var subject      = GetEntryOrDefault(infoParsed, NameToken.Subject);
                var keywords     = GetEntryOrDefault(infoParsed, NameToken.Keywords);
                var creator      = GetEntryOrDefault(infoParsed, NameToken.Creator);
                var producer     = GetEntryOrDefault(infoParsed, NameToken.Producer);
                var creationDate = GetEntryOrDefault(infoParsed, NameToken.CreationDate);
                var modifiedDate = GetEntryOrDefault(infoParsed, NameToken.ModDate);

                return(new DocumentInformation(infoParsed, title, author, subject,
                                               keywords, creator, producer, creationDate, modifiedDate));
            }

            if (token is StreamToken streamToken)
            {
                var streamDictionary = streamToken.StreamDictionary;
                if (!streamDictionary.TryGet(NameToken.Type, out NameToken typeNameToken) || typeNameToken != "Metadata")
                {
                    throw new PdfDocumentFormatException("Unknown document metadata type was found");
                }

                if (!streamDictionary.TryGet(NameToken.Subtype, out NameToken subtypeToken) || subtypeToken != "XML")
                {
                    throw new PdfDocumentFormatException("Unknown document metadata subtype was found");
                }

                // We are not fully supporting XMP Stream so we let the user fully deserialize the stream
                return(DocumentInformation.Default);
            }

            if (isLenientParsing)
            {
                return(DocumentInformation.Default);
            }

            throw new PdfDocumentFormatException($"Unknown document information token was found {token.GetType().Name}");
        }
Example #28
0
        private static DictionaryToken ParseTrailer(CrossReferenceTable crossReferenceTable, bool isLenientParsing, IPdfTokenScanner pdfTokenScanner)
        {
            if (crossReferenceTable.Trailer.EncryptionToken != null)
            {
                throw new NotSupportedException("Cannot currently parse a document using encryption: " + crossReferenceTable.Trailer.EncryptionToken);
            }

            var rootDictionary = DirectObjectFinder.Get <DictionaryToken>(crossReferenceTable.Trailer.Root, pdfTokenScanner);

            if (!rootDictionary.ContainsKey(NameToken.Type) && isLenientParsing)
            {
                rootDictionary = rootDictionary.With(NameToken.Type, NameToken.Catalog);
            }

            return(rootDictionary);
        }
        public static NameToken GetName(IPdfTokenScanner pdfScanner, DictionaryToken dictionary, FontDescriptor descriptor, bool isLenientParsing)
        {
            if (dictionary.TryGet(NameToken.BaseFont, out var nameBase))
            {
                var name = DirectObjectFinder.Get <NameToken>(nameBase, pdfScanner);

                return(name);
            }

            if (descriptor.FontName != null)
            {
                return(descriptor.FontName);
            }

            throw new InvalidFontFormatException($"Could not find a name for this font {dictionary}.");
        }
Example #30
0
        public static PdfRectangle ToIntRectangle(this ArrayToken array, IPdfTokenScanner tokenScanner)
        {
            if (array == null)
            {
                throw new ArgumentNullException(nameof(array));
            }

            if (array.Data.Count != 4)
            {
                throw new PdfDocumentFormatException($"Cannot convert array to rectangle, expected 4 values instead got: {array}.");
            }

            return(new PdfRectangle(DirectObjectFinder.Get <NumericToken>(array[0], tokenScanner).Int,
                                    DirectObjectFinder.Get <NumericToken>(array[1], tokenScanner).Int,
                                    DirectObjectFinder.Get <NumericToken>(array[2], tokenScanner).Int,
                                    DirectObjectFinder.Get <NumericToken>(array[3], tokenScanner).Int));
        }