@@ -54,8 +54,10 @@ This file is part of the iText (R) project.
54
54
import com .itextpdf .kernel .pdf .PdfString ;
55
55
56
56
import java .util .ArrayList ;
57
+ import java .util .HashSet ;
57
58
import java .util .List ;
58
59
import java .util .Map ;
60
+ import java .util .Set ;
59
61
import java .util .TreeMap ;
60
62
61
63
/**
@@ -69,10 +71,33 @@ This file is part of the iText (R) project.
69
71
public class PdfOCProperties extends PdfObjectWrapper <PdfDictionary > {
70
72
71
73
private static final long serialVersionUID = 1137977454824741350L ;
72
- private List <PdfLayer > layers = new ArrayList <>();
74
+ private List <PdfLayer > layers = new ArrayList <>();
75
+
76
+ /**
77
+ * Gets the order of the layers in which they will be displayed in the layer view panel,
78
+ * including nesting.
79
+ */
80
+ private static void getOCGOrder (PdfArray order , PdfLayer layer ) {
81
+ if (!layer .isOnPanel ())
82
+ return ;
83
+ if (layer .getTitle () == null )
84
+ order .add (layer .getPdfObject ().getIndirectReference ());
85
+ List <PdfLayer > children = layer .getChildren ();
86
+ if (children == null )
87
+ return ;
88
+ PdfArray kids = new PdfArray ();
89
+ if (layer .getTitle () != null )
90
+ kids .add (new PdfString (layer .getTitle (), PdfEncodings .UNICODE_BIG ));
91
+ for (PdfLayer child : children ) {
92
+ getOCGOrder (kids , child );
93
+ }
94
+ if (kids .size () > 0 )
95
+ order .add (kids );
96
+ }
73
97
74
98
/**
75
99
* Creates a new PdfOCProperties instance.
100
+ *
76
101
* @param document the document the optional content belongs to
77
102
*/
78
103
public PdfOCProperties (PdfDocument document ) {
@@ -97,6 +122,7 @@ public PdfOCProperties(PdfDictionary ocPropertiesDict) {
97
122
* That is, the state of at most one optional content group
98
123
* in the array should be ON at a time: if one group is turned
99
124
* ON, all others must be turned OFF.
125
+ *
100
126
* @param group the radio group
101
127
*/
102
128
public void addOCGRadioGroup (List <PdfLayer > group ) {
@@ -127,6 +153,7 @@ public void addOCGRadioGroup(List<PdfLayer> group) {
127
153
* Fills the underlying PdfDictionary object with the current layers and their settings.
128
154
* Note that it completely regenerates the dictionary, so your direct changes to the dictionary
129
155
* will not take any affect.
156
+ *
130
157
* @return the resultant dictionary
131
158
*/
132
159
public PdfObject fillDictionary () {
@@ -146,6 +173,8 @@ public PdfObject fillDictionary() {
146
173
d = new PdfDictionary ();
147
174
if (rbGroups != null )
148
175
d .put (PdfName .RBGroups , rbGroups );
176
+ d .put (PdfName .Name , new PdfString (createUniqueName (), PdfEncodings .UNICODE_BIG ));
177
+
149
178
getPdfObject ().put (PdfName .D , d );
150
179
151
180
@@ -160,14 +189,14 @@ public PdfObject fillDictionary() {
160
189
161
190
PdfArray order = new PdfArray ();
162
191
for (Object element : docOrder ) {
163
- PdfLayer layer = (PdfLayer )element ;
192
+ PdfLayer layer = (PdfLayer ) element ;
164
193
getOCGOrder (order , layer );
165
194
}
166
195
d .put (PdfName .Order , order );
167
196
168
197
PdfArray off = new PdfArray ();
169
198
for (Object element : layers ) {
170
- PdfLayer layer = (PdfLayer )element ;
199
+ PdfLayer layer = (PdfLayer ) element ;
171
200
if (layer .getTitle () == null && !layer .isOn ())
172
201
off .add (layer .getIndirectReference ());
173
202
}
@@ -195,6 +224,24 @@ public PdfObject fillDictionary() {
195
224
return getPdfObject ();
196
225
}
197
226
227
+ private String createUniqueName () {
228
+ int uniqueID = 0 ;
229
+ Set <String > usedNames = new HashSet <>();
230
+ PdfArray configs = getPdfObject ().getAsArray (PdfName .Configs );
231
+ if (null != configs ) {
232
+ for (int i = 0 ; i < configs .size (); i ++) {
233
+ PdfDictionary alternateDictionary = configs .getAsDictionary (i );
234
+ if (null != alternateDictionary && alternateDictionary .containsKey (PdfName .Name )) {
235
+ usedNames .add (alternateDictionary .getAsString (PdfName .Name ).toUnicodeString ());
236
+ }
237
+ }
238
+ }
239
+ while (usedNames .contains ("OCConfigName" + uniqueID )) {
240
+ uniqueID ++;
241
+ }
242
+ return "OCConfigName" + uniqueID ;
243
+ }
244
+
198
245
@ Override
199
246
public void flush () {
200
247
fillDictionary ();
@@ -216,6 +263,7 @@ protected boolean isWrappedObjectMustBeIndirect() {
216
263
217
264
/**
218
265
* This method registers a new layer in the OCProperties.
266
+ *
219
267
* @param layer the new layer
220
268
*/
221
269
protected void registerLayer (PdfLayer layer ) {
@@ -228,28 +276,6 @@ protected PdfDocument getDocument() {
228
276
return getPdfObject ().getIndirectReference ().getDocument ();
229
277
}
230
278
231
- /**
232
- * Gets the order of the layers in which they will be displayed in the layer view panel,
233
- * including nesting.
234
- */
235
- private static void getOCGOrder (PdfArray order , PdfLayer layer ) {
236
- if (!layer .isOnPanel ())
237
- return ;
238
- if (layer .getTitle () == null )
239
- order .add (layer .getPdfObject ().getIndirectReference ());
240
- List <PdfLayer > children = layer .getChildren ();
241
- if (children == null )
242
- return ;
243
- PdfArray kids = new PdfArray ();
244
- if (layer .getTitle () != null )
245
- kids .add (new PdfString (layer .getTitle (), PdfEncodings .UNICODE_BIG ));
246
- for (PdfLayer child : children ) {
247
- getOCGOrder (kids , child );
248
- }
249
- if (kids .size () > 0 )
250
- order .add (kids );
251
- }
252
-
253
279
/**
254
280
* Populates the /AS entry in the /D dictionary.
255
281
*/
@@ -344,11 +370,11 @@ private void readOrderFromDictionary(PdfLayer parent, PdfArray orderArray, Map<P
344
370
}
345
371
}
346
372
} else if (item .getType () == PdfObject .ARRAY ) {
347
- PdfArray subArray = (PdfArray )item ;
373
+ PdfArray subArray = (PdfArray ) item ;
348
374
if (subArray .isEmpty ()) continue ;
349
375
PdfObject firstObj = subArray .get (0 );
350
376
if (firstObj .getType () == PdfObject .STRING ) {
351
- PdfLayer titleLayer = PdfLayer .createTitleSilent (((PdfString )firstObj ).toUnicodeString (), getDocument ());
377
+ PdfLayer titleLayer = PdfLayer .createTitleSilent (((PdfString ) firstObj ).toUnicodeString (), getDocument ());
352
378
titleLayer .onPanel = true ;
353
379
layers .add (titleLayer );
354
380
if (parent != null )
0 commit comments