Hi to all, some time ago I discovered that Batik was not able to support
multi-page printing with the PrintTranscoder. This resulted in the
impossibility to print with Java more than one SVG file on different page in
the same print job. Searching on Internet I discovered that a lot of people
had this problem. By investigating the code, I've found the problem in the
org.apache.batik.transcoder.print.PrintTranscoder class: the bug is in
the public int print(Graphics _g, PageFormat pageFormat, int pageIndex)
method and is very simple to fix. Change all the method with this one:

/**
  * Printable implementation
  */
 public int print(Graphics _g, PageFormat pageFormat, int pageIndex){
     //
     // On the first page, take a snapshot of the vector of
     // TranscodeInputs.
     //
     pageIndex = curIndex+1;

     if(printedInputs == null){
         printedInputs = new ArrayList( inputs );
     }

     //
     // If we have already printed each page, return
     //
     if(pageIndex >= printedInputs.size()){
         curIndex = -1;
         if (theCtx != null)
             theCtx.dispose();
         userAgent.displayMessage("Done");
         return NO_SUCH_PAGE;
     }

     //
     // Load a new document now if we are printing a new page
     //
     if(curIndex != pageIndex){
         if (theCtx != null)
             theCtx.dispose();

         // The following call will invoke this class' transcode
         // method which takes a document as an input. That method
         // builds the GVT root tree.{
         try{
             width  = (int)pageFormat.getImageableWidth();
             height = (int)pageFormat.getImageableHeight();
             super.transcode
                 ((TranscoderInput)printedInputs.get(pageIndex),null);

         }catch(TranscoderException e){
             drawError(_g, e);
             return PAGE_EXISTS;
         }
     }

     // Cast to Graphics2D to access Java 2D features
     Graphics2D g = (Graphics2D)_g;
     g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
     g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                        RenderingHints.VALUE_INTERPOLATION_BILINEAR);
     g.setRenderingHint(RenderingHintsKeyExt.KEY_TRANSCODING,
                        RenderingHintsKeyExt.VALUE_TRANSCODING_PRINTING);

     //
     // Compute transform so that the SVG document fits on one page
     //
     AffineTransform t = g.getTransform();
     Shape clip = g.getClip();

     // System.err.println("X/Y: " + pageFormat.getImageableX() + ", " +
     //                    pageFormat.getImageableY());
     // System.err.println("W/H: " + width + ", " + height);
     // System.err.println("Clip: " + clip.getBounds2D());

     // Offset 0,0 to the start of the imageable Area.
     g.translate(pageFormat.getImageableX(),
                 pageFormat.getImageableY());
     //
     // Append transform to selected area
     //
     g.transform(curTxf);

     //
     // Delegate rendering to painter
     //
     try{
         root.paint(g);
     }catch(Exception e){
         g.setTransform(t);
         g.setClip(clip);
         drawError(_g, e);
     }

     //
     // Restore transform and clip
     //
     g.setTransform(t);
     g.setClip(clip);

     // g.setPaint(Color.black);
     // g.drawString(uris[pageIndex], 30, 30);


     //
     // Return status indicated that we did paint a page
     //
     return PAGE_EXISTS;
 }


 If you compare the old method with this one, you'll find that the only
problems were the curIndex and pageIndex variables not updated. With this
fix you can do something like this:

import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Pageable;
import java.awt.print.Paper;

.....
PrinterJob job = PrinterJob.getPrinterJob();
PageFormat pf = job.defaultPage();
....

PrintTranscoder t = new PrintTranscoder();
PrintTranscoder t2 = new PrintTranscoder();

....Construct the two indipendent SVG transcoder....


Paper paper = new Paper();
paper.setSize(pf.getWidth(), pf.getHeight());
paper.setImageableArea(0.0,0.0,pf.getWidth(), pf.getHeight());

pf.setPaper(paper);

Book _book = new Book();
_book.append(t, pf);
_book.append(t2, pf);
job.setPageable( _book );
job.setCopies(1);
job.print();

 and the two SVG will be printed (through the new print() method in the
PrintTranscoder class) in two different pages in the same document.

 Please include the fix in the main source distribution for the next
release.

-- 
Diego

Reply via email to