@@ -69,19 +69,16 @@ This file is part of the iText (R) project.
69
69
import com .itextpdf .kernel .pdf .tagutils .TagReference ;
70
70
import com .itextpdf .kernel .pdf .tagutils .TagTreePointer ;
71
71
import com .itextpdf .kernel .pdf .xobject .PdfFormXObject ;
72
+ import org .slf4j .Logger ;
73
+ import org .slf4j .LoggerFactory ;
72
74
73
- import java .util .ArrayList ;
74
75
import java .util .Collection ;
75
76
import java .util .Collections ;
76
77
import java .util .LinkedHashMap ;
77
78
import java .util .LinkedHashSet ;
78
- import java .util .List ;
79
79
import java .util .Map ;
80
80
import java .util .Set ;
81
81
82
- import org .slf4j .Logger ;
83
- import org .slf4j .LoggerFactory ;
84
-
85
82
/**
86
83
* This class represents the static form technology AcroForm on a PDF file.
87
84
*/
@@ -134,10 +131,10 @@ public class PdfAcroForm extends PdfObjectWrapper<PdfDictionary> {
134
131
*/
135
132
protected PdfDocument document ;
136
133
137
- private static PdfName [] resourceNames = {PdfName .Font , PdfName .XObject , PdfName .ColorSpace , PdfName .Pattern };
138
134
private PdfDictionary defaultResources ;
139
135
private Set <PdfFormField > fieldsForFlattening = new LinkedHashSet <>();
140
136
private XfaForm xfaForm ;
137
+ private static Logger logger = LoggerFactory .getLogger (PdfAcroForm .class );
141
138
142
139
/**
143
140
* Creates a PdfAcroForm as a wrapper of a dictionary.
@@ -235,17 +232,6 @@ public void addField(PdfFormField field, PdfPage page) {
235
232
iterateFields (field .getKids (), fields );
236
233
}
237
234
238
- //There's an issue described in DEVSIX-573. When you create multiple fields with different fonts those font may
239
- // have same names (F1, F2, etc). So only first of them will be save in default resources.
240
- if (field .getFormType () != null && (field .getFormType ().equals (PdfName .Tx ) || field .getFormType ().equals (PdfName .Ch ))) {
241
- List <PdfDictionary > resources = getResources (field .getPdfObject ());
242
- for (PdfDictionary resDict : resources ) {
243
- mergeResources (defaultResources , resDict );
244
- }
245
- if (!defaultResources .isEmpty ()) {
246
- put (PdfName .DR , defaultResources );
247
- }
248
- }
249
235
if (fieldDic .containsKey (PdfName .Subtype ) && page != null ) {
250
236
PdfAnnotation annot = PdfAnnotation .makeAnnotation (fieldDic );
251
237
addWidgetAnnotationToPage (page , annot );
@@ -285,7 +271,6 @@ public void addFieldAppearanceToPage(PdfFormField field, PdfPage page) {
285
271
public Map <String , PdfFormField > getFormFields () {
286
272
if (fields .size () == 0 ) {
287
273
fields = iterateFields (getFields ());
288
-
289
274
}
290
275
return fields ;
291
276
}
@@ -647,7 +632,7 @@ public void flattenFields() {
647
632
initialPageResourceClones .put (i , resources == null ? null : resources .clone ());
648
633
}
649
634
650
- Set <PdfPage > wrappedPages = new LinkedHashSet <PdfPage >();
635
+ Set <PdfPage > wrappedPages = new LinkedHashSet <>();
651
636
PdfPage page ;
652
637
for (PdfFormField field : fields ) {
653
638
PdfDictionary fieldObject = field .getPdfObject ();
@@ -676,58 +661,54 @@ public void flattenFields() {
676
661
appDic = fieldObject .getAsDictionary (PdfName .AP );
677
662
}
678
663
}
679
- if (null != appDic ) {
680
- PdfObject normal = appDic .get (PdfName .N );
681
- if (null == normal ) {
682
- Logger logger = LoggerFactory .getLogger (PdfAcroForm .class );
683
- logger .error (LogMessageConstant .N_ENTRY_IS_REQUIRED_FOR_APPEARANCE_DICTIONARY );
684
- } else {
685
- PdfFormXObject xObject = null ;
686
- if (normal .isStream ()) {
687
- xObject = new PdfFormXObject ((PdfStream ) normal );
688
- } else if (normal .isDictionary ()) {
689
- PdfName as = fieldObject .getAsName (PdfName .AS );
690
- if (((PdfDictionary ) normal ).getAsStream (as ) != null ) {
691
- xObject = new PdfFormXObject (((PdfDictionary ) normal ).getAsStream (as ));
692
- xObject .makeIndirect (document );
693
- }
664
+ PdfObject normal = appDic != null ? appDic .get (PdfName .N ) : null ;
665
+ if (null != normal ) {
666
+ PdfFormXObject xObject = null ;
667
+ if (normal .isStream ()) {
668
+ xObject = new PdfFormXObject ((PdfStream ) normal );
669
+ } else if (normal .isDictionary ()) {
670
+ PdfName as = fieldObject .getAsName (PdfName .AS );
671
+ if (((PdfDictionary ) normal ).getAsStream (as ) != null ) {
672
+ xObject = new PdfFormXObject (((PdfDictionary ) normal ).getAsStream (as ));
673
+ xObject .makeIndirect (document );
694
674
}
675
+ }
676
+
677
+ if (xObject != null ) {
678
+ //subtype is required field for FormXObject, but can be omitted in normal appearance.
679
+ xObject .put (PdfName .Subtype , PdfName .Form );
680
+ Rectangle annotBBox = fieldObject .getAsRectangle (PdfName .Rect );
681
+ if (page .isFlushed ()) {
682
+ throw new PdfException (PdfException .PageAlreadyFlushedUseAddFieldAppearanceToPageMethodBeforePageFlushing );
683
+ }
684
+ PdfCanvas canvas = new PdfCanvas (page , !wrappedPages .contains (page ));
685
+ wrappedPages .add (page );
686
+
687
+ // Here we avoid circular reference which might occur when page resources and the appearance xObject's
688
+ // resources are the same object
689
+ PdfObject xObjectResources = xObject .getPdfObject ().get (PdfName .Resources );
690
+ PdfObject pageResources = page .getResources ().getPdfObject ();
691
+ if (xObjectResources != null && xObjectResources == pageResources ) {
692
+ xObject .getPdfObject ().put (PdfName .Resources , initialPageResourceClones .get (document .getPageNumber (page )));
693
+ }
694
+
695
+ if (tagPointer != null ) {
696
+ tagPointer .setPageForTagging (page );
697
+ TagReference tagRef = tagPointer .getTagReference ();
698
+ canvas .openTag (tagRef );
699
+ }
700
+
701
+ AffineTransform at = calcFieldAppTransformToAnnotRect (xObject , annotBBox );
702
+ float [] m = new float [6 ];
703
+ at .getMatrix (m );
704
+ canvas .addXObject (xObject , m [0 ], m [1 ], m [2 ], m [3 ], m [4 ], m [5 ]);
695
705
696
- if (xObject != null ) {
697
- //subtype is required field for FormXObject, but can be omitted in normal appearance.
698
- xObject .put (PdfName .Subtype , PdfName .Form );
699
- Rectangle annotBBox = fieldObject .getAsRectangle (PdfName .Rect );
700
- if (page .isFlushed ()) {
701
- throw new PdfException (PdfException .PageAlreadyFlushedUseAddFieldAppearanceToPageMethodBeforePageFlushing );
702
- }
703
- PdfCanvas canvas = new PdfCanvas (page , !wrappedPages .contains (page ));
704
- wrappedPages .add (page );
705
-
706
- // Here we avoid circular reference which might occur when page resources and the appearance xObject's
707
- // resources are the same object
708
- PdfObject xObjectResources = xObject .getPdfObject ().get (PdfName .Resources );
709
- PdfObject pageResources = page .getResources ().getPdfObject ();
710
- if (xObjectResources != null && pageResources != null &&
711
- xObjectResources == pageResources ) {
712
- xObject .getPdfObject ().put (PdfName .Resources , initialPageResourceClones .get (document .getPageNumber (page )));
713
- }
714
-
715
- if (tagPointer != null ) {
716
- tagPointer .setPageForTagging (page );
717
- TagReference tagRef = tagPointer .getTagReference ();
718
- canvas .openTag (tagRef );
719
- }
720
-
721
- AffineTransform at = calcFieldAppTransformToAnnotRect (xObject , annotBBox );
722
- float [] m = new float [6 ];
723
- at .getMatrix (m );
724
- canvas .addXObject (xObject , m [0 ], m [1 ], m [2 ], m [3 ], m [4 ], m [5 ]);
725
-
726
- if (tagPointer != null ) {
727
- canvas .closeTag ();
728
- }
706
+ if (tagPointer != null ) {
707
+ canvas .closeTag ();
729
708
}
730
709
}
710
+ } else {
711
+ logger .error (LogMessageConstant .N_ENTRY_IS_REQUIRED_FOR_APPEARANCE_DICTIONARY );
731
712
}
732
713
733
714
PdfArray fFields = getFields ();
@@ -839,10 +820,8 @@ public void renameField(String oldName, String newName) {
839
820
public PdfFormField copyField (String name ) {
840
821
PdfFormField oldField = getField (name );
841
822
if (oldField != null ) {
842
- PdfFormField field = new PdfFormField ((PdfDictionary ) oldField .getPdfObject ().clone ().makeIndirect (document ));
843
- return field ;
823
+ return new PdfFormField ((PdfDictionary ) oldField .getPdfObject ().clone ().makeIndirect (document ));
844
824
}
845
-
846
825
return null ;
847
826
}
848
827
@@ -866,7 +845,6 @@ public void replaceField(String name, PdfFormField field) {
866
845
protected PdfArray getFields () {
867
846
PdfArray fields = getPdfObject ().getAsArray (PdfName .Fields );
868
847
if (fields == null ) {
869
- Logger logger = LoggerFactory .getLogger (PdfAcroForm .class );
870
848
logger .warn (LogMessageConstant .NO_FIELDS_IN_ACROFORM );
871
849
fields = new PdfArray ();
872
850
getPdfObject ().put (PdfName .Fields , fields );
@@ -883,7 +861,6 @@ private Map<String, PdfFormField> iterateFields(PdfArray array, Map<String, PdfF
883
861
int index = 1 ;
884
862
for (PdfObject field : array ) {
885
863
if (field .isFlushed ()) {
886
- Logger logger = LoggerFactory .getLogger (PdfAcroForm .class );
887
864
logger .warn (LogMessageConstant .FORM_FIELD_WAS_FLUSHED );
888
865
continue ;
889
866
}
@@ -987,62 +964,6 @@ private void addWidgetAnnotationToPage(PdfPage page, PdfAnnotation annot) {
987
964
}
988
965
}
989
966
990
- private List <PdfDictionary > getResources (PdfDictionary field ) {
991
- List <PdfDictionary > resources = new ArrayList <>();
992
-
993
- PdfDictionary ap = field .getAsDictionary (PdfName .AP );
994
- if (ap != null && !ap .isFlushed ()) {
995
- PdfObject normal = ap .get (PdfName .N );
996
- if (normal != null && !normal .isFlushed ()) {
997
- if (normal .isDictionary ()) {
998
- for (PdfName key : ((PdfDictionary ) normal ).keySet ()) {
999
- PdfStream appearance = ((PdfDictionary ) normal ).getAsStream (key );
1000
- PdfDictionary resDict = appearance .getAsDictionary (PdfName .Resources );
1001
- if (resDict != null ) {
1002
- resources .add (resDict );
1003
- break ;
1004
- }
1005
- }
1006
- } else if (normal .isStream ()) {
1007
- PdfDictionary resDict = ((PdfStream ) normal ).getAsDictionary (PdfName .Resources );
1008
- if (resDict != null ) {
1009
- resources .add (resDict );
1010
- }
1011
- }
1012
- }
1013
- }
1014
-
1015
- PdfArray kids = field .getAsArray (PdfName .Kids );
1016
- if (kids != null ) {
1017
- for (PdfObject kid : kids ) {
1018
- resources .addAll (getResources ((PdfDictionary ) kid ));
1019
- }
1020
- }
1021
-
1022
- return resources ;
1023
- }
1024
-
1025
- /**
1026
- * Merges two dictionaries. When both dictionaries contain the same key,
1027
- * the value from the first dictionary is kept.
1028
- *
1029
- * @param result the {@link PdfDictionary} which may get extra entries from source
1030
- * @param source the {@link PdfDictionary} whose entries may be merged into result
1031
- */
1032
- private void mergeResources (PdfDictionary result , PdfDictionary source ) {
1033
- for (PdfName name : resourceNames ) {
1034
- PdfDictionary dic = source .isFlushed () ? null : source .getAsDictionary (name );
1035
- PdfDictionary res = result .getAsDictionary (name );
1036
- if (res == null ) {
1037
- res = new PdfDictionary ();
1038
- }
1039
- if (dic != null ) {
1040
- res .mergeDifferent (dic );
1041
- result .put (name , res );
1042
- }
1043
- }
1044
- }
1045
-
1046
967
/**
1047
968
* Determines whether the AcroForm contains XFA data.
1048
969
*
0 commit comments