/*
 * Copyright (c) 1998, 2014, 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.peer.FontPeer;
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.FontAccess;
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}
     * 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}
     * 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 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;

   private double xres = PS_XRES;
   private double yres = PS_XRES;

   /* 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} 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} method.
    */
    private String mClipOpStr = WINDING_CLIP_STR;

   /**
    * A stack that represents the PostScript gstate stack.
    */
   ArrayList<GState> 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<Object>() {
            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.
     * @return 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 = java.security.AccessController.doPrivileged(
                new java.security.PrivilegedAction<Boolean>() {
                    public Boolean 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<OutputStream> {
        PrinterException pex;
        OutputStream result;

        public OutputStream 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<Object> {
        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<Object>() {

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

    private String getCoordPrep() {
        return " 0 exch translate "
             + "1 -1 scale"
             + "[72 " + getXRes() + " div "
             + "0 0 "
             + "72 " + getYRes() + " div "
             + "0 0]concat";
    }

    /**
     * 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 = java.security.AccessController.doPrivileged(
                new java.security.PrivilegedAction<Boolean>() {
                    public Boolean 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 + getCoordPrep());
    }

    /**
     * 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} to PostScript. The image is drawn at
     * {@code (destX, destY)} in device coordinates.
     * The image is scaled into a square of size
     * specified by {@code destWidth} and
     * {@code destHeight}. The portion of the
     * source image copied into that square is specified
     * by {@code srcX}, {@code srcY},
     * {@code srcWidth}, 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 * 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} 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} to perform
     * that conversion. If there is not an object
     * capable of the conversion then return
     * {@code null}. Returning {@code null}
     * 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;
        }
        PlatformFont peer = (PlatformFont) FontAccess.getFontAccess()
                                                     .getFontPeer(font);
        CharsetString[] acs = peer.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;
            }
            PlatformFont peer = (PlatformFont) FontAccess.getFontAccess()
                                                         .getFontPeer(mLastFont);
            CharsetString[] acs = peer.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;

                    StringBuilder nativeStr = new StringBuilder();
                    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} (using the
     * even-odd file rule) or {@code FILL_WINDING}
     * (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}
     */
    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)}.
     */
    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)}.
     */
    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 xres;
    }
    /**
     * Return the y resolution of the coordinates
     * to be rendered.
     */
    protected double getYRes() {
        return yres;
    }

    /**
     * Set the resolution at which to print.
     */
    protected void setXYRes(double x, double y) {
        xres = x;
        yres = y;
    }

    /**
     * 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 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} 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}
     * with the specified color.
     * The path is provided in current user space.
     */
    protected void deviceFill(PathIterator pathIter, Color color,
                              AffineTransform tx, Shape clip) {

        if (Double.isNaN(tx.getScaleX()) ||
            Double.isNaN(tx.getScaleY()) ||
            Double.isNaN(tx.getShearX()) ||
            Double.isNaN(tx.getShearY()) ||
            Double.isNaN(tx.getTranslateX()) ||
            Double.isNaN(tx.getTranslateY())) {
            return;
        }
        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
         */
        @SuppressWarnings("deprecation")
        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;
            }
        }

    }
}
