This implements cancellable jobs, proper support for Pageable and also reverse landscape. Whatever people want that for.
It's still slow of course. /Sven 2006-05-15 Sven de Marothy <[EMAIL PROTECTED]> * gnu/java/awt/print/JavaPrinterGraphics.java: Sweeping changes I can't be bothered to document in detail. * gnu/java/awt/print/JavaPrinterJob.java (getPageAttributes): New method. (setPageable,cancel,isCancelled): Implement.
Index: gnu/java/awt/print/JavaPrinterGraphics.java =================================================================== RCS file: /sources/classpath/classpath/gnu/java/awt/print/JavaPrinterGraphics.java,v retrieving revision 1.3 diff -U3 -r1.3 JavaPrinterGraphics.java --- gnu/java/awt/print/JavaPrinterGraphics.java 13 May 2006 17:06:38 -0000 1.3 +++ gnu/java/awt/print/JavaPrinterGraphics.java 15 May 2006 01:35:09 -0000 @@ -37,6 +37,7 @@ package gnu.java.awt.print; +import java.awt.print.Pageable; import java.awt.print.PrinterGraphics; import java.awt.print.Printable; import java.awt.print.PrinterJob; @@ -85,11 +86,6 @@ private PrinterJob printerJob; /** - * The paper format. - */ - PageFormat pageFormat; - - /** * Rendering resolution */ private static final double DPI = 72.0; @@ -104,66 +100,96 @@ */ private Image image; - public JavaPrinterGraphics( PrinterJob printerJob, PageFormat pageFormat ) + public JavaPrinterGraphics( PrinterJob printerJob ) { this.printerJob = printerJob; - this.pageFormat = pageFormat; - - // Create a really big image and draw to that. - xSize = (int)(DPI*pageFormat.getWidth()/72.0); - ySize = (int)(DPI*pageFormat.getHeight()/72.0); - - // FIXME: This should at least be BufferedImage. Fix once we have a working B.I. - // Graphics2D should also be supported of course. - image = new GtkImage(xSize, ySize); - - initImage(); } /** - * The only method worthy of mention here. + * Spool a document to PostScript. + * If Pageable is non-null, it will print that, otherwise it will use + * the supplied printable and pageFormat. */ - public SpooledDocument spoolPostScript(Printable p) + public SpooledDocument spoolPostScript(Printable printable, + PageFormat pageFormat, + Pageable pageable) throws PrinterException - { - try - { - // spool to a temporary file - File temp = File.createTempFile("cpspool", ".ps"); - temp.deleteOnExit(); - - PrintWriter out = new PrintWriter - (new BufferedWriter + { + try + { + // spool to a temporary file + File temp = File.createTempFile("cpspool", ".ps"); + temp.deleteOnExit(); + + PrintWriter out = new PrintWriter + (new BufferedWriter (new OutputStreamWriter (new FileOutputStream(temp), "ISO8859_1"), 1000000)); - writePSHeader(out); - int status; - int index = 0; - while(p.print(this, pageFormat, index++) == Printable.PAGE_EXISTS) - { - g.dispose(); - g = null; - writePage( out ); - initImage(); - } - + writePSHeader(out); + + if(pageable != null) + { + for(int index = 0; index < pageable.getNumberOfPages(); index++) + spoolPage(out, pageable.getPrintable(index), + pageable.getPageFormat(index), index); + } + else + { + int index = 0; + while(spoolPage(out, printable, pageFormat, index++) == + Printable.PAGE_EXISTS); + } out.println("%%Trailer"); - out.println("grestore % restore original stuff"); out.println("%%EOF"); out.close(); return new SpooledDocument( temp ); } - catch (IOException e) - { - PrinterException pe = new PrinterException(); - pe.initCause(e); - throw pe; - } - } + catch (IOException e) + { + PrinterException pe = new PrinterException(); + pe.initCause(e); + throw pe; + } + } - private void initImage() + /** + * Spools a single page, returns NO_SUCH_PAGE unsuccessful, + * PAGE_EXISTS if it was. + */ + public int spoolPage(PrintWriter out, + Printable printable, + PageFormat pageFormat, + int index) throws IOException, PrinterException + { + initImage( pageFormat ); + if(printable.print(this, pageFormat, index) == Printable.NO_SUCH_PAGE) + return Printable.NO_SUCH_PAGE; + g.dispose(); + g = null; + writePage( out, pageFormat ); + return Printable.PAGE_EXISTS; + } + + private void initImage(PageFormat pageFormat) { + // Create a really big image and draw to that. + xSize = (int)(DPI*pageFormat.getWidth()/72.0); + ySize = (int)(DPI*pageFormat.getHeight()/72.0); + + // Swap X and Y sizes if it's a Landscape page. + if( pageFormat.getOrientation() != PageFormat.PORTRAIT ) + { + int t = xSize; + xSize = ySize; + ySize = t; + } + + // FIXME: This should at least be BufferedImage. + // Fix once we have a working B.I. + // Graphics2D should also be supported of course. + image = new GtkImage(xSize, ySize); + g = image.getGraphics(); setColor(Color.white); fillRect(0, 0, xSize, ySize); @@ -172,21 +198,11 @@ private void writePSHeader(PrintWriter out) { - Paper p = pageFormat.getPaper(); out.println("%!PS-Adobe-3.0"); out.println("%%Title: "+printerJob.getJobName()); out.println("%%Creator: GNU Classpath "); out.println("%%DocumentData: Clean8Bit"); - out.println("%%Orientation: "+ ((pageFormat.getOrientation() == - PageFormat.PORTRAIT) ? - "Portrait" : "Landscape")); - - // invert the Y axis so that we get screen-like coordinates instead. - AffineTransform pageTransform = new AffineTransform(); - pageTransform.translate(0.0, p.getHeight()); - pageTransform.scale(1.0,-1.0); - concatCTM(out, pageTransform); - + out.println("%%DocumentNeededResources: font Times-Roman Helvetica Courier"); // out.println("%%Pages: "+); // FIXME # pages. out.println("%%EndComments"); @@ -199,26 +215,54 @@ // E.g. "A4" "Letter" // out.println("%%BeginFeature: *PageSize A4"); - // 595x842; 612x792 respectively - out.println("<< /PageSize [" +p.getWidth() + " "+p.getHeight()+ "] >> setpagedevice"); out.println("%%EndFeature"); out.println("%%EndSetup"); // out.println("%%Page: 1 1"); - out.println("%%BeginPageSetup"); - - out.println("gsave % first save"); } - private void writePage(PrintWriter out) + private void writePage(PrintWriter out, PageFormat pageFormat) { - out.println("% writePage()"); + out.println("%%BeginPageSetup"); + + Paper p = pageFormat.getPaper(); + double pWidth = p.getWidth(); + double pHeight = p.getHeight(); + + if( pageFormat.getOrientation() == PageFormat.PORTRAIT ) + out.println( "%%Orientation: Portrait" ); + else + { + out.println( "%%Orientation: Landscape" ); + double t = pWidth; + pWidth = pHeight; + pHeight = t; + } + + out.println("gsave % first save"); + + // 595x842; 612x792 respectively + out.println("<< /PageSize [" +pWidth + " "+pHeight+ "] >> setpagedevice"); + + // invert the Y axis so that we get screen-like coordinates instead. + AffineTransform pageTransform = new AffineTransform(); + if( pageFormat.getOrientation() == PageFormat.REVERSE_LANDSCAPE ) + { + pageTransform.translate(pWidth, pHeight); + pageTransform.scale(-1.0, -1.0); + } + concatCTM(out, pageTransform); + out.println("%%EndPageSetup"); + out.println("gsave"); + + + // Draw the image out.println(xSize+" "+ySize+" 8 [1 0 0 -1 0 "+ySize+" ]"); out.println("{currentfile 3 string readhexstring pop} bind"); out.println("false 3 colorimage"); - int[] pixels = new int[xSize * ySize]; + int[] pixels = new int[xSize * ySize]; PixelGrabber pg = new PixelGrabber(image, 0, 0, xSize, ySize, pixels, 0, xSize); try { Index: gnu/java/awt/print/JavaPrinterJob.java =================================================================== RCS file: /sources/classpath/classpath/gnu/java/awt/print/JavaPrinterJob.java,v retrieving revision 1.1 diff -U3 -r1.1 JavaPrinterJob.java --- gnu/java/awt/print/JavaPrinterJob.java 13 May 2006 15:05:12 -0000 1.1 +++ gnu/java/awt/print/JavaPrinterJob.java 15 May 2006 01:35:09 -0000 @@ -49,6 +49,7 @@ import java.awt.print.PrinterJob; import java.awt.print.PrinterAbortException; import java.awt.print.PrinterException; +import javax.print.CancelablePrintJob; import javax.print.PrintService; import javax.print.PrintServiceLookup; import javax.print.DocFlavor; @@ -63,6 +64,7 @@ import javax.print.attribute.standard.Copies; import javax.print.attribute.standard.JobName; import javax.print.attribute.standard.RequestingUserName; +import javax.print.attribute.standard.OrientationRequested; /** * This is the default implementation of PrinterJob @@ -101,6 +103,16 @@ */ private PageFormat pageFormat; + /** + * A pageable, or null + */ + private Pageable pageable = null; + + /** + * Cancelled or not + */ + private boolean cancelled = false; + static { // lookup all services without any constraints @@ -123,6 +135,21 @@ pageFormat = new PageFormat(); // default page format. } + private void getPageAttributes() + { + OrientationRequested orientation = (OrientationRequested) + attributes.get( OrientationRequested.LANDSCAPE.getCategory() ); + if( orientation == null) + return; + + if( orientation.equals(OrientationRequested.PORTRAIT) ) + pageFormat.setOrientation(PageFormat.PORTRAIT); + else if( orientation.equals(OrientationRequested.LANDSCAPE) ) + pageFormat.setOrientation(PageFormat.LANDSCAPE); + else if( orientation.equals(OrientationRequested.REVERSE_LANDSCAPE) ) + pageFormat.setOrientation(PageFormat.REVERSE_LANDSCAPE); + } + /** * Returns the number of copies to be printed. * @@ -178,6 +205,17 @@ */ public void cancel() { + try + { + if(printJob != null && (printJob instanceof CancelablePrintJob)) + { + ((CancelablePrintJob)printJob).cancel(); + cancelled = true; + } + } + catch(PrintException pe) + { + } } /** @@ -188,7 +226,7 @@ */ public boolean isCancelled() { - return false; + return cancelled; } /** @@ -223,12 +261,15 @@ */ public void print() throws PrinterException { - if( printable == null ) + if( printable == null && pageable == null ) // nothing to print? return; - JavaPrinterGraphics pg = new JavaPrinterGraphics( this, pageFormat ); + JavaPrinterGraphics pg = new JavaPrinterGraphics( this ); + SpooledDocument doc = pg.spoolPostScript( printable, pageFormat, + pageable ); + + cancelled = false; printJob = printer.createPrintJob(); - SpooledDocument doc = pg.spoolPostScript( printable ); try { printJob.print(doc, attributes); @@ -239,6 +280,8 @@ p.initCause(pe); throw p; } + // no printjob active. + printJob = null; } /** @@ -277,6 +320,8 @@ (null, 50, 50, services, null, DocFlavor.INPUT_STREAM.POSTSCRIPT, attributes); + getPageAttributes(); + if( chosenPrinter != null ) { try @@ -299,7 +344,9 @@ */ public void setPageable(Pageable pageable) { - // FIXME + if( pageable == null ) + throw new NullPointerException("Pageable cannot be null."); + this.pageable = pageable; } /** @@ -323,7 +370,7 @@ public void setPrintable(Printable printable, PageFormat page_format) { this.printable = printable; - // FIXME + this.pageFormat = pageFormat; } /**