KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > lowagie > text > pdf > codec > postscript > PAContext


1 /*
2  * Copyright 1998 by Sun Microsystems, Inc.,
3  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
4  * All rights reserved.
5  *
6  * This software is the confidential and proprietary information
7  * of Sun Microsystems, Inc. ("Confidential Information"). You
8  * shall not disclose such Confidential Information and shall use
9  * it only in accordance with the terms of the license agreement
10  * you entered into with Sun.
11  */

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      // pencil.graphics.dispose();
64
}
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(); // the start array mark itself
196
}
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     // newpath
213
systemDict.put("newpath", new PACommand() {
214       public void execute(PAContext context) throws PainterException {
215         context.pencil.newpath();
216       }
217     });
218
219     // moveto
220
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     // rmoveto
230
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     // lineto
240
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     // rlineto
250
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     // arc
260
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     // arcn
270
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     // curveto
280
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     // rcurveto
291
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     // closepath
302
systemDict.put("closepath", new PACommand() {
303       public void execute(PAContext context) throws PainterException {
304         context.pencil.closepath();
305       }
306     });
307
308     // gsave
309
systemDict.put("gsave", new PACommand() {
310       public void execute(PAContext context) throws PainterException {
311         context.pencil.gsave();
312       }
313     });
314
315     // grestore
316
systemDict.put("grestore", new PACommand() {
317       public void execute(PAContext context) throws PainterException {
318         context.pencil.grestore();
319       }
320     });
321
322     // translate
323
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     // rotate
373
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     // scale
418
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     // stroke
468
systemDict.put("stroke", new PACommand() {
469       public void execute(PAContext context) throws PainterException {
470         context.pencil.stroke();
471       }
472     });
473
474     // fill
475
systemDict.put("fill", new PACommand() {
476       public void execute(PAContext context) throws PainterException {
477         context.pencil.fill();
478       }
479     });
480
481     // eofill
482
systemDict.put("eofill", new PACommand() {
483       public void execute(PAContext context) throws PainterException {
484         context.pencil.eofill();
485       }
486     });
487
488     // show
489
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     // stringwidth
502
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     // showpage
522
systemDict.put("showpage", new PACommand() {
523       public void execute(PAContext context) throws PainterException {
524         context.pencil.showpage();
525       }
526     });
527
528     // findfont
529
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     // scalefont
546
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     // setfont
562
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     // def
574
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     // bind
596
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     // mul
614
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     // div
624
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     // mod
634
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     // add
648
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     // neg
658
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     // sub
668
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     // atan
678
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     // sin
688
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     // cos
698
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     // sqrt
708
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     // exch
718
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     // dup
729
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     // roll
740
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           // downward roll
768
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           // upward roll
779
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     // pop
791
systemDict.put("pop", new PACommand() {
792       public void execute(PAContext context) throws PainterException {
793         context.popOperands(1);
794       }
795     });
796
797     // index
798
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         }
805         int index = ( (Number) data[0]).intValue();
806         try {
807           context.operands.push(context.operands.elementAt(index));
808         }
809         catch (ArrayIndexOutOfBoundsException e) {
810           throw new PainterException(e.toString());
811         }
812       }
813     });
814
815     // mark
816
systemDict.put("mark", new PACommand() {
817       public void execute(PAContext context) throws PainterException {
818         context.operands.push(new PAToken(null, PAToken.MARK));
819       }
820     });
821
822     // cleartomark
823
systemDict.put("cleartomark", new PACommand() {
824       public void execute(PAContext context) throws PainterException {
825         Object data;
826         boolean finished = false;
827
828         while (!finished) {
829           try {
830             data = context.operands.pop();
831             if (data instanceof PAToken) {
832               if ( ( (PAToken) data).type == PAToken.MARK) {
833                 finished = true;
834               }
835             }
836           }
837           catch (EmptyStackException e) {
838             throw new PainterException(e.toString());
839           }
840         }
841       }
842     });
843
844     // copy
845
systemDict.put("copy", new PACommand() {
846       public void execute(PAContext context) throws PainterException {
847         Object data[];
848         data = context.popOperands(2);
849
850         // decide if it's a simple copy or a composite object copy
851
if ( (data[0] instanceof PAToken) && (data[1] instanceof PAToken)) {
852           // composite object copy
853
if ( ( (PAToken) data[0]).type == ( (PAToken) data[1]).type) {
854             // our tokens are immutable so a copy is easy
855
context.operands.push(data[0]);
856             context.operands.push(data[0]);
857           }
858           else {
859             throw new PainterException(
860                 "copy operation failed because composite objects on stack are not of same type");
861           }
862         }
863         else {
864           // restore first arg, we're not interested in it in this simple case
865
context.operands.push(data[0]);
866
867           if (data[1] instanceof Number) {
868             int index = ( (Number) data[1]).intValue();
869             int i, n;
870             n = context.operands.size();
871             Object[] copyData = new Object[index];
872             for (i = n - index; i < n; i++) {
873               try {
874                 copyData[i - n + index] = context.operands.elementAt(i);
875               }
876               catch (ArrayIndexOutOfBoundsException e) {
877                 throw new PainterException(e.toString());
878               }
879             }
880             for (i = 0; i < index; i++) {
881               context.operands.push(copyData[i]);
882             }
883           }
884           else {
885             throw new PainterException("I expect a number on stack, dude");
886           }
887         }
888       }
889     });
890
891     // setgray
892
systemDict.put("setgray", new PACommand() {
893       public void execute(PAContext context) throws PainterException {
894         double data[];
895
896         data = context.popNumberOperands(1);
897         context.pencil.graphics.setPaint(new Color( (float) data[0],
898             (float) data[0], (float) data[0]));
899       }
900     });
901
902     // setrgbcolor
903
systemDict.put("setrgbcolor", new PACommand() {
904       public void execute(PAContext context) throws PainterException {
905         double data[];
906
907         data = context.popNumberOperands(3);
908         float[] fv = new float[3];
909         fv[0] = (float) Math.max(Math.min(data[0], 1.0d), 0.0d);
910         fv[1] = (float) Math.max(Math.min(data[1], 1.0d), 0.0d);
911         fv[2] = (float) Math.max(Math.min(data[2], 1.0d), 0.0d);
912         context.pencil.graphics.setPaint(new Color(fv[0], fv[1], fv[2]));
913       }
914     });
915
916     // PENDING(uweh): color stuff still shaky
917
// sethsbcolor
918
systemDict.put("sethsbcolor", new PACommand() {
919       public void execute(PAContext context) throws PainterException {
920         double data[];
921
922         data = context.popNumberOperands(3);
923         float[] fv = new float[3];
924         fv[0] = (float) Math.max(Math.min(data[0], 1.0d), 0.0d);
925         fv[1] = (float) Math.max(Math.min(data[1], 1.0d), 0.0d);
926         fv[2] = (float) Math.max(Math.min(data[2], 1.0d), 0.0d);
927         context.pencil.graphics.setPaint(new Color(fv[0], fv[1], fv[2]));
928       }
929     });
930
931     // PENDING(uweh): I have to convert these puppies myself to rgb ?
932
// setcmybcolor
933
systemDict.put("setcmybcolor", new PACommand() {
934       public void execute(PAContext context) throws PainterException {
935         double data[];
936         int rd, gr, bl;
937
938         data = context.popNumberOperands(4);
939         float[] fv = new float[4];
940         fv[0] = (float) data[0];
941         fv[1] = (float) data[1];
942         fv[2] = (float) data[2];
943         fv[3] = (float) data[3];
944         rd = (int) (255 * Math.max(0, 1 - fv[0] - fv[3]));
945         gr = (int) (255 * Math.max(0, 1 - fv[1] - fv[3]));
946         bl = (int) (255 * Math.max(0, 1 - fv[2] - fv[3]));
947         context.pencil.graphics.setPaint(new Color(rd, gr, bl));
948       }
949     });
950
951     // setlinewidth
952
systemDict.put("setlinewidth", new PACommand() {
953       private double minLineWidth(double w, AffineTransform at) {
954         double matrix[] = new double[4];
955         at.getMatrix(matrix);
956         double scale = matrix[0] * matrix[3] - matrix[1] * matrix[2];
957         double minlw = .25 / Math.sqrt(Math.abs(scale));
958         if (w < minlw) {
959           w = minlw;
960         }
961         return w;
962       }
963
964       public void execute(PAContext context) throws PainterException {
965         double data[];
966         BasicStroke newStroke;
967         Stroke oldStroke = context.pencil.graphics.getStroke();
968         data = context.popNumberOperands(1);
969         data[0] = this.minLineWidth(data[0],
970                                     context.pencil.graphics.getTransform());
971         if (oldStroke instanceof BasicStroke) {
972           newStroke = new BasicStroke( (float) data[0],
973                                       ( (BasicStroke) oldStroke).getEndCap(),
974                                       ( (BasicStroke) oldStroke).getLineJoin(),
975                                       ( (BasicStroke) oldStroke).getMiterLimit(),
976                                       ( (BasicStroke) oldStroke).getDashArray(),
977                                       ( (BasicStroke) oldStroke).getDashPhase());
978         }
979         else {
980           newStroke = new BasicStroke( (float) data[0], BasicStroke.CAP_ROUND,
981                                       BasicStroke.JOIN_ROUND);
982         }
983         context.pencil.graphics.setStroke(newStroke);
984       }
985     });
986
987     // setlinecap
988
systemDict.put("setlinecap", new PACommand() {
989       public void execute(PAContext context) throws PainterException {
990         double data[];
991         BasicStroke newStroke;
992         Stroke oldStroke = context.pencil.graphics.getStroke();
993         data = context.popNumberOperands(1);
994         if (oldStroke instanceof BasicStroke) {
995           newStroke = new BasicStroke( ( (BasicStroke) oldStroke).getLineWidth(),
996                                       (int) data[0],
997                                       ( (BasicStroke) oldStroke).getLineJoin(),
998                                       ( (BasicStroke) oldStroke).getMiterLimit(),
999                                       ( (BasicStroke) oldStroke).getDashArray(),
1000                                      ( (BasicStroke) oldStroke).getDashPhase());
1001        }
1002        else {
1003          newStroke = new BasicStroke(1.0f, (int) data[0],
1004                                      BasicStroke.JOIN_ROUND);
1005        }
1006        context.pencil.graphics.setStroke(newStroke);
1007      }
1008    });
1009
1010    // setmiterlimit
1011
systemDict.put("setmiterlimit", new PACommand() {
1012      public void execute(PAContext context) throws PainterException {
1013        double data[];
1014        BasicStroke newStroke;
1015        Stroke oldStroke = context.pencil.graphics.getStroke();
1016        data = context.popNumberOperands(1);
1017        if (oldStroke instanceof BasicStroke) {
1018          newStroke = new BasicStroke( ( (BasicStroke) oldStroke).getLineWidth(),
1019                                      ( (BasicStroke) oldStroke).getEndCap(),
1020                                      ( (BasicStroke) oldStroke).getLineJoin(),
1021                                      (float) data[0],
1022                                      ( (BasicStroke) oldStroke).getDashArray(),
1023                                      ( (BasicStroke) oldStroke).getDashPhase());
1024        }
1025        else {
1026          newStroke = new BasicStroke(1.0f, BasicStroke.CAP_ROUND,
1027                                      BasicStroke.JOIN_ROUND, (float) data[0]);
1028        }
1029        context.pencil.graphics.setStroke(newStroke);
1030      }
1031    });
1032
1033    // setdash
1034
systemDict.put("setdash", new PACommand() {
1035      public void execute(PAContext context) throws PainterException {
1036        Object data[];
1037        BasicStroke newStroke;
1038        Stroke oldStroke = context.pencil.graphics.getStroke();
1039        data = context.popOperands(2);
1040        if (! (data[0] instanceof ArrayList)) {
1041          throw new PainterException("wrong arguments");
1042        }
1043        if (! (data[1] instanceof Number)) {
1044          throw new PainterException("wrong arguments");
1045        }
1046
1047        ArrayList list = (ArrayList) data[0];
1048
1049        if (list.size() == 0) {
1050          return;
1051        }
1052        float[] dashpattern = new float[list.size()];
1053        for (int i = 0; i < dashpattern.length; i++) {
1054          dashpattern[i] = ( (Number) list.get(i)).floatValue();
1055        }
1056        float dashoffset = ( (Number) data[1]).floatValue();
1057        if (oldStroke instanceof BasicStroke) {
1058          newStroke = new BasicStroke( ( (BasicStroke) oldStroke).getLineWidth(),
1059                                      ( (BasicStroke) oldStroke).getEndCap(),
1060                                      ( (BasicStroke) oldStroke).getLineJoin(),
1061                                      ( (BasicStroke) oldStroke).getMiterLimit(),
1062                                      dashpattern,
1063                                      dashoffset);
1064        }
1065        else {
1066          newStroke = new BasicStroke(1.0f, BasicStroke.CAP_ROUND,
1067                                      BasicStroke.JOIN_ROUND, 1.0f, dashpattern,
1068                                      dashoffset);
1069        }
1070        context.pencil.graphics.setStroke(newStroke);
1071      }
1072    });
1073
1074    // setlinejoin
1075
systemDict.put("setlinejoin", new PACommand() {
1076      public void execute(PAContext context) throws PainterException {
1077        double data[];
1078        BasicStroke newStroke;
1079        Stroke oldStroke = context.pencil.graphics.getStroke();
1080        data = context.popNumberOperands(1);
1081        if (oldStroke instanceof BasicStroke) {
1082          newStroke = new BasicStroke( ( (BasicStroke) oldStroke).getLineWidth(),
1083                                      ( (BasicStroke) oldStroke).getEndCap(),
1084                                      (int) data[0],
1085                                      ( (BasicStroke) oldStroke).getMiterLimit(),
1086                                      ( (BasicStroke) oldStroke).getDashArray(),
1087                                      ( (BasicStroke) oldStroke).getDashPhase());
1088        }
1089        else {
1090          newStroke = new BasicStroke(1.0f, BasicStroke.CAP_ROUND, (int) data[0]);
1091        }
1092        context.pencil.graphics.setStroke(newStroke);
1093      }
1094    });
1095
1096    // dumpstack
1097
systemDict.put("dumpstack", new PACommand() {
1098      public void execute(PAContext context) throws PainterException {
1099        Enumeration enumx = context.operands.elements();
1100        System.out.println("-------------Stack--------------");
1101        while (enumx.hasMoreElements()) {
1102          System.out.println(enumx.nextElement());
1103        }
1104        System.out.println("--------------------------------");
1105      }
1106    });
1107
1108    // for
1109
systemDict.put("for", new PACommand() {
1110      public void execute(PAContext context) throws PainterException {
1111        Object data[];
1112        PAToken patoken;
1113
1114        data = context.popOperands(4);
1115        if (! (data[3] instanceof PAToken)) {
1116          throw new PainterException("wrong arguments");
1117        }
1118        if (! (data[0] instanceof Number)) {
1119          throw new PainterException("wrong arguments");
1120        }
1121        if (! (data[1] instanceof Number)) {
1122          throw new PainterException("wrong arguments");
1123        }
1124        if (! (data[2] instanceof Number)) {
1125          throw new PainterException("wrong arguments");
1126        }
1127        patoken = (PAToken) data[3];
1128        if (! (patoken.type == PAToken.PROCEDURE)) {
1129          throw new PainterException("wrong arguments");
1130        }
1131        int i0, i1, i2;
1132        i0 = ( (Number) data[0]).intValue();
1133        i1 = ( (Number) data[1]).intValue();
1134        i2 = ( (Number) data[2]).intValue();
1135
1136        if (i1 > 0) {
1137          for (int i = i0; i <= i2; i += i1) {
1138            context.operands.push(new Integer(i));
1139            context.engine.process(patoken);
1140          }
1141        }
1142        else {
1143          for (int i = i0; i >= i2; i -= i1) {
1144            context.operands.push(new Integer(i));
1145            context.engine.process(patoken);
1146          }
1147        }
1148      }
1149    });
1150
1151    // repeat
1152
systemDict.put("repeat", new PACommand() {
1153      public void execute(PAContext context) throws PainterException {
1154        Object data[];
1155        PAToken patoken;
1156        data = context.popOperands(2);
1157        if (! (data[1] instanceof PAToken)) {
1158          throw new PainterException("wrong arguments");
1159        }
1160        if (! (data[0] instanceof Number)) {
1161          throw new PainterException("wrong arguments");
1162        }
1163        patoken = (PAToken) data[1];
1164        if (! (patoken.type == PAToken.PROCEDURE)) {
1165          throw new PainterException("wrong arguments");
1166        }
1167        int n = ( (Number) data[0]).intValue();
1168        for (int i = 0; i < n; i++) {
1169          context.engine.process(patoken);
1170        }
1171      }
1172    });
1173
1174    // true
1175
systemDict.put("true", new PACommand() {
1176      public void execute(PAContext context) throws PainterException {
1177        context.operands.push(new Boolean(true));
1178      }
1179    });
1180
1181    // false
1182
systemDict.put("false", new PACommand() {
1183      public void execute(PAContext context) throws PainterException {
1184        context.operands.push(new Boolean(false));
1185      }
1186    });
1187
1188    // lt
1189
systemDict.put("lt", new PACommand() {
1190      public void execute(PAContext context) throws PainterException {
1191        Object data[];
1192
1193        data = context.popOperands(2);
1194        if (! (data[0] instanceof Number) && ! (data[0] instanceof String)) {
1195          throw new PainterException("wrong arguments");
1196        }
1197        if (data[0] instanceof Number) {
1198          if (! (data[1] instanceof Number)) {
1199            throw new PainterException("wrong arguments");
1200          }
1201          double d0, d1;
1202          d0 = ( (Number) data[0]).doubleValue();
1203          d1 = ( (Number) data[1]).doubleValue();
1204          if (d0 < d1) {
1205            context.operands.push(new Boolean(true));
1206          }
1207          else {
1208            context.operands.push(new Boolean(false));
1209          }
1210        }
1211        else {
1212          if (! (data[1] instanceof String)) {
1213            throw new PainterException("wrong arguments");
1214          }
1215          String s0, s1;
1216          s0 = (String) data[0];
1217          s1 = (String) data[1];
1218          if (s0.compareTo(s1) < 0) {
1219            context.operands.push(new Boolean(true));
1220          }
1221          else {
1222            context.operands.push(new Boolean(false));
1223          }
1224        }
1225      }
1226    });
1227
1228    // gt
1229
systemDict.put("gt", new PACommand() {
1230      public void execute(PAContext context) throws PainterException {
1231        Object data[];
1232
1233        data = context.popOperands(2);
1234        if (! (data[0] instanceof Number) && ! (data[0] instanceof String)) {
1235          throw new PainterException("wrong arguments");
1236        }
1237        if (data[0] instanceof Number) {
1238          if (! (data[1] instanceof Number)) {
1239            throw new PainterException("wrong arguments");
1240          }
1241          double d0, d1;
1242          d0 = ( (Number) data[0]).doubleValue();
1243          d1 = ( (Number) data[1]).doubleValue();
1244          if (d0 > d1) {
1245            context.operands.push(new Boolean(true));
1246          }
1247          else {
1248            context.operands.push(new Boolean(false));
1249          }
1250        }
1251        else {
1252          if (! (data[1] instanceof String)) {
1253            throw new PainterException("wrong arguments");
1254          }
1255          String s0, s1;
1256          s0 = (String) data[0];
1257          s1 = (String) data[1];
1258          if (s0.compareTo(s1) > 0) {
1259            context.operands.push(new Boolean(true));
1260          }
1261          else {
1262            context.operands.push(new Boolean(false));
1263          }
1264        }
1265      }
1266    });
1267
1268    // ne
1269
systemDict.put("ne", new PACommand() {
1270      public void execute(PAContext context) throws PainterException {
1271        Object data[];
1272
1273        data = context.popOperands(2);
1274        if (! (data[0] instanceof Number) && ! (data[0] instanceof String)) {
1275          throw new PainterException("wrong arguments");
1276        }
1277        if (data[0] instanceof Number) {
1278          if (! (data[1] instanceof Number)) {
1279            throw new PainterException("wrong arguments");
1280          }
1281          double d0, d1;
1282          d0 = ( (Number) data[0]).doubleValue();
1283          d1 = ( (Number) data[1]).doubleValue();
1284          if (d0 != d1) {
1285            context.operands.push(new Boolean(true));
1286          }
1287          else {
1288            context.operands.push(new Boolean(false));
1289          }
1290        }
1291        else {
1292          if (! (data[1] instanceof String)) {
1293            throw new PainterException("wrong arguments");
1294          }
1295          String s0, s1;
1296          s0 = (String) data[0];
1297          s1 = (String) data[1];
1298          if (s0.equals(s1)) {
1299            context.operands.push(new Boolean(false));
1300          }
1301          else {
1302            context.operands.push(new Boolean(true));
1303          }
1304        }
1305      }
1306    });
1307
1308    // eq
1309
systemDict.put("eq", new PACommand() {
1310      public void execute(PAContext context) throws PainterException {
1311        Object data[];
1312
1313        data = context.popOperands(2);
1314        if (! (data[0] instanceof Number) && ! (data[0] instanceof String)) {
1315          throw new PainterException("wrong arguments");
1316        }
1317        if (data[0] instanceof Number) {
1318          if (! (data[1] instanceof Number)) {
1319            throw new PainterException("wrong arguments");
1320          }
1321          double d0, d1;
1322          d0 = ( (Number) data[0]).doubleValue();
1323          d1 = ( (Number) data[1]).doubleValue();
1324          if (d0 == d1) {
1325            context.operands.push(new Boolean(true));
1326          }
1327          else {
1328            context.operands.push(new Boolean(false));
1329          }
1330        }
1331        else {
1332          if (! (data[1] instanceof String)) {
1333            throw new PainterException("wrong arguments");
1334          }
1335          String s0, s1;
1336          s0 = (String) data[0];
1337          s1 = (String) data[1];
1338          if (s0.compareTo(s1) == 0) {
1339            context.operands.push(new Boolean(true));
1340          }
1341          else {
1342            context.operands.push(new Boolean(false));
1343          }
1344        }
1345      }
1346    });
1347
1348    // if
1349
systemDict.put("if", new PACommand() {
1350      public void execute(PAContext context) throws PainterException {
1351        Object data[];
1352        PAToken patoken;
1353        data = context.popOperands(2);
1354        if (! (data[0] instanceof Boolean)) {
1355          throw new PainterException("wrong arguments");
1356        }
1357        if (! (data[1] instanceof PAToken)) {
1358          throw new PainterException("wrong arguments");
1359        }
1360        patoken = (PAToken) data[1];
1361        if (! (patoken.type == PAToken.PROCEDURE)) {
1362          throw new PainterException("wrong arguments");
1363        }
1364        if ( ( (Boolean) data[0]).booleanValue()) {
1365          context.engine.process(patoken);
1366        }
1367      }
1368    });
1369
1370    // ifelse
1371
systemDict.put("ifelse", new PACommand() {
1372      public void execute(PAContext context) throws PainterException {
1373        Object data[];
1374        PAToken patoken1, patoken2;
1375        data = context.popOperands(3);
1376        if (! (data[0] instanceof Boolean)) {
1377          throw new PainterException("wrong arguments");
1378        }
1379        if (! (data[1] instanceof PAToken)) {
1380          throw new PainterException("wrong arguments");
1381        }
1382        if (! (data[2] instanceof PAToken)) {
1383          throw new PainterException("wrong arguments");
1384        }
1385        patoken1 = (PAToken) data[1];
1386        patoken2 = (PAToken) data[2];
1387        if (! (patoken1.type == PAToken.PROCEDURE)) {
1388          throw new PainterException("wrong arguments");
1389        }
1390        if (! (patoken2.type == PAToken.PROCEDURE)) {
1391          throw new PainterException("wrong arguments");
1392        }
1393        if ( ( (Boolean) data[0]).booleanValue()) {
1394          context.engine.process(patoken1);
1395        }
1396        else {
1397          context.engine.process(patoken2);
1398        }
1399      }
1400    });
1401
1402    // dict
1403
systemDict.put("dict", new PACommand() {
1404      public void execute(PAContext context) throws PainterException {
1405        double data[];
1406
1407        data = context.popNumberOperands(1);
1408        context.operands.push(new HashMap());
1409      }
1410    });
1411
1412    // userdict
1413
systemDict.put("userdict", new PACommand() {
1414      public void execute(PAContext context) throws PainterException {
1415        double data[];
1416
1417        data = context.popNumberOperands(1);
1418        context.operands.push(new HashMap());
1419      }
1420    });
1421    // put
1422
systemDict.put("put", new PACommand() {
1423      public void execute(PAContext context) throws PainterException {
1424        Object data[];
1425        PAToken patoken;
1426        data = context.popOperands(3);
1427        if (! (data[0] instanceof HashMap)) {
1428          throw new PainterException("wrong arguments");
1429        }
1430        if (! (data[1] instanceof PAToken)) {
1431          throw new PainterException("wrong arguments");
1432        }
1433        patoken = (PAToken) data[1];
1434        if (! (patoken.type == PAToken.KEY)) {
1435          throw new PainterException("wrong arguments");
1436        }
1437        ( (HashMap) data[0]).put(patoken.value, data[2]);
1438      }
1439    });
1440
1441    // get
1442
systemDict.put("get", new PACommand() {
1443      public void execute(PAContext context) throws PainterException {
1444        Object data[];
1445        PAToken patoken;
1446        data = context.popOperands(2);
1447        if (! (data[0] instanceof HashMap) && ! (data[0] instanceof ArrayList)) {
1448          throw new PainterException("wrong arguments");
1449        }
1450        if (data[0] instanceof HashMap) {
1451          if (! (data[1] instanceof PAToken)) {
1452            throw new PainterException("wrong arguments");
1453          }
1454          patoken = (PAToken) data[1];
1455          if (! (patoken.type == PAToken.KEY)) {
1456            throw new PainterException("wrong arguments");
1457          }
1458          context.operands.push( ( (HashMap) data[0]).get(patoken.value));
1459        }
1460        else if (data[0] instanceof ArrayList) {
1461          if (! (data[1] instanceof Number)) {
1462            throw new PainterException("wrong arguments");
1463          }
1464          context.operands.push( ( (ArrayList) data[0]).get( ( (Number) data[1]).
1465              intValue()));
1466        }
1467      }
1468    });
1469
1470    // load
1471
systemDict.put("load", new PACommand() {
1472      public void execute(PAContext context) throws PainterException {
1473        Object data[];
1474        PAToken patoken;
1475        data = context.popOperands(1);
1476        if (! (data[0] instanceof PAToken)) {
1477          throw new PainterException("wrong arguments");
1478        }
1479        patoken = (PAToken) data[0];
1480        if (! (patoken.type == PAToken.KEY)) {
1481          throw new PainterException("wrong arguments");
1482        }
1483        context.operands.push(context.findIdentifier(patoken.value));
1484      }
1485    });
1486
1487    // length
1488
systemDict.put("length", new PACommand() {
1489      public void execute(PAContext context) throws PainterException {
1490        Object data[];
1491        PAToken patoken;
1492        int size = 0;
1493        data = context.popOperands(1);
1494        if (data[0] instanceof PAToken) {
1495          patoken = (PAToken) data[0];
1496          if (! (patoken.type == PAToken.KEY)) {
1497            throw new PainterException("wrong arguments");
1498          }
1499          size = ( (String) patoken.value).length();
1500        }
1501        else if (data[0] instanceof HashMap) {
1502          size = ( (HashMap) data[0]).size();
1503        }
1504        else if (data[0] instanceof ArrayList) {
1505          size = ( (ArrayList) data[0]).size();
1506        }
1507        else if (data[0] instanceof String) {
1508          size = ( (String) data[0]).length();
1509        }
1510        else {
1511          throw new PainterException("wrong arguments");
1512        }
1513
1514        context.operands.push(new Integer(size));
1515      }
1516    });
1517
1518    // begin
1519
systemDict.put("begin", new PACommand() {
1520      public void execute(PAContext context) throws PainterException {
1521        Object data[];
1522        data = context.popOperands(1);
1523        if (! (data[0] instanceof HashMap)) {
1524          throw new PainterException("wrong arguments");
1525        }
1526        context.dictionaries.push(data[0]);
1527      }
1528    });
1529
1530    // end
1531
systemDict.put("end", new PACommand() {
1532      public void execute(PAContext context) throws PainterException {
1533        try {
1534          context.dictionaries.pop();
1535        }
1536        catch (EmptyStackException e) {
1537          throw new PainterException("Dictionary stack is empty");
1538        }
1539      }
1540    });
1541
1542    // undef
1543
systemDict.put("undef", new PACommand() {
1544      public void execute(PAContext context) throws PainterException {
1545        Object data[];
1546        PAToken patoken;
1547        data = context.popOperands(2);
1548        if (! (data[0] instanceof HashMap)) {
1549          throw new PainterException("wrong arguments");
1550        }
1551        if (! (data[1] instanceof PAToken)) {
1552          throw new PainterException("wrong arguments");
1553        }
1554        patoken = (PAToken) data[1];
1555        if (! (patoken.type == PAToken.KEY)) {
1556          throw new PainterException("wrong arguments");
1557        }
1558        // we don't do an actual undef because we don't care
1559
}
1560    });
1561
1562    // known
1563
systemDict.put("known", new PACommand() {
1564      public void execute(PAContext context) throws PainterException {
1565        Object data[], foundObject;
1566        PAToken patoken;
1567        data = context.popOperands(1);
1568        if (! (data[0] instanceof PAToken)) {
1569          throw new PainterException("wrong arguments");
1570        }
1571        patoken = (PAToken) data[0];
1572        if (! (patoken.type == PAToken.KEY)) {
1573          throw new PainterException("wrong arguments");
1574        }
1575        foundObject = context.findIdentifier(patoken.value);
1576        if (foundObject != null) {
1577          context.operands.push(new Boolean(true));
1578        }
1579        else {
1580          context.operands.push(new Boolean(false));
1581        }
1582      }
1583    });
1584
1585    // where
1586
systemDict.put("where", new PACommand() {
1587      public void execute(PAContext context) throws PainterException {
1588        Object data[], foundObject;
1589        PAToken patoken;
1590        data = context.popOperands(1);
1591        if (! (data[0] instanceof PAToken)) {
1592          throw new PainterException("wrong arguments");
1593        }
1594        patoken = (PAToken) data[0];
1595        if (! (patoken.type == PAToken.KEY)) {
1596          throw new PainterException("wrong arguments");
1597        }
1598        foundObject = context.findDictionary(patoken.value);
1599        if (foundObject != null) {
1600          context.operands.push(foundObject);
1601          context.operands.push(new Boolean(true));
1602        }
1603        else {
1604          context.operands.push(new Boolean(false));
1605        }
1606      }
1607    });
1608
1609    // aload
1610
systemDict.put("aload", new PACommand() {
1611      public void execute(PAContext context) throws PainterException {
1612        Object data[];
1613        ArrayList list;
1614        data = context.popOperands(1);
1615        if (! (data[0] instanceof ArrayList)) {
1616          throw new PainterException("wrong arguments");
1617        }
1618        list = (ArrayList) data[0];
1619        Iterator iterator = list.iterator();
1620        while (iterator.hasNext()) {
1621          context.operands.push(iterator.next());
1622        }
1623        context.operands.push(data[0]);
1624      }
1625    });
1626
1627    // forall
1628
systemDict.put("forall", new PACommand() {
1629      public void execute(PAContext context) throws PainterException {
1630        Object data[];
1631        ArrayList list;
1632        PAToken patoken;
1633
1634        data = context.popOperands(2);
1635        if (! (data[0] instanceof ArrayList)) {
1636          throw new PainterException("wrong arguments");
1637        }
1638        if (! (data[1] instanceof PAToken)) {
1639          throw new PainterException("wrong arguments");
1640        }
1641
1642        patoken = (PAToken) data[1];
1643        if (! (patoken.type == PAToken.PROCEDURE)) {
1644          throw new PainterException("wrong arguments");
1645        }
1646
1647        list = (ArrayList) data[0];
1648        Iterator iterator = list.iterator();
1649        while (iterator.hasNext()) {
1650          context.operands.push(iterator.next());
1651          context.engine.process(patoken);
1652        }
1653
1654      }
1655    });
1656
1657    // currentflat PENDING(uweh):placeholder for now
1658
systemDict.put("currentflat", new PACommand() {
1659      public void execute(PAContext context) throws PainterException {
1660        context.operands.push(new Float(1.0f));
1661      }
1662    });
1663
1664    // setflat PENDING(uweh):placeholder for now
1665
systemDict.put("setflat", new PACommand() {
1666      public void execute(PAContext context) throws PainterException {
1667        double data[];
1668
1669        data = context.popNumberOperands(1);
1670      }
1671    });
1672
1673    // round
1674
systemDict.put("round", new PACommand() {
1675      public void execute(PAContext context) throws PainterException {
1676        double data[];
1677
1678        data = context.popNumberOperands(1);
1679        context.operands.push(new Long(Math.round(data[0])));
1680      }
1681    });
1682
1683    // abs
1684
systemDict.put("abs", new PACommand() {
1685      public void execute(PAContext context) throws PainterException {
1686        double data[];
1687
1688        data = context.popNumberOperands(1);
1689        context.operands.push(new Double(Math.abs(data[0])));
1690      }
1691    });
1692
1693    // transform
1694
systemDict.put("transform", new PACommand() {
1695      public void execute(PAContext context) throws PainterException {
1696        if (context.peekOperand() instanceof Number) {
1697          double data[];
1698          double[] transformedData = new double[2];
1699          data = context.popNumberOperands(2);
1700          AffineTransform at = context.pencil.graphics.getTransform();
1701          at.transform(data, 0, transformedData, 0, 1);
1702          context.operands.push(new Double(transformedData[0]));
1703          context.operands.push(new Double(transformedData[1]));
1704        }
1705        else {
1706          Object data[];
1707
1708          data = context.popOperands(3);
1709          if (! (data[0] instanceof Number)) {
1710            throw new PainterException("wrong arguments");
1711          }
1712          if (! (data[1] instanceof Number)) {
1713            throw new PainterException("wrong arguments");
1714          }
1715          if (! (data[2] instanceof ArrayList)) {
1716            throw new PainterException("wrong arguments");
1717          }
1718
1719          ArrayList array = (ArrayList) data[2];
1720
1721          double[] entries = new double[6];
1722
1723          if (! (array.size() == 6)) {
1724            throw new PainterException("wrong arguments");
1725          }
1726
1727          for (int i = 0; i < 6; i++) {
1728            entries[i] = ( (Number) array.get(i)).doubleValue();
1729          }
1730
1731          AffineTransform at = new AffineTransform(entries);
1732
1733          double numberdata[] = new double[2];
1734          numberdata[0] = ( (Number) data[0]).doubleValue();
1735          numberdata[1] = ( (Number) data[0]).doubleValue();
1736
1737          double[] transformedData = new double[2];
1738
1739          at.transform(numberdata, 0, transformedData, 0, 1);
1740          context.operands.push(new Double(transformedData[0]));
1741          context.operands.push(new Double(transformedData[1]));
1742        }
1743      }
1744    });
1745
1746    // itransform
1747
systemDict.put("itransform", new PACommand() {
1748      public void execute(PAContext context) throws PainterException {
1749        if (context.peekOperand() instanceof Number) {
1750          double data[];
1751          double[] transformedData = new double[2];
1752          data = context.popNumberOperands(2);
1753          AffineTransform at = context.pencil.graphics.getTransform();
1754          try {
1755            at.inverseTransform(data, 0, transformedData, 0, 1);
1756          }
1757          catch (NoninvertibleTransformException e) {
1758            throw new PainterException(e.toString());
1759          }
1760          context.operands.push(new Double(transformedData[0]));
1761          context.operands.push(new Double(transformedData[1]));
1762        }
1763        else {
1764          Object data[];
1765
1766          data = context.popOperands(3);
1767          if (! (data[0] instanceof Number)) {
1768            throw new PainterException("wrong arguments");
1769          }
1770          if (! (data[1] instanceof Number)) {
1771            throw new PainterException("wrong arguments");
1772          }
1773          if (! (data[2] instanceof ArrayList)) {
1774            throw new PainterException("wrong arguments");
1775          }
1776
1777          ArrayList array = (ArrayList) data[2];
1778
1779          double[] entries = new double[6];
1780
1781          if (! (array.size() == 6)) {
1782            throw new PainterException("wrong arguments");
1783          }
1784
1785          for (int i = 0; i < 6; i++) {
1786            entries[i] = ( (Number) array.get(i)).doubleValue();
1787          }
1788
1789          AffineTransform at = new AffineTransform(entries);
1790
1791          double numberdata[] = new double[2];
1792          numberdata[0] = ( (Number) data[0]).doubleValue();
1793          numberdata[1] = ( (Number) data[0]).doubleValue();
1794
1795          double[] transformedData = new double[2];
1796
1797          try {
1798            at.inverseTransform(numberdata, 0, transformedData, 0, 1);
1799          }
1800          catch (NoninvertibleTransformException e) {
1801            throw new PainterException(e.toString());
1802          }
1803          context.operands.push(new Double(transformedData[0]));
1804          context.operands.push(new Double(transformedData[1]));
1805        }
1806      }
1807    });
1808
1809    // currentpoint
1810
// PENDING(uweh): what about CTM, same thing when you construct path
1811
// this is different than ps, might not work in a few instances
1812
systemDict.put("currentpoint", new PACommand() {
1813      public void execute(PAContext context) throws PainterException {
1814        Point2D currentPoint = context.pencil.state.path.getCurrentPoint();
1815        context.operands.push(new Double(currentPoint.getX()));
1816        context.operands.push(new Double(currentPoint.getY()));
1817      }
1818    });
1819
1820    // clippath
1821
systemDict.put("clippath", new PACommand() {
1822      public void execute(PAContext context) throws PainterException {
1823        context.pencil.clippath();
1824      }
1825    });
1826
1827    // matrix
1828
systemDict.put("matrix", new PACommand() {
1829      public void execute(PAContext context) throws PainterException {
1830        ArrayList identityMatrix = new ArrayList(6);
1831
1832        identityMatrix.add(new Double(1.0d));
1833        identityMatrix.add(new Double(0.0d));
1834        identityMatrix.add(new Double(0.0d));
1835        identityMatrix.add(new Double(1.0d));
1836        identityMatrix.add(new Double(0.0d));
1837        identityMatrix.add(new Double(0.0d));
1838        context.operands.push(identityMatrix);
1839      }
1840    });
1841
1842    // concatmatrix
1843
systemDict.put("concatmatrix", new PACommand() {
1844      public void execute(PAContext context) throws PainterException {
1845        Object data[];
1846        data = context.popOperands(3);
1847        if (! (data[0] instanceof ArrayList)) {
1848          throw new PainterException("wrong arguments");
1849        }
1850        if (! (data[1] instanceof ArrayList)) {
1851          throw new PainterException("wrong arguments");
1852        }
1853        if (! (data[2] instanceof ArrayList)) {
1854          throw new PainterException("wrong arguments");
1855        }
1856        ArrayList arrayOne, arrayTwo, arrayThree;
1857        AffineTransform atOne, atTwo;
1858
1859        arrayOne = (ArrayList) data[0];
1860        arrayTwo = (ArrayList) data[1];
1861        arrayThree = (ArrayList) data[2];
1862
1863        double[] entries = new double[6];
1864
1865        if (! (arrayOne.size() == 6)) {
1866          throw new PainterException("wrong arguments");
1867        }
1868        if (! (arrayTwo.size() == 6)) {
1869          throw new PainterException("wrong arguments");
1870        }
1871        if (! (arrayThree.size() == 6)) {
1872          throw new PainterException("wrong arguments");
1873        }
1874
1875        for (int i = 0; i < 6; i++) {
1876          entries[i] = ( (Number) arrayOne.get(i)).doubleValue();
1877        }
1878        atOne = new AffineTransform(entries);
1879        for (int i = 0; i < 6; i++) {
1880          entries[i] = ( (Number) arrayTwo.get(i)).doubleValue();
1881        }
1882        atTwo = new AffineTransform(entries);
1883
1884        atOne.concatenate(atTwo);
1885
1886        atOne.getMatrix(entries);
1887        for (int i = 0; i < 6; i++) {
1888          arrayThree.set(i, new Double(entries[i]));
1889        }
1890        context.operands.push(arrayThree);
1891      }
1892    });
1893
1894    // pathbbox
1895
systemDict.put("pathbbox", new PACommand() {
1896      public void execute(PAContext context) throws PainterException {
1897        Rectangle2D pathBounds = context.pencil.state.path.getBounds2D();
1898
1899        context.operands.push(new Double(pathBounds.getMinX()));
1900        context.operands.push(new Double(pathBounds.getMinY()));
1901        context.operands.push(new Double(pathBounds.getMaxX()));
1902        context.operands.push(new Double(pathBounds.getMaxY()));
1903      }
1904    });
1905
1906    // truncate
1907
systemDict.put("truncate", new PACommand() {
1908      public void execute(PAContext context) throws PainterException {
1909        double data[];
1910        double truncated;
1911
1912        data = context.popNumberOperands(1);
1913        if (data[0] < 0) {
1914          truncated = Math.ceil(data[0]);
1915        }
1916        else {
1917          truncated = Math.floor(data[0]);
1918        }
1919        context.operands.push(new Double(truncated));
1920      }
1921    });
1922
1923    // rand
1924
systemDict.put("rand", new PACommand() {
1925      public void execute(PAContext context) throws PainterException {
1926
1927        context.operands.push(new Integer(randomNumberGenerator.nextInt(231)));
1928      }
1929    });
1930
1931    // srand
1932
systemDict.put("srand", new PACommand() {
1933      public void execute(PAContext context) throws PainterException {
1934        double data[];
1935
1936        data = context.popNumberOperands(1);
1937        randomNumberGenerator = new Random(Math.round(data[0]));
1938      }
1939    });
1940
1941    // cvi
1942
systemDict.put("cvi", new PACommand() {
1943      public void execute(PAContext context) throws PainterException {
1944        Object data[];
1945
1946        data = context.popOperands(1);
1947        if (! (data[0] instanceof Number) && ! (data[0] instanceof String)) {
1948          throw new PainterException("wrong arguments");
1949        }
1950        if (data[0] instanceof Number) {
1951          int d;
1952
1953          d = ( (Number) data[0]).intValue();
1954          context.operands.push(new Integer(d));
1955        }
1956        else {
1957          String s;
1958          s = (String) data[0];
1959
1960          context.operands.push(new Integer(s));
1961        }
1962      }
1963    });
1964
1965    // usertime
1966
systemDict.put("usertime", new PACommand() {
1967      public void execute(PAContext context) throws PainterException {
1968
1969        context.operands.push(new Long(System.currentTimeMillis()));
1970      }
1971    });
1972// save
1973
systemDict.put("save", new PACommand() {
1974      public void execute(PAContext context) throws PainterException {
1975
1976        // context.operands.push(new Long(System.currentTimeMillis()));
1977
}
1978    });
1979// restore
1980
systemDict.put("restore", new PACommand() {
1981      public void execute(PAContext context) throws PainterException {
1982
1983        // Object data[];
1984

1985        // data = context.popOperands(1);
1986

1987      }
1988    });
1989// clear
1990
systemDict.put("clear", new PACommand() {
1991      public void execute(PAContext context) throws PainterException {
1992
1993        // Object data[];
1994

1995        // data = context.popOperands(1);
1996

1997      }
1998    });
1999// cleardictstack
2000
systemDict.put("cleardictstack", new PACommand() {
2001      public void execute(PAContext context) throws PainterException {
2002
2003        // Object data[];
2004

2005        // data = context.popOperands(1);
2006

2007      }
2008    });
2009
2010    // charpath
2011
systemDict.put("charpath", new PACommand() {
2012      public void execute(PAContext context) throws PainterException {
2013        Object data[];
2014
2015        data = context.popOperands(2);
2016        if (! (data[0] instanceof String)) {
2017          throw new PainterException("wrong arguments");
2018        }
2019        if (! (data[1] instanceof Boolean)) {
2020          throw new PainterException("wrong arguments");
2021        }
2022
2023        context.pencil.charpath( (String) data[0],
2024                                ( (Boolean) data[1]).booleanValue());
2025      }
2026    });
2027
2028    // PENDING(uweh): we only support procedure right now and always push false on the stack
2029
// stopped
2030
systemDict.put("stopped", new PACommand() {
2031      public void execute(PAContext context) throws PainterException {
2032        Object data[];
2033        PAToken patoken;
2034
2035        data = context.popOperands(1);
2036        if (! (data[0] instanceof PAToken)) {
2037          throw new PainterException("wrong arguments");
2038        }
2039
2040        patoken = (PAToken) data[0];
2041        if (! (patoken.type == PAToken.PROCEDURE)) {
2042          throw new PainterException("wrong arguments");
2043        }
2044        context.engine.process(patoken);
2045        context.operands.push(new Boolean(false));
2046      }
2047    });
2048
2049    return systemDict;
2050  }
2051
2052}
2053
Popular Tags