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;
   }
 
   /**

Reply via email to