1 | /* | |
2 | * $Id: PdfPages.java 4065 2009-09-16 23:09:11Z psoares33 $ | |
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.Document; | |
53 | import com.lowagie.text.DocumentException; | |
54 | ||
55 | import com.lowagie.text.error_messages.MessageLocalization; | |
56 | import com.lowagie.text.ExceptionConverter; | |
57 | ||
58 | import java.io.IOException; | |
59 | import java.util.ArrayList; | |
60 | ||
61 | /** | |
62 | * <CODE>PdfPages</CODE> is the PDF Pages-object. | |
63 | * <P> | |
64 | * The Pages of a document are accessible through a tree of nodes known as the Pages tree. | |
65 | * This tree defines the ordering of the pages in the document.<BR> | |
66 | * This object is described in the 'Portable Document Format Reference Manual version 1.3' | |
67 | * section 6.3 (page 71-73) | |
68 | * | |
69 | * @see PdfPage | |
70 | */ | |
71 | ||
72 | public class PdfPages { | |
73 | | |
74 | private ArrayList pages = new ArrayList(); | |
75 | private ArrayList parents = new ArrayList(); | |
76 | private int leafSize = 10; | |
77 | private PdfWriter writer; | |
78 | private PdfIndirectReference topParent; | |
79 | | |
80 | // constructors | |
81 | | |
82 | /** | |
83 | * Constructs a <CODE>PdfPages</CODE>-object. | |
84 | */ | |
85 | | |
86 | PdfPages(PdfWriter writer) { | |
87 | this.writer = writer; | |
88 | } | |
89 | | |
90 | void addPage(PdfDictionary page) { | |
91 | try { | |
92 |
2
1. addPage : Replaced integer modulus with multiplication → NO_COVERAGE 2. addPage : negated conditional → NO_COVERAGE |
if ((pages.size() % leafSize) == 0) |
93 | parents.add(writer.getPdfIndirectReference()); | |
94 |
1
1. addPage : Replaced integer subtraction with addition → NO_COVERAGE |
PdfIndirectReference parent = (PdfIndirectReference)parents.get(parents.size() - 1); |
95 |
1
1. addPage : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
page.put(PdfName.PARENT, parent); |
96 | PdfIndirectReference current = writer.getCurrentPage(); | |
97 | writer.addToBody(page, current); | |
98 | pages.add(current); | |
99 | } | |
100 | catch (Exception e) { | |
101 | throw new ExceptionConverter(e); | |
102 | } | |
103 | } | |
104 | | |
105 | PdfIndirectReference addPageRef(PdfIndirectReference pageRef) { | |
106 | try { | |
107 |
2
1. addPageRef : Replaced integer modulus with multiplication → NO_COVERAGE 2. addPageRef : negated conditional → NO_COVERAGE |
if ((pages.size() % leafSize) == 0) |
108 | parents.add(writer.getPdfIndirectReference()); | |
109 | pages.add(pageRef); | |
110 |
2
1. addPageRef : Replaced integer subtraction with addition → NO_COVERAGE 2. addPageRef : mutated return of Object value for com/lowagie/text/pdf/PdfPages::addPageRef to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return (PdfIndirectReference)parents.get(parents.size() - 1); |
111 | } | |
112 | catch (Exception e) { | |
113 | throw new ExceptionConverter(e); | |
114 | } | |
115 | } | |
116 | | |
117 | // returns the top parent to include in the catalog | |
118 | PdfIndirectReference writePageTree() throws IOException { | |
119 |
1
1. writePageTree : negated conditional → NO_COVERAGE |
if (pages.isEmpty()) |
120 | throw new IOException(MessageLocalization.getComposedMessage("the.document.has.no.pages")); | |
121 | int leaf = 1; | |
122 | ArrayList tParents = parents; | |
123 | ArrayList tPages = pages; | |
124 | ArrayList nextParents = new ArrayList(); | |
125 | while (true) { | |
126 |
1
1. writePageTree : Replaced integer multiplication with division → NO_COVERAGE |
leaf *= leafSize; |
127 | int stdCount = leafSize; | |
128 |
1
1. writePageTree : Replaced integer modulus with multiplication → NO_COVERAGE |
int rightCount = tPages.size() % leafSize; |
129 |
1
1. writePageTree : negated conditional → NO_COVERAGE |
if (rightCount == 0) |
130 | rightCount = leafSize; | |
131 |
3
1. writePageTree : changed conditional boundary → NO_COVERAGE 2. writePageTree : Changed increment from 1 to -1 → NO_COVERAGE 3. writePageTree : negated conditional → NO_COVERAGE |
for (int p = 0; p < tParents.size(); ++p) { |
132 | int count; | |
133 | int thisLeaf = leaf; | |
134 |
2
1. writePageTree : Replaced integer subtraction with addition → NO_COVERAGE 2. writePageTree : negated conditional → NO_COVERAGE |
if (p == tParents.size() - 1) { |
135 | count = rightCount; | |
136 |
1
1. writePageTree : Replaced integer modulus with multiplication → NO_COVERAGE |
thisLeaf = pages.size() % leaf; |
137 |
1
1. writePageTree : negated conditional → NO_COVERAGE |
if (thisLeaf == 0) |
138 | thisLeaf = leaf; | |
139 | } | |
140 | else | |
141 | count = stdCount; | |
142 | PdfDictionary top = new PdfDictionary(PdfName.PAGES); | |
143 |
1
1. writePageTree : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
top.put(PdfName.COUNT, new PdfNumber(thisLeaf)); |
144 |
3
1. writePageTree : Replaced integer multiplication with division → NO_COVERAGE 2. writePageTree : Replaced integer multiplication with division → NO_COVERAGE 3. writePageTree : Replaced integer addition with subtraction → NO_COVERAGE |
PdfArray kids = new PdfArray(tPages.subList(p * stdCount, p * stdCount + count)); |
145 |
1
1. writePageTree : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
top.put(PdfName.KIDS, kids); |
146 |
2
1. writePageTree : changed conditional boundary → NO_COVERAGE 2. writePageTree : negated conditional → NO_COVERAGE |
if (tParents.size() > 1) { |
147 |
2
1. writePageTree : Replaced integer modulus with multiplication → NO_COVERAGE 2. writePageTree : negated conditional → NO_COVERAGE |
if ((p % leafSize) == 0) |
148 | nextParents.add(writer.getPdfIndirectReference()); | |
149 |
2
1. writePageTree : Replaced integer division with multiplication → NO_COVERAGE 2. writePageTree : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
top.put(PdfName.PARENT, (PdfIndirectReference)nextParents.get(p / leafSize)); |
150 | } | |
151 | else { | |
152 |
1
1. writePageTree : removed call to com/lowagie/text/pdf/PdfDictionary::put → NO_COVERAGE |
top.put(PdfName.ITXT, new PdfString(Document.getRelease())); |
153 | } | |
154 | writer.addToBody(top, (PdfIndirectReference)tParents.get(p)); | |
155 | } | |
156 |
1
1. writePageTree : negated conditional → NO_COVERAGE |
if (tParents.size() == 1) { |
157 | topParent = (PdfIndirectReference)tParents.get(0); | |
158 |
1
1. writePageTree : mutated return of Object value for com/lowagie/text/pdf/PdfPages::writePageTree to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return topParent; |
159 | } | |
160 | tPages = tParents; | |
161 | tParents = nextParents; | |
162 | nextParents = new ArrayList(); | |
163 | } | |
164 | } | |
165 | | |
166 | PdfIndirectReference getTopParent() { | |
167 | return topParent; | |
168 | } | |
169 | | |
170 | void setLinearMode(PdfIndirectReference topParent) { | |
171 |
2
1. setLinearMode : changed conditional boundary → NO_COVERAGE 2. setLinearMode : negated conditional → NO_COVERAGE |
if (parents.size() > 1) |
172 | throw new RuntimeException(MessageLocalization.getComposedMessage("linear.page.mode.can.only.be.called.with.a.single.parent")); | |
173 |
1
1. setLinearMode : negated conditional → NO_COVERAGE |
if (topParent != null) { |
174 | this.topParent = topParent; | |
175 |
1
1. setLinearMode : removed call to java/util/ArrayList::clear → NO_COVERAGE |
parents.clear(); |
176 | parents.add(topParent); | |
177 | } | |
178 | leafSize = 10000000; | |
179 | } | |
180 | ||
181 | void addPage(PdfIndirectReference page) { | |
182 | pages.add(page); | |
183 | } | |
184 | ||
185 | int reorderPages(int[] order) throws DocumentException { | |
186 |
1
1. reorderPages : negated conditional → NO_COVERAGE |
if (order == null) |
187 |
1
1. reorderPages : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return pages.size(); |
188 |
2
1. reorderPages : changed conditional boundary → NO_COVERAGE 2. reorderPages : negated conditional → NO_COVERAGE |
if (parents.size() > 1) |
189 | throw new DocumentException(MessageLocalization.getComposedMessage("page.reordering.requires.a.single.parent.in.the.page.tree.call.pdfwriter.setlinearmode.after.open")); | |
190 |
1
1. reorderPages : negated conditional → NO_COVERAGE |
if (order.length != pages.size()) |
191 | throw new DocumentException(MessageLocalization.getComposedMessage("page.reordering.requires.an.array.with.the.same.size.as.the.number.of.pages")); | |
192 | int max = pages.size(); | |
193 | boolean[] temp = new boolean[max]; | |
194 |
3
1. reorderPages : changed conditional boundary → NO_COVERAGE 2. reorderPages : Changed increment from 1 to -1 → NO_COVERAGE 3. reorderPages : negated conditional → NO_COVERAGE |
for (int k = 0; k < max; ++k) { |
195 | int p = order[k]; | |
196 |
4
1. reorderPages : changed conditional boundary → NO_COVERAGE 2. reorderPages : changed conditional boundary → NO_COVERAGE 3. reorderPages : negated conditional → NO_COVERAGE 4. reorderPages : negated conditional → NO_COVERAGE |
if (p < 1 || p > max) |
197 | throw new DocumentException(MessageLocalization.getComposedMessage("page.reordering.requires.pages.between.1.and.1.found.2", String.valueOf(max), String.valueOf(p))); | |
198 |
2
1. reorderPages : Replaced integer subtraction with addition → NO_COVERAGE 2. reorderPages : negated conditional → NO_COVERAGE |
if (temp[p - 1]) |
199 | throw new DocumentException(MessageLocalization.getComposedMessage("page.reordering.requires.no.page.repetition.page.1.is.repeated", p)); | |
200 |
1
1. reorderPages : Replaced integer subtraction with addition → NO_COVERAGE |
temp[p - 1] = true; |
201 | } | |
202 | Object[] copy = pages.toArray(); | |
203 |
3
1. reorderPages : changed conditional boundary → NO_COVERAGE 2. reorderPages : Changed increment from 1 to -1 → NO_COVERAGE 3. reorderPages : negated conditional → NO_COVERAGE |
for (int k = 0; k < max; ++k) { |
204 |
1
1. reorderPages : Replaced integer subtraction with addition → NO_COVERAGE |
pages.set(k, copy[order[k] - 1]); |
205 | } | |
206 |
1
1. reorderPages : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return max; |
207 | } | |
208 | } | |
Mutations | ||
92 |
1.1 2.2 |
|
94 |
1.1 |
|
95 |
1.1 |
|
107 |
1.1 2.2 |
|
110 |
1.1 2.2 |
|
119 |
1.1 |
|
126 |
1.1 |
|
128 |
1.1 |
|
129 |
1.1 |
|
131 |
1.1 2.2 3.3 |
|
134 |
1.1 2.2 |
|
136 |
1.1 |
|
137 |
1.1 |
|
143 |
1.1 |
|
144 |
1.1 2.2 3.3 |
|
145 |
1.1 |
|
146 |
1.1 2.2 |
|
147 |
1.1 2.2 |
|
149 |
1.1 2.2 |
|
152 |
1.1 |
|
156 |
1.1 |
|
158 |
1.1 |
|
171 |
1.1 2.2 |
|
173 |
1.1 |
|
175 |
1.1 |
|
186 |
1.1 |
|
187 |
1.1 |
|
188 |
1.1 2.2 |
|
190 |
1.1 |
|
194 |
1.1 2.2 3.3 |
|
196 |
1.1 2.2 3.3 4.4 |
|
198 |
1.1 2.2 |
|
200 |
1.1 |
|
203 |
1.1 2.2 3.3 |
|
204 |
1.1 |
|
206 |
1.1 |