KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fop > render > ps > PSGraphics2D


1 /*
2  * $Id: PSGraphics2D.java,v 1.2.2.5 2003/05/15 06:50:17 jeremias Exp $
3  * ============================================================================
4  * The Apache Software License, Version 1.1
5  * ============================================================================
6  *
7  * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without modifica-
10  * tion, are permitted provided that the following conditions are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * 3. The end-user documentation included with the redistribution, if any, must
20  * include the following acknowledgment: "This product includes software
21  * developed by the Apache Software Foundation (http://www.apache.org/)."
22  * Alternately, this acknowledgment may appear in the software itself, if
23  * and wherever such third-party acknowledgments normally appear.
24  *
25  * 4. The names "FOP" and "Apache Software Foundation" must not be used to
26  * endorse or promote products derived from this software without prior
27  * written permission. For written permission, please contact
28  * apache@apache.org.
29  *
30  * 5. Products derived from this software may not be called "Apache", nor may
31  * "Apache" appear in their name, without prior written permission of the
32  * Apache Software Foundation.
33  *
34  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
35  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
36  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
37  * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
38  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
39  * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
40  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
41  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
42  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
43  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44  * ============================================================================
45  *
46  * This software consists of voluntary contributions made by many individuals
47  * on behalf of the Apache Software Foundation and was originally created by
48  * James Tauber <jtauber@jtauber.com>. For more information on the Apache
49  * Software Foundation, please see <http://www.apache.org/>.
50  */

51 package org.apache.fop.render.ps;
52
53 import org.apache.fop.pdf.*;
54 import org.apache.fop.layout.*;
55 import org.apache.fop.image.*;
56 import org.apache.fop.datatypes.ColorSpace;
57
58 import org.apache.batik.ext.awt.g2d.*;
59
60 import java.text.AttributedCharacterIterator JavaDoc;
61 import java.text.CharacterIterator JavaDoc;
62 import java.awt.*;
63 import java.awt.Font JavaDoc;
64 import java.awt.Image JavaDoc;
65 import java.awt.image.*;
66 import java.awt.geom.*;
67 import java.awt.image.renderable.*;
68
69 import java.util.Map JavaDoc;
70 import java.util.ArrayList JavaDoc;
71
72 /**
73  * This concrete implementation of <tt>AbstractGraphics2D</tt> is a
74  * simple help to programmers to get started with their own
75  * implementation of <tt>Graphics2D</tt>.
76  * <tt>DefaultGraphics2D</tt> implements all the abstract methods
77  * is <tt>AbstractGraphics2D</tt> and makes it easy to start
78  * implementing a <tt>Graphic2D</tt> piece-meal.
79  *
80  * @author <a HREF="mailto:keiron@aftexsw.com">Keiron Liddle</a>
81  * @version $Id: PSGraphics2D.java,v 1.2.2.5 2003/05/15 06:50:17 jeremias Exp $
82  * @see org.apache.batik.ext.awt.g2d.AbstractGraphics2D
83  */

84 public class PSGraphics2D extends AbstractGraphics2D {
85     boolean standalone = false;
86
87     /**
88      * the PDF Document being created
89      */

90     protected PSRenderer psRenderer;
91
92     protected FontState fontState;
93
94     /**
95      * the current (internal) font name
96      */

97     protected String JavaDoc currentFontName;
98
99     /**
100      * the current font size in millipoints
101      */

102     protected int currentFontSize;
103
104     /**
105      * the current vertical position in millipoints from bottom
106      */

107     protected int currentYPosition = 0;
108
109     /**
110      * the current horizontal position in millipoints from left
111      */

112     protected int currentXPosition = 0;
113
114     /**
115      * the current colour for use in svg
116      */

117     PDFColor currentColour = new PDFColor(0, 0, 0);
118
119     FontInfo fontInfo;
120
121     /**
122      * Create a new PDFGraphics2D with the given pdf document info.
123      * This is used to create a Graphics object for use inside an already
124      * existing document.
125      */

126     public PSGraphics2D(boolean textAsShapes, FontState fs, PSRenderer ren,
127                         String JavaDoc font, int size, int xpos, int ypos) {
128         super(textAsShapes);
129         psRenderer = ren;
130         currentFontName = font;
131         currentFontSize = size;
132         currentYPosition = ypos;
133         currentXPosition = xpos;
134         fontState = fs;
135     }
136
137     public PSGraphics2D(boolean textAsShapes) {
138         super(textAsShapes);
139     }
140
141     public void setGraphicContext(GraphicContext c) {
142         gc = c;
143     }
144
145     /**
146      * This constructor supports the create method
147      */

148     public PSGraphics2D(PSGraphics2D g) {
149         super(g);
150     }
151
152     /**
153      * Creates a new <code>Graphics</code> object that is
154      * a copy of this <code>Graphics</code> object.
155      * @return a new graphics context that is a copy of
156      * this graphics context.
157      */

158     public Graphics create() {
159         return new PSGraphics2D(this);
160     }
161
162     /**
163      * Draws as much of the specified image as is currently available.
164      * The image is drawn with its top-left corner at
165      * (<i>x</i>,&nbsp;<i>y</i>) in this graphics context's coordinate
166      * space. Transparent pixels in the image do not affect whatever
167      * pixels are already there.
168      * <p>
169      * This method returns immediately in all cases, even if the
170      * complete image has not yet been loaded, and it has not been dithered
171      * and converted for the current output device.
172      * <p>
173      * If the image has not yet been completely loaded, then
174      * <code>drawImage</code> returns <code>false</code>. As more of
175      * the image becomes available, the process that draws the image notifies
176      * the specified image observer.
177      * @param img the specified image to be drawn.
178      * @param x the <i>x</i> coordinate.
179      * @param y the <i>y</i> coordinate.
180      * @param observer object to be notified as more of
181      * the image is converted.
182      * @see java.awt.Image
183      * @see java.awt.image.ImageObserver
184      * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
185      */

186     public boolean drawImage(Image JavaDoc img, int x, int y,
187                              ImageObserver observer) {
188         // System.err.println("drawImage:x, y");
189

190         final int width = img.getWidth(observer);
191         final int height = img.getHeight(observer);
192         if (width == -1 || height == -1) {
193             return false;
194         }
195
196         Dimension size = new Dimension(width, height);
197         BufferedImage buf = buildBufferedImage(size);
198
199         java.awt.Graphics2D JavaDoc g = buf.createGraphics();
200         g.setComposite(AlphaComposite.SrcOver);
201         g.setBackground(new Color(1, 1, 1, 0));
202         g.setPaint(new Color(1, 1, 1, 0));
203         g.fillRect(0, 0, width, height);
204         g.clip(new Rectangle(0, 0, buf.getWidth(), buf.getHeight()));
205
206         if (!g.drawImage(img, 0, 0, observer)) {
207             return false;
208         }
209         g.dispose();
210
211         final byte[] result = new byte[buf.getWidth() * buf.getHeight() * 3];
212         final byte[] mask = new byte[buf.getWidth() * buf.getHeight()];
213
214         Raster raster = buf.getData();
215         DataBuffer bd = raster.getDataBuffer();
216
217         int count = 0;
218         int maskpos = 0;
219         switch (bd.getDataType()) {
220         case DataBuffer.TYPE_INT:
221             int[][] idata = ((DataBufferInt)bd).getBankData();
222             for (int i = 0; i < idata.length; i++) {
223                 for (int j = 0; j < idata[i].length; j++) {
224                     // mask[maskpos++] = (byte)((idata[i][j] >> 24) & 0xFF);
225
if (((idata[i][j] >> 24) & 0xFF) != 255) {
226                         result[count++] = (byte)0xFF;
227                         result[count++] = (byte)0xFF;
228                         result[count++] = (byte)0xFF;
229                     } else {
230                         result[count++] = (byte)((idata[i][j] >> 16) & 0xFF);
231                         result[count++] = (byte)((idata[i][j] >> 8) & 0xFF);
232                         result[count++] = (byte)((idata[i][j]) & 0xFF);
233                     }
234                 }
235             }
236             break;
237         default:
238             // error
239
break;
240         }
241
242         try {
243             FopImage fopimg = new TempImage(width, height, result, mask);
244             AffineTransform at = getTransform();
245             double[] matrix = new double[6];
246             at.getMatrix(matrix);
247             psRenderer.write("gsave");
248             Shape imclip = getClip();
249             writeClip(imclip);
250             psRenderer.write("1000 -1000 scale");
251             // psRenderer.write("" + matrix[0] + " " + matrix[1] +
252
// " " + matrix[2] + " " + matrix[3] + " " +
253
// matrix[4] + " " + matrix[5] + " cm\n");
254
psRenderer.renderBitmap(fopimg, x, -y, width, height);
255             psRenderer.write("grestore");
256         } catch (Exception JavaDoc e) {
257             e.printStackTrace();
258         }
259         return true;
260     }
261
262     public BufferedImage buildBufferedImage(Dimension size) {
263         return new BufferedImage(size.width, size.height,
264                                  BufferedImage.TYPE_INT_ARGB);
265     }
266
267     class TempImage implements FopImage {
268         int m_height;
269         int m_width;
270         int m_bitsPerPixel;
271         ColorSpace m_colorSpace;
272         int m_bitmapSiye;
273         byte[] m_bitmaps;
274         byte[] m_mask;
275         PDFColor transparent = new PDFColor(255, 255, 255);
276
277         TempImage(int width, int height, byte[] result,
278                   byte[] mask) throws FopImageException {
279             this.m_height = height;
280             this.m_width = width;
281             this.m_bitsPerPixel = 8;
282             this.m_colorSpace = new ColorSpace(ColorSpace.DEVICE_RGB);
283             // this.m_isTransparent = false;
284
// this.m_bitmapsSize = this.m_width * this.m_height * 3;
285
this.m_bitmaps = result;
286             this.m_mask = mask;
287         }
288     public boolean invertImage() {
289 return false;
290 }
291
292         public String JavaDoc getURL() {
293             return "" + m_bitmaps;
294         }
295
296         // image size
297
public int getWidth() throws FopImageException {
298             return m_width;
299         }
300
301         public int getHeight() throws FopImageException {
302             return m_height;
303         }
304
305         // DeviceGray, DeviceRGB, or DeviceCMYK
306
public ColorSpace getColorSpace() throws FopImageException {
307             return m_colorSpace;
308         }
309
310         // bits per pixel
311
public int getBitsPerPixel() throws FopImageException {
312             return m_bitsPerPixel;
313         }
314
315         // For transparent images
316
public boolean isTransparent() throws FopImageException {
317             return transparent != null;
318         }
319
320         public PDFColor getTransparentColor() throws FopImageException {
321             return transparent;
322         }
323
324         public byte[] getMask() throws FopImageException {
325             return m_mask;
326         }
327
328         // get the image bytes, and bytes properties
329

330         // get uncompressed image bytes
331
public byte[] getBitmaps() throws FopImageException {
332             return m_bitmaps;
333         }
334
335         // width * (bitsPerPixel / 8) * height, no ?
336
public int getBitmapsSize() throws FopImageException {
337             return m_width * m_height * 3;
338         }
339
340         // get compressed image bytes
341
// I don't know if we really need it, nor if it
342
// should be changed...
343
public byte[] getRessourceBytes() throws FopImageException {
344             return null;
345         }
346
347         public int getRessourceBytesSize() throws FopImageException {
348             return 0;
349         }
350
351         // return null if no corresponding PDFFilter
352
public PDFFilter getPDFFilter() throws FopImageException {
353             return null;
354         }
355
356         // release memory
357
public void close() {}
358
359     }
360
361
362     /**
363      * Draws as much of the specified image as has already been scaled
364      * to fit inside the specified rectangle.
365      * <p>
366      * The image is drawn inside the specified rectangle of this
367      * graphics context's coordinate space, and is scaled if
368      * necessary. Transparent pixels do not affect whatever pixels
369      * are already there.
370      * <p>
371      * This method returns immediately in all cases, even if the
372      * entire image has not yet been scaled, dithered, and converted
373      * for the current output device.
374      * If the current output representation is not yet complete, then
375      * <code>drawImage</code> returns <code>false</code>. As more of
376      * the image becomes available, the process that draws the image notifies
377      * the image observer by calling its <code>imageUpdate</code> method.
378      * <p>
379      * A scaled version of an image will not necessarily be
380      * available immediately just because an unscaled version of the
381      * image has been constructed for this output device. Each size of
382      * the image may be cached separately and generated from the original
383      * data in a separate image production sequence.
384      * @param img the specified image to be drawn.
385      * @param x the <i>x</i> coordinate.
386      * @param y the <i>y</i> coordinate.
387      * @param width the width of the rectangle.
388      * @param height the height of the rectangle.
389      * @param observer object to be notified as more of
390      * the image is converted.
391      * @see java.awt.Image
392      * @see java.awt.image.ImageObserver
393      * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
394      */

395     public boolean drawImage(Image JavaDoc img, int x, int y, int width, int height,
396                              ImageObserver observer) {
397         System.out.println("drawImage");
398         return true;
399     }
400
401     /**
402      * Disposes of this graphics context and releases
403      * any system resources that it is using.
404      * A <code>Graphics</code> object cannot be used after
405      * <code>dispose</code>has been called.
406      * <p>
407      * When a Java program runs, a large number of <code>Graphics</code>
408      * objects can be created within a short time frame.
409      * Although the finalization process of the garbage collector
410      * also disposes of the same system resources, it is preferable
411      * to manually free the associated resources by calling this
412      * method rather than to rely on a finalization process which
413      * may not run to completion for a long period of time.
414      * <p>
415      * Graphics objects which are provided as arguments to the
416      * <code>paint</code> and <code>update</code> methods
417      * of components are automatically released by the system when
418      * those methods return. For efficiency, programmers should
419      * call <code>dispose</code> when finished using
420      * a <code>Graphics</code> object only if it was created
421      * directly from a component or another <code>Graphics</code> object.
422      * @see java.awt.Graphics#finalize
423      * @see java.awt.Component#paint
424      * @see java.awt.Component#update
425      * @see java.awt.Component#getGraphics
426      * @see java.awt.Graphics#create
427      */

428     public void dispose() {
429         // System.out.println("dispose");
430
psRenderer = null;
431         fontState = null;
432         currentFontName = null;
433         currentColour = null;
434         fontInfo = null;
435     }
436
437     /**
438      * Strokes the outline of a <code>Shape</code> using the settings of the
439      * current <code>Graphics2D</code> context. The rendering attributes
440      * applied include the <code>Clip</code>, <code>Transform</code>,
441      * <code>Paint</code>, <code>Composite</code> and
442      * <code>Stroke</code> attributes.
443      * @param s the <code>Shape</code> to be rendered
444      * @see #setStroke
445      * @see #setPaint
446      * @see java.awt.Graphics#setColor
447      * @see #transform
448      * @see #setTransform
449      * @see #clip
450      * @see #setClip
451      * @see #setComposite
452      */

453     public void draw(Shape s) {
454         // System.out.println("draw(Shape)");
455
psRenderer.write("gsave");
456         Shape imclip = getClip();
457         writeClip(imclip);
458         Color c = getColor();
459         psRenderer.write(c.getRed() + " " + c.getGreen() + " " + c.getBlue()
460                          + " setrgbcolor");
461
462         applyPaint(getPaint(), false);
463         applyStroke(getStroke());
464
465         psRenderer.write("newpath");
466         PathIterator iter = s.getPathIterator(getTransform());
467         while (!iter.isDone()) {
468             double vals[] = new double[6];
469             int type = iter.currentSegment(vals);
470             switch (type) {
471             case PathIterator.SEG_CUBICTO:
472                 psRenderer.write(PDFNumber.doubleOut(1000 * vals[0]) + " "
473                                  + PDFNumber.doubleOut(1000 * vals[1]) + " "
474                                  + PDFNumber.doubleOut(1000 * vals[2]) + " "
475                                  + PDFNumber.doubleOut(1000 * vals[3]) + " "
476                                  + PDFNumber.doubleOut(1000 * vals[4]) + " "
477                                  + PDFNumber.doubleOut(1000 * vals[5])
478                                  + " curveto");
479                 break;
480             case PathIterator.SEG_LINETO:
481                 psRenderer.write(PDFNumber.doubleOut(1000 * vals[0]) + " "
482                                  + PDFNumber.doubleOut(1000 * vals[1])
483                                  + " lineto");
484                 break;
485             case PathIterator.SEG_MOVETO:
486                 psRenderer.write(PDFNumber.doubleOut(1000 * vals[0]) + " "
487                                  + PDFNumber.doubleOut(1000 * vals[1])
488                                  + " M");
489                 break;
490             case PathIterator.SEG_QUADTO:
491                 // psRenderer.write((1000 * PDFNumber.doubleOut(vals[0])) +
492
// " " + (1000 * PDFNumber.doubleOut(vals[1])) + " " +
493
// (1000 * PDFNumber.doubleOut(vals[2])) + " " +
494
// (1000 * PDFNumber.doubleOut(vals[3])) + " y\n");
495
break;
496             case PathIterator.SEG_CLOSE:
497                 psRenderer.write("closepath");
498                 break;
499             default:
500                 break;
501             }
502             iter.next();
503         }
504         doDrawing(false, true, false);
505         psRenderer.write("grestore");
506     }
507
508     protected void writeClip(Shape s) {
509         PathIterator iter = s.getPathIterator(getTransform());
510         psRenderer.write("newpath");
511         while (!iter.isDone()) {
512             double vals[] = new double[6];
513             int type = iter.currentSegment(vals);
514             switch (type) {
515             case PathIterator.SEG_CUBICTO:
516                 psRenderer.write(PDFNumber.doubleOut(1000 * vals[0]) + " "
517                                  + PDFNumber.doubleOut(1000 * vals[1]) + " "
518                                  + PDFNumber.doubleOut(1000 * vals[2]) + " "
519                                  + PDFNumber.doubleOut(1000 * vals[3]) + " "
520                                  + PDFNumber.doubleOut(1000 * vals[4]) + " "
521                                  + PDFNumber.doubleOut(1000 * vals[5])
522                                  + " curveto");
523                 break;
524             case PathIterator.SEG_LINETO:
525                 psRenderer.write(PDFNumber.doubleOut(1000 * vals[0]) + " "
526                                  + PDFNumber.doubleOut(1000 * vals[1])
527                                  + " lineto");
528                 break;
529             case PathIterator.SEG_MOVETO:
530                 psRenderer.write(PDFNumber.doubleOut(1000 * vals[0]) + " "
531                                  + PDFNumber.doubleOut(1000 * vals[1])
532                                  + " M");
533                 break;
534             case PathIterator.SEG_QUADTO:
535                 // psRenderer.write(1000 * PDFNumber.doubleOut(vals[0]) +
536
// " " + 1000 * PDFNumber.doubleOut(vals[1]) + " " +
537
// 1000 * PDFNumber.doubleOut(vals[2]) + " " +
538
// 1000 * PDFNumber.doubleOut(vals[3]) + " y\n");
539
break;
540             case PathIterator.SEG_CLOSE:
541                 psRenderer.write("closepath");
542                 break;
543             default:
544                 break;
545             }
546             iter.next();
547         }
548         // clip area
549
psRenderer.write("clippath");
550     }
551
552     protected void applyPaint(Paint paint, boolean fill) {
553         if (paint instanceof GradientPaint) {
554             GradientPaint gp = (GradientPaint)paint;
555             Color c1 = gp.getColor1();
556             Color c2 = gp.getColor2();
557             Point2D p1 = gp.getPoint1();
558             Point2D p2 = gp.getPoint2();
559             boolean cyclic = gp.isCyclic();
560
561             ArrayList JavaDoc theCoords = new ArrayList JavaDoc();
562             theCoords.add(new Double JavaDoc(p1.getX()));
563             theCoords.add(new Double JavaDoc(p1.getY()));
564             theCoords.add(new Double JavaDoc(p2.getX()));
565             theCoords.add(new Double JavaDoc(p2.getY()));
566
567             ArrayList JavaDoc theExtend = new ArrayList JavaDoc();
568             theExtend.add(new Boolean JavaDoc(true));
569             theExtend.add(new Boolean JavaDoc(true));
570
571             ArrayList JavaDoc theDomain = new ArrayList JavaDoc();
572             theDomain.add(new Double JavaDoc(0));
573             theDomain.add(new Double JavaDoc(1));
574
575             ArrayList JavaDoc theEncode = new ArrayList JavaDoc();
576             theEncode.add(new Double JavaDoc(0));
577             theEncode.add(new Double JavaDoc(1));
578             theEncode.add(new Double JavaDoc(0));
579             theEncode.add(new Double JavaDoc(1));
580
581             ArrayList JavaDoc theBounds = new ArrayList JavaDoc();
582             theBounds.add(new Double JavaDoc(0));
583             theBounds.add(new Double JavaDoc(1));
584
585             ArrayList JavaDoc theFunctions = new ArrayList JavaDoc();
586
587             ArrayList JavaDoc someColors = new ArrayList JavaDoc();
588
589             PDFColor color1 = new PDFColor(c1.getRed(), c1.getGreen(),
590                                            c1.getBlue());
591             someColors.add(color1);
592             PDFColor color2 = new PDFColor(c2.getRed(), c2.getGreen(),
593                                            c2.getBlue());
594             someColors.add(color2);
595
596             ColorSpace aColorSpace = new ColorSpace(ColorSpace.DEVICE_RGB);
597         } else if (paint instanceof TexturePaint) {}
598     }
599
600     protected void applyStroke(Stroke stroke) {
601         if (stroke instanceof BasicStroke) {
602             BasicStroke bs = (BasicStroke)stroke;
603
604             float[] da = bs.getDashArray();
605             if (da != null) {
606                 psRenderer.write("[");
607                 for (int count = 0; count < da.length; count++) {
608                     psRenderer.write("" + (1000 * (int)da[count]));
609                     if (count < da.length - 1) {
610                         psRenderer.write(" ");
611                     }
612                 }
613                 psRenderer.write("] ");
614                 float offset = bs.getDashPhase();
615                 psRenderer.write((1000 * (int)offset) + " setdash");
616             }
617             int ec = bs.getEndCap();
618             switch (ec) {
619             case BasicStroke.CAP_BUTT:
620                 psRenderer.write(0 + " setlinecap");
621                 break;
622             case BasicStroke.CAP_ROUND:
623                 psRenderer.write(1 + " setlinecap");
624                 break;
625             case BasicStroke.CAP_SQUARE:
626                 psRenderer.write(2 + " setlinecap");
627                 break;
628             }
629
630             int lj = bs.getLineJoin();
631             switch (lj) {
632             case BasicStroke.JOIN_MITER:
633                 psRenderer.write(0 + " setlinejoin");
634                 break;
635             case BasicStroke.JOIN_ROUND:
636                 psRenderer.write(1 + " setlinejoin");
637                 break;
638             case BasicStroke.JOIN_BEVEL:
639                 psRenderer.write(2 + " setlinejoin");
640                 break;
641             }
642             float lw = bs.getLineWidth();
643             psRenderer.write(PDFNumber.doubleOut(1000 * lw)
644                              + " setlinewidth");
645
646             float ml = bs.getMiterLimit();
647             psRenderer.write(PDFNumber.doubleOut(1000 * ml)
648                              + " setmiterlimit");
649         }
650     }
651
652     /**
653      * Renders a {@link RenderedImage},
654      * applying a transform from image
655      * space into user space before drawing.
656      * The transformation from user space into device space is done with
657      * the current <code>Transform</code> in the <code>Graphics2D</code>.
658      * The specified transformation is applied to the image before the
659      * transform attribute in the <code>Graphics2D</code> context is applied.
660      * The rendering attributes applied include the <code>Clip</code>,
661      * <code>Transform</code>, and <code>Composite</code> attributes. Note
662      * that no rendering is done if the specified transform is
663      * noninvertible.
664      * @param img the image to be rendered
665      * @param xform the transformation from image space into user space
666      * @see #transform
667      * @see #setTransform
668      * @see #setComposite
669      * @see #clip
670      * @see #setClip
671      */

672     public void drawRenderedImage(RenderedImage img, AffineTransform xform) {
673         System.out.println("drawRenderedImage");
674     }
675
676
677     /**
678      * Renders a
679      * {@link RenderableImage},
680      * applying a transform from image space into user space before drawing.
681      * The transformation from user space into device space is done with
682      * the current <code>Transform</code> in the <code>Graphics2D</code>.
683      * The specified transformation is applied to the image before the
684      * transform attribute in the <code>Graphics2D</code> context is applied.
685      * The rendering attributes applied include the <code>Clip</code>,
686      * <code>Transform</code>, and <code>Composite</code> attributes. Note
687      * that no rendering is done if the specified transform is
688      * noninvertible.
689      * <p>
690      * Rendering hints set on the <code>Graphics2D</code> object might
691      * be used in rendering the <code>RenderableImage</code>.
692      * If explicit control is required over specific hints recognized by a
693      * specific <code>RenderableImage</code>, or if knowledge of which hints
694      * are used is required, then a <code>RenderedImage</code> should be
695      * obtained directly from the <code>RenderableImage</code>
696      * and rendered using
697      * {@link #drawRenderedImage(RenderedImage, AffineTransform) drawRenderedImage}.
698      * @param img the image to be rendered
699      * @param xform the transformation from image space into user space
700      * @see #transform
701      * @see #setTransform
702      * @see #setComposite
703      * @see #clip
704      * @see #setClip
705      * @see #drawRenderedImage
706      */

707     public void drawRenderableImage(RenderableImage img,
708                                     AffineTransform xform) {
709         System.out.println("drawRenderableImage");
710     }
711
712     /**
713      * Renders the text specified by the specified <code>String</code>,
714      * using the current <code>Font</code> and <code>Paint</code> attributes
715      * in the <code>Graphics2D</code> context.
716      * The baseline of the first character is at position
717      * (<i>x</i>,&nbsp;<i>y</i>) in the User Space.
718      * The rendering attributes applied include the <code>Clip</code>,
719      * <code>Transform</code>, <code>Paint</code>, <code>Font</code> and
720      * <code>Composite</code> attributes. For characters in script systems
721      * such as Hebrew and Arabic, the glyphs can be rendered from right to
722      * left, in which case the coordinate supplied is the location of the
723      * leftmost character on the baseline.
724      * @param s the <code>String</code> to be rendered
725      * @param x,&nbsp;y the coordinates where the <code>String</code>
726      * should be rendered
727      * @see #setPaint
728      * @see java.awt.Graphics#setColor
729      * @see java.awt.Graphics#setFont
730      * @see #setTransform
731      * @see #setComposite
732      * @see #setClip
733      */

734     public void drawString(String JavaDoc s, float x, float y) {
735         System.out.println("drawString(String)");
736         psRenderer.write("BT");
737         Shape imclip = getClip();
738         writeClip(imclip);
739         Color c = getColor();
740         psRenderer.write(c.getRed() + " " + c.getGreen() + " " + c.getBlue()
741                          + " setrgbcolor");
742
743         AffineTransform trans = getTransform();
744         trans.translate(x, y);
745         double[] vals = new double[6];
746         trans.getMatrix(vals);
747
748         psRenderer.write(PDFNumber.doubleOut(vals[0]) + " "
749                          + PDFNumber.doubleOut(vals[1]) + " "
750                          + PDFNumber.doubleOut(vals[2]) + " "
751                          + PDFNumber.doubleOut(vals[3]) + " "
752                          + PDFNumber.doubleOut(vals[4]) + " "
753                          + PDFNumber.doubleOut(vals[5]) + " "
754                          + PDFNumber.doubleOut(vals[6]) + " Tm [" + s + "]");
755
756         psRenderer.write("ET");
757     }
758
759     /**
760      * Renders the text of the specified iterator, using the
761      * <code>Graphics2D</code> context's current <code>Paint</code>. The
762      * iterator must specify a font
763      * for each character. The baseline of the
764      * first character is at position (<i>x</i>,&nbsp;<i>y</i>) in the
765      * User Space.
766      * The rendering attributes applied include the <code>Clip</code>,
767      * <code>Transform</code>, <code>Paint</code>, and
768      * <code>Composite</code> attributes.
769      * For characters in script systems such as Hebrew and Arabic,
770      * the glyphs can be rendered from right to left, in which case the
771      * coordinate supplied is the location of the leftmost character
772      * on the baseline.
773      * @param iterator the iterator whose text is to be rendered
774      * @param x,&nbsp;y the coordinates where the iterator's text is to be
775      * rendered
776      * @see #setPaint
777      * @see java.awt.Graphics#setColor
778      * @see #setTransform
779      * @see #setComposite
780      * @see #setClip
781      */

782     public void drawString(AttributedCharacterIterator JavaDoc iterator, float x,
783                            float y) {
784         System.err.println("drawString(AttributedCharacterIterator)");
785
786         psRenderer.write("BT");
787         Shape imclip = getClip();
788         writeClip(imclip);
789         Color c = getColor();
790         currentColour = new PDFColor(c.getRed(), c.getGreen(), c.getBlue());
791         psRenderer.write(currentColour.getColorSpaceOut(true));
792         c = getBackground();
793         PDFColor col = new PDFColor(c.getRed(), c.getGreen(), c.getBlue());
794         psRenderer.write(col.getColorSpaceOut(false));
795
796         AffineTransform trans = getTransform();
797         trans.translate(x, y);
798         double[] vals = new double[6];
799         trans.getMatrix(vals);
800
801         for (char ch = iterator.first(); ch != CharacterIterator.DONE;
802                 ch = iterator.next()) {
803             Map JavaDoc attr = iterator.getAttributes();
804
805             psRenderer.write(PDFNumber.doubleOut(vals[0]) + " "
806                              + PDFNumber.doubleOut(vals[1]) + " "
807                              + PDFNumber.doubleOut(vals[2]) + " "
808                              + PDFNumber.doubleOut(vals[3]) + " "
809                              + PDFNumber.doubleOut(vals[4]) + " "
810                              + PDFNumber.doubleOut(vals[5]) + " "
811                              + PDFNumber.doubleOut(vals[6]) + " Tm [" + ch
812                              + "]");
813         }
814
815         psRenderer.write("ET");
816     }
817
818     /**
819      * Fills the interior of a <code>Shape</code> using the settings of the
820      * <code>Graphics2D</code> context. The rendering attributes applied
821      * include the <code>Clip</code>, <code>Transform</code>,
822      * <code>Paint</code>, and <code>Composite</code>.
823      * @param s the <code>Shape</code> to be filled
824      * @see #setPaint
825      * @see java.awt.Graphics#setColor
826      * @see #transform
827      * @see #setTransform
828      * @see #setComposite
829      * @see #clip
830      * @see #setClip
831      */

832     public void fill(Shape s) {
833         // System.err.println("fill");
834
psRenderer.write("gsave");
835         Shape imclip = getClip();
836         writeClip(imclip);
837         Color c = getColor();
838         psRenderer.write(c.getRed() + " " + c.getGreen() + " " + c.getBlue()
839                          + " setrgbcolor");
840
841         applyPaint(getPaint(), true);
842
843         psRenderer.write("newpath");
844         PathIterator iter = s.getPathIterator(getTransform());
845         while (!iter.isDone()) {
846             double vals[] = new double[6];
847             int type = iter.currentSegment(vals);
848             switch (type) {
849             case PathIterator.SEG_CUBICTO:
850                 psRenderer.write(PDFNumber.doubleOut(1000 * vals[0]) + " "
851                                  + PDFNumber.doubleOut(1000 * vals[1]) + " "
852                                  + PDFNumber.doubleOut(1000 * vals[2]) + " "
853                                  + PDFNumber.doubleOut(1000 * vals[3]) + " "
854                                  + PDFNumber.doubleOut(1000 * vals[4]) + " "
855                                  + PDFNumber.doubleOut(1000 * vals[5])
856                                  + " curveto");
857                 break;
858             case PathIterator.SEG_LINETO:
859                 psRenderer.write(PDFNumber.doubleOut(1000 * vals[0]) + " "
860                                  + PDFNumber.doubleOut(1000 * vals[1])
861                                  + " lineto");
862                 break;
863             case PathIterator.SEG_MOVETO:
864                 psRenderer.write(PDFNumber.doubleOut(1000 * vals[0]) + " "
865                                  + PDFNumber.doubleOut(1000 * vals[1])
866                                  + " M");
867                 break;
868             case PathIterator.SEG_QUADTO:
869                 // psRenderer.write(1000 * PDFNumber.doubleOut(vals[0]) +
870
// " " + 1000 * PDFNumber.doubleOut(vals[1]) + " " +
871
// 1000 * PDFNumber.doubleOut(vals[2]) + " " +
872
// 1000 * PDFNumber.doubleOut(vals[3]) + " y\n");
873
break;
874             case PathIterator.SEG_CLOSE:
875                 psRenderer.write("closepath");
876                 break;
877             default:
878                 break;
879             }
880             iter.next();
881         }
882         doDrawing(true, false,
883                   iter.getWindingRule() == PathIterator.WIND_EVEN_ODD);
884         psRenderer.write("grestore");
885     }
886
887     protected void doDrawing(boolean fill, boolean stroke, boolean nonzero) {
888         if (fill) {
889             if (stroke) {
890                 if (!nonzero)
891                     psRenderer.write("stroke");
892                 else
893                     psRenderer.write("stroke");
894             } else {
895                 if (!nonzero)
896                     psRenderer.write("fill");
897                 else
898                     psRenderer.write("fill");
899             }
900         } else {
901             // if(stroke)
902
psRenderer.write("stroke");
903         }
904     }
905
906     /**
907      * Returns the device configuration associated with this
908      * <code>Graphics2D</code>.
909      */

910     public GraphicsConfiguration getDeviceConfiguration() {
911         // System.out.println("getDeviceConviguration");
912
return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
913     }
914
915     /**
916      * Used to create proper font metrics
917      */

918     private Graphics2D fmg;
919
920     {
921         BufferedImage bi = new BufferedImage(1, 1,
922                                              BufferedImage.TYPE_INT_ARGB);
923
924         fmg = bi.createGraphics();
925     }
926
927     /**
928      * Gets the font metrics for the specified font.
929      * @return the font metrics for the specified font.
930      * @param f the specified font
931      * @see java.awt.Graphics#getFont
932      * @see java.awt.FontMetrics
933      * @see java.awt.Graphics#getFontMetrics()
934      */

935     public FontMetrics getFontMetrics(Font JavaDoc f) {
936         return fmg.getFontMetrics(f);
937     }
938
939     /**
940      * Sets the paint mode of this graphics context to alternate between
941      * this graphics context's current color and the new specified color.
942      * This specifies that logical pixel operations are performed in the
943      * XOR mode, which alternates pixels between the current color and
944      * a specified XOR color.
945      * <p>
946      * When drawing operations are performed, pixels which are the
947      * current color are changed to the specified color, and vice versa.
948      * <p>
949      * Pixels that are of colors other than those two colors are changed
950      * in an unpredictable but reversible manner; if the same figure is
951      * drawn twice, then all pixels are restored to their original values.
952      * @param c1 the XOR alternation color
953      */

954     public void setXORMode(Color c1) {
955         System.out.println("setXORMode");
956     }
957
958
959     /**
960      * Copies an area of the component by a distance specified by
961      * <code>dx</code> and <code>dy</code>. From the point specified
962      * by <code>x</code> and <code>y</code>, this method
963      * copies downwards and to the right. To copy an area of the
964      * component to the left or upwards, specify a negative value for
965      * <code>dx</code> or <code>dy</code>.
966      * If a portion of the source rectangle lies outside the bounds
967      * of the component, or is obscured by another window or component,
968      * <code>copyArea</code> will be unable to copy the associated
969      * pixels. The area that is omitted can be refreshed by calling
970      * the component's <code>paint</code> method.
971      * @param x the <i>x</i> coordinate of the source rectangle.
972      * @param y the <i>y</i> coordinate of the source rectangle.
973      * @param width the width of the source rectangle.
974      * @param height the height of the source rectangle.
975      * @param dx the horizontal distance to copy the pixels.
976      * @param dy the vertical distance to copy the pixels.
977      */

978     public void copyArea(int x, int y, int width, int height, int dx,
979                          int dy) {
980         System.out.println("copyArea");
981     }
982
983 }
984
Popular Tags