OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [java/] [awt/] [print/] [PostScriptGraphics2D.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* PostScriptGraphics2D.java -- AWT printer rendering class.
2
   Copyright (C) 2006  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
package gnu.java.awt.print;
39
 
40
import java.awt.BasicStroke;
41
import java.awt.Color;
42
import java.awt.Composite;
43
import java.awt.Paint;
44
import java.awt.Font;
45
import java.awt.FontMetrics;
46
import java.awt.GradientPaint;
47
import java.awt.Graphics;
48
import java.awt.GraphicsConfiguration;
49
import java.awt.Graphics2D;
50
import java.awt.Image;
51
import java.awt.Polygon;
52
import java.awt.Rectangle;
53
import java.awt.RenderingHints;
54
import java.awt.Shape;
55
import java.awt.Stroke;
56
import java.awt.geom.AffineTransform;
57
import java.awt.geom.Arc2D;
58
import java.awt.geom.Ellipse2D;
59
import java.awt.geom.RoundRectangle2D;
60
import java.awt.geom.PathIterator;
61
import java.awt.geom.Point2D;
62
import java.awt.geom.Rectangle2D;
63
import java.awt.font.FontRenderContext;
64
import java.awt.font.GlyphVector;
65
import java.awt.font.TextLayout;
66
import java.awt.image.BufferedImage;
67
import java.awt.image.BufferedImageOp;
68
import java.awt.image.renderable.RenderableImage;
69
import java.awt.image.RenderedImage;
70
import java.awt.image.ImageObserver;
71
import java.awt.image.PixelGrabber;
72
import java.awt.print.PageFormat;
73
import java.awt.print.Pageable;
74
import java.awt.print.Paper;
75
import java.awt.print.Printable;
76
import java.awt.print.PrinterException;
77
import java.awt.print.PrinterJob;
78
import java.io.BufferedWriter;
79
import java.io.File;
80
import java.io.FileOutputStream;
81
import java.io.IOException;
82
import java.io.OutputStreamWriter;
83
import java.io.PrintWriter;
84
import java.text.AttributedCharacterIterator;
85
import java.util.Map;
86
 
87
/**
88
 * Class PostScriptGraphics2D - Class that implements the Graphics2D object,
89
 * writing the output to a PostScript or EPS file
90
 *
91
 * @author Sven de Marothy
92
 *
93
 */
94
class PostScriptGraphics2D extends Graphics2D
95
{
96
  /**
97
   * The associated printer job.
98
   */
99
  private PrinterJob printerJob;
100
 
101
  /**
102
   * Output file.
103
   */
104
  private PrintWriter out;
105
 
106
  // Graphics data
107
  private AffineTransform currentTransform = new AffineTransform();
108
  private AffineTransform pageTransform;
109
  private RenderingHints renderingHints;
110
  private Paint currentPaint = null;
111
  private Shape clipShape = null;
112
  private Font currentFont = null;
113
  private Color currentColor = Color.black;
114
  private Color backgroundColor = Color.white;
115
  private Stroke currentStroke = null;
116
  private static Stroke ordinaryStroke = new BasicStroke(0.0f,
117
                                                         BasicStroke.CAP_BUTT,
118
                                                         BasicStroke.JOIN_MITER);
119
  private float cx; // current drawing position
120
  private float cy; // current drawing position
121
  private boolean currentFontIsPS; // set if currentFont is one of the above
122
 
123
  // settings
124
  private double pageX = 595;
125
  private double pageY = 842;
126
  private double Y = pageY;
127
  private boolean gradientOn = false;
128
 
129
  /**
130
   * Constructor
131
   *
132
   */
133
  public PostScriptGraphics2D( PrinterJob pg )
134
  {
135
    printerJob = pg;
136
    // create transform objects
137
    pageTransform = new AffineTransform();
138
    currentTransform = new AffineTransform();
139
 
140
    /*
141
      Create Rendering hints
142
      No text aliasing
143
      Quality color and rendering
144
      Bicubic interpolation
145
      Fractional metrics supported
146
    */
147
    renderingHints = new RenderingHints(null);
148
    renderingHints.put(RenderingHints.KEY_RENDERING,
149
                       RenderingHints.VALUE_RENDER_QUALITY);
150
    renderingHints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
151
                       RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
152
    renderingHints.put(RenderingHints.KEY_INTERPOLATION,
153
                       RenderingHints.VALUE_INTERPOLATION_BICUBIC);
154
    renderingHints.put(RenderingHints.KEY_FRACTIONALMETRICS,
155
                       RenderingHints.VALUE_FRACTIONALMETRICS_ON);
156
    renderingHints.put(RenderingHints.KEY_COLOR_RENDERING,
157
                       RenderingHints.VALUE_COLOR_RENDER_QUALITY);
158
  }
159
 
160
  /**
161
   * Spool a document to PostScript.
162
   * If Pageable is non-null, it will print that, otherwise it will use
163
   * the supplied printable and pageFormat.
164
   */
165
  public SpooledDocument spoolPostScript(Printable printable,
166
                                         PageFormat pageFormat,
167
                                         Pageable pageable)
168
    throws PrinterException
169
  {
170
    try
171
      {
172
        // spool to a temporary file
173
        File temp = File.createTempFile("cpspool", ".ps");
174
        temp.deleteOnExit();
175
 
176
        out = new PrintWriter(new BufferedWriter
177
                              (new OutputStreamWriter
178
                               (new FileOutputStream(temp),
179
                                "ISO8859_1"), 1000000));
180
 
181
        writePSHeader();
182
 
183
        if(pageable != null)
184
          {
185
            for(int index = 0; index < pageable.getNumberOfPages(); index++)
186
              spoolPage(out, pageable.getPrintable(index),
187
                        pageable.getPageFormat(index), index);
188
          }
189
        else
190
          {
191
            int index = 0;
192
            while(spoolPage(out, printable, pageFormat, index++) ==
193
                  Printable.PAGE_EXISTS)
194
              ;
195
          }
196
        out.println("%%Trailer");
197
        out.println("%%EOF");
198
        out.close();
199
        return new SpooledDocument( temp );
200
      }
201
    catch (IOException e)
202
      {
203
        PrinterException pe = new PrinterException();
204
        pe.initCause(e);
205
        throw pe;
206
      }
207
  }
208
 
209
  //--------------------------------------------------------------------------
210
 
211
  /**
212
   * Write the postscript file header,
213
   * setup the page format and transforms.
214
   */
215
  private void writePSHeader()
216
  {
217
    out.println("%!PS-Adobe-3.0");
218
    out.println("%%Title: "+printerJob.getJobName());
219
    out.println("%%Creator: GNU Classpath ");
220
    out.println("%%DocumentData: Clean8Bit");
221
 
222
    out.println("%%DocumentNeededResources: font Times-Roman Helvetica Courier");
223
    out.println("%%EndComments");
224
 
225
    out.println("%%BeginProlog");
226
    out.println("%%EndProlog");
227
    out.println("%%BeginSetup");
228
 
229
    out.println("%%EndFeature");
230
    setupFonts();
231
    out.println("%%EndSetup");
232
 
233
    // set default fonts and colors
234
    setFont( new Font("Dialog", Font.PLAIN, 12) );
235
    currentColor = Color.white;
236
    currentStroke = new BasicStroke();
237
    setPaint(currentColor);
238
    setStroke(currentStroke);
239
  }
240
 
241
  /**
242
   * setupFonts - set up the font dictionaries for
243
   * helvetica, times and courier
244
   */
245
  private void setupFonts()
246
  {
247
    out.println("/helveticaISO");
248
    out.println("/Helvetica findfont dup length dict begin");
249
    out.println("{ 1 index /FID eq { pop pop } { def } ifelse } forall");
250
    out.println("/Encoding ISOLatin1Encoding def");
251
    out.println("currentdict end definefont pop");
252
 
253
    out.println("/timesISO");
254
    out.println("/Times-Roman findfont dup length dict begin");
255
    out.println("{ 1 index /FID eq { pop pop } { def } ifelse } forall");
256
    out.println("/Encoding ISOLatin1Encoding def");
257
    out.println("currentdict end definefont pop");
258
 
259
    out.println("/courierISO");
260
    out.println("/Courier findfont dup length dict begin");
261
    out.println("{ 1 index /FID eq { pop pop } { def } ifelse } forall");
262
    out.println("/Encoding ISOLatin1Encoding def");
263
    out.println("currentdict end definefont pop");
264
  }
265
 
266
  /**
267
   * Spools a single page, returns NO_SUCH_PAGE unsuccessful,
268
   * PAGE_EXISTS if it was.
269
   */
270
  public int spoolPage(PrintWriter out,
271
                       Printable printable,
272
                       PageFormat pageFormat,
273
                       int index) throws IOException, PrinterException
274
  {
275
    out.println("%%BeginPageSetup");
276
 
277
    Paper p = pageFormat.getPaper();
278
    pageX = p.getWidth();
279
    pageY = p.getHeight();
280
 
281
    if( pageFormat.getOrientation() == PageFormat.PORTRAIT )
282
      out.println( "%%Orientation: Portrait" );
283
    else
284
      {
285
        out.println( "%%Orientation: Landscape" );
286
        double t = pageX;
287
        pageX = pageY;
288
        pageY = t;
289
      }
290
 
291
    setClip(0, 0, (int)pageX, (int)pageY);
292
 
293
    out.println("gsave % first save");
294
 
295
    // 595x842; 612x792 respectively
296
    out.println("<< /PageSize [" +pageX + " "+pageY+ "] >> setpagedevice");
297
 
298
    if( pageFormat.getOrientation() != PageFormat.LANDSCAPE )
299
      {
300
        pageTransform.translate(pageX, 0);
301
        pageTransform.scale(-1.0, 1.0);
302
      }
303
 
304
    // save the original CTM
305
    pushCTM();
306
    concatCTM(pageTransform);
307
    setTransform(new AffineTransform());
308
 
309
    out.println("%%EndPageSetup");
310
 
311
    out.println("gsave");
312
 
313
    if( printable.print(this, pageFormat, index) == Printable.NO_SUCH_PAGE )
314
      return Printable.NO_SUCH_PAGE;
315
 
316
    out.println("grestore");
317
    out.println("showpage");
318
 
319
    return Printable.PAGE_EXISTS;
320
  }
321
 
322
  /** push the Current Transformation Matrix onto the PS stack */
323
  private void pushCTM()
324
  {
325
    out.println("matrix currentmatrix   % pushCTM()");
326
  }
327
 
328
  /** pop the Current Transformation Matrix from the PS stack */
329
  private void popCTM()
330
  {
331
    out.println("setmatrix % restore CTM");
332
  }
333
 
334
  ///////////////////////////////////////////////////////////////////////////
335
 
336
  public Graphics create()
337
  {
338
    return null;
339
  }
340
 
341
  public void drawOval(int x, int y, int width, int height)
342
  {
343
    out.println("% drawOval()");
344
    setStroke(ordinaryStroke);
345
    draw(new Ellipse2D.Double(x, y, width, height));
346
    setStroke(currentStroke);
347
  }
348
 
349
  public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
350
  {
351
    if (nPoints <= 0 || xPoints.length < nPoints || yPoints.length < nPoints)
352
      return;
353
    out.println("newpath % drawPolyLine()");
354
    out.println(xPoints[0] + " " + yPoints[0] + " moveto");
355
    for (int i = 1; i < nPoints; i++)
356
      out.println(xPoints[i] + " " + yPoints[i] + " lineto");
357
    out.println("closepath");
358
    out.println("stroke");
359
  }
360
 
361
  public void drawRoundRect(int x, int y, int width, int height, int arcWidth,
362
                            int arcHeight)
363
  {
364
    out.println("% drawRoundRect()");
365
    RoundRectangle2D.Double rr = new RoundRectangle2D.Double(x, y, width,
366
                                                             height, arcWidth,
367
                                                             arcHeight);
368
    setStroke(ordinaryStroke);
369
    draw(rr);
370
    setStroke(currentStroke);
371
  }
372
 
373
  public void fillRoundRect(int x, int y, int width, int height, int arcWidth,
374
                            int arcHeight)
375
  {
376
    out.println("% fillRoundRect()");
377
    RoundRectangle2D.Double rr = new RoundRectangle2D.Double(x, y, width,
378
                                                             height, arcWidth,
379
                                                             arcHeight);
380
    fill(rr);
381
  }
382
 
383
  public void drawArc(int x, int y, int width, int height, int startAngle,
384
                      int arcAngle)
385
  {
386
    setStroke(ordinaryStroke);
387
    draw(new Arc2D.Double(x, y, width, height, startAngle, arcAngle, Arc2D.OPEN));
388
    setStroke(currentStroke);
389
  }
390
 
391
  public void fillArc(int x, int y, int width, int height, int startAngle,
392
                      int arcAngle)
393
  {
394
    fill(new Arc2D.Double(x, y, width, height, startAngle, arcAngle, Arc2D.PIE));
395
  }
396
 
397
  public void fillOval(int x, int y, int width, int height)
398
  {
399
    out.println("% fillOval()");
400
    fill( new Ellipse2D.Double(x, y, width, height) );
401
  }
402
 
403
  public void fillPolygon(int[] x, int[] y, int nPoints)
404
  {
405
    out.println("% fillPolygon()");
406
    fill( new Polygon(x, y, nPoints) );
407
  }
408
 
409
  public void drawLine(int x1, int y1, int x2, int y2)
410
  {
411
    out.println("% drawLine()");
412
    setStroke(ordinaryStroke);
413
    out.println("newpath");
414
    out.println(x1 + " " + (y1) + " moveto");
415
    out.println(x2 + " " + (y2) + " lineto");
416
    out.println("stroke");
417
    setStroke(currentStroke);
418
  }
419
 
420
  //--------------- Image drawing ------------------------------------------
421
  public boolean drawImage(Image img, int x, int y, Color bgcolor,
422
                           ImageObserver observer)
423
  {
424
    int w = img.getWidth(null);
425
    int h = img.getHeight(null);
426
 
427
    return drawImage(img, x, y, x + w, y + h, 0, 0, w - 1, h - 1, bgcolor,
428
                     observer);
429
  }
430
 
431
  public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2,
432
                           int sx1, int sy1, int sx2, int sy2, Color bgcolor,
433
                           ImageObserver observer)
434
  {
435
    int n = 0;
436
    boolean flipx = false;
437
    boolean flipy = false;
438
 
439
    // swap X and Y's
440
    if (sx1 > sx2)
441
      {
442
        n = sx1;
443
        sx1 = sx2;
444
        sx2 = n;
445
        flipx = ! flipx;
446
      }
447
    if (sy1 > sy2)
448
      {
449
        n = sy1;
450
        sy1 = sy2;
451
        sy2 = n;
452
        flipy = ! flipy;
453
      }
454
    if (dx1 > dx2)
455
      {
456
        n = dx1;
457
        dx1 = dx2;
458
        dx2 = n;
459
        flipx = ! flipx;
460
      }
461
    if (dy1 > dy2)
462
      {
463
        n = dy1;
464
        dy1 = dy2;
465
        dy2 = n;
466
        flipy = ! flipy;
467
      }
468
    n = 0;
469
    int sw = sx2 - sx1; // source width
470
    int sh = sy2 - sy1; // source height
471
    int[] pixels = new int[sw * sh]; // pixel buffer
472
    int dw = dx2 - dx1; // destination width
473
    int dh = dy2 - dy1; // destination height
474
    double x_scale = ((double) dw) / ((double) sw);
475
    double y_scale = ((double) dh) / ((double) sh);
476
 
477
    out.println("% drawImage() 2");
478
    out.println("gsave");
479
    out.println(dx1 + " " + dy1 + " translate");
480
    out.println(dw + " " + dh + " scale");
481
    out.println(sw + " " + sh + " 8 [" + (flipx ? -sw : sw) + " 0 0 "
482
                + (flipy ? -sh : sh) + " " + (flipx ? sw : 0) + " "
483
                + (flipy ? sh : 0) + " ]");
484
    out.println("{currentfile 3 string readhexstring pop} bind");
485
    out.println("false 3 colorimage");
486
 
487
    PixelGrabber pg = new PixelGrabber(img, sx1, sy1, sw, sh, pixels, 0, sw);
488
    try
489
      {
490
        pg.grabPixels();
491
      }
492
    catch (InterruptedException e)
493
      {
494
        System.err.println("interrupted waiting for pixels!");
495
        return (false);
496
      }
497
 
498
    if ((pg.getStatus() & ImageObserver.ABORT) != 0)
499
      {
500
        System.err.println("image fetch aborted or errored");
501
        return (false);
502
      }
503
 
504
    for (int j = 0; j < sh; j++)
505
      {
506
        for (int i = 0; i < sw; i++)
507
          {
508
            out.print(colorTripleHex(new Color(pixels[j * sw + i])));
509
            if (((++n) % 11) == 0)
510
              out.println();
511
          }
512
      }
513
 
514
    out.println();
515
    out.println("%%EOF");
516
    out.println("grestore");
517
    return true;
518
  }
519
 
520
  public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2,
521
                           int sx1, int sy1, int sx2, int sy2,
522
                           ImageObserver observer)
523
  {
524
    return drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null,
525
                     observer);
526
  }
527
 
528
  public boolean drawImage(Image img, int x, int y, ImageObserver observer)
529
  {
530
    return drawImage(img, x, y, null, observer);
531
  }
532
 
533
  public boolean drawImage(Image img, int x, int y, int width, int height,
534
                           Color bgcolor, ImageObserver observer)
535
  {
536
    int sw = img.getWidth(null);
537
    int sh = img.getHeight(null);
538
    return drawImage(img, x, y, x + width, y + height, /* destination */
539
                     0, 0, sw - 1, sh - 1, /* source */
540
                     bgcolor, observer);
541
    // correct?
542
  }
543
 
544
  public boolean drawImage(Image img, int x, int y, int width, int height,
545
                           ImageObserver observer)
546
  {
547
    return drawImage(img, x, y, width, height, null, observer);
548
  }
549
 
550
  /** Renders a BufferedImage that is filtered with a BufferedImageOp. */
551
  public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y)
552
  {
553
    BufferedImage result = op.filter(img, null);
554
    drawImage(result, x, y, null);
555
  }
556
 
557
  /** Renders an image, applying a transform from image space
558
      into user space before drawing. */
559
  public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs)
560
  {
561
    AffineTransform oldTransform = new AffineTransform(currentTransform);
562
    boolean ret;
563
 
564
    transform(xform);
565
    ret = drawImage(img, 0, 0, null, obs);
566
    setTransform(oldTransform);
567
 
568
    return ret;
569
  }
570
 
571
  /** Renders a RenderableImage, applying a transform from image
572
      space into user space before drawing. */
573
  public void drawRenderableImage(RenderableImage img, AffineTransform xform)
574
  {
575
    // FIXME
576
  }
577
 
578
  /** Renders a RenderedImage, applying a transform from
579
      image space into user space before drawing. */
580
  public void drawRenderedImage(RenderedImage img, AffineTransform xform)
581
  {
582
    // FIXME
583
  }
584
 
585
  //-------------------------------------------------------------------------
586
  public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
587
  {
588
    setStroke(ordinaryStroke);
589
    draw(new Polygon(xPoints, yPoints, nPoints));
590
    setStroke(currentStroke);
591
  }
592
 
593
  public void drawString(String str, int x, int y)
594
  {
595
    drawString(str, (float) x, (float) y);
596
  }
597
 
598
  public void drawString(String str, float x, float y)
599
  {
600
    if( str.trim().equals("") )
601
      return; // don't draw whitespace, silly!
602
 
603
    if( currentFontIsPS )
604
      {
605
        drawStringPSFont(str, x, y);
606
        return;
607
      }
608
 
609
    TextLayout text = new TextLayout(str, currentFont, getFontRenderContext());
610
    Shape s = text.getOutline(AffineTransform.getTranslateInstance(x, y));
611
    drawStringShape(s);
612
  }
613
 
614
  private void drawStringPSFont(String str, float x, float y)
615
  {
616
    out.println("% drawString PS font");
617
    out.println(x + " " + y + " moveto");
618
    saveAndInvertAxis();
619
    out.println("(" + str + ") show");
620
    restoreAxis();
621
  }
622
 
623
  private void saveAndInvertAxis()
624
  {
625
    // Invert the Y axis of the CTM.
626
    popCTM();
627
    pushCTM();
628
 
629
    double[] test =
630
      {
631
        pageTransform.getScaleX(), pageTransform.getShearY(),
632
        pageTransform.getShearX(), pageTransform.getScaleY(),
633
        pageTransform.getTranslateX(),
634
        -pageTransform.getTranslateY() + pageY
635
      };
636
 
637
    double[] test2 =
638
      {
639
        currentTransform.getScaleX(),
640
        currentTransform.getShearY(),
641
        -currentTransform.getShearX(),
642
        -currentTransform.getScaleY(),
643
        currentTransform.getTranslateX(),
644
        currentTransform.getTranslateY()
645
      };
646
 
647
    AffineTransform total = new AffineTransform(test);
648
    total.concatenate(new AffineTransform(test2));
649
    concatCTM(total);
650
  }
651
 
652
  private void restoreAxis()
653
  {
654
    // reset the CTM
655
    popCTM();
656
    pushCTM();
657
    AffineTransform total = new AffineTransform(pageTransform);
658
    total.concatenate(currentTransform);
659
    concatCTM(total);
660
  }
661
 
662
  /**
663
   * special drawing routine for string shapes,
664
   * which need to be drawn with the Y axis uninverted.
665
   */
666
  private void drawStringShape(Shape s)
667
  {
668
    saveAndInvertAxis();
669
 
670
    // draw the shape s with an inverted Y axis.
671
    PathIterator pi = s.getPathIterator(null);
672
    float[] coords = new float[6];
673
 
674
    while (! pi.isDone())
675
      {
676
        switch (pi.currentSegment(coords))
677
          {
678
          case PathIterator.SEG_MOVETO:
679
            out.println((coords[0]) + " " + (Y - coords[1]) + " moveto");
680
            cx = coords[0];
681
            cy = coords[1];
682
            break;
683
          case PathIterator.SEG_LINETO:
684
            out.println((coords[0]) + " " + (Y - coords[1]) + " lineto");
685
            cx = coords[0];
686
            cy = coords[1];
687
            break;
688
          case PathIterator.SEG_QUADTO:
689
            // convert to cubic bezier points
690
            float x1 = (cx + 2 * coords[0]) / 3;
691
            float y1 = (cy + 2 * coords[1]) / 3;
692
            float x2 = (2 * coords[2] + coords[0]) / 3;
693
            float y2 = (2 * coords[3] + coords[1]) / 3;
694
 
695
            out.print((x1) + " " + (Y - y1) + " ");
696
            out.print((x2) + " " + (Y - y2) + " ");
697
            out.println((coords[2]) + " " + (Y - coords[3]) + " curveto");
698
            cx = coords[2];
699
            cy = coords[3];
700
            break;
701
          case PathIterator.SEG_CUBICTO:
702
            out.print((coords[0]) + " " + (Y - coords[1]) + " ");
703
            out.print((coords[2]) + " " + (Y - coords[3]) + " ");
704
            out.println((coords[4]) + " " + (Y - coords[5]) + " curveto");
705
            cx = coords[4];
706
            cy = coords[5];
707
            break;
708
          case PathIterator.SEG_CLOSE:
709
            out.println("closepath");
710
            break;
711
          }
712
        pi.next();
713
      }
714
    out.println("fill");
715
 
716
    restoreAxis();
717
  }
718
 
719
  public void setColor(Color c)
720
  {
721
    /* don't set the color if it's already set */
722
    if (c.equals(currentColor))
723
      return;
724
    gradientOn = false;
725
    currentColor = c;
726
    currentPaint = c; // Graphics2D extends colors to paint
727
 
728
    out.println(colorTriple(c) + " setrgbcolor");
729
  }
730
 
731
  public void clearRect(int x, int y, int width, int height)
732
  {
733
    out.println("% clearRect");
734
    Color c = currentColor;
735
    setColor(backgroundColor);
736
    fill(new Rectangle2D.Double(x, y, width, height));
737
    setColor(c);
738
  }
739
 
740
  public void clipRect(int x, int y, int width, int height)
741
  {
742
    clip(new Rectangle2D.Double(x, y, width, height));
743
  }
744
 
745
  public void copyArea(int x, int y, int width, int height, int dx, int dy)
746
  {
747
    // FIXME
748
  }
749
 
750
  public void fillRect(int x, int y, int width, int height)
751
  {
752
    fill(new Rectangle2D.Double(x, y, width, height));
753
  }
754
 
755
  public void dispose()
756
  {
757
  }
758
 
759
  public void setClip(int x, int y, int width, int height)
760
  {
761
    out.println("% setClip()");
762
    setClip(new Rectangle2D.Double(x, y, width, height));
763
  }
764
 
765
  public void setClip(Shape s)
766
  {
767
    clip(s);
768
  }
769
 
770
  public Shape getClip()
771
  {
772
    return clipShape;
773
  }
774
 
775
  public Rectangle getClipBounds()
776
  {
777
    return clipShape.getBounds();
778
  }
779
 
780
  public Color getColor()
781
  {
782
    return currentColor;
783
  }
784
 
785
  public Font getFont()
786
  {
787
    return currentFont;
788
  }
789
 
790
  public FontMetrics getFontMetrics()
791
  {
792
    return getFontMetrics(currentFont);
793
  }
794
 
795
  public FontMetrics getFontMetrics(Font f)
796
  {
797
    // FIXME
798
    return null;
799
  }
800
 
801
  public void setFont(Font font)
802
  {
803
    out.println("% setfont()");
804
    if (font == null)
805
      // use the default font
806
      font = new Font("Dialog", Font.PLAIN, 12);
807
    currentFont = font;
808
    setPSFont(); // set up the PostScript fonts
809
  }
810
 
811
  /**
812
   * Setup the postscript font if the current font is one
813
   */
814
  private void setPSFont()
815
  {
816
    currentFontIsPS = false;
817
 
818
    String s = currentFont.getName();
819
    out.println("% setPSFont: Fontname: " + s);
820
    if (s.equalsIgnoreCase("Helvetica") || s.equalsIgnoreCase("SansSerif"))
821
      out.print("/helveticaISO findfont ");
822
    else if (s.equalsIgnoreCase("Times New Roman"))
823
      out.print("/timesISO findfont ");
824
    else if (s.equalsIgnoreCase("Courier"))
825
      out.print("/courierISO findfont ");
826
    else
827
      return;
828
 
829
    currentFontIsPS = true;
830
 
831
    out.print(currentFont.getSize() + " scalefont ");
832
    out.println("setfont");
833
  }
834
 
835
  /** XOR mode is not supported */
836
  public void setPaintMode()
837
  {
838
  }
839
 
840
  /** XOR mode is not supported */
841
  public void setXORMode(Color c1)
842
  {
843
  }
844
 
845
  public void close()
846
  {
847
    out.println("showpage");
848
    out.println("%%Trailer");
849
    out.println("grestore % restore original stuff");
850
    out.println("%%EOF");
851
 
852
    try
853
      {
854
        out.close();
855
      }
856
    catch (Exception e)
857
      {
858
      }
859
    out = null;
860
  }
861
 
862
  //----------------------------------------------------------------
863
  // Graphics2D stuff ----------------------------------------------
864
 
865
  /**  Sets the values of an arbitrary number of
866
       preferences for the rendering algorithms. */
867
  public void addRenderingHints(Map hints)
868
  {
869
    /* rendering hint changes are disallowed */
870
  }
871
 
872
  /** write a shape to the file */
873
  private void writeShape(Shape s)
874
  {
875
    PathIterator pi = s.getPathIterator(null);
876
    float[] coords = new float[6];
877
 
878
    while (! pi.isDone())
879
      {
880
        switch (pi.currentSegment(coords))
881
          {
882
          case PathIterator.SEG_MOVETO:
883
            out.println(coords[0] + " " + (coords[1]) + " moveto");
884
            cx = coords[0];
885
            cy = coords[1];
886
            break;
887
          case PathIterator.SEG_LINETO:
888
            out.println(coords[0] + " " + (coords[1]) + " lineto");
889
            cx = coords[0];
890
            cy = coords[1];
891
            break;
892
          case PathIterator.SEG_QUADTO:
893
            // convert to cubic bezier points
894
            float x1 = (cx + 2 * coords[0]) / 3;
895
            float y1 = (cy + 2 * coords[1]) / 3;
896
            float x2 = (2 * coords[2] + coords[0]) / 3;
897
            float y2 = (2 * coords[3] + coords[1]) / 3;
898
 
899
            out.print(x1 + " " + (Y - y1) + " ");
900
            out.print(x2 + " " + (Y - y2) + " ");
901
            out.println(coords[2] + " " + (Y - coords[3]) + " curveto");
902
            cx = coords[2];
903
            cy = coords[3];
904
            break;
905
          case PathIterator.SEG_CUBICTO:
906
            out.print(coords[0] + " " + coords[1] + " ");
907
            out.print(coords[2] + " " + coords[3] + " ");
908
            out.println(coords[4] + " " + coords[5] + " curveto");
909
            cx = coords[4];
910
            cy = coords[5];
911
            break;
912
          case PathIterator.SEG_CLOSE:
913
            out.println("closepath");
914
            break;
915
          }
916
        pi.next();
917
      }
918
  }
919
 
920
  /** Intersects the current Clip with the interior of
921
      the specified Shape and sets the Clip to the resulting intersection. */
922
  public void clip(Shape s)
923
  {
924
    clipShape = s;
925
    out.println("% clip INACTIVE");
926
    //  writeShape(s);
927
    //  out.println("clip");
928
  }
929
 
930
  /** Strokes the outline of a Shape using the
931
      settings of the current Graphics2D context.*/
932
  public void draw(Shape s)
933
  {
934
    if(!(currentStroke instanceof BasicStroke))
935
      fill(currentStroke.createStrokedShape(s));
936
 
937
    out.println("% draw");
938
    writeShape(s);
939
    out.println("stroke");
940
  }
941
 
942
  /** Renders the text of the specified GlyphVector using the
943
      Graphics2D context's rendering attributes. */
944
  public void drawGlyphVector(GlyphVector gv, float x, float y)
945
  {
946
    out.println("% drawGlyphVector");
947
    Shape s = gv.getOutline();
948
    drawStringShape(AffineTransform.getTranslateInstance(x, y)
949
                    .createTransformedShape(s));
950
  }
951
 
952
  /** Renders the text of the specified iterator,
953
      using the Graphics2D context's current Paint.*/
954
  public void drawString(AttributedCharacterIterator iterator, float x, float y)
955
  {
956
    TextLayout text = new TextLayout(iterator, getFontRenderContext());
957
    Shape s = text.getOutline(AffineTransform.getTranslateInstance(x, y));
958
    drawStringShape(s);
959
  }
960
 
961
  /** Renders the text of the specified iterator,
962
      using the Graphics2D context's current Paint. */
963
  public void drawString(AttributedCharacterIterator iterator, int x, int y)
964
  {
965
    drawString(iterator, (float) x, (float) y);
966
  }
967
 
968
  /** Fills the interior of a Shape using the settings of the Graphics2D context. */
969
  public void fill(Shape s)
970
  {
971
    out.println("% fill");
972
    if (! gradientOn)
973
      {
974
        writeShape(s);
975
        out.println("fill");
976
      }
977
    else
978
      {
979
        out.println("gsave");
980
        writeShape(s);
981
        out.println("clip");
982
        writeGradient();
983
        out.println("shfill");
984
        out.println("grestore");
985
      }
986
  }
987
 
988
  /** Returns the background color used for clearing a region. */
989
  public Color getBackground()
990
  {
991
    return backgroundColor;
992
  }
993
 
994
  /** Returns the current Composite in the Graphics2D context. */
995
  public Composite getComposite()
996
  {
997
    // FIXME
998
    return null;
999
  }
1000
 
1001
  /** Returns the device configuration associated with this Graphics2D. */
1002
  public GraphicsConfiguration getDeviceConfiguration()
1003
  {
1004
    // FIXME
1005
    out.println("% getDeviceConfiguration()");
1006
    return null;
1007
  }
1008
 
1009
  /** Get the rendering context of the Font within this Graphics2D context. */
1010
  public FontRenderContext getFontRenderContext()
1011
  {
1012
    out.println("% getFontRenderContext()");
1013
 
1014
    double[] scaling =
1015
      {
1016
        pageTransform.getScaleX(), 0, 0,
1017
        -pageTransform.getScaleY(), 0, 0
1018
      };
1019
 
1020
    return (new FontRenderContext(new AffineTransform(scaling), false, true));
1021
  }
1022
 
1023
  /** Returns the current Paint of the Graphics2D context. */
1024
  public Paint getPaint()
1025
  {
1026
    return currentPaint;
1027
  }
1028
 
1029
  /** Returns the value of a single preference for the rendering algorithms. */
1030
  public Object getRenderingHint(RenderingHints.Key hintKey)
1031
  {
1032
    return renderingHints.get(hintKey);
1033
  }
1034
 
1035
  /** Gets the preferences for the rendering algorithms. */
1036
  public RenderingHints getRenderingHints()
1037
  {
1038
    return renderingHints;
1039
  }
1040
 
1041
  /** Returns the current Stroke in the Graphics2D context. */
1042
  public Stroke getStroke()
1043
  {
1044
    return currentStroke;
1045
  }
1046
 
1047
  /** Returns a copy of the current Transform in the Graphics2D context. */
1048
  public AffineTransform getTransform()
1049
  {
1050
    return currentTransform;
1051
  }
1052
 
1053
  /**
1054
   * Checks whether or not the specified Shape intersects
1055
   * the specified Rectangle, which is in device space.
1056
   */
1057
  public boolean hit(Rectangle rect, Shape s, boolean onStroke)
1058
  {
1059
    Rectangle2D.Double r = new Rectangle2D.Double(rect.getX(), rect.getY(),
1060
                                                  rect.getWidth(),
1061
                                                  rect.getHeight());
1062
    return s.intersects(r);
1063
  }
1064
 
1065
  /** Sets the background color for the Graphics2D context.*/
1066
  public void setBackground(Color color)
1067
  {
1068
    out.println("% setBackground(" + color + ")");
1069
    backgroundColor = color;
1070
  }
1071
 
1072
  /** Sets the Composite for the Graphics2D context.
1073
      Not supported. */
1074
  public void setComposite(Composite comp)
1075
  {
1076
  }
1077
 
1078
  /** Sets the Paint attribute for the Graphics2D context.*/
1079
  public void setPaint(Paint paint)
1080
  {
1081
    currentPaint = paint;
1082
    gradientOn = false;
1083
    if (paint instanceof Color)
1084
      {
1085
        setColor((Color) paint);
1086
        return;
1087
      }
1088
    if (paint instanceof GradientPaint)
1089
      {
1090
        gradientOn = true;
1091
        return;
1092
      }
1093
  }
1094
 
1095
  /* get a space seperated 0.0 - 1.0 color RGB triple */
1096
  private String colorTriple(Color c)
1097
  {
1098
    return (((double) c.getRed() / 255.0) + " "
1099
            + ((double) c.getGreen() / 255.0) + " "
1100
            + ((double) c.getBlue() / 255.0));
1101
  }
1102
 
1103
  /**
1104
   * Get a nonsperated hex RGB triple, eg FFFFFF = white
1105
   * used by writeGradient and drawImage
1106
   */
1107
  private String colorTripleHex(Color c)
1108
  {
1109
    String r = "00" + Integer.toHexString(c.getRed());
1110
    r = r.substring(r.length() - 2);
1111
    String g = "00" + Integer.toHexString(c.getGreen());
1112
    g = g.substring(g.length() - 2);
1113
    String b = "00" + Integer.toHexString(c.getBlue());
1114
    b = b.substring(b.length() - 2);
1115
    return r + g + b;
1116
  }
1117
 
1118
  /* write the current gradient fill */
1119
  private void writeGradient()
1120
  {
1121
    GradientPaint paint = (GradientPaint) currentPaint;
1122
    out.println("% writeGradient()");
1123
 
1124
    int n = 1;
1125
    double x;
1126
    double y;
1127
    double dx;
1128
    double dy;
1129
    Point2D p1 = currentTransform.transform(paint.getPoint1(), null);
1130
    Point2D p2 = currentTransform.transform(paint.getPoint2(), null);
1131
    x = p1.getX();
1132
    y = p1.getY();
1133
    dx = p2.getX() - x;
1134
    dy = p2.getY() - y;
1135
 
1136
    // get number of repetitions
1137
    while (x + n * dx < pageY && y + n * dy < pageX && x + n * dx > 0
1138
           && y + n * dy > 0)
1139
      n++;
1140
 
1141
    out.println("<<"); // start
1142
    out.println("/ShadingType 2"); // gradient fill
1143
    out.println("/ColorSpace [ /DeviceRGB ]"); // RGB colors
1144
    out.print("/Coords [");
1145
    out.print(x + " " + y + " " + (x + n * dx) + " " + (y + n * dy) + " ");
1146
    out.println("]"); // coordinates defining the axis
1147
    out.println("/Function <<");
1148
    out.println("/FunctionType 0");
1149
    out.println("/Order 1");
1150
    out.println("/Domain [ 0 1 ]");
1151
    out.println("/Range [ 0 1  0 1  0 1 ]");
1152
    out.println("/BitsPerSample 8");
1153
    out.println("/Size [ " + (1 + n) + " ]");
1154
    out.print("/DataSource < " + colorTripleHex(paint.getColor1()) + " "
1155
              + colorTripleHex(paint.getColor2()) + " ");
1156
    for (; n > 1; n--)
1157
      if (paint.isCyclic())
1158
        {
1159
          if ((n % 2) == 1)
1160
            out.print(colorTripleHex(paint.getColor1()) + " ");
1161
          else
1162
            out.print(colorTripleHex(paint.getColor2()) + " ");
1163
        }
1164
      else
1165
        out.print(colorTripleHex(paint.getColor2()) + " ");
1166
    out.println(">");
1167
    out.println(">>");
1168
    out.println(">>");
1169
  }
1170
 
1171
  /** Sets the value of a single preference for the rendering algorithms. */
1172
  public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue)
1173
  {
1174
    /* we don't allow the changing of rendering hints. */
1175
  }
1176
 
1177
  /** Replaces the values of all preferences for the rendering algorithms
1178
      with the specified hints. */
1179
  public void setRenderingHints(Map hints)
1180
  {
1181
    /* we don't allow the changing of rendering hints. */
1182
  }
1183
 
1184
  /**
1185
   * Sets the Stroke for the Graphics2D context. BasicStroke fully implemented.
1186
   */
1187
  public void setStroke(Stroke s)
1188
  {
1189
    currentStroke = s;
1190
 
1191
    if (! (s instanceof BasicStroke))
1192
      return;
1193
 
1194
    BasicStroke bs = (BasicStroke) s;
1195
    out.println("% setStroke()");
1196
    try
1197
      {
1198
        // set the line width
1199
        out.println(bs.getLineWidth() + " setlinewidth");
1200
 
1201
        // set the line dash
1202
        float[] dashArray = bs.getDashArray();
1203
        if (dashArray != null)
1204
          {
1205
            out.print("[ ");
1206
            for (int i = 0; i < dashArray.length; i++)
1207
              out.print(dashArray[i] + " ");
1208
            out.println("] " + bs.getDashPhase() + " setdash");
1209
          }
1210
        else
1211
          out.println("[] 0 setdash"); // set solid
1212
 
1213
        // set the line cap
1214
        switch (bs.getEndCap())
1215
          {
1216
          case BasicStroke.CAP_BUTT:
1217
            out.println("0 setlinecap");
1218
            break;
1219
          case BasicStroke.CAP_ROUND:
1220
            out.println("1 setlinecap");
1221
            break;
1222
          case BasicStroke.CAP_SQUARE:
1223
            out.println("2 setlinecap");
1224
            break;
1225
          }
1226
 
1227
        // set the line join
1228
        switch (bs.getLineJoin())
1229
          {
1230
          case BasicStroke.JOIN_BEVEL:
1231
            out.println("2 setlinejoin");
1232
            break;
1233
          case BasicStroke.JOIN_MITER:
1234
            out.println("0 setlinejoin");
1235
            out.println(bs.getMiterLimit() + " setmiterlimit");
1236
            break;
1237
          case BasicStroke.JOIN_ROUND:
1238
            out.println("1 setlinejoin");
1239
            break;
1240
          }
1241
      }
1242
    catch (Exception e)
1243
      {
1244
        out.println("% Exception in setStroke()");
1245
      }
1246
  }
1247
 
1248
  //////////////////// TRANSFORM SETTING /////////////////////////////////////
1249
  private void concatCTM(AffineTransform Tx)
1250
  {
1251
    double[] matrixElements = new double[6];
1252
    Tx.getMatrix(matrixElements);
1253
 
1254
    out.print("[ ");
1255
    for (int i = 0; i < 6; i++)
1256
      out.print(matrixElements[i] + " ");
1257
    out.println("] concat");
1258
  }
1259
 
1260
  /** Sets the Transform in the Graphics2D context. */
1261
  public void setTransform(AffineTransform Tx)
1262
  {
1263
    // set the transformation matrix;
1264
    currentTransform = Tx;
1265
 
1266
    // concatenate the current transform and the page transform
1267
    AffineTransform totalTransform = new AffineTransform(pageTransform);
1268
    totalTransform.concatenate(currentTransform);
1269
    out.println("% setTransform()");
1270
    out.println("% pageTransform:" + pageTransform);
1271
    out.println("% currentTransform:" + currentTransform);
1272
    out.println("% totalTransform:" + totalTransform);
1273
 
1274
    popCTM();
1275
    pushCTM(); // set the CTM to it's original state
1276
    concatCTM(totalTransform); // apply our transforms
1277
  }
1278
 
1279
  /** Composes an AffineTransform object with the Transform
1280
      in this Graphics2D according to the rule last-specified-first-applied. */
1281
  public void transform(AffineTransform Tx)
1282
  {
1283
    // concatenate the current transform
1284
    currentTransform.concatenate(Tx);
1285
    // and the PS CTM
1286
    concatCTM(Tx);
1287
  }
1288
 
1289
  ////////////////////////// TRANSFORMS //////////////////////////////////////
1290
 
1291
  /** shear transform */
1292
  public void shear(double shx, double shy)
1293
  {
1294
    out.println("% shear()");
1295
    AffineTransform Tx = new AffineTransform();
1296
    Tx.shear(shx, shy);
1297
    transform(Tx);
1298
  }
1299
 
1300
  /** Translates the origin of the Graphics2D context
1301
      to the point (x, y) in the current coordinate system. */
1302
  public void translate(int x, int y)
1303
  {
1304
    out.println("% translate()");
1305
    AffineTransform Tx = new AffineTransform();
1306
    Tx.translate(x, y);
1307
    transform(Tx);
1308
  }
1309
 
1310
  /** Translates the origin of the Graphics2D context
1311
      to the point (x, y) in the current coordinate system. */
1312
  public void translate(double x, double y)
1313
  {
1314
    out.println("% translate(" + x + ", " + y + ")");
1315
    AffineTransform Tx = new AffineTransform();
1316
    Tx.translate(x, y);
1317
    transform(Tx);
1318
  }
1319
 
1320
  /** Concatenates the current Graphics2D Transform with a rotation transform.*/
1321
  public void rotate(double theta)
1322
  {
1323
    out.println("% rotate(" + theta + ")");
1324
    AffineTransform Tx = new AffineTransform();
1325
    Tx.rotate(theta);
1326
    transform(Tx);
1327
  }
1328
 
1329
  /** Concatenates the current Graphics2D Transform with
1330
      a translated rotation transform.*/
1331
  public void rotate(double theta, double x, double y)
1332
  {
1333
    out.println("% rotate()");
1334
    AffineTransform Tx = new AffineTransform();
1335
    Tx.rotate(theta, x, y);
1336
    transform(Tx);
1337
  }
1338
 
1339
  /** Concatenates the current Graphics2D Transform with a scaling
1340
      transformation Subsequent rendering is resized according to the
1341
      specified scaling factors relative to the previous scaling.*/
1342
  public void scale(double sx, double sy)
1343
  {
1344
    out.println("% scale(" + sx + ", " + sy + ")");
1345
    AffineTransform Tx = new AffineTransform();
1346
    Tx.scale(sx, sy);
1347
    transform(Tx);
1348
  }
1349
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.