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
|