/**
  * Draw a filled rectangle in current pen color.
  *
  * @param x starting x coord
  * @param y starting y coord
  * @param width rectangle width
  * @param height rectangle height
  */
 public void fillRect(int x, int y, int width, int height) {
   if (width == m_extent.width && height == m_extent.height) {
     clearRect(x, y, width, height); // if we're painting the entire background, just make it white
   } else {
     if (DEBUG) m_printstream.println("% fillRect");
     setStateToLocal();
     m_printstream.println(
         xTransform(xScale(x))
             + " "
             + yTransform(yScale(y))
             + " "
             + xScale(width)
             + " "
             + yScale(height)
             + " true Rect");
   }
 }
  /**
   * Set current font. Default to Plain Courier 11 if null.
   *
   * @param font new font.
   */
  public void setFont(Font font) {

    if (font != null) {
      m_localGraphicsState.setFont(font);
      if (font.getName().equals(m_psGraphicsState.getFont().getName())
          && (m_psGraphicsState.getFont().getStyle() == font.getStyle())
          && (m_psGraphicsState.getFont().getSize() == yScale(font.getSize()))) return;
      m_psGraphicsState.setFont(
          new Font(font.getName(), font.getStyle(), yScale(getFont().getSize())));
    } else {
      m_localGraphicsState.setFont(new Font("Courier", Font.PLAIN, 11));
      m_psGraphicsState.setFont(getFont());
    }

    m_printstream.println("/(" + replacePSFont(getFont().getPSName()) + ")" + " findfont");
    m_printstream.println(yScale(getFont().getSize()) + " scalefont setfont");
  }
 /**
  * Draw text in current pen color.
  *
  * @param str Text to output
  * @param x starting x coord
  * @param y starting y coord
  */
 public void drawString(String str, int x, int y) {
   setStateToLocal();
   m_printstream.println(
       xTransform(xScale(x))
           + " "
           + yTransform(yScale(y))
           + " moveto"
           + " ("
           + escape(str)
           + ") show stroke");
 }
 /**
  * Draw a filled Oval in current pen color.
  *
  * @param x x-axis center of oval
  * @param y y-axis center of oval
  * @param width oval width
  * @param height oval height
  */
 public void fillOval(int x, int y, int width, int height) {
   setStateToLocal();
   m_printstream.println(
       xTransform(xScale(x))
           + " "
           + yTransform(yScale(y))
           + " "
           + xScale(width)
           + " "
           + yScale(height)
           + " true Oval");
 }
 /**
  * Draw an outlined rectangle in current pen color.
  *
  * @param x starting x coord
  * @param y starting y coord
  * @param width rectangle width
  * @param height rectangle height
  */
 public void drawRect(int x, int y, int width, int height) {
   setStateToLocal();
   m_printstream.println(
       xTransform(xScale(x))
           + " "
           + yTransform(yScale(y))
           + " "
           + xScale(width)
           + " "
           + yScale(height)
           + " false Rect");
 }
 /**
  * Draw a line in current pen color.
  *
  * @param x1 starting x coord
  * @param y1 starting y coord
  * @param x2 ending x coord
  * @param y2 ending y coord
  */
 public void drawLine(int x1, int y1, int x2, int y2) {
   setStateToLocal();
   m_printstream.println(
       xTransform(xScale(x1))
           + " "
           + yTransform(yScale(y1))
           + " moveto "
           + xTransform(xScale(x2))
           + " "
           + yTransform(yScale(y2))
           + " lineto stroke");
 }
 /**
  * Draw a filled rectangle with the background color.
  *
  * @param x starting x coord
  * @param y starting y coord
  * @param width rectangle width
  * @param height rectangle height
  */
 public void clearRect(int x, int y, int width, int height) {
   setStateToLocal();
   Color saveColor = getColor();
   setColor(Color.white); // background color for page
   m_printstream.println(
       xTransform(xScale(x))
           + " "
           + yTransform(yScale(y))
           + " "
           + xScale(width)
           + " "
           + yScale(height)
           + " true Rect");
   setColor(saveColor);
 }
  /**
   * PS see http://astronomy.swin.edu.au/~pbourke/geomformats/postscript/ Java
   * http://show.docjava.com:8086/book/cgij/doc/ip/graphics/SimpleImageFrame.java.html
   */
  public boolean drawImage(
      Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer) {
    try {
      // get data from image
      int[] pixels = new int[width * height];
      PixelGrabber grabber = new PixelGrabber(img, 0, 0, width, height, pixels, 0, width);
      grabber.grabPixels();
      ColorModel model = ColorModel.getRGBdefault();

      // print data to ps
      m_printstream.println("gsave");
      m_printstream.println(
          xTransform(xScale(x)) + " " + (yTransform(yScale(y)) - yScale(height)) + " translate");
      m_printstream.println(xScale(width) + " " + yScale(height) + " scale");
      m_printstream.println(
          width + " " + height + " " + "8" + " [" + width + " 0 0 " + (-height) + " 0 " + height
              + "]");
      m_printstream.println("{<");

      int index;
      for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
          index = i * width + j;
          m_printstream.print(toHex(model.getRed(pixels[index])));
          m_printstream.print(toHex(model.getGreen(pixels[index])));
          m_printstream.print(toHex(model.getBlue(pixels[index])));
        }
        m_printstream.println();
      }

      m_printstream.println(">}");
      m_printstream.println("false 3 colorimage");
      m_printstream.println("grestore");
      return true;
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    }
  }
 /**
  * Set current pen color. Default to black if null.
  *
  * @param c new pen color.
  */
 public void setColor(Color c) {
   if (c != null) {
     m_localGraphicsState.setColor(c);
     if (m_psGraphicsState.getColor().equals(c)) {
       return;
     }
     m_psGraphicsState.setColor(c);
   } else {
     m_localGraphicsState.setColor(Color.black);
     m_psGraphicsState.setColor(getColor());
   }
   m_printstream.print(getColor().getRed() / 255.0);
   m_printstream.print(" ");
   m_printstream.print(getColor().getGreen() / 255.0);
   m_printstream.print(" ");
   m_printstream.print(getColor().getBlue() / 255.0);
   m_printstream.println(" setrgbcolor");
 }
 /** Clone a PostscriptGraphics object */
 public Graphics create() {
   if (DEBUG) m_printstream.println("%create");
   PostscriptGraphics psg = new PostscriptGraphics(this);
   return (psg);
 }
  /** Output postscript header to PrintStream, including helper macros. */
  private void Header() {
    m_printstream.println("%!PS-Adobe-3.0 EPSF-3.0");
    m_printstream.println(
        "%%BoundingBox: 0 0 " + xScale(m_extent.width) + " " + yScale(m_extent.height));
    m_printstream.println("%%CreationDate: " + Calendar.getInstance().getTime());

    m_printstream.println("/Oval { % x y w h filled");
    m_printstream.println("gsave");
    m_printstream.println("/filled exch def /h exch def /w exch def /y exch def /x exch def");
    m_printstream.println("x w 2 div add y h 2 div sub translate");
    m_printstream.println("1 h w div scale");
    m_printstream.println("filled {0 0 moveto} if");
    m_printstream.println("0 0 w 2 div 0 360 arc");
    m_printstream.println("filled {closepath fill} {stroke} ifelse grestore} bind def");

    m_printstream.println("/Rect { % x y w h filled");
    m_printstream.println("/filled exch def /h exch def /w exch def /y exch def /x exch def");
    m_printstream.println("newpath ");
    m_printstream.println("x y moveto");
    m_printstream.println("w 0 rlineto");
    m_printstream.println("0 h neg rlineto");
    m_printstream.println("w neg 0 rlineto");
    m_printstream.println("closepath");
    m_printstream.println("filled {fill} {stroke} ifelse} bind def");

    m_printstream.println("%%BeginProlog\n%%EndProlog");
    m_printstream.println("%%Page 1 1");
    setFont(null); // set to default
    setColor(null); // set to default
    setStroke(null); // set to default
  }