1 package com.etymon.pjx.util; 2 3 import java.io.*; 4 import java.util.*; 5 import com.etymon.pj.*; 6 import com.etymon.pj.exception.*; 7 import com.etymon.pj.object.*; 8 import com.etymon.pj.object.pagemark.*; 9 import com.etymon.pjx.*; 10 11 17 public class PdfModifier { 18 19 27 public int getPageCount() throws IOException, com.etymon.pjx.PdfFormatException { 28 return new PdfPageTree(_m).getNumberOfPages(); 29 } 30 31 35 protected static final PdfName PDFNAME_ACROFORM = new PdfName("AcroForm"); 36 37 41 protected static final PdfName PDFNAME_FIELDS = new PdfName("Fields"); 42 43 47 protected static final PdfName PDFNAME_KIDS = new PdfName("Kids"); 48 49 53 protected static final PdfName PDFNAME_PAGES = new PdfName("Pages"); 54 55 59 protected static final PdfName PDFNAME_ROOT = new PdfName("Root"); 60 61 64 protected PdfManager _m; 65 66 70 public PdfModifier(PdfManager manager) { 71 72 _m = manager; 73 74 } 75 76 82 public PdfReference getCatalogReference() throws com.etymon.pjx.PdfFormatException { 83 synchronized (this) { 84 85 PdfDictionary trailer = _m.getTrailerDictionary(); 86 87 Map map = trailer.getMap(); 88 89 Object root = map.get(PdfModifier.PDFNAME_ROOT); 90 91 if ( !(root instanceof PdfReference) ) { 92 throw new com.etymon.pjx.PdfFormatException("Catalog dictionary is not an indirect reference."); 93 } 94 95 return (PdfReference)root; 96 } 97 } 98 99 106 public PdfDictionary getCatalog() throws IOException, com.etymon.pjx.PdfFormatException { 107 synchronized (this) { 108 109 PdfReference catalogRef = getCatalogReference(); 110 111 if (catalogRef == null) { 112 return null; 113 } 114 115 Object catalog = _m.getObjectIndirect(catalogRef); 116 117 if ( !(catalog instanceof PdfDictionary) ) { 118 throw new com.etymon.pjx.PdfFormatException("Catalog is not a dictionary."); 119 } 120 121 return (PdfDictionary)catalog; 122 } 123 } 124 125 132 public void setCatalog(PdfDictionary catalog) throws com.etymon.pjx.PdfFormatException { 133 synchronized (this) { 134 135 PdfReference catalogRef = getCatalogReference(); 136 137 if (catalogRef != null) { 138 139 _m.setObject(catalog, catalogRef.getObjectNumber()); 140 141 } else { 142 143 int catalogId = _m.addObject(catalog); 145 146 149 PdfDictionary trailer = _m.getTrailerDictionary(); 150 151 Map map = trailer.getMap(); 152 153 HashMap h = new HashMap(map.size()); 154 h.putAll(map); 155 156 h.put(PdfModifier.PDFNAME_ROOT, 157 new PdfReference(catalogId, 0) ); 158 159 _m.setTrailerDictionary(new PdfDictionary(h)); 160 } 161 162 } 163 } 164 165 174 public PdfReference getPageTreeRootReference() throws IOException, com.etymon.pjx.PdfFormatException { 175 synchronized (this) { 176 177 PdfDictionary catalog = getCatalog(); 178 179 Map map = catalog.getMap(); 180 181 Object pages = map.get(PdfModifier.PDFNAME_PAGES); 182 183 if ( !(pages instanceof PdfReference) ) { 184 throw new com.etymon.pjx.PdfFormatException("Page tree root (Pages) is not an indirect reference."); 185 } 186 187 return (PdfReference)pages; 188 } 189 } 190 191 198 public PdfDictionary getPageTreeRoot() throws IOException, com.etymon.pjx.PdfFormatException { 199 synchronized (this) { 200 201 PdfReference pageTreeRootRef = getPageTreeRootReference(); 202 203 if (pageTreeRootRef == null) { 204 return null; 205 } 206 207 Object pageTreeRoot = _m.getObjectIndirect(pageTreeRootRef); 208 209 if ( !(pageTreeRoot instanceof PdfDictionary) ) { 210 throw new com.etymon.pjx.PdfFormatException("Page tree root is not a dictionary."); 211 } 212 213 return (PdfDictionary)pageTreeRoot; 214 } 215 } 216 217 226 public void setPageTreeRoot(PdfDictionary pageTreeRoot) throws IOException, com.etymon.pjx.PdfFormatException { 227 synchronized (this) { 228 229 PdfReference pageTreeRootRef = getPageTreeRootReference(); 230 231 if (pageTreeRootRef != null) { 232 233 _m.setObject(pageTreeRoot, pageTreeRootRef.getObjectNumber()); 234 235 } else { 236 237 int pageTreeRootId = _m.addObject(pageTreeRoot); 239 240 242 PdfDictionary catalog = getCatalog(); 243 244 Map map = catalog.getMap(); 245 246 HashMap h = new HashMap(map.size()); 247 h.putAll(map); 248 249 h.put(PdfModifier.PDFNAME_PAGES, 250 new PdfReference(pageTreeRootId, 0) ); 251 252 setCatalog(new PdfDictionary(h)); 253 } 254 255 } 256 } 257 258 261 private void getFieldsAddField(ArrayList fieldList, PdfReference fieldRef) 262 throws IOException, com.etymon.pjx.PdfFormatException { 263 264 PdfDictionary field; 266 try { 267 field = (PdfDictionary)(_m.getObjectIndirect(fieldRef)); 268 } 269 catch (ClassCastException e) { 270 throw new com.etymon.pjx.PdfFormatException("Field object is not a dictionary."); 271 } 272 273 Map fieldHt = field.getMap(); 274 275 fieldList.add(field); 277 278 PdfArray kids; 280 try { 281 kids = (PdfArray)(_m.getObjectIndirect((PdfObject)(fieldHt.get(PDFNAME_KIDS)))); 282 } 283 catch (ClassCastException e) { 284 throw new com.etymon.pjx.PdfFormatException("Kids object is not an array."); 285 } 286 287 if (kids != null) { 289 List kidsV = kids.getList(); 290 int kidsV_n = kidsV.size(); 291 for (int x = 0; x < kidsV_n; x++) { 292 293 PdfReference fieldRef2; 295 try { 296 fieldRef2 = (PdfReference)(kidsV.get(x)); 297 } 298 catch (ClassCastException e) { 299 throw new com.etymon.pjx.PdfFormatException("Kids array element is not a reference."); 300 } 301 302 getFieldsAddField(fieldList, fieldRef2); 303 304 } 305 } 306 307 } 308 309 315 public PdfDictionary pjUpdateFieldValue(PdfDictionary origField, PdfDictionary field, String value) 316 throws IOException, com.etymon.pjx.PdfFormatException { 317 318 synchronized (this) { 319 320 try { 321 322 Map origFieldHt = new HashMap(origField.getMap()); 323 324 Map fieldHt = field.getMap(); 325 326 PdfString oldValue = (PdfString)(fieldHt.get(new PdfName("V"))); 328 329 PdfString valueString = new PdfString(value); 330 origFieldHt.put(new PdfName("V"), valueString); 331 origFieldHt.put(new PdfName("DV"), valueString); 332 333 PdfInteger q = (PdfInteger)(_m.getObjectIndirect((PdfObject)(fieldHt.get(new PdfName("Q"))))); 335 boolean leftJustified = false; 336 boolean centered = false; 337 boolean rightJustified = false; 338 if (q == null) { 339 leftJustified = true; 340 } else { 341 switch (q.getInt()) { 342 case 1: 343 centered = true; 344 break; 345 case 2: 346 rightJustified = true; 347 break; 348 default: 349 leftJustified = true; 350 } 351 } 352 353 PdfDictionary ap = 354 (PdfDictionary)(_m.getObjectIndirect((PdfObject)(fieldHt.get(new PdfName("AP"))))); 355 Map apHt; 356 if (ap == null) { 357 apHt = null; 358 } else { 359 apHt = new HashMap(ap.getMap()); 360 PdfObject apnObj = (PdfObject)(apHt.get(new PdfName("N"))); 361 int apnId; 362 PdfReference apnRef; 363 PdfObject apn; 364 PdfDictionary apnDict; 365 byte[] apnBuffer; 366 if (apnObj instanceof PdfReference) { 367 apnRef = (PdfReference)apnObj; 369 apnId = apnRef.getObjectNumber(); 370 apn = _m.getObjectIndirect(apnRef); 371 } else { 372 apnId = _m.addObject(apnObj); 374 apnRef = new PdfReference(apnId, 0); 375 apHt.put(new PdfName("N"), apnRef); 376 apn = apnObj; 377 } 378 379 385 float rectX1 = 0; 386 float rectX2 = 0; 387 float rectWidth = 0; 388 if (centered) { 389 PdfArray rect = 391 (PdfArray)(fieldHt.get(new PdfName("Rect"))); 392 List rectList = rect.getList(); 393 rectX1 = ((PdfNumber)rectList.get(0)).getFloat(); 394 rectX2 = ((PdfNumber)rectList.get(2)).getFloat(); 395 rectWidth = rectX2 - rectX1; 396 } 397 398 if ( (apn != null) && (apn instanceof PdfStream) ) { 399 PjStream apnPj = (PjStream)PjxConvert.toPjObject(apn); 402 Vector pmVector = new StreamParser().parse( 403 apnPj.flateDecompress()); 404 if (oldValue != null) { 405 replaceTextData(pmVector, oldValue, valueString); 406 } 407 if (centered) { 408 adjustTextMatrixX(pmVector, rectWidth); 409 } 410 ByteArrayOutputStream baos = 412 new ByteArrayOutputStream(); 413 for (int pmX = 0; pmX < pmVector.size(); pmX++) { 414 PageMark pm = (PageMark)(pmVector.elementAt(pmX)); 415 try { 416 pm.writePdf(baos); 417 } 418 catch (IOException e) { 419 e.printStackTrace(); 420 } 421 } 422 byte[] ba = baos.toByteArray(); 423 PjStream temp = new PjStream( apnPj.getStreamDictionary(), ba ); 424 _m.setObject(PjxConvert.toPjxObject(temp), apnId); 425 } 426 } 427 428 if (apHt != null) { 429 origFieldHt.put(new PdfName("AP"), new PdfDictionary(apHt)); 430 } 431 432 return new PdfDictionary(origFieldHt); 433 434 } 435 catch (com.etymon.pj.exception.PdfFormatException e) { 436 throw new com.etymon.pjx.PdfFormatException(e.getMessage()); 437 } 438 catch (com.etymon.pj.exception.InvalidPdfObjectException f) { 439 throw new com.etymon.pjx.PdfFormatException(f.getMessage()); 440 } 441 } 442 } 443 444 448 private static void replaceTextData(Vector pmVector, PdfString oldText, PdfString newText) 449 throws com.etymon.pj.exception.PdfFormatException { 450 451 453 int pmX = pmVector.size(); 454 455 PjString oldTextPj = (PjString)PjxConvert.toPjObject(oldText); 456 PjString newTextPj = (PjString)PjxConvert.toPjObject(newText); 457 458 while (pmX > 0) { 461 462 pmX--; 463 PageMark pm = (PageMark)(pmVector.elementAt(pmX)); 464 465 if (pm instanceof XTj) { 466 XTj tj = (XTj)pm; 467 if (tj.getText().equals(oldTextPj)) { 468 XTj newTj = new XTj(newTextPj); 469 pmVector.setElementAt(newTj, pmX); 470 } 471 } 472 473 } 474 } 475 476 480 private static void adjustTextMatrixX(Vector pmVector, float rectWidth) { 481 486 int pmX = pmVector.size(); 487 float textWidth = 0; 488 float rectCenter = rectWidth / 2; 489 490 while (pmX > 0) { 491 492 pmX--; 493 PageMark pm = (PageMark)(pmVector.elementAt(pmX)); 494 495 if (pm instanceof XTj) { 496 XTj tj = (XTj)pm; 497 textWidth = tj.getText().getString().length() * 6; 498 } 499 500 if (pm instanceof XTm) { 501 float newX = rectCenter - (textWidth / 2); 502 if (newX < 0) { 503 newX = 0; 504 } 505 XTm tm = (XTm)pm; 506 XTm newTm = new XTm( 507 tm.getA(), 508 tm.getB(), 509 tm.getC(), 510 tm.getD(), 511 new PjNumber(newX), 512 tm.getY()); 513 pmVector.setElementAt(newTm, pmX); 514 pmX = 0; } 516 517 } 518 } 519 520 524 private static void clearTextMatrixX(Vector pmVector) { 525 528 int pmX = pmVector.size(); 529 530 while (pmX > 0) { 531 532 pmX--; 533 PageMark pm = (PageMark)(pmVector.elementAt(pmX)); 534 535 if (pm instanceof XTm) { 536 XTm tm = (XTm)pm; 537 XTm newTm = new XTm( 538 tm.getA(), 539 tm.getB(), 540 tm.getC(), 541 tm.getD(), 542 PjNumber.ZERO, 543 tm.getY()); 544 pmVector.setElementAt(newTm, pmX); 545 pmX = 0; } 547 548 } 549 } 550 551 555 private void inheritFieldAttributesCollapse(PjName name, Hashtable ht, PjDictionary newNode, PjDictionary parent) { 556 if (ht.get(name) == null) { 557 Object obj = parent.getHashtable().get(name); 558 if (obj != null) { 559 ht.put(name, obj); 560 } 561 } 562 } 563 564 } 565 | Popular Tags |