1 package com.etymon.pj.tools; 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 9 18 public class PjScript { 19 20 public static void main(String [] args) { 21 22 if (args.length < 1) { 23 System.out.println("pjscript [script_file] [script_arguments]"); 24 return; 25 } 26 27 FileReader fr; 29 BufferedReader br = null; 30 try { 31 fr = new FileReader(args[0]); 32 br = new BufferedReader(fr); 33 } 34 catch (IOException e) { 35 System.out.println(new PjScriptException("No such file or directory.", 36 -1, args[0], 1).getFullMessage()); 37 Runtime.getRuntime().exit(1); 38 } 39 String [] scriptArgs = new String [args.length - 1]; 40 System.arraycopy(args, 1, scriptArgs, 0, scriptArgs.length); 41 try { 42 script(args[0], br, scriptArgs); 43 } 44 catch (PjScriptException e) { 45 System.out.println(e.getFullMessage()); 46 Runtime.getRuntime().exit(e.getErrorType()); 47 } 48 } 49 50 59 public static Pdf script(String source, BufferedReader br, String [] args) throws PjScriptException { 60 String line; 62 StringTokenizer tokenizer; 63 String command; 64 String endLine; 65 Pdf pdf = new Pdf(); 66 int lineNumber = 0; 67 boolean good; 68 Hashtable vars = new Hashtable(); 69 Vector texts = new Vector(); 70 texts.setSize(2); 71 Hashtable fonts = new Hashtable(); 72 if (args != null) { 74 for (int x = 0; x < args.length; x++) { 75 vars.put("arg" + new Integer (x).toString(), args[x]); 76 } 77 } 78 vars.put("fontsize", "10"); 79 vars.put("font", "Courier"); 80 vars.put("linewidth", "1"); 81 vars.put("mediabox", "letter-portrait"); 82 vars.put("page", "1"); 83 vars.put("xinit", "72"); 84 vars.put("x", vars.get("xinit")); 85 vars.put("x0", "0"); 86 vars.put("x1", "0"); 87 vars.put("yinit", "720"); 88 vars.put("y", vars.get("yinit")); 89 vars.put("y0", "0"); 90 vars.put("y1", "0"); 91 vars.put("ylimit", "72"); 92 do { 93 try { 95 line = br.readLine(); 96 } 97 catch (IOException e) { 98 throw new PjScriptException("I/O error reading input stream.", -1, source, 1); 99 } 100 if (line != null) { 101 lineNumber++; 102 tokenizer = new StringTokenizer(line); 104 if (tokenizer.hasMoreTokens()) { 105 command = tokenizer.nextToken(); 106 } else { 107 command = new String (); 108 } 109 endLine = getEndLine(line); 111 good = false; 113 if (command.equals("")) { 114 good = true; 115 } 116 if (command.startsWith("#")) { 117 good = true; 118 } 119 if (command.equals("newpdf")) { 120 good = true; 121 pdf = new Pdf(); 122 texts = new Vector(); 123 texts.setSize(2); 124 fonts = new Hashtable(); 125 String mediaBox = (String )(vars.get("mediabox")); 127 if (mediaBox == null) { 128 throw new PjScriptException("Media box was not specified.", lineNumber, 129 source, 3); 130 } 131 float yinit = setMediaBox(pdf, 1, mediaBox, source, lineNumber); 132 vars.put("yinit", new PjNumber(yinit).toString()); 133 vars.put("y", vars.get("yinit")); 134 } 135 if ( (command.startsWith("$")) && (command.length() > 1) ) { 136 good = true; 137 if (endLine.length() == 0) { 138 throw new PjScriptException("Missing argument.", lineNumber, source, 2); 139 } 140 String value; 141 if (endLine.charAt(0) == '\"') { 142 if (endLine.charAt(endLine.length() - 1) != '\"') { 143 throw new PjScriptException("'\"' expected.", lineNumber, 144 source, 2); 145 } 146 value = endLine.substring(1, endLine.length() - 1); 147 } else { 148 value = endLine; 149 } 150 vars.put(command.substring(1), value); 151 } 152 if ( (command.startsWith("+")) && (command.length() > 1) ) { 153 good = true; 154 if (endLine.length() == 0) { 155 throw new PjScriptException("Missing argument.", lineNumber, source, 2); 156 } 157 String value; 158 if (endLine.charAt(0) == '\"') { 159 if (endLine.charAt(endLine.length() - 1) != '\"') { 160 throw new PjScriptException("'\"' expected.", lineNumber, 161 source, 2); 162 } 163 value = endLine.substring(1, endLine.length() - 1); 164 } else { 165 value = endLine; 166 } 167 try { 168 float sum = 169 new Float ((String )(vars.get(command.substring(1)))).floatValue() 170 + new Float (value).floatValue(); 171 vars.put(command.substring(1), new PjNumber(sum).toString()); 172 } 173 catch (NumberFormatException e) { 174 throw new PjScriptException("Argument must be numeric.", 175 lineNumber, source, 2); 176 } 177 } 178 if ( (command.startsWith("=")) && (command.length() > 1) ) { 179 good = true; 180 if (endLine.length() == 0) { 181 throw new PjScriptException("Missing argument.", lineNumber, source, 2); 182 } 183 String value = (String )(vars.get(endLine)); 184 if (value == null) { 185 throw new PjScriptException("Undefined variable.", lineNumber, source, 3); 186 } 187 vars.put(command.substring(1), value); 188 } 189 if ( (command.startsWith("?")) && (command.length() > 1) ) { 190 good = true; 191 String value = (String )(vars.get(command.substring(1))); 192 if (value == null) { 193 throw new PjScriptException("Undefined variable.", lineNumber, source, 3); 194 } 195 System.out.print(value); 196 } 197 if (command.equals("dump")) { 198 good = true; 199 String key; 200 for (Enumeration m = vars.keys(); m.hasMoreElements();) { 201 key = (String )(m.nextElement()); 202 System.out.println(key + ": \"" + 203 (String )(vars.get(key)) + "\""); 204 } 205 } 206 if (command.equals("print")) { 207 good = true; 208 if ( ! quoted(endLine) ) { 209 throw new PjScriptException("'\"' expected.", lineNumber, source, 2); 210 } 211 System.out.print(endLine.substring(1, endLine.length() - 1)); 212 } 213 if (command.equals("println")) { 214 good = true; 215 if ( ! quoted(endLine) ) { 216 throw new PjScriptException("'\"' expected.", lineNumber, source, 2); 217 } 218 System.out.println(endLine.substring(1, endLine.length() - 1)); 219 } 220 if (command.equals("readpdf")) { 221 good = true; 222 String fn = (String )(vars.get("file")); 223 if (fn == null) { 224 throw new PjScriptException("File was not specified.", lineNumber, 225 source, 3); 226 } else { 227 try { 228 pdf = new Pdf(fn); 229 } 230 catch (IOException ioe) { 231 throw new PjScriptException("Unable to read PDF file.", 232 lineNumber, source, 3); 233 } 234 catch (PjException pje) { 235 throw new PjScriptException("Error parsing PDF file.", 236 lineNumber, source, 3); 237 } 238 } 239 texts = new Vector(); 240 try { 241 texts.setSize(pdf.getPageCount() + 1); 242 } 243 catch (InvalidPdfObjectException e) { 244 throw new PjScriptException("PDF error: " + e.getMessage(), 245 lineNumber, source, 3); 246 } 247 fonts = new Hashtable(); 248 } 249 if (command.equals("appendpdf")) { 250 good = true; 251 String fn = (String )(vars.get("file")); 252 if (fn == null) { 253 throw new PjScriptException("File was not specified.", lineNumber, 254 source, 3); 255 } else { 256 try { 257 Pdf other = new Pdf(fn); 258 pdf.appendPdfDocument(other); 259 } 260 catch (IOException ioe) { 261 throw new PjScriptException("Unable to read PDF file.", 262 lineNumber, source, 3); 263 } 264 catch (PjException pje) { 265 throw new PjScriptException("Error parsing PDF file.", 266 lineNumber, source, 3); 267 } 268 } 269 texts = new Vector(); 270 try { 271 texts.setSize(pdf.getPageCount() + 1); 272 } 273 catch (InvalidPdfObjectException e) { 274 throw new PjScriptException("PDF error: " + e.getMessage(), 275 lineNumber, source, 3); 276 } 277 fonts = new Hashtable(); 278 } 279 if (command.equals("appendpage")) { 280 good = true; 281 int pageNumber; 282 try { 283 pageNumber = appendPage(pdf, texts, vars); 284 } 285 catch (PjException e) { 286 throw new PjScriptException("PDF error: " + e.getMessage(), 287 lineNumber, source, 3); 288 } 289 String mediaBox = (String )(vars.get("mediabox")); 291 if (mediaBox == null) { 292 throw new PjScriptException("Media box was not specified.", lineNumber, 293 source, 3); 294 } 295 float yinit = setMediaBox(pdf, pageNumber, mediaBox, source, lineNumber); 296 vars.put("yinit", new PjNumber(yinit).toString()); 297 vars.put("y", vars.get("yinit")); 298 } 299 if (command.equals("deletepage")) { 300 good = true; 301 String page = (String )(vars.get("page")); 302 int pageCount; 303 try { 304 pageCount = pdf.getPageCount(); 305 } 306 catch (InvalidPdfObjectException e) { 307 throw new PjScriptException("PDF error: " + e.getMessage(), 308 lineNumber, source, 3); 309 } 310 if (pageCount <= 0) { 311 throw new PjScriptException("No pages to delete.", 312 lineNumber, source, 3); 313 } 314 if (pageCount == 1) { 315 throw new PjScriptException("Cannot delete the only page.", 316 lineNumber, source, 3); 317 } 318 int pageNumber = Integer.parseInt(page); 319 try { 320 pdf.deletePage(pageNumber); 321 } 322 catch (IndexOutOfBoundsException e) { 323 throw new PjScriptException("Page number out of range.", 324 lineNumber, source, 3); 325 } 326 catch (InvalidPdfObjectException pe) { 327 throw new PjScriptException("PDF error: " + pe.getMessage(), 328 lineNumber, source, 3); 329 } 330 } 331 if (command.equals("writepdf")) { 332 good = true; 333 String fn = (String )(vars.get("file")); 334 if (fn == null) { 335 throw new PjScriptException("File was not specified.", lineNumber, 336 source, 3); 337 } else { 338 drawText(pdf, source, lineNumber, fonts, texts); 340 341 if (fn.length() > 0) { 343 try { 344 pdf.writeToFile(fn); 345 } 346 catch (IOException ioe) { 347 throw new PjScriptException("Unable to write PDF file.", 348 lineNumber, source, 3); 349 } 350 } 351 } 352 } 353 if (command.equals("initxy")) { 354 good = true; 355 vars.put("x", vars.get("xinit")); 356 vars.put("y", vars.get("yinit")); 357 } 358 if (command.equals("setinfo")) { 359 good = true; 360 String key = (String )(vars.get("key")); 361 if (key == null) { 362 throw new PjScriptException("Key was not specified.", 363 lineNumber, source, 3); 364 } 365 String text = (String )(vars.get("text")); 366 if (text == null) { 367 throw new PjScriptException("Text was not specified.", 368 lineNumber, source, 3); 369 } 370 PjReference infoRef; 372 try { 373 infoRef = pdf.getInfoDictionary(); 374 } 375 catch (InvalidPdfObjectException e) { 376 throw new PjScriptException("PDF error: " + e.getMessage(), 377 lineNumber, source, 3); 378 } 379 PjInfo info; 380 if (infoRef == null) { 381 info = new PjInfo(); 383 int infoId = pdf.registerObject(info); 384 infoRef = new PjReference(new PjNumber(infoId), PjNumber.ZERO); 385 pdf.setInfoDictionary(infoRef); 386 } else { 387 PjDictionary d = 388 (PjDictionary)(pdf.getObject(infoRef.getObjNumber().getInt())); 389 info = new PjInfo(d.getHashtable()); 390 } 391 info.getHashtable().put(new PjName(key), new PjString(text)); 393 } 394 if (command.equals("getinfo")) { 395 good = true; 396 String key = (String )(vars.get("key")); 397 if (key == null) { 398 throw new PjScriptException("Key was not specified.", 399 lineNumber, source, 3); 400 } 401 PjReference infoRef; 403 try { 404 infoRef = pdf.getInfoDictionary(); 405 } 406 catch (InvalidPdfObjectException e) { 407 throw new PjScriptException("PDF error: " + e.getMessage(), 408 lineNumber, source, 3); 409 } 410 vars.put("text", ""); 412 PjInfo info; 414 if (infoRef != null) { 415 PjDictionary d; 416 try { 417 d = (PjDictionary)(pdf.getObject( 418 infoRef.getObjNumber().getInt())); 419 } 420 catch (ClassCastException e) { 421 throw new PjScriptException( 422 "PDF error: Info object is not a dictionary.", 423 lineNumber, source, 3); 424 } 425 info = new PjInfo(d.getHashtable()); 426 PjString str; 427 try { 428 str = (PjString)(info.getHashtable().get(new PjName(key))); 429 } 430 catch (ClassCastException e) { 431 throw new PjScriptException( 432 "PDF error: Field in info object is not a string.", 433 lineNumber, source, 3); 434 } 435 if (str != null) { 436 vars.put("text", str.getString()); 437 } 438 } 439 } 440 if (command.equals("nextxy")) { 441 good = true; 442 vars.put("x", vars.get("xinit")); 443 float y = new Float ((String )(vars.get("y"))).floatValue() - 444 new Float ((String )(vars.get("fontsize"))).floatValue(); 445 if (y < new Float ((String )(vars.get("ylimit"))).floatValue()) { 446 int page = Integer.parseInt((String )(vars.get("page"))); 447 int pageCount; 448 try { 449 pageCount = pdf.getPageCount(); 450 } 451 catch (InvalidPdfObjectException e) { 452 throw new PjScriptException("PDF error: " + e.getMessage(), 453 lineNumber, source, 3); 454 } 455 if (page == pageCount) { 456 int pageNumber; 457 try { 458 pageNumber = appendPage(pdf, texts, vars); 459 } 460 catch (PjException e) { 461 throw new PjScriptException("PDF error: " + e.getMessage(), 462 lineNumber, source, 3); 463 } 464 String mediaBox = (String )(vars.get("mediabox")); 466 if (mediaBox == null) { 467 throw new PjScriptException("Media box was not specified.", 468 lineNumber, 469 source, 3); 470 } 471 float yinit = setMediaBox(pdf, pageNumber, mediaBox, source, 472 lineNumber); 473 vars.put("yinit", new PjNumber(yinit).toString()); 474 } else { 475 vars.put("page", new Integer (page + 1).toString()); 476 } 477 vars.put("y", vars.get("yinit")); 478 } else { 479 vars.put("y", new PjNumber(y).toString()); 480 } 481 } 482 if (command.equals("drawtext")) { 483 good = true; 484 String text = (String )(vars.get("text")); 485 if (text == null) { 486 throw new PjScriptException("Text was not specified.", 487 lineNumber, source, 3); 488 } 489 String page = (String )(vars.get("page")); 490 String x = (String )(vars.get("x")); 491 String y = (String )(vars.get("y")); 492 String font = (String )(vars.get("font")); 493 String fontsize = (String )(vars.get("fontsize")); 494 int pageNumber = Integer.parseInt(page); 495 int pageCount; 496 try { 497 pageCount = pdf.getPageCount(); 498 } 499 catch (InvalidPdfObjectException e) { 500 throw new PjScriptException("PDF error: " + e.getMessage(), 501 lineNumber, source, 3); 502 } 503 if ( (pageNumber < 1) || (pageNumber > pageCount) ) { 504 throw new PjScriptException("Page number out of range.", 505 lineNumber, source, 3); 506 } 507 StringBuffer sb = (StringBuffer )(texts.elementAt(pageNumber)); 508 if (sb == null) { 509 sb = new StringBuffer (); 510 texts.setElementAt(sb, pageNumber); 511 } 512 sb.append("BT\n/Pj" + font + " " + fontsize + " Tf\n" + x + " " + y + 513 " Td\n" + 514 "0 Tc\n" + 515 "/DeviceGray cs\n0 sc\n" + 517 "(" + text + ") Tj\nET\n"); 518 if (fonts.get(font) == null) { 519 fonts.put(font, font); 520 } 521 } 522 if (command.equals("drawline")) { 523 good = true; 524 String page = (String )(vars.get("page")); 525 String x0 = (String )(vars.get("x0")); 526 String y0 = (String )(vars.get("y0")); 527 String x1 = (String )(vars.get("x1")); 528 String y1 = (String )(vars.get("y1")); 529 String linewidth = (String )(vars.get("linewidth")); 530 int pageNumber = Integer.parseInt(page); 531 int pageCount; 532 try { 533 pageCount = pdf.getPageCount(); 534 } 535 catch (InvalidPdfObjectException e) { 536 throw new PjScriptException("PDF error: " + e.getMessage(), 537 lineNumber, source, 3); 538 } 539 if ( (pageNumber < 1) || (pageNumber > pageCount) ) { 540 throw new PjScriptException("Page number out of range.", 541 lineNumber, source, 3); 542 } 543 StringBuffer sb = (StringBuffer )(texts.elementAt(pageNumber)); 544 if (sb == null) { 545 sb = new StringBuffer (); 546 texts.setElementAt(sb, pageNumber); 547 } 548 sb.append(linewidth + " w\n" + x0 + ' ' + y0 + " m\n" + x1 + ' ' + y1 + " l\nS\n"); 549 } 550 if (good == false) { 551 throw new PjScriptException("Unknown command.", lineNumber, source, 2); 552 } 553 } 554 } while (line != null); 555 try { 556 br.close(); 557 } 558 catch (IOException e) { 559 } 560 return pdf; 561 } 562 563 564 private static void drawText(Pdf pdf, String source, int lineNumber, Hashtable fonts, Vector texts) 565 throws PjScriptException { 566 int pageCount; 567 try { 568 pageCount = pdf.getPageCount(); 569 } 570 catch (InvalidPdfObjectException e) { 571 throw new PjScriptException("PDF error: " + e.getMessage(), 572 lineNumber, source, 3); 573 } 574 for (int x = 1; x <= pageCount; x++) { 575 StringBuffer sb = (StringBuffer )(texts.elementAt(x)); 576 if (sb != null) { 577 578 PjPage page; 579 PjResources resources; 580 try { 581 page = 582 (PjPage)(pdf.getObject(pdf.getPage(x))); 583 resources = (PjResources)(pdf.resolve( 585 page.getResources())); 586 if (resources == null) { 587 Vector v = new Vector(); 588 v.addElement(PjName.PDF); 589 v.addElement(PjName.TEXT); 590 PjProcSet procSet = new PjProcSet(v); 591 resources = new PjResources(); 592 resources.setProcSet(procSet); 593 page.setResources(resources); 594 } 595 } 596 catch (InvalidPdfObjectException e) { 597 throw new PjScriptException("PDF error: " + 598 e.getMessage(), 599 lineNumber, source, 3); 600 } 601 602 PjDictionary fontDictionary; 604 try { 605 fontDictionary = (PjDictionary)(pdf.resolve( 606 resources.getFont())); 607 } 608 catch (InvalidPdfObjectException e) { 609 throw new PjScriptException("PDF error: " + 610 e.getMessage(), 611 lineNumber, source, 3); 612 } 613 if (fontDictionary == null) { 614 fontDictionary = new PjDictionary(); 615 resources.setFont(fontDictionary); 616 } 617 Hashtable fontResHt = fontDictionary.getHashtable(); 618 for (Enumeration m = fonts.keys(); m.hasMoreElements();) { 622 String name = (String )(m.nextElement()); 623 PjFontType1 font = new PjFontType1(); 624 font.setBaseFont(new PjName(name)); 625 font.setEncoding(new PjName("WinAnsiEncoding")); 626 int fontId = pdf.registerObject(font); 627 fontResHt.put(new PjName("Pj" + name), 628 new PjReference( 629 new PjNumber(fontId))); 630 } 631 int resourcesId = pdf.registerObject(resources); 632 633 byte[] data = sb.toString().getBytes(); 635 try { 636 PjStream stream = 637 new PjStream(data).flateCompress(); 638 int streamId = pdf.registerObject(stream); 639 pdf.addToPage(page, streamId); 640 } 641 catch (InvalidPdfObjectException e) { 642 throw new PjScriptException( 643 "PDF error: " + e.getMessage(), 644 lineNumber, source, 3); 645 } 646 } 647 } 648 } 649 650 private static String getEndLine(String line) { 651 int x = 0; 652 int length = line.length(); 653 while ( (x < length) && (Character.isWhitespace(line.charAt(x)) == false) ) { 655 x++; 656 } 657 while ( (x < length) && (Character.isWhitespace(line.charAt(x)) == true) ) { 659 x++; 660 } 661 return line.substring(x, length).trim(); 662 } 663 664 private static boolean quoted(String s) { 665 int length = s.length(); 666 if (length < 2) { 667 return false; 668 } 669 return ( (s.charAt(0) == '\"') && (s.charAt(length - 1) == '\"') ); 670 } 671 672 private static int appendPage(Pdf pdf, Vector texts, Hashtable vars) throws PjException { 674 PjFontType1 font = new PjFontType1(); 676 font.setBaseFont(new PjName("Helvetica-Bold")); 677 font.setEncoding(new PjName("WinAnsiEncoding")); 678 679 PjResources resources = new PjResources(); 681 Vector procsetVector = new Vector(); 683 procsetVector.addElement(new PjName("PDF")); 684 procsetVector.addElement(new PjName("Text")); 685 resources.setProcSet(new PjProcSet(procsetVector)); 686 int resourcesId = pdf.registerObject(resources); 687 688 PjPage page = new PjPage(); 690 page.setResources( new PjReference( 691 new PjNumber(resourcesId), 692 PjNumber.ZERO ) ); 693 int pageId = pdf.registerObject(page); 694 695 pdf.appendPage(pageId); 696 int pageCount; 697 pageCount = pdf.getPageCount(); 698 texts.setSize(pageCount + 1); 699 vars.put("page", new Integer (pageCount).toString()); 700 return pageCount; 701 } 702 703 private static float setMediaBox(Pdf pdf, int pageNumber, String mediaBox, 705 String source, int lineNumber) throws PjScriptException { 706 int pageId; 707 try { 708 pageId = pdf.getPage(pageNumber); 709 } 710 catch (IndexOutOfBoundsException a) { 711 return -1; 713 } 714 catch (InvalidPdfObjectException b) { 715 throw new PjScriptException("PDF error: " + b.getMessage(), 716 lineNumber, source, 3); 717 } 718 PjPage page = (PjPage)(pdf.getObject(pageId)); 719 PjRectangle rect = getMediaBoxArray(mediaBox); 720 page.setMediaBox(rect); 721 return ((PjNumber)(rect.getVector().lastElement())).getFloat() - 72; 722 } 723 724 private static PjRectangle getMediaBoxArray(String mediaBox) { 725 Vector v = new Vector(); 726 if (mediaBox.equalsIgnoreCase("legal-portrait")) { 727 v.addElement(PjNumber.ZERO); 728 v.addElement(PjNumber.ZERO); 729 v.addElement(new PjNumber(612)); 730 v.addElement(new PjNumber(1008)); 731 return new PjRectangle(v); 732 } 733 if (mediaBox.equalsIgnoreCase("legal-landscape")) { 734 v.addElement(PjNumber.ZERO); 735 v.addElement(PjNumber.ZERO); 736 v.addElement(new PjNumber(1008)); 737 v.addElement(new PjNumber(612)); 738 return new PjRectangle(v); 739 } 740 if (mediaBox.equalsIgnoreCase("letter-landscape")) { 741 v.addElement(PjNumber.ZERO); 742 v.addElement(PjNumber.ZERO); 743 v.addElement(new PjNumber(792)); 744 v.addElement(new PjNumber(612)); 745 return new PjRectangle(v); 746 } 747 v.addElement(PjNumber.ZERO); 749 v.addElement(PjNumber.ZERO); 750 v.addElement(new PjNumber(612)); 751 v.addElement(new PjNumber(792)); 752 return new PjRectangle(v); 753 } 754 755 } 756 | Popular Tags |