1 4 5 package com.etymon.pjx; 6 7 import java.io.*; 8 import java.util.*; 9 10 15 public final class PdfManager { 16 17 protected long _last_startxref; 18 19 22 public long getStartxref() { 23 return _last_startxref; 24 } 25 26 protected static final PdfName PDFNAME_PREV = new PdfName("Prev"); 27 28 protected static final PdfName PDFNAME_SIZE = new PdfName("Size"); 29 30 35 protected Map _modobj; 36 37 42 protected int _modsize; 43 44 47 protected PdfReader _reader; 48 49 53 public PdfReader getReader() { 54 synchronized (this) { 55 56 return _reader; 57 58 } 59 } 60 61 65 protected long _startxref; 66 67 71 protected PdfDictionary _trailer; 72 73 77 protected XrefTable _xt; 78 79 89 public PdfManager(boolean init) { 90 91 _reader = null; 92 _startxref = 0; 93 _xt = null; 94 95 _trailer = new PdfDictionary(new HashMap()); 96 97 _modsize = 1; 98 construct(); 99 100 if (init) { 101 initialize(); 102 } 103 } 104 105 112 private void initialize() { 113 114 List list; 115 Map map; 116 PdfName nameType = new PdfName("Type"); 117 118 list = new ArrayList(2); 120 list.add(new PdfName("PDF")); 121 list.add(new PdfName("Text")); 122 PdfArray procSet = new PdfArray(list); 123 int procSetId = addObject(procSet); 124 125 map = new HashMap(1); 127 map.put(new PdfName("ProcSet"), 128 new PdfReference(procSetId, 0)); 129 PdfDictionary resources = new PdfDictionary(map); 130 int resourcesId = addObject(resources); 131 132 list = new ArrayList(4); 134 list.add(new PdfInteger(0)); 135 list.add(new PdfInteger(0)); 136 list.add(new PdfInteger(612)); 137 list.add(new PdfInteger(792)); 138 PdfArray mediaBox = new PdfArray(list); 139 140 int pageId = addObject(new PdfDictionary()); 142 143 list = new ArrayList(1); 145 list.add(new PdfReference(pageId, 0)); 146 PdfArray kids = new PdfArray(list); 147 148 map = new HashMap(5); 150 map.put(nameType, new PdfName("Pages")); 151 map.put(new PdfName("Resources"), new PdfReference(resourcesId, 0)); 152 map.put(new PdfName("MediaBox"), mediaBox); 153 map.put(new PdfName("Count"), new PdfInteger(1)); 154 map.put(new PdfName("Kids"), kids); 155 int rootId = addObject(new PdfDictionary(map)); 156 157 map = new HashMap(2); 160 map.put(nameType, new PdfName("Page")); 161 map.put(new PdfName("Parent"), 162 new PdfReference(rootId, 0)); 163 PdfDictionary page = new PdfDictionary(map); 164 setObject(page, pageId); 165 166 map = new HashMap(2); 168 map.put(nameType, new PdfName("Catalog")); 169 map.put(new PdfName("Pages"), 170 new PdfReference(rootId, 0)); 171 int catalogId = addObject(new PdfDictionary(map)); 172 173 175 map = new HashMap(getTrailerDictionary().getMap()); 177 map.put(new PdfName("Root"), 178 new PdfReference(catalogId, 0)); 179 setTrailerDictionary(new PdfDictionary(map)); 180 181 } 182 183 191 public PdfManager(PdfReader pdfReader) throws IOException, PdfFormatException { 192 193 _startxref = pdfReader.readStartxref(); 194 _xt = pdfReader.readXrefTable(_startxref); 195 _trailer = _xt.getTrailerDictionary(); 196 _reader = pdfReader; 197 _modsize = _xt.size(); 198 construct(); 199 } 200 201 208 public int addObject(PdfObject obj) { 209 synchronized (this) { 210 211 int id = _modsize++; 212 213 setObject(obj, id); 214 215 return id; 216 } 217 } 218 219 228 public PdfObject getObject(int objectNumber) throws IOException, PdfFormatException { 229 synchronized (this) { 230 231 PdfObject obj = (PdfObject)_modobj.get(new Integer (objectNumber)); 233 if (obj != null) { 234 return obj; 235 } 236 237 if (_reader == null) { 239 return null; 240 } 241 if (_xt.unwrapUsageArray()[objectNumber] != XrefTable.ENTRY_IN_USE) { 242 return null; 243 } 244 long start = _xt.getIndex(objectNumber); 245 long end = _xt.estimateObjectEnd(objectNumber); 246 return _reader.readObject(start, end, true, _xt); 247 } 248 249 } 250 251 263 public PdfObject getObjectIndirect(PdfObject obj) throws IOException, PdfFormatException { 264 synchronized (this) { 265 266 if (obj == null) { 267 return null; 268 } 269 270 if (obj instanceof PdfReference) { 271 return getObjectIndirect( getObject( ((PdfReference)obj).getObjectNumber() ) ); 275 } else { 276 return obj; 277 } 278 279 } 280 } 281 282 286 public PdfDictionary getTrailerDictionary() { 287 synchronized (this) { 288 return _trailer; 289 } 290 } 291 292 298 public int getXrefTableSize() { 299 synchronized (this) { 300 return _modsize; 301 } 302 } 303 304 309 protected void construct() { 310 _modobj = new HashMap(); 311 } 312 313 322 public void setObject(PdfObject obj, int objectNumber) { 323 synchronized (this) { 324 _modobj.put(new Integer (objectNumber), obj); 325 if (objectNumber >= _modsize) { 326 _modsize = objectNumber + 1; 327 } 328 } 329 } 330 331 336 public void setTrailerDictionary(PdfDictionary dictionary) { 337 synchronized (this) { 338 _trailer = dictionary; 339 } 340 } 341 342 362 public long writeDocument(PdfWriter pdfWriter) throws IOException, PdfFormatException { 363 return writeDocument(pdfWriter, true); 364 } 365 366 393 public long writeDocument(PdfWriter pdfWriter, boolean useIncrementalUpdate) 394 throws IOException, PdfFormatException { 395 synchronized (this) { 396 397 int modsize = _modsize; 398 XrefTable xt = _xt; 399 PdfReader reader = _reader; 400 Map modobj = _modobj; 401 402 boolean incUpdate; 403 if (reader == null) { 404 incUpdate = false; 405 } else { 406 incUpdate = useIncrementalUpdate; 407 } 408 409 PdfWriter w = pdfWriter; 410 long pos = 0; 411 412 if (incUpdate) { 413 pos += w.writeCopy(reader); 414 } else { 415 pos += w.writeHeader(); 416 } 417 418 long[] nindex = new long[modsize]; 419 int[] ngeneration = new int[modsize]; 420 byte[] nusage = new byte[modsize]; 421 HashMap ntrailerMap = new HashMap(_trailer.getMap()); 424 425 long[] index = null; 426 int[] generation = null; 427 byte[] usage = null; 428 429 if (reader != null) { 430 index = xt.unwrapIndexArray(); 431 generation = xt.unwrapGenerationArray(); 432 usage = xt.unwrapUsageArray(); 433 } 434 435 int id; 436 for (Iterator it = modobj.keySet().iterator(); it.hasNext(); ) { 439 Integer key = (Integer )it.next(); 440 id = key.intValue(); 441 nusage[id] = XrefTable.ENTRY_IN_USE; 442 nindex[id] = pos; 443 PdfObject obj = (PdfObject)modobj.get(key); 444 445 if (reader == null) { 447 ngeneration[id] = 0; 448 } else { 449 if ( (id < xt.size()) && (usage[id] != XrefTable.ENTRY_UNDEFINED) ) { 450 ngeneration[id] = generation[id]; 451 } else { 452 ngeneration[id] = 0; 453 } 454 } 455 456 if ( (incUpdate) || (reader == null) ) { 457 pos += w.writeObjectIndirect(obj, id, ngeneration[id]); 458 } 459 } 460 461 ngeneration[0] = 65535; 463 nusage[0] = XrefTable.ENTRY_FREE; 464 465 if (!incUpdate) { 466 for (id = 1; id < modsize; id++) { 467 PdfObject obj = null; 468 if ( (reader != null) && (nusage[id] == XrefTable.ENTRY_UNDEFINED) ) { 469 if ( (id < xt.size()) && 470 (usage[id] != XrefTable.ENTRY_UNDEFINED) ) { 471 if (usage[id] == XrefTable.ENTRY_IN_USE) { 472 long start = index[id]; 473 long end = xt.estimateObjectEnd(id); 474 obj = reader.readObject(start, end, true, xt); 475 } 476 ngeneration[id] = generation[id]; 477 nusage[id] = usage[id]; 478 } 479 } else { 480 obj = (PdfObject)modobj.get(new Integer (id)); 481 } 482 if (nusage[id] == XrefTable.ENTRY_IN_USE) { 483 nindex[id] = pos; 484 pos += w.writeObjectIndirect(obj, id, ngeneration[id]); 485 } 486 487 } 488 } 489 490 if (incUpdate) { 491 ntrailerMap.put(PDFNAME_PREV, new PdfLong(_startxref)); 492 } else { 493 ntrailerMap.remove(PDFNAME_PREV); 494 } 495 ntrailerMap.put(PDFNAME_SIZE, new PdfInteger(modsize)); 496 497 XrefTable nxt = XrefTable.wrap(nindex, ngeneration, nusage, 498 new PdfDictionary(ntrailerMap)); 499 500 _last_startxref = pos; 501 502 pos += w.writeXrefTable(nxt, pos); 503 504 return pos; 505 } 506 } 507 508 } 509 | Popular Tags |