1 package com.etymon.pj; 2 3 import java.io.*; 4 import java.util.*; 5 import com.etymon.pj.exception.*; 6 import com.etymon.pj.object.*; 7 import com.etymon.pj.object.pagemark.*; 8 import com.etymon.pj.util.*; 9 10 14 public class Pdf { 15 16 19 public Pdf() { 20 init(); 21 createEmpty(); 22 } 23 24 30 public Pdf(String filename) throws IOException, PjException { 31 32 readFromFile(filename); 33 34 PjReference infoRef; 37 try { 38 infoRef = getInfoDictionary(); 39 } 40 catch (InvalidPdfObjectException e) { 41 infoRef = null; 42 } 43 PjInfo info; 44 if (infoRef == null) { 45 info = new PjInfo(); 47 int infoId = registerObject(info); 48 infoRef = new PjReference(new PjNumber(infoId)); 49 setInfoDictionary(infoRef); 50 } else { 51 PjDictionary d = (PjDictionary)(getObject(infoRef.getObjNumber().getInt())); 52 info = new PjInfo(d.getHashtable()); 53 } 54 info.setProducer(new PjString("")); 57 } 58 59 64 public void writeToFile(String filename) throws IOException { 65 File file = new File(filename); 66 file.delete(); 67 FileOutputStream fos = new FileOutputStream(file); 68 BufferedOutputStream bos = new BufferedOutputStream(fos); 69 writeToStream(bos); 70 bos.close(); 71 fos.close(); 72 } 73 74 79 public void writeToStream(OutputStream os) throws IOException { 80 _trailer.remove(PjName.PREV); 84 _trailer.remove(PjName.ID); 86 long z = 0; 88 z = z + PjObject.writeln(os, "%PDF-" + PjConst.PDF_VERSION); 89 z = z + PjObject.writeln(os, PjConst.VERSION_IN_PDF); 90 z = z + PjObject.writeln(os, PjConst.COPYRIGHT_IN_PDF); 94 z = z + PjObject.writeln(os, "%\323\343\317\342"); 95 PjObject obj; 96 Integer objnum; 97 int highest = 0; 98 int size = _objects.size(); 99 long[] position = new long[size]; 100 for (int x = 1; x < size; x++) { 101 if (x > highest) { 102 highest = x; 103 } 104 obj = _objects.objectAt(x); 105 position[x] = z; 106 z = z + PjObject.writeln(os, x + " 0 obj"); 107 if (obj != null) { 108 z = z + obj.writePdf(os); 109 } else { 110 z = z + PjNumber.ZERO.writePdf(os); 112 } 113 z = z + PjObject.writeln(os, ""); 114 z = z + PjObject.writeln(os, "endobj"); 115 } 116 long startxref = z; 118 z = z + PjObject.writeln(os, "xref"); 119 int p = 0; 120 int r; 121 Long g; 122 String s; 123 position[0] = -1; 124 int count = 0; 125 while (p <= highest) { 126 while ( (p <= highest) && (position[p] == 0) ) { 127 p++; 128 } 129 r = p; 130 while ( (r <= highest) && (position[r] != 0) ) { 131 r++; 132 } 133 z = z + PjObject.write(os, p + " "); 134 z = z + PjObject.writeln(os, new Integer (r - p)); 135 for (int x = p; x < r; x++) { 136 count++; 137 if (x == 0) { 138 z = z + PjObject.write(os, 139 "0000000000 65535 f \n"); 140 } else { 141 s = new Long (position[x]).toString(); 142 for (int w = 1; 143 (w + s.length()) <= 10; w++) { 144 z = z + PjObject.write(os, "0"); 145 } 146 z = z + PjObject.write(os, s); 147 z = z + PjObject.write(os, " 00000 n \n"); 148 } 149 } 150 p = r; 151 } 152 z = z + PjObject.writeln(os, "trailer"); 154 _trailer.put(new PjName("Size"), new PjNumber(count)); 155 PjDictionary trailer = new PjDictionary(_trailer); 156 z = z + trailer.writePdf(os); 157 z = z + PjObject.writeln(os, ""); 158 z = z + PjObject.writeln(os, "startxref"); 159 z = z + PjObject.writeln(os, new Long (startxref)); 160 z = z + PjObject.writeln(os, "%%EOF"); 161 } 162 163 168 public int registerObject(PjObject obj) { 169 int n = _objects.getFirstFree(); 170 _objects.setObjectAt(obj, n); 171 return n; 172 } 173 174 180 public void registerObject(PjObject obj, int objectNumber) { 181 _objects.setObjectAt(obj, objectNumber); 182 } 183 184 191 public void addToPage(PjPage page, int objectNumber) throws InvalidPdfObjectException { 192 PjReference objectToAdd = new PjReference(new PjNumber(objectNumber)); 193 PjObject contents = page.getContents(); 201 if (contents == null) { 202 page.setContents(objectToAdd); 204 } 205 else if (contents instanceof PjReference) { 206 PjObject indirectContents = 208 getObject(((PjReference)contents).getObjNumber().getInt()); 209 if (indirectContents instanceof PjArray) { 210 ((PjArray)indirectContents).getVector().addElement(objectToAdd); 212 } 213 else if (indirectContents instanceof PjStream) { 214 Vector v = new Vector(); 219 v.addElement(contents); 220 v.addElement(objectToAdd); 221 PjArray array = new PjArray(v); 222 int arrayId = registerObject(array); 224 page.setContents(new PjReference(new PjNumber(arrayId))); 226 } 227 else { 228 throw new InvalidPdfObjectException( 229 "Contents reference in page does not reference a stream or array."); 230 } 231 } 232 else if (contents instanceof PjArray) { 233 ((PjArray)contents).getVector().addElement(objectToAdd); 235 } 236 else { 237 throw new InvalidPdfObjectException("Contents object in page is not a reference or array."); 238 } 239 } 240 241 246 public PjObject getObject(int objectNumber) { 247 return _objects.objectAt(objectNumber); 248 } 249 250 255 public PjObject resolve(PjObject obj) { 256 if (obj == null) { 257 return null; 258 } else { 259 if (obj instanceof PjReference) { 260 return resolve( getObject( ((PjReference)obj).getObjNumber().getInt() ) ); 261 } else { 262 return obj; 263 } 264 } 265 } 266 267 273 public int getPageCount() throws InvalidPdfObjectException { 274 int pagesId = getRootPages(); 277 PjDictionary d; 278 try { 279 d = (PjDictionary)getObject(pagesId); 280 } 281 catch (ClassCastException e) { 282 throw new InvalidPdfObjectException("Root pages object is not a dictionary."); 283 } 284 PjPages pages = new PjPages(d.getHashtable()); 285 286 PjObject countObj = pages.getCount(); 287 PjNumber count; 288 try { 289 count = (PjNumber)(resolve(countObj)); 290 if (count.isInteger() == false) { 291 throw new ClassCastException (); 292 } 293 } 294 catch (ClassCastException e) { 295 throw new InvalidPdfObjectException("Count field in root pages object is not an integer."); 296 } 297 return count.getInt(); 298 } 299 300 private int findPage(int pageNumber, int objectNumber, PjPages parentPages, IntCounter counter, boolean delete) 301 throws InvalidPdfObjectException { 302 PjDictionary node; 303 try { 304 node = (PjDictionary)getObject(objectNumber); 305 } 306 catch (ClassCastException e) { 307 throw new InvalidPdfObjectException("Object in page tree is not a dictionary."); 308 } 309 PjName type; 311 try { 312 type = (PjName)(node.getHashtable().get(PjName.TYPE)); 313 } 314 catch (ClassCastException e) { 315 throw new InvalidPdfObjectException( 316 "Type field in dictionary in page tree is not a name object."); 317 } 318 if (type.equals(PjName.PAGES)) { 319 PjPages pages = new PjPages(node.getHashtable()); 320 PjArray kids; 321 try { 322 kids = (PjArray)(resolve((PjObject)(pages.getKids()))); 323 } 324 catch (ClassCastException e) { 325 throw new InvalidPdfObjectException("Kids field in pages object is not an array."); 326 } 327 if (kids != null) { 328 Vector v = kids.getVector(); 329 int size = v.size(); 330 PjReference nodeRef; 331 int found; 332 for (int x = 0; x < size; x++) { 333 try { 334 nodeRef = (PjReference)(v.elementAt(x)); 335 } 336 catch (ClassCastException e) { 337 throw new InvalidPdfObjectException( 338 "Object is kids array in pages object is not an indirect reference."); 339 } 340 found = findPage(pageNumber, nodeRef.getObjNumber().getInt(), 341 pages, counter, delete); 342 if (found != -1) { 343 if (delete) { 344 PjNumber count; 346 try { 347 count = (PjNumber)(resolve((PjObject)(pages.getCount()))); 348 if (count.isInteger() == false) { 349 throw new ClassCastException (); 350 } 351 } 352 catch (ClassCastException e) { 353 throw new InvalidPdfObjectException( 354 "Count field in pages object is not an integer."); 355 } 356 pages.setCount(new PjNumber(count.getInt() - 1)); 357 } 358 return found; 359 } 360 } 361 } 362 return -1; 363 } 364 if (type.equals(PjName.PAGE)) { 365 counter.inc(); 366 if (counter.value() == pageNumber) { 367 if (delete) { 368 ((PjArray)(parentPages.getKids())).getVector().removeElement( 370 new PjReference(new PjNumber(objectNumber))); 371 } 372 return objectNumber; 373 } else { 374 return -1; 375 } 376 } 377 return -1; 378 } 379 380 390 public int getPage(int pageNumber) throws IndexOutOfBoundsException , InvalidPdfObjectException { 391 if (pageNumber < 1) { 392 throw new IndexOutOfBoundsException ("Page number " + pageNumber + " is not >= 1."); 393 } 394 IntCounter counter = new IntCounter(0); 395 int found = findPage(pageNumber, getRootPages(), null, counter, false); 396 if (found == -1) { 397 if (pageNumber > getPageCount()) { 398 throw new IndexOutOfBoundsException ("Page number " + pageNumber + " is not <= " + 399 getPageCount() + "."); 400 } else { 401 throw new InvalidPdfObjectException("Page number " + pageNumber + 402 " not found; ran out of pages."); 403 } 404 } else { 405 return found; 406 } 407 } 408 409 422 public int deletePage(int pageNumber) throws IndexOutOfBoundsException , InvalidPdfObjectException { 423 if (pageNumber < 1) { 424 throw new IndexOutOfBoundsException ("Page number " + pageNumber + " is not >= 1."); 425 } 426 IntCounter counter = new IntCounter(0); 427 int found = findPage(pageNumber, getRootPages(), null, counter, true); 428 if (found == -1) { 429 if (pageNumber > getPageCount()) { 430 throw new IndexOutOfBoundsException ("Page number " + pageNumber + " is not <= " + 431 getPageCount() + "."); 432 } else { 433 throw new InvalidPdfObjectException("Page number " + pageNumber + 434 " not found; ran out of pages."); 435 } 436 } else { 437 return found; 438 } 439 } 440 441 448 public int appendPage(int objectNumber) { 449 PjReference catalogRef = (PjReference)(_trailer.get(PjName.ROOT)); 455 PjDictionary catalog = (PjDictionary)getObject(catalogRef.getObjNumber().getInt()); 456 PjReference pagesRef = (PjReference)(catalog.getHashtable().get(PjName.PAGES)); 457 PjDictionary pages = (PjDictionary)getObject(pagesRef.getObjNumber().getInt()); 458 PjArray kids = (PjArray)(pages.getHashtable().get(PjName.KIDS)); 460 if (kids == null) { 461 kids = new PjArray(); 462 pages.getHashtable().put(PjName.KIDS, kids); 463 } 464 kids.getVector().addElement( new PjReference(new PjNumber(objectNumber)) ); 465 PjPage page = (PjPage)getObject(objectNumber); 467 page.setParent(pagesRef); 468 PjObject countObj = (PjObject)(pages.getHashtable().get(PjName.COUNT)); 470 PjNumber count = (PjNumber)resolve(countObj); 471 int newCount = count.getInt() + 1; 472 pages.getHashtable().put(PjName.COUNT, new PjNumber(newCount)); 473 return newCount; 474 } 475 476 485 public void appendPdfDocument(Pdf pdf) throws InvalidPdfObjectException { 486 487 489 int otherCatalogId = pdf.getCatalog(); 493 PjCatalog otherCatalog; 494 try { 495 otherCatalog = (PjCatalog)(pdf.getObject(otherCatalogId)); 496 } 497 catch (ClassCastException e) { 498 throw new InvalidPdfObjectException("Catalog object is not a dictionary."); 499 } 500 PjDictionary otherAcroForm; 502 try { 503 otherAcroForm = (PjDictionary)(pdf.resolve(otherCatalog.getAcroForm())); 504 } 505 catch (ClassCastException e) { 506 throw new InvalidPdfObjectException("AcroForm object is not a dictionary."); 507 } 508 Vector otherFieldsV = null; 509 if (otherAcroForm != null) { 510 PjArray otherFields = (PjArray)(otherAcroForm.getHashtable().get(PjName.FIELDS)); 511 if (otherFields != null) { 512 otherFieldsV = otherFields.getVector(); 513 } 514 } 515 516 int pagesId = pdf.getRootPages(); 518 PjDictionary d; 519 try { 520 d = (PjDictionary)(pdf.getObject(pagesId)); 521 } 522 catch (ClassCastException e) { 523 throw new InvalidPdfObjectException("Root pages object is not a dictionary."); 524 } 525 PjPages pages = new PjPages(d.getHashtable()); 526 527 int pageCount = pdf.getPageCount(); 529 530 int thisPagesId = getRootPages(); 532 try { 533 d = (PjDictionary)(getObject(thisPagesId)); 534 } 535 catch (ClassCastException e) { 536 throw new InvalidPdfObjectException("Root pages object is not a dictionary."); 537 } 538 PjPages thisPages = new PjPages(d.getHashtable()); 539 540 542 int id; 545 PjObject obj; 546 int pagesIdNew = -1; 547 int size = pdf._objects.size(); 548 Hashtable map = new Hashtable(size); 549 for (int x = 1; x < size; x++) { 550 obj = pdf._objects.objectAt(x); 551 if (obj != null) { 552 id = registerObject(obj); 553 if (x == pagesId) { 555 pagesIdNew = id; 556 } 557 map.put(new PjNumber(x), 559 new PjReference(new PjNumber(id))); 560 } 561 } 562 563 for (Enumeration m = map.keys(); m.hasMoreElements();) { 566 id = ((PjReference)(map.get(m.nextElement()))).getObjNumber().getInt(); 568 obj = _objects.objectAt(id); 569 if (obj instanceof PjReference) { 570 registerObject((PjReference)(map.get(((PjReference)obj).getObjNumber())), id); 571 } else { 572 obj.renumber(map); 573 } 574 } 575 576 PjPages newPages = new PjPages(); 578 int newPagesId = registerObject(newPages); 579 Vector v = new Vector(); 580 v.addElement(new PjReference(new PjNumber(thisPagesId))); 581 v.addElement(new PjReference(new PjNumber(pagesIdNew))); 582 newPages.setKids(new PjArray(v)); 583 newPages.setCount(new PjNumber(getPageCount() + pageCount)); 584 PjReference newPagesRef = new PjReference(new PjNumber(newPagesId)); 586 thisPages.setParent(newPagesRef); 587 pages.setParent(newPagesRef); 588 589 int catalogId = getCatalog(); 591 PjCatalog catalog; 592 try { 593 catalog = (PjCatalog)(getObject(catalogId)); 594 } 595 catch (ClassCastException e) { 596 throw new InvalidPdfObjectException("Catalog object is not a dictionary."); 597 } 598 catalog.setPages(newPagesRef); 599 600 PjDictionary acroForm = (PjDictionary)(resolve(catalog.getAcroForm())); 602 if (acroForm == null) { 603 PjDictionary otherAf = (PjDictionary)(otherCatalog.getAcroForm()); 605 if (otherAcroForm != null) { 606 catalog.setAcroForm(otherAf); 607 } 608 } else { 609 PjArray fields = (PjArray)(acroForm.getHashtable().get(PjName.FIELDS)); 612 if ( (otherFieldsV != null) && (fields != null) ) { 613 Vector fieldsV = fields.getVector(); 614 int otherFieldsV_n = otherFieldsV.size(); 615 for (int x = 0; x < otherFieldsV_n; x++) { 616 fieldsV.addElement(otherFieldsV.elementAt(x)); 617 } 618 } 619 } 620 621 } 622 623 629 public int getCatalog() throws InvalidPdfObjectException { 630 PjReference catalogRef; 631 try { 632 catalogRef = (PjReference)(_trailer.get(PjName.ROOT)); 633 } 634 catch (ClassCastException e) { 635 throw new InvalidPdfObjectException("Root field in trailer is not an indirect reference."); 636 } 637 return catalogRef.getObjNumber().getInt(); 638 } 639 640 646 public int getRootPages() throws InvalidPdfObjectException { 647 int catalogId = getCatalog(); 649 PjDictionary catalog; 650 try { 651 catalog = (PjDictionary)getObject(catalogId); 652 } 653 catch (ClassCastException e) { 654 throw new InvalidPdfObjectException("Catalog is not a dictionary."); 655 } 656 PjReference pagesRef; 657 try { 658 pagesRef = (PjReference)(catalog.getHashtable().get(PjName.PAGES)); 659 } 660 catch (ClassCastException e) { 661 throw new InvalidPdfObjectException("Pages field in catalog is not an indirect reference."); 662 } 663 return pagesRef.getObjNumber().getInt(); 664 } 665 666 675 public PjReference getInfoDictionary() throws InvalidPdfObjectException { 676 PjReference r; 677 try { 678 r = (PjReference)(_trailer.get(PjName.INFO)); 679 } 680 catch (ClassCastException e) { 681 throw new InvalidPdfObjectException("Info field is not an indirect reference."); 682 } 683 return r; 684 } 685 686 690 public void setInfoDictionary(PjReference ref) { 691 _trailer.put(PjName.INFO, ref); 692 } 693 694 703 public PjDictionary getEncryptDictionary() throws InvalidPdfObjectException { 704 PjDictionary d; 705 try { 706 d = (PjDictionary)(resolve((PjObject)(_trailer.get(PjName.ENCRYPT)))); 707 } 708 catch (ClassCastException e) { 709 throw new InvalidPdfObjectException("Encrypt field is not a dictionary."); 710 } 711 return d; 712 } 713 714 718 public void setEncryptDictionary(PjReference ref) { 719 _trailer.put(PjName.ENCRYPT, ref); 720 } 721 722 726 public void setEncryptDictionary(PjDictionary dict) { 727 _trailer.put(PjName.ENCRYPT, dict); 728 } 729 730 746 public PjPagesNode inheritPageAttributes(PjPagesNode node) throws InvalidPdfObjectException { 747 PjPagesNode newNode; 748 try { 749 newNode = (PjPagesNode)(node.clone()); 750 } 751 catch (CloneNotSupportedException e) { 752 throw new InvalidPdfObjectException(e.getMessage()); 753 } 754 Hashtable ht = newNode.getHashtable(); 755 PjObject parentRef = newNode.getParent(); 756 while (parentRef != null) { 757 PjObject parentObj = resolve(parentRef); 758 if ( ! (parentObj instanceof PjPagesNode) ) { 759 throw new InvalidPdfObjectException("Ancestor of pages node is not a pages node."); 760 } 761 PjPagesNode parent = (PjPagesNode)parentObj; 762 inheritPageAttributesCollapse(PjName.MEDIABOX, ht, newNode, parent); 763 inheritPageAttributesCollapse(PjName.RESOURCES, ht, newNode, parent); 764 inheritPageAttributesCollapse(PjName.CROPBOX, ht, newNode, parent); 765 inheritPageAttributesCollapse(PjName.ROTATE, ht, newNode, parent); 766 inheritPageAttributesCollapse(PjName.DUR, ht, newNode, parent); 767 inheritPageAttributesCollapse(PjName.HID, ht, newNode, parent); 768 inheritPageAttributesCollapse(PjName.TRANS, ht, newNode, parent); 769 inheritPageAttributesCollapse(PjName.AA, ht, newNode, parent); 770 parentRef = parent.getParent(); 771 } 772 return newNode; 773 } 774 775 791 public PjDictionary inheritFieldAttributes(PjDictionary node) throws InvalidPdfObjectException { 792 PjDictionary newNode; 793 try { 794 newNode = (PjDictionary)(node.clone()); 795 } 796 catch (CloneNotSupportedException e) { 797 throw new InvalidPdfObjectException(e.getMessage()); 798 } 799 Hashtable ht = newNode.getHashtable(); 800 PjObject parentRef = (PjObject)(newNode.getHashtable().get(PjName.PARENT)); 801 while (parentRef != null) { 802 PjObject parentObj = resolve(parentRef); 803 if ( ! (parentObj instanceof PjDictionary) ) { 804 throw new InvalidPdfObjectException("Ancestor of field node is not a dictionary."); 805 } 806 PjDictionary parent = (PjDictionary)parentObj; 807 inheritFieldAttributesCollapse(PjName.FT, ht, newNode, parent); 808 inheritFieldAttributesCollapse(PjName.V, ht, newNode, parent); 809 inheritFieldAttributesCollapse(PjName.DV, ht, newNode, parent); 810 inheritFieldAttributesCollapse(PjName.FF, ht, newNode, parent); 811 inheritFieldAttributesCollapse(PjName.DR, ht, newNode, parent); 812 inheritFieldAttributesCollapse(PjName.DA, ht, newNode, parent); 813 inheritFieldAttributesCollapse(PjName.Q, ht, newNode, parent); 814 inheritFieldAttributesCollapse(PjName.OPT, ht, newNode, parent); 815 inheritFieldAttributesCollapse(PjName.TOPINDEX, ht, newNode, parent); 816 inheritFieldAttributesCollapse(PjName.MAXLEN, ht, newNode, parent); 817 parentRef = (PjObject)(parent.getHashtable().get(PjName.PARENT)); 818 } 819 return newNode; 820 } 821 822 831 public int getMaxObjectNumber() { 832 return Math.max(_objects.size() - 1, 0); 833 } 834 835 836 public Vector getFields() throws InvalidPdfObjectException { 837 838 Vector fieldList = new Vector(); 839 840 int catalogId = getCatalog(); 842 PjCatalog catalog; 843 try { 844 catalog = (PjCatalog)(getObject(catalogId)); 845 } 846 catch (ClassCastException e) { 847 throw new InvalidPdfObjectException("Catalog object is not a dictionary."); 848 } 849 850 PjDictionary acroForm; 852 try { 853 acroForm = (PjDictionary)(resolve(catalog.getAcroForm())); 854 } 855 catch (ClassCastException e) { 856 throw new InvalidPdfObjectException("AcroForm object is not a dictionary."); 857 } 858 859 if (acroForm == null) { 860 return fieldList; 861 } 862 863 866 PjArray fields = (PjArray)(acroForm.getHashtable().get(PjName.FIELDS)); 868 if (fields == null) { 869 return fieldList; 870 } 871 Vector fieldsV = fields.getVector(); 872 873 int fieldsV_n = fieldsV.size(); 875 for (int x = 0; x < fieldsV_n; x++) { 876 877 PjReference fieldRef; 879 try { 880 fieldRef = (PjReference)(fieldsV.elementAt(x)); 881 } 882 catch (ClassCastException e) { 883 throw new InvalidPdfObjectException("Fields array element is not a reference."); 884 } 885 886 getFieldsAddField(fieldList, fieldRef); 887 888 } 889 890 return fieldList; 891 892 } 893 894 895 private void getFieldsAddField(Vector fieldList, PjReference fieldRef) 896 throws InvalidPdfObjectException { 897 898 PjDictionary field; 900 try { 901 field = (PjDictionary)(resolve(fieldRef)); 902 } 903 catch (ClassCastException e) { 904 throw new InvalidPdfObjectException("Field object is not a dictionary."); 905 } 906 907 Hashtable fieldHt = field.getHashtable(); 908 909 fieldList.addElement(field); 911 912 PjArray kids; 914 try { 915 kids = (PjArray)(resolve((PjObject)(fieldHt.get(PjName.KIDS)))); 916 } 917 catch (ClassCastException e) { 918 throw new InvalidPdfObjectException("Kids object is not an array."); 919 } 920 921 if (kids != null) { 923 Vector kidsV = kids.getVector(); 924 int kidsV_n = kidsV.size(); 925 for (int x = 0; x < kidsV_n; x++) { 926 927 PjReference fieldRef2; 929 try { 930 fieldRef2 = (PjReference)(kidsV.elementAt(x)); 931 } 932 catch (ClassCastException e) { 933 throw new InvalidPdfObjectException("Kids array element is not a reference."); 934 } 935 936 getFieldsAddField(fieldList, fieldRef2); 937 938 } 939 } 940 941 } 942 943 944 public void updateFieldValue(PjDictionary origField, PjDictionary field, String value) 945 throws PdfFormatException, InvalidPdfObjectException { 946 947 Hashtable origFieldHt = origField.getHashtable(); 948 949 Hashtable fieldHt = field.getHashtable(); 950 951 PjString oldValue = (PjString)(fieldHt.get(PjName.V)); 953 954 PjString valueString = new PjString(value); 955 origFieldHt.put(PjName.V, valueString); 956 origFieldHt.put(PjName.DV, valueString); 957 958 PjNumber q = (PjNumber)(resolve((PjObject)(fieldHt.get(PjName.Q)))); 960 boolean leftJustified = false; 961 boolean centered = false; 962 boolean rightJustified = false; 963 if (q == null) { 964 leftJustified = true; 965 } else { 966 switch (q.getInt()) { 967 case 1: 968 centered = true; 969 break; 970 case 2: 971 rightJustified = true; 972 break; 973 default: 974 leftJustified = true; 975 } 976 } 977 978 PjDictionary ap = (PjDictionary)(resolve((PjObject)(fieldHt.get(PjName.AP)))); 979 if (ap != null) { 980 Hashtable apHt = ap.getHashtable(); 981 PjObject apnObj = (PjObject)(apHt.get(PjName.N)); 982 int apnId; 983 PjReference apnRef; 984 PjObject apn; 985 PjDictionary apnDict; 986 byte[] apnBuffer; 987 if (apnObj instanceof PjReference) { 988 apnRef = (PjReference)apnObj; 990 apnId = apnRef.getObjNumber().getInt(); 991 apn = resolve(apnRef); 992 } else { 993 apnId = registerObject(apnObj); 995 apnRef = new PjReference(new PjNumber(apnId)); 996 apHt.put(PjName.N, apnRef); 997 apn = apnObj; 998 } 999 1000 1006 float rectX1 = 0; 1007 float rectX2 = 0; 1008 float rectWidth = 0; 1009 if (centered) { 1010 PjRectangle rect = 1012 (PjRectangle)(fieldHt.get(PjName.RECT)); 1013 rectX1 = rect.getLowerLeftX().getFloat(); 1014 rectX2 = rect.getUpperRightX().getFloat(); 1015 rectWidth = rectX2 - rectX1; 1016 } 1017 1018 if ( (apn != null) && (apn instanceof PjStream) ) { 1019 Vector pmVector = new StreamParser().parse( 1022 ((PjStream)(apn)).flateDecompress()); 1023 if (oldValue != null) { 1024 replaceTextData(pmVector, oldValue, valueString); 1025 } 1026 if (centered) { 1027 adjustTextMatrixX(pmVector, rectWidth); 1028 } 1029 ByteArrayOutputStream baos = 1031 new ByteArrayOutputStream(); 1032 for (int pmX = 0; pmX < pmVector.size(); pmX++) { 1033 PageMark pm = (PageMark)(pmVector.elementAt(pmX)); 1034 try { 1035 pm.writePdf(baos); 1036 } 1037 catch (IOException e) { 1038 e.printStackTrace(); 1039 } 1040 } 1041 byte[] ba = baos.toByteArray(); 1042 registerObject(new PjStream(((PjStream)(apn)).getStreamDictionary(), ba), apnId); 1044 1045 } 1046 } 1047 1048 } 1049 1050 1051 private static void replaceTextData(Vector pmVector, PjString oldText, PjString newText) { 1053 1055 int pmX = pmVector.size(); 1056 1057 while (pmX > 0) { 1060 1061 pmX--; 1062 PageMark pm = (PageMark)(pmVector.elementAt(pmX)); 1063 1064 if (pm instanceof XTj) { 1065 XTj tj = (XTj)pm; 1066 if (tj.getText().equals(oldText)) { 1067 XTj newTj = new XTj(newText); 1068 pmVector.setElementAt(newTj, pmX); 1069 } 1070 } 1071 1072 } 1073 } 1074 1075 1076 private static void adjustTextMatrixX(Vector pmVector, float rectWidth) { 1078 1083 int pmX = pmVector.size(); 1084 float textWidth = 0; 1085 float rectCenter = rectWidth / 2; 1086 1087 while (pmX > 0) { 1088 1089 pmX--; 1090 PageMark pm = (PageMark)(pmVector.elementAt(pmX)); 1091 1092 if (pm instanceof XTj) { 1093 XTj tj = (XTj)pm; 1094 textWidth = tj.getText().getString().length() * 6; 1095 } 1096 1097 if (pm instanceof XTm) { 1098 float newX = rectCenter - (textWidth / 2); 1099 if (newX < 0) { 1100 newX = 0; 1101 } 1102 XTm tm = (XTm)pm; 1103 XTm newTm = new XTm( 1104 tm.getA(), 1105 tm.getB(), 1106 tm.getC(), 1107 tm.getD(), 1108 new PjNumber(newX), 1109 tm.getY()); 1110 pmVector.setElementAt(newTm, pmX); 1111 pmX = 0; } 1113 1114 } 1115 } 1116 1117 1118 private static void clearTextMatrixX(Vector pmVector) { 1120 1123 int pmX = pmVector.size(); 1124 1125 while (pmX > 0) { 1126 1127 pmX--; 1128 PageMark pm = (PageMark)(pmVector.elementAt(pmX)); 1129 1130 if (pm instanceof XTm) { 1131 XTm tm = (XTm)pm; 1132 XTm newTm = new XTm( 1133 tm.getA(), 1134 tm.getB(), 1135 tm.getC(), 1136 tm.getD(), 1137 PjNumber.ZERO, 1138 tm.getY()); 1139 pmVector.setElementAt(newTm, pmX); 1140 pmX = 0; } 1142 1143 } 1144 } 1145 1146 1147 private void inheritPageAttributesCollapse(PjName name, Hashtable ht, PjPagesNode newNode, PjPagesNode parent) { 1148 if (ht.get(name) == null) { 1149 Object obj = parent.getHashtable().get(name); 1150 if (obj != null) { 1151 ht.put(name, obj); 1152 } 1153 } 1154 } 1155 1156 1157 private void inheritFieldAttributesCollapse(PjName name, Hashtable ht, PjDictionary newNode, PjDictionary parent) { 1158 if (ht.get(name) == null) { 1159 Object obj = parent.getHashtable().get(name); 1160 if (obj != null) { 1161 ht.put(name, obj); 1162 } 1163 } 1164 } 1165 1166 1167 private void init() { 1168 _objects = new PjObjectVector(); 1169 _trailer = new Hashtable(); 1170 } 1171 1172 private void createEmpty() { 1175 Vector v = new Vector(); 1177 v.addElement(PjName.PDF); 1178 v.addElement(PjName.TEXT); 1179 PjProcSet procSet = new PjProcSet(v); 1180 int procSetId = registerObject(procSet); 1181 PjResources resources = new PjResources(); 1183 resources.setProcSet(new PjReference(new PjNumber(procSetId))); 1184 int resourcesId = registerObject(resources); 1185 PjRectangle mediaBox = new PjRectangle(); 1187 mediaBox.setLowerLeftX(PjNumber.ZERO); 1188 mediaBox.setLowerLeftY(PjNumber.ZERO); 1189 mediaBox.setUpperRightX(new PjNumber(612)); 1190 mediaBox.setUpperRightY(new PjNumber(792)); 1191 PjPage page = new PjPage(); 1193 int pageId = registerObject(page); 1194 v = new Vector(); 1196 v.addElement(new PjReference(new PjNumber(pageId))); 1197 PjArray kids = new PjArray(v); 1198 PjPages root = new PjPages(); 1200 root.setResources(new PjReference(new PjNumber(resourcesId))); 1201 root.setMediaBox(mediaBox); 1202 root.setCount(PjNumber.ONE); 1203 root.setKids(kids); 1204 int rootId = registerObject(root); 1205 page.setParent(new PjReference(new PjNumber(rootId))); 1207 PjCatalog catalog = new PjCatalog(); 1209 catalog.setPages(new PjReference(new PjNumber(rootId))); 1210 int catalogId = registerObject(catalog); 1211 _trailer.put(PjName.ROOT, new PjReference(new PjNumber(catalogId))); 1213 PjInfo info = new PjInfo(); 1215 info.setCreator(PjConst.COPYRIGHT_IN_INFO); 1216 int infoId = registerObject(info); 1218 _trailer.put(PjName.INFO, new PjReference(new PjNumber(infoId))); 1219 } 1220 1221 private void readFromFile(String filename) throws IOException, 1222 PjException { 1223 init(); 1224 RandomAccessFile raf = new RandomAccessFile(filename, 1225 "r"); 1226 try { 1227 PdfParser.getObjects(this, raf); 1228 } 1229 finally { 1230 try { 1232 raf.close(); 1233 } 1234 catch (IOException e) { 1235 } 1236 } 1237 } 1238 1239 protected PjObjectVector _objects; 1240 protected Hashtable _trailer; 1241 1242} 1243 | Popular Tags |