* 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 Load more
* 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);