/// <inheritdoc /> /// <summary> /// Create a new <see cref="T:UglyToad.PdfPig.AcroForms.Fields.AcroSignatureField" />. /// </summary> public AcroSignatureField(DictionaryToken dictionary, string fieldType, uint fieldFlags, AcroFieldCommonInformation information, int?pageNumber, PdfRectangle?bounds) : base(dictionary, fieldType, fieldFlags, AcroFieldType.Signature, information, pageNumber, bounds) { }
internal ArtifactMarkedContentElement(int markedContentIdentifier, NameToken tag, DictionaryToken properties, string language, string actualText, string alternateDescription, string expandedForm, ArtifactType artifactType, string subType, string attributeOwners, PdfRectangle?boundingBox, IReadOnlyList <NameToken> attached, IReadOnlyList <MarkedContentElement> children, IReadOnlyList <Letter> letters, IReadOnlyList <PdfPath> paths, IReadOnlyList <IPdfImage> images, int index) : base(markedContentIdentifier, tag, properties, language, actualText, alternateDescription, expandedForm, true, children, letters, paths, images, index) { Type = artifactType; SubType = subType; AttributeOwners = attributeOwners; BoundingBox = boundingBox; Attached = attached ?? EmptyArray <NameToken> .Instance; }
/// <inheritdoc /> /// <summary> /// Create a new <see cref="AcroRadioButtonsField"/>. /// </summary> public AcroRadioButtonsField(DictionaryToken dictionary, string fieldType, AcroButtonFieldFlags fieldFlags, AcroFieldCommonInformation information, int?pageNumber, PdfRectangle?bounds) : base(dictionary, fieldType, (uint)fieldFlags, AcroFieldType.RadioButton, information, pageNumber, bounds) { Flags = fieldFlags; }
/// <inheritdoc /> /// <summary> /// Create a new <see cref="AcroRadioButtonField"/>. /// </summary> public AcroRadioButtonField(DictionaryToken dictionary, string fieldType, AcroButtonFieldFlags fieldFlags, AcroFieldCommonInformation information, int?pageNumber, PdfRectangle?bounds, NameToken currentValue, bool isSelected) : base(dictionary, fieldType, (uint)fieldFlags, AcroFieldType.RadioButton, information, pageNumber, bounds) { Flags = fieldFlags; CurrentValue = currentValue; IsSelected = isSelected; }
/// <inheritdoc /> /// <summary> /// Create a new <see cref="T:UglyToad.PdfPig.AcroForms.Fields.AcroTextField" />. /// </summary> /// <param name="dictionary">The dictionary for this field.</param> /// <param name="fieldType">The type of this field, must be <see cref="F:UglyToad.PdfPig.Tokens.NameToken.Ch" />.</param> /// <param name="fieldFlags">The flags specifying behaviour for this field.</param> /// <param name="information">Additional information for this field.</param> /// <param name="value">The text value.</param> /// <param name="maxLength">The maximum length.</param> /// <param name="pageNumber">The number of the page this field appears on.</param> /// <param name="bounds">The location of this field on the page.</param> public AcroTextField(DictionaryToken dictionary, string fieldType, AcroTextFieldFlags fieldFlags, AcroFieldCommonInformation information, string value, int?maxLength, int?pageNumber, PdfRectangle?bounds) : base(dictionary, fieldType, (uint)fieldFlags, AcroFieldType.Text, information, pageNumber, bounds) { Flags = fieldFlags; Value = value; MaxLength = maxLength; IsRichText = Flags.HasFlag(AcroTextFieldFlags.RichText); IsMultiline = Flags.HasFlag(AcroTextFieldFlags.Multiline); }
/// <summary> /// Create a new <see cref="AcroFieldBase"/>. /// </summary> /// <param name="dictionary">The dictionary for this field.</param> /// <param name="rawFieldType">The PDF string type of this field.</param> /// <param name="fieldFlags">The flags specifying behaviour for this field.</param> /// <param name="fieldType">The type of this field.</param> /// <param name="information">Additional information for this field.</param> /// <param name="pageNumber">The number of the page this field appears on.</param> /// <param name="bounds">The location of this field on the page.</param> protected AcroFieldBase(DictionaryToken dictionary, string rawFieldType, uint fieldFlags, AcroFieldType fieldType, AcroFieldCommonInformation information, int?pageNumber, PdfRectangle?bounds) { Dictionary = dictionary ?? throw new ArgumentNullException(nameof(dictionary)); RawFieldType = rawFieldType ?? throw new ArgumentNullException(nameof(rawFieldType)); FieldFlags = fieldFlags; FieldType = fieldType; Information = information ?? new AcroFieldCommonInformation(null, null, null, null); PageNumber = pageNumber; Bounds = bounds; }
/// <inheritdoc /> /// <summary> /// Create a new <see cref="T:UglyToad.PdfPig.AcroForms.Fields.AcroComboBoxField" />. /// </summary> /// <param name="dictionary">The dictionary for this field.</param> /// <param name="fieldType">The type of this field, must be <see cref="F:UglyToad.PdfPig.Tokens.NameToken.Ch" />.</param> /// <param name="fieldFlags">The flags specifying behaviour for this field.</param> /// <param name="information">Additional information for this field.</param> /// <param name="options">The options in this field.</param> /// <param name="selectedOptionIndices">The indices of the selected options where there are multiple with the same name.</param> /// <param name="selectedOptions">The names of the selected options.</param> /// <param name="pageNumber">The number of the page this field appears on.</param> /// <param name="bounds">The location of this field on the page.</param> public AcroComboBoxField(DictionaryToken dictionary, string fieldType, AcroChoiceFieldFlags fieldFlags, AcroFieldCommonInformation information, IReadOnlyList <AcroChoiceOption> options, IReadOnlyList <string> selectedOptions, IReadOnlyList <int> selectedOptionIndices, int?pageNumber, PdfRectangle?bounds) : base(dictionary, fieldType, (uint)fieldFlags, AcroFieldType.ComboBox, information, pageNumber, bounds) { Flags = fieldFlags; Options = options ?? throw new ArgumentNullException(nameof(options)); SelectedOptions = selectedOptions ?? throw new ArgumentNullException(nameof(selectedOptions)); SelectedOptionIndices = selectedOptionIndices; }
private PdfRectangle GetBoundingBoxInGlyphSpace(int characterCode) { if (characterCode < firstChar || characterCode > lastChar) { return(new PdfRectangle(0, 0, 250, 0)); } if (fontProgram == null) { return(new PdfRectangle(0, 0, widths[characterCode - firstChar], 0)); } PdfRectangle?rect = null; if (fontProgram.TryGetFirst(out var t1Font)) { var name = encoding.GetName(characterCode); rect = t1Font.GetCharacterBoundingBox(name); } else if (fontProgram.TryGetSecond(out var cffFont)) { var first = cffFont.FirstFont; string characterName; if (encoding != null) { characterName = encoding.GetName(characterCode); } else { characterName = cffFont.GetCharacterName(characterCode); } rect = first.GetCharacterBoundingBox(characterName); } if (!rect.HasValue) { return(new PdfRectangle(0, 0, widths[characterCode - firstChar], 0)); } // ReSharper disable once PossibleInvalidOperationException return(rect.Value); }
private AcroFieldBase GetTextField(DictionaryToken fieldDictionary, NameToken fieldType, uint fieldFlags, AcroFieldCommonInformation information, int?pageNumber, PdfRectangle?bounds) { var textFlags = (AcroTextFieldFlags)fieldFlags; var textValue = default(string); if (fieldDictionary.TryGet(NameToken.V, out var textValueToken)) { if (DirectObjectFinder.TryGet(textValueToken, tokenScanner, out StringToken valueStringToken)) { textValue = valueStringToken.Data; } else if (DirectObjectFinder.TryGet(textValueToken, tokenScanner, out HexToken valueHexToken)) { textValue = valueHexToken.Data; } else if (DirectObjectFinder.TryGet(textValueToken, tokenScanner, out StreamToken valueStreamToken)) { textValue = OtherEncodings.BytesAsLatin1String(valueStreamToken.Decode(filterProvider).ToArray()); } } var maxLength = default(int?); if (fieldDictionary.TryGetOptionalTokenDirect(NameToken.MaxLen, tokenScanner, out NumericToken maxLenToken)) { maxLength = maxLenToken.Int; } var field = new AcroTextField(fieldDictionary, fieldType, textFlags, information, textValue, maxLength, pageNumber, bounds); return(field); }
private AcroFieldBase GetChoiceField(DictionaryToken fieldDictionary, NameToken fieldType, uint fieldFlags, AcroFieldCommonInformation information, int?pageNumber, PdfRectangle?bounds) { var selectedOptions = EmptyArray <string> .Instance; if (fieldDictionary.TryGet(NameToken.V, out var valueToken)) { if (DirectObjectFinder.TryGet(valueToken, tokenScanner, out StringToken valueString)) { selectedOptions = new[] { valueString.Data }; } else if (DirectObjectFinder.TryGet(valueToken, tokenScanner, out HexToken valueHex)) { selectedOptions = new[] { valueHex.Data }; } else if (DirectObjectFinder.TryGet(valueToken, tokenScanner, out ArrayToken valueArray)) { selectedOptions = new string[valueArray.Length]; for (var i = 0; i < valueArray.Length; i++) { var valueOptToken = valueArray.Data[i]; if (DirectObjectFinder.TryGet(valueOptToken, tokenScanner, out StringToken valueOptString)) { selectedOptions[i] = valueOptString.Data; } else if (DirectObjectFinder.TryGet(valueOptToken, tokenScanner, out HexToken valueOptHex)) { selectedOptions[i] = valueOptHex.Data; } } } } var selectedIndices = default(int[]); if (fieldDictionary.TryGetOptionalTokenDirect(NameToken.I, tokenScanner, out ArrayToken indicesArray)) { selectedIndices = new int[indicesArray.Length]; for (var i = 0; i < indicesArray.Data.Count; i++) { var token = indicesArray.Data[i]; var numericToken = DirectObjectFinder.Get <NumericToken>(token, tokenScanner); selectedIndices[i] = numericToken.Int; } } var options = new List <AcroChoiceOption>(); if (fieldDictionary.TryGetOptionalTokenDirect(NameToken.Opt, tokenScanner, out ArrayToken optionsArrayToken)) { for (var i = 0; i < optionsArrayToken.Data.Count; i++) { var optionToken = optionsArrayToken.Data[i]; if (DirectObjectFinder.TryGet(optionToken, tokenScanner, out StringToken optionStringToken)) { var name = optionStringToken.Data; var isSelected = IsChoiceSelected(selectedOptions, selectedIndices, i, name); options.Add(new AcroChoiceOption(i, isSelected, optionStringToken.Data)); } else if (DirectObjectFinder.TryGet(optionToken, tokenScanner, out HexToken optionHexToken)) { var name = optionHexToken.Data; var isSelected = IsChoiceSelected(selectedOptions, selectedIndices, i, name); options.Add(new AcroChoiceOption(i, isSelected, optionHexToken.Data)); } else if (DirectObjectFinder.TryGet(optionToken, tokenScanner, out ArrayToken optionArrayToken)) { if (optionArrayToken.Length != 2) { throw new PdfDocumentFormatException($"An option array containing array elements should contain 2 strings, instead got: {optionArrayToken}."); } string exportValue; if (DirectObjectFinder.TryGet(optionArrayToken.Data[0], tokenScanner, out StringToken exportValueStringToken)) { exportValue = exportValueStringToken.Data; } else if (DirectObjectFinder.TryGet(optionArrayToken.Data[0], tokenScanner, out HexToken exportValueHexToken)) { exportValue = exportValueHexToken.Data; } else { throw new PdfDocumentFormatException($"An option array array element's first value should be the export value string, instead got: {optionArrayToken.Data[0]}."); } string name; if (DirectObjectFinder.TryGet(optionArrayToken.Data[1], tokenScanner, out StringToken nameStringToken)) { name = nameStringToken.Data; } else if (DirectObjectFinder.TryGet(optionArrayToken.Data[1], tokenScanner, out HexToken nameHexToken)) { name = nameHexToken.Data; } else { throw new PdfDocumentFormatException($"An option array array element's second value should be the option name string, instead got: {optionArrayToken.Data[1]}."); } var isSelected = IsChoiceSelected(selectedOptions, selectedIndices, i, name); options.Add(new AcroChoiceOption(i, isSelected, name, exportValue)); } else { throw new PdfDocumentFormatException($"An option array should contain either strings or 2 element arrays, instead got: {optionToken}."); } } } var choiceFlags = (AcroChoiceFieldFlags)fieldFlags; if (choiceFlags.HasFlag(AcroChoiceFieldFlags.Combo)) { var field = new AcroComboBoxField(fieldDictionary, fieldType, choiceFlags, information, options, selectedOptions, selectedIndices, pageNumber, bounds); return(field); } var topIndex = default(int?); if (fieldDictionary.TryGetOptionalTokenDirect(NameToken.Ti, tokenScanner, out NumericToken topIndexToken)) { topIndex = topIndexToken.Int; } return(new AcroListBoxField(fieldDictionary, fieldType, choiceFlags, information, options, selectedOptions, selectedIndices, topIndex, pageNumber, bounds)); }
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); }
public MediaBox(PdfRectangle?bounds) { Bounds = bounds ?? throw new ArgumentNullException(nameof(bounds)); }
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); }