/*
 * Copyright (c) 1998, 2025, 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.Shape;

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.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.Copies;
import javax.print.attribute.standard.Destination;
import javax.print.attribute.standard.DialogTypeSelection;
import javax.print.attribute.standard.JobName;
import javax.print.attribute.standard.OutputBin;
import javax.print.attribute.standard.Sides;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
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.Locale;
import java.util.Properties;

import sun.awt.CharsetString;
import sun.awt.FontConfiguration;
import sun.awt.OSInfo;
import sun.awt.PlatformFont;
import sun.awt.SunToolkit;
import sun.font.FontAccess;
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;
import javax.print.attribute.Attribute;
import javax.print.attribute.standard.JobSheets;
import javax.print.attribute.standard.Media;

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

   /**
    * 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 {
        initStatic();
    }

    private static void initStatic() {
        mFontProps = initProps();
        isMac = OSInfo.getOSType() == OSInfo.OSType.MACOSX;
    }

    /*
     * 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
                Properties props = new Properties();
                try (FileInputStream in = new FileInputStream(f.getPath())) {
                    props.load(in);
                }
                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.
     * @throws 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;
    }

    @Override
    protected void setAttributes(PrintRequestAttributeSet attributes)
                                 throws PrinterException {
        super.setAttributes(attributes);
        if (attributes == null) {
            return; // now always use attributes, so this shouldn't happen.
        }
        mOptions = "";
        Attribute attr = attributes.get(Media.class);
        if (attr instanceof CustomMediaTray) {
            CustomMediaTray customTray = (CustomMediaTray)attr;
            String choice = customTray.getChoiceName();
            if (choice != null) {
                mOptions += " InputSlot="+ choice;
            }
        }
        String outputBin = getOutputBinValue(outputBinAttr);
        if (outputBin != null) {
            mOptions += " output-bin=" + outputBin;
        }
    }

    /**
     * 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 privileged open operations.
        // Note that we only open a file if it has been nominated by
        // the end-user in a dialog that we ourselves put up.

        OutputStream output = 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) {
                    abortDoc();
                    throw new PrinterIOException(ex);
                }
            } else {
                PrinterOpener po = new PrinterOpener();
                po.run();
                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." + 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");
        // 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.TRUE;
        try {
            Class<?> psClass = Class.forName("sun.print.IPPPrintService");
            if (psClass.isInstance(pservice)) {
                Method isPSMethod = psClass.getMethod("isPostscript",
                                                      (Class[])null);
                isPS = (Boolean)isPSMethod.invoke(pservice, (Object[])null);
            }
        } catch (Throwable t) {
        }
        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 open the printer output stream.

    private class PrinterOpener {
        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 invoke the system print command

    private class PrinterSpooler {
        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();
        }
        if (spoolFile != null && spoolFile.exists()) {
            spoolFile.delete();
        }
    }

    /**
     * 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 (mPSStream.checkError()) {
                abortDoc();
                throw new PrinterException("Error while writing to file");
            }
            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();
            spooler.run();
            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 = Boolean.TRUE;
            try {
                Class<?> psClass = Class.forName("sun.print.IPPPrintService");
                if (psClass.isInstance(pservice)) {
                    Method isPSMethod =
                                psClass.getMethod("isPostscript",
                                                  (Class[])null);
                    isPS = (Boolean) isPSMethod.invoke(pservice,
                                                      (Object[])null);
                }
            } catch (Throwable t) {
            }
            if (isPS) {
                mPSStream.print(" /DeferredMediaSelection true");
            }
            mPSStream.println(" >> setpagedevice");
        }
        mPSStream.println(PAGE_SAVE);
        mPSStream.println(paperHeight + getCoordPrep());
    }

    /**
     * The RasterPrintJob 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 terminate 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;
     }

    /* 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) {
        /* If we don't have fonts, use 2D path instead. */
        if (mFontProps == null) {
            return false;
        }

        /* 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.isEmpty()) {
            return true;
        }

        /* If AWT can't convert all chars, use 2D path instead. */
        FontAccess access = FontAccess.getFontAccess();
        PlatformFont peer = (PlatformFont) access.getFontPeer(mLastFont);
        CharsetString[] acs = peer.makeMultiCharsetString(str, false);
        if (acs == null) {
            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) {
            return false;
        }

        /* Prepare graphics context, now that we know we can handle the text. */
        prepDrawing();

        /* Draw each string segment. */
        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 | 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 true;
            }
            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;
        }

        return true;
    }

    /**
     * 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 jobTitle, int copies, String spoolFile) {
        int PRINTER = 0x1;
        int OPTIONS = 0x2;
        int JOBTITLE  = 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.isEmpty() && !printer.equals("lp")) {
            pFlags |= PRINTER;
            ncomps+=1;
        }
        if (options != null && !options.isEmpty()) {
            pFlags |= OPTIONS;
            ncomps+=options.trim().split(" ").length;
        }
        if (jobTitle != null && !jobTitle.isEmpty()) {
            pFlags |= JOBTITLE;
            ncomps+=1;
        }
        if (copies > 1) {
            pFlags |= COPIES;
            ncomps+=1;
        }
        if (noJobSheet) {
            pFlags |= NOSHEET;
            ncomps+=1;
        } else if (getPrintService().
                        isAttributeCategorySupported(JobSheets.class)) {
            ncomps+=1; // for jobsheet
        }

        if (OSInfo.getOSType() == OSInfo.OSType.LINUX ||
                OSInfo.getOSType() == OSInfo.OSType.MACOSX) {
            execCmd = new String[ncomps];
            execCmd[n++] = "/usr/bin/lpr";
            if ((pFlags & PRINTER) != 0) {
                execCmd[n++] = "-P" + printer;
            }
            if ((pFlags & JOBTITLE) != 0) {
                execCmd[n++] = "-J"  + jobTitle;
            }
            if ((pFlags & COPIES) != 0) {
                execCmd[n++] = "-#" + copies;
            }
            if ((pFlags & NOSHEET) != 0) {
                execCmd[n++] = "-h";
            } else if (getPrintService().
                        isAttributeCategorySupported(JobSheets.class)) {
                execCmd[n++] = "-o job-sheets=standard";
            }
            if ((pFlags & OPTIONS) != 0) {
                for (String option : options.trim().split(" ")) {
                    execCmd[n++] = "-o " + option;
                }
            }
        } 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 & JOBTITLE) != 0) {
                execCmd[n++] = "-t"  + jobTitle;
            }
            if ((pFlags & COPIES) != 0) {
                execCmd[n++] = "-n" + copies;
            }
            if ((pFlags & NOSHEET) != 0) {
                execCmd[n++] = "-o nobanner";
            } else if (getPrintService().
                        isAttributeCategorySupported(JobSheets.class)) {
                execCmd[n++] = "-o job-sheets=standard";
            }
            if ((pFlags & OPTIONS) != 0) {
                for (String option : options.trim().split(" ")) {
                    execCmd[n++] = "-o " + option;
                }
            }
        }
        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 (pathIter.isDone() ||
            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;

    }
}
