/Users/lyon/j4p/src/graphics/dclap/Gr2PICT.java
|
1 // graphics.dclap/gr2pict.java
2 // write java ip.graphics calls to outstream in PICT format (apple macintosh)
3 // d.gilbert, dec. 1996
4 // based on PSgr by E.J. Friedman-Hill
5
6
7 package graphics.dclap;
8
9 // pack edu.indiana.bio.graphics.dclap;
10
11 import java.awt.*;
12 import java.awt.image.ImageObserver;
13 import java.io.DataOutputStream;
14 import java.io.IOException;
15 import java.io.OutputStream;
16
17 /**
18 * Gr2PICT is a Graphics subclass that draws to PICT format.
19 * @version 1.0
20 * @author Don Gilbert
21 */
22
23
24 public class Gr2PICT extends java.awt.Graphics {
25 //uncomment for jdk 1.2
26 public void drawString(java.text.AttributedCharacterIterator aci, int a, int b) {
27 };
28
29 public final static int CLONE = 49;
30 protected final static int PAGEHEIGHT = 792;
31 protected final static int PAGEWIDTH = 612;
32
33 protected DataOutputStream os;
34 protected Color clr = Color.black;
35 protected Font font = new
36 Font("Times", Font.PLAIN, 12);
37 protected Rectangle clipr = new Rectangle(-30000, -30000, 60000, 60000);
38 protected Point origin = new Point(0, 0);
39 protected boolean trouble = false;
40 protected Graphics g;
41
42
43 public Rectangle getClipBounds() {
44 Rectangle r = new Rectangle();
45 return r;
46 }
47
48 public void setClip(int a, int b, int c, int d) {
49 return;
50 }
51
52 public void setClip(java.awt.Shape a) {
53 return;
54 }
55
56 public java.awt.Shape getClip() {
57 Rectangle s = new Rectangle();
58 return s;
59 }
60
61 public void drawPolyline(int[] a, int[] b, int c) {
62 return;
63 }
64
65 public boolean drawImage(Image i, int a, int b, int c, int d, int e, int f, int g, int h, ImageObserver o) {
66 return true;
67 }
68
69 public boolean drawImage(Image i, int a, int b, int c, int d, int e, int f, int g, int h, Color cl, ImageObserver o) {
70 return true;
71 }
72
73 /**
74 * Constructs a new Gr2PICT Object. Unlike regular Graphics objects,
75 * Gr2PICT contexts can be created directly.
76 * @param o Output stream for PostScript output
77 * @see #create
78 */
79
80
81 public Gr2PICT(OutputStream o, Graphics g) {
82 os = new DataOutputStream(o);
83 trouble = false;
84 this.g = g;
85 Rectangle r = g.getClipBounds();
86 if (r == null)
87 r = new
88 Rectangle(0, 0, PAGEWIDTH, PAGEHEIGHT);
89 emitHeader(r.width, r.height);
90 }
91
92 public Gr2PICT(OutputStream o,
93 Graphics g, int what) {
94 os = new DataOutputStream(o);
95 trouble = false;
96 this.g = g;
97 Rectangle r = g.getClipBounds();
98 if (r == null)
99 r = new
100 Rectangle(0, 0, PAGEWIDTH, PAGEHEIGHT);
101 if (what != CLONE)
102 emitHeader(r.width, r.height);
103 }
104
105 private int fAlign = 0;
106
107 protected void emitbyte(int v) {
108 try {
109 os.writeByte(v);
110 fAlign++;
111 } catch (IOException ex) {
112 trouble = true;
113 }
114 }
115
116 protected void emitword(int v, DataOutputStream dos) {
117 try {
118 dos.writeShort(v);
119 } catch (IOException ex) {
120 trouble = true;
121 }
122 }
123
124 protected void emitint(int v) {
125 try {
126 os.writeInt(v);
127 } catch (IOException ex) {
128 trouble = true;
129 }
130 }
131
132 protected void emitstring(String s) {
133 try {
134 os.writeBytes(s);
135 fAlign += s.length();
136 } catch (IOException ex) {
137 trouble = true;
138 }
139 }
140
141 protected final void emitop(int op) {
142 if ((fAlign & 1) == 1) emitbyte(0); // pad to word size
143 emitword(op, os);
144 }
145
146 protected final void emitcolor(Color c) {
147 emitword(c.getRed() << 8, os);
148 emitword(c.getGreen() << 8, os);
149 emitword(c.getBlue() << 8, os);
150 }
151
152 protected final void emitrect(int x, int y, int width, int height) {
153 emitword(y, os);
154 emitword(x, os);
155 emitword(y + height, os);
156 emitword(x + width, os);
157 }
158
159 protected final void emitroundrect(
160 int opcode, int x, int y,
161 int width, int height, int arcWidth,
162 int arcHeight) {
163 emitop(QD.oOvSize);
164 emitword(arcHeight, os);
165 emitword(arcWidth, os);
166 emitop(opcode);
167 emitrect(x, y, width, height);
168 }
169
170 protected void emitpolygon(Polygon p) {
171 int polysize = 2 + 8 + p.npoints * 4;
172 emitword(polysize, os);
173 Rectangle r = p.getBounds();
174 emitrect(r.x, r.y, r.width, r.height);
175 for (int i = 0; i < p.npoints; i++) {
176 emitword(p.ypoints[i], os);
177 emitword(p.xpoints[i], os);
178 }
179 }
180
181 protected void emitcomment(int kind, int datasize, String data) {
182 if (datasize == 0) {
183 emitop(QD.oShortComment);
184 emitword(kind, os);
185 } else {
186 emitop(QD.oLongComment);
187 emitword(kind, os);
188 emitword(data.length(), os);
189 emitstring(data);
190 }
191 }
192
193 public final void beginPicGroup() {
194 emitcomment(QD.picGrpBeg, 0, null);
195 }
196
197 public final void endPicGroup() {
198 emitcomment(QD.picGrpEnd, 0, null);
199 }
200
201 public void laserLine(int num, int denom) {
202 // set laserwriter line width
203 // use num=1, denom=4 for 1/300 dpi line
204 //emitcomment( QD.setLineWidth, sizeof(lineSize), lineSize);
205 emitop(QD.oLongComment);
206 emitword(QD.setLineWidth, os);
207 emitword(4, os);
208 emitword(num, os);
209 emitword(denom, os);
210 }
211
212
213 /**
214 Top of every PICT file
215 */
216
217 protected void emitHeader(int picwidth, int picheight) {
218 // 512 byte writeHeader
219 try {
220 int buflen = 512;
221 byte[] buf = new byte[buflen]; // java zeros buf !?
222 os.write(buf, 0, buflen);
223 } catch (IOException ex) {
224 trouble = true;
225 }
226
227 int picbytes = 0; // will zero here suffice !? seems to be working...
228 emitword(picbytes, os);
229 emitrect(0, 0, picwidth, picheight);
230 emitop(QD.oVersion);
231 emitword(QD.version2, os);
232
233 // writeHeader from clarisdraw
234 // C00 0x10 0xc00 : (skip 24) FF FF FF FF FF FF 0 0 FF FF
235
236 emitop(QD.oHeaderOp); // reserved writeHeader opcode, followed by 24 byte writeHeader
237 emitint(-1); // total size in bytes or -1
238 for (int i = 0; i < 4; i++) {
239 emitword(-1, os);
240 emitword(0, os);
241 } // fixedpt bound box or -1
242 emitint(-1); // reserved or -1
243
244 //oDefHilite & clipRect of pict size as 1st op is usual but not required !?
245 emitop(QD.oDefHilite);
246 clipRect(clipr.x, clipr.y, clipr.width, clipr.height);
247 beginPicGroup();
248 }
249
250
251
252 ///////////// Graphics Public Interface ////////////
253
254
255
256 /**
257 * Creates a new Gr2PICT Object that is a copy of the original Gr2PICT Object.
258 */
259 public Graphics create() {
260 Gr2PICT grpict = new Gr2PICT(os, g, CLONE);
261 grpict.font = font;
262 grpict.clipr = clipr;
263 grpict.clr = clr;
264 return grpict;
265 }
266
267 /**
268 * Creates a new Graphics Object with the specified parameters,
269 * based on the original
270 * Graphics Object.
271 * This method translates the specified parameters, x and y, to
272 * the proper origin coordinates and then clips the Graphics Object to the
273 * area.
274 * @param x the x coordinate
275 * @param y the y coordinate
276 * @param width the width of the area
277 * @param height the height of the area
278 * @see #translate
279 */
280 public Graphics create(int x, int y, int width, int height) {
281 Graphics g = create();
282 g.translate(x, y);
283 g.clipRect(0, 0, width, height);
284 return g;
285 }
286
287 /**
288 * Translates the specified parameters into the origin of
289 * the ip.graphics context. All subsequent
290 * operations on this ip.graphics context will be relative to this origin.
291 * @param x the x coordinate
292 * @param y the y coordinate
293 * @see #scale
294 */
295
296 public void translate(int x, int y) {
297 // ? do this internally, adjusting each emitted x,y?
298 origin.x = x;
299 origin.y = y;
300 // or as emitted opcode ??
301 emitop(QD.oOrigin);
302 emitword(-x, os);
303 emitword(-y, os);
304 }
305
306
307 /**
308 * Gets the current color.
309 * @see #setColor
310 */
311 public Color getColor() {
312 return clr;
313 }
314
315
316 /**
317 * Sets the current color to the specified color. All subsequent ip.graphics operations
318 * will use this specified color.
319 * @param c the color to be set
320 * @see Color
321 * @see #getColor
322 */
323
324 public void setColor(Color c) {
325 if (c != null) clr = c;
326 emitop(QD.oRGBFgCol);
327 emitcolor(clr);
328 }
329
330
331 /**
332 * Sets the default paint mode to overwrite the destination with the
333 * current color.
334 */
335 public void setPaintMode() {
336 emitop(QD.oPnMode);
337 emitword(QD.patCopy, os); // or QD.patOr
338 }
339
340 /**
341 * Sets the paint mode to alternate between the current color
342 * and the new specified color.
343 * @param c1 the second color
344 */
345 public void setXORMode(Color c1) {
346 emitop(QD.oPnMode);
347 emitword(QD.patXor, os);
348 if (c1 != null) {
349 // set c1 as PICT HiliteColor & set HiliteMode !?
350 emitop(QD.oHiliteMode);
351 emitop(QD.oHiliteColor);
352 emitcolor(c1);
353 }
354 }
355
356 /**
357 * Gets the current font.
358 * @see #setFont
359 */
360 public Font getFont() {
361 return font;
362 }
363
364 /**
365 * Sets the font for all subsequent text-drawing operations.
366 * @param font the specified font
367 * @see Font
368 * @see #getFont
369 * @see #drawString
370 * @see #drawBytes
371 * @see #drawChars
372 */
373 public void setFont(Font f) {
374 if (f != null) {
375 this.font = f;
376
377 // count # bytes in name + number +
378 String fname = font.getName();
379 fname = "Times"; // HACK!
380 // Make sure the font is really
381 // Times, for the purpose of printing!!
382 int qdnum = QD.getQuickDrawFontNum(fname);
383 if (qdnum >= 0) {
384 emitop(QD.oTxFont);
385 emitword(qdnum, os);
386 } else {
387 emitop(QD.oFontName);
388 int len = fname.length() + 1 + 2 + 2; // length-byte + fontnum + #bytes total
389 emitword(len, os);
390 emitword(QD.fontnum++, os);
391 emitstring(fname);
392 }
393
394 int face = 0;
395 int style = font.getStyle();
396 if ((style & Font.BOLD) != 0) face |= QD.bold;
397 if ((style & Font.ITALIC) != 0) face |= QD.italic;
398 emitop(QD.oTxFace);
399 emitbyte(face);
400
401 emitop(QD.oTxSize);
402 emitword(font.getSize(), os);
403 }
404 }
405
406
407 /**
408 * Gets the current font metrics.
409 * @see #getFont
410 */
411 public FontMetrics getFontMetrics() {
412 return getFontMetrics(getFont());
413 }
414
415 /**
416 * Gets the current font metrics for the specified font.
417 * @param f the specified font
418 * @see #getFont
419 * @see #getFontMetrics
420 */
421 public FontMetrics getFontMetrics(Font f) {
422 return g.getFontMetrics(f);
423 }
424
425
426 /**
427 * Returns the bounding rectangle of the current clipping area.
428 * @see #clipRect
429 */
430 public Rectangle getBounds() {
431 return clipr;
432 }
433
434 /**
435 * Clips to a rectangle. The resulting clipping area is the
436 * intersection of the current clipping area and the specified
437 * rectangle. Graphic operations have no effect outside of the
438 * clipping area.
439 * @param x the x coordinate
440 * @param y the y coordinate
441 * @param width the width of the rectangle
442 * @param height the height of the rectangle
443 * @see #getClipRect
444 */
445 public void clipRect(int x, int y, int width, int height) {
446 clipr = new Rectangle(x, y, width, height);
447 emitop(QD.oClip);
448 int rgnsize = 2 + 8; //size-word + sizeof(rect) + sizeof(region)??
449 emitword(rgnsize, os);
450 emitrect(x, y, width, height);
451 }
452
453 /**
454 * Copies an area of the screen.
455 * @param x the x-coordinate of the source
456 * @param y the y-coordinate of the source
457 * @param width the width
458 * @param height the height
459 * @param dx the horizontal distance
460 * @param dy the vertical distance
461 */
462 public void copyArea(int x, int y, int width, int height, int dx, int dy) {
463 //throw new RuntimeException("copyArea not supported");
464 }
465
466 /**
467 * Draws a line between the coordinates (x1,y1) and (x2,y2). The line is drawn
468 * below and to the left of the logical coordinates.
469 * @param x1 the first point's x coordinate
470 * @param y1 the first point's y coordinate
471 * @param x2 the second point's x coordinate
472 * @param y2 the second point's y coordinate
473 */
474
475 public void drawLine(int x1, int y1, int x2, int y2) {
476 emitop(QD.oLine);
477 emitword(y1, os);
478 emitword(x1, os);
479 emitword(y2, os);
480 emitword(x2, os);
481 }
482
483 /**
484 * Fills the specified rectangle with the current color.
485 * @param x the x coordinate
486 * @param y the y coordinate
487 * @param width the width of the rectangle
488 * @param height the height of the rectangle
489 * @see #drawRect
490 * @see #clearRect
491 */
492 public void fillRect(int x, int y, int width, int height) {
493 emitop(QD.opaintRect);
494 emitrect(x, y, width, height);
495 }
496
497 /**
498 * Draws the outline of the specified rectangle using the current color.
499 * Use drawRect(x, y, width-1, height-1) to draw the outline inside the specified
500 * rectangle.
501 * @param x the x coordinate
502 * @param y the y coordinate
503 * @param width the width of the rectangle
504 * @param height the height of the rectangle
505 * @see #fillRect
506 * @see #clearRect
507 */
508 public void drawRect(int x, int y, int width, int height) {
509 emitop(QD.oframeRect);
510 emitrect(x, y, width, height);
511 }
512
513 /**
514 * Clears the specified rectangle by filling it with the current background color
515 * of the current drawing surface.
516 * Which drawing surface it selects depends on how the ip.graphics context
517 * was created.
518 * @param x the x coordinate
519 * @param y the y coordinate
520 * @param width the width of the rectangle
521 * @param height the height of the rectangle
522 * @see #fillRect
523 * @see #drawRect
524 */
525 public void clearRect(int x, int y, int width, int height) {
526 emitop(QD.oeraseRect);
527 emitrect(x, y, width, height);
528 }
529
530
531 /**
532 * Draws an outlined rounded corner rectangle using the current color.
533 * @param x the x coordinate
534 * @param y the y coordinate
535 * @param width the width of the rectangle
536 * @param height the height of the rectangle
537 * @param arcWidth the diameter of the arc
538 * @param arcHeight the radius of the arc
539 * @see #fillRoundRect
540 */
541 public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
542 emitroundrect(QD.oframeRRect, x, y, width, height, arcWidth, arcHeight);
543 }
544
545 /**
546 * Draws a rounded rectangle filled in with the current color.
547 * @param x the x coordinate
548 * @param y the y coordinate
549 * @param width the width of the rectangle
550 * @param height the height of the rectangle
551 * @param arcWidth the diameter of the arc
552 * @param arcHeight the radius of the arc
553 * @see #drawRoundRect
554 */
555 public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
556 emitroundrect(QD.opaintRRect, x, y, width, height, arcWidth, arcHeight);
557 }
558
559 /**
560 * Draws a highlighted 3-D rectangle.
561 * @param x the x coordinate
562 * @param y the y coordinate
563 * @param width the width of the rectangle
564 * @param height the height of the rectangle
565 * @param raised a boolean that states whether the rectangle is raised or not
566 */
567 public void draw3DRect(int x, int y, int width, int height, boolean raised) {
568 Color c = getColor();
569 Color brighter = c.brighter();
570 Color darker = c.darker();
571
572 setColor(raised ? brighter : darker);
573 drawLine(x, y, x, y + height);
574 drawLine(x + 1, y, x + width - 1, y);
575 setColor(raised ? darker : brighter);
576 drawLine(x + 1, y + height, x + width, y + height);
577 drawLine(x + width, y, x + width, y + height);
578 setColor(c);
579 }
580
581 /**
582 * Paints a highlighted 3-D rectangle using the current color.
583 * @param x the x coordinate
584 * @param y the y coordinate
585 * @param width the width of the rectangle
586 * @param height the height of the rectangle
587 * @param raised a boolean that states whether the rectangle is raised or not
588 */
589 public void fill3DRect(int x, int y, int width, int height, boolean raised) {
590 Color c = getColor();
591 Color brighter = c.brighter();
592 Color darker = c.darker();
593
594 if (!raised) setColor(darker);
595 fillRect(x + 1, y + 1, width - 2, height - 2);
596 setColor(raised ? brighter : darker);
597 drawLine(x, y, x, y + height - 1);
598 drawLine(x + 1, y, x + width - 2, y);
599 setColor(raised ? darker : brighter);
600 drawLine(x + 1, y + height - 1, x + width - 1, y + height - 1);
601 drawLine(x + width - 1, y, x + width - 1, y + height - 1);
602 setColor(c);
603 }
604
605 /**
606 * Draws an oval inside the specified rectangle using the current color.
607 * @param x the x coordinate
608 * @param y the y coordinate
609 * @param width the width of the rectangle
610 * @param height the height of the rectangle
611 * @see #fillOval
612 */
613 public void drawOval(int x, int y, int width, int height) {
614 emitop(QD.oframeOval);
615 emitrect(x, y, width, height);
616 }
617
618 /**
619 * Fills an oval inside the specified rectangle using the current color.
620 * @param x the x coordinate
621 * @param y the y coordinate
622 * @param width the width of the rectangle
623 * @param height the height of the rectangle
624 * @see #drawOval
625 */
626 public void fillOval(int x, int y, int width, int height) {
627 emitop(QD.opaintOval);
628 emitrect(x, y, width, height);
629 }
630
631
632 /**
633 * Draws an arc bounded by the specified rectangle from startAngle to
634 * endAngle. 0 degrees is at the 3-o'clock position.Positive arc
635 * angles indicate counter-clockwise rotations, negative arc angles are
636 * drawn clockwise.
637 * @param x the x coordinate
638 * @param y the y coordinate
639 * @param width the width of the rectangle
640 * @param height the height of the rectangle
641 * @param startAngle the beginning angle
642 * @param arcAngle the angle of the arc (relative to startAngle).
643 * @see #fillArc
644 */
645 public void drawArc(int x, int y, int width, int height,
646 int startAngle, int arcAngle) {
647 emitop(QD.oframeArc);
648 emitrect(x, y, width, height);
649 emitword(startAngle + 90, os);
650 emitword(arcAngle, os);
651 }
652
653 /**
654 * Fills an arc using the current color. This generates a pie shape.
655 *
656 * @param x the x coordinate
657 * @param y the y coordinate
658 * @param width the width of the arc
659 * @param height the height of the arc
660 * @param startAngle the beginning angle
661 * @param arcAngle the angle of the arc (relative to startAngle).
662 * @see #drawArc
663 */
664 public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
665 emitop(QD.opaintArc);
666 emitrect(x, y, width, height);
667 emitword(startAngle, os);
668 emitword(arcAngle, os);
669 }
670
671
672 /**
673 * Draws a polygon defined by an array of x points and y points.
674 * @param xPoints an array of x points
675 * @param yPoints an array of y points
676 * @param nPoints the total number of points
677 * @see #fillPolygon
678 */
679 public void drawPolygon(int xPoints[], int yPoints[], int nPoints) {
680 drawPolygon(new Polygon(xPoints, yPoints, nPoints));
681 }
682
683 /**
684 * Draws a polygon defined by the specified point.
685 * @param p the specified polygon
686 * @see #fillPolygon
687 */
688 public void drawPolygon(Polygon p) {
689 emitop(QD.oframePoly);
690 emitpolygon(p);
691 }
692
693 /**
694 * Fills a polygon with the current color.
695 * @param xPoints an array of x points
696 * @param yPoints an array of y points
697 * @param nPoints the total number of points
698 * @see #drawPolygon
699 */
700 public void fillPolygon(int xPoints[], int yPoints[], int nPoints) {
701 fillPolygon(new Polygon(xPoints, yPoints, nPoints));
702 }
703
704 /**
705 * Fills the specified polygon with the current color.
706 * @param p the polygon
707 * @see #drawPolygon
708 */
709 public void fillPolygon(Polygon p) {
710 emitop(QD.opaintPoly);
711 emitpolygon(p);
712 }
713
714 /**
715 * Draws the specified String using the current font and color.
716 * The x,y position is the starting point of the baseline of the String.
717 * @param str the String to be drawn
718 * @param x the x coordinate
719 * @param y the y coordinate
720 * @see #drawChars
721 * @see #drawBytes
722 */
723 public void drawString(String str, int x, int y) {
724 emitop(QD.oLongText);
725 emitword(y, os);
726 emitword(x, os);
727 emitbyte(str.length());
728 emitstring(str);
729 }
730
731 /**
732 * Draws the specified characters using the current font and color.
733 * @param data the array of characters to be drawn
734 * @param offset the start offset in the data
735 * @param length the number of characters to be drawn
736 * @param x the x coordinate
737 * @param y the y coordinate
738 * @see #drawString
739 * @see #drawBytes
740 */
741 public void drawChars(char data[], int offset, int length, int x, int y) {
742 drawString(new String(data, offset, length), x, y);
743 }
744
745 /**
746 * Draws the specified bytes using the current font and color.
747 * @param data the data to be drawn
748 * @param offset the start offset in the data
749 * @param length the number of bytes that are drawn
750 * @param x the x coordinate
751 * @param y the y coordinate
752 * @see #drawString
753 * @see #drawChars
754 */
755 public void drawBytes(byte data[], int offset, int length, int x, int y) {
756 // deprecated:
757 //drawString(new String(data, 0, offset, length), x, y);
758 drawString(new String(data, offset, length), x, y);
759 }
760
761
762 /******
763 // possible data for imaging
764 // hexadecimal digits
765 protected final static char hd[] = {'0', '1', '2', '3', '4', '5', '6', '7',
766 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
767 // number of chars in a full row of pixel data
768 protected final static int charsPerRow = 12*6;
769 *******/
770
771
772 public boolean doImage(Image img, int x, int y, int width, int height,
773 ImageObserver observer, Color bgcolor) {
774 /******
775
776 // This class fetches the pixels in its constructor.
777 PixelConsumer pc = new PixelConsumer(img);
778
779 y = transformY(y);
780 os.println("gsave");
781
782 os.println("% build a temporary dictionary");
783 os.println("20 dict begin");
784 emitColorImageProlog(pc.xdim);
785
786 os.println("% lower left corner");
787 os.print(x);
788 os.print(" ");
789 os.print(y);
790 os.println(" translate");
791
792 // compute image size. First of all, if width or height is 0, image is 1:1.
793 if (height == 0 || width == 0) {
794 height = pc.ydim;
795 width = pc.xdim;
796 }
797
798 os.println("% size of image");
799 os.print(width);
800 os.print(" ");
801 os.print(height);
802 os.println(" scale");
803
804 os.print(pc.xdim);
805 os.print(" ");
806 os.print(pc.ydim);
807 os.println(" 8");
808
809 os.print("[");
810 os.print(pc.xdim);
811 os.print(" 0 0 -");
812 os.print(pc.ydim);
813 os.print(" 0 ");
814 os.print(0);
815 os.println("]");
816
817 os.println("{currentfile pix readhexstring pop}");
818 os.println("false 3 colorimage");
819 os.println("");
820
821
822 int offset, sleepyet=0;;
823 // array to hold a line of pixel data
824 char[] sb = new char[charsPerRow + 1];
825
826 for (int i=0; i<pc.ydim; i++) {
827 offset = 0;
828 ++sleepyet;
829 if (bgcolor == null) {
830 // real color image. We're deliberately duplicating code here
831 // in the interest of speed - we don't want to check bgcolor
832 // on every iteration.
833 for (int j=0; j<pc.xdim; j++) {
834 int n = pc.pix[j][i];
835
836 // put hex chars into string
837 // flip red for blue, to make postscript happy.
838
839 sb[offset++] = hd[(n & 0xF0) >> 4];
840 sb[offset++] = hd[(n & 0xF) ];
841 sb[offset++] = hd[(n & 0xF000) >> 12];
842 sb[offset++] = hd[(n & 0xF00) >> 8];
843 sb[offset++] = hd[(n & 0xF00000) >> 20];
844 sb[offset++] = hd[(n & 0xF0000) >> 16];
845
846 if (offset >= charsPerRow) {
847 String s = String.copyValueOf(sb, 0, offset);
848 os.println(s);
849 if (sleepyet > 5) {
850 try {
851 // let the screen update occasionally!
852 Thread.sleep(15);
853 } catch (java.lang.InterruptedException ex) {
854 // yeah, so?
855 }
856 sleepyet = 0;
857 }
858 offset = 0;
859 }
860 }
861 } else {
862 os.println("%FalseColor"); // was System.out.println
863 // false color image.
864 for (int j=0; j<pc.xdim; j++) {
865 int bg =
866 bgcolor.getGreen() << 16 + bgcolor.getBlue() << 8 + bgcolor.getRed();
867 int fg =
868 clr.getGreen() << 16 + clr.getBlue() << 8 + clr.getRed();
869
870 int n = (pc.pix[j][i] == 1 ? fg : bg);
871
872 // put hex chars into string
873
874 sb[offset++] = hd[(n & 0xF0) ];
875 sb[offset++] = hd[(n & 0xF) ];
876 sb[offset++] = hd[(n & 0xF000) ];
877 sb[offset++] = hd[(n & 0xF00) ];
878 sb[offset++] = hd[(n & 0xF00000)];
879 sb[offset++] = hd[(n & 0xF0000) ];
880
881 if (offset >= charsPerRow) {
882 String s = String.copyValueOf(sb, 0, offset);
883 os.println(s);
884 if (sleepyet > 5) {
885 try {
886 // let the screen update occasionally!
887 Thread.sleep(15);
888 } catch (java.lang.InterruptedException ex) {
889 // yeah, so?
890 }
891 sleepyet = 0;
892 }
893 offset = 0;
894 }
895 }
896 }
897 // print partial rows
898 if (offset != 0) {
899 String s = String.copyValueOf(sb, 0, offset);
900 os.println(s);
901 }
902 }
903
904 os.println("");
905 os.println("end");
906 os.println("grestore");
907 ************/
908 return true;
909 }
910
911 /**
912 * Draws the specified image at the specified coordinate (x, y). If the image is
913 * incomplete the image observer will be notified later.
914 * @param img the specified image to be drawn
915 * @param x the x coordinate
916 * @param y the y coordinate
917 * @param observer notifies if the image is complete or not
918 * @see Image
919 * @see ImageObserver
920 */
921
922 public boolean drawImage(Image img, int x, int y,
923 ImageObserver observer) {
924 return doImage(img, x, y, 0, 0, observer, null);
925 }
926
927 /**
928 * Draws the specified image inside the specified rectangle. The image is
929 * scaled if necessary. If the image is incomplete the image observer will be
930 * notified later.
931 * @param img the specified image to be drawn
932 * @param x the x coordinate
933 * @param y the y coordinate
934 * @param width the width of the rectangle
935 * @param height the height of the rectangle
936 * @param observer notifies if the image is complete or not
937 * @see Image
938 * @see ImageObserver
939 */
940 public boolean drawImage(Image img, int x, int y,
941 int width, int height,
942 ImageObserver observer) {
943 return doImage(img, x, y, width, height, observer, null);
944 }
945
946 /**
947 * Draws the specified image at the specified coordinate (x, y). If the image is
948 * incomplete the image observer will be notified later.
949 * @param img the specified image to be drawn
950 * @param x the x coordinate
951 * @param y the y coordinate
952 * @param bgcolor the background color
953 * @param observer notifies if the image is complete or not
954 * @see Image
955 * @see ImageObserver
956 */
957
958 public boolean drawImage(Image img, int x, int y, Color bgcolor,
959 ImageObserver observer) {
960 return doImage(img, x, y, 0, 0, observer, bgcolor);
961 }
962
963 /**
964 * Draws the specified image inside the specified rectangle. The image is
965 * scaled if necessary. If the image is incomplete the image observer will be
966 * notified later.
967 * @param img the specified image to be drawn
968 * @param x the x coordinate
969 * @param y the y coordinate
970 * @param width the width of the rectangle
971 * @param height the height of the rectangle
972 * @param bgcolor the background color
973 * @param observer notifies if the image is complete or not
974 * @see Image
975 * @see ImageObserver
976 *
977 */
978 public boolean drawImage(Image img, int x, int y,
979 int width, int height, Color bgcolor,
980 ImageObserver observer) {
981 return doImage(img, x, y, width, height, observer, bgcolor);
982 }
983
984 /**
985 * Disposes of this ip.graphics context. The Graphics context cannot be used after
986 * being disposed of.
987 * @see #finalize
988 */
989 public void dispose() {
990 endPicGroup();
991 emitop(QD.oopEndPic);
992 try {
993 os.flush();
994 } catch (IOException ex) {
995 trouble = true;
996 }
997 }
998
999 /**
1000 * Disposes of this ip.graphics context once it is no longer referenced.
1001 * @see #dispose
1002 */
1003 public void finalize() {
1004 super.finalize();
1005 dispose();
1006 }
1007
1008 /**
1009 * Returns a String object representing this Graphic's value.
1010 */
1011 public String toString() {
1012 return getClass().getName() + "[font=" + getFont() + ",color=" + getColor() + "]";
1013 }
1014
1015 public boolean checkError() {
1016 return trouble;
1017 }
1018
1019 }
1020
1021
1022