src/share/classes/sun/print/RasterPrinterJob.java

Print this page


   1 /*
   2  * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 164     /**
 165      * When the system property SHAPE_TEXT_PROP has this value
 166      * then text is always rendered as a shape, and no attempt is made
 167      * to match the font through GDI
 168      */
 169     private static final String SHAPE_TEXT_PROP = "sun.java2d.print.shapetext";
 170 
 171     /**
 172      * values obtained from System properties in static initialiser block
 173      */
 174     public static boolean forcePDL = false;
 175     public static boolean forceRaster = false;
 176     public static boolean shapeTextProp = false;
 177 
 178     static {
 179         /* The system property FORCE_PIPE_PROP
 180          * can be used to force the printing code to
 181          * use a particular pipeline. Either the raster
 182          * pipeline or the pdl pipeline can be forced.
 183          */
 184         String forceStr =
 185            (String)java.security.AccessController.doPrivileged(
 186                    new sun.security.action.GetPropertyAction(FORCE_PIPE_PROP));
 187 
 188         if (forceStr != null) {
 189             if (forceStr.equalsIgnoreCase(FORCE_PDL)) {
 190                 forcePDL = true;
 191             } else if (forceStr.equalsIgnoreCase(FORCE_RASTER)) {
 192                 forceRaster = true;
 193             }
 194         }
 195 
 196         String shapeTextStr =
 197            (String)java.security.AccessController.doPrivileged(
 198                    new sun.security.action.GetPropertyAction(SHAPE_TEXT_PROP));
 199 
 200         if (shapeTextStr != null) {
 201             shapeTextProp = true;
 202         }
 203     }
 204 
 205     /* Instance Variables */
 206 
 207     /**
 208      * Used to minimize GC & reallocation of band when printing
 209      */
 210     private int cachedBandWidth = 0;
 211     private int cachedBandHeight = 0;
 212     private BufferedImage cachedBand = null;
 213 
 214     /**
 215      * The number of book copies to be printed.
 216      */
 217     private int mNumCopies = 1;


 495      * Associate this PrinterJob with a new PrintService.
 496      *
 497      * Throws <code>PrinterException</code> if the specified service
 498      * cannot support the <code>Pageable</code> and
 499      * <code>Printable</code> interfaces necessary to support 2D printing.
 500      * @param a print service which supports 2D printing.
 501      *
 502      * @throws PrinterException if the specified service does not support
 503      * 2D printing or no longer available.
 504      */
 505     public void setPrintService(PrintService service)
 506         throws PrinterException {
 507         if (service == null) {
 508             throw new PrinterException("Service cannot be null");
 509         } else if (!(service instanceof StreamPrintService) &&
 510                    service.getName() == null) {
 511             throw new PrinterException("Null PrintService name.");
 512         } else {
 513             // Check the list of services.  This service may have been
 514             // deleted already
 515             PrinterState prnState = (PrinterState)service.getAttribute(
 516                                                   PrinterState.class);
 517             if (prnState == PrinterState.STOPPED) {
 518                 PrinterStateReasons prnStateReasons =
 519                     (PrinterStateReasons)service.getAttribute(
 520                                                  PrinterStateReasons.class);
 521                 if ((prnStateReasons != null) &&
 522                     (prnStateReasons.containsKey(PrinterStateReason.SHUTDOWN)))
 523                 {
 524                     throw new PrinterException("PrintService is no longer available.");
 525                 }
 526             }
 527 
 528 
 529             if (service.isDocFlavorSupported(
 530                                              DocFlavor.SERVICE_FORMATTED.PAGEABLE) &&
 531                 service.isDocFlavorSupported(
 532                                              DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
 533                 myService = service;
 534             } else {
 535                 throw new PrinterException("Not a 2D print service: " + service);
 536             }
 537         }
 538     }
 539 
 540     private PageFormat attributeToPageFormat(PrintService service,


1336         /*
1337          * In the future PrinterJob will probably always dispatch
1338          * the print job to the PrintService.
1339          * This is how third party 2D Print Services will be invoked
1340          * when applications use the PrinterJob API.
1341          * However the JRE's concrete PrinterJob implementations have
1342          * not yet been re-worked to be implemented as standalone
1343          * services, and are implemented only as subclasses of PrinterJob.
1344          * So here we dispatch only those services we do not recognize
1345          * as implemented through platform subclasses of PrinterJob
1346          * (and this class).
1347          */
1348         PrintService psvc = getPrintService();
1349         debug_println("psvc = "+psvc);
1350         if (psvc == null) {
1351             throw new PrinterException("No print service found.");
1352         }
1353 
1354         // Check the list of services.  This service may have been
1355         // deleted already
1356         PrinterState prnState = (PrinterState)psvc.getAttribute(
1357                                                   PrinterState.class);
1358         if (prnState == PrinterState.STOPPED) {
1359             PrinterStateReasons prnStateReasons =
1360                     (PrinterStateReasons)psvc.getAttribute(
1361                                                  PrinterStateReasons.class);
1362                 if ((prnStateReasons != null) &&
1363                     (prnStateReasons.containsKey(PrinterStateReason.SHUTDOWN)))
1364                 {
1365                     throw new PrinterException("PrintService is no longer available.");
1366                 }
1367         }
1368 
1369         if ((PrinterIsAcceptingJobs)(psvc.getAttribute(
1370                          PrinterIsAcceptingJobs.class)) ==
1371                          PrinterIsAcceptingJobs.NOT_ACCEPTING_JOBS) {
1372             throw new PrinterException("Printer is not accepting job.");
1373         }
1374 
1375         if ((psvc instanceof SunPrinterJobService) &&
1376             ((SunPrinterJobService)psvc).usesClass(getClass())) {
1377             setAttributes(attributes);
1378             // throw exception for invalid destination
1379             if (destinationAttr != null) {
1380                 validateDestination(destinationAttr);
1381             }
1382         } else {
1383             spoolToService(psvc, attributes);
1384             return;
1385         }
1386         /* We need to make sure that the collation and copies
1387          * settings are initialised */
1388         initPrinter();
1389 
1390         int numCollatedCopies = getCollatedCopies();


2018          * some drivers behave badly if scanlines aren't multiples of 4 bytes.
2019          */
2020         int bandWidth = (int) deviceArea.getWidth();
2021         if (bandWidth % 4 != 0) {
2022             bandWidth += (4 - (bandWidth % 4));
2023         }
2024         if (bandWidth <= 0) {
2025             throw new PrinterException("Paper's imageable width is too small.");
2026         }
2027 
2028         int deviceAreaHeight = (int)deviceArea.getHeight();
2029         if (deviceAreaHeight <= 0) {
2030             throw new PrinterException("Paper's imageable height is too small.");
2031         }
2032 
2033         /* Figure out the number of lines that will fit into
2034          * our maximum band size. The hard coded 3 reflects the
2035          * fact that we can only create 24 bit per pixel 3 byte BGR
2036          * BufferedImages. FIX.
2037          */
2038         int bandHeight = (int)(MAX_BAND_SIZE / bandWidth / 3);
2039 
2040         int deviceLeft = (int)Math.rint(paper.getImageableX() * xScale);
2041         int deviceTop  = (int)Math.rint(paper.getImageableY() * yScale);
2042 
2043         /* The device transform is used to move the band down
2044          * the page using translates. Normally this is all it
2045          * would do, but since, when printing, the Window's
2046          * DIB format wants the last line to be first (lowest) in
2047          * memory, the deviceTransform moves the origin to the
2048          * bottom of the band and flips the origin. This way the
2049          * app prints upside down into the band which is the DIB
2050          * format.
2051          */
2052         AffineTransform deviceTransform = new AffineTransform();
2053         deviceTransform.translate(-deviceLeft, deviceTop);
2054         deviceTransform.translate(0, bandHeight);
2055         deviceTransform.scale(1, -1);
2056 
2057         /* Create a BufferedImage to hold the band. We set the clip
2058          * of the band to be tight around the bits so that the


   1 /*
   2  * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 164     /**
 165      * When the system property SHAPE_TEXT_PROP has this value
 166      * then text is always rendered as a shape, and no attempt is made
 167      * to match the font through GDI
 168      */
 169     private static final String SHAPE_TEXT_PROP = "sun.java2d.print.shapetext";
 170 
 171     /**
 172      * values obtained from System properties in static initialiser block
 173      */
 174     public static boolean forcePDL = false;
 175     public static boolean forceRaster = false;
 176     public static boolean shapeTextProp = false;
 177 
 178     static {
 179         /* The system property FORCE_PIPE_PROP
 180          * can be used to force the printing code to
 181          * use a particular pipeline. Either the raster
 182          * pipeline or the pdl pipeline can be forced.
 183          */
 184         String forceStr = java.security.AccessController.doPrivileged(

 185                    new sun.security.action.GetPropertyAction(FORCE_PIPE_PROP));
 186 
 187         if (forceStr != null) {
 188             if (forceStr.equalsIgnoreCase(FORCE_PDL)) {
 189                 forcePDL = true;
 190             } else if (forceStr.equalsIgnoreCase(FORCE_RASTER)) {
 191                 forceRaster = true;
 192             }
 193         }
 194 
 195         String shapeTextStr =java.security.AccessController.doPrivileged(

 196                    new sun.security.action.GetPropertyAction(SHAPE_TEXT_PROP));
 197 
 198         if (shapeTextStr != null) {
 199             shapeTextProp = true;
 200         }
 201     }
 202 
 203     /* Instance Variables */
 204 
 205     /**
 206      * Used to minimize GC & reallocation of band when printing
 207      */
 208     private int cachedBandWidth = 0;
 209     private int cachedBandHeight = 0;
 210     private BufferedImage cachedBand = null;
 211 
 212     /**
 213      * The number of book copies to be printed.
 214      */
 215     private int mNumCopies = 1;


 493      * Associate this PrinterJob with a new PrintService.
 494      *
 495      * Throws <code>PrinterException</code> if the specified service
 496      * cannot support the <code>Pageable</code> and
 497      * <code>Printable</code> interfaces necessary to support 2D printing.
 498      * @param a print service which supports 2D printing.
 499      *
 500      * @throws PrinterException if the specified service does not support
 501      * 2D printing or no longer available.
 502      */
 503     public void setPrintService(PrintService service)
 504         throws PrinterException {
 505         if (service == null) {
 506             throw new PrinterException("Service cannot be null");
 507         } else if (!(service instanceof StreamPrintService) &&
 508                    service.getName() == null) {
 509             throw new PrinterException("Null PrintService name.");
 510         } else {
 511             // Check the list of services.  This service may have been
 512             // deleted already
 513             PrinterState prnState = service.getAttribute(PrinterState.class);

 514             if (prnState == PrinterState.STOPPED) {
 515                 PrinterStateReasons prnStateReasons =
 516                     service.getAttribute(PrinterStateReasons.class);

 517                 if ((prnStateReasons != null) &&
 518                     (prnStateReasons.containsKey(PrinterStateReason.SHUTDOWN)))
 519                 {
 520                     throw new PrinterException("PrintService is no longer available.");
 521                 }
 522             }
 523 
 524 
 525             if (service.isDocFlavorSupported(
 526                                              DocFlavor.SERVICE_FORMATTED.PAGEABLE) &&
 527                 service.isDocFlavorSupported(
 528                                              DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
 529                 myService = service;
 530             } else {
 531                 throw new PrinterException("Not a 2D print service: " + service);
 532             }
 533         }
 534     }
 535 
 536     private PageFormat attributeToPageFormat(PrintService service,


1332         /*
1333          * In the future PrinterJob will probably always dispatch
1334          * the print job to the PrintService.
1335          * This is how third party 2D Print Services will be invoked
1336          * when applications use the PrinterJob API.
1337          * However the JRE's concrete PrinterJob implementations have
1338          * not yet been re-worked to be implemented as standalone
1339          * services, and are implemented only as subclasses of PrinterJob.
1340          * So here we dispatch only those services we do not recognize
1341          * as implemented through platform subclasses of PrinterJob
1342          * (and this class).
1343          */
1344         PrintService psvc = getPrintService();
1345         debug_println("psvc = "+psvc);
1346         if (psvc == null) {
1347             throw new PrinterException("No print service found.");
1348         }
1349 
1350         // Check the list of services.  This service may have been
1351         // deleted already
1352         PrinterState prnState = psvc.getAttribute(PrinterState.class);

1353         if (prnState == PrinterState.STOPPED) {
1354             PrinterStateReasons prnStateReasons =
1355                     psvc.getAttribute(PrinterStateReasons.class);

1356                 if ((prnStateReasons != null) &&
1357                     (prnStateReasons.containsKey(PrinterStateReason.SHUTDOWN)))
1358                 {
1359                     throw new PrinterException("PrintService is no longer available.");
1360                 }
1361         }
1362 
1363         if ((psvc.getAttribute(PrinterIsAcceptingJobs.class)) ==

1364                          PrinterIsAcceptingJobs.NOT_ACCEPTING_JOBS) {
1365             throw new PrinterException("Printer is not accepting job.");
1366         }
1367 
1368         if ((psvc instanceof SunPrinterJobService) &&
1369             ((SunPrinterJobService)psvc).usesClass(getClass())) {
1370             setAttributes(attributes);
1371             // throw exception for invalid destination
1372             if (destinationAttr != null) {
1373                 validateDestination(destinationAttr);
1374             }
1375         } else {
1376             spoolToService(psvc, attributes);
1377             return;
1378         }
1379         /* We need to make sure that the collation and copies
1380          * settings are initialised */
1381         initPrinter();
1382 
1383         int numCollatedCopies = getCollatedCopies();


2011          * some drivers behave badly if scanlines aren't multiples of 4 bytes.
2012          */
2013         int bandWidth = (int) deviceArea.getWidth();
2014         if (bandWidth % 4 != 0) {
2015             bandWidth += (4 - (bandWidth % 4));
2016         }
2017         if (bandWidth <= 0) {
2018             throw new PrinterException("Paper's imageable width is too small.");
2019         }
2020 
2021         int deviceAreaHeight = (int)deviceArea.getHeight();
2022         if (deviceAreaHeight <= 0) {
2023             throw new PrinterException("Paper's imageable height is too small.");
2024         }
2025 
2026         /* Figure out the number of lines that will fit into
2027          * our maximum band size. The hard coded 3 reflects the
2028          * fact that we can only create 24 bit per pixel 3 byte BGR
2029          * BufferedImages. FIX.
2030          */
2031         int bandHeight = (MAX_BAND_SIZE / bandWidth / 3);
2032 
2033         int deviceLeft = (int)Math.rint(paper.getImageableX() * xScale);
2034         int deviceTop  = (int)Math.rint(paper.getImageableY() * yScale);
2035 
2036         /* The device transform is used to move the band down
2037          * the page using translates. Normally this is all it
2038          * would do, but since, when printing, the Window's
2039          * DIB format wants the last line to be first (lowest) in
2040          * memory, the deviceTransform moves the origin to the
2041          * bottom of the band and flips the origin. This way the
2042          * app prints upside down into the band which is the DIB
2043          * format.
2044          */
2045         AffineTransform deviceTransform = new AffineTransform();
2046         deviceTransform.translate(-deviceLeft, deviceTop);
2047         deviceTransform.translate(0, bandHeight);
2048         deviceTransform.scale(1, -1);
2049 
2050         /* Create a BufferedImage to hold the band. We set the clip
2051          * of the band to be tight around the bits so that the