コード例 #1
0
        private AcroFieldBase GetAcroField(DictionaryToken fieldDictionary, Catalog catalog)
        {
            fieldDictionary.TryGet(NameToken.Ft, out NameToken fieldType);
            fieldDictionary.TryGet(NameToken.Ff, out NumericToken fieldFlagsToken);

            var kids = new List <DictionaryToken>();

            if (fieldDictionary.TryGetOptionalTokenDirect(NameToken.Kids, tokenScanner, out ArrayToken kidsToken))
            {
                foreach (var kid in kidsToken.Data)
                {
                    if (!(kid is IndirectReferenceToken kidReferenceToken))
                    {
                        throw new PdfDocumentFormatException($"AcroForm kids should only contain indirect reference, instead got: {kid}.");
                    }

                    var kidObject = tokenScanner.Get(kidReferenceToken.Data);

                    if (kidObject.Data is DictionaryToken kidDictionaryToken)
                    {
                        kids.Add(kidDictionaryToken);
                    }
                    else
                    {
                        throw new PdfDocumentFormatException($"Unexpected type of kid in AcroForm field. Expected dictionary but got: {kidObject.Data}.");
                    }
                }
            }

            fieldDictionary.TryGetOptionalStringDirect(NameToken.T, tokenScanner, out var partialFieldName);
            fieldDictionary.TryGetOptionalStringDirect(NameToken.Tu, tokenScanner, out var alternateFieldName);
            fieldDictionary.TryGetOptionalStringDirect(NameToken.Tm, tokenScanner, out var mappingName);
            fieldDictionary.TryGet(NameToken.Parent, out IndirectReferenceToken parentReferenceToken);
            var information = new AcroFieldCommonInformation(parentReferenceToken?.Data, partialFieldName, alternateFieldName, mappingName);

            int?pageNumber = null;

            if (fieldDictionary.TryGet(NameToken.P, tokenScanner, out IndirectReferenceToken pageReference))
            {
                pageNumber = catalog.GetPageByReference(pageReference.Data)?.PageNumber;
            }

            PdfRectangle?bounds = null;

            if (fieldDictionary.TryGet(NameToken.Rect, tokenScanner, out ArrayToken rectArray) && rectArray.Length == 4)
            {
                bounds = rectArray.ToRectangle();
            }

            var fieldFlags = (uint)(fieldFlagsToken?.Long ?? 0);

            AcroFieldBase result;

            if (fieldType == null)
            {
                var children = new List <AcroFieldBase>();
                foreach (var kid in kids)
                {
                    var kidField = GetAcroField(kid, catalog);
                    children.Add(kidField);
                }

                result = new AcroNonTerminalField(fieldDictionary, "Non-Terminal Field", fieldFlags, information, children);
            }
            else if (fieldType == NameToken.Btn)
            {
                var buttonFlags = (AcroButtonFieldFlags)fieldFlags;

                if (buttonFlags.HasFlag(AcroButtonFieldFlags.Radio))
                {
                    var field = new AcroRadioButtonsField(fieldDictionary, fieldType, buttonFlags, information,
                                                          pageNumber,
                                                          bounds);
                    result = field;
                }
                else if (buttonFlags.HasFlag(AcroButtonFieldFlags.PushButton))
                {
                    var field = new AcroPushButtonField(fieldDictionary, fieldType, buttonFlags, information,
                                                        pageNumber,
                                                        bounds);
                    result = field;
                }
                else
                {
                    var isChecked = false;
                    if (!fieldDictionary.TryGetOptionalTokenDirect(NameToken.V, tokenScanner, out NameToken valueToken))
                    {
                        valueToken = NameToken.Off;
                    }
                    else
                    {
                        isChecked = !string.Equals(valueToken.Data, NameToken.Off, StringComparison.OrdinalIgnoreCase);
                    }

                    var field = new AcroCheckboxField(fieldDictionary, fieldType, buttonFlags, information,
                                                      valueToken,
                                                      isChecked,
                                                      pageNumber,
                                                      bounds);

                    result = field;
                }
            }
            else if (fieldType == NameToken.Tx)
            {
                result = GetTextField(fieldDictionary, fieldType, fieldFlags, information, pageNumber, bounds);
            }
            else if (fieldType == NameToken.Ch)
            {
                result = GetChoiceField(fieldDictionary, fieldType, fieldFlags, information,
                                        pageNumber,
                                        bounds);
            }
            else if (fieldType == NameToken.Sig)
            {
                var field = new AcroSignatureField(fieldDictionary, fieldType, fieldFlags, information,
                                                   pageNumber,
                                                   bounds);
                result = field;
            }
            else
            {
                throw new PdfDocumentFormatException($"Unexpected type for field in AcroForm: {fieldType}.");
            }

            return(result);
        }
コード例 #2
0
ファイル: AcroFormFactory.cs プロジェクト: zyj0021/PdfPig
        private AcroFieldBase GetAcroField(DictionaryToken fieldDictionary, Catalog catalog,
                                           IReadOnlyList <DictionaryToken> parentDictionaries)
        {
            var(combinedFieldDictionary, inheritsValue) = CreateInheritedDictionary(fieldDictionary, parentDictionaries);

            fieldDictionary = combinedFieldDictionary;

            fieldDictionary.TryGet(NameToken.Ft, tokenScanner, out NameToken fieldType);
            fieldDictionary.TryGet(NameToken.Ff, tokenScanner, out NumericToken fieldFlagsToken);

            var kids = new List <(bool hasParent, DictionaryToken dictionary)>();

            if (fieldDictionary.TryGetOptionalTokenDirect(NameToken.Kids, tokenScanner, out ArrayToken kidsToken))
            {
                foreach (var kid in kidsToken.Data)
                {
                    if (!(kid is IndirectReferenceToken kidReferenceToken))
                    {
                        throw new PdfDocumentFormatException($"AcroForm kids should only contain indirect reference, instead got: {kid}.");
                    }

                    var kidObject = tokenScanner.Get(kidReferenceToken.Data);

                    if (kidObject.Data is DictionaryToken kidDictionaryToken)
                    {
                        var hasParent = kidDictionaryToken.TryGet(NameToken.Parent, out IndirectReferenceToken _);
                        kids.Add((hasParent, kidDictionaryToken));
                    }
                    else
                    {
                        throw new PdfDocumentFormatException($"Unexpected type of kid in AcroForm field. Expected dictionary but got: {kidObject.Data}.");
                    }
                }
            }

            fieldDictionary.TryGetOptionalStringDirect(NameToken.T, tokenScanner, out var partialFieldName);
            fieldDictionary.TryGetOptionalStringDirect(NameToken.Tu, tokenScanner, out var alternateFieldName);
            fieldDictionary.TryGetOptionalStringDirect(NameToken.Tm, tokenScanner, out var mappingName);
            fieldDictionary.TryGet(NameToken.Parent, out IndirectReferenceToken parentReferenceToken);
            var information = new AcroFieldCommonInformation(parentReferenceToken?.Data, partialFieldName, alternateFieldName, mappingName);

            int?pageNumber = null;

            if (fieldDictionary.TryGet(NameToken.P, tokenScanner, out IndirectReferenceToken pageReference))
            {
                pageNumber = catalog.GetPageByReference(pageReference.Data)?.PageNumber;
            }

            PdfRectangle?bounds = null;

            if (fieldDictionary.TryGet(NameToken.Rect, tokenScanner, out ArrayToken rectArray) && rectArray.Length == 4)
            {
                bounds = rectArray.ToRectangle(tokenScanner);
            }

            var newParentDictionaries = new List <DictionaryToken>(parentDictionaries)
            {
                fieldDictionary
            };

            var children = new List <AcroFieldBase>(kids.Count);

            foreach (var kid in kids)
            {
                if (!kid.hasParent)
                {
                    // Is a widget annotation dictionary.
                    continue;
                }

                children.Add(GetAcroField(kid.dictionary, catalog, newParentDictionaries));
            }

            var fieldFlags = (uint)(fieldFlagsToken?.Long ?? 0);

            AcroFieldBase result;

            if (fieldType == null)
            {
                result = new AcroNonTerminalField(fieldDictionary, "Non-Terminal Field", fieldFlags, information, AcroFieldType.Unknown, children);
            }
            else if (fieldType == NameToken.Btn)
            {
                var buttonFlags = (AcroButtonFieldFlags)fieldFlags;

                if (buttonFlags.HasFlag(AcroButtonFieldFlags.Radio))
                {
                    if (children.Count > 0)
                    {
                        result = new AcroRadioButtonsField(fieldDictionary, fieldType, buttonFlags, information,
                                                           children);
                    }
                    else
                    {
                        var(isChecked, valueToken) = GetCheckedState(fieldDictionary, inheritsValue);

                        var field = new AcroRadioButtonField(fieldDictionary, fieldType, buttonFlags, information,
                                                             pageNumber,
                                                             bounds,
                                                             valueToken,
                                                             isChecked);

                        result = field;
                    }
                }
                else if (buttonFlags.HasFlag(AcroButtonFieldFlags.PushButton))
                {
                    var field = new AcroPushButtonField(fieldDictionary, fieldType, buttonFlags, information,
                                                        pageNumber,
                                                        bounds);
                    result = field;
                }
                else
                {
                    if (children.Count > 0)
                    {
                        result = new AcroCheckboxesField(fieldDictionary, fieldType, buttonFlags, information,
                                                         children);
                    }
                    else
                    {
                        var(isChecked, valueToken) = GetCheckedState(fieldDictionary, inheritsValue);
                        var field = new AcroCheckboxField(fieldDictionary, fieldType, buttonFlags, information,
                                                          valueToken,
                                                          isChecked,
                                                          pageNumber,
                                                          bounds);

                        result = field;
                    }
                }
            }
            else if (fieldType == NameToken.Tx)
            {
                result = GetTextField(fieldDictionary, fieldType, fieldFlags, information, pageNumber, bounds);
            }
            else if (fieldType == NameToken.Ch)
            {
                result = GetChoiceField(fieldDictionary, fieldType, fieldFlags, information,
                                        pageNumber,
                                        bounds);
            }
            else if (fieldType == NameToken.Sig)
            {
                var field = new AcroSignatureField(fieldDictionary, fieldType, fieldFlags, information,
                                                   pageNumber,
                                                   bounds);
                result = field;
            }
            else
            {
                throw new PdfDocumentFormatException($"Unexpected type for field in AcroForm: {fieldType}.");
            }

            return(result);
        }
コード例 #3
0
ファイル: AcroFormFactory.cs プロジェクト: rbanks54/PdfPig
        private AcroFieldBase GetAcroField(DictionaryToken fieldDictionary)
        {
            fieldDictionary.TryGet(NameToken.Ft, out NameToken fieldType);
            fieldDictionary.TryGet(NameToken.Ff, out NumericToken fieldFlagsToken);

            var kids = new List <DictionaryToken>();

            if (fieldDictionary.TryGetOptionalTokenDirect(NameToken.Kids, tokenScanner, out ArrayToken kidsToken))
            {
                foreach (var kid in kidsToken.Data)
                {
                    if (!(kid is IndirectReferenceToken kidReferenceToken))
                    {
                        throw new PdfDocumentFormatException($"AcroForm kids should only contain indirect reference, instead got: {kid}.");
                    }

                    var kidObject = tokenScanner.Get(kidReferenceToken.Data);

                    if (kidObject.Data is DictionaryToken kidDictionaryToken)
                    {
                        kids.Add(kidDictionaryToken);
                    }
                    else
                    {
                        throw new PdfDocumentFormatException($"Unexpected type of kid in AcroForm field. Expected dictionary but got: {kidObject.Data}.");
                    }
                }
            }

            fieldDictionary.TryGetOptionalStringDirect(NameToken.T, tokenScanner, out var partialFieldName);
            fieldDictionary.TryGetOptionalStringDirect(NameToken.Tu, tokenScanner, out var alternateFieldName);
            fieldDictionary.TryGetOptionalStringDirect(NameToken.Tm, tokenScanner, out var mappingName);
            fieldDictionary.TryGet(NameToken.Parent, out IndirectReferenceToken parentReferenceToken);
            var information = new AcroFieldCommonInformation(parentReferenceToken?.Data, partialFieldName, alternateFieldName, mappingName);


            var fieldFlags = (uint)(fieldFlagsToken?.Long ?? 0);

            AcroFieldBase result;

            if (fieldType == null)
            {
                var children = new List <AcroFieldBase>();
                foreach (var kid in kids)
                {
                    var kidField = GetAcroField(kid);
                    children.Add(kidField);
                }

                result = new NonTerminalAcroField(fieldDictionary, "Non-Terminal Field", fieldFlags, information, children);
            }
            else if (fieldType == NameToken.Btn)
            {
                var buttonFlags = (AcroButtonFieldFlags)fieldFlags;

                if (buttonFlags.HasFlag(AcroButtonFieldFlags.Radio))
                {
                    var field = new AcroRadioButtonsField(fieldDictionary, fieldType, buttonFlags, information);
                    result = field;
                }
                else if (buttonFlags.HasFlag(AcroButtonFieldFlags.PushButton))
                {
                    var field = new AcroPushButtonField(fieldDictionary, fieldType, buttonFlags, information);
                    result = field;
                }
                else
                {
                    if (!fieldDictionary.TryGetOptionalTokenDirect(NameToken.V, tokenScanner, out NameToken valueToken))
                    {
                        valueToken = NameToken.Off;
                    }

                    var field = new AcroCheckboxField(fieldDictionary, fieldType, buttonFlags, information, valueToken);
                    result = field;
                }
            }
            else if (fieldType == NameToken.Tx)
            {
                result = GetTextField(fieldDictionary, fieldType, fieldFlags, information);
            }
            else if (fieldType == NameToken.Ch)
            {
                result = GetChoiceField(fieldDictionary, fieldType, fieldFlags, information);
            }
            else if (fieldType == NameToken.Sig)
            {
                var field = new AcroSignatureField(fieldDictionary, fieldType, fieldFlags, information);
                result = field;
            }
            else
            {
                throw new PdfDocumentFormatException($"Unexpected type for field in AcroForm: {fieldType}.");
            }

            return(result);
        }