001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.harmony.x.print;
019:
020: import java.awt.Color;
021: import java.awt.Font;
022: import java.awt.Graphics;
023: import java.awt.GraphicsConfiguration;
024: import java.awt.Image;
025: import java.awt.Rectangle;
026: import java.awt.Shape;
027: import java.awt.font.GlyphVector;
028: import java.awt.font.TextLayout;
029: import java.awt.geom.AffineTransform;
030: import java.awt.geom.PathIterator;
031: import java.awt.geom.Rectangle2D;
032: import java.awt.image.BufferedImage;
033: import java.awt.image.BufferedImageOp;
034: import java.awt.image.ImageObserver;
035: import java.awt.print.PageFormat;
036: import java.io.PrintStream;
037: import java.text.AttributedCharacterIterator;
038: import java.text.CharacterIterator;
039: import java.util.Date;
040: import java.util.HashMap;
041: import java.util.Map;
042:
043: import org.apache.harmony.awt.gl.CommonGraphics2D;
044:
045: public class Graphics2D2PS extends CommonGraphics2D {
046:
047: private static final Font DEF_FONT;
048: private static final Map<String, String> FONT_MAP;
049:
050: private final PrintStream out_stream;
051: private final PageFormat format;
052: private final Rectangle defaultClip;
053: private double yscale = 1;
054:
055: static {
056: DEF_FONT = new Font("Dialog", Font.PLAIN, 12); //$NON-NLS-1$
057: FONT_MAP = new HashMap<String, String>();
058: FONT_MAP.put("Serif", "Times"); //$NON-NLS-1$ //$NON-NLS-2$
059: FONT_MAP.put("SansSerif", "Helvetica"); //$NON-NLS-1$ //$NON-NLS-2$
060: FONT_MAP.put("Monospaced", "Courier"); //$NON-NLS-1$ //$NON-NLS-2$
061: FONT_MAP.put("Dialog", "Helvetica"); //$NON-NLS-1$ //$NON-NLS-2$
062: FONT_MAP.put("DialogInput", "Courier"); //$NON-NLS-1$ //$NON-NLS-2$
063: }
064:
065: public Graphics2D2PS(final PrintStream stream,
066: final PageFormat format) {
067: super ();
068: if (stream == null) {
069: throw new IllegalArgumentException("stream is null"); //$NON-NLS-1$
070: }
071:
072: out_stream = stream;
073: this .format = format != null ? format : new PageFormat();
074: defaultClip = new Rectangle((int) this .format.getImageableX(),
075: (int) this .format.getImageableY(), (int) this .format
076: .getImageableWidth(), (int) this .format
077: .getImageableHeight());
078: PS.printHeader(stream);
079: resetGraphics();
080: setColor(fgColor);
081: setFont(DEF_FONT);
082: setClip(defaultClip);
083: ps(PS.setDefGstate);
084: }
085:
086: public Graphics2D2PS(final PrintStream stream) {
087: this (stream, null);
088: }
089:
090: public void finish() {
091: PS.printFooter(out_stream);
092: out_stream.close();
093: }
094:
095: public void startPage(final int number) {
096: ps(PS.comment, "Page: " + number + " " + number); //$NON-NLS-1$ //$NON-NLS-2$
097: ps(PS.restoreDefGstate);
098: resetGraphics();
099: }
100:
101: public void endOfPage(final int number) {
102: ps(PS.showpage);
103: ps(PS.comment, "EndPage: " + number + " " + number); //$NON-NLS-1$ //$NON-NLS-2$
104: }
105:
106: public boolean drawImage(final Image image, final int x,
107: final int y, final ImageObserver imageObserver) {
108: drawImage(image, x, convY(y));
109: return true;
110: }
111:
112: public boolean drawImage(final Image image, final int x,
113: final int y, final int width, final int height,
114: final ImageObserver imageObserver) {
115: final BufferedImage imageGIF = (BufferedImage) image;
116: final float w = (float) imageGIF.getWidth();
117: final float h = (float) imageGIF.getHeight();
118:
119: drawImage(image, x, convY(y), true, ((float) width) / w,
120: ((float) height) / h);
121: return true;
122: }
123:
124: public boolean drawImage(final Image image, final int x,
125: final int y, final Color bbgcolor,
126: final ImageObserver imageObserver) {
127: final BufferedImage imageGIF = (BufferedImage) image;
128: final int iw = imageGIF.getWidth();
129: final int ih = imageGIF.getHeight();
130: final Color cur_color = getColor();
131:
132: setColor(bbgcolor);
133: fillRect(x, y, iw, ih);
134: setColor(cur_color);
135: drawImage(image, x, convY(y));
136: return true;
137: }
138:
139: public boolean drawImage(final Image image, final int x,
140: final int y, final int width, final int height,
141: final Color bbgcolor, final ImageObserver imageObserver) {
142: final BufferedImage imageGIF = (BufferedImage) image;
143: final float w = (float) imageGIF.getWidth();
144: final float h = (float) imageGIF.getHeight();
145: final Color cur_color = getColor();
146:
147: setColor(bbgcolor);
148: fillRect(x, y, width, height);
149: setColor(cur_color);
150: drawImage(image, x, convY(y), true, ((float) width) / w,
151: ((float) height) / h);
152: return true;
153: }
154:
155: public boolean drawImage(Image image, int dx1, int dy1, int dx2,
156: int dy2, int sx1, int sy1, int sx2, int sy2,
157: ImageObserver imageObserver) {
158: int sx;
159: int sy;
160: int width;
161: int height;
162: int dx;
163: int dy;
164: int d;
165: int comp;
166: BufferedImage newImage;
167: BufferedImage imageGIF;
168:
169: // TODO: this method have to be improved to flip image if dx2 < dx1 or
170: // dy2<dy1
171: if (dx2 < dx1) {
172: d = dx2;
173: dx2 = dx1;
174: dx1 = d;
175: }
176: if (dy2 < dy1) {
177: d = dy2;
178: dy2 = dy1;
179: dy1 = d;
180: }
181: dx = dx2 - dx1 + 1;
182: dy = dy2 - dy1 + 1;
183:
184: imageGIF = (BufferedImage) image;
185: width = imageGIF.getWidth();
186: height = imageGIF.getHeight();
187: if (dx2 > width || dy2 > height) {
188: return false;
189: }
190: newImage = new BufferedImage(dx, dy,
191: BufferedImage.TYPE_INT_ARGB);
192:
193: sy = 0;
194: for (int iy = dy1; iy <= dy2; iy++) {
195: sx = 0;
196: for (int ix = dx1; ix <= dx2; ix++) {
197: comp = imageGIF.getRGB(ix, iy);
198: newImage.setRGB(sx++, sy, comp);
199: }
200: sy++;
201: }
202: drawImage(newImage, sx1, sy1, sx2 - sx1 + 1, sy2 - sy1 + 1,
203: null);
204:
205: return true;
206: }
207:
208: public boolean drawImage(final Image image, final int dx1,
209: final int dy1, final int dx2, final int dy2, final int sx1,
210: final int sy1, final int sx2, final int sy2,
211: final Color bbgcolor, final ImageObserver imageObserver) {
212: final Color cur_color = getColor();
213:
214: setColor(bbgcolor);
215: fillRect(sx1, sy1, sx2 - sx1 + 1, sy2 - sy1 + 1);
216: setColor(cur_color);
217:
218: return drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2,
219: imageObserver);
220:
221: }
222:
223: public boolean drawImage(final Image image,
224: final AffineTransform transform,
225: final ImageObserver imageObserver) {
226: // TODO: Implement
227: return false;
228: }
229:
230: public void drawImage(final BufferedImage image,
231: final BufferedImageOp arg1, final int arg2, final int arg3) {
232: // TODO: Implement
233: }
234:
235: public void drawString(final String text, final float x,
236: final float y) {
237: drawString(text, (int) x, (int) y);
238: }
239:
240: public void drawString(final String text, final int x, final int y) {
241: if (text == null) {
242: return;
243: }
244:
245: StringBuffer sb = new StringBuffer(text.length());
246: int lastX = x;
247:
248: for (int i = 0; i < text.length(); i++) {
249: if (text.codePointAt(i) < 256) {
250: sb.append(text.charAt(i));
251: } else {
252: if (sb.length() > 0) {
253: lastX += drawPSString(sb.toString(), lastX, y);
254: sb = new StringBuffer(text.length() - i);
255: }
256:
257: lastX += drawStringShape(
258: String.valueOf(text.charAt(i)), lastX, y);
259: }
260: }
261:
262: if (sb.length() > 0) {
263: drawPSString(sb.toString(), lastX, y);
264: }
265: }
266:
267: public void drawString(final AttributedCharacterIterator iterator,
268: final float x, final float y) {
269: drawString(iterator, (int) x, (int) y);
270: }
271:
272: public void drawString(final AttributedCharacterIterator iterator,
273: final int x, final int y) {
274: final int n = iterator.getEndIndex();
275: final char[] cc = new char[n];
276: int i = 0;
277:
278: for (char c = iterator.first(); c != CharacterIterator.DONE; c = iterator
279: .next()) {
280: cc[i++] = c;
281: }
282: drawChars(cc, 0, n, x, y);
283: }
284:
285: public void drawLine(final int x1, final int y1, final int x2,
286: final int y2) {
287: ps(PS.newpath);
288: ps(PS.moveto, x1, convY(y1));
289: ps(PS.lineto, x2, convY(y2));
290: ps(PS.stroke);
291: }
292:
293: public void drawOval(final int x, final int y, final int width,
294: final int height) {
295: drawArc(x, y, width, height, 0, 360, false);
296: }
297:
298: public void fillOval(final int x, final int y, final int width,
299: final int height) {
300: drawArc(x, y, width, height, 0, 360, true);
301: }
302:
303: public void drawArc(final int x, final int y, final int width,
304: final int height, final int startAngle, final int arcAngle) {
305: drawArc(x, y, width, height, startAngle, arcAngle, false);
306: }
307:
308: public void fillArc(final int x, final int y, final int width,
309: final int height, final int startAngle, final int arcAngle) {
310: drawArc(x, y, width, height, startAngle, arcAngle, true);
311: }
312:
313: public void drawRoundRect(final int x, final int y,
314: final int width, final int height, final int arcWidth,
315: final int arcHeight) {
316: drawRoundRect(x, y, width, height, arcWidth, arcHeight, false);
317: }
318:
319: public void fillRoundRect(final int x, final int y,
320: final int width, final int height, final int arcWidth,
321: final int arcHeight) {
322: drawRoundRect(x, y, width, height, arcWidth, arcHeight, true);
323: }
324:
325: public void drawRect(final int x, final int y, final int width,
326: final int height) {
327: int x2 = x + width;
328: int y1 = convY(y);
329: int y2 = convY(y + height);
330: int[] xPoints = { x, x2, x2, x };
331: int[] yPoints = { y1, y1, y2, y2 };
332: drawPolyline(xPoints, yPoints, 4, true, false);
333: }
334:
335: public void fillRect(final int x, final int y, final int width,
336: final int height) {
337: int x2 = x + width;
338: int y1 = convY(y);
339: int y2 = convY(y + height);
340: int[] xPoints = { x, x2, x2, x };
341: int[] yPoints = { y1, y1, y2, y2 };
342: drawPolyline(xPoints, yPoints, 4, true, true);
343: }
344:
345: public void clearRect(final int x, final int y, final int width,
346: final int height) {
347: final Color savecolor = getColor();
348: setColor(bgColor);
349: fillRect(x, y, width, height);
350: setColor(savecolor);
351: }
352:
353: public void drawPolygon(final int[] xPoints, final int[] yPoints,
354: final int nPoints) {
355: for (int i = 0; i < nPoints; i++) {
356: yPoints[i] = convY(yPoints[i]);
357: }
358: drawPolyline(xPoints, yPoints, nPoints, true, false);
359: }
360:
361: public void drawPolyline(final int[] xPoints, final int[] yPoints,
362: final int nPoints) {
363: for (int i = 0; i < nPoints; i++) {
364: yPoints[i] = convY(yPoints[i]);
365: }
366: drawPolyline(xPoints, yPoints, nPoints, false, false);
367: }
368:
369: public void fillPolygon(final int[] xPoints, final int[] yPoints,
370: final int nPoints) {
371: for (int i = 0; i < nPoints; i++) {
372: yPoints[i] = convY(yPoints[i]);
373: }
374: drawPolyline(xPoints, yPoints, nPoints, true, true);
375: }
376:
377: public void draw(final Shape shape) {
378: drawShape(shape, false, true);
379: }
380:
381: public void fill(final Shape shape) {
382: drawShape(shape, true, true);
383: }
384:
385: private void drawShape(final Shape shape, final boolean fill,
386: final boolean stroke) {
387: final float[] coords = new float[6];
388: final PathIterator pathIterator = shape
389: .getPathIterator((AffineTransform) null);
390: float x = 0;
391: float y = 0;
392:
393: ps(PS.newpath);
394:
395: while (!pathIterator.isDone()) {
396: switch (pathIterator.currentSegment(coords)) {
397: case PathIterator.SEG_MOVETO: {
398: ps(PS.moveto, (int) coords[0], convY((int) coords[1]));
399: x = coords[0];
400: y = coords[1];
401: break;
402: }
403: case PathIterator.SEG_LINETO: {
404: ps(PS.lineto, (int) coords[0], convY((int) coords[1]));
405: x = coords[0];
406: y = coords[1];
407: break;
408: }
409: case PathIterator.SEG_QUADTO: {
410: final float x1 = (x + 2 * coords[0]) / 3;
411: final float y1 = (y + 2 * coords[1]) / 3;
412: final float x2 = (2 * coords[2] + coords[0]) / 3;
413: final float y2 = (2 * coords[3] + coords[1]) / 3;
414:
415: x = coords[2];
416: y = coords[3];
417: ps(PS.curveto, x1, convY((int) y1), x2,
418: convY((int) y2), x, convY((int) y));
419: break;
420: }
421: case PathIterator.SEG_CUBICTO: {
422: ps(PS.curveto, (int) coords[0], convY((int) coords[1]),
423: (int) coords[2], convY((int) coords[3]),
424: (int) coords[4], convY((int) coords[5]));
425: x = coords[4];
426: y = coords[5];
427: break;
428: }
429: case PathIterator.SEG_CLOSE: {
430: ps(PS.closepath);
431: break;
432: }
433: }
434: pathIterator.next();
435: }
436:
437: if (fill) {
438: ps(PS.fill);
439: }
440:
441: if (stroke) {
442: ps(PS.stroke);
443: }
444: }
445:
446: public void setColor(final Color color) {
447: super .setColor(color);
448: final float[] rgb = fgColor
449: .getRGBColorComponents((float[]) null);
450: ps(PS.setcolor, rgb[0], rgb[1], rgb[2]);
451: }
452:
453: public void setFont(final Font font) {
454: // looking for direct mapping of <name>.<style> to PostScript name
455: String psName = FONT_MAP.get(font.getName()
456: + "." + font.getStyle()); //$NON-NLS-1$
457:
458: if (psName == null) {
459: // looking for font name mapping
460: final String name = FONT_MAP.get(font.getName());
461: if (name != null) {
462: psName = PSFont.getPSName(name, font.getStyle());
463: }
464: }
465:
466: if (psName == null) {
467: psName = PSFont.Helvetica.psName;
468: }
469:
470: ps(PS.setfnt, psName, font.getSize());
471: super .setFont(font);
472: }
473:
474: public void translate(final int x, final int y) {
475: ps(PS.translate, x, -y);
476: }
477:
478: public void translate(final double x, final double y) {
479: translate((int) x, (int) y);
480: }
481:
482: public void rotate(final double theta) {
483: rotate(theta, 0d, 0d);
484: }
485:
486: public void rotate(final double theta, final double x,
487: final double y) {
488: final double alfa = -theta * 180 / java.lang.Math.PI;
489: final int x0 = (int) x;
490: final int y0 = convY((int) y);
491:
492: ps(PS.translate, x0, y0);
493: ps(PS.rotate, alfa);
494: ps(PS.translate, -x0, -y0);
495: }
496:
497: public void scale(final double sx, final double sy) {
498: ps(PS.scale, sx, sy);
499: yscale = yscale / sy;
500: }
501:
502: public void setClip(final int x, final int y, final int width,
503: final int height) {
504: setClip(new Rectangle(x, y, width, height));
505: }
506:
507: @Override
508: public void setClip(final Shape s) {
509: super .setClip(s);
510: drawShape(s, false, false);
511: ps(PS.clip);
512: }
513:
514: @Override
515: public void drawGlyphVector(GlyphVector g, float x, float y) {
516: // TODO Implement
517: }
518:
519: @Override
520: public GraphicsConfiguration getDeviceConfiguration() {
521: // TODO Implement
522: return null;
523: }
524:
525: @Override
526: public void copyArea(int sx, int sy, int width, int height, int dx,
527: int dy) {
528: // TODO Implement
529: }
530:
531: @Override
532: public Graphics create() {
533: return this ;
534: }
535:
536: @Override
537: public void setTransform(final AffineTransform transform) {
538: super .setTransform(transform);
539: ps(PS.concat, matrix[0], matrix[1], matrix[2], matrix[3],
540: matrix[4], matrix[5]);
541: }
542:
543: private static String wrapString(final String str) {
544: return str
545: .replace("\\", "\\\\").replace("\n", "\\\n").replace("\r", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$//$NON-NLS-5$
546: "\\\r").replace("(", "\\(").replace(")", "\\)"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
547: }
548:
549: private static String threebytes2Hex(int b) {
550: final char[] hex = { '0', '1', '2', '3', '4', '5', '6', '7',
551: '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
552: final char[] ret = new char[6];
553:
554: for (int i = 0; i < 6; i++) {
555: ret[5 - i] = hex[b & 0x0F];
556: b = b >> 4;
557: }
558: return new String(ret);
559: }
560:
561: private void drawImage(final Image image, final int x, final int y) {
562: drawImage(image, x, y, false, 0f, 0f);
563: }
564:
565: /**
566: * common private method for image drawing
567: */
568: private void drawImage(final Image image, final int x, final int y,
569: final boolean scale, final float sx, final float sy) {
570: if (image != null) {
571: final int imageHeight = image.getHeight(null);
572: final int imageWidth = image.getWidth(null);
573: final BufferedImage imageGIF = (BufferedImage) image;
574: int line = 0;
575: int comp;
576:
577: ps(PS.translate, x, y);
578:
579: if (scale) {
580: ps(PS.scale, sx, sy);
581: }
582:
583: out_stream.print(imageWidth);
584: out_stream.println(imageHeight + " 8"); //$NON-NLS-1$
585:
586: out_stream.println(" [1 0 0 -1 0 1]"); //$NON-NLS-1$
587: out_stream.println("{ currentfile"); //$NON-NLS-1$
588:
589: out_stream.println(" 32 string readhexstring pop"); //$NON-NLS-1$
590: out_stream.println("}"); //$NON-NLS-1$
591: out_stream.println("false 3"); //$NON-NLS-1$
592: out_stream.println("colorimage"); //$NON-NLS-1$
593:
594: for (int iy = 0; iy < imageHeight; iy++) {
595: for (int ix = 0; ix < imageWidth; ix++) {
596: comp = imageGIF.getRGB(ix, iy);
597: out_stream.print(threebytes2Hex(comp));
598: if (line++ == 30) {
599: out_stream.println();
600: line = 0;
601: }
602: }
603: if (line != 0) {
604: line = 0;
605: out_stream.println();
606: }
607: }
608:
609: if (scale) {
610: ps(PS.scale, 1 / sx, 1 / sy);
611: }
612: ps(PS.translate, -x, -y);
613: ps(PS.stroke);
614: }
615: }
616:
617: /**
618: * common private method for drawOval, fillOval, drawArc and fillArc
619: * methods.
620: */
621: private void drawArc(final int x, final int y, final int width,
622: final int height, final int startAngle, final int arcAngle,
623: final boolean fill) {
624: final int cx = x + width / 2;
625: final int cy = convY(y + height / 2);
626: final float scale1 = (float) width / (float) height;
627: final float scale2 = (float) height / (float) width;
628:
629: ps(PS.newpath);
630: ps(PS.scale, scale1, 1);
631: ps(PS.arc, (cx * scale2), cy, (height / 2), startAngle,
632: arcAngle);
633: if (fill) {
634: ps(PS.lineto, (cx * scale2), cy);
635: ps(PS.fill);
636: }
637: ps(PS.scale, scale2, 1);
638: ps(PS.stroke);
639: }
640:
641: /**
642: * common private method for drawRoundRect and fillRoundRect methods.
643: */
644: private void drawRoundRect(final int x, final int y,
645: final int width, final int height, final int arcWidth,
646: final int arcHeight, final boolean fill) {
647:
648: final int x1 = x + arcWidth;
649: final int x2 = x + width - arcWidth;
650: final int y1 = convY(y + arcHeight);
651: final int y2 = convY(y + height - arcHeight);
652: final float scale1 = (float) arcWidth / (float) arcHeight;
653: final float scale2 = (float) arcHeight / (float) arcWidth;
654:
655: ps(PS.newpath);
656: ps(PS.moveto, x, y1);
657: ps(PS.scale, scale1, 1);
658: ps(PS.arc, (x1 * scale2), y2, arcHeight, 180, 270);
659: ps(PS.arc, (x2 * scale2), y2, arcHeight, 270, 0);
660: ps(PS.arc, (x2 * scale2), y1, arcHeight, 0, 90);
661: ps(PS.arc, (x1 * scale2), y1, arcHeight, 90, 180);
662: ps(PS.scale, scale2, 1);
663:
664: if (fill) {
665: ps(PS.fill);
666: }
667: ps(PS.stroke);
668: }
669:
670: /**
671: * common private method for drawPolyline, drawPolygon, drawRect, clearRect,
672: * fillPolyline, fillPolygon and fillRect methods.
673: */
674: private void drawPolyline(final int[] xPoints, final int[] yPoints,
675: final int nPoints, final boolean close, final boolean fill) {
676: ps(PS.moveto, xPoints[0], yPoints[0]);
677:
678: for (int i = 1; i < nPoints; i++) {
679: ps(PS.lineto, xPoints[i], yPoints[i]);
680: }
681: if (close) {
682: ps(PS.closepath);
683: }
684: if (fill) {
685: ps(PS.fill);
686: }
687: ps(PS.stroke);
688: }
689:
690: private int drawPSString(final String text, final int x, final int y) {
691: final Rectangle2D r = font.getStringBounds(text, frc);
692: final double w = r.getWidth();
693:
694: ps(PS.show, "(" + wrapString(text) + ")", w, x, convY(y)); //$NON-NLS-1$ //$NON-NLS-2$
695: return (int) w;
696: }
697:
698: private int drawStringShape(final String str, final int x,
699: final int y) {
700: final TextLayout l = new TextLayout(str, font, frc);
701:
702: drawShape(l.getOutline(AffineTransform.getTranslateInstance(x,
703: y)), true, true);
704: return (int) font.getStringBounds(str, frc).getWidth();
705: }
706:
707: /**
708: * Generates PostScript procedure call with the specified arguments.
709: *
710: * @param ps procedure name
711: * @param args procedure arguments
712: */
713: private void ps(final PS ps, final Object... args) {
714: ps.print(out_stream, args);
715: }
716:
717: private int convY(final int y) {
718: return (int) (format.getHeight() * yscale) - y;
719: }
720:
721: private void resetGraphics() {
722: super .setTransform(new AffineTransform());
723: super .setClip(defaultClip);
724: super .setFont(DEF_FONT);
725: super .setColor(Color.BLACK);
726: super .setBackground(Color.WHITE);
727: }
728:
729: private enum PS {
730: arc, clip, closepath, curveto, def, exch, fill, grestore, gsave, lineto, moveto, newpath, rlineto, rmoveto, rotate, scale, scalefont, setfont, setlinewidth, show(
731: null, "%s %s %s %s S"), //$NON-NLS-1$
732: showpage, stroke, translate, comment(null, "%%%%%s"), //$NON-NLS-1$
733: concat(null, "[%s %s %s %s %s %s] concat"), //$NON-NLS-1$
734: setcolor("C", null), //$NON-NLS-1$
735: setfnt(null, "/%s %s F"), //$NON-NLS-1$
736: setDefGstate(null, "/DEF_GSTATE gstate def"), //$NON-NLS-1$
737: restoreDefGstate(null, "DEF_GSTATE setgstate"); //$NON-NLS-1$
738:
739: final String name;
740: final String format;
741:
742: PS() {
743: this (null, null);
744: }
745:
746: PS(final String name, final String format) {
747: this .name = (name != null) ? name : name();
748: this .format = format;
749: }
750:
751: static void printHeader(final PrintStream out) {
752: out.println("%!PS-Adobe-3"); //$NON-NLS-1$
753: out.println("%%Title: G2D generated document"); //$NON-NLS-1$
754: out.println("%%Creator: Apache Harmony"); //$NON-NLS-1$
755: out.println("%%CreationDate: " + new Date()); //$NON-NLS-1$
756: out.println("%%EndComments"); //$NON-NLS-1$
757: out
758: .println("/F {exch findfont exch scalefont setfont} def"); //$NON-NLS-1$
759: out.println("/C {setrgbcolor} bind def"); //$NON-NLS-1$
760: out
761: .println("/S {gsave moveto 1 index stringwidth pop div 1 scale " //$NON-NLS-1$
762: + "show grestore} def"); //$NON-NLS-1$
763: }
764:
765: static void printFooter(final PrintStream out) {
766: out.println("%%EOF"); //$NON-NLS-1$
767: }
768:
769: void print(final PrintStream out, final Object... args) {
770: if (format != null) {
771: out.printf(format, args);
772: out.println();
773: } else {
774: for (Object arg : args) {
775: out.print(arg + " "); //$NON-NLS-1$
776: }
777: out.println(name);
778: }
779: }
780: }
781:
782: private enum PSFont {
783: Times_Roman("Times", null, Font.PLAIN), //$NON-NLS-1$
784: Times_Italic("Times", null, Font.ITALIC), //$NON-NLS-1$
785: Times_Bold("Times", null, Font.BOLD), //$NON-NLS-1$
786: Times_BoldItalic("Times", null, Font.BOLD + Font.ITALIC), //$NON-NLS-1$
787: Helvetica("Helvetica", null, Font.PLAIN), //$NON-NLS-1$
788: Helvetica_Oblique("Helvetica", null, Font.ITALIC), //$NON-NLS-1$
789: Helvetica_Bold("Helvetica", null, Font.BOLD), //$NON-NLS-1$
790: Helvetica_BoldOblique(
791: "Helvetica", null, Font.BOLD + Font.ITALIC), //$NON-NLS-1$
792: Courier("Courier", null, Font.PLAIN), //$NON-NLS-1$
793: Courier_Oblique("Courier", null, Font.ITALIC), //$NON-NLS-1$
794: Courier_Bold("Courier", null, Font.BOLD), //$NON-NLS-1$
795: Courier_BoldOblique("Courier", null, Font.BOLD + Font.ITALIC); //$NON-NLS-1$
796:
797: final String name;
798: final String psName;
799: final int style;
800:
801: PSFont(final String name, final String psName, final int style) {
802: this .name = name;
803: this .psName = (psName != null) ? psName : name().replace(
804: '_', '-');
805: this .style = style;
806: }
807:
808: static String getPSName(final String name, final int style) {
809: for (PSFont f : values()) {
810: if ((f.style == style) && f.name.equalsIgnoreCase(name)) {
811: return f.psName;
812: }
813: }
814: return null;
815: }
816: }
817: }
|