/*
 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.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.PrintServiceAttributeSet;
import javax.print.attribute.standard.PrinterName;
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.BufferedReader;
import java.io.CharConversionException;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;

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 sun.font.FontManagerFactory;
import sun.font.FontUtilities;

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

//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;

   private static boolean isMac;

    /* 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();
                String osName = System.getProperty("os.name");
                isMac = osName.startsWith("Mac");
                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();
                   if (isMac) {
                        PrintServiceAttributeSet psaSet = pServ.getAttributes() ;
                        if (psaSet != null) {
                            mDestination = psaSet.get(PrinterName.class).toString();
                        }
                    }
                }
            }
        }

        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 = Files.createTempFile("javaprint", ".ps").toFile();
                    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;

        private void handleProcessFailure(final Process failedProcess,
                final String[] execCmd, final int result) throws IOException {
            try (StringWriter sw = new StringWriter();
                    PrintWriter pw = new PrintWriter(sw)) {
                pw.append("error=").append(Integer.toString(result));
                pw.append(" running:");
                for (String arg: execCmd) {
                    pw.append(" '").append(arg).append("'");
                }
                try (InputStream is = failedProcess.getErrorStream();
                        InputStreamReader isr = new InputStreamReader(is);
                        BufferedReader br = new BufferedReader(isr)) {
                    while (br.ready()) {
                        pw.println();
                        pw.append("\t\t").append(br.readLine());
                    }
                } finally {
                    pw.flush();
                    throw new IOException(sw.toString());
                }
            }
        }

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

                Process process = Runtime.getRuntime().exec(execCmd);
                process.waitFor();
                final int result = process.exitValue();
                if (0 != result) {
                    handleProcessFailure(process, execCmd, result);
                }
            } catch (IOException ex) {
                pex = new PrinterIOException(ex);
            } catch (InterruptedException ie) {
                pex = new PrinterException(ie.toString());
            } finally {
                spoolFile.delete();
            }
            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) {
            PrintService pServ = getPrintService();
            if (pServ != null) {
                mDestination = pServ.getName();
               if (isMac) {
                    PrintServiceAttributeSet psaSet = pServ.getAttributes();
                    if (psaSet != null) {
                        mDestination = psaSet.get(PrinterName.class).toString() ;
                    }
                }
            }
            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() |
                FontUtilities.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;
        }

       String osname = System.getProperty("os.name");
       if (osname.equals("Linux") || osname.contains("OS X")) {
            execCmd = new String[ncomps];
            execCmd[n++] = "/usr/bin/lpr";
            if ((pFlags & PRINTER) != 0) {
                execCmd[n++] = "-P" + printer;
            }
            if ((pFlags & BANNER) != 0) {
                execCmd[n++] = "-J"  + banner;
            }
            if ((pFlags & COPIES) != 0) {
                execCmd[n++] = "-#" + copies;
            }
            if ((pFlags & NOSHEET) != 0) {
                execCmd[n++] = "-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++] = "-d" + printer;
            }
            if ((pFlags & BANNER) != 0) {
                execCmd[n++] = "-t"  + banner;
            }
            if ((pFlags & COPIES) != 0) {
                execCmd[n++] = "-n" + copies;
            }
            if ((pFlags & NOSHEET) != 0) {
                execCmd[n++] = "-o nobanner";
            }
            if ((pFlags & OPTIONS) != 0) {
                execCmd[n++] = "-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.properties. 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;
            }
        }

    }
}
