2283 lines · 83.3 KB · Java
RawDownload
/* * Copyright (c) 1998, 2008, 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.io.FilePermission; import java.awt.Color;import java.awt.Dialog;import java.awt.Frame;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.GraphicsConfiguration;import java.awt.GraphicsEnvironment;import java.awt.HeadlessException;import java.awt.KeyboardFocusManager;import java.awt.Rectangle;import java.awt.Shape;import java.awt.geom.AffineTransform;import java.awt.geom.Area;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.awt.image.BufferedImage;import java.awt.print.Book;import java.awt.print.Pageable;import java.awt.print.PageFormat;import java.awt.print.Paper;import java.awt.print.Printable;import java.awt.print.PrinterAbortException;import java.awt.print.PrinterException;import java.awt.print.PrinterJob;import java.awt.Window;import java.io.File;import java.io.IOException;import java.util.ArrayList;import java.util.Enumeration;import java.util.Locale;import sun.awt.image.ByteInterleavedRaster; import javax.print.Doc;import javax.print.DocFlavor;import javax.print.DocPrintJob;import javax.print.PrintException;import javax.print.PrintService;import javax.print.PrintServiceLookup;import javax.print.ServiceUI;import javax.print.StreamPrintService;import javax.print.StreamPrintServiceFactory;import javax.print.attribute.Attribute;import javax.print.attribute.AttributeSet;import javax.print.attribute.HashPrintRequestAttributeSet;import javax.print.attribute.PrintRequestAttributeSet;import javax.print.attribute.Size2DSyntax;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.Fidelity;import javax.print.attribute.standard.JobName;import javax.print.attribute.standard.JobSheets;import javax.print.attribute.standard.Media;import javax.print.attribute.standard.MediaPrintableArea;import javax.print.attribute.standard.MediaSize;import javax.print.attribute.standard.MediaSizeName;import javax.print.attribute.standard.OrientationRequested;import javax.print.attribute.standard.PageRanges;import javax.print.attribute.standard.PrinterState;import javax.print.attribute.standard.PrinterStateReason;import javax.print.attribute.standard.PrinterStateReasons;import javax.print.attribute.standard.PrinterIsAcceptingJobs;import javax.print.attribute.standard.RequestingUserName;import javax.print.attribute.standard.SheetCollate;import javax.print.attribute.standard.Sides; import sun.print.PageableDoc;import sun.print.ServiceDialog;import sun.print.SunPrinterJobService;import sun.print.SunPageSelection; /** * A class which rasterizes a printer job. * * @author Richard Blanchard */public abstract class RasterPrinterJob extends PrinterJob {  /* Class Constants */      /* Printer destination type. */    protected static final int PRINTER = 0;      /* File destination type.  */    protected static final int FILE = 1;     /* Stream destination type.  */    protected static final int STREAM = 2;     /**     * Maximum amount of memory in bytes to use for the     * buffered image "band". 4Mb is a compromise between     * limiting the number of bands on hi-res printers and     * not using too much of the Java heap or causing paging     * on systems with little RAM.     */    private static final int MAX_BAND_SIZE = (1024 * 1024 * 4);     /* Dots Per Inch */    private static final float DPI = 72.0f;     /**     * Useful mainly for debugging, this system property     * can be used to force the printing code to print     * using a particular pipeline. The two currently     * supported values are FORCE_RASTER and FORCE_PDL.     */    private static final String FORCE_PIPE_PROP = "sun.java2d.print.pipeline";     /**     * When the system property FORCE_PIPE_PROP has this value     * then each page of a print job will be rendered through     * the raster pipeline.     */    private static final String FORCE_RASTER = "raster";     /**     * When the system property FORCE_PIPE_PROP has this value     * then each page of a print job will be rendered through     * the PDL pipeline.     */    private static final String FORCE_PDL = "pdl";     /**     * When the system property SHAPE_TEXT_PROP has this value     * then text is always rendered as a shape, and no attempt is made     * to match the font through GDI     */    private static final String SHAPE_TEXT_PROP = "sun.java2d.print.shapetext";     /**     * values obtained from System properties in static initialiser block     */    public static boolean forcePDL = false;    public static boolean forceRaster = false;    public static boolean shapeTextProp = false;     static {        /* The system property FORCE_PIPE_PROP         * can be used to force the printing code to         * use a particular pipeline. Either the raster         * pipeline or the pdl pipeline can be forced.         */        String forceStr =           (String)java.security.AccessController.doPrivileged(                   new sun.security.action.GetPropertyAction(FORCE_PIPE_PROP));         if (forceStr != null) {            if (forceStr.equalsIgnoreCase(FORCE_PDL)) {                forcePDL = true;            } else if (forceStr.equalsIgnoreCase(FORCE_RASTER)) {                forceRaster = true;            }        }         String shapeTextStr =           (String)java.security.AccessController.doPrivileged(                   new sun.security.action.GetPropertyAction(SHAPE_TEXT_PROP));         if (shapeTextStr != null) {            shapeTextProp = true;        }    }     /* Instance Variables */     /**     * Used to minimise GC & reallocation of band when printing     */    private int cachedBandWidth = 0;    private int cachedBandHeight = 0;    private BufferedImage cachedBand = null;     /**     * The number of book copies to be printed.     */    private int mNumCopies = 1;     /**     * Collation effects the order of the pages printed     * when multiple copies are requested. For two copies     * of a three page document the page order is:     *  mCollate true: 1, 2, 3, 1, 2, 3     *  mCollate false: 1, 1, 2, 2, 3, 3     */    private boolean mCollate = false;     /**     * The zero based indices of the first and last     * pages to be printed. If 'mFirstPage' is     * UNDEFINED_PAGE_NUM then the first page to     * be printed is page 0. If 'mLastPage' is     * UNDEFINED_PAGE_NUM then the last page to     * be printed is the last one in the book.     */    private int mFirstPage = Pageable.UNKNOWN_NUMBER_OF_PAGES;    private int mLastPage = Pageable.UNKNOWN_NUMBER_OF_PAGES;     /**     * The previous print stream Paper     * Used to check if the paper size has changed such that the     * implementation needs to emit the new paper size information     * into the print stream.     * Since we do our own rotation, and the margins aren't relevant,     * Its strictly the dimensions of the paper that we will check.     */    private Paper previousPaper;     /**     * The document to be printed. It is initialized to an     * empty (zero pages) book.     */    private Pageable mDocument = new Book();     /**     * The name of the job being printed.     */    private String mDocName = "Java Printing";      /**     * Printing cancellation flags     */    private boolean performingPrinting = false;    private boolean userCancelled = false;    /**    * Print to file permission variables.    */    private FilePermission printToFilePermission;     /**     * List of areas & the graphics state for redrawing     */    private ArrayList redrawList = new ArrayList();      /* variables representing values extracted from an attribute set.     * These take precedence over values set on a printer job     */    private int copiesAttr;    private String jobNameAttr;    private String userNameAttr;    private PageRanges pageRangesAttr;    protected Sides sidesAttr;    protected String destinationAttr;    protected boolean noJobSheet = false;    protected int mDestType = RasterPrinterJob.FILE;    protected String mDestination = "";    protected boolean collateAttReq = false;     /**     * Device rotation flag, if it support 270, this is set to true;     */    protected boolean landscapeRotates270 = false;    /**     * attributes used by no-args page and print dialog and print method to     * communicate state     */    protected PrintRequestAttributeSet attributes = null;     /**     * Class to keep state information for redrawing areas     * "region" is an area at as a high a resolution as possible.     * The redrawing code needs to look at sx, sy to calculate the scale     * to device resolution.     */    private class GraphicsState {        Rectangle2D region;  // Area of page to repaint        Shape theClip;       // image drawing clip.        AffineTransform theTransform; // to transform clip to dev coords.        double sx;           // X scale from region to device resolution        double sy;           // Y scale from region to device resolution    }     /**     * Service for this job     */    protected PrintService myService;  /* Constructors */     public RasterPrinterJob()    {    } /* Abstract Methods */     /**     * Returns the resolution in dots per inch across the width     * of the page.     */    abstract protected double getXRes();     /**     * Returns the resolution in dots per inch down the height     * of the page.     */    abstract protected double getYRes();     /**     * Must be obtained from the current printer.     * Value is in device pixels.     * Not adjusted for orientation of the paper.     */    abstract protected double getPhysicalPrintableX(Paper p);     /**     * Must be obtained from the current printer.     * Value is in device pixels.     * Not adjusted for orientation of the paper.     */    abstract protected double getPhysicalPrintableY(Paper p);     /**     * Must be obtained from the current printer.     * Value is in device pixels.     * Not adjusted for orientation of the paper.     */    abstract protected double getPhysicalPrintableWidth(Paper p);     /**     * Must be obtained from the current printer.     * Value is in device pixels.     * Not adjusted for orientation of the paper.     */    abstract protected double getPhysicalPrintableHeight(Paper p);     /**     * Must be obtained from the current printer.     * Value is in device pixels.     * Not adjusted for orientation of the paper.     */    abstract protected double getPhysicalPageWidth(Paper p);     /**     * Must be obtained from the current printer.     * Value is in device pixels.     * Not adjusted for orientation of the paper.     */    abstract protected double getPhysicalPageHeight(Paper p);     /**     * Begin a new page.     */    abstract protected void startPage(PageFormat format, Printable painter,                                      int index, boolean paperChanged)        throws PrinterException;     /**     * End a page.     */    abstract protected void endPage(PageFormat format, Printable painter,                                    int index)        throws PrinterException;     /**     * 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.     */    abstract protected void printBand(byte[] data, int x, int y,                                      int width, int height)        throws PrinterException; /* Instance Methods */     /**      * save graphics state of a PathGraphics for later redrawing      * of part of page represented by the region in that state      */     public void saveState(AffineTransform at, Shape clip,                          Rectangle2D region, double sx, double sy) {        GraphicsState gstate = new GraphicsState();        gstate.theTransform = at;        gstate.theClip = clip;        gstate.region = region;        gstate.sx = sx;        gstate.sy = sy;        redrawList.add(gstate);    }      /*     * A convenience method which returns the default service     * for 2D <code>PrinterJob</code>s.     * May return null if there is no suitable default (although there     * may still be 2D services available).     * @return default 2D print service, or null.     * @since     1.4     */    protected static PrintService lookupDefaultPrintService() {        PrintService service = PrintServiceLookup.lookupDefaultPrintService();         /* Pageable implies Printable so checking both isn't strictly needed */        if (service != null &&            service.isDocFlavorSupported(                                DocFlavor.SERVICE_FORMATTED.PAGEABLE) &&            service.isDocFlavorSupported(                                DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {            return service;        } else {           PrintService []services =             PrintServiceLookup.lookupPrintServices(                                DocFlavor.SERVICE_FORMATTED.PAGEABLE, null);           if (services.length > 0) {               return services[0];           }        }        return null;    }    /**     * Returns the service (printer) for this printer job.     * Implementations of this class which do not support print services     * may return null;     * @return the service for this printer job.     *     */    public PrintService getPrintService() {        if (myService == null) {            PrintService svc = PrintServiceLookup.lookupDefaultPrintService();            if (svc != null &&                svc.isDocFlavorSupported(                     DocFlavor.SERVICE_FORMATTED.PAGEABLE)) {                try {                    setPrintService(svc);                    myService = svc;                } catch (PrinterException e) {                }            }            if (myService == null) {                PrintService[] svcs = PrintServiceLookup.lookupPrintServices(                    DocFlavor.SERVICE_FORMATTED.PAGEABLE, null);                if (svcs.length > 0) {                    try {                        setPrintService(svcs[0]);                        myService = svcs[0];                    } catch (PrinterException e) {                    }                }            }        }        return myService;    }     /**     * Associate this PrinterJob with a new PrintService.     *     * Throws <code>PrinterException</code> if the specified service     * cannot support the <code>Pageable</code> and     * <code>Printable</code> interfaces necessary to support 2D printing.     * @param a print service which supports 2D printing.     *     * @throws PrinterException if the specified service does not support     * 2D printing or no longer available.     */    public void setPrintService(PrintService service)        throws PrinterException {        if (service == null) {            throw new PrinterException("Service cannot be null");        } else if (!(service instanceof StreamPrintService) &&                   service.getName() == null) {            throw new PrinterException("Null PrintService name.");        } else {            // Check the list of services.  This service may have been

Lines 1–500 of 2283.