001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Aleksei V. Ivaschenko
019: * @version $Revision: 1.2 $
020: */package org.apache.harmony.x.print;
021:
022: import java.awt.Graphics;
023: import java.awt.Image;
024: import java.awt.Toolkit;
025: import java.awt.image.BufferedImage;
026: import java.awt.image.ImageObserver;
027: import java.awt.print.PageFormat;
028: import java.awt.print.Pageable;
029: import java.awt.print.Paper;
030: import java.awt.print.Printable;
031: import java.awt.print.PrinterException;
032: import java.io.IOException;
033: import java.io.InputStream;
034: import java.io.OutputStream;
035: import java.io.PrintStream;
036: import java.net.URL;
037: import java.util.ArrayList;
038: import javax.print.Doc;
039: import javax.print.DocFlavor;
040: import javax.print.DocPrintJob;
041: import javax.print.PrintException;
042: import javax.print.PrintService;
043: import javax.print.StreamPrintService;
044: import javax.print.attribute.HashPrintJobAttributeSet;
045: import javax.print.attribute.PrintJobAttributeSet;
046: import javax.print.attribute.PrintRequestAttributeSet;
047: import javax.print.attribute.standard.MediaSize;
048: import javax.print.attribute.standard.MediaSizeName;
049: import javax.print.attribute.standard.OrientationRequested;
050: import javax.print.event.PrintJobAttributeListener;
051: import javax.print.event.PrintJobListener;
052:
053: /*
054: * Image2PSDocPrintJob
055: */
056: public class All2PSDocPrintJob implements DocPrintJob {
057: private PrintService begetPrintService;
058: private HashPrintJobAttributeSet printJobAttributeSet;
059: private ArrayList printJobListeners;
060: private ArrayList printJobAttributeListeners;
061: private boolean action = false;
062: private PrintStream outstream;
063: /*
064: private PrinterJob printerJob;
065: private MediaSize mediaSize;
066: */
067: private String jobName;
068: private int copies;
069:
070: private final static int BANK_MAX_BYTES = 32768;
071:
072: /*
073: * static method to read images
074: */
075: public static Image readImage(InputStream source)
076: throws PrintException {
077: ArrayList banks = new ArrayList();
078: ArrayList bankLengths = new ArrayList();
079: Image image = null;
080: Toolkit toolkit;
081:
082: int bytesRead = 0;
083: int nBanks = 0;
084: int totalSize = 0;
085: byte[] byteImage;
086: byte[] buffer;
087:
088: try {
089: do {
090: buffer = new byte[BANK_MAX_BYTES];
091: bytesRead = source.read(buffer);
092: if (bytesRead > 0) {
093: banks.add(buffer);
094: bankLengths.add(new Integer(bytesRead));
095: totalSize += bytesRead;
096: }
097: } while (bytesRead >= 0);
098: source.close();
099: nBanks = banks.size();
100: byteImage = new byte[totalSize];
101: int k = 0;
102: for (int i = 0; i < nBanks; i++) {
103: buffer = (byte[]) banks.get(i);
104: int bufferLength = ((Integer) bankLengths.get(i))
105: .intValue();
106: for (int j = 0; j < bufferLength; j++) {
107: byteImage[k++] = buffer[j];
108: }
109: }
110: } catch (IOException ioe) {
111: throw new PrintException("Can't read print data.");
112: }
113:
114: toolkit = Toolkit.getDefaultToolkit();
115:
116: image = toolkit.createImage(byteImage);
117: while (!toolkit.prepareImage(image, -1, -1, null)
118: && (toolkit.checkImage(image, -1, -1, null) & (ImageObserver.ERROR | ImageObserver.ABORT)) == 0) {
119: try {
120: Thread.sleep(100);
121: } catch (InterruptedException ie) {
122: // Interrupted by user.
123: return (BufferedImage) null;
124: }
125: }
126: if (!toolkit.prepareImage(image, -1, -1, null)) {
127: throw new PrintException(
128: "Error while loading image (possibly, "
129: + "image format is not supported).");
130: }
131: BufferedImage bufferedImage = new BufferedImage(image
132: .getWidth(null), image.getHeight(null),
133: BufferedImage.TYPE_INT_ARGB);
134: Graphics graphics = bufferedImage.getGraphics();
135: graphics.drawImage(image, 0, 0, null);
136: return bufferedImage;
137: }
138:
139: protected All2PSDocPrintJob(StreamPrintService printService) {
140: super ();
141: begetPrintService = printService;
142: printJobListeners = new ArrayList();
143: printJobAttributeListeners = new ArrayList();
144: printJobAttributeSet = new HashPrintJobAttributeSet();
145: jobName = "PS printing";
146: copies = 1;
147: outstream = new PrintStream(printService.getOutputStream());
148: }
149:
150: /*
151: * Determines the PrintService object
152: * to which this print job object is bound.
153: * It's private field begetPrintService;
154: */
155: public PrintService getPrintService() {
156: return begetPrintService;
157: }
158:
159: /*
160: * Returns the print job attributes.
161: */
162: public PrintJobAttributeSet getAttributes() {
163: return printJobAttributeSet;
164: }
165:
166: /*
167: * Registers a listener for event occurring during this print job.
168: */
169: public void addPrintJobListener(PrintJobListener listener) {
170: if (listener != null) {
171: if (!printJobListeners.contains(listener)) {
172: printJobListeners.add(listener);
173: }
174: }
175: }
176:
177: /*
178: * Registers a listener for changes in the specified attributes
179: */
180: public void addPrintJobAttributeListener(
181: PrintJobAttributeListener listener,
182: PrintJobAttributeSet attributes) {
183:
184: if (listener != null) {
185: printJobAttributeListeners.add(listener);
186: }
187: printJobAttributeSet.addAll(attributes);
188: }
189:
190: public void removePrintJobAttributeListener(
191: PrintJobAttributeListener listener) {
192: printJobAttributeListeners.remove(listener);
193: }
194:
195: public void removePrintJobListener(PrintJobListener listener) {
196: printJobListeners.remove(listener);
197: }
198:
199: public void print(Doc doc, PrintRequestAttributeSet attributes)
200: throws PrintException {
201:
202: Object data;
203: DocFlavor docflavor;
204: String docflavorClassName;
205: Image image = null;
206: int x = 0;
207: int y = 0;
208: int width;
209: int height;
210: int iWidth;
211: int iHeight;
212: int newWidth;
213: int newHeight;
214: float scaleX;
215: float scaleY;
216:
217: synchronized (this ) {
218: if (action) {
219: throw new PrintException("printing is in action");
220: }
221: action = true;
222: }
223:
224: try { // for finally block. To make action false.
225:
226: docflavor = doc.getDocFlavor();
227: try {
228: data = doc.getPrintData();
229: } catch (IOException ioexception) {
230: throw new PrintException("no data for print: "
231: + ioexception.toString());
232: }
233: if (docflavor == null) {
234: throw new PrintException("flavor is null");
235: }
236: if (!begetPrintService.isDocFlavorSupported(docflavor)) {
237: throw new PrintException("invalid flavor :"
238: + docflavor.toString());
239: }
240:
241: docflavorClassName = docflavor.getRepresentationClassName();
242:
243: if (docflavor.equals(DocFlavor.INPUT_STREAM.GIF)
244: || docflavor.equals(DocFlavor.BYTE_ARRAY.GIF)
245: || docflavor.equals(DocFlavor.INPUT_STREAM.JPEG)
246: || docflavor.equals(DocFlavor.BYTE_ARRAY.JPEG)
247: || docflavor.equals(DocFlavor.INPUT_STREAM.PNG)
248: || docflavor.equals(DocFlavor.BYTE_ARRAY.PNG)) {
249: try {
250: image = readImage(doc.getStreamForBytes());
251: } catch (IOException ioe) {
252: throw new PrintException(ioe);
253: }
254: } else if (docflavor.equals(DocFlavor.URL.GIF)
255: || docflavor.equals(DocFlavor.URL.JPEG)
256: || docflavor.equals(DocFlavor.URL.PNG)) {
257: URL url = (URL) data;
258: try {
259: image = readImage(url.openStream());
260: } catch (IOException ioe) {
261: throw new PrintException(ioe);
262: }
263: } else if (docflavor
264: .equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
265: Printable printable = (Printable) data;
266: print(printable, null);
267: } else if (docflavor
268: .equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE)) {
269: Pageable pageable = (Pageable) data;
270: print(null, pageable);
271: } else {
272: throw new PrintException("Wrong DocFlavor class: "
273: + docflavorClassName);
274: }
275:
276: if (image != null) {
277: final PageFormat format = new PageFormat();
278: final Paper p = format.getPaper();
279:
280: MediaSize size = null;
281: if (attributes != null) {
282: if (attributes.containsKey(MediaSize.class)) {
283: size = (MediaSize) attributes
284: .get(MediaSize.class);
285: } else if (attributes
286: .containsKey(MediaSizeName.class)) {
287: MediaSizeName name = (MediaSizeName) attributes
288: .get(MediaSizeName.class);
289: size = MediaSize.getMediaSizeForName(name);
290: } else {
291: size = MediaSize
292: .getMediaSizeForName(MediaSizeName.ISO_A4);
293: }
294: } else {
295: size = MediaSize
296: .getMediaSizeForName(MediaSizeName.ISO_A4);
297: }
298: width = (int) (size.getX(MediaSize.INCH) * 72.0);
299: height = (int) (size.getY(MediaSize.INCH) * 72.0);
300: if (attributes != null) {
301: if (attributes
302: .containsValue(OrientationRequested.LANDSCAPE)) {
303: int temp = width;
304: width = height;
305: height = temp;
306: }
307: }
308: iWidth = image.getWidth(null);
309: iHeight = image.getHeight(null);
310: x = (width - iWidth) / 2;
311: y = (height - iHeight) / 2;
312: p.setSize(width, height);
313: p.setImageableArea(x, y, iWidth, iHeight);
314:
315: Graphics2D2PS graphics = new Graphics2D2PS(outstream,
316: format);
317: graphics.startPage(1);
318: if (x < 0 || y < 0) {
319: scaleX = (float) image.getWidth(null)
320: / (float) width;
321: scaleY = (float) image.getHeight(null)
322: / (float) height;
323: newWidth = width;
324: newHeight = height;
325:
326: if (scaleX > scaleY) {
327: newWidth = (int) ((float) iWidth / scaleX);
328: newHeight = (int) ((float) iHeight / scaleX);
329: x = 0;
330: y = (height - newHeight) / 2;
331: } else {
332: newWidth = (int) ((float) iWidth / scaleY);
333: newHeight = (int) ((float) iHeight / scaleY);
334: y = 0;
335: x = (width - newWidth) / 2;
336: }
337: graphics.drawImage(image, x, y, newWidth,
338: newHeight, null);
339: } else {
340: graphics.drawImage(image, x, y, null);
341: }
342: graphics.endOfPage(1);
343: graphics.finish();
344: }
345:
346: } finally {
347: synchronized (this ) {
348: action = false;
349: }
350: }
351: }
352:
353: private void print(Printable psPrintable, Pageable psDocument)
354: throws PrintException {
355: PageFormat format = null;
356: Graphics2D2PS converter = null;
357:
358: if (psPrintable == null && psDocument == null) {
359: return;
360: }
361:
362: if (psDocument == null) {
363: converter = new Graphics2D2PS(outstream);
364: format = null;
365: } else {
366: format = psDocument.getPageFormat(0);
367: converter = new Graphics2D2PS(outstream, format);
368: }
369:
370: Graphics2D2PS fake = new Graphics2D2PS(new PrintStream(
371: new OutputStream() {
372: public void write(int b) {
373: // Do nothing.
374: }
375: }));
376:
377: int iPage = 0;
378: int result = -1;
379: int pages = -1;
380: if (psDocument != null) {
381: pages = psDocument.getNumberOfPages();
382: }
383: do {
384: try {
385: Printable page = null;
386: PageFormat pageFormat = null;
387: result = -1;
388: if (psPrintable != null) {
389: page = psPrintable;
390: pageFormat = format;
391: result = psPrintable.print(fake, format, iPage);
392: } else {
393: if (pages != Pageable.UNKNOWN_NUMBER_OF_PAGES
394: && iPage >= pages) {
395: break;
396: }
397: page = psDocument.getPrintable(iPage);
398: pageFormat = psDocument.getPageFormat(iPage);
399: if (page != null) {
400: result = page.print(fake, pageFormat, iPage);
401: } else {
402: throw new PrinterException(
403: "No printable for page " + iPage
404: + " in given document.");
405: }
406: }
407: if (result == Printable.PAGE_EXISTS) {
408: converter.startPage(iPage + 1);
409: result = page.print(converter, pageFormat, iPage);
410: converter.endOfPage(iPage + 1);
411: }
412: } catch (PrinterException pe) {
413: converter.finish();
414: throw new PrintException(pe.getMessage());
415: }
416: iPage++;
417: } while (result == Printable.PAGE_EXISTS);
418: converter.finish();
419: }
420: }
|