Skip to content

Commit 3e81b6b

Browse files
rnadvodnyiText-CI
authored andcommitted
Create a copy for form field with name contains dot symbol
DEVSIX-2187 Autoported commit. Original commit hash: [3f045676f]
1 parent 0e17d65 commit 3e81b6b

File tree

7 files changed

+169
-93
lines changed

7 files changed

+169
-93
lines changed

itext.tests/itext.forms.tests/itext/forms/PdfFormCopyTest.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ public virtual void CopyFieldsTest05() {
171171
/// <exception cref="System.IO.IOException"/>
172172
/// <exception cref="System.Exception"/>
173173
[NUnit.Framework.Test]
174-
[LogMessage(iText.IO.LogMessageConstant.DOCUMENT_ALREADY_HAS_FIELD, Count = 2)]
174+
[LogMessage(iText.IO.LogMessageConstant.DOCUMENT_ALREADY_HAS_FIELD, Count = 4)]
175175
public virtual void CopyMultipleSubfieldsTest01() {
176176
String srcFilename = sourceFolder + "copyMultipleSubfieldsTest01.pdf";
177177
String destFilename = destinationFolder + "copyMultipleSubfieldsTest01.pdf";
@@ -342,6 +342,27 @@ public virtual void CopyFieldsTest12() {
342342
, destinationFolder, "diff_"));
343343
}
344344

345+
/// <exception cref="System.IO.IOException"/>
346+
/// <exception cref="System.Exception"/>
347+
[NUnit.Framework.Test]
348+
[LogMessage(iText.IO.LogMessageConstant.DOCUMENT_ALREADY_HAS_FIELD, Count = 1)]
349+
public virtual void CopyFieldsTest13() {
350+
String srcFilename = sourceFolder + "copyFields13.pdf";
351+
String destFilename = destinationFolder + "copyFields13.pdf";
352+
PdfDocument srcDoc = new PdfDocument(new PdfReader(srcFilename));
353+
PdfDocument destDoc = new PdfDocument(new PdfWriter(destFilename));
354+
PdfPageFormCopier pdfPageFormCopier = new PdfPageFormCopier();
355+
for (int i = 0; i < 1; ++i) {
356+
srcDoc.CopyPagesTo(1, 1, destDoc, pdfPageFormCopier);
357+
}
358+
PdfAcroForm acroForm = PdfAcroForm.GetAcroForm(destDoc, false);
359+
acroForm.GetField("text").SetValue("Text!");
360+
destDoc.Close();
361+
srcDoc.Close();
362+
NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(destFilename, sourceFolder + "cmp_copyFields13.pdf"
363+
, destinationFolder, "diff_"));
364+
}
365+
345366
/// <exception cref="System.IO.IOException"/>
346367
/// <exception cref="System.Exception"/>
347368
[NUnit.Framework.Test]

itext/itext.forms/itext/forms/PdfPageFormCopier.cs

Lines changed: 145 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ namespace iText.Forms {
5757
/// <remarks>
5858
/// A sample implementation of the {#link IPdfPageExtraCopier} interface which
5959
/// copies only AcroForm fields to a new page.
60+
/// <p>
61+
/// <p>
6062
/// NOTE: While it's absolutely not necessary to use the same PdfPageFormCopier instance for copying operations,
6163
/// it is still worth to know that PdfPageFormCopier uses some caching logic which can potentially improve performance
6264
/// in case of the reusing of the same instance.
@@ -81,93 +83,110 @@ public virtual void Copy(PdfPage fromPage, PdfPage toPage) {
8183
documentTo = toPage.GetDocument();
8284
formTo = PdfAcroForm.GetAcroForm(documentTo, true);
8385
}
84-
if (formFrom != null) {
85-
//duplicate AcroForm dictionary
86-
IList<PdfName> excludedKeys = new List<PdfName>();
87-
excludedKeys.Add(PdfName.Fields);
88-
excludedKeys.Add(PdfName.DR);
89-
PdfDictionary dict = formFrom.GetPdfObject().CopyTo(documentTo, excludedKeys, false);
90-
formTo.GetPdfObject().MergeDifferent(dict);
86+
if (formFrom == null) {
87+
return;
9188
}
92-
if (formFrom != null) {
93-
IDictionary<String, PdfFormField> fieldsFrom = formFrom.GetFormFields();
94-
if (fieldsFrom.Count > 0) {
95-
IDictionary<String, PdfFormField> fieldsTo = formTo.GetFormFields();
96-
IList<PdfAnnotation> annots = toPage.GetAnnotations();
97-
foreach (PdfAnnotation annot in annots) {
98-
if (annot.GetSubtype().Equals(PdfName.Widget)) {
99-
PdfDictionary parent = annot.GetPdfObject().GetAsDictionary(PdfName.Parent);
100-
if (parent != null) {
101-
PdfFormField parentField = GetParentField(parent, documentTo);
102-
PdfString parentName = parentField.GetFieldName();
103-
if (parentName == null) {
104-
continue;
105-
}
106-
if (!fieldsTo.ContainsKey(parentName.ToUnicodeString())) {
107-
PdfFormField field = CreateParentFieldCopy(annot.GetPdfObject(), documentTo);
108-
PdfArray kids = field.GetKids();
109-
field.GetPdfObject().Remove(PdfName.Kids);
110-
formTo.AddField(field, toPage);
111-
field.GetPdfObject().Put(PdfName.Kids, kids);
112-
}
113-
else {
114-
PdfFormField field = PdfFormField.MakeFormField(annot.GetPdfObject(), documentTo);
115-
PdfString fieldName = field.GetFieldName();
116-
if (fieldName != null) {
117-
PdfFormField existingField = fieldsTo.Get(fieldName.ToUnicodeString());
118-
if (existingField != null) {
119-
PdfFormField clonedField = PdfFormField.MakeFormField(field.GetPdfObject().Clone().MakeIndirect(documentTo
120-
), documentTo);
121-
toPage.GetPdfObject().GetAsArray(PdfName.Annots).Add(clonedField.GetPdfObject());
122-
toPage.RemoveAnnotation(annot);
123-
MergeFieldsWithTheSameName(clonedField);
124-
}
125-
else {
126-
HashSet<String> existingFields = new HashSet<String>();
127-
GetAllFieldNames(formTo.GetFields(), existingFields);
128-
AddChildToExistingParent(annot.GetPdfObject(), existingFields);
129-
}
130-
}
131-
else {
132-
if (!parentField.GetKids().Contains(field.GetPdfObject())) {
133-
HashSet<String> existingFields = new HashSet<String>();
134-
GetAllFieldNames(formTo.GetFields(), existingFields);
135-
AddChildToExistingParent(annot.GetPdfObject(), existingFields);
136-
}
137-
}
138-
}
139-
}
140-
else {
141-
PdfString annotName = annot.GetPdfObject().GetAsString(PdfName.T);
142-
String annotNameString = null;
143-
if (annotName != null) {
144-
annotNameString = annotName.ToUnicodeString();
145-
}
146-
if (annotNameString != null && fieldsFrom.ContainsKey(annotNameString)) {
147-
PdfFormField field = fieldsTo.Get(annotNameString);
148-
if (field != null) {
149-
PdfDictionary clonedAnnot = (PdfDictionary)annot.GetPdfObject().Clone().MakeIndirect(documentTo);
150-
toPage.GetPdfObject().GetAsArray(PdfName.Annots).Add(clonedAnnot);
151-
toPage.RemoveAnnotation(annot);
152-
field = MergeFieldsWithTheSameName(PdfFormField.MakeFormField(clonedAnnot, toPage.GetDocument()));
153-
logger.Warn(MessageFormatUtil.Format(iText.IO.LogMessageConstant.DOCUMENT_ALREADY_HAS_FIELD, annotNameString
154-
));
155-
PdfArray kids = field.GetKids();
156-
if (kids != null) {
157-
field.GetPdfObject().Remove(PdfName.Kids);
158-
formTo.AddField(field, toPage);
159-
field.GetPdfObject().Put(PdfName.Kids, kids);
160-
}
161-
else {
162-
formTo.AddField(field, toPage);
163-
}
164-
}
165-
else {
166-
formTo.AddField(PdfFormField.MakeFormField(annot.GetPdfObject(), documentTo), null);
167-
}
168-
}
169-
}
170-
}
89+
//duplicate AcroForm dictionary
90+
IList<PdfName> excludedKeys = new List<PdfName>();
91+
excludedKeys.Add(PdfName.Fields);
92+
excludedKeys.Add(PdfName.DR);
93+
PdfDictionary dict = formFrom.GetPdfObject().CopyTo(documentTo, excludedKeys, false);
94+
formTo.GetPdfObject().MergeDifferent(dict);
95+
IDictionary<String, PdfFormField> fieldsFrom = formFrom.GetFormFields();
96+
if (fieldsFrom.Count <= 0) {
97+
return;
98+
}
99+
IDictionary<String, PdfFormField> fieldsTo = formTo.GetFormFields();
100+
IList<PdfAnnotation> annots = toPage.GetAnnotations();
101+
foreach (PdfAnnotation annot in annots) {
102+
if (!annot.GetSubtype().Equals(PdfName.Widget)) {
103+
continue;
104+
}
105+
CopyField(toPage, fieldsFrom, fieldsTo, annot);
106+
}
107+
}
108+
109+
private void CopyField(PdfPage toPage, IDictionary<String, PdfFormField> fieldsFrom, IDictionary<String, PdfFormField
110+
> fieldsTo, PdfAnnotation currentAnnot) {
111+
PdfDictionary parent = currentAnnot.GetPdfObject().GetAsDictionary(PdfName.Parent);
112+
if (parent != null) {
113+
PdfFormField parentField = GetParentField(parent, documentTo);
114+
PdfString parentName = parentField.GetFieldName();
115+
if (parentName == null) {
116+
return;
117+
}
118+
CopyParentFormField(toPage, fieldsTo, currentAnnot, parentField);
119+
}
120+
else {
121+
PdfString annotName = currentAnnot.GetPdfObject().GetAsString(PdfName.T);
122+
String annotNameString = null;
123+
if (annotName != null) {
124+
annotNameString = annotName.ToUnicodeString();
125+
}
126+
if (annotNameString != null && fieldsFrom.ContainsKey(annotNameString)) {
127+
PdfFormField field = fieldsTo.Get(annotNameString);
128+
if (field == null) {
129+
formTo.AddField(PdfFormField.MakeFormField(currentAnnot.GetPdfObject(), documentTo), null);
130+
}
131+
else {
132+
CopyExistingField(toPage, currentAnnot, annotNameString);
133+
}
134+
}
135+
}
136+
}
137+
138+
private void CopyExistingField(PdfPage toPage, PdfAnnotation currentAnnot, String annotNameString) {
139+
PdfFormField field;
140+
PdfDictionary clonedAnnot = (PdfDictionary)currentAnnot.GetPdfObject().Clone().MakeIndirect(documentTo);
141+
toPage.GetPdfObject().GetAsArray(PdfName.Annots).Add(clonedAnnot);
142+
toPage.RemoveAnnotation(currentAnnot);
143+
field = MergeFieldsWithTheSameName(PdfFormField.MakeFormField(clonedAnnot, toPage.GetDocument()));
144+
logger.Warn(MessageFormatUtil.Format(iText.IO.LogMessageConstant.DOCUMENT_ALREADY_HAS_FIELD, annotNameString
145+
));
146+
PdfArray kids = field.GetKids();
147+
if (kids != null) {
148+
field.GetPdfObject().Remove(PdfName.Kids);
149+
formTo.AddField(field, toPage);
150+
field.GetPdfObject().Put(PdfName.Kids, kids);
151+
}
152+
else {
153+
formTo.AddField(field, toPage);
154+
}
155+
}
156+
157+
private void CopyParentFormField(PdfPage toPage, IDictionary<String, PdfFormField> fieldsTo, PdfAnnotation
158+
annot, PdfFormField parentField) {
159+
PdfString parentName = parentField.GetFieldName();
160+
if (!fieldsTo.ContainsKey(parentName.ToUnicodeString())) {
161+
PdfFormField field = CreateParentFieldCopy(annot.GetPdfObject(), documentTo);
162+
PdfArray kids = field.GetKids();
163+
field.GetPdfObject().Remove(PdfName.Kids);
164+
formTo.AddField(field, toPage);
165+
field.GetPdfObject().Put(PdfName.Kids, kids);
166+
}
167+
else {
168+
PdfFormField field = PdfFormField.MakeFormField(annot.GetPdfObject(), documentTo);
169+
PdfString fieldName = field.GetFieldName();
170+
if (fieldName != null) {
171+
PdfFormField existingField = fieldsTo.Get(fieldName.ToUnicodeString());
172+
if (existingField != null) {
173+
PdfFormField clonedField = PdfFormField.MakeFormField(field.GetPdfObject().Clone().MakeIndirect(documentTo
174+
), documentTo);
175+
toPage.GetPdfObject().GetAsArray(PdfName.Annots).Add(clonedField.GetPdfObject());
176+
toPage.RemoveAnnotation(annot);
177+
MergeFieldsWithTheSameName(clonedField);
178+
}
179+
else {
180+
HashSet<String> existingFields = new HashSet<String>();
181+
GetAllFieldNames(formTo.GetFields(), existingFields);
182+
AddChildToExistingParent(annot.GetPdfObject(), existingFields, fieldsTo, toPage, annot);
183+
}
184+
}
185+
else {
186+
if (!parentField.GetKids().Contains(field.GetPdfObject())) {
187+
HashSet<String> existingFields = new HashSet<String>();
188+
GetAllFieldNames(formTo.GetFields(), existingFields);
189+
AddChildToExistingParent(annot.GetPdfObject(), existingFields);
171190
}
172191
}
173192
}
@@ -233,18 +252,26 @@ private PdfFormField GetParentField(PdfDictionary parent, PdfDocument pdfDoc) {
233252
}
234253

235254
private PdfFormField CreateParentFieldCopy(PdfDictionary fieldDic, PdfDocument pdfDoc) {
236-
fieldDic.Remove(PdfName.Kids);
237255
PdfDictionary parent = fieldDic.GetAsDictionary(PdfName.Parent);
238256
PdfFormField field = PdfFormField.MakeFormField(fieldDic, pdfDoc);
239257
if (parent != null) {
240258
field = CreateParentFieldCopy(parent, pdfDoc);
241-
parent.Put(PdfName.Kids, new PdfArray(fieldDic));
259+
PdfArray kids = (PdfArray)parent.Get(PdfName.Kids);
260+
if (kids == null) {
261+
parent.Put(PdfName.Kids, new PdfArray(fieldDic));
262+
}
263+
else {
264+
kids.Add(fieldDic);
265+
}
242266
}
243267
return field;
244268
}
245269

246270
private void AddChildToExistingParent(PdfDictionary fieldDic, ICollection<String> existingFields) {
247271
PdfDictionary parent = fieldDic.GetAsDictionary(PdfName.Parent);
272+
if (parent == null) {
273+
return;
274+
}
248275
PdfString parentName = parent.GetAsString(PdfName.T);
249276
if (parentName != null) {
250277
String name = parentName.ToUnicodeString();
@@ -259,6 +286,36 @@ private void AddChildToExistingParent(PdfDictionary fieldDic, ICollection<String
259286
}
260287
}
261288

289+
private void AddChildToExistingParent(PdfDictionary fieldDic, ICollection<String> existingFields, IDictionary
290+
<String, PdfFormField> fieldsTo, PdfPage toPage, PdfAnnotation annot) {
291+
PdfDictionary parent = fieldDic.GetAsDictionary(PdfName.Parent);
292+
if (parent == null) {
293+
return;
294+
}
295+
PdfString parentName = parent.GetAsString(PdfName.T);
296+
if (parentName != null) {
297+
String name = parentName.ToUnicodeString();
298+
if (existingFields.Contains(name)) {
299+
PdfArray kids = parent.GetAsArray(PdfName.Kids);
300+
foreach (PdfObject kid in kids) {
301+
if (((PdfDictionary)kid).Get(PdfName.T).Equals(fieldDic.Get(PdfName.T))) {
302+
PdfFormField kidField = PdfFormField.MakeFormField(kid, documentTo);
303+
fieldsTo.Put(kidField.GetFieldName().ToUnicodeString(), kidField);
304+
logger.Warn(MessageFormatUtil.Format(iText.IO.LogMessageConstant.DOCUMENT_ALREADY_HAS_FIELD, kidField.GetFieldName
305+
().ToUnicodeString()));
306+
MergeFieldsWithTheSameName(PdfFormField.MakeFormField(fieldDic, documentTo));
307+
return;
308+
}
309+
}
310+
kids.Add(fieldDic);
311+
}
312+
else {
313+
parent.Put(PdfName.Kids, new PdfArray(fieldDic));
314+
AddChildToExistingParent(parent, existingFields);
315+
}
316+
}
317+
}
318+
262319
private void GetAllFieldNames(PdfArray fields, ICollection<String> existingFields) {
263320
foreach (PdfObject field in fields) {
264321
if (field.IsFlushed()) {

itext/itext.kernel/itext/kernel/pdf/PdfPage.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1653,10 +1653,8 @@ private void RebuildFormFieldParent(PdfDictionary field, PdfDictionary newField,
16531653
RebuildFormFieldParent(oldParent, newParent, toDocument);
16541654
PdfArray kids = newParent.GetAsArray(PdfName.Kids);
16551655
if (kids == null) {
1656-
kids = new PdfArray();
1657-
newParent.Put(PdfName.Kids, kids);
1656+
newParent.Put(PdfName.Kids, new PdfArray());
16581657
}
1659-
kids.Add(newField);
16601658
newField.Put(PdfName.Parent, newParent);
16611659
}
16621660
}

port-hash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
5b04a612e5541d864c1d8bbc4932176e39ece268
1+
3f045676f1eca3102cbac51dc826cfcee0cf1329

0 commit comments

Comments
 (0)