1 52 package com.lowagie.text.pdf; 53 54 import java.io.IOException ; 55 import java.io.OutputStream ; 56 import java.util.HashMap ; 57 import java.util.Iterator ; 58 import java.util.List ; 59 60 import com.lowagie.text.Document; 61 import com.lowagie.text.DocumentException; 62 import com.lowagie.text.ExceptionConverter; 63 64 69 70 public class PdfCopy extends PdfWriter { 71 75 static class IndirectReferences { 76 PdfIndirectReference theRef; 77 boolean hasCopied; 78 IndirectReferences(PdfIndirectReference ref) { 79 theRef = ref; 80 hasCopied = false; 81 } 82 void setCopied() { hasCopied = true; } 83 boolean getCopied() { return hasCopied; } 84 PdfIndirectReference getRef() { return theRef; } 85 }; 86 protected HashMap indirects; 87 protected HashMap indirectMap; 88 protected int currentObjectNum = 1; 89 protected PdfReader reader; 90 protected PdfIndirectReference acroForm; 91 protected List newBookmarks; 92 93 96 protected static class RefKey { 97 int num; 98 int gen; 99 RefKey(int num, int gen) { 100 this.num = num; 101 this.gen = gen; 102 } 103 RefKey(PdfIndirectReference ref) { 104 num = ref.getNumber(); 105 gen = ref.getGeneration(); 106 } 107 RefKey(PRIndirectReference ref) { 108 num = ref.getNumber(); 109 gen = ref.getGeneration(); 110 } 111 public int hashCode() { 112 return (gen<<16)+num; 113 } 114 public boolean equals(Object o) { 115 if (!(o instanceof RefKey)) return false; 116 RefKey other = (RefKey)o; 117 return this.gen == other.gen && this.num == other.num; 118 } 119 public String toString() { 120 return Integer.toString(num) + ' ' + gen; 121 } 122 } 123 124 129 public PdfCopy(Document document, OutputStream os) throws DocumentException { 130 super(new PdfDocument(), os); 131 document.addDocListener(pdf); 132 pdf.addWriter(this); 133 indirectMap = new HashMap (); 134 } 135 136 public void open() { 137 super.open(); 138 } 139 140 146 public PdfImportedPage getImportedPage(PdfReader reader, int pageNumber) { 147 if (currentPdfReaderInstance != null) { 148 if (currentPdfReaderInstance.getReader() != reader) { 149 try { 150 currentPdfReaderInstance.getReader().close(); 151 currentPdfReaderInstance.getReaderFile().close(); 152 } 153 catch (IOException ioe) { 154 } 156 currentPdfReaderInstance = reader.getPdfReaderInstance(this); 157 } 158 } 159 else { 160 currentPdfReaderInstance = reader.getPdfReaderInstance(this); 161 } 162 return currentPdfReaderInstance.getImportedPage(pageNumber); 163 } 164 165 166 175 protected PdfIndirectReference copyIndirect(PRIndirectReference in) throws IOException , BadPdfFormatException { 176 PdfIndirectReference theRef; 177 RefKey key = new RefKey(in); 178 IndirectReferences iRef = (IndirectReferences)indirects.get(key); 179 if (iRef != null) { 180 theRef = iRef.getRef(); 181 if (iRef.getCopied()) { 182 return theRef; 183 } 184 } 185 else { 186 theRef = body.getPdfIndirectReference(); 187 iRef = new IndirectReferences(theRef); 188 indirects.put(key, iRef); 189 } 190 PdfObject obj = PdfReader.getPdfObjectRelease(in); 191 if (obj != null && obj.isDictionary()) { 192 PdfName type = (PdfName)PdfReader.getPdfObjectRelease(((PdfDictionary)obj).get(PdfName.TYPE)); 193 if (type != null && PdfName.PAGE.equals(type)) { 194 return theRef; 195 } 196 } 197 iRef.setCopied(); 198 obj = copyObject(obj); 199 addToBody(obj, theRef); 200 return theRef; 201 } 202 203 207 protected PdfDictionary copyDictionary(PdfDictionary in) 208 throws IOException , BadPdfFormatException { 209 PdfDictionary out = new PdfDictionary(); 210 PdfName type = (PdfName)PdfReader.getPdfObjectRelease(in.get(PdfName.TYPE)); 211 212 for (Iterator it = in.getKeys().iterator(); it.hasNext();) { 213 PdfName key = (PdfName)it.next(); 214 PdfObject value = in.get(key); 215 if (type != null && PdfName.PAGE.equals(type)) { 217 if (!key.equals(PdfName.B) && !key.equals(PdfName.PARENT)) 218 out.put(key, copyObject(value)); 219 } 220 else 221 out.put(key, copyObject(value)); 222 } 223 return out; 224 } 225 226 229 protected PdfStream copyStream(PRStream in) throws IOException , BadPdfFormatException { 230 PRStream out = new PRStream(in, null); 231 232 for (Iterator it = in.getKeys().iterator(); it.hasNext();) { 233 PdfName key = (PdfName) it.next(); 234 PdfObject value = in.get(key); 235 out.put(key, copyObject(value)); 236 } 237 238 return out; 239 } 240 241 242 246 protected PdfArray copyArray(PdfArray in) throws IOException , BadPdfFormatException { 247 PdfArray out = new PdfArray(); 248 249 for (Iterator i = in.getArrayList().iterator(); i.hasNext();) { 250 PdfObject value = (PdfObject)i.next(); 251 out.add(copyObject(value)); 252 } 253 return out; 254 } 255 256 259 protected PdfObject copyObject(PdfObject in) throws IOException ,BadPdfFormatException { 260 if (in == null) 261 return PdfNull.PDFNULL; 262 switch (in.type) { 263 case PdfObject.DICTIONARY: 264 return copyDictionary((PdfDictionary)in); 266 case PdfObject.INDIRECT: 267 return copyIndirect((PRIndirectReference)in); 268 case PdfObject.ARRAY: 269 return copyArray((PdfArray)in); 270 case PdfObject.NUMBER: 271 case PdfObject.NAME: 272 case PdfObject.STRING: 273 case PdfObject.NULL: 274 case PdfObject.BOOLEAN: 275 return in; 276 case PdfObject.STREAM: 277 return copyStream((PRStream)in); 278 default: 280 if (in.type < 0) { 281 String lit = ((PdfLiteral)in).toString(); 282 if (lit.equals("true") || lit.equals("false")) { 283 return new PdfBoolean(lit); 284 } 285 return new PdfLiteral(lit); 286 } 287 System.out.println("CANNOT COPY type " + in.type); 288 return null; 289 } 290 } 291 292 295 protected int setFromIPage(PdfImportedPage iPage) { 296 int pageNum = iPage.getPageNumber(); 297 PdfReaderInstance inst = currentPdfReaderInstance = iPage.getPdfReaderInstance(); 298 reader = inst.getReader(); 299 setFromReader(reader); 300 return pageNum; 301 } 302 303 306 protected void setFromReader(PdfReader reader) { 307 this.reader = reader; 308 indirects = (HashMap )indirectMap.get(reader); 309 if (indirects == null) { 310 indirects = new HashMap (); 311 indirectMap.put(reader,indirects); 312 PdfDictionary catalog = reader.getCatalog(); 313 PRIndirectReference ref = null; 314 PdfObject o = catalog.get(PdfName.ACROFORM); 315 if (o == null || o.type() != PdfObject.INDIRECT) 316 return; 317 ref = (PRIndirectReference)o; 318 if (acroForm == null) acroForm = body.getPdfIndirectReference(); 319 indirects.put(new RefKey(ref), new IndirectReferences(acroForm)); 320 } 321 } 322 327 public void addPage(PdfImportedPage iPage) throws IOException , BadPdfFormatException { 328 int pageNum = setFromIPage(iPage); 329 330 PdfDictionary thePage = reader.getPageN(pageNum); 331 PRIndirectReference origRef = reader.getPageOrigRef(pageNum); 332 reader.releasePage(pageNum); 333 RefKey key = new RefKey(origRef); 334 PdfIndirectReference pageRef; 335 IndirectReferences iRef = (IndirectReferences)indirects.get(key); 336 if (iRef != null && !iRef.getCopied()) { 337 pageReferences.add(iRef.getRef()); 338 iRef.setCopied(); 339 } 340 pageRef = getCurrentPage(); 341 if (iRef == null) { 342 iRef = new IndirectReferences(pageRef); 343 indirects.put(key, iRef); 344 } 345 iRef.setCopied(); 346 PdfDictionary newPage = copyDictionary(thePage); 347 root.addPage(newPage); 348 ++currentPageNumber; 349 } 350 351 357 public void copyAcroForm(PdfReader reader) throws IOException , BadPdfFormatException { 358 setFromReader(reader); 359 360 PdfDictionary catalog = reader.getCatalog(); 361 PRIndirectReference hisRef = null; 362 PdfObject o = catalog.get(PdfName.ACROFORM); 363 if (o != null && o.type() == PdfObject.INDIRECT) 364 hisRef = (PRIndirectReference)o; 365 if (hisRef == null) return; RefKey key = new RefKey(hisRef); 367 PdfIndirectReference myRef; 368 IndirectReferences iRef = (IndirectReferences)indirects.get(key); 369 if (iRef != null) { 370 acroForm = myRef = iRef.getRef(); 371 } 372 else { 373 acroForm = myRef = body.getPdfIndirectReference(); 374 iRef = new IndirectReferences(myRef); 375 indirects.put(key, iRef); 376 } 377 if (! iRef.getCopied()) { 378 iRef.setCopied(); 379 PdfDictionary theForm = copyDictionary((PdfDictionary)PdfReader.getPdfObject(hisRef)); 380 addToBody(theForm, myRef); 381 } 382 } 383 384 388 protected PdfDictionary getCatalog(PdfIndirectReference rootObj) { 389 try { 390 PdfDictionary theCat = pdf.getCatalog(rootObj); 391 if (acroForm != null) theCat.put(PdfName.ACROFORM, acroForm); 392 if (newBookmarks == null || newBookmarks.isEmpty()) 393 return theCat; 394 PdfDictionary top = new PdfDictionary(); 395 PdfIndirectReference topRef = getPdfIndirectReference(); 396 Object kids[] = SimpleBookmark.iterateOutlines(this, topRef, newBookmarks, false); 397 top.put(PdfName.FIRST, (PdfIndirectReference)kids[0]); 398 top.put(PdfName.LAST, (PdfIndirectReference)kids[1]); 399 top.put(PdfName.COUNT, new PdfNumber(((Integer )kids[2]).intValue())); 400 addToBody(top, topRef); 401 theCat.put(PdfName.OUTLINES, topRef); 402 return theCat; 403 } 404 catch (IOException e) { 405 throw new ExceptionConverter(e); 406 } 407 } 408 409 414 public void setOutlines(List outlines) { 415 newBookmarks = outlines; 416 } 417 418 427 428 public synchronized void close() { 429 if (open) { 430 PdfReaderInstance ri = currentPdfReaderInstance; 431 pdf.close(); 432 super.close(); 433 if (ri != null) { 434 try { 435 ri.getReader().close(); 436 ri.getReaderFile().close(); 437 } 438 catch (IOException ioe) { 439 } 441 } 442 } 443 } 444 PdfIndirectReference add(PdfImage pdfImage, PdfIndirectReference fixedRef) throws PdfException { return null; } 445 public PdfIndirectReference add(PdfOutline outline) { return null; } 446 public void addAnnotation(PdfAnnotation annot) { } 447 PdfIndirectReference add(PdfPage page, PdfContents contents) throws PdfException { return null; } 448 449 public void freeReader(PdfReader reader) throws IOException { 450 indirectMap.remove(reader); 451 if (currentPdfReaderInstance != null) { 452 if (currentPdfReaderInstance.getReader() == reader) { 453 try { 454 currentPdfReaderInstance.getReader().close(); 455 currentPdfReaderInstance.getReaderFile().close(); 456 } 457 catch (IOException ioe) { 458 } 460 currentPdfReaderInstance = null; 461 } 462 } 463 } 464 } | Popular Tags |