| 1 12 13 package com.lowagie.text.pdf.codec.postscript; 14 15 import java.lang.*; 16 import java.lang.reflect.*; 17 import java.util.*; 18 import java.io.*; 19 import java.awt.*; 20 import java.awt.geom.*; 21 import java.awt.color.*; 22 import java.awt.font.*; 23 24 public class PAContext 25 extends Object { 26 27 public PAPencil pencil; 28 public Stack dictionaries; 29 public Stack operands; 30 public PAEngine engine; 31 PAParser poorscript = null; 32 protected Random randomNumberGenerator; 33 34 protected Object lastUnknownIdentifier; 35 36 public PAContext(Component component) { 37 this(new PAPencil(component)); 38 } 39 40 public PAContext(Graphics2D g, Dimension size) { 41 this(new PAPencil(g, size)); 42 } 43 44 public PAContext(PAPencil pencil) { 45 super(); 46 this.pencil = pencil; 47 this.dictionaries = new Stack(); 48 this.operands = new Stack(); 49 this.engine = new PAEngine(this); 50 this.dictionaries.push(this.constructSystemDict()); 51 this.dictionaries.push(this.constructGlobalDict()); 52 this.dictionaries.push(new HashMap()); 53 this.randomNumberGenerator = new Random(); 54 this.lastUnknownIdentifier = null; 55 } 56 57 public void draw(InputStream inputStream) throws PainterException { 58 try { 59 60 poorscript = new PAParser(inputStream); 61 62 poorscript.parse(this); 63 } 65 catch (ParseException e) { 66 e.printStackTrace(); 67 throw new PainterException(e.toString()); 68 } 69 } 70 71 public Object getLastUnknownIdentifier() { 72 return this.lastUnknownIdentifier; 73 } 74 75 public double[] popNumberOperands(int n) throws PainterException { 76 double[] result = new double[n]; 77 Object objectValue; 78 double doubleValue; 79 80 for (int i = n - 1; i >= 0; i--) { 81 try { 82 objectValue = this.operands.pop(); 83 } 84 catch (EmptyStackException e) { 85 throw new PainterException("Operand stack is empty"); 86 } 87 if (objectValue instanceof Number) { 88 doubleValue = ( (Number) objectValue).doubleValue(); 89 } 90 else { 91 throw new PainterException("Number expected on operand stack"); 92 } 93 result[i] = doubleValue; 94 } 95 return result; 96 } 97 98 public Object[] popOperands(int n) throws PainterException { 99 Object[] result = new Object[n]; 100 Object objectValue; 101 102 for (int i = n - 1; i >= 0; i--) { 103 try { 104 objectValue = this.operands.pop(); 105 } 106 catch (EmptyStackException e) { 107 throw new PainterException("Operand stack is empty"); 108 } 109 result[i] = objectValue; 110 } 111 return result; 112 } 113 114 public Object peekOperand() throws PainterException { 115 Object objectValue; 116 117 try { 118 objectValue = this.operands.peek(); 119 } 120 catch (EmptyStackException e) { 121 throw new PainterException("Operand stack is empty"); 122 } 123 return objectValue; 124 } 125 126 public Object findIdentifier(Object identifier) { 127 Object result = null; 128 int i, n; 129 130 n = this.dictionaries.size(); 131 i = n - 1; 132 while (i >= 0 && result == null) { 133 HashMap dictionary = (HashMap)this.dictionaries.elementAt(i); 134 result = dictionary.get(identifier); 135 i--; 136 } 137 if (result == null) { 138 this.lastUnknownIdentifier = identifier; 139 } 140 return result; 141 } 142 143 public Object findDictionary(Object identifier) { 144 Object result = null; 145 HashMap dictionary = null; 146 int i, n; 147 148 n = this.dictionaries.size(); 149 i = n - 1; 150 while (i >= 0 && result == null) { 151 dictionary = (HashMap)this.dictionaries.elementAt(i); 152 result = dictionary.get(identifier); 153 i--; 154 } 155 if (result == null) { 156 return result; 157 } 158 else { 159 return dictionary; 160 } 161 } 162 163 public void collectArray() throws PainterException { 164 ArrayList result; 165 Object objectValue; 166 int i, n; 167 boolean found = false; 168 169 n = this.operands.size(); 170 for (i = n - 1; i >= 0; i--) { 171 objectValue = this.operands.elementAt(i); 172 if (objectValue instanceof PAToken && 173 ( (PAToken) objectValue).type == PAToken.START_ARRAY) { 174 found = true; 175 break; 176 } 177 } 178 if (!found) { 179 throw new PainterException("No array was started"); 180 } 181 result = new ArrayList(n - i - 1); 182 for (int j = 0; j < n - i - 1; j++) { 183 result.add(null); 184 } 185 for (int j = n - 1; j > i; j--) { 186 try { 187 objectValue = this.operands.pop(); 188 } 189 catch (EmptyStackException e) { 190 throw new PainterException("Operand stack is empty"); 191 } 192 result.set(j - i - 1, objectValue); 193 } 194 try { 195 this.operands.pop(); } 197 catch (EmptyStackException e) { 198 throw new PainterException("Operand stack is empty"); 199 } 200 this.operands.push(result); 201 } 202 203 protected HashMap constructGlobalDict() { 204 HashMap globalDict = new HashMap(); 205 206 return globalDict; 207 } 208 209 protected HashMap constructSystemDict() { 210 HashMap systemDict = new HashMap(); 211 212 systemDict.put("newpath", new PACommand() { 214 public void execute(PAContext context) throws PainterException { 215 context.pencil.newpath(); 216 } 217 }); 218 219 systemDict.put("moveto", new PACommand() { 221 public void execute(PAContext context) throws PainterException { 222 double data[]; 223 224 data = context.popNumberOperands(2); 225 context.pencil.moveto(data[0], data[1]); 226 } 227 }); 228 229 systemDict.put("rmoveto", new PACommand() { 231 public void execute(PAContext context) throws PainterException { 232 double data[]; 233 234 data = context.popNumberOperands(2); 235 context.pencil.rmoveto(data[0], data[1]); 236 } 237 }); 238 239 systemDict.put("lineto", new PACommand() { 241 public void execute(PAContext context) throws PainterException { 242 double data[]; 243 244 data = context.popNumberOperands(2); 245 context.pencil.lineto(data[0], data[1]); 246 } 247 }); 248 249 systemDict.put("rlineto", new PACommand() { 251 public void execute(PAContext context) throws PainterException { 252 double data[]; 253 254 data = context.popNumberOperands(2); 255 context.pencil.rlineto(data[0], data[1]); 256 } 257 }); 258 259 systemDict.put("arc", new PACommand() { 261 public void execute(PAContext context) throws PainterException { 262 double data[]; 263 264 data = context.popNumberOperands(5); 265 context.pencil.arc(data[0], data[1], data[2], data[3], data[4]); 266 } 267 }); 268 269 systemDict.put("arcn", new PACommand() { 271 public void execute(PAContext context) throws PainterException { 272 double data[]; 273 274 data = context.popNumberOperands(5); 275 context.pencil.arcn(data[0], data[1], data[2], data[3], data[4]); 276 } 277 }); 278 279 systemDict.put("curveto", new PACommand() { 281 public void execute(PAContext context) throws PainterException { 282 double data[]; 283 284 data = context.popNumberOperands(6); 285 context.pencil.curveto(data[0], data[1], data[2], data[3], data[4], 286 data[5]); 287 } 288 }); 289 290 systemDict.put("rcurveto", new PACommand() { 292 public void execute(PAContext context) throws PainterException { 293 double data[]; 294 295 data = context.popNumberOperands(6); 296 context.pencil.rcurveto(data[0], data[1], data[2], data[3], data[4], 297 data[5]); 298 } 299 }); 300 301 systemDict.put("closepath", new PACommand() { 303 public void execute(PAContext context) throws PainterException { 304 context.pencil.closepath(); 305 } 306 }); 307 308 systemDict.put("gsave", new PACommand() { 310 public void execute(PAContext context) throws PainterException { 311 context.pencil.gsave(); 312 } 313 }); 314 315 systemDict.put("grestore", new PACommand() { 317 public void execute(PAContext context) throws PainterException { 318 context.pencil.grestore(); 319 } 320 }); 321 322 systemDict.put("translate", new PACommand() { 324 public void execute(PAContext context) throws PainterException { 325 if (context.peekOperand() instanceof Number) { 326 double data[]; 327 AffineTransform at = new AffineTransform(); 328 AffineTransform ctm = context.pencil.graphics.getTransform(); 329 330 data = context.popNumberOperands(2); 331 at.translate(data[0], data[1]); 332 ctm.concatenate(at); 333 context.pencil.graphics.setTransform(ctm); 334 } 335 else { 336 Object data[]; 337 338 data = context.popOperands(3); 339 if (! (data[0] instanceof Number)) { 340 throw new PainterException("wrong arguments"); 341 } 342 if (! (data[1] instanceof Number)) { 343 throw new PainterException("wrong arguments"); 344 } 345 if (! (data[2] instanceof ArrayList)) { 346 throw new PainterException("wrong arguments"); 347 } 348 349 ArrayList array = (ArrayList) data[2]; 350 351 if (! (array.size() == 6)) { 352 throw new PainterException("wrong arguments"); 353 } 354 355 AffineTransform at = new AffineTransform(); 356 357 at.translate( ( (Number) data[0]).doubleValue(), 358 ( (Number) data[1]).doubleValue()); 359 360 double[] entries = new double[6]; 361 362 at.getMatrix(entries); 363 364 for (int i = 0; i < 6; i++) { 365 array.set(i, new Double(entries[i])); 366 } 367 context.operands.push(array); 368 } 369 } 370 }); 371 372 systemDict.put("rotate", new PACommand() { 374 public void execute(PAContext context) throws PainterException { 375 if (context.peekOperand() instanceof Number) { 376 double data[]; 377 AffineTransform at = new AffineTransform(); 378 AffineTransform ctm = context.pencil.graphics.getTransform(); 379 380 data = context.popNumberOperands(1); 381 at.rotate(data[0] * Math.PI / 180.0d); 382 ctm.concatenate(at); 383 context.pencil.graphics.setTransform(ctm); 384 } 385 else { 386 Object data[]; 387 AffineTransform at = new AffineTransform(); 388 389 data = context.popOperands(2); 390 if (! (data[0] instanceof Number)) { 391 throw new PainterException("wrong arguments"); 392 } 393 if (! (data[1] instanceof ArrayList)) { 394 throw new PainterException("wrong arguments"); 395 } 396 397 ArrayList array = (ArrayList) data[1]; 398 399 if (! (array.size() == 6)) { 400 throw new PainterException("wrong arguments"); 401 } 402 403 at.rotate( ( (Number) data[0]).doubleValue()); 404 405 double[] entries = new double[6]; 406 407 at.getMatrix(entries); 408 409 for (int i = 0; i < 6; i++) { 410 array.set(i, new Double(entries[i])); 411 } 412 context.operands.push(array); 413 } 414 } 415 }); 416 417 systemDict.put("scale", new PACommand() { 419 public void execute(PAContext context) throws PainterException { 420 if (context.peekOperand() instanceof Number) { 421 double data[]; 422 AffineTransform at = new AffineTransform(); 423 AffineTransform ctm = context.pencil.graphics.getTransform(); 424 425 data = context.popNumberOperands(2); 426 at.scale(data[0], data[1]); 427 ctm.concatenate(at); 428 context.pencil.graphics.setTransform(ctm); 429 } 430 else { 431 Object data[]; 432 433 data = context.popOperands(3); 434 if (! (data[0] instanceof Number)) { 435 throw new PainterException("wrong arguments"); 436 } 437 if (! (data[1] instanceof Number)) { 438 throw new PainterException("wrong arguments"); 439 } 440 if (! (data[2] instanceof ArrayList)) { 441 throw new PainterException("wrong arguments"); 442 } 443 444 ArrayList array = (ArrayList) data[2]; 445 446 double[] entries = new double[6]; 447 448 if (! (array.size() == 6)) { 449 throw new PainterException("wrong arguments"); 450 } 451 452 entries[0] = ( (Number) data[0]).doubleValue(); 453 entries[1] = 0.0d; 454 entries[2] = 0.0d; 455 entries[3] = ( (Number) data[1]).doubleValue(); 456 entries[4] = 0.0d; 457 entries[5] = 0.0d; 458 459 for (int i = 0; i < 6; i++) { 460 array.set(i, new Double(entries[i])); 461 } 462 context.operands.push(array); 463 } 464 } 465 }); 466 467 systemDict.put("stroke", new PACommand() { 469 public void execute(PAContext context) throws PainterException { 470 context.pencil.stroke(); 471 } 472 }); 473 474 systemDict.put("fill", new PACommand() { 476 public void execute(PAContext context) throws PainterException { 477 context.pencil.fill(); 478 } 479 }); 480 481 systemDict.put("eofill", new PACommand() { 483 public void execute(PAContext context) throws PainterException { 484 context.pencil.eofill(); 485 } 486 }); 487 488 systemDict.put("show", new PACommand() { 490 public void execute(PAContext context) throws PainterException { 491 Object data[]; 492 493 data = context.popOperands(1); 494 if (! (data[0] instanceof String)) { 495 throw new PainterException("wrong arguments"); 496 } 497 context.pencil.show( (String) data[0]); 498 } 499 }); 500 501 systemDict.put("stringwidth", new PACommand() { 503 public void execute(PAContext context) throws PainterException { 504 Object data[]; 505 float[] result; 506 Font font; 507 508 data = context.popOperands(1); 509 if (! (data[0] instanceof String)) { 510 throw new PainterException("wrong arguments"); 511 } 512 font = context.pencil.graphics.getFont(); 513 Rectangle2D rect = font.getStringBounds( (String) data[0], 514 context.pencil.graphics. 515 getFontRenderContext()); 516 context.operands.push(new Float(rect.getWidth())); 517 context.operands.push(new Float(rect.getHeight())); 518 } 519 }); 520 521 systemDict.put("showpage", new PACommand() { 523 public void execute(PAContext context) throws PainterException { 524 context.pencil.showpage(); 525 } 526 }); 527 528 systemDict.put("findfont", new PACommand() { 530 public void execute(PAContext context) throws PainterException { 531 Object data[]; 532 PAToken patoken; 533 data = context.popOperands(1); 534 if (! (data[0] instanceof PAToken)) { 535 throw new PainterException("wrong arguments"); 536 } 537 patoken = (PAToken) data[0]; 538 if (! (patoken.type == PAToken.KEY)) { 539 throw new PainterException("wrong arguments"); 540 } 541 context.operands.push(context.pencil.findFont( (String) patoken.value)); 542 } 543 }); 544 545 systemDict.put("scalefont", new PACommand() { 547 public void execute(PAContext context) throws PainterException { 548 Object data[]; 549 data = context.popOperands(2); 550 if (! (data[0] instanceof Font)) { 551 throw new PainterException("wrong arguments"); 552 } 553 if (! (data[1] instanceof Number)) { 554 throw new PainterException("wrong arguments"); 555 } 556 context.operands.push( ( (Font) data[0]).deriveFont( ( (Number) data[1]). 557 floatValue())); 558 } 559 }); 560 561 systemDict.put("setfont", new PACommand() { 563 public void execute(PAContext context) throws PainterException { 564 Object data[]; 565 data = context.popOperands(1); 566 if (! (data[0] instanceof Font)) { 567 throw new PainterException("wrong arguments"); 568 } 569 context.pencil.graphics.setFont( (Font) data[0]); 570 } 571 }); 572 573 systemDict.put("def", new PACommand() { 575 public void execute(PAContext context) throws PainterException { 576 Object data[]; 577 PAToken patoken; 578 data = context.popOperands(2); 579 if (! (data[0] instanceof PAToken)) { 580 throw new PainterException("wrong arguments"); 581 } 582 patoken = (PAToken) data[0]; 583 if (! (patoken.type == PAToken.KEY)) { 584 throw new PainterException("wrong arguments"); 585 } 586 try { 587 ( (HashMap) context.dictionaries.peek()).put(patoken.value, data[1]); 588 } 589 catch (EmptyStackException e) { 590 throw new PainterException(e.toString()); 591 } 592 } 593 }); 594 595 systemDict.put("bind", new PACommand() { 597 public void execute(PAContext context) throws PainterException { 598 Object data[]; 599 PAToken patoken; 600 data = context.popOperands(1); 601 if (! (data[0] instanceof PAToken)) { 602 throw new PainterException("wrong arguments"); 603 } 604 patoken = (PAToken) data[0]; 605 if (! (patoken.type == PAToken.PROCEDURE)) { 606 throw new PainterException("wrong arguments"); 607 } 608 context.engine.bindProcedure(patoken); 609 context.operands.push(patoken); 610 } 611 }); 612 613 systemDict.put("mul", new PACommand() { 615 public void execute(PAContext context) throws PainterException { 616 double data[]; 617 618 data = context.popNumberOperands(2); 619 context.operands.push(new Double(data[0] * data[1])); 620 } 621 }); 622 623 systemDict.put("div", new PACommand() { 625 public void execute(PAContext context) throws PainterException { 626 double data[]; 627 628 data = context.popNumberOperands(2); 629 context.operands.push(new Double(data[0] / data[1])); 630 } 631 }); 632 633 systemDict.put("mod", new PACommand() { 635 public void execute(PAContext context) throws PainterException { 636 double data[]; 637 638 data = context.popNumberOperands(2); 639 int a, b, m; 640 a = (int) data[0]; 641 b = (int) data[1]; 642 m = a % b; 643 context.operands.push(new Integer(m)); 644 } 645 }); 646 647 systemDict.put("add", new PACommand() { 649 public void execute(PAContext context) throws PainterException { 650 double data[]; 651 652 data = context.popNumberOperands(2); 653 context.operands.push(new Double(data[0] + data[1])); 654 } 655 }); 656 657 systemDict.put("neg", new PACommand() { 659 public void execute(PAContext context) throws PainterException { 660 double data[]; 661 662 data = context.popNumberOperands(1); 663 context.operands.push(new Double( -data[0])); 664 } 665 }); 666 667 systemDict.put("sub", new PACommand() { 669 public void execute(PAContext context) throws PainterException { 670 double data[]; 671 672 data = context.popNumberOperands(2); 673 context.operands.push(new Double(data[0] - data[1])); 674 } 675 }); 676 677 systemDict.put("atan", new PACommand() { 679 public void execute(PAContext context) throws PainterException { 680 double data[]; 681 682 data = context.popNumberOperands(2); 683 context.operands.push(new Double(Math.atan2(data[0], data[1]))); 684 } 685 }); 686 687 systemDict.put("sin", new PACommand() { 689 public void execute(PAContext context) throws PainterException { 690 double data[]; 691 692 data = context.popNumberOperands(1); 693 context.operands.push(new Double(Math.sin(data[0] * Math.PI / 180.0))); 694 } 695 }); 696 697 systemDict.put("cos", new PACommand() { 699 public void execute(PAContext context) throws PainterException { 700 double data[]; 701 702 data = context.popNumberOperands(1); 703 context.operands.push(new Double(Math.cos(data[0] * Math.PI / 180.0))); 704 } 705 }); 706 707 systemDict.put("sqrt", new PACommand() { 709 public void execute(PAContext context) throws PainterException { 710 double data[]; 711 712 data = context.popNumberOperands(1); 713 context.operands.push(new Double(Math.sqrt(data[0]))); 714 } 715 }); 716 717 systemDict.put("exch", new PACommand() { 719 public void execute(PAContext context) throws PainterException { 720 Object data[]; 721 722 data = context.popOperands(2); 723 context.operands.push(data[1]); 724 context.operands.push(data[0]); 725 } 726 }); 727 728 systemDict.put("dup", new PACommand() { 730 public void execute(PAContext context) throws PainterException { 731 Object data[]; 732 733 data = context.popOperands(1); 734 context.operands.push(data[0]); 735 context.operands.push(data[0]); 736 } 737 }); 738 739 systemDict.put("roll", new PACommand() { 741 public void execute(PAContext context) throws PainterException { 742 Object data[]; 743 Object rollData[]; 744 745 data = context.popOperands(2); 746 if (! (data[0] instanceof Number)) { 747 throw new PainterException("wrong arguments"); 748 } 749 if (! (data[1] instanceof Number)) { 750 throw new PainterException("wrong arguments"); 751 } 752 int numberOfElements, numberOfPositions, i; 753 754 numberOfElements = ( (Number) data[0]).intValue(); 755 numberOfPositions = ( (Number) data[1]).intValue(); 756 757 if (numberOfPositions == 0 || numberOfElements <= 0) { 758 return; 759 } 760 761 rollData = context.popOperands(numberOfElements); 762 763 if (numberOfPositions < 0) { 764 numberOfPositions = -numberOfPositions; 765 numberOfPositions = numberOfPositions % numberOfElements; 766 767 for (i = numberOfPositions; i < numberOfElements; i++) { 769 context.operands.push(rollData[i]); 770 } 771 for (i = 0; i < numberOfPositions; i++) { 772 context.operands.push(rollData[i]); 773 } 774 } 775 else { 776 numberOfPositions = numberOfPositions % numberOfElements; 777 778 for (i = numberOfElements - numberOfPositions; i < numberOfElements; 780 i++) { 781 context.operands.push(rollData[i]); 782 } 783 for (i = 0; i < numberOfElements - numberOfPositions; i++) { 784 context.operands.push(rollData[i]); 785 } 786 } 787 } 788 }); 789 790 systemDict.put("pop", new PACommand() { 792 public void execute(PAContext context) throws PainterException { 793 context.popOperands(1); 794 } 795 }); 796 797 systemDict.put("index", new PACommand() { 799 public void execute(PAContext context) throws PainterException { 800 Object data[]; 801 data = context.popOperands(1); 802 if (! (data[0] instanceof Number)) { 803 throw new PainterException("wrong arguments"); 804
|