1 50 51 package com.lowagie.text.pdf; 52 53 import java.io.IOException ; 54 import java.util.ArrayList ; 55 56 import com.lowagie.text.DocumentException; 57 import com.lowagie.text.ExceptionConverter; 58 59 69 70 public class PdfPages { 71 72 private ArrayList pages = new ArrayList (); 73 private ArrayList parents = new ArrayList (); 74 private int leafSize = 10; 75 private PdfWriter writer; 76 private PdfIndirectReference topParent; 77 78 80 83 84 PdfPages(PdfWriter writer) { 85 this.writer = writer; 86 } 87 88 void addPage(PdfDictionary page) { 89 try { 90 if ((pages.size() % leafSize) == 0) 91 parents.add(writer.getPdfIndirectReference()); 92 PdfIndirectReference parent = (PdfIndirectReference)parents.get(parents.size() - 1); 93 page.put(PdfName.PARENT, parent); 94 PdfIndirectReference current = writer.getCurrentPage(); 95 writer.addToBody(page, current); 96 pages.add(current); 97 } 98 catch (Exception e) { 99 throw new ExceptionConverter(e); 100 } 101 } 102 103 PdfIndirectReference addPageRef(PdfIndirectReference pageRef) { 104 try { 105 if ((pages.size() % leafSize) == 0) 106 parents.add(writer.getPdfIndirectReference()); 107 pages.add(pageRef); 108 return (PdfIndirectReference)parents.get(parents.size() - 1); 109 } 110 catch (Exception e) { 111 throw new ExceptionConverter(e); 112 } 113 } 114 115 PdfIndirectReference writePageTree() throws IOException { 117 if (pages.isEmpty()) 118 throw new IOException ("The document has no pages."); 119 int leaf = 1; 120 ArrayList tParents = parents; 121 ArrayList tPages = pages; 122 ArrayList nextParents = new ArrayList (); 123 while (true) { 124 leaf *= leafSize; 125 int stdCount = leafSize; 126 int rightCount = tPages.size() % leafSize; 127 if (rightCount == 0) 128 rightCount = leafSize; 129 for (int p = 0; p < tParents.size(); ++p) { 130 int count; 131 int thisLeaf = leaf; 132 if (p == tParents.size() - 1) { 133 count = rightCount; 134 thisLeaf = pages.size() % leaf; 135 if (thisLeaf == 0) 136 thisLeaf = leaf; 137 } 138 else 139 count = stdCount; 140 PdfDictionary top = new PdfDictionary(PdfName.PAGES); 141 top.put(PdfName.COUNT, new PdfNumber(thisLeaf)); 142 PdfArray kids = new PdfArray(); 143 ArrayList internal = kids.getArrayList(); 144 internal.addAll(tPages.subList(p * stdCount, p * stdCount + count)); 145 top.put(PdfName.KIDS, kids); 146 if (tParents.size() > 1) { 147 if ((p % leafSize) == 0) 148 nextParents.add(writer.getPdfIndirectReference()); 149 top.put(PdfName.PARENT, (PdfIndirectReference)nextParents.get(p / leafSize)); 150 } 151 writer.addToBody(top, (PdfIndirectReference)tParents.get(p)); 152 } 153 if (tParents.size() == 1) { 154 topParent = (PdfIndirectReference)tParents.get(0); 155 return topParent; 156 } 157 tPages = tParents; 158 tParents = nextParents; 159 nextParents = new ArrayList (); 160 } 161 } 162 163 PdfIndirectReference getTopParent() { 164 return topParent; 165 } 166 167 void setLinearMode(PdfIndirectReference topParent) { 168 if (parents.size() > 1) 169 throw new RuntimeException ("Linear page mode can only be called with a single parent."); 170 if (topParent != null) { 171 this.topParent = topParent; 172 parents.clear(); 173 parents.add(topParent); 174 } 175 leafSize = 10000000; 176 } 177 178 void addPage(PdfIndirectReference page) { 179 pages.add(page); 180 } 181 182 int reorderPages(int order[]) throws DocumentException { 183 if (order == null) 184 return pages.size(); 185 if (parents.size() > 1) 186 throw new DocumentException("Page reordering requires a single parent in the page tree. Call PdfWriter.setLinearMode() after open."); 187 if (order.length != pages.size()) 188 throw new DocumentException("Page reordering requires an array with the same size as the number of pages."); 189 int max = pages.size(); 190 boolean temp[] = new boolean[max]; 191 for (int k = 0; k < max; ++k) { 192 int p = order[k]; 193 if (p < 1 || p > max) 194 throw new DocumentException("Page reordering requires pages between 1 and " + max + ". Found " + p + "."); 195 if (temp[p - 1]) 196 throw new DocumentException("Page reordering requires no page repetition. Page " + p + " is repeated."); 197 temp[p - 1] = true; 198 } 199 Object copy[] = pages.toArray(); 200 for (int k = 0; k < max; ++k) { 201 pages.set(k, copy[order[k] - 1]); 202 } 203 return max; 204 } 205 } | Popular Tags |