/* PostScriptGraphics2D.java -- AWT printer rendering class.
   Copyright (C) 2006  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package gnu.java.awt.print;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Paint;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.TextLayout;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.renderable.RenderableImage;
import java.awt.image.RenderedImage;
import java.awt.image.ImageObserver;
import java.awt.image.PixelGrabber;
import java.awt.print.PageFormat;
import java.awt.print.Pageable;
import java.awt.print.Paper;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterGraphics;
import java.awt.print.PrinterJob;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.text.AttributedCharacterIterator;
import java.util.Map;

/**
 * Class PostScriptGraphics2D - Class that implements the Graphics2D object,
 * writing the output to a PostScript or EPS file
 *
 * @author Sven de Marothy
 *
 */
class PostScriptGraphics2D extends Graphics2D
{
  /**
   * The associated printer job.
   */
  private PrinterJob printerJob;

  /**
   * Output file.
   */
  private PrintWriter out;

  // Graphics data
  private AffineTransform currentTransform = new AffineTransform();
  private AffineTransform pageTransform;
  private RenderingHints renderingHints;
  private Paint currentPaint = null;
  private Shape clipShape = null;
  private Font currentFont = null;
  private Color currentColor = Color.black;
  private Color backgroundColor = Color.white;
  private Stroke currentStroke = null;
  private static Stroke ordinaryStroke = new BasicStroke(0.0f,
                                                         BasicStroke.CAP_BUTT,
                                                         BasicStroke.JOIN_MITER);
  private float cx; // current drawing position
  private float cy; // current drawing position
  private boolean currentFontIsPS; // set if currentFont is one of the above

  // settings
  private double pageX = 595;
  private double pageY = 842;
  private double Y = pageY;
  private boolean gradientOn = false;

  /** 
   * Constructor
   *
   */
  public PostScriptGraphics2D( PrinterJob pg )
  {
    printerJob = pg;
    // create transform objects
    pageTransform = new AffineTransform();
    currentTransform = new AffineTransform();

    /*
      Create Rendering hints
      No text aliasing
      Quality color and rendering
      Bicubic interpolation
      Fractional metrics supported
    */
    renderingHints = new RenderingHints(null);
    renderingHints.put(RenderingHints.KEY_RENDERING,
                       RenderingHints.VALUE_RENDER_QUALITY);
    renderingHints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
                       RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
    renderingHints.put(RenderingHints.KEY_INTERPOLATION,
                       RenderingHints.VALUE_INTERPOLATION_BICUBIC);
    renderingHints.put(RenderingHints.KEY_FRACTIONALMETRICS,
                       RenderingHints.VALUE_FRACTIONALMETRICS_ON);
    renderingHints.put(RenderingHints.KEY_COLOR_RENDERING,
                       RenderingHints.VALUE_COLOR_RENDER_QUALITY);
  }

  /**
   * Spool a document to PostScript.
   * If Pageable is non-null, it will print that, otherwise it will use
   * the supplied printable and pageFormat.
   */
  public SpooledDocument spoolPostScript(Printable printable, 
					 PageFormat pageFormat,
					 Pageable pageable)
    throws PrinterException
  {
    try 
      {
	// spool to a temporary file
	File temp = File.createTempFile("cpspool", ".ps");
	temp.deleteOnExit();
	
	out = new PrintWriter(new BufferedWriter
			      (new OutputStreamWriter
			       (new FileOutputStream(temp), 
				"ISO8859_1"), 1000000));
	
	writePSHeader();
	
	if(pageable != null)
	  {
	    for(int index = 0; index < pageable.getNumberOfPages(); index++)
	      spoolPage(out, pageable.getPrintable(index),
			pageable.getPageFormat(index), index);
	  }
	else
	  {
	    int index = 0;
	    while(spoolPage(out, printable, pageFormat, index++) ==
		  Printable.PAGE_EXISTS);
	  }
	out.println("%%Trailer");
	out.println("%%EOF");
	out.close();
	return new SpooledDocument( temp );
      } 
    catch (IOException e) 
      {
	PrinterException pe = new PrinterException();
	pe.initCause(e);
	throw pe;
      }
  }

  //--------------------------------------------------------------------------

  /** 
   * Write the postscript file header,
   * setup the page format and transforms. 
   */
  private void writePSHeader()
  {
    out.println("%!PS-Adobe-3.0");      
    out.println("%%Title: "+printerJob.getJobName());
    out.println("%%Creator: GNU Classpath ");
    out.println("%%DocumentData: Clean8Bit");

    out.println("%%DocumentNeededResources: font Times-Roman Helvetica Courier");
    out.println("%%EndComments");
    
    out.println("%%BeginProlog");
    out.println("%%EndProlog");
    out.println("%%BeginSetup");
    
    out.println("%%EndFeature");
    setupFonts();
    out.println("%%EndSetup");
 
    // set default fonts and colors
    setFont( new Font("Dialog", Font.PLAIN, 12) );
    currentColor = Color.white;
    currentStroke = new BasicStroke();
    setPaint(currentColor);
    setStroke(currentStroke);
  }

  /**
   * setupFonts - set up the font dictionaries for
   * helvetica, times and courier
   */
  private void setupFonts()
  {
    out.println("/helveticaISO");
    out.println("/Helvetica findfont dup length dict begin");
    out.println("{ 1 index /FID eq { pop pop } { def } ifelse } forall");
    out.println("/Encoding ISOLatin1Encoding def");
    out.println("currentdict end definefont pop");

    out.println("/timesISO");
    out.println("/Times-Roman findfont dup length dict begin");
    out.println("{ 1 index /FID eq { pop pop } { def } ifelse } forall");
    out.println("/Encoding ISOLatin1Encoding def");
    out.println("currentdict end definefont pop");

    out.println("/courierISO");
    out.println("/Courier findfont dup length dict begin");
    out.println("{ 1 index /FID eq { pop pop } { def } ifelse } forall");
    out.println("/Encoding ISOLatin1Encoding def");
    out.println("currentdict end definefont pop");
  }

  /**
   * Spools a single page, returns NO_SUCH_PAGE unsuccessful,
   * PAGE_EXISTS if it was.
   */
  public int spoolPage(PrintWriter out,
		       Printable printable, 
		       PageFormat pageFormat, 
		       int index) throws IOException, PrinterException
  {
    out.println("%%BeginPageSetup");

    Paper p = pageFormat.getPaper();
    pageX = p.getWidth();
    pageY = p.getHeight();

    if( pageFormat.getOrientation() == PageFormat.PORTRAIT )
      out.println( "%%Orientation: Portrait" );
    else
      {
	out.println( "%%Orientation: Landscape" );
	double t = pageX;
	pageX = pageY;
	pageY = t;
      }
      
    setClip(0, 0, (int)pageX, (int)pageY);

    out.println("gsave % first save");
    
    // 595x842; 612x792 respectively
    out.println("<< /PageSize [" +pageX + " "+pageY+ "] >> setpagedevice");

    if( pageFormat.getOrientation() != PageFormat.LANDSCAPE )
      {
	pageTransform.translate(pageX, 0);
	pageTransform.scale(-1.0, 1.0);
      }

    // save the original CTM
    pushCTM();
    concatCTM(pageTransform);
    setTransform(new AffineTransform());

    out.println("%%EndPageSetup");

    out.println("gsave");

    if( printable.print(this, pageFormat, index) == Printable.NO_SUCH_PAGE )
      return Printable.NO_SUCH_PAGE;
    
    out.println("grestore");
    out.println("showpage");

    return Printable.PAGE_EXISTS;
  }

  /** push the Current Transformation Matrix onto the PS stack */
  private void pushCTM()
  {
    out.println("matrix currentmatrix   % pushCTM()");
  }

  /** pop the Current Transformation Matrix from the PS stack */
  private void popCTM()
  {
    out.println("setmatrix % restore CTM");
  }

  ///////////////////////////////////////////////////////////////////////////

  public Graphics create()
  {
    return null;
  }

  public void drawOval(int x, int y, int width, int height)
  {
    out.println("% drawOval()");
    setStroke(ordinaryStroke);
    draw(new Ellipse2D.Double(x, y, width, height));
    setStroke(currentStroke);
  }

  public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
  {
    if (nPoints <= 0 || xPoints.length < nPoints || yPoints.length < nPoints)
      return;
    out.println("newpath % drawPolyLine()");
    out.println(xPoints[0] + " " + yPoints[0] + " moveto");
    for (int i = 1; i < nPoints; i++)
      out.println(xPoints[i] + " " + yPoints[i] + " lineto");
    out.println("closepath");
    out.println("stroke");
  }

  public void drawRoundRect(int x, int y, int width, int height, int arcWidth,
                            int arcHeight)
  {
    out.println("% drawRoundRect()");
    RoundRectangle2D.Double rr = new RoundRectangle2D.Double(x, y, width,
                                                             height, arcWidth,
                                                             arcHeight);
    setStroke(ordinaryStroke);
    draw(rr);
    setStroke(currentStroke);
  }

  public void fillRoundRect(int x, int y, int width, int height, int arcWidth,
                            int arcHeight)
  {
    out.println("% fillRoundRect()");
    RoundRectangle2D.Double rr = new RoundRectangle2D.Double(x, y, width,
                                                             height, arcWidth,
                                                             arcHeight);
    fill(rr);
  }

  public void drawArc(int x, int y, int width, int height, int startAngle,
                      int arcAngle)
  {
    setStroke(ordinaryStroke);
    draw(new Arc2D.Double(x, y, width, height, startAngle, arcAngle, Arc2D.OPEN));
    setStroke(currentStroke);
  }

  public void fillArc(int x, int y, int width, int height, int startAngle,
                      int arcAngle)
  {
    fill(new Arc2D.Double(x, y, width, height, startAngle, arcAngle, Arc2D.PIE));
  }

  public void fillOval(int x, int y, int width, int height)
  {
    out.println("% fillOval()");
    fill( new Ellipse2D.Double(x, y, width, height) );
  }

  public void fillPolygon(int[] x, int[] y, int nPoints)
  {
    out.println("% fillPolygon()");
    fill( new Polygon(x, y, nPoints) );
  }

  public void drawLine(int x1, int y1, int x2, int y2)
  {
    out.println("% drawLine()");
    setStroke(ordinaryStroke);
    out.println("newpath");
    out.println(x1 + " " + (y1) + " moveto");
    out.println(x2 + " " + (y2) + " lineto");
    out.println("stroke");
    setStroke(currentStroke);
  }

  //--------------- Image drawing ------------------------------------------   
  public boolean drawImage(Image img, int x, int y, Color bgcolor,
                           ImageObserver observer)
  {
    int w = img.getWidth(null);
    int h = img.getHeight(null);

    return drawImage(img, x, y, x + w, y + h, 0, 0, w - 1, h - 1, bgcolor,
		     observer);
  }

  public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2,
                           int sx1, int sy1, int sx2, int sy2, Color bgcolor,
                           ImageObserver observer)
  {
    int n = 0;
    boolean flipx = false;
    boolean flipy = false;

    // swap X and Y's
    if (sx1 > sx2)
      {
	n = sx1;
	sx1 = sx2;
	sx2 = n;
	flipx = ! flipx;
      }
    if (sy1 > sy2)
      {
	n = sy1;
	sy1 = sy2;
	sy2 = n;
	flipy = ! flipy;
      }
    if (dx1 > dx2)
      {
	n = dx1;
	dx1 = dx2;
	dx2 = n;
	flipx = ! flipx;
      }
    if (dy1 > dy2)
      {
	n = dy1;
	dy1 = dy2;
	dy2 = n;
	flipy = ! flipy;
      }
    n = 0;
    int sw = sx2 - sx1; // source width
    int sh = sy2 - sy1; // source height
    int[] pixels = new int[sw * sh]; // pixel buffer
    int dw = dx2 - dx1; // destination width
    int dh = dy2 - dy1; // destination height
    double x_scale = ((double) dw) / ((double) sw);
    double y_scale = ((double) dh) / ((double) sh);

    out.println("% drawImage() 2");
    out.println("gsave");
    out.println(dx1 + " " + dy1 + " translate");
    out.println(dw + " " + dh + " scale");
    out.println(sw + " " + sh + " 8 [" + (flipx ? -sw : sw) + " 0 0 "
                + (flipy ? -sh : sh) + " " + (flipx ? sw : 0) + " "
                + (flipy ? sh : 0) + " ]");
    out.println("{currentfile 3 string readhexstring pop} bind");
    out.println("false 3 colorimage");

    PixelGrabber pg = new PixelGrabber(img, sx1, sy1, sw, sh, pixels, 0, sw);
    try
      {
	pg.grabPixels();
      }
    catch (InterruptedException e)
      {
	System.err.println("interrupted waiting for pixels!");
	return (false);
      }

    if ((pg.getStatus() & ImageObserver.ABORT) != 0)
      {
	System.err.println("image fetch aborted or errored");
	return (false);
      }

    for (int j = 0; j < sh; j++)
      {
	for (int i = 0; i < sw; i++)
	  {
	    out.print(colorTripleHex(new Color(pixels[j * sw + i])));
	    if (((++n) % 11) == 0)
	      out.println();
	  }
      }

    out.println();
    out.println("%%EOF");
    out.println("grestore");
    return true;
  }

  public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2,
                           int sx1, int sy1, int sx2, int sy2,
                           ImageObserver observer)
  {
    return drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null,
		     observer);
  }

  public boolean drawImage(Image img, int x, int y, ImageObserver observer)
  {
    return drawImage(img, x, y, null, observer);
  }

  public boolean drawImage(Image img, int x, int y, int width, int height,
			   Color bgcolor, ImageObserver observer)
  {
    int sw = img.getWidth(null);
    int sh = img.getHeight(null);
    return drawImage(img, x, y, x + width, y + height, /* destination */
		     0, 0, sw - 1, sh - 1, /* source */
		     bgcolor, observer);
    // correct?
  }

  public boolean drawImage(Image img, int x, int y, int width, int height,
			   ImageObserver observer)
  {
    return drawImage(img, x, y, width, height, null, observer);
  }

  /** Renders a BufferedImage that is filtered with a BufferedImageOp. */
  public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y)
  {
    BufferedImage result = op.filter(img, null);
    drawImage(result, x, y, null);
  }

  /** Renders an image, applying a transform from image space
      into user space before drawing. */
  public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs)
  {
    AffineTransform oldTransform = new AffineTransform(currentTransform);
    boolean ret;

    transform(xform);
    ret = drawImage(img, 0, 0, null, obs);
    setTransform(oldTransform);

    return ret;
  }

  /** Renders a RenderableImage, applying a transform from image
      space into user space before drawing. */
  public void drawRenderableImage(RenderableImage img, AffineTransform xform)
  {
    // FIXME
  }

  /** Renders a RenderedImage, applying a transform from
      image space into user space before drawing. */
  public void drawRenderedImage(RenderedImage img, AffineTransform xform)
  {
    // FIXME
  }

  //-------------------------------------------------------------------------
  public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
  {
    setStroke(ordinaryStroke);
    draw(new Polygon(xPoints, yPoints, nPoints));
    setStroke(currentStroke);
  }

  public void drawString(String str, int x, int y)
  {
    drawString(str, (float) x, (float) y);
  }

  public void drawString(String str, float x, float y)
  {
    if( str.trim().equals("") )
      return; // don't draw whitespace, silly!

    if( currentFontIsPS )
      {
	drawStringPSFont(str, x, y);
	return;
      }

    TextLayout text = new TextLayout(str, currentFont, getFontRenderContext());
    Shape s = text.getOutline(AffineTransform.getTranslateInstance(x, y));
    drawStringShape(s);
  }

  private void drawStringPSFont(String str, float x, float y)
  {
    out.println("% drawString PS font");
    out.println(x + " " + y + " moveto");
    saveAndInvertAxis();
    out.println("(" + str + ") show");
    restoreAxis();
  }

  private void saveAndInvertAxis()
  {
    // Invert the Y axis of the CTM.
    popCTM();
    pushCTM();

    double[] test = 
      {
	pageTransform.getScaleX(), pageTransform.getShearY(),
	pageTransform.getShearX(), pageTransform.getScaleY(),
	pageTransform.getTranslateX(),
	-pageTransform.getTranslateY() + pageY
      };

    double[] test2 = 
      {
	currentTransform.getScaleX(),
	currentTransform.getShearY(),
	-currentTransform.getShearX(),
	-currentTransform.getScaleY(),
	currentTransform.getTranslateX(),
	currentTransform.getTranslateY()
      };

    AffineTransform total = new AffineTransform(test);
    total.concatenate(new AffineTransform(test2));
    concatCTM(total);
  }

  private void restoreAxis()
  {
    // reset the CTM
    popCTM();
    pushCTM();
    AffineTransform total = new AffineTransform(pageTransform);
    total.concatenate(currentTransform);
    concatCTM(total);
  }

  /**
   * special drawing routine for string shapes,
   * which need to be drawn with the Y axis uninverted.
   */
  private void drawStringShape(Shape s)
  {
    saveAndInvertAxis();

    // draw the shape s with an inverted Y axis.
    PathIterator pi = s.getPathIterator(null);
    float[] coords = new float[6];

    while (! pi.isDone())
      {
	switch (pi.currentSegment(coords))
	  {
	  case PathIterator.SEG_MOVETO:
	    out.println((coords[0]) + " " + (Y - coords[1]) + " moveto");
	    cx = coords[0];
	    cy = coords[1];
	    break;
	  case PathIterator.SEG_LINETO:
	    out.println((coords[0]) + " " + (Y - coords[1]) + " lineto");
	    cx = coords[0];
	    cy = coords[1];
	    break;
	  case PathIterator.SEG_QUADTO:
	    // convert to cubic bezier points
	    float x1 = (cx + 2 * coords[0]) / 3;
	    float y1 = (cy + 2 * coords[1]) / 3;
	    float x2 = (2 * coords[2] + coords[0]) / 3;
	    float y2 = (2 * coords[3] + coords[1]) / 3;

	    out.print((x1) + " " + (Y - y1) + " ");
	    out.print((x2) + " " + (Y - y2) + " ");
	    out.println((coords[2]) + " " + (Y - coords[3]) + " curveto");
	    cx = coords[2];
	    cy = coords[3];
	    break;
	  case PathIterator.SEG_CUBICTO:
	    out.print((coords[0]) + " " + (Y - coords[1]) + " ");
	    out.print((coords[2]) + " " + (Y - coords[3]) + " ");
	    out.println((coords[4]) + " " + (Y - coords[5]) + " curveto");
	    cx = coords[4];
	    cy = coords[5];
	    break;
	  case PathIterator.SEG_CLOSE:
	    out.println("closepath");
	    break;
	  }
	pi.next();
      }
    out.println("fill");

    restoreAxis();
  }

  public void setColor(Color c)
  {
    /* don't set the color if it's already set */
    if (c.equals(currentColor))
      return;
    gradientOn = false;
    currentColor = c;
    currentPaint = c; // Graphics2D extends colors to paint

    out.println(colorTriple(c) + " setrgbcolor");
  }

  public void clearRect(int x, int y, int width, int height)
  {
    out.println("% clearRect");
    Color c = currentColor;
    setColor(backgroundColor);
    fill(new Rectangle2D.Double(x, y, width, height));
    setColor(c);
  }

  public void clipRect(int x, int y, int width, int height)
  {
    clip(new Rectangle2D.Double(x, y, width, height));
  }

  public void copyArea(int x, int y, int width, int height, int dx, int dy)
  {
    // FIXME
  }

  public void fillRect(int x, int y, int width, int height)
  {
    fill(new Rectangle2D.Double(x, y, width, height));
  }

  public void dispose()
  {
  }

  public void setClip(int x, int y, int width, int height)
  {
    out.println("% setClip()");
    setClip(new Rectangle2D.Double(x, y, width, height));
  }

  public void setClip(Shape s)
  {
    clip(s);
  }

  public Shape getClip()
  {
    return clipShape;
  }

  public Rectangle getClipBounds()
  {
    return clipShape.getBounds();
  }

  public Color getColor()
  {
    return currentColor;
  }

  public Font getFont()
  {
    return currentFont;
  }

  public FontMetrics getFontMetrics()
  {
    return getFontMetrics(currentFont);
  }

  public FontMetrics getFontMetrics(Font f)
  {
    // FIXME
    return null;
  }

  public void setFont(Font font)
  {
    out.println("% setfont()");
    if (font == null)
      // use the default font
      font = new Font("Dialog", Font.PLAIN, 12);
    currentFont = font;
    setPSFont(); // set up the PostScript fonts
  }

  /**
   * Setup the postscript font if the current font is one
   */
  private void setPSFont()
  {
    currentFontIsPS = false;

    String s = currentFont.getName();
    out.println("% setPSFont: Fontname: " + s);
    if (s.equalsIgnoreCase("Helvetica") || s.equalsIgnoreCase("SansSerif"))
      out.print("/helveticaISO findfont ");
    else if (s.equalsIgnoreCase("Times New Roman"))
      out.print("/timesISO findfont ");
    else if (s.equalsIgnoreCase("Courier"))
      out.print("/courierISO findfont ");
    else
      return;

    currentFontIsPS = true;

    out.print(currentFont.getSize() + " scalefont ");
    out.println("setfont");
  }

  /** XOR mode is not supported */
  public void setPaintMode()
  {
  }

  /** XOR mode is not supported */
  public void setXORMode(Color c1)
  {
  }

  public void close()
  {
    out.println("showpage");
    out.println("%%Trailer");
    out.println("grestore % restore original stuff");
    out.println("%%EOF");

    try
      {
	out.close();
      }
    catch (Exception e)
      {
      }
    out = null;
  }

  //----------------------------------------------------------------
  // Graphics2D stuff ----------------------------------------------

  /**  Sets the values of an arbitrary number of
       preferences for the rendering algorithms. */
  public void addRenderingHints(Map hints)
  {
    /* rendering hint changes are disallowed */
  }

  /** write a shape to the file */
  private void writeShape(Shape s)
  {
    PathIterator pi = s.getPathIterator(null);
    float[] coords = new float[6];

    while (! pi.isDone())
      {
	switch (pi.currentSegment(coords))
	  {
	  case PathIterator.SEG_MOVETO:
	    out.println(coords[0] + " " + (coords[1]) + " moveto");
	    cx = coords[0];
	    cy = coords[1];
	    break;
	  case PathIterator.SEG_LINETO:
	    out.println(coords[0] + " " + (coords[1]) + " lineto");
	    cx = coords[0];
	    cy = coords[1];
	    break;
	  case PathIterator.SEG_QUADTO:
	    // convert to cubic bezier points
	    float x1 = (cx + 2 * coords[0]) / 3;
	    float y1 = (cy + 2 * coords[1]) / 3;
	    float x2 = (2 * coords[2] + coords[0]) / 3;
	    float y2 = (2 * coords[3] + coords[1]) / 3;

	    out.print(x1 + " " + (Y - y1) + " ");
	    out.print(x2 + " " + (Y - y2) + " ");
	    out.println(coords[2] + " " + (Y - coords[3]) + " curveto");
	    cx = coords[2];
	    cy = coords[3];
	    break;
	  case PathIterator.SEG_CUBICTO:
	    out.print(coords[0] + " " + coords[1] + " ");
	    out.print(coords[2] + " " + coords[3] + " ");
	    out.println(coords[4] + " " + coords[5] + " curveto");
	    cx = coords[4];
	    cy = coords[5];
	    break;
	  case PathIterator.SEG_CLOSE:
	    out.println("closepath");
	    break;
	  }
	pi.next();
      }
  }

  /** Intersects the current Clip with the interior of
      the specified Shape and sets the Clip to the resulting intersection. */
  public void clip(Shape s)
  {
    clipShape = s;
    out.println("% clip INACTIVE");
    //	writeShape(s);
    //	out.println("clip");
  }

  /** Strokes the outline of a Shape using the
      settings of the current Graphics2D context.*/
  public void draw(Shape s)
  {
    if(!(currentStroke instanceof BasicStroke))
      fill(currentStroke.createStrokedShape(s));

    out.println("% draw");
    writeShape(s);
    out.println("stroke");
  }

  /** Renders the text of the specified GlyphVector using the
      Graphics2D context's rendering attributes. */
  public void drawGlyphVector(GlyphVector gv, float x, float y)
  {
    out.println("% drawGlyphVector");
    Shape s = gv.getOutline();
    drawStringShape(AffineTransform.getTranslateInstance(x, y)
		    .createTransformedShape(s));
  }

  /** Renders the text of the specified iterator,
      using the Graphics2D context's current Paint.*/
  public void drawString(AttributedCharacterIterator iterator, float x, float y)
  {
    TextLayout text = new TextLayout(iterator, getFontRenderContext());
    Shape s = text.getOutline(AffineTransform.getTranslateInstance(x, y));
    drawStringShape(s);
  }

  /** Renders the text of the specified iterator,
      using the Graphics2D context's current Paint. */
  public void drawString(AttributedCharacterIterator iterator, int x, int y)
  {
    drawString(iterator, (float) x, (float) y);
  }

  /** Fills the interior of a Shape using the settings of the Graphics2D context. */
  public void fill(Shape s)
  {
    out.println("% fill");
    if (! gradientOn)
      {
	writeShape(s);
	out.println("fill");
      }
    else
      {
	out.println("gsave");
	writeShape(s);
	out.println("clip");
	writeGradient();
	out.println("shfill");
	out.println("grestore");
      }
  }

  /** Returns the background color used for clearing a region. */
  public Color getBackground()
  {
    return backgroundColor;
  }

  /** Returns the current Composite in the Graphics2D context. */
  public Composite getComposite()
  {
    // FIXME
    return null;
  }

  /** Returns the device configuration associated with this Graphics2D. */
  public GraphicsConfiguration getDeviceConfiguration()
  {
    // FIXME
    out.println("% getDeviceConfiguration()");
    return null;
  }

  /** Get the rendering context of the Font within this Graphics2D context. */
  public FontRenderContext getFontRenderContext()
  {
    out.println("% getFontRenderContext()");

    double[] scaling = 
      {
	pageTransform.getScaleX(), 0, 0,
	-pageTransform.getScaleY(), 0, 0
      };

    return (new FontRenderContext(new AffineTransform(scaling), false, true));
  }

  /** Returns the current Paint of the Graphics2D context. */
  public Paint getPaint()
  {
    return currentPaint;
  }

  /** Returns the value of a single preference for the rendering algorithms. */
  public Object getRenderingHint(RenderingHints.Key hintKey)
  {
    return renderingHints.get(hintKey);
  }

  /** Gets the preferences for the rendering algorithms. */
  public RenderingHints getRenderingHints()
  {
    return renderingHints;
  }

  /** Returns the current Stroke in the Graphics2D context. */
  public Stroke getStroke()
  {
    return currentStroke;
  }

  /** Returns a copy of the current Transform in the Graphics2D context. */
  public AffineTransform getTransform()
  {
    return currentTransform;
  }

  /** 
   * Checks whether or not the specified Shape intersects 
   * the specified Rectangle, which is in device space. 
   */
  public boolean hit(Rectangle rect, Shape s, boolean onStroke)
  {
    Rectangle2D.Double r = new Rectangle2D.Double(rect.getX(), rect.getY(),
						  rect.getWidth(),
						  rect.getHeight());
    return s.intersects(r);
  }

  /** Sets the background color for the Graphics2D context.*/
  public void setBackground(Color color)
  {
    out.println("% setBackground(" + color + ")");
    backgroundColor = color;
  }

  /** Sets the Composite for the Graphics2D context.
      Not supported. */
  public void setComposite(Composite comp)
  {
  }

  /** Sets the Paint attribute for the Graphics2D context.*/
  public void setPaint(Paint paint)
  {
    currentPaint = paint;
    gradientOn = false;
    if (paint instanceof Color)
      {
	setColor((Color) paint);
	return;
      }
    if (paint instanceof GradientPaint)
      {
	gradientOn = true;
	return;
      }
  }

  /* get a space seperated 0.0 - 1.0 color RGB triple */
  private String colorTriple(Color c)
  {
    return (((double) c.getRed() / 255.0) + " "
	    + ((double) c.getGreen() / 255.0) + " "
	    + ((double) c.getBlue() / 255.0));
  }

  /**
   * Get a nonsperated hex RGB triple, eg FFFFFF = white
   * used by writeGradient and drawImage 
   */
  private String colorTripleHex(Color c)
  {
    String r = "00" + Integer.toHexString(c.getRed());
    r = r.substring(r.length() - 2);
    String g = "00" + Integer.toHexString(c.getGreen());
    g = g.substring(g.length() - 2);
    String b = "00" + Integer.toHexString(c.getBlue());
    b = b.substring(b.length() - 2);
    return r + g + b;
  }

  /* write the current gradient fill */
  private void writeGradient()
  {
    GradientPaint paint = (GradientPaint) currentPaint;
    out.println("% writeGradient()");

    int n = 1;
    double x;
    double y;
    double dx;
    double dy;
    Point2D p1 = currentTransform.transform(paint.getPoint1(), null);
    Point2D p2 = currentTransform.transform(paint.getPoint2(), null);
    x = p1.getX();
    y = p1.getY();
    dx = p2.getX() - x;
    dy = p2.getY() - y;

    // get number of repetitions
    while (x + n * dx < pageY && y + n * dy < pageX && x + n * dx > 0
	   && y + n * dy > 0)
      n++;

    out.println("<<"); // start
    out.println("/ShadingType 2"); // gradient fill 
    out.println("/ColorSpace [ /DeviceRGB ]"); // RGB colors
    out.print("/Coords [");
    out.print(x + " " + y + " " + (x + n * dx) + " " + (y + n * dy) + " ");
    out.println("]"); // coordinates defining the axis
    out.println("/Function <<");
    out.println("/FunctionType 0");
    out.println("/Order 1");
    out.println("/Domain [ 0 1 ]");
    out.println("/Range [ 0 1  0 1  0 1 ]");
    out.println("/BitsPerSample 8");
    out.println("/Size [ " + (1 + n) + " ]");
    out.print("/DataSource < " + colorTripleHex(paint.getColor1()) + " "
	      + colorTripleHex(paint.getColor2()) + " ");
    for (; n > 1; n--)
      if (paint.isCyclic())
	{
	  if ((n % 2) == 1)
	    out.print(colorTripleHex(paint.getColor1()) + " ");
	  else
	    out.print(colorTripleHex(paint.getColor2()) + " ");
	}
      else
	out.print(colorTripleHex(paint.getColor2()) + " ");
    out.println(">");
    out.println(">>");
    out.println(">>");
  }

  /** Sets the value of a single preference for the rendering algorithms. */
  public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue)
  {
    /* we don't allow the changing of rendering hints. */
  }

  /** Replaces the values of all preferences for the rendering algorithms
      with the specified hints. */
  public void setRenderingHints(Map hints)
  {
    /* we don't allow the changing of rendering hints. */
  }

  /** 
   * Sets the Stroke for the Graphics2D context. BasicStroke fully implemented.
   */
  public void setStroke(Stroke s)
  {
    currentStroke = s;

    if (! (s instanceof BasicStroke))
      return;

    BasicStroke bs = (BasicStroke) s;
    out.println("% setStroke()");
    try
      {
	// set the line width
	out.println(bs.getLineWidth() + " setlinewidth");

	// set the line dash
	float[] dashArray = bs.getDashArray();
	if (dashArray != null)
	  {
	    out.print("[ ");
	    for (int i = 0; i < dashArray.length; i++)
	      out.print(dashArray[i] + " ");
	    out.println("] " + bs.getDashPhase() + " setdash");
	  }
	else
	  out.println("[] 0 setdash"); // set solid

	// set the line cap
	switch (bs.getEndCap())
	  {
	  case BasicStroke.CAP_BUTT:
	    out.println("0 setlinecap");
	    break;
	  case BasicStroke.CAP_ROUND:
	    out.println("1 setlinecap");
	    break;
	  case BasicStroke.CAP_SQUARE:
	    out.println("2 setlinecap");
	    break;
	  }

	// set the line join
	switch (bs.getLineJoin())
	  {
	  case BasicStroke.JOIN_BEVEL:
	    out.println("2 setlinejoin");
	    break;
	  case BasicStroke.JOIN_MITER:
	    out.println("0 setlinejoin");
	    out.println(bs.getMiterLimit() + " setmiterlimit");
	    break;
	  case BasicStroke.JOIN_ROUND:
	    out.println("1 setlinejoin");
	    break;
	  }
      }
    catch (Exception e)
      {
	out.println("% Exception in setStroke()");
      }
  }

  //////////////////// TRANSFORM SETTING /////////////////////////////////////
  private void concatCTM(AffineTransform Tx)
  {
    double[] matrixElements = new double[6];
    Tx.getMatrix(matrixElements);

    out.print("[ ");
    for (int i = 0; i < 6; i++)
      out.print(matrixElements[i] + " ");
    out.println("] concat");
  }

  /** Sets the Transform in the Graphics2D context. */
  public void setTransform(AffineTransform Tx)
  {
    // set the transformation matrix;
    currentTransform = Tx;

    // concatenate the current transform and the page transform
    AffineTransform totalTransform = new AffineTransform(pageTransform);
    totalTransform.concatenate(currentTransform);
    out.println("% setTransform()");
    out.println("% pageTransform:" + pageTransform);
    out.println("% currentTransform:" + currentTransform);
    out.println("% totalTransform:" + totalTransform);

    popCTM();
    pushCTM(); // set the CTM to it's original state
    concatCTM(totalTransform); // apply our transforms
  }

  /** Composes an AffineTransform object with the Transform
      in this Graphics2D according to the rule last-specified-first-applied. */
  public void transform(AffineTransform Tx)
  {
    // concatenate the current transform
    currentTransform.concatenate(Tx);
    // and the PS CTM
    concatCTM(Tx);
  }

  ////////////////////////// TRANSFORMS //////////////////////////////////////

  /** shear transform */
  public void shear(double shx, double shy)
  {
    out.println("% shear()");
    AffineTransform Tx = new AffineTransform();
    Tx.shear(shx, shy);
    transform(Tx);
  }

  /** Translates the origin of the Graphics2D context
      to the point (x, y) in the current coordinate system. */
  public void translate(int x, int y)
  {
    out.println("% translate()");
    AffineTransform Tx = new AffineTransform();
    Tx.translate(x, y);
    transform(Tx);
  }

  /** Translates the origin of the Graphics2D context
      to the point (x, y) in the current coordinate system. */
  public void translate(double x, double y)
  {
    out.println("% translate(" + x + ", " + y + ")");
    AffineTransform Tx = new AffineTransform();
    Tx.translate(x, y);
    transform(Tx);
  }

  /** Concatenates the current Graphics2D Transform with a rotation transform.*/
  public void rotate(double theta)
  {
    out.println("% rotate(" + theta + ")");
    AffineTransform Tx = new AffineTransform();
    Tx.rotate(theta);
    transform(Tx);
  }

  /** Concatenates the current Graphics2D Transform with
      a translated rotation transform.*/
  public void rotate(double theta, double x, double y)
  {
    out.println("% rotate()");
    AffineTransform Tx = new AffineTransform();
    Tx.rotate(theta, x, y);
    transform(Tx);
  }

  /** Concatenates the current Graphics2D Transform with a scaling
      transformation Subsequent rendering is resized according to the
      specified scaling factors relative to the previous scaling.*/
  public void scale(double sx, double sy)
  {
    out.println("% scale(" + sx + ", " + sy + ")");
    AffineTransform Tx = new AffineTransform();
    Tx.scale(sx, sy);
    transform(Tx);
  }
}
