1 | /* | |
2 | * $Id: PdfWriter.java 4095 2009-11-12 14:40:41Z blowagie $ | |
3 | * | |
4 | * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie | |
5 | * | |
6 | * The contents of this file are subject to the Mozilla Public License Version 1.1 | |
7 | * (the "License"); you may not use this file except in compliance with the License. | |
8 | * You may obtain a copy of the License at http://www.mozilla.org/MPL/ | |
9 | * | |
10 | * Software distributed under the License is distributed on an "AS IS" basis, | |
11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | |
12 | * for the specific language governing rights and limitations under the License. | |
13 | * | |
14 | * The Original Code is 'iText, a free JAVA-PDF library'. | |
15 | * | |
16 | * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by | |
17 | * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. | |
18 | * All Rights Reserved. | |
19 | * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer | |
20 | * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. | |
21 | * | |
22 | * Contributor(s): all the names of the contributors are added in the source code | |
23 | * where applicable. | |
24 | * | |
25 | * Alternatively, the contents of this file may be used under the terms of the | |
26 | * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the | |
27 | * provisions of LGPL are applicable instead of those above. If you wish to | |
28 | * allow use of your version of this file only under the terms of the LGPL | |
29 | * License and not to allow others to use your version of this file under | |
30 | * the MPL, indicate your decision by deleting the provisions above and | |
31 | * replace them with the notice and other provisions required by the LGPL. | |
32 | * If you do not delete the provisions above, a recipient may use your version | |
33 | * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. | |
34 | * | |
35 | * This library is free software; you can redistribute it and/or modify it | |
36 | * under the terms of the MPL as stated above or under the terms of the GNU | |
37 | * Library General Public License as published by the Free Software Foundation; | |
38 | * either version 2 of the License, or any later version. | |
39 | * | |
40 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
41 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
42 | * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more | |
43 | * details. | |
44 | * | |
45 | * If you didn't download this code from the following link, you should check if | |
46 | * you aren't using an obsolete version: | |
47 | * http://www.lowagie.com/iText/ | |
48 | */ | |
49 | ||
50 | package com.lowagie.text.pdf; | |
51 | ||
52 | import com.lowagie.text.*; | |
53 | import com.lowagie.text.Image; | |
54 | import com.lowagie.text.Rectangle; | |
55 | import com.lowagie.text.error_messages.MessageLocalization; | |
56 | import com.lowagie.text.pdf.collection.PdfCollection; | |
57 | import com.lowagie.text.pdf.events.PdfPageEventForwarder; | |
58 | import com.lowagie.text.pdf.interfaces.*; | |
59 | import com.lowagie.text.pdf.internal.PdfVersionImp; | |
60 | import com.lowagie.text.pdf.internal.PdfXConformanceImp; | |
61 | import com.lowagie.text.xml.xmp.XmpWriter; | |
62 | ||
63 | import java.awt.*; | |
64 | import java.awt.color.ICC_Profile; | |
65 | import java.io.ByteArrayOutputStream; | |
66 | import java.io.Closeable; | |
67 | import java.io.IOException; | |
68 | import java.io.OutputStream; | |
69 | import java.security.cert.Certificate; | |
70 | import java.util.*; | |
71 | import java.util.List; | |
72 | ||
73 | /** | |
74 | * A <CODE>DocWriter</CODE> class for PDF. | |
75 | * <P> | |
76 | * When this <CODE>PdfWriter</CODE> is added | |
77 | * to a certain <CODE>PdfDocument</CODE>, the PDF representation of every Element | |
78 | * added to this Document will be written to the outputstream.</P> | |
79 | */ | |
80 | ||
81 | public class PdfWriter extends DocWriter implements | |
82 | Closeable, | |
83 | PdfViewerPreferences, | |
84 | PdfEncryptionSettings, | |
85 | PdfVersion, | |
86 | PdfDocumentActions, | |
87 | PdfPageActions, | |
88 | PdfXConformance, | |
89 | PdfRunDirection, | |
90 | PdfAnnotations { | |
91 | ||
92 | /** | |
93 | * The highest generation number possible. | |
94 | * @since iText 2.1.6 | |
95 | */ | |
96 | public static final int GENERATION_MAX = 65535; | |
97 | | |
98 | // INNER CLASSES | |
99 | ||
100 | /** | |
101 | * This class generates the structure of a PDF document. | |
102 | * <P> | |
103 | * This class covers the third section of Chapter 5 in the 'Portable Document Format | |
104 | * Reference Manual version 1.3' (page 55-60). It contains the body of a PDF document | |
105 | * (section 5.14) and it can also generate a Cross-reference Table (section 5.15). | |
106 | * | |
107 | * @see PdfWriter | |
108 | * @see PdfObject | |
109 | * @see PdfIndirectObject | |
110 | */ | |
111 | ||
112 | public static class PdfBody { | |
113 | ||
114 | // inner classes | |
115 | ||
116 | /** | |
117 | * <CODE>PdfCrossReference</CODE> is an entry in the PDF Cross-Reference table. | |
118 | */ | |
119 | ||
120 | public static class PdfCrossReference implements Comparable<PdfCrossReference> { | |
121 | ||
122 | /** | |
123 | * String template for cross-reference entry PDF representation. | |
124 | * | |
125 | * @see Formatter | |
126 | */ | |
127 | private static final String CROSS_REFERENCE_ENTRY_FORMAT = "%010d %05d %c \n"; | |
128 | ||
129 | // membervariables | |
130 | private int type; | |
131 | ||
132 | /** Byte offset in the PDF file. */ | |
133 | private int offset; | |
134 | ||
135 | private int refnum; | |
136 | /** generation of the object. */ | |
137 | private int generation; | |
138 | ||
139 | // constructors | |
140 | /** | |
141 | * Constructs a cross-reference element for a PdfIndirectObject. | |
142 | * @param refnum | |
143 | * @param offset byte offset of the object | |
144 | * @param generation generation number of the object | |
145 | */ | |
146 | ||
147 | public PdfCrossReference(int refnum, int offset, int generation) { | |
148 | type = 0; | |
149 | this.offset = offset; | |
150 | this.refnum = refnum; | |
151 | this.generation = generation; | |
152 | } | |
153 | ||
154 | /** | |
155 | * Constructs a cross-reference element for a PdfIndirectObject. | |
156 | * @param refnum | |
157 | * @param offset byte offset of the object | |
158 | */ | |
159 | ||
160 | public PdfCrossReference(int refnum, int offset) { | |
161 | type = 1; | |
162 | this.offset = offset; | |
163 | this.refnum = refnum; | |
164 | this.generation = 0; | |
165 | } | |
166 | ||
167 | public PdfCrossReference(int type, int refnum, int offset, int generation) { | |
168 | this.type = type; | |
169 | this.offset = offset; | |
170 | this.refnum = refnum; | |
171 | this.generation = generation; | |
172 | } | |
173 | ||
174 | int getRefnum() { | |
175 | return refnum; | |
176 | } | |
177 | ||
178 | /** | |
179 | * Writes PDF representation of cross-reference entry to passed output stream. | |
180 | * | |
181 | * @param os Output stream this entry to write to | |
182 | * @throws IOException If any I/O error occurs | |
183 | */ | |
184 | public void toPdf(OutputStream os) throws IOException { | |
185 | // TODO: are generation number and 'In use' keyword bound that way? | |
186 |
1
1. toPdf : negated conditional → NO_COVERAGE |
final char inUse = generation == GENERATION_MAX ? 'f' : 'n'; |
187 |
1
1. toPdf : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write(String.format(CROSS_REFERENCE_ENTRY_FORMAT, offset, generation, inUse).getBytes()); |
188 | } | |
189 | ||
190 | /** | |
191 | * Writes PDF syntax to the OutputStream | |
192 | * @param midSize | |
193 | * @param os | |
194 | * @throws IOException | |
195 | */ | |
196 | public void toPdf(int midSize, OutputStream os) throws IOException { | |
197 |
1
1. toPdf : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write((byte)type); |
198 |
3
1. toPdf : changed conditional boundary → NO_COVERAGE 2. toPdf : Changed increment from -1 to 1 → NO_COVERAGE 3. toPdf : negated conditional → NO_COVERAGE |
while (--midSize >= 0) |
199 |
4
1. toPdf : Replaced integer multiplication with division → NO_COVERAGE 2. toPdf : Replaced Unsigned Shift Right with Shift Left → NO_COVERAGE 3. toPdf : Replaced bitwise AND with OR → NO_COVERAGE 4. toPdf : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write((byte)((offset >>> (8 * midSize)) & 0xff)); |
200 |
3
1. toPdf : Replaced Unsigned Shift Right with Shift Left → NO_COVERAGE 2. toPdf : Replaced bitwise AND with OR → NO_COVERAGE 3. toPdf : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write((byte)((generation >>> 8) & 0xff)); |
201 |
2
1. toPdf : Replaced bitwise AND with OR → NO_COVERAGE 2. toPdf : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write((byte)(generation & 0xff)); |
202 | } | |
203 | ||
204 | /** | |
205 | * Compares current {@link PdfCrossReference entry} with passed {@code reference} by PDF object number. | |
206 | */ | |
207 | @Override | |
208 | public int compareTo(final PdfCrossReference reference) { | |
209 |
1
1. compareTo : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return Integer.compare(refnum, reference.refnum); |
210 | } | |
211 | ||
212 | /** | |
213 | * Checks if two entries are equal if their PDF object numbers are equal. | |
214 | * | |
215 | * @param obj Another cross-reference entry | |
216 | * @return If null, not of type {@link PdfCrossReference} or object numbers are not equal, | |
217 | * returns false; true otherwise | |
218 | */ | |
219 | @Override | |
220 | public boolean equals(Object obj) { | |
221 |
1
1. equals : negated conditional → NO_COVERAGE |
if (!(obj instanceof PdfCrossReference)) { |
222 |
1
1. equals : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return false; |
223 | } | |
224 | ||
225 | final PdfCrossReference other = (PdfCrossReference)obj; | |
226 |
2
1. equals : negated conditional → NO_COVERAGE 2. equals : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return refnum == other.refnum; |
227 | } | |
228 | ||
229 | @Override | |
230 | public int hashCode() { | |
231 | return refnum; | |
232 | } | |
233 | } | |
234 | ||
235 | private static final int OBJSINSTREAM = 200; | |
236 | ||
237 | // membervariables | |
238 | ||
239 | /** array containing the cross-reference table of the normal objects. */ | |
240 | private TreeSet<PdfCrossReference> xrefs; | |
241 | private int refnum; | |
242 | /** the current byte position in the body. */ | |
243 | private int position; | |
244 | private PdfWriter writer; | |
245 | private ByteBuffer index; | |
246 | private ByteBuffer streamObjects; | |
247 | private int currentObjNum; | |
248 | private int numObj = 0; | |
249 | ||
250 | // constructors | |
251 | ||
252 | /** | |
253 | * Constructs a new <CODE>PdfBody</CODE>. | |
254 | * @param writer | |
255 | */ | |
256 | PdfBody(PdfWriter writer) { | |
257 | xrefs = new TreeSet<>(); | |
258 | xrefs.add(new PdfCrossReference(0, 0, GENERATION_MAX)); | |
259 | position = writer.getOs().getCounter(); | |
260 | refnum = 1; | |
261 | this.writer = writer; | |
262 | } | |
263 | ||
264 | // methods | |
265 | ||
266 | void setRefnum(int refnum) { | |
267 | this.refnum = refnum; | |
268 | } | |
269 | ||
270 | private PdfWriter.PdfBody.PdfCrossReference addToObjStm(PdfObject obj, int nObj) throws IOException { | |
271 |
2
1. addToObjStm : changed conditional boundary → NO_COVERAGE 2. addToObjStm : negated conditional → NO_COVERAGE |
if (numObj >= OBJSINSTREAM) |
272 |
1
1. addToObjStm : removed call to com/lowagie/text/pdf/PdfWriter$PdfBody::flushObjStm → NO_COVERAGE |
flushObjStm(); |
273 |
1
1. addToObjStm : negated conditional → NO_COVERAGE |
if (index == null) { |
274 | index = new ByteBuffer(); | |
275 | streamObjects = new ByteBuffer(); | |
276 | currentObjNum = getIndirectReferenceNumber(); | |
277 | numObj = 0; | |
278 | } | |
279 | int p = streamObjects.size(); | |
280 |
1
1. addToObjStm : Replaced integer addition with subtraction → NO_COVERAGE |
int idx = numObj++; |
281 | PdfEncryption enc = writer.crypto; | |
282 | writer.crypto = null; | |
283 |
1
1. addToObjStm : removed call to com/lowagie/text/pdf/PdfObject::toPdf → NO_COVERAGE |
obj.toPdf(writer, streamObjects); |
284 | writer.crypto = enc; | |
285 | streamObjects.append(' '); | |
286 | index.append(nObj).append(' ').append(p).append(' '); | |
287 |
1
1. addToObjStm : mutated return of Object value for com/lowagie/text/pdf/PdfWriter$PdfBody::addToObjStm to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return new PdfWriter.PdfBody.PdfCrossReference(2, nObj, currentObjNum, idx); |
288 | } | |
289 | ||
290 | private void flushObjStm() throws IOException { | |
291 |
1
1. flushObjStm : negated conditional → NO_COVERAGE |
if (numObj == 0) |
292 | return; | |
293 | int first = index.size(); | |
294 | index.append(streamObjects); | |
295 | PdfStream stream = new PdfStream(index.toByteArray()); | |
296 |
1
1. flushObjStm : removed call to com/lowagie/text/pdf/PdfStream::flateCompress → NO_COVERAGE |
stream.flateCompress(writer.getCompressionLevel()); |
297 |
1
1. flushObjStm : removed call to com/lowagie/text/pdf/PdfStream::put → NO_COVERAGE |
stream.put(PdfName.TYPE, PdfName.OBJSTM); |
298 |
1
1. flushObjStm : removed call to com/lowagie/text/pdf/PdfStream::put → NO_COVERAGE |
stream.put(PdfName.N, new PdfNumber(numObj)); |
299 |
1
1. flushObjStm : removed call to com/lowagie/text/pdf/PdfStream::put → NO_COVERAGE |
stream.put(PdfName.FIRST, new PdfNumber(first)); |
300 | add(stream, currentObjNum); | |
301 | index = null; | |
302 | streamObjects = null; | |
303 | numObj = 0; | |
304 | } | |
305 | ||
306 | /** | |
307 | * Adds a <CODE>PdfObject</CODE> to the body. | |
308 | * <P> | |
309 | * This methods creates a <CODE>PdfIndirectObject</CODE> with a | |
310 | * certain number, containing the given <CODE>PdfObject</CODE>. | |
311 | * It also adds a <CODE>PdfCrossReference</CODE> for this object | |
312 | * to an <CODE>ArrayList</CODE> that will be used to build the | |
313 | * Cross-reference Table. | |
314 | * | |
315 | * @param object a <CODE>PdfObject</CODE> | |
316 | * @return a <CODE>PdfIndirectObject</CODE> | |
317 | * @throws IOException | |
318 | */ | |
319 | ||
320 | PdfIndirectObject add(PdfObject object) throws IOException { | |
321 |
1
1. add : mutated return of Object value for com/lowagie/text/pdf/PdfWriter$PdfBody::add to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return add(object, getIndirectReferenceNumber()); |
322 | } | |
323 | ||
324 | PdfIndirectObject add(PdfObject object, boolean inObjStm) throws IOException { | |
325 |
1
1. add : mutated return of Object value for com/lowagie/text/pdf/PdfWriter$PdfBody::add to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return add(object, getIndirectReferenceNumber(), inObjStm); |
326 | } | |
327 | ||
328 | /** | |
329 | * Gets a PdfIndirectReference for an object that will be created in the future. | |
330 | * @return a PdfIndirectReference | |
331 | */ | |
332 | ||
333 | PdfIndirectReference getPdfIndirectReference() { | |
334 |
1
1. getPdfIndirectReference : mutated return of Object value for com/lowagie/text/pdf/PdfWriter$PdfBody::getPdfIndirectReference to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return new PdfIndirectReference(0, getIndirectReferenceNumber()); |
335 | } | |
336 | ||
337 | int getIndirectReferenceNumber() { | |
338 |
1
1. getIndirectReferenceNumber : Replaced integer addition with subtraction → NO_COVERAGE |
int n = refnum++; |
339 | xrefs.add(new PdfCrossReference(n, 0, GENERATION_MAX)); | |
340 |
1
1. getIndirectReferenceNumber : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return n; |
341 | } | |
342 | ||
343 | /** | |
344 | * Adds a <CODE>PdfObject</CODE> to the body given an already existing | |
345 | * PdfIndirectReference. | |
346 | * <P> | |
347 | * This methods creates a <CODE>PdfIndirectObject</CODE> with the number given by | |
348 | * <CODE>ref</CODE>, containing the given <CODE>PdfObject</CODE>. | |
349 | * It also adds a <CODE>PdfCrossReference</CODE> for this object | |
350 | * to an <CODE>ArrayList</CODE> that will be used to build the | |
351 | * Cross-reference Table. | |
352 | * | |
353 | * @param object a <CODE>PdfObject</CODE> | |
354 | * @param ref a <CODE>PdfIndirectReference</CODE> | |
355 | * @return a <CODE>PdfIndirectObject</CODE> | |
356 | * @throws IOException | |
357 | */ | |
358 | ||
359 | PdfIndirectObject add(PdfObject object, PdfIndirectReference ref) throws IOException { | |
360 |
1
1. add : mutated return of Object value for com/lowagie/text/pdf/PdfWriter$PdfBody::add to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return add(object, ref.getNumber()); |
361 | } | |
362 | ||
363 | PdfIndirectObject add(PdfObject object, PdfIndirectReference ref, boolean inObjStm) throws IOException { | |
364 |
1
1. add : mutated return of Object value for com/lowagie/text/pdf/PdfWriter$PdfBody::add to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return add(object, ref.getNumber(), inObjStm); |
365 | } | |
366 | ||
367 | PdfIndirectObject add(PdfObject object, int refNumber) throws IOException { | |
368 |
1
1. add : mutated return of Object value for com/lowagie/text/pdf/PdfWriter$PdfBody::add to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return add(object, refNumber, true); // to false |
369 | } | |
370 | ||
371 | PdfIndirectObject add(PdfObject object, int refNumber, boolean inObjStm) throws IOException { | |
372 |
3
1. add : negated conditional → NO_COVERAGE 2. add : negated conditional → NO_COVERAGE 3. add : negated conditional → NO_COVERAGE |
if (inObjStm && object.canBeInObjStm() && writer.isFullCompression()) { |
373 | PdfCrossReference pxref = addToObjStm(object, refNumber); | |
374 | PdfIndirectObject indirect = new PdfIndirectObject(refNumber, object, writer); | |
375 |
1
1. add : negated conditional → NO_COVERAGE |
if (!xrefs.add(pxref)) { |
376 | xrefs.remove(pxref); | |
377 | xrefs.add(pxref); | |
378 | } | |
379 |
1
1. add : mutated return of Object value for com/lowagie/text/pdf/PdfWriter$PdfBody::add to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return indirect; |
380 | } | |
381 | else { | |
382 | PdfIndirectObject indirect = new PdfIndirectObject(refNumber, object, writer); | |
383 | PdfCrossReference pxref = new PdfCrossReference(refNumber, position); | |
384 |
1
1. add : negated conditional → NO_COVERAGE |
if (!xrefs.add(pxref)) { |
385 | xrefs.remove(pxref); | |
386 | xrefs.add(pxref); | |
387 | } | |
388 |
1
1. add : removed call to com/lowagie/text/pdf/PdfIndirectObject::writeTo → NO_COVERAGE |
indirect.writeTo(writer.getOs()); |
389 | position = writer.getOs().getCounter(); | |
390 |
1
1. add : mutated return of Object value for com/lowagie/text/pdf/PdfWriter$PdfBody::add to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return indirect; |
391 | } | |
392 | } | |
393 | ||
394 | /** | |
395 | * Returns the offset of the Cross-Reference table. | |
396 | * | |
397 | * @return an offset | |
398 | */ | |
399 | ||
400 | int offset() { | |
401 | return position; | |
402 | } | |
403 | ||
404 | /** | |
405 | * Returns the total number of objects contained in the CrossReferenceTable of this <CODE>Body</CODE>. | |
406 | * | |
407 | * @return a number of objects | |
408 | */ | |
409 | ||
410 | int size() { | |
411 |
2
1. size : Replaced integer addition with subtraction → NO_COVERAGE 2. size : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return Math.max((xrefs.last()).getRefnum() + 1, refnum); |
412 | } | |
413 | ||
414 | /** | |
415 | * Returns the CrossReferenceTable of the <CODE>Body</CODE>. | |
416 | * @param os | |
417 | * @param root | |
418 | * @param info | |
419 | * @param encryption | |
420 | * @param fileID | |
421 | * @param prevxref | |
422 | * @throws IOException | |
423 | */ | |
424 | ||
425 | void writeCrossReferenceTable(OutputStream os, PdfIndirectReference root, PdfIndirectReference info, PdfIndirectReference encryption, PdfObject fileID, int prevxref) throws IOException { | |
426 | int refNumber = 0; | |
427 |
1
1. writeCrossReferenceTable : negated conditional → NO_COVERAGE |
if (writer.isFullCompression()) { |
428 |
1
1. writeCrossReferenceTable : removed call to com/lowagie/text/pdf/PdfWriter$PdfBody::flushObjStm → NO_COVERAGE |
flushObjStm(); |
429 | refNumber = getIndirectReferenceNumber(); | |
430 | xrefs.add(new PdfCrossReference(refNumber, position)); | |
431 | } | |
432 | PdfCrossReference entry = xrefs.first(); | |
433 | int first = entry.getRefnum(); | |
434 | int len = 0; | |
435 | ArrayList<Integer> sections = new ArrayList<>(); | |
436 | for (PdfCrossReference xref1 : xrefs) { | |
437 | entry = xref1; | |
438 |
2
1. writeCrossReferenceTable : Replaced integer addition with subtraction → NO_COVERAGE 2. writeCrossReferenceTable : negated conditional → NO_COVERAGE |
if (first + len == entry.getRefnum()) |
439 |
1
1. writeCrossReferenceTable : Changed increment from 1 to -1 → NO_COVERAGE |
++len; |
440 | else { | |
441 | sections.add(first); | |
442 | sections.add(len); | |
443 | first = entry.getRefnum(); | |
444 | len = 1; | |
445 | } | |
446 | } | |
447 | sections.add(first); | |
448 | sections.add(len); | |
449 |
1
1. writeCrossReferenceTable : negated conditional → NO_COVERAGE |
if (writer.isFullCompression()) { |
450 | int mid = 4; | |
451 | int mask = 0xff000000; | |
452 |
3
1. writeCrossReferenceTable : changed conditional boundary → NO_COVERAGE 2. writeCrossReferenceTable : Changed increment from -1 to 1 → NO_COVERAGE 3. writeCrossReferenceTable : negated conditional → NO_COVERAGE |
for (; mid > 1; --mid) { |
453 |
2
1. writeCrossReferenceTable : Replaced bitwise AND with OR → NO_COVERAGE 2. writeCrossReferenceTable : negated conditional → NO_COVERAGE |
if ((mask & position) != 0) |
454 | break; | |
455 |
1
1. writeCrossReferenceTable : Replaced Unsigned Shift Right with Shift Left → NO_COVERAGE |
mask >>>= 8; |
456 | } | |
457 | ByteBuffer buf = new ByteBuffer(); | |
458 | ||
459 | for (PdfCrossReference xref : xrefs) { | |
460 | entry = xref; | |
461 |
1
1. writeCrossReferenceTable : removed call to com/lowagie/text/pdf/PdfWriter$PdfBody$PdfCrossReference::toPdf → NO_COVERAGE |
entry.toPdf(mid, buf); |
462 | } | |
463 | PdfStream xr = new PdfStream(buf.toByteArray()); | |
464 | buf = null; | |
465 |
1
1. writeCrossReferenceTable : removed call to com/lowagie/text/pdf/PdfStream::flateCompress → NO_COVERAGE |
xr.flateCompress(writer.getCompressionLevel()); |
466 |
1
1. writeCrossReferenceTable : removed call to com/lowagie/text/pdf/PdfStream::put → NO_COVERAGE |
xr.put(PdfName.SIZE, new PdfNumber(size())); |
467 |
1
1. writeCrossReferenceTable : removed call to com/lowagie/text/pdf/PdfStream::put → NO_COVERAGE |
xr.put(PdfName.ROOT, root); |
468 |
1
1. writeCrossReferenceTable : negated conditional → NO_COVERAGE |
if (info != null) { |
469 |
1
1. writeCrossReferenceTable : removed call to com/lowagie/text/pdf/PdfStream::put → NO_COVERAGE |
xr.put(PdfName.INFO, info); |
470 | } | |
471 |
1
1. writeCrossReferenceTable : negated conditional → NO_COVERAGE |
if (encryption != null) |
472 |
1
1. writeCrossReferenceTable : removed call to com/lowagie/text/pdf/PdfStream::put → NO_COVERAGE |
xr.put(PdfName.ENCRYPT, encryption); |
473 |
1
1. writeCrossReferenceTable : negated conditional → NO_COVERAGE |
if (fileID != null) |
474 |
1
1. writeCrossReferenceTable : removed call to com/lowagie/text/pdf/PdfStream::put → NO_COVERAGE |
xr.put(PdfName.ID, fileID); |
475 |
1
1. writeCrossReferenceTable : removed call to com/lowagie/text/pdf/PdfStream::put → NO_COVERAGE |
xr.put(PdfName.W, new PdfArray(new int[]{1, mid, 2})); |
476 |
1
1. writeCrossReferenceTable : removed call to com/lowagie/text/pdf/PdfStream::put → NO_COVERAGE |
xr.put(PdfName.TYPE, PdfName.XREF); |
477 | PdfArray idx = new PdfArray(); | |
478 | for (Integer section : sections) idx.add(new PdfNumber(section)); | |
479 |
1
1. writeCrossReferenceTable : removed call to com/lowagie/text/pdf/PdfStream::put → NO_COVERAGE |
xr.put(PdfName.INDEX, idx); |
480 |
2
1. writeCrossReferenceTable : changed conditional boundary → NO_COVERAGE 2. writeCrossReferenceTable : negated conditional → NO_COVERAGE |
if (prevxref > 0) |
481 |
1
1. writeCrossReferenceTable : removed call to com/lowagie/text/pdf/PdfStream::put → NO_COVERAGE |
xr.put(PdfName.PREV, new PdfNumber(prevxref)); |
482 | PdfEncryption enc = writer.crypto; | |
483 | writer.crypto = null; | |
484 | PdfIndirectObject indirect = new PdfIndirectObject(refNumber, xr, writer); | |
485 |
1
1. writeCrossReferenceTable : removed call to com/lowagie/text/pdf/PdfIndirectObject::writeTo → NO_COVERAGE |
indirect.writeTo(writer.getOs()); |
486 | writer.crypto = enc; | |
487 | } | |
488 | else { | |
489 |
1
1. writeCrossReferenceTable : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write(getISOBytes("xref\n")); |
490 | Iterator<PdfCrossReference> i = xrefs.iterator(); | |
491 |
3
1. writeCrossReferenceTable : changed conditional boundary → NO_COVERAGE 2. writeCrossReferenceTable : Changed increment from 2 to -2 → NO_COVERAGE 3. writeCrossReferenceTable : negated conditional → NO_COVERAGE |
for (int k = 0; k < sections.size(); k += 2) { |
492 | first = sections.get(k); | |
493 |
1
1. writeCrossReferenceTable : Replaced integer addition with subtraction → NO_COVERAGE |
len = sections.get(k + 1); |
494 |
1
1. writeCrossReferenceTable : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write(getISOBytes(String.valueOf(first))); |
495 |
1
1. writeCrossReferenceTable : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write(getISOBytes(" ")); |
496 |
1
1. writeCrossReferenceTable : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write(getISOBytes(String.valueOf(len))); |
497 |
1
1. writeCrossReferenceTable : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write('\n'); |
498 |
3
1. writeCrossReferenceTable : changed conditional boundary → NO_COVERAGE 2. writeCrossReferenceTable : Changed increment from -1 to 1 → NO_COVERAGE 3. writeCrossReferenceTable : negated conditional → NO_COVERAGE |
while (len-- > 0) { |
499 | entry = i.next(); | |
500 |
1
1. writeCrossReferenceTable : removed call to com/lowagie/text/pdf/PdfWriter$PdfBody$PdfCrossReference::toPdf → NO_COVERAGE |
entry.toPdf(os); |
501 | } | |
502 | } | |
503 | } | |
504 | } | |
505 | } | |
506 | ||
507 | /** | |
508 | * <CODE>PdfTrailer</CODE> is the PDF Trailer object. | |
509 | * <P> | |
510 | * This object is described in the 'Portable Document Format Reference Manual version 1.3' | |
511 | * section 5.16 (page 59-60). | |
512 | */ | |
513 | ||
514 | static class PdfTrailer extends PdfDictionary { | |
515 | ||
516 | // membervariables | |
517 | ||
518 | int offset; | |
519 | ||
520 | // constructors | |
521 | ||
522 | /** | |
523 | * Constructs a PDF-Trailer. | |
524 | * | |
525 | * @param size the number of entries in the <CODE>PdfCrossReferenceTable</CODE> | |
526 | * @param offset offset of the <CODE>PdfCrossReferenceTable</CODE> | |
527 | * @param root an indirect reference to the root of the PDF document | |
528 | * @param info an indirect reference to the info object of the PDF document | |
529 | * @param encryption | |
530 | * @param fileID | |
531 | * @param prevxref | |
532 | */ | |
533 | ||
534 | PdfTrailer(int size, int offset, PdfIndirectReference root, PdfIndirectReference info, PdfIndirectReference encryption, PdfObject fileID, int prevxref) { | |
535 | this.offset = offset; | |
536 |
1
1. |
put(PdfName.SIZE, new PdfNumber(size)); |
537 |
1
1. |
put(PdfName.ROOT, root); |
538 |
1
1. |
if (info != null) { |
539 |
1
1. |
put(PdfName.INFO, info); |
540 | } | |
541 |
1
1. |
if (encryption != null) |
542 |
1
1. |
put(PdfName.ENCRYPT, encryption); |
543 |
1
1. |
if (fileID != null) |
544 |
1
1. |
put(PdfName.ID, fileID); |
545 |
2
1. 2. |
if (prevxref > 0) |
546 |
1
1. |
put(PdfName.PREV, new PdfNumber(prevxref)); |
547 | } | |
548 | ||
549 | /** | |
550 | * Returns the PDF representation of this <CODE>PdfObject</CODE>. | |
551 | * @param writer | |
552 | * @param os | |
553 | * @throws IOException | |
554 | */ | |
555 | public void toPdf(PdfWriter writer, OutputStream os) throws IOException { | |
556 |
1
1. toPdf : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write(getISOBytes("trailer\n")); |
557 |
1
1. toPdf : removed call to com/lowagie/text/pdf/PdfDictionary::toPdf → NO_COVERAGE |
super.toPdf(null, os); |
558 |
1
1. toPdf : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write(getISOBytes("\nstartxref\n")); |
559 |
1
1. toPdf : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write(getISOBytes(String.valueOf(offset))); |
560 |
1
1. toPdf : removed call to java/io/OutputStream::write → NO_COVERAGE |
os.write(getISOBytes("\n%%EOF\n")); |
561 | } | |
562 | } | |
563 | ||
564 | // ESSENTIALS | |
565 | ||
566 | // Construct a PdfWriter instance | |
567 | ||
568 | /** | |
569 | * Constructs a <CODE>PdfWriter</CODE>. | |
570 | */ | |
571 | protected PdfWriter() { | |
572 | } | |
573 | ||
574 | /** | |
575 | * Constructs a <CODE>PdfWriter</CODE>. | |
576 | * <P> | |
577 | * Remark: a PdfWriter can only be constructed by calling the method | |
578 | * <CODE>getInstance(Document document, OutputStream os)</CODE>. | |
579 | * | |
580 | * @param document The <CODE>PdfDocument</CODE> that has to be written | |
581 | * @param os The <CODE>OutputStream</CODE> the writer has to write to. | |
582 | */ | |
583 | ||
584 | protected PdfWriter(PdfDocument document, OutputStream os) { | |
585 | super(document, os); | |
586 | pdf = document; | |
587 | directContent = new PdfContentByte(this); | |
588 | directContentUnder = new PdfContentByte(this); | |
589 | } | |
590 | ||
591 | /** | |
592 | * Use this method to get an instance of the <CODE>PdfWriter</CODE>. | |
593 | * | |
594 | * @param document The <CODE>Document</CODE> that has to be written | |
595 | * @param os The <CODE>OutputStream</CODE> the writer has to write to. | |
596 | * @return a new <CODE>PdfWriter</CODE> | |
597 | * | |
598 | * @throws DocumentException on error | |
599 | */ | |
600 | ||
601 | public static PdfWriter getInstance(Document document, OutputStream os) | |
602 | throws DocumentException { | |
603 | PdfDocument pdf = new PdfDocument(); | |
604 |
1
1. getInstance : removed call to com/lowagie/text/Document::addDocListener → NO_COVERAGE |
document.addDocListener(pdf); |
605 | PdfWriter writer = new PdfWriter(pdf, os); | |
606 |
1
1. getInstance : removed call to com/lowagie/text/pdf/PdfDocument::addWriter → NO_COVERAGE |
pdf.addWriter(writer); |
607 |
1
1. getInstance : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::getInstance to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return writer; |
608 | } | |
609 | ||
610 | /** | |
611 | * Use this method to get an instance of the <CODE>PdfWriter</CODE>. | |
612 | * | |
613 | * @return a new <CODE>PdfWriter</CODE> | |
614 | * @param document The <CODE>Document</CODE> that has to be written | |
615 | * @param os The <CODE>OutputStream</CODE> the writer has to write to. | |
616 | * @param listener A <CODE>DocListener</CODE> to pass to the PdfDocument. | |
617 | * @throws DocumentException on error | |
618 | */ | |
619 | ||
620 | public static PdfWriter getInstance(Document document, OutputStream os, DocListener listener) | |
621 | throws DocumentException { | |
622 | PdfDocument pdf = new PdfDocument(); | |
623 |
1
1. getInstance : removed call to com/lowagie/text/pdf/PdfDocument::addDocListener → NO_COVERAGE |
pdf.addDocListener(listener); |
624 |
1
1. getInstance : removed call to com/lowagie/text/Document::addDocListener → NO_COVERAGE |
document.addDocListener(pdf); |
625 | PdfWriter writer = new PdfWriter(pdf, os); | |
626 |
1
1. getInstance : removed call to com/lowagie/text/pdf/PdfDocument::addWriter → NO_COVERAGE |
pdf.addWriter(writer); |
627 |
1
1. getInstance : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::getInstance to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return writer; |
628 | } | |
629 | ||
630 | // the PdfDocument instance | |
631 | ||
632 | /** the pdfdocument object. */ | |
633 | protected PdfDocument pdf; | |
634 | ||
635 | /** | |
636 | * Gets the <CODE>PdfDocument</CODE> associated with this writer. | |
637 | * @return the <CODE>PdfDocument</CODE> | |
638 | */ | |
639 | ||
640 | PdfDocument getPdfDocument() { | |
641 | return pdf; | |
642 | } | |
643 | ||
644 | /** | |
645 | * Use this method to get the info dictionary if you want to | |
646 | * change it directly (add keys and values to the info dictionary). | |
647 | * @return the info dictionary | |
648 | */ | |
649 | public PdfDictionary getInfo() { | |
650 | return pdf.getInfo(); | |
651 | } | |
652 | ||
653 | /** | |
654 | * Use this method to get the current vertical page position. | |
655 | * @param ensureNewLine Tells whether a new line shall be enforced. This may cause side effects | |
656 | * for elements that do not terminate the lines they've started because those lines will get | |
657 | * terminated. | |
658 | * @return The current vertical page position. | |
659 | */ | |
660 | public float getVerticalPosition(boolean ensureNewLine) { | |
661 | return pdf.getVerticalPosition(ensureNewLine); | |
662 | } | |
663 | ||
664 | /** | |
665 | * Sets the initial leading for the PDF document. | |
666 | * This has to be done before the document is opened. | |
667 | * @param leading the initial leading | |
668 | * @since 2.1.6 | |
669 | * @throws DocumentException if you try setting the leading after the document was opened. | |
670 | */ | |
671 | public void setInitialLeading(float leading) throws DocumentException { | |
672 |
1
1. setInitialLeading : negated conditional → NO_COVERAGE |
if (open) |
673 | throw new DocumentException(MessageLocalization.getComposedMessage("you.can.t.set.the.initial.leading.if.the.document.is.already.open")); | |
674 |
1
1. setInitialLeading : removed call to com/lowagie/text/pdf/PdfDocument::setLeading → NO_COVERAGE |
pdf.setLeading(leading); |
675 | } | |
676 | | |
677 | // the PdfDirectContentByte instances | |
678 | ||
679 | /* | |
680 | * You should see Direct Content as a canvas on which you can draw | |
681 | * graphics and text. One canvas goes on top of the page (getDirectContent), | |
682 | * the other goes underneath (getDirectContentUnder). | |
683 | * You can always the same object throughout your document, | |
684 | * even if you have moved to a new page. Whatever you add on | |
685 | * the canvas will be displayed on top or under the current page. | |
686 | */ | |
687 | ||
688 | /** The direct content in this document. */ | |
689 | protected PdfContentByte directContent; | |
690 | ||
691 | /** The direct content under in this document. */ | |
692 | protected PdfContentByte directContentUnder; | |
693 | ||
694 | /** | |
695 | * Use this method to get the direct content for this document. | |
696 | * There is only one direct content, multiple calls to this method | |
697 | * will allways retrieve the same object. | |
698 | * @return the direct content | |
699 | */ | |
700 | ||
701 | public PdfContentByte getDirectContent() { | |
702 |
1
1. getDirectContent : negated conditional → NO_COVERAGE |
if (!open) |
703 | throw new RuntimeException(MessageLocalization.getComposedMessage("the.document.is.not.open")); | |
704 |
1
1. getDirectContent : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::getDirectContent to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return directContent; |
705 | } | |
706 | ||
707 | /** | |
708 | * Use this method to get the direct content under for this document. | |
709 | * There is only one direct content, multiple calls to this method | |
710 | * will always retrieve the same object. | |
711 | * @return the direct content | |
712 | */ | |
713 | ||
714 | public PdfContentByte getDirectContentUnder() { | |
715 |
1
1. getDirectContentUnder : negated conditional → NO_COVERAGE |
if (!open) |
716 | throw new RuntimeException(MessageLocalization.getComposedMessage("the.document.is.not.open")); | |
717 |
1
1. getDirectContentUnder : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::getDirectContentUnder to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return directContentUnder; |
718 | } | |
719 | ||
720 | /** | |
721 | * Resets all the direct contents to empty. | |
722 | * This happens when a new page is started. | |
723 | */ | |
724 | void resetContent() { | |
725 |
1
1. resetContent : removed call to com/lowagie/text/pdf/PdfContentByte::reset → NO_COVERAGE |
directContent.reset(); |
726 |
1
1. resetContent : removed call to com/lowagie/text/pdf/PdfContentByte::reset → NO_COVERAGE |
directContentUnder.reset(); |
727 | } | |
728 | ||
729 | // PDF body | |
730 | ||
731 | /* | |
732 | * A PDF file has 4 parts: a header, a body, a cross-reference table, and a trailer. | |
733 | * The body contains all the PDF objects that make up the PDF document. | |
734 | * Each element gets a reference (a set of numbers) and the byte position of | |
735 | * every object is stored in the cross-reference table. | |
736 | * Use these methods only if you know what you're doing. | |
737 | */ | |
738 | ||
739 | /** body of the PDF document */ | |
740 | protected PdfBody body; | |
741 | ||
742 | /** | |
743 | * Adds the local destinations to the body of the document. | |
744 | * @param dest the <CODE>HashMap</CODE> containing the destinations | |
745 | * @throws IOException on error | |
746 | */ | |
747 | ||
748 | void addLocalDestinations(TreeMap dest) throws IOException { | |
749 | for (Object o : dest.entrySet()) { | |
750 | Map.Entry entry = (Map.Entry) o; | |
751 | String name = (String) entry.getKey(); | |
752 | Object[] obj = (Object[]) entry.getValue(); | |
753 | PdfDestination destination = (PdfDestination) obj[2]; | |
754 |
1
1. addLocalDestinations : negated conditional → NO_COVERAGE |
if (obj[1] == null) |
755 | obj[1] = getPdfIndirectReference(); | |
756 |
1
1. addLocalDestinations : negated conditional → NO_COVERAGE |
if (destination == null) |
757 | addToBody(new PdfString("invalid_" + name), (PdfIndirectReference) obj[1]); | |
758 | else | |
759 | addToBody(destination, (PdfIndirectReference) obj[1]); | |
760 | } | |
761 | } | |
762 | ||
763 | /** | |
764 | * Use this method to add a PDF object to the PDF body. | |
765 | * Use this method only if you know what you're doing! | |
766 | * @param object | |
767 | * @return a PdfIndirectObject | |
768 | * @throws IOException | |
769 | */ | |
770 | public PdfIndirectObject addToBody(PdfObject object) throws IOException { | |
771 | PdfIndirectObject iobj = body.add(object); | |
772 |
1
1. addToBody : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::addToBody to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return iobj; |
773 | } | |
774 | ||
775 | /** | |
776 | * Use this method to add a PDF object to the PDF body. | |
777 | * Use this method only if you know what you're doing! | |
778 | * @param object | |
779 | * @param inObjStm | |
780 | * @return a PdfIndirectObject | |
781 | * @throws IOException | |
782 | */ | |
783 | public PdfIndirectObject addToBody(PdfObject object, boolean inObjStm) throws IOException { | |
784 | PdfIndirectObject iobj = body.add(object, inObjStm); | |
785 |
1
1. addToBody : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::addToBody to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return iobj; |
786 | } | |
787 | ||
788 | /** | |
789 | * Use this method to add a PDF object to the PDF body. | |
790 | * Use this method only if you know what you're doing! | |
791 | * @param object | |
792 | * @param ref | |
793 | * @return a PdfIndirectObject | |
794 | * @throws IOException | |
795 | */ | |
796 | public PdfIndirectObject addToBody(PdfObject object, PdfIndirectReference ref) throws IOException { | |
797 | PdfIndirectObject iobj = body.add(object, ref); | |
798 |
1
1. addToBody : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::addToBody to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return iobj; |
799 | } | |
800 | ||
801 | /** | |
802 | * Use this method to add a PDF object to the PDF body. | |
803 | * Use this method only if you know what you're doing! | |
804 | * @param object | |
805 | * @param ref | |
806 | * @param inObjStm | |
807 | * @return a PdfIndirectObject | |
808 | * @throws IOException | |
809 | */ | |
810 | public PdfIndirectObject addToBody(PdfObject object, PdfIndirectReference ref, boolean inObjStm) throws IOException { | |
811 | PdfIndirectObject iobj = body.add(object, ref, inObjStm); | |
812 |
1
1. addToBody : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::addToBody to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return iobj; |
813 | } | |
814 | ||
815 | /** | |
816 | * Use this method to add a PDF object to the PDF body. | |
817 | * Use this method only if you know what you're doing! | |
818 | * @param object | |
819 | * @param refNumber | |
820 | * @return a PdfIndirectObject | |
821 | * @throws IOException | |
822 | */ | |
823 | public PdfIndirectObject addToBody(PdfObject object, int refNumber) throws IOException { | |
824 | PdfIndirectObject iobj = body.add(object, refNumber); | |
825 |
1
1. addToBody : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::addToBody to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return iobj; |
826 | } | |
827 | ||
828 | /** | |
829 | * Use this method to add a PDF object to the PDF body. | |
830 | * Use this method only if you know what you're doing! | |
831 | * @param object | |
832 | * @param refNumber | |
833 | * @param inObjStm | |
834 | * @return a PdfIndirectObject | |
835 | * @throws IOException | |
836 | */ | |
837 | public PdfIndirectObject addToBody(PdfObject object, int refNumber, boolean inObjStm) throws IOException { | |
838 | PdfIndirectObject iobj = body.add(object, refNumber, inObjStm); | |
839 |
1
1. addToBody : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::addToBody to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return iobj; |
840 | } | |
841 | ||
842 | /** | |
843 | * Use this to get an <CODE>PdfIndirectReference</CODE> for an object that | |
844 | * will be created in the future. | |
845 | * Use this method only if you know what you're doing! | |
846 | * @return the <CODE>PdfIndirectReference</CODE> | |
847 | */ | |
848 | ||
849 | public PdfIndirectReference getPdfIndirectReference() { | |
850 | return body.getPdfIndirectReference(); | |
851 | } | |
852 | ||
853 | int getIndirectReferenceNumber() { | |
854 | return body.getIndirectReferenceNumber(); | |
855 | } | |
856 | ||
857 | /** | |
858 | * Returns the outputStreamCounter. | |
859 | * @return the outputStreamCounter | |
860 | */ | |
861 | OutputStreamCounter getOs() { | |
862 | return os; | |
863 | } | |
864 | ||
865 | ||
866 | // PDF Catalog | |
867 | ||
868 | /* | |
869 | * The Catalog is also called the root object of the document. | |
870 | * Whereas the Cross-Reference maps the objects number with the | |
871 | * byte offset so that the viewer can find the objects, the | |
872 | * Catalog tells the viewer the numbers of the objects needed | |
873 | * to render the document. | |
874 | */ | |
875 | ||
876 | protected PdfDictionary getCatalog(PdfIndirectReference rootObj) | |
877 | { | |
878 | PdfDictionary catalog = pdf.getCatalog(rootObj); | |
879 | // [F12] tagged PDF | |
880 |
1
1. getCatalog : negated conditional → NO_COVERAGE |
if (tagged) { |
881 | try { | |
882 |
1
1. getCatalog : removed call to com/lowagie/text/pdf/PdfStructureTreeRoot::buildTree → NO_COVERAGE |
getStructureTreeRoot().buildTree(); |
883 | } | |
884 | catch (Exception e) { | |
885 | throw new ExceptionConverter(e); | |
886 | } | |
887 |
1
1. getCatalog : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
catalog.put(PdfName.STRUCTTREEROOT, structureTreeRoot.getReference()); |
888 | PdfDictionary mi = new PdfDictionary(); | |
889 |
1
1. getCatalog : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
mi.put(PdfName.MARKED, PdfBoolean.PDFTRUE); |
890 |
1
1. getCatalog : negated conditional → NO_COVERAGE |
if (userProperties) |
891 |
1
1. getCatalog : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
mi.put(PdfName.USERPROPERTIES, PdfBoolean.PDFTRUE); |
892 |
1
1. getCatalog : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
catalog.put(PdfName.MARKINFO, mi); |
893 | } | |
894 | // [F13] OCG | |
895 |
1
1. getCatalog : negated conditional → NO_COVERAGE |
if (!documentOCG.isEmpty()) { |
896 |
1
1. getCatalog : removed call to com/lowagie/text/pdf/PdfWriter::fillOCProperties → NO_COVERAGE |
fillOCProperties(false); |
897 |
1
1. getCatalog : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
catalog.put(PdfName.OCPROPERTIES, OCProperties); |
898 | } | |
899 |
1
1. getCatalog : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::getCatalog to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return catalog; |
900 | } | |
901 | ||
902 | /** Holds value of property extraCatalog this is used for Output Intents. */ | |
903 | protected PdfDictionary extraCatalog; | |
904 | ||
905 | /** | |
906 | * Sets extra keys to the catalog. | |
907 | * @return the catalog to change | |
908 | */ | |
909 | public PdfDictionary getExtraCatalog() { | |
910 |
1
1. getExtraCatalog : negated conditional → NO_COVERAGE |
if (extraCatalog == null) |
911 | extraCatalog = new PdfDictionary(); | |
912 |
1
1. getExtraCatalog : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::getExtraCatalog to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return this.extraCatalog; |
913 | } | |
914 | ||
915 | // PdfPages | |
916 | ||
917 | /* | |
918 | * The page root keeps the complete page tree of the document. | |
919 | * There's an entry in the Catalog that refers to the root | |
920 | * of the page tree, the page tree contains the references | |
921 | * to pages and other page trees. | |
922 | */ | |
923 | ||
924 | /** The root of the page tree. */ | |
925 | protected PdfPages root = new PdfPages(this); | |
926 | /** The PdfIndirectReference to the pages. */ | |
927 | protected ArrayList<PdfIndirectReference> pageReferences = new ArrayList<>(); | |
928 | /** The current page number. */ | |
929 | protected int currentPageNumber = 1; | |
930 | /** | |
931 | * The value of the Tabs entry in the page dictionary. | |
932 | * @since 2.1.5 | |
933 | */ | |
934 | protected PdfName tabs = null; | |
935 | ||
936 | /** | |
937 | * Use this method to make sure the page tree has a linear structure | |
938 | * (every leave is attached directly to the root). | |
939 | * Use this method to allow page reordering with method reorderPages. | |
940 | */ | |
941 | public void setLinearPageMode() { | |
942 |
1
1. setLinearPageMode : removed call to com/lowagie/text/pdf/PdfPages::setLinearMode → NO_COVERAGE |
root.setLinearMode(null); |
943 | } | |
944 | ||
945 | /** | |
946 | * Use this method to reorder the pages in the document. | |
947 | * A <CODE>null</CODE> argument value only returns the number of pages to process. | |
948 | * It is advisable to issue a <CODE>Document.newPage()</CODE> before using this method. | |
949 | * @return the total number of pages | |
950 | * @param order an array with the new page sequence. It must have the | |
951 | * same size as the number of pages. | |
952 | * @throws DocumentException if all the pages are not present in the array | |
953 | */ | |
954 | public int reorderPages(int[] order) throws DocumentException { | |
955 | return root.reorderPages(order); | |
956 | } | |
957 | ||
958 | /** | |
959 | * Use this method to get a reference to a page existing or not. | |
960 | * If the page does not exist yet the reference will be created | |
961 | * in advance. If on closing the document, a page number greater | |
962 | * than the total number of pages was requested, an exception | |
963 | * is thrown. | |
964 | * @param page the page number. The first page is 1 | |
965 | * @return the reference to the page | |
966 | */ | |
967 | public PdfIndirectReference getPageReference(int page) { | |
968 |
1
1. getPageReference : Changed increment from -1 to 1 → NO_COVERAGE |
--page; |
969 |
2
1. getPageReference : changed conditional boundary → NO_COVERAGE 2. getPageReference : negated conditional → NO_COVERAGE |
if (page < 0) |
970 | throw new IndexOutOfBoundsException(MessageLocalization.getComposedMessage("the.page.number.must.be.gt.eq.1")); | |
971 | PdfIndirectReference ref; | |
972 |
2
1. getPageReference : changed conditional boundary → NO_COVERAGE 2. getPageReference : negated conditional → NO_COVERAGE |
if (page < pageReferences.size()) { |
973 | ref = pageReferences.get(page); | |
974 |
1
1. getPageReference : negated conditional → NO_COVERAGE |
if (ref == null) { |
975 | ref = body.getPdfIndirectReference(); | |
976 | pageReferences.set(page, ref); | |
977 | } | |
978 | } | |
979 | else { | |
980 |
1
1. getPageReference : Replaced integer subtraction with addition → NO_COVERAGE |
int empty = page - pageReferences.size(); |
981 |
3
1. getPageReference : changed conditional boundary → NO_COVERAGE 2. getPageReference : Changed increment from 1 to -1 → NO_COVERAGE 3. getPageReference : negated conditional → NO_COVERAGE |
for (int k = 0; k < empty; ++k) |
982 | pageReferences.add(null); | |
983 | ref = body.getPdfIndirectReference(); | |
984 | pageReferences.add(ref); | |
985 | } | |
986 |
1
1. getPageReference : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::getPageReference to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return ref; |
987 | } | |
988 | ||
989 | /** | |
990 | * Gets the pagenumber of this document. | |
991 | * This number can be different from the real pagenumber, | |
992 | * if you have (re)set the page number previously. | |
993 | * @return a page number | |
994 | */ | |
995 | ||
996 | public int getPageNumber() { | |
997 | return pdf.getPageNumber(); | |
998 | } | |
999 | ||
1000 | PdfIndirectReference getCurrentPage() { | |
1001 |
1
1. getCurrentPage : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::getCurrentPage to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return getPageReference(currentPageNumber); |
1002 | } | |
1003 | ||
1004 | public int getCurrentPageNumber() { | |
1005 | return currentPageNumber; | |
1006 | } | |
1007 | ||
1008 | /** | |
1009 | * Sets the value for the Tabs entry in the page tree. | |
1010 | * @param tabs Can be PdfName.R, PdfName.C or PdfName.S. | |
1011 | * Since the Adobe Extensions Level 3, it can also be PdfName.A | |
1012 | * or PdfName.W | |
1013 | * @since 2.1.5 | |
1014 | */ | |
1015 | public void setTabs(PdfName tabs) { | |
1016 | this.tabs = tabs; | |
1017 | } | |
1018 | ||
1019 | /** | |
1020 | * Returns the value to be used for the Tabs entry in the page tree. | |
1021 | * @since 2.1.5 | |
1022 | */ | |
1023 | public PdfName getTabs() { | |
1024 | return tabs; | |
1025 | } | |
1026 | ||
1027 | /** | |
1028 | * Adds some <CODE>PdfContents</CODE> to this Writer. | |
1029 | * <P> | |
1030 | * The document has to be open before you can begin to add content | |
1031 | * to the body of the document. | |
1032 | * | |
1033 | * @return a <CODE>PdfIndirectReference</CODE> | |
1034 | * @param page the <CODE>PdfPage</CODE> to add | |
1035 | * @param contents the <CODE>PdfContents</CODE> of the page | |
1036 | * @throws PdfException on error | |
1037 | */ | |
1038 | ||
1039 | PdfIndirectReference add(PdfPage page, PdfContents contents) throws PdfException { | |
1040 |
1
1. add : negated conditional → NO_COVERAGE |
if (!open) { |
1041 | throw new PdfException(MessageLocalization.getComposedMessage("the.document.is.not.open")); | |
1042 | } | |
1043 | PdfIndirectObject object; | |
1044 | try { | |
1045 | object = addToBody(contents); | |
1046 | } | |
1047 | catch(IOException ioe) { | |
1048 | throw new ExceptionConverter(ioe); | |
1049 | } | |
1050 |
1
1. add : removed call to com/lowagie/text/pdf/PdfPage::add → NO_COVERAGE |
page.add(object.getIndirectReference()); |
1051 | // [U5] | |
1052 |
1
1. add : negated conditional → NO_COVERAGE |
if (group != null) { |
1053 |
1
1. add : removed call to com/lowagie/text/pdf/PdfPage::put → NO_COVERAGE |
page.put(PdfName.GROUP, group); |
1054 | group = null; | |
1055 | } | |
1056 |
1
1. add : negated conditional → NO_COVERAGE |
else if (rgbTransparencyBlending) { |
1057 | PdfDictionary pp = new PdfDictionary(); | |
1058 |
1
1. add : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
pp.put(PdfName.TYPE, PdfName.GROUP); |
1059 |
1
1. add : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
pp.put(PdfName.S, PdfName.TRANSPARENCY); |
1060 |
1
1. add : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
pp.put(PdfName.CS, PdfName.DEVICERGB); |
1061 |
1
1. add : removed call to com/lowagie/text/pdf/PdfPage::put → NO_COVERAGE |
page.put(PdfName.GROUP, pp); |
1062 | } | |
1063 |
1
1. add : removed call to com/lowagie/text/pdf/PdfPages::addPage → NO_COVERAGE |
root.addPage(page); |
1064 |
1
1. add : Replaced integer addition with subtraction → NO_COVERAGE |
currentPageNumber++; |
1065 |
1
1. add : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::add to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return null; |
1066 | } | |
1067 | ||
1068 | // page events | |
1069 | ||
1070 | /* | |
1071 | * Page events are specific for iText, not for PDF. | |
1072 | * Upon specific events (for instance when a page starts | |
1073 | * or ends), the corresponding method in the page event | |
1074 | * implementation that is added to the writer is invoked. | |
1075 | */ | |
1076 | ||
1077 | /** The <CODE>PdfPageEvent</CODE> for this document. */ | |
1078 | private PdfPageEvent pageEvent; | |
1079 | ||
1080 | /** | |
1081 | * Sets the <CODE>PdfPageEvent</CODE> for this document. | |
1082 | * @param event the <CODE>PdfPageEvent</CODE> for this document | |
1083 | */ | |
1084 | ||
1085 | public void setPageEvent(PdfPageEvent event) { | |
1086 |
1
1. setPageEvent : negated conditional → NO_COVERAGE |
if (event == null) this.pageEvent = null; |
1087 |
1
1. setPageEvent : negated conditional → NO_COVERAGE |
else if (this.pageEvent == null) this.pageEvent = event; |
1088 |
2
1. setPageEvent : negated conditional → NO_COVERAGE 2. setPageEvent : removed call to com/lowagie/text/pdf/events/PdfPageEventForwarder::addPageEvent → NO_COVERAGE |
else if (this.pageEvent instanceof PdfPageEventForwarder) ((PdfPageEventForwarder)this.pageEvent).addPageEvent(event); |
1089 | else { | |
1090 | PdfPageEventForwarder forward = new PdfPageEventForwarder(); | |
1091 |
1
1. setPageEvent : removed call to com/lowagie/text/pdf/events/PdfPageEventForwarder::addPageEvent → NO_COVERAGE |
forward.addPageEvent(this.pageEvent); |
1092 |
1
1. setPageEvent : removed call to com/lowagie/text/pdf/events/PdfPageEventForwarder::addPageEvent → NO_COVERAGE |
forward.addPageEvent(event); |
1093 | this.pageEvent = forward; | |
1094 | } | |
1095 | } | |
1096 | ||
1097 | /** | |
1098 | * Gets the <CODE>PdfPageEvent</CODE> for this document or <CODE>null</CODE> | |
1099 | * if none is set. | |
1100 | * @return the <CODE>PdfPageEvent</CODE> for this document or <CODE>null</CODE> | |
1101 | * if none is set | |
1102 | */ | |
1103 | ||
1104 | public PdfPageEvent getPageEvent() { | |
1105 | return pageEvent; | |
1106 | } | |
1107 | ||
1108 | // Open and Close methods + method that create the PDF | |
1109 | ||
1110 | /** A number referring to the previous Cross-Reference Table. */ | |
1111 | protected int prevxref = 0; | |
1112 | ||
1113 | /** | |
1114 | * Signals that the <CODE>Document</CODE> has been opened and that | |
1115 | * <CODE>Elements</CODE> can be added. | |
1116 | * <P> | |
1117 | * When this method is called, the PDF-document header is | |
1118 | * written to the outputstream. | |
1119 | * @see com.lowagie.text.DocWriter#open() | |
1120 | */ | |
1121 | public void open() { | |
1122 |
1
1. open : removed call to com/lowagie/text/DocWriter::open → NO_COVERAGE |
super.open(); |
1123 | try { | |
1124 |
1
1. open : removed call to com/lowagie/text/pdf/internal/PdfVersionImp::writeHeader → NO_COVERAGE |
pdf_version.writeHeader(os); |
1125 | body = new PdfBody(this); | |
1126 |
1
1. open : negated conditional → NO_COVERAGE |
if (pdfxConformance.isPdfX32002()) { |
1127 | PdfDictionary sec = new PdfDictionary(); | |
1128 |
1
1. open : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
sec.put(PdfName.GAMMA, new PdfArray(new float[]{2.2f,2.2f,2.2f})); |
1129 |
1
1. open : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
sec.put(PdfName.MATRIX, new PdfArray(new float[]{0.4124f,0.2126f,0.0193f,0.3576f,0.7152f,0.1192f,0.1805f,0.0722f,0.9505f})); |
1130 |
1
1. open : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
sec.put(PdfName.WHITEPOINT, new PdfArray(new float[]{0.9505f,1f,1.089f})); |
1131 | PdfArray arr = new PdfArray(PdfName.CALRGB); | |
1132 | arr.add(sec); | |
1133 |
1
1. open : removed call to com/lowagie/text/pdf/PdfWriter::setDefaultColorspace → NO_COVERAGE |
setDefaultColorspace(PdfName.DEFAULTRGB, addToBody(arr).getIndirectReference()); |
1134 | } | |
1135 | } | |
1136 | catch(IOException ioe) { | |
1137 | throw new ExceptionConverter(ioe); | |
1138 | } | |
1139 | } | |
1140 | ||
1141 | /** | |
1142 | * Signals that the <CODE>Document</CODE> was closed and that no other | |
1143 | * <CODE>Elements</CODE> will be added. | |
1144 | * <P> | |
1145 | * The pages-tree is built and written to the outputstream. | |
1146 | * A Catalog is constructed, as well as an Info-object, | |
1147 | * the reference table is composed and everything is written | |
1148 | * to the outputstream embedded in a Trailer. | |
1149 | * @see com.lowagie.text.DocWriter#close() | |
1150 | */ | |
1151 | @Override | |
1152 | public void close() { | |
1153 |
1
1. close : negated conditional → NO_COVERAGE |
if (open) { |
1154 |
2
1. close : Replaced integer subtraction with addition → NO_COVERAGE 2. close : negated conditional → NO_COVERAGE |
if ((currentPageNumber - 1) != pageReferences.size()) |
1155 |
1
1. close : Replaced integer subtraction with addition → NO_COVERAGE |
throw new RuntimeException("The page " + pageReferences.size() + |
1156 | " was requested but the document has only " + (currentPageNumber - 1) + " pages."); | |
1157 |
1
1. close : removed call to com/lowagie/text/pdf/PdfDocument::close → NO_COVERAGE |
pdf.close(); |
1158 | try { | |
1159 |
1
1. close : removed call to com/lowagie/text/pdf/PdfWriter::addSharedObjectsToBody → NO_COVERAGE |
addSharedObjectsToBody(); |
1160 | // add the root to the body | |
1161 | PdfIndirectReference rootRef = root.writePageTree(); | |
1162 | // make the catalog-object and add it to the body | |
1163 | PdfDictionary catalog = getCatalog(rootRef); | |
1164 | // [C9] if there is XMP data to add: add it | |
1165 |
1
1. close : negated conditional → NO_COVERAGE |
if (xmpMetadata != null) { |
1166 | PdfStream xmp = new PdfStream(xmpMetadata); | |
1167 |
1
1. close : removed call to com/lowagie/text/pdf/PdfStream::put → NO_COVERAGE |
xmp.put(PdfName.TYPE, PdfName.METADATA); |
1168 |
1
1. close : removed call to com/lowagie/text/pdf/PdfStream::put → NO_COVERAGE |
xmp.put(PdfName.SUBTYPE, PdfName.XML); |
1169 |
2
1. close : negated conditional → NO_COVERAGE 2. close : negated conditional → NO_COVERAGE |
if (crypto != null && !crypto.isMetadataEncrypted()) { |
1170 | PdfArray ar = new PdfArray(); | |
1171 | ar.add(PdfName.CRYPT); | |
1172 |
1
1. close : removed call to com/lowagie/text/pdf/PdfStream::put → NO_COVERAGE |
xmp.put(PdfName.FILTER, ar); |
1173 | } | |
1174 |
1
1. close : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
catalog.put(PdfName.METADATA, body.add(xmp).getIndirectReference()); |
1175 | } | |
1176 | // [C10] make pdfx conformant | |
1177 |
1
1. close : negated conditional → NO_COVERAGE |
if (isPdfX()) { |
1178 |
1
1. close : removed call to com/lowagie/text/pdf/internal/PdfXConformanceImp::completeInfoDictionary → NO_COVERAGE |
pdfxConformance.completeInfoDictionary(getInfo()); |
1179 |
1
1. close : removed call to com/lowagie/text/pdf/internal/PdfXConformanceImp::completeExtraCatalog → NO_COVERAGE |
pdfxConformance.completeExtraCatalog(getExtraCatalog()); |
1180 | } | |
1181 | // [C11] Output Intents | |
1182 |
1
1. close : negated conditional → NO_COVERAGE |
if (extraCatalog != null) { |
1183 |
1
1. close : removed call to com/lowagie/text/pdf/PdfDictionary::mergeDifferent → NO_COVERAGE |
catalog.mergeDifferent(extraCatalog); |
1184 | } | |
1185 | ||
1186 |
1
1. close : removed call to com/lowagie/text/pdf/PdfWriter::writeOutlines → NO_COVERAGE |
writeOutlines(catalog, false); |
1187 | ||
1188 | // add the Catalog to the body | |
1189 | PdfIndirectObject indirectCatalog = addToBody(catalog, false); | |
1190 | // add the info-object to the body | |
1191 | PdfIndirectObject infoObj = addToBody(getInfo(), false); | |
1192 | ||
1193 | // [F1] encryption | |
1194 | PdfIndirectReference encryption = null; | |
1195 | PdfObject fileID = null; | |
1196 |
1
1. close : removed call to com/lowagie/text/pdf/PdfWriter$PdfBody::access$000 → NO_COVERAGE |
body.flushObjStm(); |
1197 |
1
1. close : negated conditional → NO_COVERAGE |
if (crypto != null) { |
1198 | PdfIndirectObject encryptionObject = addToBody(crypto.getEncryptionDictionary(), false); | |
1199 | encryption = encryptionObject.getIndirectReference(); | |
1200 | fileID = crypto.getFileID(); | |
1201 | } | |
1202 | else | |
1203 | fileID = PdfEncryption.createInfoId(PdfEncryption.createDocumentId()); | |
1204 | ||
1205 | // write the cross-reference table of the body | |
1206 |
1
1. close : removed call to com/lowagie/text/pdf/PdfWriter$PdfBody::writeCrossReferenceTable → NO_COVERAGE |
body.writeCrossReferenceTable(os, indirectCatalog.getIndirectReference(), |
1207 | infoObj.getIndirectReference(), encryption, fileID, prevxref); | |
1208 | ||
1209 | // make the trailer | |
1210 | // [F2] full compression | |
1211 |
1
1. close : negated conditional → NO_COVERAGE |
if (fullCompression) { |
1212 |
1
1. close : removed call to com/lowagie/text/pdf/OutputStreamCounter::write → NO_COVERAGE |
os.write(getISOBytes("startxref\n")); |
1213 |
1
1. close : removed call to com/lowagie/text/pdf/OutputStreamCounter::write → NO_COVERAGE |
os.write(getISOBytes(String.valueOf(body.offset()))); |
1214 |
1
1. close : removed call to com/lowagie/text/pdf/OutputStreamCounter::write → NO_COVERAGE |
os.write(getISOBytes("\n%%EOF\n")); |
1215 | } | |
1216 | else { | |
1217 | PdfTrailer trailer = new PdfTrailer(body.size(), | |
1218 | body.offset(), | |
1219 | indirectCatalog.getIndirectReference(), | |
1220 | infoObj.getIndirectReference(), | |
1221 | encryption, | |
1222 | fileID, prevxref); | |
1223 |
1
1. close : removed call to com/lowagie/text/pdf/PdfWriter$PdfTrailer::toPdf → NO_COVERAGE |
trailer.toPdf(this, os); |
1224 | } | |
1225 |
1
1. close : removed call to com/lowagie/text/DocWriter::close → NO_COVERAGE |
super.close(); |
1226 | } | |
1227 | catch(IOException ioe) { | |
1228 | throw new ExceptionConverter(ioe); | |
1229 | } | |
1230 | } | |
1231 | } | |
1232 | ||
1233 | protected void addSharedObjectsToBody() throws IOException { | |
1234 | // [F3] add the fonts | |
1235 | for (FontDetails details : documentFonts.values()) { | |
1236 |
1
1. addSharedObjectsToBody : removed call to com/lowagie/text/pdf/FontDetails::writeFont → NO_COVERAGE |
details.writeFont(this); |
1237 | } | |
1238 | // [F4] add the form XObjects | |
1239 | for (Object[] objs : formXObjects.values()) { | |
1240 | PdfTemplate template = (PdfTemplate) objs[1]; | |
1241 |
2
1. addSharedObjectsToBody : negated conditional → NO_COVERAGE 2. addSharedObjectsToBody : negated conditional → NO_COVERAGE |
if (template != null && template.getIndirectReference() instanceof PRIndirectReference) |
1242 | continue; | |
1243 |
2
1. addSharedObjectsToBody : negated conditional → NO_COVERAGE 2. addSharedObjectsToBody : negated conditional → NO_COVERAGE |
if (template != null && template.getType() == PdfTemplate.TYPE_TEMPLATE) { |
1244 | addToBody(template.getFormXObject(compressionLevel), template.getIndirectReference()); | |
1245 | } | |
1246 | } | |
1247 | // [F5] add all the dependencies in the imported pages | |
1248 | for (PdfReaderInstance pdfReaderInstance : importedPages.values()) { | |
1249 | currentPdfReaderInstance = pdfReaderInstance; | |
1250 |
1
1. addSharedObjectsToBody : removed call to com/lowagie/text/pdf/PdfReaderInstance::writeAllPages → NO_COVERAGE |
currentPdfReaderInstance.writeAllPages(); |
1251 | } | |
1252 | currentPdfReaderInstance = null; | |
1253 | // [F6] add the spotcolors | |
1254 | for (ColorDetails color : documentColors.values()) { | |
1255 | addToBody(color.getSpotColor(this), color.getIndirectReference()); | |
1256 | } | |
1257 | // [F7] add the pattern | |
1258 | for (PdfPatternPainter pat : documentPatterns.keySet()) { | |
1259 | addToBody(pat.getPattern(compressionLevel), pat.getIndirectReference()); | |
1260 | } | |
1261 | // [F8] add the shading patterns | |
1262 | for (PdfShadingPattern shadingPattern : documentShadingPatterns.keySet()) { | |
1263 |
1
1. addSharedObjectsToBody : removed call to com/lowagie/text/pdf/PdfShadingPattern::addToBody → NO_COVERAGE |
shadingPattern.addToBody(); |
1264 | } | |
1265 | // [F9] add the shadings | |
1266 | for (PdfShading shading : documentShadings.keySet()) { | |
1267 |
1
1. addSharedObjectsToBody : removed call to com/lowagie/text/pdf/PdfShading::addToBody → NO_COVERAGE |
shading.addToBody(); |
1268 | } | |
1269 | // [F10] add the extgstate | |
1270 | for (Map.Entry<PdfDictionary, PdfObject[]> entry : documentExtGState.entrySet()) { | |
1271 | PdfDictionary gstate = entry.getKey(); | |
1272 | PdfObject[] obj = entry.getValue(); | |
1273 | addToBody(gstate, (PdfIndirectReference) obj[1]); | |
1274 | } | |
1275 | // [F11] add the properties | |
1276 | for (Map.Entry<Object, PdfObject[]> entry : documentProperties.entrySet()) { | |
1277 | Object prop = entry.getKey(); | |
1278 | PdfObject[] obj = entry.getValue(); | |
1279 |
1
1. addSharedObjectsToBody : negated conditional → NO_COVERAGE |
if (prop instanceof PdfLayerMembership) { |
1280 | PdfLayerMembership layer = (PdfLayerMembership) prop; | |
1281 | addToBody(layer.getPdfObject(), layer.getRef()); | |
1282 |
2
1. addSharedObjectsToBody : negated conditional → NO_COVERAGE 2. addSharedObjectsToBody : negated conditional → NO_COVERAGE |
} else if ((prop instanceof PdfDictionary) && !(prop instanceof PdfLayer)) { |
1283 | addToBody((PdfDictionary) prop, (PdfIndirectReference) obj[1]); | |
1284 | } | |
1285 | } | |
1286 | // [F13] add the OCG layers | |
1287 | for (PdfOCG layer : documentOCG) { | |
1288 | addToBody(layer.getPdfObject(), layer.getRef()); | |
1289 | } | |
1290 | } | |
1291 | ||
1292 | // Root data for the PDF document (used when composing the Catalog) | |
1293 | ||
1294 | // [C1] Outlines (bookmarks) | |
1295 | ||
1296 | /** | |
1297 | * Use this method to get the root outline | |
1298 | * and construct bookmarks. | |
1299 | * @return the root outline | |
1300 | */ | |
1301 | ||
1302 | public PdfOutline getRootOutline() { | |
1303 | return directContent.getRootOutline(); | |
1304 | } | |
1305 | ||
1306 | protected List newBookmarks; | |
1307 | ||
1308 | /** | |
1309 | * Sets the bookmarks. The list structure is defined in | |
1310 | * {@link SimpleBookmark}. | |
1311 | * @param outlines the bookmarks or <CODE>null</CODE> to remove any | |
1312 | */ | |
1313 | public void setOutlines(List outlines) { | |
1314 | newBookmarks = outlines; | |
1315 | } | |
1316 | ||
1317 | protected void writeOutlines(PdfDictionary catalog, boolean namedAsNames) throws IOException { | |
1318 |
2
1. writeOutlines : negated conditional → NO_COVERAGE 2. writeOutlines : negated conditional → NO_COVERAGE |
if (newBookmarks == null || newBookmarks.isEmpty()) |
1319 | return; | |
1320 | PdfDictionary top = new PdfDictionary(); | |
1321 | PdfIndirectReference topRef = getPdfIndirectReference(); | |
1322 | Object[] kids = SimpleBookmark.iterateOutlines(this, topRef, newBookmarks, namedAsNames); | |
1323 |
1
1. writeOutlines : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
top.put(PdfName.FIRST, (PdfIndirectReference)kids[0]); |
1324 |
1
1. writeOutlines : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
top.put(PdfName.LAST, (PdfIndirectReference)kids[1]); |
1325 |
1
1. writeOutlines : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
top.put(PdfName.COUNT, new PdfNumber((Integer) kids[2])); |
1326 | addToBody(top, topRef); | |
1327 |
1
1. writeOutlines : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
catalog.put(PdfName.OUTLINES, topRef); |
1328 | } | |
1329 | ||
1330 | // [C2] PdfVersion interface | |
1331 | /** possible PDF version (header) */ | |
1332 | public static final char VERSION_1_2 = '2'; | |
1333 | /** possible PDF version (header) */ | |
1334 | public static final char VERSION_1_3 = '3'; | |
1335 | /** possible PDF version (header) */ | |
1336 | public static final char VERSION_1_4 = '4'; | |
1337 | /** possible PDF version (header) */ | |
1338 | public static final char VERSION_1_5 = '5'; | |
1339 | /** possible PDF version (header) */ | |
1340 | public static final char VERSION_1_6 = '6'; | |
1341 | /** possible PDF version (header) */ | |
1342 | public static final char VERSION_1_7 = '7'; | |
1343 | ||
1344 | /** possible PDF version (catalog) */ | |
1345 | public static final PdfName PDF_VERSION_1_2 = new PdfName("1.2"); | |
1346 | /** possible PDF version (catalog) */ | |
1347 | public static final PdfName PDF_VERSION_1_3 = new PdfName("1.3"); | |
1348 | /** possible PDF version (catalog) */ | |
1349 | public static final PdfName PDF_VERSION_1_4 = new PdfName("1.4"); | |
1350 | /** possible PDF version (catalog) */ | |
1351 | public static final PdfName PDF_VERSION_1_5 = new PdfName("1.5"); | |
1352 | /** possible PDF version (catalog) */ | |
1353 | public static final PdfName PDF_VERSION_1_6 = new PdfName("1.6"); | |
1354 | /** possible PDF version (catalog) */ | |
1355 | public static final PdfName PDF_VERSION_1_7 = new PdfName("1.7"); | |
1356 | ||
1357 | /** Stores the version information for the header and the catalog. */ | |
1358 | protected PdfVersionImp pdf_version = new PdfVersionImp(); | |
1359 | ||
1360 | /** @see com.lowagie.text.pdf.interfaces.PdfVersion#setPdfVersion(char) */ | |
1361 | public void setPdfVersion(char version) { | |
1362 | pdf_version.setPdfVersion(version); | |
1363 | } | |
1364 | ||
1365 | /** @see com.lowagie.text.pdf.interfaces.PdfVersion#setAtLeastPdfVersion(char) */ | |
1366 | public void setAtLeastPdfVersion(char version) { | |
1367 | pdf_version.setAtLeastPdfVersion(version); | |
1368 | } | |
1369 | ||
1370 | /** @see com.lowagie.text.pdf.interfaces.PdfVersion#setPdfVersion(com.lowagie.text.pdf.PdfName) */ | |
1371 | public void setPdfVersion(PdfName version) { | |
1372 | pdf_version.setPdfVersion(version); | |
1373 | } | |
1374 | ||
1375 | /** | |
1376 | * @see com.lowagie.text.pdf.interfaces.PdfVersion#addDeveloperExtension(com.lowagie.text.pdf.PdfDeveloperExtension) | |
1377 | * @since 2.1.6 | |
1378 | */ | |
1379 | public void addDeveloperExtension(PdfDeveloperExtension de) { | |
1380 | pdf_version.addDeveloperExtension(de); | |
1381 | } | |
1382 | | |
1383 | /** | |
1384 | * Returns the version information. | |
1385 | */ | |
1386 | PdfVersionImp getPdfVersion() { | |
1387 | return pdf_version; | |
1388 | } | |
1389 | ||
1390 | // [C3] PdfViewerPreferences interface | |
1391 | ||
1392 | // page layout (section 13.1.1 of "iText in Action") | |
1393 | ||
1394 | /** A viewer preference */ | |
1395 | public static final int PageLayoutSinglePage = 1; | |
1396 | /** A viewer preference */ | |
1397 | public static final int PageLayoutOneColumn = 2; | |
1398 | /** A viewer preference */ | |
1399 | public static final int PageLayoutTwoColumnLeft = 4; | |
1400 | /** A viewer preference */ | |
1401 | public static final int PageLayoutTwoColumnRight = 8; | |
1402 | /** A viewer preference */ | |
1403 | public static final int PageLayoutTwoPageLeft = 16; | |
1404 | /** A viewer preference */ | |
1405 | public static final int PageLayoutTwoPageRight = 32; | |
1406 | ||
1407 | // page mode (section 13.1.2 of "iText in Action") | |
1408 | ||
1409 | /** A viewer preference */ | |
1410 | public static final int PageModeUseNone = 64; | |
1411 | /** A viewer preference */ | |
1412 | public static final int PageModeUseOutlines = 128; | |
1413 | /** A viewer preference */ | |
1414 | public static final int PageModeUseThumbs = 256; | |
1415 | /** A viewer preference */ | |
1416 | public static final int PageModeFullScreen = 512; | |
1417 | /** A viewer preference */ | |
1418 | public static final int PageModeUseOC = 1024; | |
1419 | /** A viewer preference */ | |
1420 | public static final int PageModeUseAttachments = 2048; | |
1421 | ||
1422 | // values for setting viewer preferences in iText versions older than 2.x | |
1423 | ||
1424 | /** A viewer preference */ | |
1425 | public static final int HideToolbar = 1 << 12; | |
1426 | /** A viewer preference */ | |
1427 | public static final int HideMenubar = 1 << 13; | |
1428 | /** A viewer preference */ | |
1429 | public static final int HideWindowUI = 1 << 14; | |
1430 | /** A viewer preference */ | |
1431 | public static final int FitWindow = 1 << 15; | |
1432 | /** A viewer preference */ | |
1433 | public static final int CenterWindow = 1 << 16; | |
1434 | /** A viewer preference */ | |
1435 | public static final int DisplayDocTitle = 1 << 17; | |
1436 | ||
1437 | /** A viewer preference */ | |
1438 | public static final int NonFullScreenPageModeUseNone = 1 << 18; | |
1439 | /** A viewer preference */ | |
1440 | public static final int NonFullScreenPageModeUseOutlines = 1 << 19; | |
1441 | /** A viewer preference */ | |
1442 | public static final int NonFullScreenPageModeUseThumbs = 1 << 20; | |
1443 | /** A viewer preference */ | |
1444 | public static final int NonFullScreenPageModeUseOC = 1 << 21; | |
1445 | ||
1446 | /** A viewer preference */ | |
1447 | public static final int DirectionL2R = 1 << 22; | |
1448 | /** A viewer preference */ | |
1449 | public static final int DirectionR2L = 1 << 23; | |
1450 | ||
1451 | /** A viewer preference */ | |
1452 | public static final int PrintScalingNone = 1 << 24; | |
1453 | ||
1454 | /** @see com.lowagie.text.pdf.interfaces.PdfViewerPreferences#setViewerPreferences(int) */ | |
1455 | public void setViewerPreferences(int preferences) { | |
1456 | pdf.setViewerPreferences(preferences); | |
1457 | } | |
1458 | ||
1459 | /** @see com.lowagie.text.pdf.interfaces.PdfViewerPreferences#addViewerPreference(com.lowagie.text.pdf.PdfName, com.lowagie.text.pdf.PdfObject) */ | |
1460 | public void addViewerPreference(PdfName key, PdfObject value) { | |
1461 | pdf.addViewerPreference(key, value); | |
1462 | } | |
1463 | ||
1464 | // [C4] Page labels | |
1465 | ||
1466 | /** | |
1467 | * Use this method to add page labels | |
1468 | * @param pageLabels the page labels | |
1469 | */ | |
1470 | public void setPageLabels(PdfPageLabels pageLabels) { | |
1471 | pdf.setPageLabels(pageLabels); | |
1472 | } | |
1473 | ||
1474 | // [C5] named objects: named destinations, javascript, embedded files | |
1475 | ||
1476 | /** | |
1477 | * Adds named destinations in bulk. | |
1478 | * Valid keys and values of the map can be found in the map | |
1479 | * that is created by SimpleNamedDestination. | |
1480 | * @param map a map with strings as keys for the names, | |
1481 | * and structured strings as values for the destinations | |
1482 | * @param page_offset number of pages that has to be added to | |
1483 | * the page numbers in the destinations (useful if you | |
1484 | * use this method in combination with PdfCopy). | |
1485 | * @since iText 5.0 | |
1486 | */ | |
1487 | public void addNamedDestinations(Map<String, String> map, int page_offset) { | |
1488 | Map.Entry<String, String> entry; | |
1489 | int page; | |
1490 | String dest; | |
1491 | PdfDestination destination; | |
1492 | for (Map.Entry<String, String> stringStringEntry : map.entrySet()) { | |
1493 | entry = stringStringEntry; | |
1494 | dest = entry.getValue(); | |
1495 | page = Integer.parseInt(dest.substring(0, dest.indexOf(" "))); | |
1496 |
1
1. addNamedDestinations : Replaced integer addition with subtraction → NO_COVERAGE |
destination = new PdfDestination(dest.substring(dest.indexOf(" ") + 1)); |
1497 |
2
1. addNamedDestinations : Replaced integer addition with subtraction → NO_COVERAGE 2. addNamedDestinations : removed call to com/lowagie/text/pdf/PdfWriter::addNamedDestination → NO_COVERAGE |
addNamedDestination(entry.getKey(), page + page_offset, destination); |
1498 | } | |
1499 | } | |
1500 | | |
1501 | /** | |
1502 | * Adds one named destination. | |
1503 | * @param name the name for the destination | |
1504 | * @param page the page number where you want to jump to | |
1505 | * @param dest an explicit destination | |
1506 | * @since iText 5.0 | |
1507 | */ | |
1508 | public void addNamedDestination(String name, int page, PdfDestination dest) { | |
1509 | dest.addPage(getPageReference(page)); | |
1510 | pdf.localDestination(name, dest); | |
1511 | } | |
1512 | | |
1513 | /** | |
1514 | * Use this method to add a JavaScript action at the document level. | |
1515 | * When the document opens, all this JavaScript runs. | |
1516 | * @param js The JavaScript action | |
1517 | */ | |
1518 | public void addJavaScript(PdfAction js) { | |
1519 | pdf.addJavaScript(js); | |
1520 | } | |
1521 | ||
1522 | /** | |
1523 | * Use this method to add a JavaScript action at the document level. | |
1524 | * When the document opens, all this JavaScript runs. | |
1525 | * @param code the JavaScript code | |
1526 | * @param unicode select JavaScript unicode. Note that the internal | |
1527 | * Acrobat JavaScript engine does not support unicode, | |
1528 | * so this may or may not work for you | |
1529 | */ | |
1530 | public void addJavaScript(String code, boolean unicode) { | |
1531 |
1
1. addJavaScript : removed call to com/lowagie/text/pdf/PdfWriter::addJavaScript → NO_COVERAGE |
addJavaScript(PdfAction.javaScript(code, this, unicode)); |
1532 | } | |
1533 | ||
1534 | /** | |
1535 | * Use this method to adds a JavaScript action at the document level. | |
1536 | * When the document opens, all this JavaScript runs. | |
1537 | * @param code the JavaScript code | |
1538 | */ | |
1539 | public void addJavaScript(String code) { | |
1540 |
1
1. addJavaScript : removed call to com/lowagie/text/pdf/PdfWriter::addJavaScript → NO_COVERAGE |
addJavaScript(code, false); |
1541 | } | |
1542 | /** | |
1543 | * Use this method to add a JavaScript action at the document level. | |
1544 | * When the document opens, all this JavaScript runs. | |
1545 | * @param name The name of the JS Action in the name tree | |
1546 | * @param js The JavaScript action | |
1547 | */ | |
1548 | public void addJavaScript(String name, PdfAction js) { | |
1549 | pdf.addJavaScript(name, js); | |
1550 | } | |
1551 | ||
1552 | /** | |
1553 | * Use this method to add a JavaScript action at the document level. | |
1554 | * When the document opens, all this JavaScript runs. | |
1555 | * @param name The name of the JS Action in the name tree | |
1556 | * @param code the JavaScript code | |
1557 | * @param unicode select JavaScript unicode. Note that the internal | |
1558 | * Acrobat JavaScript engine does not support unicode, | |
1559 | * so this may or may not work for you | |
1560 | */ | |
1561 | public void addJavaScript(String name, String code, boolean unicode) { | |
1562 |
1
1. addJavaScript : removed call to com/lowagie/text/pdf/PdfWriter::addJavaScript → NO_COVERAGE |
addJavaScript(name, PdfAction.javaScript(code, this, unicode)); |
1563 | } | |
1564 | ||
1565 | /** | |
1566 | * Use this method to adds a JavaScript action at the document level. | |
1567 | * When the document opens, all this JavaScript runs. | |
1568 | * @param name The name of the JS Action in the name tree | |
1569 | * @param code the JavaScript code | |
1570 | */ | |
1571 | public void addJavaScript(String name, String code) { | |
1572 |
1
1. addJavaScript : removed call to com/lowagie/text/pdf/PdfWriter::addJavaScript → NO_COVERAGE |
addJavaScript(name, code, false); |
1573 | } | |
1574 | ||
1575 | /** | |
1576 | * Use this method to add a file attachment at the document level. | |
1577 | * @param description the file description | |
1578 | * @param fileStore an array with the file. If it's <CODE>null</CODE> | |
1579 | * the file will be read from the disk | |
1580 | * @param file the path to the file. It will only be used if | |
1581 | * <CODE>fileStore</CODE> is not <CODE>null</CODE> | |
1582 | * @param fileDisplay the actual file name stored in the pdf | |
1583 | * @throws IOException on error | |
1584 | */ | |
1585 | public void addFileAttachment(String description, byte[] fileStore, String file, String fileDisplay) throws IOException { | |
1586 |
1
1. addFileAttachment : removed call to com/lowagie/text/pdf/PdfWriter::addFileAttachment → NO_COVERAGE |
addFileAttachment(description, PdfFileSpecification.fileEmbedded(this, file, fileDisplay, fileStore)); |
1587 | } | |
1588 | ||
1589 | /** | |
1590 | * Use this method to add a file attachment at the document level. | |
1591 | * @param description the file description | |
1592 | * @param fs the file specification | |
1593 | */ | |
1594 | public void addFileAttachment(String description, PdfFileSpecification fs) throws IOException { | |
1595 | pdf.addFileAttachment(description, fs); | |
1596 | } | |
1597 | ||
1598 | /** | |
1599 | * Use this method to add a file attachment at the document level. | |
1600 | * @param fs the file specification | |
1601 | */ | |
1602 | public void addFileAttachment(PdfFileSpecification fs) throws IOException { | |
1603 |
1
1. addFileAttachment : removed call to com/lowagie/text/pdf/PdfWriter::addFileAttachment → NO_COVERAGE |
addFileAttachment(null, fs); |
1604 | } | |
1605 | ||
1606 | // [C6] Actions (open and additional) | |
1607 | ||
1608 | /** action value */ | |
1609 | public static final PdfName DOCUMENT_CLOSE = PdfName.WC; | |
1610 | /** action value */ | |
1611 | public static final PdfName WILL_SAVE = PdfName.WS; | |
1612 | /** action value */ | |
1613 | public static final PdfName DID_SAVE = PdfName.DS; | |
1614 | /** action value */ | |
1615 | public static final PdfName WILL_PRINT = PdfName.WP; | |
1616 | /** action value */ | |
1617 | public static final PdfName DID_PRINT = PdfName.DP; | |
1618 | ||
1619 | /** @see com.lowagie.text.pdf.interfaces.PdfDocumentActions#setOpenAction(java.lang.String) */ | |
1620 | public void setOpenAction(String name) { | |
1621 | pdf.setOpenAction(name); | |
1622 | } | |
1623 | ||
1624 | /** @see com.lowagie.text.pdf.interfaces.PdfDocumentActions#setOpenAction(com.lowagie.text.pdf.PdfAction) */ | |
1625 | public void setOpenAction(PdfAction action) { | |
1626 | pdf.setOpenAction(action); | |
1627 | } | |
1628 | ||
1629 | /** @see com.lowagie.text.pdf.interfaces.PdfDocumentActions#setAdditionalAction(com.lowagie.text.pdf.PdfName, com.lowagie.text.pdf.PdfAction) */ | |
1630 | public void setAdditionalAction(PdfName actionType, PdfAction action) throws DocumentException { | |
1631 |
1
1. setAdditionalAction : negated conditional → NO_COVERAGE |
if (!(actionType.equals(DOCUMENT_CLOSE) || |
1632 |
1
1. setAdditionalAction : negated conditional → NO_COVERAGE |
actionType.equals(WILL_SAVE) || |
1633 |
1
1. setAdditionalAction : negated conditional → NO_COVERAGE |
actionType.equals(DID_SAVE) || |
1634 |
1
1. setAdditionalAction : negated conditional → NO_COVERAGE |
actionType.equals(WILL_PRINT) || |
1635 |
1
1. setAdditionalAction : negated conditional → NO_COVERAGE |
actionType.equals(DID_PRINT))) { |
1636 | throw new DocumentException(MessageLocalization.getComposedMessage("invalid.additional.action.type.1", actionType.toString())); | |
1637 | } | |
1638 |
1
1. setAdditionalAction : removed call to com/lowagie/text/pdf/PdfDocument::addAdditionalAction → NO_COVERAGE |
pdf.addAdditionalAction(actionType, action); |
1639 | } | |
1640 | ||
1641 | // [C7] portable collections | |
1642 | ||
1643 | /** | |
1644 | * Use this method to add the Collection dictionary. | |
1645 | * @param collection a dictionary of type PdfCollection | |
1646 | */ | |
1647 | public void setCollection(PdfCollection collection) { | |
1648 |
1
1. setCollection : removed call to com/lowagie/text/pdf/PdfWriter::setAtLeastPdfVersion → NO_COVERAGE |
setAtLeastPdfVersion(VERSION_1_7); |
1649 |
1
1. setCollection : removed call to com/lowagie/text/pdf/PdfDocument::setCollection → NO_COVERAGE |
pdf.setCollection(collection); |
1650 | } | |
1651 | ||
1652 | // [C8] AcroForm | |
1653 | ||
1654 | /** signature value */ | |
1655 | public static final int SIGNATURE_EXISTS = 1; | |
1656 | /** signature value */ | |
1657 | public static final int SIGNATURE_APPEND_ONLY = 2; | |
1658 | ||
1659 | /** @see com.lowagie.text.pdf.interfaces.PdfAnnotations#getAcroForm() */ | |
1660 | public PdfAcroForm getAcroForm() { | |
1661 | return pdf.getAcroForm(); | |
1662 | } | |
1663 | ||
1664 | /** @see com.lowagie.text.pdf.interfaces.PdfAnnotations#addAnnotation(com.lowagie.text.pdf.PdfAnnotation) */ | |
1665 | public void addAnnotation(PdfAnnotation annot) { | |
1666 | pdf.addAnnotation(annot); | |
1667 | } | |
1668 | ||
1669 | void addAnnotation(PdfAnnotation annot, int page) { | |
1670 | addAnnotation(annot); | |
1671 | } | |
1672 | ||
1673 | /** @see com.lowagie.text.pdf.interfaces.PdfAnnotations#addCalculationOrder(com.lowagie.text.pdf.PdfFormField) */ | |
1674 | public void addCalculationOrder(PdfFormField annot) { | |
1675 | pdf.addCalculationOrder(annot); | |
1676 | } | |
1677 | ||
1678 | /** @see com.lowagie.text.pdf.interfaces.PdfAnnotations#setSigFlags(int) */ | |
1679 | public void setSigFlags(int f) { | |
1680 | pdf.setSigFlags(f); | |
1681 | } | |
1682 | ||
1683 | // [C9] Metadata | |
1684 | ||
1685 | /** XMP Metadata for the document. */ | |
1686 | protected byte[] xmpMetadata = null; | |
1687 | ||
1688 | /** | |
1689 | * Use this method to set the XMP Metadata. | |
1690 | * @param xmpMetadata The xmpMetadata to set. | |
1691 | */ | |
1692 | public void setXmpMetadata(byte[] xmpMetadata) { | |
1693 | this.xmpMetadata = xmpMetadata; | |
1694 | } | |
1695 | ||
1696 | /** | |
1697 | * Use this method to set the XMP Metadata for each page. | |
1698 | * @param xmpMetadata The xmpMetadata to set. | |
1699 | */ | |
1700 | public void setPageXmpMetadata(byte[] xmpMetadata) { | |
1701 | pdf.setXmpMetadata(xmpMetadata); | |
1702 | } | |
1703 | ||
1704 | /** | |
1705 | * Use this method to creates XMP Metadata based | |
1706 | * on the metadata in the PdfDocument. | |
1707 | */ | |
1708 | public void createXmpMetadata() { | |
1709 |
1
1. createXmpMetadata : removed call to com/lowagie/text/pdf/PdfWriter::setXmpMetadata → NO_COVERAGE |
setXmpMetadata(createXmpMetadataBytes()); |
1710 | } | |
1711 | ||
1712 | /** | |
1713 | * @return an XmpMetadata byte array | |
1714 | */ | |
1715 | private byte[] createXmpMetadataBytes() { | |
1716 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |
1717 | try { | |
1718 | XmpWriter xmp = new XmpWriter(baos, pdf.getInfo(), pdfxConformance.getPDFXConformance()); | |
1719 |
1
1. createXmpMetadataBytes : removed call to com/lowagie/text/xml/xmp/XmpWriter::close → NO_COVERAGE |
xmp.close(); |
1720 | } | |
1721 | catch (IOException ioe) { | |
1722 |
1
1. createXmpMetadataBytes : removed call to java/io/IOException::printStackTrace → NO_COVERAGE |
ioe.printStackTrace(); |
1723 | } | |
1724 |
1
1. createXmpMetadataBytes : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::createXmpMetadataBytes to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return baos.toByteArray(); |
1725 | } | |
1726 | ||
1727 | // [C10] PDFX Conformance | |
1728 | /** A PDF/X level. */ | |
1729 | public static final int PDFXNONE = 0; | |
1730 | /** A PDF/X level. */ | |
1731 | public static final int PDFX1A2001 = 1; | |
1732 | /** A PDF/X level. */ | |
1733 | public static final int PDFX32002 = 2; | |
1734 | /** PDFA-1A level. */ | |
1735 | public static final int PDFA1A = 3; | |
1736 | /** PDFA-1B level. */ | |
1737 | public static final int PDFA1B = 4; | |
1738 | ||
1739 | /** Stores the PDF/X level. */ | |
1740 | private PdfXConformanceImp pdfxConformance = new PdfXConformanceImp(); | |
1741 | ||
1742 | /** @see com.lowagie.text.pdf.interfaces.PdfXConformance#setPDFXConformance(int) */ | |
1743 | public void setPDFXConformance(int pdfx) { | |
1744 |
1
1. setPDFXConformance : negated conditional → NO_COVERAGE |
if (pdfxConformance.getPDFXConformance() == pdfx) |
1745 | return; | |
1746 |
1
1. setPDFXConformance : negated conditional → NO_COVERAGE |
if (pdf.isOpen()) |
1747 | throw new PdfXConformanceException(MessageLocalization.getComposedMessage("pdfx.conformance.can.only.be.set.before.opening.the.document")); | |
1748 |
1
1. setPDFXConformance : negated conditional → NO_COVERAGE |
if (crypto != null) |
1749 | throw new PdfXConformanceException(MessageLocalization.getComposedMessage("a.pdfx.conforming.document.cannot.be.encrypted")); | |
1750 |
2
1. setPDFXConformance : negated conditional → NO_COVERAGE 2. setPDFXConformance : negated conditional → NO_COVERAGE |
if (pdfx == PDFA1A || pdfx == PDFA1B) |
1751 |
1
1. setPDFXConformance : removed call to com/lowagie/text/pdf/PdfWriter::setPdfVersion → NO_COVERAGE |
setPdfVersion(VERSION_1_4); |
1752 |
1
1. setPDFXConformance : negated conditional → NO_COVERAGE |
else if (pdfx != PDFXNONE) |
1753 |
1
1. setPDFXConformance : removed call to com/lowagie/text/pdf/PdfWriter::setPdfVersion → NO_COVERAGE |
setPdfVersion(VERSION_1_3); |
1754 |
1
1. setPDFXConformance : removed call to com/lowagie/text/pdf/internal/PdfXConformanceImp::setPDFXConformance → NO_COVERAGE |
pdfxConformance.setPDFXConformance(pdfx); |
1755 | } | |
1756 | ||
1757 | /** @see com.lowagie.text.pdf.interfaces.PdfXConformance#getPDFXConformance() */ | |
1758 | public int getPDFXConformance() { | |
1759 | return pdfxConformance.getPDFXConformance(); | |
1760 | } | |
1761 | ||
1762 | /** @see com.lowagie.text.pdf.interfaces.PdfXConformance#isPdfX() */ | |
1763 | public boolean isPdfX() { | |
1764 | return pdfxConformance.isPdfX(); | |
1765 | } | |
1766 | ||
1767 | // [C11] Output intents | |
1768 | /** | |
1769 | * Sets the values of the output intent dictionary. Null values are allowed to | |
1770 | * suppress any key. | |
1771 | * | |
1772 | * @param outputConditionIdentifier a value | |
1773 | * @param outputCondition a value, "PDFA/A" to force GTS_PDFA1, otherwise cued by pdfxConformance. | |
1774 | * @param registryName a value | |
1775 | * @param info a value | |
1776 | * @param colorProfile a value | |
1777 | * @since 2.1.5 | |
1778 | * @throws IOException on error | |
1779 | */ | |
1780 | public void setOutputIntents(String outputConditionIdentifier, String outputCondition, String registryName, String info, ICC_Profile colorProfile) throws IOException { | |
1781 | getExtraCatalog(); | |
1782 | PdfDictionary out = new PdfDictionary(PdfName.OUTPUTINTENT); | |
1783 |
1
1. setOutputIntents : negated conditional → NO_COVERAGE |
if (outputCondition != null) |
1784 |
1
1. setOutputIntents : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
out.put(PdfName.OUTPUTCONDITION, new PdfString(outputCondition, PdfObject.TEXT_UNICODE)); |
1785 |
1
1. setOutputIntents : negated conditional → NO_COVERAGE |
if (outputConditionIdentifier != null) |
1786 |
1
1. setOutputIntents : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
out.put(PdfName.OUTPUTCONDITIONIDENTIFIER, new PdfString(outputConditionIdentifier, PdfObject.TEXT_UNICODE)); |
1787 |
1
1. setOutputIntents : negated conditional → NO_COVERAGE |
if (registryName != null) |
1788 |
1
1. setOutputIntents : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
out.put(PdfName.REGISTRYNAME, new PdfString(registryName, PdfObject.TEXT_UNICODE)); |
1789 |
1
1. setOutputIntents : negated conditional → NO_COVERAGE |
if (info != null) |
1790 |
1
1. setOutputIntents : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
out.put(PdfName.INFO, new PdfString(info, PdfObject.TEXT_UNICODE)); |
1791 |
1
1. setOutputIntents : negated conditional → NO_COVERAGE |
if (colorProfile != null) { |
1792 | PdfStream stream = new PdfICCBased(colorProfile, compressionLevel); | |
1793 |
1
1. setOutputIntents : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
out.put(PdfName.DESTOUTPUTPROFILE, addToBody(stream).getIndirectReference()); |
1794 | } | |
1795 | ||
1796 | PdfName intentSubtype; | |
1797 |
2
1. setOutputIntents : negated conditional → NO_COVERAGE 2. setOutputIntents : negated conditional → NO_COVERAGE |
if (pdfxConformance.isPdfA1() || "PDFA/1".equals(outputCondition)) { |
1798 | intentSubtype = PdfName.GTS_PDFA1; | |
1799 | } | |
1800 | else { | |
1801 | intentSubtype = PdfName.GTS_PDFX; | |
1802 | } | |
1803 | ||
1804 |
1
1. setOutputIntents : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
out.put(PdfName.S, intentSubtype); |
1805 | ||
1806 |
1
1. setOutputIntents : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
extraCatalog.put(PdfName.OUTPUTINTENTS, new PdfArray(out)); |
1807 | } | |
1808 | ||
1809 | /** | |
1810 | * Sets the values of the output intent dictionary. Null values are allowed to | |
1811 | * suppress any key. | |
1812 | * | |
1813 | * Prefer the <CODE>ICC_Profile</CODE>-based version of this method. | |
1814 | * @param outputConditionIdentifier a value | |
1815 | * @param outputCondition a value, "PDFA/A" to force GTS_PDFA1, otherwise cued by pdfxConformance. | |
1816 | * @param registryName a value | |
1817 | * @param info a value | |
1818 | * @param destOutputProfile a value | |
1819 | * @since 1.x | |
1820 | * | |
1821 | * @throws IOException | |
1822 | */ | |
1823 | public void setOutputIntents(String outputConditionIdentifier, String outputCondition, String registryName, String info, byte[] destOutputProfile) throws IOException { | |
1824 |
1
1. setOutputIntents : negated conditional → NO_COVERAGE |
ICC_Profile colorProfile = (destOutputProfile == null) ? null : ICC_Profile.getInstance(destOutputProfile); |
1825 |
1
1. setOutputIntents : removed call to com/lowagie/text/pdf/PdfWriter::setOutputIntents → NO_COVERAGE |
setOutputIntents(outputConditionIdentifier, outputCondition, registryName, info, colorProfile); |
1826 | } | |
1827 | ||
1828 | ||
1829 | /** | |
1830 | * Use this method to copy the output intent dictionary | |
1831 | * from another document to this one. | |
1832 | * @param reader the other document | |
1833 | * @param checkExistence <CODE>true</CODE> to just check for the existence of a valid output intent | |
1834 | * dictionary, <CODE>false</CODE> to insert the dictionary if it exists | |
1835 | * @throws IOException on error | |
1836 | * @return <CODE>true</CODE> if the output intent dictionary exists, <CODE>false</CODE> | |
1837 | * otherwise | |
1838 | */ | |
1839 | public boolean setOutputIntents(PdfReader reader, boolean checkExistence) throws IOException { | |
1840 | PdfDictionary catalog = reader.getCatalog(); | |
1841 | PdfArray outs = catalog.getAsArray(PdfName.OUTPUTINTENTS); | |
1842 |
1
1. setOutputIntents : negated conditional → NO_COVERAGE |
if (outs == null) |
1843 |
1
1. setOutputIntents : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return false; |
1844 |
1
1. setOutputIntents : negated conditional → NO_COVERAGE |
if (outs.isEmpty()) |
1845 |
1
1. setOutputIntents : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return false; |
1846 | PdfDictionary out = outs.getAsDict(0); | |
1847 | PdfObject obj = PdfReader.getPdfObject(out.get(PdfName.S)); | |
1848 |
1
1. setOutputIntents : negated conditional → NO_COVERAGE |
if (!PdfName.GTS_PDFX.equals(obj)) |
1849 |
1
1. setOutputIntents : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return false; |
1850 |
1
1. setOutputIntents : negated conditional → NO_COVERAGE |
if (checkExistence) |
1851 |
1
1. setOutputIntents : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return true; |
1852 | PRStream stream = (PRStream)PdfReader.getPdfObject(out.get(PdfName.DESTOUTPUTPROFILE)); | |
1853 | byte[] destProfile = null; | |
1854 |
1
1. setOutputIntents : negated conditional → NO_COVERAGE |
if (stream != null) { |
1855 | destProfile = PdfReader.getStreamBytes(stream); | |
1856 | } | |
1857 |
1
1. setOutputIntents : removed call to com/lowagie/text/pdf/PdfWriter::setOutputIntents → NO_COVERAGE |
setOutputIntents(getNameString(out, PdfName.OUTPUTCONDITIONIDENTIFIER), getNameString(out, PdfName.OUTPUTCONDITION), |
1858 | getNameString(out, PdfName.REGISTRYNAME), getNameString(out, PdfName.INFO), destProfile); | |
1859 |
1
1. setOutputIntents : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return true; |
1860 | } | |
1861 | ||
1862 | private static String getNameString(PdfDictionary dic, PdfName key) { | |
1863 | PdfObject obj = PdfReader.getPdfObject(dic.get(key)); | |
1864 |
2
1. getNameString : negated conditional → NO_COVERAGE 2. getNameString : negated conditional → NO_COVERAGE |
if (obj == null || !obj.isString()) |
1865 |
1
1. getNameString : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::getNameString to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return null; |
1866 |
1
1. getNameString : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::getNameString to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return ((PdfString)obj).toUnicodeString(); |
1867 | } | |
1868 | ||
1869 | // PDF Objects that have an impact on the PDF body | |
1870 | ||
1871 | // [F1] PdfEncryptionSettings interface | |
1872 | ||
1873 | // types of encryption | |
1874 | ||
1875 | /** Type of encryption */ | |
1876 | public static final int STANDARD_ENCRYPTION_40 = 0; | |
1877 | /** Type of encryption */ | |
1878 | public static final int STANDARD_ENCRYPTION_128 = 1; | |
1879 | /** Type of encryption */ | |
1880 | public static final int ENCRYPTION_AES_128 = 2; | |
1881 | /** Mask to separate the encryption type from the encryption mode. */ | |
1882 | static final int ENCRYPTION_MASK = 7; | |
1883 | /** Add this to the mode to keep the metadata in clear text */ | |
1884 | public static final int DO_NOT_ENCRYPT_METADATA = 8; | |
1885 | /** | |
1886 | * Add this to the mode to keep encrypt only the embedded files. | |
1887 | * @since 2.1.3 | |
1888 | */ | |
1889 | public static final int EMBEDDED_FILES_ONLY = 24; | |
1890 | ||
1891 | // permissions | |
1892 | ||
1893 | /** The operation permitted when the document is opened with the user password | |
1894 | * | |
1895 | * @since 2.0.7 | |
1896 | */ | |
1897 | public static final int ALLOW_PRINTING = 4 + 2048; | |
1898 | ||
1899 | /** The operation permitted when the document is opened with the user password | |
1900 | * | |
1901 | * @since 2.0.7 | |
1902 | */ | |
1903 | public static final int ALLOW_MODIFY_CONTENTS = 8; | |
1904 | ||
1905 | /** The operation permitted when the document is opened with the user password | |
1906 | * | |
1907 | * @since 2.0.7 | |
1908 | */ | |
1909 | public static final int ALLOW_COPY = 16; | |
1910 | ||
1911 | /** The operation permitted when the document is opened with the user password | |
1912 | * | |
1913 | * @since 2.0.7 | |
1914 | */ | |
1915 | public static final int ALLOW_MODIFY_ANNOTATIONS = 32; | |
1916 | ||
1917 | /** The operation permitted when the document is opened with the user password | |
1918 | * | |
1919 | * @since 2.0.7 | |
1920 | */ | |
1921 | public static final int ALLOW_FILL_IN = 256; | |
1922 | ||
1923 | /** The operation permitted when the document is opened with the user password | |
1924 | * | |
1925 | * @since 2.0.7 | |
1926 | */ | |
1927 | public static final int ALLOW_SCREENREADERS = 512; | |
1928 | ||
1929 | /** The operation permitted when the document is opened with the user password | |
1930 | * | |
1931 | * @since 2.0.7 | |
1932 | */ | |
1933 | public static final int ALLOW_ASSEMBLY = 1024; | |
1934 | ||
1935 | /** The operation permitted when the document is opened with the user password | |
1936 | * | |
1937 | * @since 2.0.7 | |
1938 | */ | |
1939 | public static final int ALLOW_DEGRADED_PRINTING = 4; | |
1940 | ||
1941 | /** @deprecated As of iText 2.0.7, use {@link #ALLOW_PRINTING} instead. Scheduled for removal at or after 2.2.0 */ | |
1942 | public static final int AllowPrinting = ALLOW_PRINTING; | |
1943 | /** @deprecated As of iText 2.0.7, use {@link #ALLOW_MODIFY_CONTENTS} instead. Scheduled for removal at or after 2.2.0 */ | |
1944 | public static final int AllowModifyContents = ALLOW_MODIFY_CONTENTS; | |
1945 | /** @deprecated As of iText 2.0.7, use {@link #ALLOW_COPY} instead. Scheduled for removal at or after 2.2.0 */ | |
1946 | public static final int AllowCopy = ALLOW_COPY; | |
1947 | /** @deprecated As of iText 2.0.7, use {@link #ALLOW_MODIFY_ANNOTATIONS} instead. Scheduled for removal at or after 2.2.0 */ | |
1948 | public static final int AllowModifyAnnotations = ALLOW_MODIFY_ANNOTATIONS; | |
1949 | /** @deprecated As of iText 2.0.7, use {@link #ALLOW_FILL_IN} instead. Scheduled for removal at or after 2.2.0 */ | |
1950 | public static final int AllowFillIn = ALLOW_FILL_IN; | |
1951 | /** @deprecated As of iText 2.0.7, use {@link #ALLOW_SCREENREADERS} instead. Scheduled for removal at or after 2.2.0 */ | |
1952 | public static final int AllowScreenReaders = ALLOW_SCREENREADERS; | |
1953 | /** @deprecated As of iText 2.0.7, use {@link #ALLOW_ASSEMBLY} instead. Scheduled for removal at or after 2.2.0 */ | |
1954 | public static final int AllowAssembly = ALLOW_ASSEMBLY; | |
1955 | /** @deprecated As of iText 2.0.7, use {@link #ALLOW_DEGRADED_PRINTING} instead. Scheduled for removal at or after 2.2.0 */ | |
1956 | public static final int AllowDegradedPrinting = ALLOW_DEGRADED_PRINTING; | |
1957 | ||
1958 | // Strength of the encryption (kept for historical reasons) | |
1959 | /** @deprecated As of iText 2.0.7, use {@link #STANDARD_ENCRYPTION_40} instead. Scheduled for removal at or after 2.2.0 */ | |
1960 | public static final boolean STRENGTH40BITS = false; | |
1961 | /** @deprecated As of iText 2.0.7, use {@link #STANDARD_ENCRYPTION_128} instead. Scheduled for removal at or after 2.2.0 */ | |
1962 | public static final boolean STRENGTH128BITS = true; | |
1963 | ||
1964 | /** Contains the business logic for cryptography. */ | |
1965 | protected PdfEncryption crypto; | |
1966 | PdfEncryption getEncryption() { | |
1967 | return crypto; | |
1968 | } | |
1969 | ||
1970 | /** @see com.lowagie.text.pdf.interfaces.PdfEncryptionSettings#setEncryption(byte[], byte[], int, int) */ | |
1971 | public void setEncryption(byte[] userPassword, byte[] ownerPassword, int permissions, int encryptionType) throws DocumentException { | |
1972 |
1
1. setEncryption : negated conditional → NO_COVERAGE |
if (pdf.isOpen()) |
1973 | throw new DocumentException(MessageLocalization.getComposedMessage("encryption.can.only.be.added.before.opening.the.document")); | |
1974 | crypto = new PdfEncryption(); | |
1975 |
1
1. setEncryption : removed call to com/lowagie/text/pdf/PdfEncryption::setCryptoMode → NO_COVERAGE |
crypto.setCryptoMode(encryptionType, 0); |
1976 |
1
1. setEncryption : removed call to com/lowagie/text/pdf/PdfEncryption::setupAllKeys → NO_COVERAGE |
crypto.setupAllKeys(userPassword, ownerPassword, permissions); |
1977 | } | |
1978 | ||
1979 | /** @see com.lowagie.text.pdf.interfaces.PdfEncryptionSettings#setEncryption(java.security.cert.Certificate[], int[], int) */ | |
1980 | public void setEncryption(Certificate[] certs, int[] permissions, int encryptionType) throws DocumentException { | |
1981 |
1
1. setEncryption : negated conditional → NO_COVERAGE |
if (pdf.isOpen()) |
1982 | throw new DocumentException(MessageLocalization.getComposedMessage("encryption.can.only.be.added.before.opening.the.document")); | |
1983 | crypto = new PdfEncryption(); | |
1984 |
1
1. setEncryption : negated conditional → NO_COVERAGE |
if (certs != null) { |
1985 |
2
1. setEncryption : changed conditional boundary → NO_COVERAGE 2. setEncryption : negated conditional → NO_COVERAGE |
for (int i=0; i < certs.length; i++) { |
1986 |
1
1. setEncryption : removed call to com/lowagie/text/pdf/PdfEncryption::addRecipient → NO_COVERAGE |
crypto.addRecipient(certs[i], permissions[i]); |
1987 | } | |
1988 | } | |
1989 |
1
1. setEncryption : removed call to com/lowagie/text/pdf/PdfEncryption::setCryptoMode → NO_COVERAGE |
crypto.setCryptoMode(encryptionType, 0); |
1990 | crypto.getEncryptionDictionary(); | |
1991 | } | |
1992 | ||
1993 | /** | |
1994 | * Sets the encryption options for this document. The userPassword and the | |
1995 | * ownerPassword can be null or have zero length. In this case the ownerPassword | |
1996 | * is replaced by a random string. The open permissions for the document can be | |
1997 | * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, | |
1998 | * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. | |
1999 | * The permissions can be combined by ORing them. | |
2000 | * @param userPassword the user password. Can be null or empty | |
2001 | * @param ownerPassword the owner password. Can be null or empty | |
2002 | * @param permissions the user permissions | |
2003 | * @param strength128Bits <code>true</code> for 128 bit key length, <code>false</code> for 40 bit key length | |
2004 | * @throws DocumentException if the document is already open | |
2005 | * @deprecated As of iText 2.0.3, replaced by (@link #setEncryption(byte[], byte[], int, int)}. Scheduled for removal at or after 2.2.0 | |
2006 | */ | |
2007 | public void setEncryption(byte[] userPassword, byte[] ownerPassword, int permissions, boolean strength128Bits) throws DocumentException { | |
2008 | setEncryption(userPassword, ownerPassword, permissions, strength128Bits ? STANDARD_ENCRYPTION_128 : STANDARD_ENCRYPTION_40); | |
2009 | } | |
2010 | ||
2011 | /** | |
2012 | * Sets the encryption options for this document. The userPassword and the | |
2013 | * ownerPassword can be null or have zero length. In this case the ownerPassword | |
2014 | * is replaced by a random string. The open permissions for the document can be | |
2015 | * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, | |
2016 | * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. | |
2017 | * The permissions can be combined by ORing them. | |
2018 | * @param strength <code>true</code> for 128 bit key length, <code>false</code> for 40 bit key length | |
2019 | * @param userPassword the user password. Can be null or empty | |
2020 | * @param ownerPassword the owner password. Can be null or empty | |
2021 | * @param permissions the user permissions | |
2022 | * @throws DocumentException if the document is already open | |
2023 | * @deprecated As of iText 2.0.3, replaced by (@link #setEncryption(byte[], byte[], int, int)}. Scheduled for removal at or after 2.2.0 | |
2024 | */ | |
2025 | public void setEncryption(boolean strength, String userPassword, String ownerPassword, int permissions) throws DocumentException { | |
2026 | setEncryption(getISOBytes(userPassword), getISOBytes(ownerPassword), permissions, strength ? STANDARD_ENCRYPTION_128 : STANDARD_ENCRYPTION_40); | |
2027 | } | |
2028 | ||
2029 | /** | |
2030 | * Sets the encryption options for this document. The userPassword and the | |
2031 | * ownerPassword can be null or have zero length. In this case the ownerPassword | |
2032 | * is replaced by a random string. The open permissions for the document can be | |
2033 | * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, | |
2034 | * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. | |
2035 | * The permissions can be combined by ORing them. | |
2036 | * @param encryptionType the type of encryption. It can be one of STANDARD_ENCRYPTION_40, STANDARD_ENCRYPTION_128 or ENCRYPTION_AES128. | |
2037 | * Optionally DO_NOT_ENCRYPT_METADATA can be ored to output the metadata in cleartext | |
2038 | * @param userPassword the user password. Can be null or empty | |
2039 | * @param ownerPassword the owner password. Can be null or empty | |
2040 | * @param permissions the user permissions | |
2041 | * @throws DocumentException if the document is already open | |
2042 | * @deprecated As of iText 2.0.3, replaced by (@link #setEncryption(byte[], byte[], int, int)}. Scheduled for removal at or after 2.2.0 | |
2043 | */ | |
2044 | public void setEncryption(int encryptionType, String userPassword, String ownerPassword, int permissions) throws DocumentException { | |
2045 | setEncryption(getISOBytes(userPassword), getISOBytes(ownerPassword), permissions, encryptionType); | |
2046 | } | |
2047 | ||
2048 | // [F2] compression | |
2049 | ||
2050 | /** Holds value of property fullCompression. */ | |
2051 | protected boolean fullCompression = false; | |
2052 | ||
2053 | /** | |
2054 | * Use this method to find out if 1.5 compression is on. | |
2055 | * @return the 1.5 compression status | |
2056 | */ | |
2057 | public boolean isFullCompression() { | |
2058 | return this.fullCompression; | |
2059 | } | |
2060 | ||
2061 | /** | |
2062 | * Use this method to set the document's compression to the | |
2063 | * PDF 1.5 mode with object streams and xref streams. | |
2064 | * It can be set at any time but once set it can't be unset. | |
2065 | * <p> | |
2066 | * If set before opening the document it will also set the pdf version to 1.5. | |
2067 | */ | |
2068 | public void setFullCompression() { | |
2069 | this.fullCompression = true; | |
2070 |
1
1. setFullCompression : removed call to com/lowagie/text/pdf/PdfWriter::setAtLeastPdfVersion → NO_COVERAGE |
setAtLeastPdfVersion(VERSION_1_5); |
2071 | } | |
2072 | ||
2073 | /** | |
2074 | * The compression level of the content streams. | |
2075 | * @since 2.1.3 | |
2076 | */ | |
2077 | protected int compressionLevel = PdfStream.DEFAULT_COMPRESSION; | |
2078 | ||
2079 | /** | |
2080 | * Returns the compression level used for streams written by this writer. | |
2081 | * @return the compression level (0 = best speed, 9 = best compression, -1 is default) | |
2082 | * @since 2.1.3 | |
2083 | */ | |
2084 | public int getCompressionLevel() { | |
2085 | return compressionLevel; | |
2086 | } | |
2087 | ||
2088 | /** | |
2089 | * Sets the compression level to be used for streams written by this writer. | |
2090 | * @param compressionLevel a value between 0 (best speed) and 9 (best compression) | |
2091 | * @since 2.1.3 | |
2092 | */ | |
2093 | public void setCompressionLevel(int compressionLevel) { | |
2094 |
4
1. setCompressionLevel : changed conditional boundary → NO_COVERAGE 2. setCompressionLevel : changed conditional boundary → NO_COVERAGE 3. setCompressionLevel : negated conditional → NO_COVERAGE 4. setCompressionLevel : negated conditional → NO_COVERAGE |
if (compressionLevel < PdfStream.NO_COMPRESSION || compressionLevel > PdfStream.BEST_COMPRESSION) |
2095 | this.compressionLevel = PdfStream.DEFAULT_COMPRESSION; | |
2096 | else | |
2097 | this.compressionLevel = compressionLevel; | |
2098 | } | |
2099 | ||
2100 | // [F3] adding fonts | |
2101 | ||
2102 | /** The fonts of this document */ | |
2103 | protected LinkedHashMap<BaseFont, FontDetails> documentFonts = new LinkedHashMap<>(); | |
2104 | ||
2105 | /** The font number counter for the fonts in the document. */ | |
2106 | protected int fontNumber = 1; | |
2107 | ||
2108 | /** | |
2109 | * Adds a <CODE>BaseFont</CODE> to the document but not to the page resources. | |
2110 | * It is used for templates. | |
2111 | * @param bf the <CODE>BaseFont</CODE> to add | |
2112 | * @return an <CODE>Object[]</CODE> where position 0 is a <CODE>PdfName</CODE> | |
2113 | * and position 1 is an <CODE>PdfIndirectReference</CODE> | |
2114 | */ | |
2115 | ||
2116 | FontDetails addSimple(BaseFont bf) { | |
2117 |
1
1. addSimple : negated conditional → NO_COVERAGE |
if (bf.getFontType() == BaseFont.FONT_TYPE_DOCUMENT) { |
2118 |
2
1. addSimple : Replaced integer addition with subtraction → NO_COVERAGE 2. addSimple : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::addSimple to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return new FontDetails(new PdfName("F" + (fontNumber++)), ((DocumentFont)bf).getIndirectReference(), bf); |
2119 | } | |
2120 | FontDetails ret = documentFonts.get(bf); | |
2121 |
1
1. addSimple : negated conditional → NO_COVERAGE |
if (ret == null) { |
2122 |
1
1. addSimple : removed call to com/lowagie/text/pdf/internal/PdfXConformanceImp::checkPDFXConformance → NO_COVERAGE |
PdfXConformanceImp.checkPDFXConformance(this, PdfXConformanceImp.PDFXKEY_FONT, bf); |
2123 |
1
1. addSimple : Replaced integer addition with subtraction → NO_COVERAGE |
ret = new FontDetails(new PdfName("F" + (fontNumber++)), body.getPdfIndirectReference(), bf); |
2124 | documentFonts.put(bf, ret); | |
2125 | } | |
2126 |
1
1. addSimple : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::addSimple to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return ret; |
2127 | } | |
2128 | ||
2129 | void eliminateFontSubset(PdfDictionary fonts) { | |
2130 | for (FontDetails ft : documentFonts.values()) { | |
2131 |
1
1. eliminateFontSubset : negated conditional → NO_COVERAGE |
if (fonts.get(ft.getFontName()) != null) |
2132 |
1
1. eliminateFontSubset : removed call to com/lowagie/text/pdf/FontDetails::setSubset → NO_COVERAGE |
ft.setSubset(false); |
2133 | } | |
2134 | } | |
2135 | ||
2136 | // [F4] adding (and releasing) form XObjects | |
2137 | ||
2138 | /** The form XObjects in this document. The key is the xref and the value | |
2139 | is Object[]{PdfName, template}.*/ | |
2140 | protected LinkedHashMap<PdfIndirectReference, Object[]> formXObjects = new LinkedHashMap<>(); | |
2141 | ||
2142 | /** The name counter for the form XObjects name. */ | |
2143 | protected int formXObjectsCounter = 1; | |
2144 | ||
2145 | /** | |
2146 | * Adds a template to the document but not to the page resources. | |
2147 | * @param template the template to add | |
2148 | * @param forcedName the template name, rather than a generated one. Can be null | |
2149 | * @return the <CODE>PdfName</CODE> for this template | |
2150 | */ | |
2151 | ||
2152 | PdfName addDirectTemplateSimple(PdfTemplate template, PdfName forcedName) { | |
2153 | PdfIndirectReference ref = template.getIndirectReference(); | |
2154 | Object[] obj = formXObjects.get(ref); | |
2155 | PdfName name = null; | |
2156 | try { | |
2157 |
1
1. addDirectTemplateSimple : negated conditional → NO_COVERAGE |
if (obj == null) { |
2158 |
1
1. addDirectTemplateSimple : negated conditional → NO_COVERAGE |
if (forcedName == null) { |
2159 | name = new PdfName("Xf" + formXObjectsCounter); | |
2160 |
1
1. addDirectTemplateSimple : Replaced integer addition with subtraction → NO_COVERAGE |
++formXObjectsCounter; |
2161 | } | |
2162 | else | |
2163 | name = forcedName; | |
2164 |
1
1. addDirectTemplateSimple : negated conditional → NO_COVERAGE |
if (template.getType() == PdfTemplate.TYPE_IMPORTED) { |
2165 | // If we got here from PdfCopy we'll have to fill importedPages | |
2166 | PdfImportedPage ip = (PdfImportedPage)template; | |
2167 | PdfReader r = ip.getPdfReaderInstance().getReader(); | |
2168 |
1
1. addDirectTemplateSimple : negated conditional → NO_COVERAGE |
if (!importedPages.containsKey(r)) { |
2169 | importedPages.put(r, ip.getPdfReaderInstance()); | |
2170 | } | |
2171 | template = null; | |
2172 | } | |
2173 | formXObjects.put(ref, new Object[]{name, template}); | |
2174 | } | |
2175 | else | |
2176 | name = (PdfName)obj[0]; | |
2177 | } | |
2178 | catch (Exception e) { | |
2179 | throw new ExceptionConverter(e); | |
2180 | } | |
2181 |
1
1. addDirectTemplateSimple : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::addDirectTemplateSimple to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return name; |
2182 | } | |
2183 | ||
2184 | /** | |
2185 | * Use this method to releases the memory used by a template. | |
2186 | * This method writes the template to the output. | |
2187 | * The template can still be added to any content | |
2188 | * but changes to the template itself won't have any effect. | |
2189 | * @param tp the template to release | |
2190 | * @throws IOException on error | |
2191 | */ | |
2192 | public void releaseTemplate(PdfTemplate tp) throws IOException { | |
2193 | PdfIndirectReference ref = tp.getIndirectReference(); | |
2194 | Object[] objs = formXObjects.get(ref); | |
2195 |
2
1. releaseTemplate : negated conditional → NO_COVERAGE 2. releaseTemplate : negated conditional → NO_COVERAGE |
if (objs == null || objs[1] == null) |
2196 | return; | |
2197 | PdfTemplate template = (PdfTemplate)objs[1]; | |
2198 |
1
1. releaseTemplate : negated conditional → NO_COVERAGE |
if (template.getIndirectReference() instanceof PRIndirectReference) |
2199 | return; | |
2200 |
1
1. releaseTemplate : negated conditional → NO_COVERAGE |
if (template.getType() == PdfTemplate.TYPE_TEMPLATE) { |
2201 | addToBody(template.getFormXObject(compressionLevel), template.getIndirectReference()); | |
2202 | objs[1] = null; | |
2203 | } | |
2204 | } | |
2205 | ||
2206 | // [F5] adding pages imported form other PDF documents | |
2207 | ||
2208 | protected HashMap<PdfReader, PdfReaderInstance> importedPages = new HashMap<>(); | |
2209 | ||
2210 | /** | |
2211 | * Use this method to get a page from other PDF document. | |
2212 | * The page can be used as any other PdfTemplate. | |
2213 | * Note that calling this method more than once with the same parameters | |
2214 | * will retrieve the same object. | |
2215 | * @param reader the PDF document where the page is | |
2216 | * @param pageNumber the page number. The first page is 1 | |
2217 | * @return the template representing the imported page | |
2218 | */ | |
2219 | public PdfImportedPage getImportedPage(PdfReader reader, int pageNumber) { | |
2220 | PdfReaderInstance inst = importedPages.get(reader); | |
2221 |
1
1. getImportedPage : negated conditional → NO_COVERAGE |
if (inst == null) { |
2222 | inst = reader.getPdfReaderInstance(this); | |
2223 | importedPages.put(reader, inst); | |
2224 | } | |
2225 |
1
1. getImportedPage : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::getImportedPage to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return inst.getImportedPage(pageNumber); |
2226 | } | |
2227 | ||
2228 | /** | |
2229 | * Use this method to writes the reader to the document | |
2230 | * and free the memory used by it. | |
2231 | * The main use is when concatenating multiple documents | |
2232 | * to keep the memory usage restricted to the current | |
2233 | * appending document. | |
2234 | * @param reader the <CODE>PdfReader</CODE> to free | |
2235 | * @throws IOException on error | |
2236 | */ | |
2237 | public void freeReader(PdfReader reader) throws IOException { | |
2238 | currentPdfReaderInstance = importedPages.get(reader); | |
2239 |
1
1. freeReader : negated conditional → NO_COVERAGE |
if (currentPdfReaderInstance == null) |
2240 | return; | |
2241 |
1
1. freeReader : removed call to com/lowagie/text/pdf/PdfReaderInstance::writeAllPages → NO_COVERAGE |
currentPdfReaderInstance.writeAllPages(); |
2242 | currentPdfReaderInstance = null; | |
2243 | importedPages.remove(reader); | |
2244 | } | |
2245 | ||
2246 | /** | |
2247 | * Use this method to gets the current document size. | |
2248 | * This size only includes the data already written | |
2249 | * to the output stream, it does not include templates or fonts. | |
2250 | * It is useful if used with <CODE>freeReader()</CODE> | |
2251 | * when concatenating many documents and an idea of | |
2252 | * the current size is needed. | |
2253 | * @return the approximate size without fonts or templates | |
2254 | */ | |
2255 | public int getCurrentDocumentSize() { | |
2256 |
4
1. getCurrentDocumentSize : Replaced integer multiplication with division → NO_COVERAGE 2. getCurrentDocumentSize : Replaced integer addition with subtraction → NO_COVERAGE 3. getCurrentDocumentSize : Replaced integer addition with subtraction → NO_COVERAGE 4. getCurrentDocumentSize : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return body.offset() + body.size() * 20 + 0x48; |
2257 | } | |
2258 | ||
2259 | protected PdfReaderInstance currentPdfReaderInstance; | |
2260 | ||
2261 | protected int getNewObjectNumber(PdfReader reader, int number, int generation) { | |
2262 | return currentPdfReaderInstance.getNewObjectNumber(number, generation); | |
2263 | } | |
2264 | ||
2265 | RandomAccessFileOrArray getReaderFile(PdfReader reader) { | |
2266 | return currentPdfReaderInstance.getReaderFile(); | |
2267 | } | |
2268 | ||
2269 | // [F6] spot colors | |
2270 | ||
2271 | /** The colors of this document */ | |
2272 | protected HashMap<PdfSpotColor, ColorDetails> documentColors = new HashMap<>(); | |
2273 | ||
2274 | /** The color number counter for the colors in the document. */ | |
2275 | protected int colorNumber = 1; | |
2276 | ||
2277 | PdfName getColorspaceName() { | |
2278 |
2
1. getColorspaceName : Replaced integer addition with subtraction → NO_COVERAGE 2. getColorspaceName : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::getColorspaceName to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return new PdfName("CS" + (colorNumber++)); |
2279 | } | |
2280 | ||
2281 | /** | |
2282 | * Adds a <CODE>SpotColor</CODE> to the document but not to the page resources. | |
2283 | * @param spc the <CODE>SpotColor</CODE> to add | |
2284 | * @return an <CODE>Object[]</CODE> where position 0 is a <CODE>PdfName</CODE> | |
2285 | * and position 1 is an <CODE>PdfIndirectReference</CODE> | |
2286 | */ | |
2287 | ColorDetails addSimple(PdfSpotColor spc) { | |
2288 | ColorDetails ret = documentColors.get(spc); | |
2289 |
1
1. addSimple : negated conditional → NO_COVERAGE |
if (ret == null) { |
2290 | ret = new ColorDetails(getColorspaceName(), body.getPdfIndirectReference(), spc); | |
2291 | documentColors.put(spc, ret); | |
2292 | } | |
2293 |
1
1. addSimple : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::addSimple to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return ret; |
2294 | } | |
2295 | ||
2296 | // [F7] document patterns | |
2297 | ||
2298 | /** The patterns of this document */ | |
2299 | protected HashMap<PdfPatternPainter, PdfName> documentPatterns = new HashMap<>(); | |
2300 | ||
2301 | /** The pattern number counter for the colors in the document. */ | |
2302 | protected int patternNumber = 1; | |
2303 | ||
2304 | PdfName addSimplePattern(PdfPatternPainter painter) { | |
2305 | PdfName name = documentPatterns.get(painter); | |
2306 | try { | |
2307 |
1
1. addSimplePattern : negated conditional → NO_COVERAGE |
if ( name == null ) { |
2308 | name = new PdfName("P" + patternNumber); | |
2309 |
1
1. addSimplePattern : Replaced integer addition with subtraction → NO_COVERAGE |
++patternNumber; |
2310 | documentPatterns.put(painter, name); | |
2311 | } | |
2312 | } catch (Exception e) { | |
2313 | throw new ExceptionConverter(e); | |
2314 | } | |
2315 |
1
1. addSimplePattern : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::addSimplePattern to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return name; |
2316 | } | |
2317 | ||
2318 | // [F8] shading patterns | |
2319 | ||
2320 | protected HashMap<PdfShadingPattern, Object> documentShadingPatterns = new HashMap<>(); | |
2321 | ||
2322 | void addSimpleShadingPattern(PdfShadingPattern shading) { | |
2323 |
1
1. addSimpleShadingPattern : negated conditional → NO_COVERAGE |
if (!documentShadingPatterns.containsKey(shading)) { |
2324 |
1
1. addSimpleShadingPattern : removed call to com/lowagie/text/pdf/PdfShadingPattern::setName → NO_COVERAGE |
shading.setName(patternNumber); |
2325 |
1
1. addSimpleShadingPattern : Replaced integer addition with subtraction → NO_COVERAGE |
++patternNumber; |
2326 | documentShadingPatterns.put(shading, null); | |
2327 |
1
1. addSimpleShadingPattern : removed call to com/lowagie/text/pdf/PdfWriter::addSimpleShading → NO_COVERAGE |
addSimpleShading(shading.getShading()); |
2328 | } | |
2329 | } | |
2330 | ||
2331 | // [F9] document shadings | |
2332 | ||
2333 | protected HashMap<PdfShading, Object> documentShadings = new HashMap<>(); | |
2334 | ||
2335 | void addSimpleShading(PdfShading shading) { | |
2336 |
1
1. addSimpleShading : negated conditional → NO_COVERAGE |
if (!documentShadings.containsKey(shading)) { |
2337 | documentShadings.put(shading, null); | |
2338 |
1
1. addSimpleShading : removed call to com/lowagie/text/pdf/PdfShading::setName → NO_COVERAGE |
shading.setName(documentShadings.size()); |
2339 | } | |
2340 | } | |
2341 | ||
2342 | // [F10] extended graphics state (for instance for transparency) | |
2343 | ||
2344 | protected HashMap<PdfDictionary, PdfObject[]> documentExtGState = new HashMap<>(); | |
2345 | ||
2346 | PdfObject[] addSimpleExtGState(PdfDictionary gstate) { | |
2347 |
1
1. addSimpleExtGState : negated conditional → NO_COVERAGE |
if (!documentExtGState.containsKey(gstate)) { |
2348 |
1
1. addSimpleExtGState : removed call to com/lowagie/text/pdf/internal/PdfXConformanceImp::checkPDFXConformance → NO_COVERAGE |
PdfXConformanceImp.checkPDFXConformance(this, PdfXConformanceImp.PDFXKEY_GSTATE, gstate); |
2349 |
1
1. addSimpleExtGState : Replaced integer addition with subtraction → NO_COVERAGE |
documentExtGState.put(gstate, new PdfObject[]{new PdfName("GS" + (documentExtGState.size() + 1)), getPdfIndirectReference()}); |
2350 | } | |
2351 |
1
1. addSimpleExtGState : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::addSimpleExtGState to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return documentExtGState.get(gstate); |
2352 | } | |
2353 | ||
2354 | // [F11] adding properties (OCG, marked content) | |
2355 | ||
2356 | protected HashMap<Object, PdfObject[]> documentProperties = new HashMap<>(); | |
2357 | PdfObject[] addSimpleProperty(Object prop, PdfIndirectReference refi) { | |
2358 |
1
1. addSimpleProperty : negated conditional → NO_COVERAGE |
if (!documentProperties.containsKey(prop)) { |
2359 |
1
1. addSimpleProperty : negated conditional → NO_COVERAGE |
if (prop instanceof PdfOCG) |
2360 |
1
1. addSimpleProperty : removed call to com/lowagie/text/pdf/internal/PdfXConformanceImp::checkPDFXConformance → NO_COVERAGE |
PdfXConformanceImp.checkPDFXConformance(this, PdfXConformanceImp.PDFXKEY_LAYER, null); |
2361 |
1
1. addSimpleProperty : Replaced integer addition with subtraction → NO_COVERAGE |
documentProperties.put(prop, new PdfObject[]{new PdfName("Pr" + (documentProperties.size() + 1)), refi}); |
2362 | } | |
2363 |
1
1. addSimpleProperty : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::addSimpleProperty to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return documentProperties.get(prop); |
2364 | } | |
2365 | ||
2366 | boolean propertyExists(Object prop) { | |
2367 | return documentProperties.containsKey(prop); | |
2368 | } | |
2369 | ||
2370 | // [F12] tagged PDF | |
2371 | ||
2372 | protected boolean tagged = false; | |
2373 | protected PdfStructureTreeRoot structureTreeRoot; | |
2374 | ||
2375 | /** | |
2376 | * Mark this document for tagging. It must be called before open. | |
2377 | */ | |
2378 | public void setTagged() { | |
2379 |
1
1. setTagged : negated conditional → NO_COVERAGE |
if (open) |
2380 | throw new IllegalArgumentException(MessageLocalization.getComposedMessage("tagging.must.be.set.before.opening.the.document")); | |
2381 | tagged = true; | |
2382 | } | |
2383 | ||
2384 | /** | |
2385 | * Check if the document is marked for tagging. | |
2386 | * @return <CODE>true</CODE> if the document is marked for tagging | |
2387 | */ | |
2388 | public boolean isTagged() { | |
2389 | return tagged; | |
2390 | } | |
2391 | ||
2392 | /** | |
2393 | * Gets the structure tree root. If the document is not marked for tagging it will return <CODE>null</CODE>. | |
2394 | * @return the structure tree root | |
2395 | */ | |
2396 | public PdfStructureTreeRoot getStructureTreeRoot() { | |
2397 |
2
1. getStructureTreeRoot : negated conditional → NO_COVERAGE 2. getStructureTreeRoot : negated conditional → NO_COVERAGE |
if (tagged && structureTreeRoot == null) |
2398 | structureTreeRoot = new PdfStructureTreeRoot(this); | |
2399 |
1
1. getStructureTreeRoot : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::getStructureTreeRoot to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return structureTreeRoot; |
2400 | } | |
2401 | ||
2402 | // [F13] Optional Content Groups | |
2403 | /** A hashSet containing all the PdfLayer objects. */ | |
2404 | protected Set<PdfOCG> documentOCG = new HashSet<>(); | |
2405 | /** An array list used to define the order of an OCG tree. */ | |
2406 | protected List<PdfOCG> documentOCGorder = new ArrayList<>(); | |
2407 | /** The OCProperties in a catalog dictionary. */ | |
2408 | protected PdfOCProperties OCProperties; | |
2409 | /** The RBGroups array in an OCG dictionary */ | |
2410 | protected PdfArray OCGRadioGroup = new PdfArray(); | |
2411 | /** | |
2412 | * The locked array in an OCG dictionary | |
2413 | * @since 2.1.2 | |
2414 | */ | |
2415 | protected PdfArray OCGLocked = new PdfArray(); | |
2416 | ||
2417 | /** | |
2418 | * Use this method to get the <B>Optional Content Properties Dictionary</B>. | |
2419 | * Each call fills the dictionary with the current layer state. | |
2420 | * It's advisable to only call this method right before close | |
2421 | * and do any modifications at that time. | |
2422 | * @return the Optional Content Properties Dictionary | |
2423 | */ | |
2424 | public PdfOCProperties getOCProperties() { | |
2425 |
1
1. getOCProperties : removed call to com/lowagie/text/pdf/PdfWriter::fillOCProperties → NO_COVERAGE |
fillOCProperties(true); |
2426 |
1
1. getOCProperties : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::getOCProperties to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return OCProperties; |
2427 | } | |
2428 | ||
2429 | /** | |
2430 | * Use this method to set a collection of optional content groups | |
2431 | * whose states are intended to follow a "radio button" paradigm. | |
2432 | * That is, the state of at most one optional content group | |
2433 | * in the array should be ON at a time: if one group is turned | |
2434 | * ON, all others must be turned OFF. | |
2435 | * @param group the radio group | |
2436 | */ | |
2437 | public void addOCGRadioGroup(ArrayList<PdfLayer> group) { | |
2438 | PdfArray ar = new PdfArray(); | |
2439 | for (PdfLayer layer : group) { | |
2440 |
1
1. addOCGRadioGroup : negated conditional → NO_COVERAGE |
if (layer.getTitle() == null) |
2441 | ar.add(layer.getRef()); | |
2442 | } | |
2443 |
1
1. addOCGRadioGroup : negated conditional → NO_COVERAGE |
if (ar.size() == 0) |
2444 | return; | |
2445 | OCGRadioGroup.add(ar); | |
2446 | } | |
2447 | ||
2448 | /** | |
2449 | * Use this method to lock an optional content group. | |
2450 | * The state of a locked group cannot be changed through the user interface | |
2451 | * of a viewer application. Producers can use this entry to prevent the visibility | |
2452 | * of content that depends on these groups from being changed by users. | |
2453 | * @param layer the layer that needs to be added to the array of locked OCGs | |
2454 | * @since 2.1.2 | |
2455 | */ | |
2456 | public void lockLayer(PdfLayer layer) { | |
2457 | OCGLocked.add(layer.getRef()); | |
2458 | } | |
2459 | ||
2460 | private static void getOCGOrder(PdfArray order, PdfLayer layer) { | |
2461 |
1
1. getOCGOrder : negated conditional → NO_COVERAGE |
if (!layer.isOnPanel()) |
2462 | return; | |
2463 |
1
1. getOCGOrder : negated conditional → NO_COVERAGE |
if (layer.getTitle() == null) |
2464 | order.add(layer.getRef()); | |
2465 | ArrayList<PdfLayer> children = layer.getChildren(); | |
2466 |
1
1. getOCGOrder : negated conditional → NO_COVERAGE |
if (children == null) |
2467 | return; | |
2468 | PdfArray kids = new PdfArray(); | |
2469 |
1
1. getOCGOrder : negated conditional → NO_COVERAGE |
if (layer.getTitle() != null) |
2470 | kids.add(new PdfString(layer.getTitle(), PdfObject.TEXT_UNICODE)); | |
2471 | for (PdfLayer child : children) { | |
2472 |
1
1. getOCGOrder : removed call to com/lowagie/text/pdf/PdfWriter::getOCGOrder → NO_COVERAGE |
getOCGOrder(kids, child); |
2473 | } | |
2474 |
2
1. getOCGOrder : changed conditional boundary → NO_COVERAGE 2. getOCGOrder : negated conditional → NO_COVERAGE |
if (kids.size() > 0) |
2475 | order.add(kids); | |
2476 | } | |
2477 | ||
2478 | private void addASEvent(PdfName event, PdfName category) { | |
2479 | PdfArray arr = new PdfArray(); | |
2480 | for (PdfOCG o : documentOCG) { | |
2481 | PdfLayer layer = (PdfLayer) o; | |
2482 | PdfDictionary usage = (PdfDictionary) layer.get(PdfName.USAGE); | |
2483 |
2
1. addASEvent : negated conditional → NO_COVERAGE 2. addASEvent : negated conditional → NO_COVERAGE |
if (usage != null && usage.get(category) != null) |
2484 | arr.add(layer.getRef()); | |
2485 | } | |
2486 |
1
1. addASEvent : negated conditional → NO_COVERAGE |
if (arr.size() == 0) |
2487 | return; | |
2488 | PdfDictionary d = (PdfDictionary)OCProperties.get(PdfName.D); | |
2489 | PdfArray arras = (PdfArray)d.get(PdfName.AS); | |
2490 |
1
1. addASEvent : negated conditional → NO_COVERAGE |
if (arras == null) { |
2491 | arras = new PdfArray(); | |
2492 |
1
1. addASEvent : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
d.put(PdfName.AS, arras); |
2493 | } | |
2494 | PdfDictionary as = new PdfDictionary(); | |
2495 |
1
1. addASEvent : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
as.put(PdfName.EVENT, event); |
2496 |
1
1. addASEvent : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
as.put(PdfName.CATEGORY, new PdfArray(category)); |
2497 |
1
1. addASEvent : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
as.put(PdfName.OCGS, arr); |
2498 | arras.add(as); | |
2499 | } | |
2500 | ||
2501 | /** | |
2502 | * @since 2.1.2 | |
2503 | */ | |
2504 | protected void fillOCProperties(boolean erase) { | |
2505 |
1
1. fillOCProperties : negated conditional → NO_COVERAGE |
if (OCProperties == null) |
2506 | OCProperties = new PdfOCProperties(); | |
2507 |
1
1. fillOCProperties : negated conditional → NO_COVERAGE |
if (erase) { |
2508 |
1
1. fillOCProperties : removed call to com/lowagie/text/pdf/PdfOCProperties::remove → NO_COVERAGE |
OCProperties.remove(PdfName.OCGS); |
2509 |
1
1. fillOCProperties : removed call to com/lowagie/text/pdf/PdfOCProperties::remove → NO_COVERAGE |
OCProperties.remove(PdfName.D); |
2510 | } | |
2511 |
1
1. fillOCProperties : negated conditional → NO_COVERAGE |
if (OCProperties.get(PdfName.OCGS) == null) { |
2512 | PdfArray gr = new PdfArray(); | |
2513 | for (PdfOCG o : documentOCG) { | |
2514 | PdfLayer layer = (PdfLayer) o; | |
2515 | gr.add(layer.getRef()); | |
2516 | } | |
2517 |
1
1. fillOCProperties : removed call to com/lowagie/text/pdf/PdfOCProperties::put → NO_COVERAGE |
OCProperties.put(PdfName.OCGS, gr); |
2518 | } | |
2519 |
1
1. fillOCProperties : negated conditional → NO_COVERAGE |
if (OCProperties.get(PdfName.D) != null) |
2520 | return; | |
2521 | List<PdfOCG> docOrder = new ArrayList<>(documentOCGorder); | |
2522 | for (Iterator<PdfOCG> it = docOrder.iterator(); it.hasNext();) { | |
2523 | PdfLayer layer = (PdfLayer)it.next(); | |
2524 |
1
1. fillOCProperties : negated conditional → NO_COVERAGE |
if (layer.getParent() != null) |
2525 |
1
1. fillOCProperties : removed call to java/util/Iterator::remove → NO_COVERAGE |
it.remove(); |
2526 | } | |
2527 | PdfArray order = new PdfArray(); | |
2528 | for (PdfOCG o1 : docOrder) { | |
2529 | PdfLayer layer = (PdfLayer) o1; | |
2530 |
1
1. fillOCProperties : removed call to com/lowagie/text/pdf/PdfWriter::getOCGOrder → NO_COVERAGE |
getOCGOrder(order, layer); |
2531 | } | |
2532 | PdfDictionary d = new PdfDictionary(); | |
2533 |
1
1. fillOCProperties : removed call to com/lowagie/text/pdf/PdfOCProperties::put → NO_COVERAGE |
OCProperties.put(PdfName.D, d); |
2534 |
1
1. fillOCProperties : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
d.put(PdfName.ORDER, order); |
2535 | PdfArray gr = new PdfArray(); | |
2536 | for (PdfOCG o : documentOCG) { | |
2537 | PdfLayer layer = (PdfLayer) o; | |
2538 |
1
1. fillOCProperties : negated conditional → NO_COVERAGE |
if (!layer.isOn()) |
2539 | gr.add(layer.getRef()); | |
2540 | } | |
2541 |
2
1. fillOCProperties : changed conditional boundary → NO_COVERAGE 2. fillOCProperties : negated conditional → NO_COVERAGE |
if (gr.size() > 0) |
2542 |
1
1. fillOCProperties : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
d.put(PdfName.OFF, gr); |
2543 |
2
1. fillOCProperties : changed conditional boundary → NO_COVERAGE 2. fillOCProperties : negated conditional → NO_COVERAGE |
if (OCGRadioGroup.size() > 0) |
2544 |
1
1. fillOCProperties : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
d.put(PdfName.RBGROUPS, OCGRadioGroup); |
2545 |
2
1. fillOCProperties : changed conditional boundary → NO_COVERAGE 2. fillOCProperties : negated conditional → NO_COVERAGE |
if (OCGLocked.size() > 0) |
2546 |
1
1. fillOCProperties : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
d.put(PdfName.LOCKED, OCGLocked); |
2547 |
1
1. fillOCProperties : removed call to com/lowagie/text/pdf/PdfWriter::addASEvent → NO_COVERAGE |
addASEvent(PdfName.VIEW, PdfName.ZOOM); |
2548 |
1
1. fillOCProperties : removed call to com/lowagie/text/pdf/PdfWriter::addASEvent → NO_COVERAGE |
addASEvent(PdfName.VIEW, PdfName.VIEW); |
2549 |
1
1. fillOCProperties : removed call to com/lowagie/text/pdf/PdfWriter::addASEvent → NO_COVERAGE |
addASEvent(PdfName.PRINT, PdfName.PRINT); |
2550 |
1
1. fillOCProperties : removed call to com/lowagie/text/pdf/PdfWriter::addASEvent → NO_COVERAGE |
addASEvent(PdfName.EXPORT, PdfName.EXPORT); |
2551 |
1
1. fillOCProperties : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
d.put(PdfName.LISTMODE, PdfName.VISIBLEPAGES); |
2552 | } | |
2553 | ||
2554 | void registerLayer(PdfOCG layer) { | |
2555 |
1
1. registerLayer : removed call to com/lowagie/text/pdf/internal/PdfXConformanceImp::checkPDFXConformance → NO_COVERAGE |
PdfXConformanceImp.checkPDFXConformance(this, PdfXConformanceImp.PDFXKEY_LAYER, null); |
2556 |
1
1. registerLayer : negated conditional → NO_COVERAGE |
if (layer instanceof PdfLayer) { |
2557 | PdfLayer la = (PdfLayer)layer; | |
2558 |
1
1. registerLayer : negated conditional → NO_COVERAGE |
if (la.getTitle() == null) { |
2559 |
1
1. registerLayer : negated conditional → NO_COVERAGE |
if (!documentOCG.contains(layer)) { |
2560 | documentOCG.add(layer); | |
2561 | documentOCGorder.add(layer); | |
2562 | } | |
2563 | } | |
2564 | else { | |
2565 | documentOCGorder.add(layer); | |
2566 | } | |
2567 | } | |
2568 | else | |
2569 | throw new IllegalArgumentException(MessageLocalization.getComposedMessage("only.pdflayer.is.accepted")); | |
2570 | } | |
2571 | ||
2572 | // User methods to change aspects of the page | |
2573 | ||
2574 | // [U1] page size | |
2575 | ||
2576 | /** | |
2577 | * Use this method to get the size of the media box. | |
2578 | * @return a Rectangle | |
2579 | */ | |
2580 | public Rectangle getPageSize() { | |
2581 | return pdf.getPageSize(); | |
2582 | } | |
2583 | ||
2584 | /** | |
2585 | * Use this method to set the crop box. | |
2586 | * The crop box should not be rotated even if the page is rotated. | |
2587 | * This change only takes effect in the next page. | |
2588 | * @param crop the crop box | |
2589 | */ | |
2590 | public void setCropBoxSize(Rectangle crop) { | |
2591 | pdf.setCropBoxSize(crop); | |
2592 | } | |
2593 | ||
2594 | /** | |
2595 | * Use this method to set the page box sizes. | |
2596 | * Allowed names are: "crop", "trim", "art" and "bleed". | |
2597 | * @param boxName the box size | |
2598 | * @param size the size | |
2599 | */ | |
2600 | public void setBoxSize(String boxName, Rectangle size) { | |
2601 | pdf.setBoxSize(boxName, size); | |
2602 | } | |
2603 | ||
2604 | /** | |
2605 | * Use this method to get the size of a trim, art, crop or bleed box, | |
2606 | * or null if not defined. | |
2607 | * @param boxName crop, trim, art or bleed | |
2608 | */ | |
2609 | public Rectangle getBoxSize(String boxName) { | |
2610 | return pdf.getBoxSize(boxName); | |
2611 | } | |
2612 | ||
2613 | // [U2] take care of empty pages | |
2614 | ||
2615 | /** | |
2616 | * Use this method to make sure a page is added, | |
2617 | * even if it's empty. If you use setPageEmpty(false), | |
2618 | * invoking newPage() after a blank page will add a newPage. | |
2619 | * setPageEmpty(true) won't have any effect. | |
2620 | * @param pageEmpty the state | |
2621 | */ | |
2622 | public void setPageEmpty(boolean pageEmpty) { | |
2623 |
1
1. setPageEmpty : negated conditional → NO_COVERAGE |
if (pageEmpty) |
2624 | return; | |
2625 |
1
1. setPageEmpty : removed call to com/lowagie/text/pdf/PdfDocument::setPageEmpty → NO_COVERAGE |
pdf.setPageEmpty(pageEmpty); |
2626 | } | |
2627 | ||
2628 | /** | |
2629 | * Checks if a newPage() will actually generate a new page. | |
2630 | * @return true if a new page will be generated, false otherwise | |
2631 | * @since 2.1.8 | |
2632 | */ | |
2633 | public boolean isPageEmpty() { | |
2634 | return pdf.isPageEmpty(); | |
2635 | } | |
2636 | ||
2637 | // [U3] page actions (open and close) | |
2638 | ||
2639 | /** action value */ | |
2640 | public static final PdfName PAGE_OPEN = PdfName.O; | |
2641 | /** action value */ | |
2642 | public static final PdfName PAGE_CLOSE = PdfName.C; | |
2643 | ||
2644 | /** @see com.lowagie.text.pdf.interfaces.PdfPageActions#setPageAction(com.lowagie.text.pdf.PdfName, com.lowagie.text.pdf.PdfAction) */ | |
2645 | public void setPageAction(PdfName actionType, PdfAction action) throws DocumentException { | |
2646 |
2
1. setPageAction : negated conditional → NO_COVERAGE 2. setPageAction : negated conditional → NO_COVERAGE |
if (!actionType.equals(PAGE_OPEN) && !actionType.equals(PAGE_CLOSE)) |
2647 | throw new DocumentException(MessageLocalization.getComposedMessage("invalid.page.additional.action.type.1", actionType.toString())); | |
2648 |
1
1. setPageAction : removed call to com/lowagie/text/pdf/PdfDocument::setPageAction → NO_COVERAGE |
pdf.setPageAction(actionType, action); |
2649 | } | |
2650 | ||
2651 | /** @see com.lowagie.text.pdf.interfaces.PdfPageActions#setDuration(int) */ | |
2652 | public void setDuration(int seconds) { | |
2653 | pdf.setDuration(seconds); | |
2654 | } | |
2655 | ||
2656 | /** @see com.lowagie.text.pdf.interfaces.PdfPageActions#setTransition(com.lowagie.text.pdf.PdfTransition) */ | |
2657 | public void setTransition(PdfTransition transition) { | |
2658 | pdf.setTransition(transition); | |
2659 | } | |
2660 | ||
2661 | // [U4] Thumbnail image | |
2662 | ||
2663 | /** | |
2664 | * Use this method to set the thumbnail image for the current page. | |
2665 | * @param image the image | |
2666 | * @throws PdfException on error | |
2667 | * @throws DocumentException or error | |
2668 | */ | |
2669 | public void setThumbnail(Image image) throws DocumentException { | |
2670 | pdf.setThumbnail(image); | |
2671 | } | |
2672 | ||
2673 | // [U5] Transparency groups | |
2674 | ||
2675 | /** | |
2676 | * A group attributes dictionary specifying the attributes | |
2677 | * of the page's page group for use in the transparent | |
2678 | * imaging model | |
2679 | */ | |
2680 | protected PdfDictionary group; | |
2681 | ||
2682 | /** | |
2683 | * Use this method to get the group dictionary. | |
2684 | * @return Value of property group. | |
2685 | */ | |
2686 | public PdfDictionary getGroup() { | |
2687 | return this.group; | |
2688 | } | |
2689 | ||
2690 | /** | |
2691 | * Use this method to set the group dictionary. | |
2692 | * @param group New value of property group. | |
2693 | */ | |
2694 | public void setGroup(PdfDictionary group) { | |
2695 | this.group = group; | |
2696 | } | |
2697 | ||
2698 | // [U6] space char ratio | |
2699 | ||
2700 | /** The default space-char ratio. */ | |
2701 | public static final float SPACE_CHAR_RATIO_DEFAULT = 2.5f; | |
2702 | /** Disable the inter-character spacing. */ | |
2703 | public static final float NO_SPACE_CHAR_RATIO = 10000000f; | |
2704 | ||
2705 | /** | |
2706 | * The ratio between the extra word spacing and the extra character spacing. | |
2707 | * Extra word spacing will grow <CODE>ratio</CODE> times more than extra character spacing. | |
2708 | */ | |
2709 | private float spaceCharRatio = SPACE_CHAR_RATIO_DEFAULT; | |
2710 | ||
2711 | /** | |
2712 | * Use this method to gets the space/character extra spacing ratio | |
2713 | * for fully justified text. | |
2714 | * @return the space/character extra spacing ratio | |
2715 | */ | |
2716 | public float getSpaceCharRatio() { | |
2717 | return spaceCharRatio; | |
2718 | } | |
2719 | ||
2720 | /** | |
2721 | * Use this method to set the ratio between the extra word spacing and | |
2722 | * the extra character spacing when the text is fully justified. | |
2723 | * Extra word spacing will grow <CODE>spaceCharRatio</CODE> times more | |
2724 | * than extra character spacing. If the ratio is <CODE>PdfWriter.NO_SPACE_CHAR_RATIO</CODE> | |
2725 | * then the extra character spacing will be zero. | |
2726 | * @param spaceCharRatio the ratio between the extra word spacing and the extra character spacing | |
2727 | */ | |
2728 | public void setSpaceCharRatio(float spaceCharRatio) { | |
2729 |
2
1. setSpaceCharRatio : changed conditional boundary → NO_COVERAGE 2. setSpaceCharRatio : negated conditional → NO_COVERAGE |
if (spaceCharRatio < 0.001f) |
2730 | this.spaceCharRatio = 0.001f; | |
2731 | else | |
2732 | this.spaceCharRatio = spaceCharRatio; | |
2733 | } | |
2734 | ||
2735 | // [U7] run direction (doesn't actually do anything) | |
2736 | ||
2737 | /** Use the default run direction. */ | |
2738 | public static final int RUN_DIRECTION_DEFAULT = 0; | |
2739 | /** Do not use bidirectional reordering. */ | |
2740 | public static final int RUN_DIRECTION_NO_BIDI = 1; | |
2741 | ||
2742 | /** Use bidirectional reordering with left-to-right | |
2743 | * preferential run direction. | |
2744 | */ | |
2745 | public static final int RUN_DIRECTION_LTR = 2; | |
2746 | /** Use bidirectional reordering with right-to-left | |
2747 | * preferential run direction. | |
2748 | */ | |
2749 | public static final int RUN_DIRECTION_RTL = 3; | |
2750 | ||
2751 | protected int runDirection = RUN_DIRECTION_NO_BIDI; | |
2752 | ||
2753 | /** | |
2754 | * Use this method to set the run direction. | |
2755 | * This is only used as a placeholder as it does not affect anything. | |
2756 | * @param runDirection the run direction | |
2757 | */ | |
2758 | public void setRunDirection(int runDirection) { | |
2759 |
4
1. setRunDirection : changed conditional boundary → NO_COVERAGE 2. setRunDirection : changed conditional boundary → NO_COVERAGE 3. setRunDirection : negated conditional → NO_COVERAGE 4. setRunDirection : negated conditional → NO_COVERAGE |
if (runDirection < RUN_DIRECTION_NO_BIDI || runDirection > RUN_DIRECTION_RTL) |
2760 | throw new RuntimeException(MessageLocalization.getComposedMessage("invalid.run.direction.1", runDirection)); | |
2761 | this.runDirection = runDirection; | |
2762 | } | |
2763 | ||
2764 | /** | |
2765 | * Use this method to set the run direction. | |
2766 | * @return the run direction | |
2767 | */ | |
2768 | public int getRunDirection() { | |
2769 | return runDirection; | |
2770 | } | |
2771 | ||
2772 | // [U8] user units | |
2773 | ||
2774 | protected float userunit = 0f; | |
2775 | /** | |
2776 | * Use this method to get the user unit. | |
2777 | * A user unit is a value that defines the default user space unit. | |
2778 | * The minimum UserUnit is 1 (1 unit = 1/72 inch). | |
2779 | * The maximum UserUnit is 75,000. | |
2780 | * Note that this userunit only works starting with PDF1.6! | |
2781 | * @return Returns the userunit. | |
2782 | */ | |
2783 | public float getUserunit() { | |
2784 | return userunit; | |
2785 | } | |
2786 | /** | |
2787 | * Use this method to set the user unit. | |
2788 | * A UserUnit is a value that defines the default user space unit. | |
2789 | * The minimum UserUnit is 1 (1 unit = 1/72 inch). | |
2790 | * The maximum UserUnit is 75,000. | |
2791 | * Note that this userunit only works starting with PDF1.6! | |
2792 | * @param userunit The userunit to set. | |
2793 | * @throws DocumentException on error | |
2794 | */ | |
2795 | public void setUserunit(float userunit) throws DocumentException { | |
2796 |
4
1. setUserunit : changed conditional boundary → NO_COVERAGE 2. setUserunit : changed conditional boundary → NO_COVERAGE 3. setUserunit : negated conditional → NO_COVERAGE 4. setUserunit : negated conditional → NO_COVERAGE |
if (userunit < 1f || userunit > 75000f) throw new DocumentException(MessageLocalization.getComposedMessage("userunit.should.be.a.value.between.1.and.75000")); |
2797 | this.userunit = userunit; | |
2798 |
1
1. setUserunit : removed call to com/lowagie/text/pdf/PdfWriter::setAtLeastPdfVersion → NO_COVERAGE |
setAtLeastPdfVersion(VERSION_1_6); |
2799 | } | |
2800 | ||
2801 | // Miscellaneous topics | |
2802 | ||
2803 | // [M1] Color settings | |
2804 | ||
2805 | protected PdfDictionary defaultColorspace = new PdfDictionary(); | |
2806 | /** | |
2807 | * Use this method to get the default colorspaces. | |
2808 | * @return the default colorspaces | |
2809 | */ | |
2810 | public PdfDictionary getDefaultColorspace() { | |
2811 | return defaultColorspace; | |
2812 | } | |
2813 | ||
2814 | /** | |
2815 | * Use this method to sets the default colorspace that will be applied | |
2816 | * to all the document. The colorspace is only applied if another colorspace | |
2817 | * with the same name is not present in the content. | |
2818 | * <p> | |
2819 | * The colorspace is applied immediately when creating templates and | |
2820 | * at the page end for the main document content. | |
2821 | * @param key the name of the colorspace. It can be <CODE>PdfName.DEFAULTGRAY</CODE>, <CODE>PdfName.DEFAULTRGB</CODE> | |
2822 | * or <CODE>PdfName.DEFAULTCMYK</CODE> | |
2823 | * @param cs the colorspace. A <CODE>null</CODE> or <CODE>PdfNull</CODE> removes any colorspace with the same name | |
2824 | */ | |
2825 | public void setDefaultColorspace(PdfName key, PdfObject cs) { | |
2826 |
2
1. setDefaultColorspace : negated conditional → NO_COVERAGE 2. setDefaultColorspace : negated conditional → NO_COVERAGE |
if (cs == null || cs.isNull()) |
2827 |
1
1. setDefaultColorspace : removed call to com/lowagie/text/pdf/PdfDictionary::remove → NO_COVERAGE |
defaultColorspace.remove(key); |
2828 |
1
1. setDefaultColorspace : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
defaultColorspace.put(key, cs); |
2829 | } | |
2830 | ||
2831 | // [M2] spot patterns | |
2832 | ||
2833 | protected HashMap<ColorDetails, ColorDetails> documentSpotPatterns = new HashMap<>(); | |
2834 | protected ColorDetails patternColorspaceRGB; | |
2835 | protected ColorDetails patternColorspaceGRAY; | |
2836 | protected ColorDetails patternColorspaceCMYK; | |
2837 | ||
2838 | ColorDetails addSimplePatternColorspace(Color color) { | |
2839 | int type = ExtendedColor.getType(color); | |
2840 |
2
1. addSimplePatternColorspace : negated conditional → NO_COVERAGE 2. addSimplePatternColorspace : negated conditional → NO_COVERAGE |
if (type == ExtendedColor.TYPE_PATTERN || type == ExtendedColor.TYPE_SHADING) |
2841 | throw new RuntimeException(MessageLocalization.getComposedMessage("an.uncolored.tile.pattern.can.not.have.another.pattern.or.shading.as.color")); | |
2842 | try { | |
2843 | switch (type) { | |
2844 | case ExtendedColor.TYPE_RGB: | |
2845 |
1
1. addSimplePatternColorspace : negated conditional → NO_COVERAGE |
if (patternColorspaceRGB == null) { |
2846 | patternColorspaceRGB = new ColorDetails(getColorspaceName(), body.getPdfIndirectReference(), null); | |
2847 | PdfArray array = new PdfArray(PdfName.PATTERN); | |
2848 | array.add(PdfName.DEVICERGB); | |
2849 | addToBody(array, patternColorspaceRGB.getIndirectReference()); | |
2850 | } | |
2851 |
1
1. addSimplePatternColorspace : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::addSimplePatternColorspace to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return patternColorspaceRGB; |
2852 | case ExtendedColor.TYPE_CMYK: | |
2853 |
1
1. addSimplePatternColorspace : negated conditional → NO_COVERAGE |
if (patternColorspaceCMYK == null) { |
2854 | patternColorspaceCMYK = new ColorDetails(getColorspaceName(), body.getPdfIndirectReference(), null); | |
2855 | PdfArray array = new PdfArray(PdfName.PATTERN); | |
2856 | array.add(PdfName.DEVICECMYK); | |
2857 | addToBody(array, patternColorspaceCMYK.getIndirectReference()); | |
2858 | } | |
2859 |
1
1. addSimplePatternColorspace : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::addSimplePatternColorspace to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return patternColorspaceCMYK; |
2860 | case ExtendedColor.TYPE_GRAY: | |
2861 |
1
1. addSimplePatternColorspace : negated conditional → NO_COVERAGE |
if (patternColorspaceGRAY == null) { |
2862 | patternColorspaceGRAY = new ColorDetails(getColorspaceName(), body.getPdfIndirectReference(), null); | |
2863 | PdfArray array = new PdfArray(PdfName.PATTERN); | |
2864 | array.add(PdfName.DEVICEGRAY); | |
2865 | addToBody(array, patternColorspaceGRAY.getIndirectReference()); | |
2866 | } | |
2867 |
1
1. addSimplePatternColorspace : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::addSimplePatternColorspace to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return patternColorspaceGRAY; |
2868 | case ExtendedColor.TYPE_SEPARATION: { | |
2869 | ColorDetails details = addSimple(((SpotColor)color).getPdfSpotColor()); | |
2870 | ColorDetails patternDetails = documentSpotPatterns.get(details); | |
2871 |
1
1. addSimplePatternColorspace : negated conditional → NO_COVERAGE |
if (patternDetails == null) { |
2872 | patternDetails = new ColorDetails(getColorspaceName(), body.getPdfIndirectReference(), null); | |
2873 | PdfArray array = new PdfArray(PdfName.PATTERN); | |
2874 | array.add(details.getIndirectReference()); | |
2875 | addToBody(array, patternDetails.getIndirectReference()); | |
2876 | documentSpotPatterns.put(details, patternDetails); | |
2877 | } | |
2878 |
1
1. addSimplePatternColorspace : mutated return of Object value for com/lowagie/text/pdf/PdfWriter::addSimplePatternColorspace to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return patternDetails; |
2879 | } | |
2880 | default: | |
2881 | throw new RuntimeException(MessageLocalization.getComposedMessage("invalid.color.type")); | |
2882 | } | |
2883 | } | |
2884 | catch (Exception e) { | |
2885 | throw new RuntimeException(e.getMessage()); | |
2886 | } | |
2887 | } | |
2888 | ||
2889 | // [M3] Images | |
2890 | ||
2891 | /** | |
2892 | * Use this method to get the strictImageSequence status. | |
2893 | * @return value of property strictImageSequence | |
2894 | */ | |
2895 | public boolean isStrictImageSequence() { | |
2896 | return pdf.isStrictImageSequence(); | |
2897 | } | |
2898 | ||
2899 | /** | |
2900 | * Use this method to set the image sequence, so that it follows | |
2901 | * the text in strict order (or not). | |
2902 | * @param strictImageSequence new value of property strictImageSequence | |
2903 | * | |
2904 | */ | |
2905 | public void setStrictImageSequence(boolean strictImageSequence) { | |
2906 | pdf.setStrictImageSequence(strictImageSequence); | |
2907 | } | |
2908 | ||
2909 | /** | |
2910 | * Use this method to clear text wrapping around images (if applicable). | |
2911 | * @throws DocumentException | |
2912 | */ | |
2913 | public void clearTextWrap() throws DocumentException { | |
2914 | pdf.clearTextWrap(); | |
2915 | } | |
2916 | ||
2917 | /** Dictionary, containing all the images of the PDF document */ | |
2918 | protected PdfDictionary imageDictionary = new PdfDictionary(); | |
2919 | ||
2920 | /** This is the list with all the images in the document. */ | |
2921 | private HashMap<Long, PdfName> images = new HashMap<>(); | |
2922 | ||
2923 | /** | |
2924 | * Use this method to adds an image to the document | |
2925 | * but not to the page resources. It is used with | |
2926 | * templates and <CODE>Document.add(Image)</CODE>. | |
2927 | * Use this method only if you know what you're doing! | |
2928 | * @param image the <CODE>Image</CODE> to add | |
2929 | * @return the name of the image added | |
2930 | * @throws PdfException on error | |
2931 | * @throws DocumentException on error | |
2932 | */ |