2283 lines · 83.3 KB · Java
RawDownload
             * take precedence. Make sure imageable area fits on the paper.             */            Paper defaultPaper = new Paper();            wid = ((wid > 0.0) ? wid : defaultPaper.getWidth());            hgt = ((hgt > 0.0) ? hgt : defaultPaper.getHeight());            ix = ((ix > 0.0) ? ix : defaultPaper.getImageableX());            iy = ((iy > 0.0) ? iy : defaultPaper.getImageableY());            iw = ((iw > 0.0) ? iw : defaultPaper.getImageableWidth());            ih = ((ih > 0.0) ? ih : defaultPaper.getImageableHeight());            /* full width/height is not likely to be imageable, but since we             * don't know the limits we have to allow it             */            if (iw > wid) {                iw = wid;            }            if (ih > hgt) {                ih = hgt;            }            if ((ix + iw) > wid) {                ix = wid - iw;            }            if ((iy + ih) > hgt) {                iy = hgt - ih;            }            newPaper.setSize(wid, hgt);            newPaper.setImageableArea(ix, iy, iw, ih);        }    }     /**     * The passed in PageFormat will be copied and altered to describe     * the default page size and orientation of the PrinterJob's     * current printer.     * Platform subclasses which can access the actual default paper size     * for a printer may override this method.     */    public PageFormat defaultPage(PageFormat page) {        PageFormat newPage = (PageFormat)page.clone();        newPage.setOrientation(PageFormat.PORTRAIT);        Paper newPaper = new Paper();        double ptsPerInch = 72.0;        double w, h;        Media media = null;         PrintService service = getPrintService();        if (service != null) {            MediaSize size;            media =                (Media)service.getDefaultAttributeValue(Media.class);             if (media instanceof MediaSizeName &&               ((size = MediaSize.getMediaSizeForName((MediaSizeName)media)) !=                null)) {                w =  size.getX(MediaSize.INCH) * ptsPerInch;                h =  size.getY(MediaSize.INCH) * ptsPerInch;                newPaper.setSize(w, h);                newPaper.setImageableArea(ptsPerInch, ptsPerInch,                                          w - 2.0*ptsPerInch,                                          h - 2.0*ptsPerInch);                newPage.setPaper(newPaper);                return newPage;             }        }         /* Default to A4 paper outside North America.         */        String defaultCountry = Locale.getDefault().getCountry();        if (!Locale.getDefault().equals(Locale.ENGLISH) && // ie "C"            defaultCountry != null &&            !defaultCountry.equals(Locale.US.getCountry()) &&            !defaultCountry.equals(Locale.CANADA.getCountry())) {             double mmPerInch = 25.4;            w = Math.rint((210.0*ptsPerInch)/mmPerInch);            h = Math.rint((297.0*ptsPerInch)/mmPerInch);            newPaper.setSize(w, h);            newPaper.setImageableArea(ptsPerInch, ptsPerInch,                                      w - 2.0*ptsPerInch,                                      h - 2.0*ptsPerInch);        }         newPage.setPaper(newPaper);         return newPage;    }     /**     * The passed in PageFormat is cloned and altered to be usable on     * the PrinterJob's current printer.     */    public PageFormat validatePage(PageFormat page) {        PageFormat newPage = (PageFormat)page.clone();        Paper newPaper = new Paper();        validatePaper(newPage.getPaper(), newPaper);        newPage.setPaper(newPaper);         return newPage;    }     /**     * Set the number of copies to be printed.     */    public void setCopies(int copies) {        mNumCopies = copies;    }     /**     * Get the number of copies to be printed.     */    public int getCopies() {        return mNumCopies;    }    /* Used when executing a print job where an attribute set may     * over ride API values.     */    protected int getCopiesInt() {        return (copiesAttr > 0) ? copiesAttr : getCopies();    }     /**     * Get the name of the printing user.     * The caller must have security permission to read system properties.     */    public String getUserName() {        return System.getProperty("user.name");    }    /* Used when executing a print job where an attribute set may     * over ride API values.     */    protected String getUserNameInt() {        if  (userNameAttr != null) {            return userNameAttr;        } else {            try {                return  getUserName();            } catch (SecurityException e) {                return "";            }        }    }     /**     * Set the name of the document to be printed.     * The document name can not be null.     */    public void setJobName(String jobName) {        if (jobName != null) {            mDocName = jobName;        } else {            throw new NullPointerException();        }    }     /**     * Get the name of the document to be printed.     */    public String getJobName() {        return mDocName;    }     /* Used when executing a print job where an attribute set may     * over ride API values.     */    protected String getJobNameInt() {        return (jobNameAttr != null) ? jobNameAttr : getJobName();    }     /**     * Set the range of pages from a Book to be printed.     * Both 'firstPage' and 'lastPage' are zero based     * page indices. If either parameter is less than     * zero then the page range is set to be from the     * first page to the last.     */    protected void setPageRange(int firstPage, int lastPage) {        if(firstPage >= 0 && lastPage >= 0) {            mFirstPage = firstPage;            mLastPage = lastPage;            if(mLastPage < mFirstPage) mLastPage = mFirstPage;        } else {            mFirstPage = Pageable.UNKNOWN_NUMBER_OF_PAGES;            mLastPage = Pageable.UNKNOWN_NUMBER_OF_PAGES;        }    }     /**     * Return the zero based index of the first page to     * be printed in this job.     */    protected int getFirstPage() {        return mFirstPage == Book.UNKNOWN_NUMBER_OF_PAGES ? 0 : mFirstPage;    }     /**     * Return the zero based index of the last page to     * be printed in this job.     */    protected int getLastPage() {        return mLastPage;    }     /**     * Set whether copies should be collated or not.     * Two collated copies of a three page document     * print in this order: 1, 2, 3, 1, 2, 3 while     * uncollated copies print in this order:     * 1, 1, 2, 2, 3, 3.     * This is set when request is using an attribute set.     */    protected void setCollated(boolean collate) {        mCollate = collate;        collateAttReq = true;    }     /**     * Return true if collated copies will be printed as determined     * in an attribute set.     */    protected boolean isCollated() {            return mCollate;    }     /**     * Called by the print() method at the start of     * a print job.     */    protected abstract void startDoc() throws PrinterException;     /**     * Called by the print() method at the end of     * a print job.     */    protected abstract void endDoc() throws PrinterException;     /* Called by cancelDoc */    protected abstract void abortDoc();     private void cancelDoc() throws PrinterAbortException {        abortDoc();        synchronized (this) {            userCancelled = false;            performingPrinting = false;            notify();        }        throw new PrinterAbortException();    }     /**     * Returns how many times the entire book should     * be printed by the PrintJob. If the printer     * itself supports collation then this method     * should return 1 indicating that the entire     * book need only be printed once and the copies     * will be collated and made in the printer.     */    protected int getCollatedCopies() {        return isCollated() ? getCopiesInt() : 1;    }     /**     * 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 isCollated() ? 1 : getCopiesInt();    }      /* The printer graphics config is cached on the job, so that it can     * be created once, and updated only as needed (for now only to change     * the bounds if when using a Pageable the page sizes changes).     */     private int deviceWidth, deviceHeight;    private AffineTransform defaultDeviceTransform;    private PrinterGraphicsConfig pgConfig;     synchronized void setGraphicsConfigInfo(AffineTransform at,                                            double pw, double ph) {        Point2D.Double pt = new Point2D.Double(pw, ph);        at.transform(pt, pt);         if (pgConfig == null ||            defaultDeviceTransform == null ||            !at.equals(defaultDeviceTransform) ||            deviceWidth != (int)pt.getX() ||            deviceHeight != (int)pt.getY()) {                 deviceWidth = (int)pt.getX();                deviceHeight = (int)pt.getY();                defaultDeviceTransform = at;                pgConfig = null;        }    }     synchronized PrinterGraphicsConfig getPrinterGraphicsConfig() {        if (pgConfig != null) {            return pgConfig;        }        String deviceID = "Printer Device";        PrintService service = getPrintService();        if (service != null) {            deviceID = service.toString();        }        pgConfig = new PrinterGraphicsConfig(deviceID,                                             defaultDeviceTransform,                                             deviceWidth, deviceHeight);        return pgConfig;    }     /**     * Print a page from the provided document.     * @return int Printable.PAGE_EXISTS if the page existed and was drawn and     *             Printable.NO_SUCH_PAGE if the page did not exist.     * @see java.awt.print.Printable     */    protected int printPage(Pageable document, int pageIndex)        throws PrinterException    {        PageFormat page;        PageFormat origPage;        Printable painter;        try {            origPage = document.getPageFormat(pageIndex);            page = (PageFormat)origPage.clone();            painter = document.getPrintable(pageIndex);        } catch (Exception e) {            PrinterException pe =                    new PrinterException("Error getting page or printable.[ " +                                          e +" ]");            pe.initCause(e);            throw pe;        }         /* Get the imageable area from Paper instead of PageFormat         * because we do not want it adjusted by the page orientation.         */        Paper paper = page.getPaper();        // if non-portrait and 270 degree landscape rotation        if (page.getOrientation() != PageFormat.PORTRAIT &&            landscapeRotates270) {             double left = paper.getImageableX();            double top = paper.getImageableY();            double width = paper.getImageableWidth();            double height = paper.getImageableHeight();            paper.setImageableArea(paper.getWidth()-left-width,                                   paper.getHeight()-top-height,                                   width, height);            page.setPaper(paper);            if (page.getOrientation() == PageFormat.LANDSCAPE) {                page.setOrientation(PageFormat.REVERSE_LANDSCAPE);            } else {                page.setOrientation(PageFormat.LANDSCAPE);            }        }         double xScale = getXRes() / 72.0;        double yScale = getYRes() / 72.0;         /* The deviceArea is the imageable area in the printer's         * resolution.         */        Rectangle2D deviceArea =            new Rectangle2D.Double(paper.getImageableX() * xScale,                                   paper.getImageableY() * yScale,                                   paper.getImageableWidth() * xScale,                                   paper.getImageableHeight() * yScale);         /* Build and hold on to a uniform transform so that         * we can get back to device space at the beginning         * of each band.         */        AffineTransform uniformTransform = new AffineTransform();         /* The scale transform is used to switch from the         * device space to the user's 72 dpi space.         */        AffineTransform scaleTransform = new AffineTransform();        scaleTransform.scale(xScale, yScale);         /* bandwidth is multiple of 4 as the data is used in a win32 DIB and         * some drivers behave badly if scanlines aren't multiples of 4 bytes.         */        int bandWidth = (int) deviceArea.getWidth();        if (bandWidth % 4 != 0) {            bandWidth += (4 - (bandWidth % 4));        }        if (bandWidth <= 0) {            throw new PrinterException("Paper's imageable width is too small.");        }         int deviceAreaHeight = (int)deviceArea.getHeight();        if (deviceAreaHeight <= 0) {            throw new PrinterException("Paper's imageable height is too small.");        }         /* Figure out the number of lines that will fit into         * our maximum band size. The hard coded 3 reflects the         * fact that we can only create 24 bit per pixel 3 byte BGR         * BufferedImages. FIX.         */        int bandHeight = (int)(MAX_BAND_SIZE / bandWidth / 3);         int deviceLeft = (int)Math.rint(paper.getImageableX() * xScale);        int deviceTop  = (int)Math.rint(paper.getImageableY() * yScale);         /* The device transform is used to move the band down         * the page using translates. Normally this is all it         * would do, but since, when printing, the Window's         * DIB format wants the last line to be first (lowest) in         * memory, the deviceTransform moves the origin to the         * bottom of the band and flips the origin. This way the         * app prints upside down into the band which is the DIB         * format.         */        AffineTransform deviceTransform = new AffineTransform();        deviceTransform.translate(-deviceLeft, deviceTop);        deviceTransform.translate(0, bandHeight);        deviceTransform.scale(1, -1);         /* Create a BufferedImage to hold the band. We set the clip         * of the band to be tight around the bits so that the         * application can use it to figure what part of the         * page needs to be drawn. The clip is never altered in         * this method, but we do translate the band's coordinate         * system so that the app will see the clip moving down the         * page though it s always around the same set of pixels.         */        BufferedImage pBand = new BufferedImage(1, 1,                                                BufferedImage.TYPE_3BYTE_BGR);         /* Have the app draw into a PeekGraphics object so we can         * learn something about the needs of the print job.         */         PeekGraphics peekGraphics = createPeekGraphics(pBand.createGraphics(),                                                       this);         Rectangle2D.Double pageFormatArea =            new Rectangle2D.Double(page.getImageableX(),                                   page.getImageableY(),                                   page.getImageableWidth(),                                   page.getImageableHeight());        peekGraphics.transform(scaleTransform);        peekGraphics.translate(-getPhysicalPrintableX(paper) / xScale,                               -getPhysicalPrintableY(paper) / yScale);        peekGraphics.transform(new AffineTransform(page.getMatrix()));        initPrinterGraphics(peekGraphics, pageFormatArea);        AffineTransform pgAt = peekGraphics.getTransform();         /* Update the information used to return a GraphicsConfiguration         * for this printer device. It needs to be updated per page as         * not all pages in a job may be the same size (different bounds)         * The transform is the scaling transform as this corresponds to         * the default transform for the device. The width and height are         * those of the paper, not the page format, as we want to describe         * the bounds of the device in its natural coordinate system of         * device coordinate whereas a page format may be in a rotated context.         */        setGraphicsConfigInfo(scaleTransform,                              paper.getWidth(), paper.getHeight());        int pageResult = painter.print(peekGraphics, origPage, pageIndex);        debug_println("pageResult "+pageResult);        if (pageResult == Printable.PAGE_EXISTS) {            debug_println("startPage "+pageIndex);             /* We need to check if the paper size is changed.             * Note that it is not sufficient to ask for the pageformat             * of "pageIndex-1", since PageRanges mean that pages can be             * skipped. So we have to look at the actual last paper size used.             */            Paper thisPaper = page.getPaper();            boolean paperChanged =                previousPaper == null ||                thisPaper.getWidth() != previousPaper.getWidth() ||                thisPaper.getHeight() != previousPaper.getHeight();            previousPaper = thisPaper;             startPage(page, painter, pageIndex, paperChanged);            Graphics2D pathGraphics = createPathGraphics(peekGraphics, this,                                                         painter, page,                                                         pageIndex);             /* If we can convert the page directly to the             * underlying graphics system then we do not             * need to rasterize. We also may not need to             * create the 'band' if all the pages can take             * this path.             */            if (pathGraphics != null) {                pathGraphics.transform(scaleTransform);                // user (0,0) should be origin of page, not imageable area                pathGraphics.translate(-getPhysicalPrintableX(paper) / xScale,                                       -getPhysicalPrintableY(paper) / yScale);

Lines 1501–2000 of 2283. Previous lines