/*
 * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package sun.print;

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GraphicsEnvironment;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.HeadlessException;
import java.awt.Rectangle;
import java.awt.Shape;

import java.awt.image.BufferedImage;

import java.awt.font.FontRenderContext;

import java.awt.geom.AffineTransform;
import java.awt.geom.PathIterator;
import java.awt.geom.Rectangle2D;

import java.awt.image.BufferedImage;

import java.awt.print.Pageable;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterIOException;
import java.awt.print.PrinterJob;

import javax.print.DocFlavor;
import javax.print.PrintService;
import javax.print.StreamPrintService;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Chromaticity;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.Destination;
import javax.print.attribute.standard.DialogTypeSelection;
import javax.print.attribute.standard.JobName;
import javax.print.attribute.standard.Sides;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.CharConversionException;
import java.io.File;
import java.io.InputStream;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Properties;

import sun.awt.CharsetString;
import sun.awt.FontConfiguration;
import sun.awt.FontDescriptor;
import sun.awt.PlatformFont;
import sun.awt.SunToolkit;

import java.nio.charset.*;
import java.nio.CharBuffer;
import java.nio.ByteBuffer;

//REMIND: Remove use of this class when IPPPrintService is moved to share directory.
import java.lang.reflect.Method;

/**
 * A class which initiates and executes a PostScript printer job.
 *
 * @author Richard Blanchard
 */
public class PSPrinterJob extends RasterPrinterJob {

 /* Class Constants */

    /**
     * Passed to the <code>setFillMode</code>
     * method this value forces fills to be
     * done using the even-odd fill rule.
     */
    protected static final int FILL_EVEN_ODD = 1;

    /**
     * Passed to the <code>setFillMode</code>
     * method this value forces fills to be
     * done using the non-zero winding rule.
     */
    protected static final int FILL_WINDING = 2;

    /* PostScript has a 64K maximum on its strings.
     */
    private static final int MAX_PSSTR = (1024 * 64 - 1);

    private static final int RED_MASK = 0x00ff0000;
    private static final int GREEN_MASK = 0x0000ff00;
    private static final int BLUE_MASK = 0x000000ff;

    private static final int RED_SHIFT = 16;
    private static final int GREEN_SHIFT = 8;
    private static final int BLUE_SHIFT = 0;

    private static final int LOWNIBBLE_MASK = 0x0000000f;
    private static final int HINIBBLE_MASK =  0x000000f0;
    private static final int HINIBBLE_SHIFT = 4;
    private static final byte hexDigits[] = {
        (byte)'0', (byte)'1', (byte)'2', (byte)'3',
        (byte)'4', (byte)'5', (byte)'6', (byte)'7',
        (byte)'8', (byte)'9', (byte)'A', (byte)'B',
        (byte)'C', (byte)'D', (byte)'E', (byte)'F'
    };

    private static final int PS_XRES = 300;
    private static final int PS_YRES = 300;

    private static final String ADOBE_PS_STR =  "%!PS-Adobe-3.0";
    private static final String EOF_COMMENT =   "%%EOF";
    private static final String PAGE_COMMENT =  "%%Page: ";

    private static final String READIMAGEPROC = "/imStr 0 def /imageSrc " +
        "{currentfile /ASCII85Decode filter /RunLengthDecode filter " +
        " imStr readstring pop } def";

    private static final String COPIES =        "/#copies exch def";
    private static final String PAGE_SAVE =     "/pgSave save def";
    private static final String PAGE_RESTORE =  "pgSave restore";
    private static final String SHOWPAGE =      "showpage";
    private static final String IMAGE_SAVE =    "/imSave save def";
    private static final String IMAGE_STR =     " string /imStr exch def";
    private static final String IMAGE_RESTORE = "imSave restore";

    private static final String COORD_PREP =    " 0 exch translate "
                                              + "1 -1 scale"
                                              + "[72 " + PS_XRES + " div "
                                              + "0 0 "
                                              + "72 " + PS_YRES + " div "
                                              + "0 0]concat";

    private static final String SetFontName = "F";

    private static final String DrawStringName = "S";

    /**
     * The PostScript invocation to fill a path using the
     * even-odd rule. (eofill)
     */
    private static final String EVEN_ODD_FILL_STR = "EF";

    /**
     * The PostScript invocation to fill a path using the
     * non-zero winding rule. (fill)
     */
    private static final String WINDING_FILL_STR = "WF";

    /**
     * The PostScript to set the clip to be the current path
     * using the even odd rule. (eoclip)
     */
    private static final String EVEN_ODD_CLIP_STR = "EC";

    /**
     * The PostScript to set the clip to be the current path
     * using the non-zero winding rule. (clip)
     */
    private static final String WINDING_CLIP_STR = "WC";

    /**
     * Expecting two numbers on the PostScript stack, this
     * invocation moves the current pen position. (moveto)
     */
    private static final String MOVETO_STR = " M";
    /**
     * Expecting two numbers on the PostScript stack, this
     * invocation draws a PS line from the current pen
     * position to the point on the stack. (lineto)
     */
    private static final String LINETO_STR = " L";

    /**
     * This PostScript operator takes two control points
     * and an ending point and using the current pen
     * position as a starting point adds a bezier
     * curve to the current path. (curveto)
     */
    private static final String CURVETO_STR = " C";

    /**
     * The PostScript to pop a state off of the printer's
     * gstate stack. (grestore)
     */
    private static final String GRESTORE_STR = "R";
    /**
     * The PostScript to push a state on to the printer's
     * gstate stack. (gsave)
     */
    private static final String GSAVE_STR = "G";

    /**
     * Make the current PostScript path an empty path. (newpath)
     */
    private static final String NEWPATH_STR = "N";

    /**
     * Close the current subpath by generating a line segment
     * from the current position to the start of the subpath. (closepath)
     */
    private static final String CLOSEPATH_STR = "P";

    /**
     * Use the three numbers on top of the PS operator
     * stack to set the rgb color. (setrgbcolor)
     */
    private static final String SETRGBCOLOR_STR = " SC";

    /**
     * Use the top number on the stack to set the printer's
     * current gray value. (setgray)
     */
    private static final String SETGRAY_STR = " SG";

 /* Instance Variables */

   private int mDestType;

   private String mDestination = "lp";

   private boolean mNoJobSheet = false;

   private String mOptions;

   private Font mLastFont;

   private Color mLastColor;

   private Shape mLastClip;

   private AffineTransform mLastTransform;

   /* non-null if printing EPS for Java Plugin */
   private EPSPrinter epsPrinter = null;

   /**
    * The metrics for the font currently set.
    */
   FontMetrics mCurMetrics;

   /**
    * The output stream to which the generated PostScript
    * is written.
    */
   PrintStream mPSStream;

   /* The temporary file to which we spool before sending to the printer  */

   File spoolFile;

   /**
    * This string holds the PostScript operator to
    * be used to fill a path. It can be changed
    * by the <code>setFillMode</code> method.
    */
    private String mFillOpStr = WINDING_FILL_STR;

   /**
    * This string holds the PostScript operator to
    * be used to clip to a path. It can be changed
    * by the <code>setFillMode</code> method.
    */
    private String mClipOpStr = WINDING_CLIP_STR;

   /**
    * A stack that represents the PostScript gstate stack.
    */
   ArrayList mGStateStack = new ArrayList();

   /**
    * The x coordinate of the current pen position.
    */
   private float mPenX;

   /**
    * The y coordinate of the current pen position.
    */
   private float mPenY;

   /**
    * The x coordinate of the starting point of
    * the current subpath.
    */
   private float mStartPathX;

   /**
    * The y coordinate of the starting point of
    * the current subpath.
    */
   private float mStartPathY;

   /**
    * An optional mapping of fonts to PostScript names.
    */
   private static Properties mFontProps = null;

    /* Class static initialiser block */
    static {
       //enable priviledges so initProps can access system properties,
        // open the property file, etc.
        java.security.AccessController.doPrivileged(
                            new java.security.PrivilegedAction() {
            public Object run() {
                mFontProps = initProps();
                return null;
            }
        });
    }

    /*
     * Initialize PostScript font properties.
     * Copied from PSPrintStream
     */
    private static Properties initProps() {
        // search psfont.properties for fonts
        // and create and initialize fontProps if it exist.

        String jhome = System.getProperty("java.home");

        if (jhome != null){
            String ulocale = SunToolkit.getStartupLocale().getLanguage();
            try {

                File f = new File(jhome + File.separator +
                                  "lib" + File.separator +
                                  "psfontj2d.properties." + ulocale);

                if (!f.canRead()){

                    f = new File(jhome + File.separator +
                                      "lib" + File.separator +
                                      "psfont.properties." + ulocale);
                    if (!f.canRead()){

                        f = new File(jhome + File.separator + "lib" +
                                     File.separator + "psfontj2d.properties");

                        if (!f.canRead()){

                            f = new File(jhome + File.separator + "lib" +
                                         File.separator + "psfont.properties");

                            if (!f.canRead()){
                                return (Properties)null;
                            }
                        }
                    }
                }

                // Load property file
                InputStream in =
                    new BufferedInputStream(new FileInputStream(f.getPath()));
                Properties props = new Properties();
                props.load(in);
                in.close();
                return props;
            } catch (Exception e){
                return (Properties)null;
            }
        }
        return (Properties)null;
    }

 /* Constructors */

    public PSPrinterJob()
    {
    }

 /* Instance Methods */

   /**
     * Presents the user a dialog for changing properties of the
     * print job interactively.
     * @returns false if the user cancels the dialog and
     *          true otherwise.
     * @exception HeadlessException if GraphicsEnvironment.isHeadless()
     * returns true.
     * @see java.awt.GraphicsEnvironment#isHeadless
     */
    public boolean printDialog() throws HeadlessException {

        if (GraphicsEnvironment.isHeadless()) {
            throw new HeadlessException();
        }

        if (attributes == null) {
            attributes = new HashPrintRequestAttributeSet();
        }
        attributes.add(new Copies(getCopies()));
        attributes.add(new JobName(getJobName(), null));

        boolean doPrint = false;
        DialogTypeSelection dts =
            (DialogTypeSelection)attributes.get(DialogTypeSelection.class);
        if (dts == DialogTypeSelection.NATIVE) {
            // Remove DialogTypeSelection.NATIVE to prevent infinite loop in
            // RasterPrinterJob.
            attributes.remove(DialogTypeSelection.class);
            doPrint = printDialog(attributes);
            // restore attribute
            attributes.add(DialogTypeSelection.NATIVE);
        } else {
            doPrint = printDialog(attributes);
        }

        if (doPrint) {
            JobName jobName = (JobName)attributes.get(JobName.class);
            if (jobName != null) {
                setJobName(jobName.getValue());
            }
            Copies copies = (Copies)attributes.get(Copies.class);
            if (copies != null) {
                setCopies(copies.getValue());
            }

            Destination dest = (Destination)attributes.get(Destination.class);

            if (dest != null) {
                try {
                    mDestType = RasterPrinterJob.FILE;
                    mDestination = (new File(dest.getURI())).getPath();
                } catch (Exception e) {
                    mDestination = "out.ps";
                }
            } else {
                mDestType = RasterPrinterJob.PRINTER;
                PrintService pServ = getPrintService();
                if (pServ != null) {
                    mDestination = pServ.getName();
                }
            }
        }

        return doPrint;
    }

    /**
     * Invoked by the RasterPrinterJob super class
     * this method is called to mark the start of a
     * document.
     */
    protected void startDoc() throws PrinterException {

        // A security check has been performed in the
        // java.awt.print.printerJob.getPrinterJob method.
        // We use an inner class to execute the privilged open operations.
        // Note that we only open a file if it has been nominated by
        // the end-user in a dialog that we ouselves put up.

        OutputStream output;

        if (epsPrinter == null) {
            if (getPrintService() instanceof PSStreamPrintService) {
                StreamPrintService sps = (StreamPrintService)getPrintService();
                mDestType = RasterPrinterJob.STREAM;
                if (sps.isDisposed()) {
                    throw new PrinterException("service is disposed");
                }
                output = sps.getOutputStream();
                if (output == null) {
                    throw new PrinterException("Null output stream");
                }
            } else {
                /* REMIND: This needs to be more maintainable */
                mNoJobSheet = super.noJobSheet;
                if (super.destinationAttr != null) {
                    mDestType = RasterPrinterJob.FILE;
                    mDestination = super.destinationAttr;
                }
                if (mDestType == RasterPrinterJob.FILE) {
                    try {
                        spoolFile = new File(mDestination);
                        output =  new FileOutputStream(spoolFile);
                    } catch (IOException ex) {
                        throw new PrinterIOException(ex);
                    }
                } else {
                    PrinterOpener po = new PrinterOpener();
                    java.security.AccessController.doPrivileged(po);
                    if (po.pex != null) {
                        throw po.pex;
                    }
                    output = po.result;
                }
            }

            mPSStream = new PrintStream(new BufferedOutputStream(output));
            mPSStream.println(ADOBE_PS_STR);
        }

        mPSStream.println("%%BeginProlog");
        mPSStream.println(READIMAGEPROC);
        mPSStream.println("/BD {bind def} bind def");
        mPSStream.println("/D {def} BD");
        mPSStream.println("/C {curveto} BD");
        mPSStream.println("/L {lineto} BD");
        mPSStream.println("/M {moveto} BD");
        mPSStream.println("/R {grestore} BD");
        mPSStream.println("/G {gsave} BD");
        mPSStream.println("/N {newpath} BD");
        mPSStream.println("/P {closepath} BD");
        mPSStream.println("/EC {eoclip} BD");
        mPSStream.println("/WC {clip} BD");
        mPSStream.println("/EF {eofill} BD");
        mPSStream.println("/WF {fill} BD");
        mPSStream.println("/SG {setgray} BD");
        mPSStream.println("/SC {setrgbcolor} BD");
        mPSStream.println("/ISOF {");
        mPSStream.println("     dup findfont dup length 1 add dict begin {");
        mPSStream.println("             1 index /FID eq {pop pop} {D} ifelse");
        mPSStream.println("     } forall /Encoding ISOLatin1Encoding D");
        mPSStream.println("     currentdict end definefont");
        mPSStream.println("} BD");
        mPSStream.println("/NZ {dup 1 lt {pop 1} if} BD");
        /* The following procedure takes args: string, x, y, desiredWidth.
         * It calculates using stringwidth the width of the string in the
         * current font and subtracts it from the desiredWidth and divides
         * this by stringLen-1. This gives us a per-glyph adjustment in
         * the spacing needed (either +ve or -ve) to make the string
         * print at the desiredWidth. The ashow procedure call takes this
         * per-glyph adjustment as an argument. This is necessary for WYSIWYG
         */
        mPSStream.println("/"+DrawStringName +" {");
        mPSStream.println("     moveto 1 index stringwidth pop NZ sub");
        mPSStream.println("     1 index length 1 sub NZ div 0");
        mPSStream.println("     3 2 roll ashow newpath} BD");
        mPSStream.println("/FL [");
        if (mFontProps == null){
            mPSStream.println(" /Helvetica ISOF");
            mPSStream.println(" /Helvetica-Bold ISOF");
            mPSStream.println(" /Helvetica-Oblique ISOF");
            mPSStream.println(" /Helvetica-BoldOblique ISOF");
            mPSStream.println(" /Times-Roman ISOF");
            mPSStream.println(" /Times-Bold ISOF");
            mPSStream.println(" /Times-Italic ISOF");
            mPSStream.println(" /Times-BoldItalic ISOF");
            mPSStream.println(" /Courier ISOF");
            mPSStream.println(" /Courier-Bold ISOF");
            mPSStream.println(" /Courier-Oblique ISOF");
            mPSStream.println(" /Courier-BoldOblique ISOF");
        } else {
            int cnt = Integer.parseInt(mFontProps.getProperty("font.num", "9"));
            for (int i = 0; i < cnt; i++){
                mPSStream.println("    /" + mFontProps.getProperty
                           ("font." + String.valueOf(i), "Courier ISOF"));
            }
        }
        mPSStream.println("] D");

        mPSStream.println("/"+SetFontName +" {");
        mPSStream.println("     FL exch get exch scalefont");
        mPSStream.println("     [1 0 0 -1 0 0] makefont setfont} BD");

        mPSStream.println("%%EndProlog");

        mPSStream.println("%%BeginSetup");
        if (epsPrinter == null) {
            // Set Page Size using first page's format.
            PageFormat pageFormat = getPageable().getPageFormat(0);
            double paperHeight = pageFormat.getPaper().getHeight();
            double paperWidth = pageFormat.getPaper().getWidth();

            /* PostScript printers can always generate uncollated copies.
             */
            mPSStream.print("<< /PageSize [" +
                                           paperWidth + " "+ paperHeight+"]");

            final PrintService pservice = getPrintService();
            Boolean isPS = (Boolean)java.security.AccessController.doPrivileged(
                new java.security.PrivilegedAction() {
                    public Object run() {
                       try {
                           Class psClass = Class.forName("sun.print.IPPPrintService");
                           if (psClass.isInstance(pservice)) {
                               Method isPSMethod = psClass.getMethod("isPostscript",
                                                                     (Class[])null);
                               return (Boolean)isPSMethod.invoke(pservice, (Object[])null);
                           }
                       } catch (Throwable t) {
                       }
                       return Boolean.TRUE;
                    }
                }
            );
            if (isPS) {
                mPSStream.print(" /DeferredMediaSelection true");
            }

            mPSStream.print(" /ImagingBBox null /ManualFeed false");
            mPSStream.print(isCollated() ? " /Collate true":"");
            mPSStream.print(" /NumCopies " +getCopiesInt());

            if (sidesAttr != Sides.ONE_SIDED) {
                if (sidesAttr == Sides.TWO_SIDED_LONG_EDGE) {
                    mPSStream.print(" /Duplex true ");
                } else if (sidesAttr == Sides.TWO_SIDED_SHORT_EDGE) {
                    mPSStream.print(" /Duplex true /Tumble true ");
                }
            }
            mPSStream.println(" >> setpagedevice ");
        }
        mPSStream.println("%%EndSetup");
    }

    // Inner class to run "privileged" to open the printer output stream.

    private class PrinterOpener implements java.security.PrivilegedAction {
        PrinterException pex;
        OutputStream result;

        public Object run() {
            try {

                    /* Write to a temporary file which will be spooled to
                     * the printer then deleted. In the case that the file
                     * is not removed for some reason, request that it is
                     * removed when the VM exits.
                     */
                    spoolFile = File.createTempFile("javaprint", ".ps", null);
                    spoolFile.deleteOnExit();

                result = new FileOutputStream(spoolFile);
                return result;
            } catch (IOException ex) {
                // If there is an IOError we subvert it to a PrinterException.
                pex = new PrinterIOException(ex);
            }
            return null;
        }
    }

    // Inner class to run "privileged" to invoke the system print command

    private class PrinterSpooler implements java.security.PrivilegedAction {
        PrinterException pex;

        public Object run() {
            try {
                /**
                 * Spool to the printer.
                 */
                if (spoolFile == null || !spoolFile.exists()) {
                   pex = new PrinterException("No spool file");
                   return null;
                }
                String fileName = spoolFile.getAbsolutePath();
                String execCmd[] = printExecCmd(mDestination, mOptions,
                               mNoJobSheet, getJobNameInt(),
                                                1, fileName);

                Process process = Runtime.getRuntime().exec(execCmd);
                process.waitFor();
                spoolFile.delete();

            } catch (IOException ex) {
                pex = new PrinterIOException(ex);
            } catch (InterruptedException ie) {
                pex = new PrinterException(ie.toString());
            }
            return null;
        }
    }


    /**
     * Invoked if the application cancelled the printjob.
     */
    protected void abortDoc() {
        if (mPSStream != null && mDestType != RasterPrinterJob.STREAM) {
            mPSStream.close();
        }
        java.security.AccessController.doPrivileged(
            new java.security.PrivilegedAction() {

            public Object run() {
               if (spoolFile != null && spoolFile.exists()) {
                   spoolFile.delete();
               }
               return null;
            }
        });
    }

    /**
     * Invoked by the RasterPrintJob super class
     * this method is called after that last page
     * has been imaged.
     */
    protected void endDoc() throws PrinterException {
        if (mPSStream != null) {
            mPSStream.println(EOF_COMMENT);
            mPSStream.flush();
            if (mDestType != RasterPrinterJob.STREAM) {
                mPSStream.close();
            }
        }
        if (mDestType == RasterPrinterJob.PRINTER) {
            if (getPrintService() != null) {
                mDestination = getPrintService().getName();
            }
            PrinterSpooler spooler = new PrinterSpooler();
            java.security.AccessController.doPrivileged(spooler);
            if (spooler.pex != null) {
                throw spooler.pex;
            }
        }
    }

    /**
     * The RasterPrintJob super class calls this method
     * at the start of each page.
     */
    protected void startPage(PageFormat pageFormat, Printable painter,
                             int index, boolean paperChanged)
        throws PrinterException
    {
        double paperHeight = pageFormat.getPaper().getHeight();
        double paperWidth = pageFormat.getPaper().getWidth();
        int pageNumber = index + 1;

        /* Place an initial gstate on to our gstate stack.
         * It will have the default PostScript gstate
         * attributes.
         */
        mGStateStack = new ArrayList();
        mGStateStack.add(new GState());

        mPSStream.println(PAGE_COMMENT + pageNumber + " " + pageNumber);

        /* Check current page's pageFormat against the previous pageFormat,
         */
        if (index > 0 && paperChanged) {

            mPSStream.print("<< /PageSize [" +
                            paperWidth + " " + paperHeight + "]");

            final PrintService pservice = getPrintService();
            Boolean isPS =
                (Boolean)java.security.AccessController.doPrivileged(

                new java.security.PrivilegedAction() {
                    public Object run() {
                        try {
                            Class psClass =
                                Class.forName("sun.print.IPPPrintService");
                            if (psClass.isInstance(pservice)) {
                                Method isPSMethod =
                                    psClass.getMethod("isPostscript",
                                                      (Class[])null);
                                return (Boolean)
                                    isPSMethod.invoke(pservice,
                                                      (Object[])null);
                            }
                        } catch (Throwable t) {
                        }
                        return Boolean.TRUE;
                    }
                    }
                );

            if (isPS) {
                mPSStream.print(" /DeferredMediaSelection true");
            }
            mPSStream.println(" >> setpagedevice");
        }
        mPSStream.println(PAGE_SAVE);
        mPSStream.println(paperHeight + COORD_PREP);
    }

    /**
     * The RastePrintJob super class calls this method
     * at the end of each page.
     */
    protected void endPage(PageFormat format, Printable painter,
                           int index)
        throws PrinterException
    {
        mPSStream.println(PAGE_RESTORE);
        mPSStream.println(SHOWPAGE);
    }

   /**
     * Convert the 24 bit BGR image buffer represented by
     * <code>image</code> to PostScript. The image is drawn at
     * <code>(destX, destY)</code> in device coordinates.
     * The image is scaled into a square of size
     * specified by <code>destWidth</code> and
     * <code>destHeight</code>. The portion of the
     * source image copied into that square is specified
     * by <code>srcX</code>, <code>srcY</code>,
     * <code>srcWidth</code>, and srcHeight.
     */
    protected void drawImageBGR(byte[] bgrData,
                                   float destX, float destY,
                                   float destWidth, float destHeight,
                                   float srcX, float srcY,
                                   float srcWidth, float srcHeight,
                                   int srcBitMapWidth, int srcBitMapHeight) {

        /* We draw images at device resolution so we probably need
         * to change the current PostScript transform.
         */
        setTransform(new AffineTransform());
        prepDrawing();

        int intSrcWidth = (int) srcWidth;
        int intSrcHeight = (int) srcHeight;

        mPSStream.println(IMAGE_SAVE);

        /* Create a PS string big enough to hold a row of pixels.
         */
        int psBytesPerRow = 3 * (int) intSrcWidth;
        while (psBytesPerRow > MAX_PSSTR) {
            psBytesPerRow /= 2;
        }

        mPSStream.println(psBytesPerRow + IMAGE_STR);

        /* Scale and translate the unit image.
         */
        mPSStream.println("[" + destWidth + " 0 "
                          + "0 " + destHeight
                          + " " + destX + " " + destY
                          +"]concat");

        /* Color Image invocation.
         */
        mPSStream.println(intSrcWidth + " " + intSrcHeight + " " + 8 + "["
                          + intSrcWidth + " 0 "
                          + "0 " + intSrcHeight
                          + " 0 " + 0 + "]"
                          + "/imageSrc load false 3 colorimage");

        /* Image data.
         */
        int index = 0;
        byte[] rgbData = new byte[intSrcWidth * 3];

        try {
            /* Skip the parts of the image that are not part
             * of the source rectangle.
             */
            index = (int) srcY * srcBitMapWidth;

            for(int i = 0; i < intSrcHeight; i++) {

                /* Skip the left part of the image that is not
                 * part of the source rectangle.
                 */
                index += (int) srcX;

                index = swapBGRtoRGB(bgrData, index, rgbData);
                byte[] encodedData = rlEncode(rgbData);
                byte[] asciiData = ascii85Encode(encodedData);
                mPSStream.write(asciiData);
                mPSStream.println("");
            }

            /*
             * If there is an IOError we subvert it to a PrinterException.
             * Fix: There has got to be a better way, maybe define
             * a PrinterIOException and then throw that?
             */
        } catch (IOException e) {
            //throw new PrinterException(e.toString());
        }

        mPSStream.println(IMAGE_RESTORE);
    }

    /**
     * Prints the contents of the array of ints, 'data'
     * to the current page. The band is placed at the
     * location (x, y) in device coordinates on the
     * page. The width and height of the band is
     * specified by the caller. Currently the data
     * is 24 bits per pixel in BGR format.
     */
    protected void printBand(byte[] bgrData, int x, int y,
                             int width, int height)
        throws PrinterException
    {

        mPSStream.println(IMAGE_SAVE);

        /* Create a PS string big enough to hold a row of pixels.
         */
        int psBytesPerRow = 3 * width;
        while (psBytesPerRow > MAX_PSSTR) {
            psBytesPerRow /= 2;
        }

        mPSStream.println(psBytesPerRow + IMAGE_STR);

        /* Scale and translate the unit image.
         */
        mPSStream.println("[" + width + " 0 "
                          + "0 " + height
                          + " " + x + " " + y
                          +"]concat");

        /* Color Image invocation.
         */
        mPSStream.println(width + " " + height + " " + 8 + "["
                          + width + " 0 "
                          + "0 " + -height
                          + " 0 " + height + "]"
                          + "/imageSrc load false 3 colorimage");

        /* Image data.
         */
        int index = 0;
        byte[] rgbData = new byte[width*3];

        try {
            for(int i = 0; i < height; i++) {
                index = swapBGRtoRGB(bgrData, index, rgbData);
                byte[] encodedData = rlEncode(rgbData);
                byte[] asciiData = ascii85Encode(encodedData);
                mPSStream.write(asciiData);
                mPSStream.println("");
            }

        } catch (IOException e) {
            throw new PrinterIOException(e);
        }

        mPSStream.println(IMAGE_RESTORE);
    }

    /**
     * Examine the metrics captured by the
     * <code>PeekGraphics</code> instance and
     * if capable of directly converting this
     * print job to the printer's control language
     * or the native OS's graphics primitives, then
     * return a <code>PSPathGraphics</code> to perform
     * that conversion. If there is not an object
     * capable of the conversion then return
     * <code>null</code>. Returning <code>null</code>
     * causes the print job to be rasterized.
     */

    protected Graphics2D createPathGraphics(PeekGraphics peekGraphics,
                                            PrinterJob printerJob,
                                            Printable painter,
                                            PageFormat pageFormat,
                                            int pageIndex) {

        PSPathGraphics pathGraphics;
        PeekMetrics metrics = peekGraphics.getMetrics();

        /* If the application has drawn anything that
         * out PathGraphics class can not handle then
         * return a null PathGraphics.
         */
        if (forcePDL == false && (forceRaster == true
                        || metrics.hasNonSolidColors()
                        || metrics.hasCompositing())) {

            pathGraphics = null;
        } else {

            BufferedImage bufferedImage = new BufferedImage(8, 8,
                                            BufferedImage.TYPE_INT_RGB);
            Graphics2D bufferedGraphics = bufferedImage.createGraphics();
            boolean canRedraw = peekGraphics.getAWTDrawingOnly() == false;

            pathGraphics =  new PSPathGraphics(bufferedGraphics, printerJob,
                                               painter, pageFormat, pageIndex,
                                               canRedraw);
        }

        return pathGraphics;
    }

    /**
     * Intersect the gstate's current path with the
     * current clip and make the result the new clip.
     */
    protected void selectClipPath() {

        mPSStream.println(mClipOpStr);
    }

    protected void setClip(Shape clip) {

        mLastClip = clip;
    }

    protected void setTransform(AffineTransform transform) {
        mLastTransform = transform;
    }

    /**
     * Set the current PostScript font.
     * Taken from outFont in PSPrintStream.
     */
     protected boolean setFont(Font font) {
        mLastFont = font;
        return true;
    }

    /**
     * Given an array of CharsetStrings that make up a run
     * of text, this routine converts each CharsetString to
     * an index into our PostScript font list. If one or more
     * CharsetStrings can not be represented by a PostScript
     * font, then this routine will return a null array.
     */
     private int[] getPSFontIndexArray(Font font, CharsetString[] charSet) {
        int[] psFont = null;

        if (mFontProps != null) {
            psFont = new int[charSet.length];
        }

        for (int i = 0; i < charSet.length && psFont != null; i++){

            /* Get the encoding of the run of text.
             */
            CharsetString cs = charSet[i];

            CharsetEncoder fontCS = cs.fontDescriptor.encoder;
            String charsetName = cs.fontDescriptor.getFontCharsetName();
            /*
             * sun.awt.Symbol perhaps should return "symbol" for encoding.
             * Similarly X11Dingbats should return "dingbats"
             * Forced to check for win32 & x/unix names for these converters.
             */

            if ("Symbol".equals(charsetName)) {
                charsetName = "symbol";
            } else if ("WingDings".equals(charsetName) ||
                       "X11Dingbats".equals(charsetName)) {
                charsetName = "dingbats";
            } else {
                charsetName = makeCharsetName(charsetName, cs.charsetChars);
            }

            int styleMask = font.getStyle() |
                sun.font.FontManager.getFont2D(font).getStyle();

            String style = FontConfiguration.getStyleString(styleMask);

            /* First we map the font name through the properties file.
             * This mapping provides alias names for fonts, for example,
             * "timesroman" is mapped to "serif".
             */
            String fontName = font.getFamily().toLowerCase(Locale.ENGLISH);
            fontName = fontName.replace(' ', '_');
            String name = mFontProps.getProperty(fontName, "");

            /* Now map the alias name, character set name, and style
             * to a PostScript name.
             */
            String psName =
                mFontProps.getProperty(name + "." + charsetName + "." + style,
                                      null);

            if (psName != null) {

                /* Get the PostScript font index for the PostScript font.
                 */
                try {
                    psFont[i] =
                        Integer.parseInt(mFontProps.getProperty(psName));

                /* If there is no PostScript font for this font name,
                 * then we want to termintate the loop and the method
                 * indicating our failure. Setting the array to null
                 * is used to indicate these failures.
                 */
                } catch(NumberFormatException e){
                    psFont = null;
                }

            /* There was no PostScript name for the font, character set,
             * and style so give up.
             */
            } else {
                psFont = null;
            }
        }

         return psFont;
     }


    private static String escapeParens(String str) {
        if (str.indexOf('(') == -1 && str.indexOf(')') == -1 ) {
            return str;
        } else {
            int count = 0;
            int pos = 0;
            while ((pos = str.indexOf('(', pos)) != -1) {
                count++;
                pos++;
            }
            pos = 0;
            while ((pos = str.indexOf(')', pos)) != -1) {
                count++;
                pos++;
            }
            char []inArr = str.toCharArray();
            char []outArr = new char[inArr.length+count];
            pos = 0;
            for (int i=0;i<inArr.length;i++) {
                if (inArr[i] == '(' || inArr[i] == ')') {
                    outArr[pos++] = '\\';
                }
                outArr[pos++] = inArr[i];
            }
            return new String(outArr);

        }
    }

    /* return of 0 means unsupported. Other return indicates the number
     * of distinct PS fonts needed to draw this text. This saves us
     * doing this processing one extra time.
     */
    protected int platformFontCount(Font font, String str) {
        if (mFontProps == null) {
            return 0;
        }
        CharsetString[] acs =
            ((PlatformFont)(font.getPeer())).makeMultiCharsetString(str,false);
        if (acs == null) {
            /* AWT can't convert all chars so use 2D path */
            return 0;
        }
        int[] psFonts = getPSFontIndexArray(font, acs);
        return (psFonts == null) ? 0 : psFonts.length;
    }

     protected boolean textOut(Graphics g, String str, float x, float y,
                               Font mLastFont, FontRenderContext frc,
                               float width) {
        boolean didText = true;

        if (mFontProps == null) {
            return false;
        } else {
            prepDrawing();

            /* On-screen drawString renders most control chars as the missing
             * glyph and have the non-zero advance of that glyph.
             * Exceptions are \t, \n and \r which are considered zero-width.
             * Postscript handles control chars mostly as a missing glyph.
             * But we use 'ashow' specifying a width for the string which
             * assumes zero-width for those three exceptions, and Postscript
             * tries to squeeze the extra char in, with the result that the
             * glyphs look compressed or even overlap.
             * So exclude those control chars from the string sent to PS.
             */
            str = removeControlChars(str);
            if (str.length() == 0) {
                return true;
            }
            CharsetString[] acs =
                ((PlatformFont)
                 (mLastFont.getPeer())).makeMultiCharsetString(str, false);
            if (acs == null) {
                /* AWT can't convert all chars so use 2D path */
                return false;
            }
            /* Get an array of indices into our PostScript name
             * table. If all of the runs can not be converted
             * to PostScript fonts then null is returned and
             * we'll want to fall back to printing the text
             * as shapes.
             */
            int[] psFonts = getPSFontIndexArray(mLastFont, acs);
            if (psFonts != null) {

                for (int i = 0; i < acs.length; i++){
                    CharsetString cs = acs[i];
                    CharsetEncoder fontCS = cs.fontDescriptor.encoder;

                    StringBuffer nativeStr = new StringBuffer();
                    byte[] strSeg = new byte[cs.length * 2];
                    int len = 0;
                    try {
                        ByteBuffer bb = ByteBuffer.wrap(strSeg);
                        fontCS.encode(CharBuffer.wrap(cs.charsetChars,
                                                      cs.offset,
                                                      cs.length),
                                      bb, true);
                        bb.flip();
                        len = bb.limit();
                    } catch(IllegalStateException xx){
                        continue;
                    } catch(CoderMalfunctionError xx){
                        continue;
                    }
                    /* The width to fit to may either be specified,
                     * or calculated. Specifying by the caller is only
                     * valid if the text does not need to be decomposed
                     * into multiple calls.
                     */
                    float desiredWidth;
                    if (acs.length == 1 && width != 0f) {
                        desiredWidth = width;
                    } else {
                        Rectangle2D r2d =
                            mLastFont.getStringBounds(cs.charsetChars,
                                                      cs.offset,
                                                      cs.offset+cs.length,
                                                      frc);
                        desiredWidth = (float)r2d.getWidth();
                    }
                    /* unprintable chars had width of 0, causing a PS error
                     */
                    if (desiredWidth == 0) {
                        return didText;
                    }
                    nativeStr.append('<');
                    for (int j = 0; j < len; j++){
                        byte b = strSeg[j];
                        // to avoid encoding conversion with println()
                        String hexS = Integer.toHexString(b);
                        int length = hexS.length();
                        if (length > 2) {
                            hexS = hexS.substring(length - 2, length);
                        } else if (length == 1) {
                            hexS = "0" + hexS;
                        } else if (length == 0) {
                            hexS = "00";
                        }
                        nativeStr.append(hexS);
                    }
                    nativeStr.append('>');
                    /* This comment costs too much in output file size */
//                  mPSStream.println("% Font[" + mLastFont.getName() + ", " +
//                             FontConfiguration.getStyleString(mLastFont.getStyle()) + ", "
//                             + mLastFont.getSize2D() + "]");
                    getGState().emitPSFont(psFonts[i], mLastFont.getSize2D());

                    // out String
                    mPSStream.println(nativeStr.toString() + " " +
                                      desiredWidth + " " + x + " " + y + " " +
                                      DrawStringName);
                    x += desiredWidth;
                }
            } else {
                didText = false;
            }
        }

        return didText;
     }
    /**
     * Set the current path rule to be either
     * <code>FILL_EVEN_ODD</code> (using the
     * even-odd file rule) or <code>FILL_WINDING</code>
     * (using the non-zero winding rule.)
     */
    protected void setFillMode(int fillRule) {

        switch (fillRule) {

         case FILL_EVEN_ODD:
            mFillOpStr = EVEN_ODD_FILL_STR;
            mClipOpStr = EVEN_ODD_CLIP_STR;
            break;

         case FILL_WINDING:
             mFillOpStr = WINDING_FILL_STR;
             mClipOpStr = WINDING_CLIP_STR;
             break;

         default:
             throw new IllegalArgumentException();
        }

    }

    /**
     * Set the printer's current color to be that
     * defined by <code>color</code>
     */
    protected void setColor(Color color) {
        mLastColor = color;
    }

    /**
     * Fill the current path using the current fill mode
     * and color.
     */
    protected void fillPath() {

        mPSStream.println(mFillOpStr);
    }

    /**
     * Called to mark the start of a new path.
     */
    protected void beginPath() {

        prepDrawing();
        mPSStream.println(NEWPATH_STR);

        mPenX = 0;
        mPenY = 0;
    }

    /**
     * Close the current subpath by appending a straight
     * line from the current point to the subpath's
     * starting point.
     */
    protected void closeSubpath() {

        mPSStream.println(CLOSEPATH_STR);

        mPenX = mStartPathX;
        mPenY = mStartPathY;
    }


    /**
     * Generate PostScript to move the current pen
     * position to <code>(x, y)</code>.
     */
    protected void moveTo(float x, float y) {

        mPSStream.println(trunc(x) + " " + trunc(y) + MOVETO_STR);

        /* moveto marks the start of a new subpath
         * and we need to remember that starting
         * position so that we know where the
         * pen returns to with a close path.
         */
        mStartPathX = x;
        mStartPathY = y;

        mPenX = x;
        mPenY = y;
    }
    /**
     * Generate PostScript to draw a line from the
     * current pen position to <code>(x, y)</code>.
     */
    protected void lineTo(float x, float y) {

        mPSStream.println(trunc(x) + " " + trunc(y) + LINETO_STR);

        mPenX = x;
        mPenY = y;
    }

    /**
     * Add to the current path a bezier curve formed
     * by the current pen position and the method parameters
     * which are two control points and an ending
     * point.
     */
    protected void bezierTo(float control1x, float control1y,
                                float control2x, float control2y,
                                float endX, float endY) {

//      mPSStream.println(control1x + " " + control1y
//                        + " " + control2x + " " + control2y
//                        + " " + endX + " " + endY
//                        + CURVETO_STR);
        mPSStream.println(trunc(control1x) + " " + trunc(control1y)
                          + " " + trunc(control2x) + " " + trunc(control2y)
                          + " " + trunc(endX) + " " + trunc(endY)
                          + CURVETO_STR);


        mPenX = endX;
        mPenY = endY;
    }

    String trunc(float f) {
        float af = Math.abs(f);
        if (af >= 1f && af <=1000f) {
            f = Math.round(f*1000)/1000f;
        }
        return Float.toString(f);
    }

    /**
     * Return the x coordinate of the pen in the
     * current path.
     */
    protected float getPenX() {

        return mPenX;
    }
    /**
     * Return the y coordinate of the pen in the
     * current path.
     */
    protected float getPenY() {

        return mPenY;
    }

    /**
     * Return the x resolution of the coordinates
     * to be rendered.
     */
    protected double getXRes() {
        return PS_XRES;
    }
    /**
     * Return the y resolution of the coordinates
     * to be rendered.
     */
    protected double getYRes() {
        return PS_YRES;
    }

    /**
     * For PostScript the origin is in the upper-left of the
     * paper not at the imageable area corner.
     */
    protected double getPhysicalPrintableX(Paper p) {
        return 0;

    }

    /**
     * For PostScript the origin is in the upper-left of the
     * paper not at the imageable area corner.
     */
    protected double getPhysicalPrintableY(Paper p) {
        return 0;
    }

    protected double getPhysicalPrintableWidth(Paper p) {
        return p.getImageableWidth();
    }

    protected double getPhysicalPrintableHeight(Paper p) {
        return p.getImageableHeight();
    }

    protected double getPhysicalPageWidth(Paper p) {
        return p.getWidth();
    }

    protected double getPhysicalPageHeight(Paper p) {
        return p.getHeight();
    }

   /**
     * Returns how many times each page in the book
     * should be consecutively printed by PrintJob.
     * If the printer makes copies itself then this
     * method should return 1.
     */
    protected int getNoncollatedCopies() {
        return 1;
    }

    protected int getCollatedCopies() {
        return 1;
    }

    private String[] printExecCmd(String printer, String options,
                                  boolean noJobSheet,
                                  String banner, int copies, String spoolFile) {
        int PRINTER = 0x1;
        int OPTIONS = 0x2;
        int BANNER  = 0x4;
        int COPIES  = 0x8;
        int NOSHEET = 0x10;
        int pFlags = 0;
        String execCmd[];
        int ncomps = 2; // minimum number of print args
        int n = 0;

        if (printer != null && !printer.equals("") && !printer.equals("lp")) {
            pFlags |= PRINTER;
            ncomps+=1;
        }
        if (options != null && !options.equals("")) {
            pFlags |= OPTIONS;
            ncomps+=1;
        }
        if (banner != null && !banner.equals("")) {
            pFlags |= BANNER;
            ncomps+=1;
        }
        if (copies > 1) {
            pFlags |= COPIES;
            ncomps+=1;
        }
        if (noJobSheet) {
            pFlags |= NOSHEET;
            ncomps+=1;
        }
       if (System.getProperty("os.name").equals("Linux")) {
            execCmd = new String[ncomps];
            execCmd[n++] = "/usr/bin/lpr";
            if ((pFlags & PRINTER) != 0) {
                execCmd[n++] = new String("-P" + printer);
            }
            if ((pFlags & BANNER) != 0) {
                execCmd[n++] = new String("-J"  + banner);
            }
            if ((pFlags & COPIES) != 0) {
                execCmd[n++] = new String("-#" + new Integer(copies).toString());
            }
            if ((pFlags & NOSHEET) != 0) {
                execCmd[n++] = new String("-h");
            }
            if ((pFlags & OPTIONS) != 0) {
                execCmd[n++] = new String(options);
            }
        } else {
            ncomps+=1; //add 1 arg for lp
            execCmd = new String[ncomps];
            execCmd[n++] = "/usr/bin/lp";
            execCmd[n++] = "-c";           // make a copy of the spool file
            if ((pFlags & PRINTER) != 0) {
                execCmd[n++] = new String("-d" + printer);
            }
            if ((pFlags & BANNER) != 0) {
                execCmd[n++] = new String("-t"  + banner);
            }
            if ((pFlags & COPIES) != 0) {
                execCmd[n++] = new String("-n" + new Integer(copies).toString());
            }
            if ((pFlags & NOSHEET) != 0) {
                execCmd[n++] = new String("-o nobanner");
            }
            if ((pFlags & OPTIONS) != 0) {
                execCmd[n++] = new String("-o" + options);
            }
        }
        execCmd[n++] = spoolFile;
        return execCmd;
    }

    private static int swapBGRtoRGB(byte[] image, int index, byte[] dest) {
        int destIndex = 0;
        while(index < image.length-2 && destIndex < dest.length-2) {
            dest[destIndex++] = image[index+2];
            dest[destIndex++] = image[index+1];
            dest[destIndex++] = image[index+0];
            index+=3;
        }
        return index;
    }

    /*
     * Currently CharToByteConverter.getCharacterEncoding() return values are
     * not fixed yet. These are used as the part of the key of
     * psfont.propeties. When those name are fixed this routine can
     * be erased.
     */
    private String makeCharsetName(String name, char[] chs) {
        if (name.equals("Cp1252") || name.equals("ISO8859_1")) {
            return "latin1";
        } else if (name.equals("UTF8")) {
            // same as latin 1 if all chars < 256
            for (int i=0; i < chs.length; i++) {
                if (chs[i] > 255) {
                    return name.toLowerCase();
                }
            }
            return "latin1";
        } else if (name.startsWith("ISO8859")) {
            // same as latin 1 if all chars < 128
            for (int i=0; i < chs.length; i++) {
                if (chs[i] > 127) {
                    return name.toLowerCase();
                }
            }
            return "latin1";
        } else {
            return name.toLowerCase();
        }
    }

    private void prepDrawing() {

        /* Pop gstates until we can set the needed clip
         * and transform or until we are at the outer most
         * gstate.
         */
        while (isOuterGState() == false
               && (getGState().canSetClip(mLastClip) == false
                   || getGState().mTransform.equals(mLastTransform) == false)) {


            grestore();
        }

        /* Set the color. This can push the color to the
         * outer most gsave which is often a good thing.
         */
        getGState().emitPSColor(mLastColor);

        /* We do not want to change the outermost
         * transform or clip so if we are at the
         * outer clip the generate a gsave.
         */
        if (isOuterGState()) {
            gsave();
            getGState().emitTransform(mLastTransform);
            getGState().emitPSClip(mLastClip);
        }

        /* Set the font if we have been asked to. It is
         * important that the font is set after the
         * transform in order to get the font size
         * correct.
         */
//      if (g != null) {
//          getGState().emitPSFont(g, mLastFont);
//      }

    }

    /**
     * Return the GState that is currently on top
     * of the GState stack. There should always be
     * a GState on top of the stack. If there isn't
     * then this method will throw an IndexOutOfBounds
     * exception.
     */
    private GState getGState() {
        int count = mGStateStack.size();
        return (GState) mGStateStack.get(count - 1);
    }

    /**
     * Emit a PostScript gsave command and add a
     * new GState on to our stack which represents
     * the printer's gstate stack.
     */
    private void gsave() {
        GState oldGState = getGState();
        mGStateStack.add(new GState(oldGState));
        mPSStream.println(GSAVE_STR);
    }

    /**
     * Emit a PostScript grestore command and remove
     * a GState from our stack which represents the
     * printer's gstate stack.
     */
    private void grestore() {
        int count = mGStateStack.size();
        mGStateStack.remove(count - 1);
        mPSStream.println(GRESTORE_STR);
    }

    /**
     * Return true if the current GState is the
     * outermost GState and therefore should not
     * be restored.
     */
    private boolean isOuterGState() {
        return mGStateStack.size() == 1;
    }

    /**
     * A stack of GStates is maintained to model the printer's
     * gstate stack. Each GState holds information about
     * the current graphics attributes.
     */
    private class GState{
        Color mColor;
        Shape mClip;
        Font mFont;
        AffineTransform mTransform;

        GState() {
            mColor = Color.black;
            mClip = null;
            mFont = null;
            mTransform = new AffineTransform();
        }

        GState(GState copyGState) {
            mColor = copyGState.mColor;
            mClip = copyGState.mClip;
            mFont = copyGState.mFont;
            mTransform = copyGState.mTransform;
        }

        boolean canSetClip(Shape clip) {

            return mClip == null || mClip.equals(clip);
        }


        void emitPSClip(Shape clip) {
            if (clip != null
                && (mClip == null || mClip.equals(clip) == false)) {
                String saveFillOp = mFillOpStr;
                String saveClipOp = mClipOpStr;
                convertToPSPath(clip.getPathIterator(new AffineTransform()));
                selectClipPath();
                mClip = clip;
                /* The clip is a shape and has reset the winding rule state */
                mClipOpStr = saveFillOp;
                mFillOpStr = saveFillOp;
            }
        }

        void emitTransform(AffineTransform transform) {

            if (transform != null && transform.equals(mTransform) == false) {
                double[] matrix = new double[6];
                transform.getMatrix(matrix);
                mPSStream.println("[" + (float)matrix[0]
                                  + " " + (float)matrix[1]
                                  + " " + (float)matrix[2]
                                  + " " + (float)matrix[3]
                                  + " " + (float)matrix[4]
                                  + " " + (float)matrix[5]
                                  + "] concat");

                mTransform = transform;
            }
        }

        void emitPSColor(Color color) {
            if (color != null && color.equals(mColor) == false) {
                float[] rgb = color.getRGBColorComponents(null);

                /* If the color is a gray value then use
                 * setgray.
                 */
                if (rgb[0] == rgb[1] && rgb[1] == rgb[2]) {
                    mPSStream.println(rgb[0] + SETGRAY_STR);

                /* It's not gray so use setrgbcolor.
                 */
                } else {
                    mPSStream.println(rgb[0] + " "
                                      + rgb[1] + " "
                                      + rgb[2] + " "
                                      + SETRGBCOLOR_STR);
                }

                mColor = color;

            }
        }

        void emitPSFont(int psFontIndex, float fontSize) {
            mPSStream.println(fontSize + " " +
                              psFontIndex + " " + SetFontName);
        }
    }

       /**
        * Given a Java2D <code>PathIterator</code> instance,
        * this method translates that into a PostScript path..
        */
        void convertToPSPath(PathIterator pathIter) {

            float[] segment = new float[6];
            int segmentType;

            /* Map the PathIterator's fill rule into the PostScript
             * fill rule.
             */
            int fillRule;
            if (pathIter.getWindingRule() == PathIterator.WIND_EVEN_ODD) {
                fillRule = FILL_EVEN_ODD;
            } else {
                fillRule = FILL_WINDING;
            }

            beginPath();

            setFillMode(fillRule);

            while (pathIter.isDone() == false) {
                segmentType = pathIter.currentSegment(segment);

                switch (segmentType) {
                 case PathIterator.SEG_MOVETO:
                    moveTo(segment[0], segment[1]);
                    break;

                 case PathIterator.SEG_LINETO:
                    lineTo(segment[0], segment[1]);
                    break;

                /* Convert the quad path to a bezier.
                 */
                 case PathIterator.SEG_QUADTO:
                    float lastX = getPenX();
                    float lastY = getPenY();
                    float c1x = lastX + (segment[0] - lastX) * 2 / 3;
                    float c1y = lastY + (segment[1] - lastY) * 2 / 3;
                    float c2x = segment[2] - (segment[2] - segment[0]) * 2/ 3;
                    float c2y = segment[3] - (segment[3] - segment[1]) * 2/ 3;
                    bezierTo(c1x, c1y,
                             c2x, c2y,
                             segment[2], segment[3]);
                    break;

                 case PathIterator.SEG_CUBICTO:
                    bezierTo(segment[0], segment[1],
                             segment[2], segment[3],
                             segment[4], segment[5]);
                    break;

                 case PathIterator.SEG_CLOSE:
                    closeSubpath();
                    break;
                }


                pathIter.next();
            }
        }

    /*
     * Fill the path defined by <code>pathIter</code>
     * with the specified color.
     * The path is provided in current user space.
     */
    protected void deviceFill(PathIterator pathIter, Color color,
                              AffineTransform tx, Shape clip) {

        setTransform(tx);
        setClip(clip);
        setColor(color);
        convertToPSPath(pathIter);
        /* Specify the path to fill as the clip, this ensures that only
         * pixels which are inside the path will be filled, which is
         * what the Java 2D APIs specify
         */
        mPSStream.println(GSAVE_STR);
        selectClipPath();
        fillPath();
        mPSStream.println(GRESTORE_STR + " " + NEWPATH_STR);
    }

    /*
     * Run length encode byte array in a form suitable for decoding
     * by the PS Level 2 filter RunLengthDecode.
     * Array data to encode is inArr. Encoded data is written to outArr
     * outArr must be long enough to hold the encoded data but this
     * can't be known ahead of time.
     * A safe assumption is to use double the length of the input array.
     * This is then copied into a new array of the correct length which
     * is returned.
     * Algorithm:
     * Encoding is a lead byte followed by data bytes.
     * Lead byte of 0->127 indicates leadByte + 1 distinct bytes follow
     * Lead byte of 129->255 indicates 257 - leadByte is the number of times
     * the following byte is repeated in the source.
     * 128 is a special lead byte indicating end of data (EOD) and is
     * written as the final byte of the returned encoded data.
     */
     private byte[] rlEncode(byte[] inArr) {

         int inIndex = 0;
         int outIndex = 0;
         int startIndex = 0;
         int runLen = 0;
         byte[] outArr = new byte[(inArr.length * 2) +2];
         while (inIndex < inArr.length) {
             if (runLen == 0) {
                 startIndex = inIndex++;
                 runLen=1;
             }

             while (runLen < 128 && inIndex < inArr.length &&
                    inArr[inIndex] == inArr[startIndex]) {
                 runLen++; // count run of same value
                 inIndex++;
             }

             if (runLen > 1) {
                 outArr[outIndex++] = (byte)(257 - runLen);
                 outArr[outIndex++] = inArr[startIndex];
                 runLen = 0;
                 continue; // back to top of while loop.
             }

             // if reach here have a run of different values, or at the end.
             while (runLen < 128 && inIndex < inArr.length &&
                    inArr[inIndex] != inArr[inIndex-1]) {
                 runLen++; // count run of different values
                 inIndex++;
             }
             outArr[outIndex++] = (byte)(runLen - 1);
             for (int i = startIndex; i < startIndex+runLen; i++) {
                 outArr[outIndex++] = inArr[i];
             }
             runLen = 0;
         }
         outArr[outIndex++] = (byte)128;
         byte[] encodedData = new byte[outIndex];
         System.arraycopy(outArr, 0, encodedData, 0, outIndex);

         return encodedData;
     }

    /* written acc. to Adobe Spec. "Filtered Files: ASCIIEncode Filter",
     * "PS Language Reference Manual, 2nd edition: Section 3.13"
     */
    private byte[] ascii85Encode(byte[] inArr) {
        byte[]  outArr = new byte[((inArr.length+4) * 5 / 4) + 2];
        long p1 = 85;
        long p2 = p1*p1;
        long p3 = p1*p2;
        long p4 = p1*p3;
        byte pling = '!';

        int i = 0;
        int olen = 0;
        long val, rem;

        while (i+3 < inArr.length) {
            val = ((long)((inArr[i++]&0xff))<<24) +
                  ((long)((inArr[i++]&0xff))<<16) +
                  ((long)((inArr[i++]&0xff))<< 8) +
                  ((long)(inArr[i++]&0xff));
            if (val == 0) {
                outArr[olen++] = 'z';
            } else {
                rem = val;
                outArr[olen++] = (byte)(rem / p4 + pling); rem = rem % p4;
                outArr[olen++] = (byte)(rem / p3 + pling); rem = rem % p3;
                outArr[olen++] = (byte)(rem / p2 + pling); rem = rem % p2;
                outArr[olen++] = (byte)(rem / p1 + pling); rem = rem % p1;
                outArr[olen++] = (byte)(rem + pling);
            }
        }
        // input not a multiple of 4 bytes, write partial output.
        if (i < inArr.length) {
            int n = inArr.length - i; // n bytes remain to be written

            val = 0;
            while (i < inArr.length) {
                val = (val << 8) + (inArr[i++]&0xff);
            }

            int append = 4 - n;
            while (append-- > 0) {
                val = val << 8;
            }
            byte []c = new byte[5];
            rem = val;
            c[0] = (byte)(rem / p4 + pling); rem = rem % p4;
            c[1] = (byte)(rem / p3 + pling); rem = rem % p3;
            c[2] = (byte)(rem / p2 + pling); rem = rem % p2;
            c[3] = (byte)(rem / p1 + pling); rem = rem % p1;
            c[4] = (byte)(rem + pling);

            for (int b = 0; b < n+1 ; b++) {
                outArr[olen++] = c[b];
            }
        }

        // write EOD marker.
        outArr[olen++]='~'; outArr[olen++]='>';

        /* The original intention was to insert a newline after every 78 bytes.
         * This was mainly intended for legibility but I decided against this
         * partially because of the (small) amount of extra space, and
         * partially because for line breaks either would have to hardwire
         * ascii 10 (newline) or calculate space in bytes to allocate for
         * the platform's newline byte sequence. Also need to be careful
         * about where its inserted:
         * Ascii 85 decoder ignores white space except for one special case:
         * you must ensure you do not split the EOD marker across lines.
         */
        byte[] retArr = new byte[olen];
        System.arraycopy(outArr, 0, retArr, 0, olen);
        return retArr;

    }

    /**
     * PluginPrinter generates EPSF wrapped with a header and trailer
     * comment. This conforms to the new requirements of Mozilla 1.7
     * and FireFox 1.5 and later. Earlier versions of these browsers
     * did not support plugin printing in the general sense (not just Java).
     * A notable limitation of these browsers is that they handle plugins
     * which would span page boundaries by scaling plugin content to fit on a
     * single page. This means white space is left at the bottom of the
     * previous page and its impossible to print these cases as they appear on
     * the web page. This is contrast to how the same browsers behave on
     * Windows where it renders as on-screen.
     * Cases where the content fits on a single page do work fine, and they
     * are the majority of cases.
     * The scaling that the browser specifies to make the plugin content fit
     * when it is larger than a single page can hold is non-uniform. It
     * scales the axis in which the content is too large just enough to
     * ensure it fits. For content which is extremely long this could lead
     * to noticeable distortion. However that is probably rare enough that
     * its not worth compensating for that here, but we can revisit that if
     * needed, and compensate by making the scale for the other axis the
     * same.
     */
    public static class PluginPrinter implements Printable {

        private EPSPrinter epsPrinter;
        private Component applet;
        private PrintStream stream;
        private String epsTitle;
        private int bx, by, bw, bh;
        private int width, height;

        /**
         * This is called from the Java Plug-in to print an Applet's
         * contents as EPS to a postscript stream provided by the browser.
         * @param applet the applet component to print.
         * @param stream the print stream provided by the plug-in
         * @param x the x location of the applet panel in the browser window
         * @param y the y location of the applet panel in the browser window
         * @param w the width of the applet panel in the browser window
         * @param h the width of the applet panel in the browser window
         */
        public PluginPrinter(Component applet,
                             PrintStream stream,
                             int x, int y, int w, int h) {

            this.applet = applet;
            this.epsTitle = "Java Plugin Applet";
            this.stream = stream;
            bx = x;
            by = y;
            bw = w;
            bh = h;
            width = applet.size().width;
            height = applet.size().height;
            epsPrinter = new EPSPrinter(this, epsTitle, stream,
                                        0, 0, width, height);
        }

        public void printPluginPSHeader() {
            stream.println("%%BeginDocument: JavaPluginApplet");
        }

        public void printPluginApplet() {
            try {
                epsPrinter.print();
            } catch (PrinterException e) {
            }
        }

        public void printPluginPSTrailer() {
            stream.println("%%EndDocument: JavaPluginApplet");
            stream.flush();
        }

        public void printAll() {
            printPluginPSHeader();
            printPluginApplet();
            printPluginPSTrailer();
        }

        public int print(Graphics g, PageFormat pf, int pgIndex) {
            if (pgIndex > 0) {
                return Printable.NO_SUCH_PAGE;
            } else {
                // "aware" client code can detect that its been passed a
                // PrinterGraphics and could theoretically print
                // differently. I think this is more likely useful than
                // a problem.
                applet.printAll(g);
                return Printable.PAGE_EXISTS;
            }
        }

    }

    /*
     * This class can take an application-client supplied printable object
     * and send the result to a stream.
     * The application does not need to send any postscript to this stream
     * unless it needs to specify a translation etc.
     * It assumes that its importing application obeys all the conventions
     * for importation of EPS. See Appendix H - Encapsulated Postscript File
     * Format - of the Adobe Postscript Language Reference Manual, 2nd edition.
     * This class could be used as the basis for exposing the ability to
     * generate EPSF from 2D graphics as a StreamPrintService.
     * In that case a MediaPrintableArea attribute could be used to
     * communicate the bounding box.
     */
    public static class EPSPrinter implements Pageable {

        private PageFormat pf;
        private PSPrinterJob job;
        private int llx, lly, urx, ury;
        private Printable printable;
        private PrintStream stream;
        private String epsTitle;

        public EPSPrinter(Printable printable, String title,
                          PrintStream stream,
                          int x, int y, int wid, int hgt) {

            this.printable = printable;
            this.epsTitle = title;
            this.stream = stream;
            llx = x;
            lly = y;
            urx = llx+wid;
            ury = lly+hgt;
            // construct a PageFormat with zero margins representing the
            // exact bounds of the applet. ie construct a theoretical
            // paper which happens to exactly match applet panel size.
            Paper p = new Paper();
            p.setSize((double)wid, (double)hgt);
            p.setImageableArea(0.0,0.0, (double)wid, (double)hgt);
            pf = new PageFormat();
            pf.setPaper(p);
        }

        public void print() throws PrinterException {
            stream.println("%!PS-Adobe-3.0 EPSF-3.0");
            stream.println("%%BoundingBox: " +
                           llx + " " + lly + " " + urx + " " + ury);
            stream.println("%%Title: " + epsTitle);
            stream.println("%%Creator: Java Printing");
            stream.println("%%CreationDate: " + new java.util.Date());
            stream.println("%%EndComments");
            stream.println("/pluginSave save def");
            stream.println("mark"); // for restoring stack state on return

            job = new PSPrinterJob();
            job.epsPrinter = this; // modifies the behaviour of PSPrinterJob
            job.mPSStream = stream;
            job.mDestType = RasterPrinterJob.STREAM; // prevents closure

            job.startDoc();
            try {
                job.printPage(this, 0);
            } catch (Throwable t) {
                if (t instanceof PrinterException) {
                    throw (PrinterException)t;
                } else {
                    throw new PrinterException(t.toString());
                }
            } finally {
                stream.println("cleartomark"); // restore stack state
                stream.println("pluginSave restore");
                job.endDoc();
            }
            stream.flush();
        }

        public int getNumberOfPages() {
            return 1;
        }

        public PageFormat getPageFormat(int pgIndex) {
            if (pgIndex > 0) {
                throw new IndexOutOfBoundsException("pgIndex");
            } else {
                return pf;
            }
        }

        public Printable getPrintable(int pgIndex) {
            if (pgIndex > 0) {
                throw new IndexOutOfBoundsException("pgIndex");
            } else {
            return printable;
            }
        }

    }
}
