0 Replies Latest reply: Mar 12, 2012 5:42 AM by 922380 RSS

    java printing : huge number of calls

    922380
      Ok, I know it is now documented that it is the normal api implementation to call multiple times the print function of a single Printable implementation and I can understand some of the key points( as stated "This is a requirement for banded raster printing in low-memory environments"), I alway see for truetype fonts at least 2 calls, no problem with that.

      But now let's consider you have to print a document using Type3 fonts, for which glyphs are in fact images.

      The following code simulate printing a single page (45 identical lines of the same 64 characters) using such glyphs, first begin with a 'preview' (only one call), then Ctrl-P to print.

      Running the sample on a standard computer (laser printer and 4gb memory : not a typical low-memory environment) takes 25 sec and need 2882 calls to print just a single page.

      I can't imagine anybody to use that sort of reasoning in a production environment.

      import java.awt.*;
      import java.awt.event.*;
      import java.awt.geom.*;
      import java.awt.image.*;
      import java.awt.print.*;
      import javax.swing.*;

      public class TestP
      {
           public static void main(String[] args)
           {
                glyphs=new Image[64];
                for(int i=0;i<glyphs.length;i++) {
                     glyphs=randomGlyph(32,32);
                }
                final JFrame f=new JFrame();
                f.addWindowListener(new WindowAdapter() {
                     public void windowClosing(WindowEvent e)
                     {
                          f.dispose();
                     }
                     public void windowClosed(java.awt.event.WindowEvent e)
                     {
                          System.exit(0);
                     }
                });
                f.add(new Page());
                f.setSize(400,400);
                f.setVisible(true);
           }
           static Image glyphs[];
           static Image randomGlyph(int width,int height)
           {
                BufferedImage img=java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage(width,height,java.awt.Transparency.TRANSLUCENT);
                for(int x=0;x<width;x++) {
                     for(int y=0;y<height;y++) {
                          if(((int)(Math.random()*100))%2==0) {
                               img.setRGB(x,y,Color.red.getRGB());
                          }
                     }
                }
                return(img);
           }
           static class Page extends JComponent
           {
                private static final long serialVersionUID=1L;
                Page()
                {
                     super();
                     getInputMap().put(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_P,java.awt.event.InputEvent.CTRL_MASK),
                          "Print"
                     );
                     getActionMap().put("Print",
                          new AbstractAction() {
                               private static final long serialVersionUID=1L;
                               public void actionPerformed(java.awt.event.ActionEvent ae)
                               {
                                    doPrint();
                               }
                          }
                     );
                }
                public void paintComponent(Graphics g)
                {
                     test((Graphics2D)g);
                }
           }
           static int counter;
           static void test(Graphics2D g)
           {
                Graphics2D g2d=(Graphics2D)g;
                int fontSize=10;
                g2d.translate(100,100);
                for(int y=0;y<45;y++) {
                     AffineTransform yat=g.getTransform();
                     for(int x=0;x<glyphs.length;x++) {
                          AffineTransform gat=g.getTransform();
                          g.scale(.01*fontSize,.01*fontSize);
                          g.drawImage(glyphs[x],0,0,null);
                          g.setTransform(gat);
                          g.translate(fontSize/2,0);
                     }
                     g.setTransform(yat);
                     g.translate(0,fontSize+2);
                }
                counter++;
           }
           static void doPrint()
           {
                PrinterJob job=PrinterJob.getPrinterJob();
                Book book=new Book();
                PageFormat format=new PageFormat();
                Paper paper=new Paper();
                paper.setSize(595,842);
                format.setPaper(paper);
                format.setOrientation(PageFormat.PORTRAIT);
                book.append(new PrintablePage(),format);
                job.setPageable(book);
                if(job.printDialog()) {
                     counter=0;
                     java.util.Date b=new java.util.Date();
                     try {
                          job.print();
                     }
                     catch(Exception e) {
                          e.printStackTrace();
                     }
                     java.util.Date e=new java.util.Date();
                     long time=e.getTime()-b.getTime();
                     long sec=time/1000;
                     long ms=time-sec*1000;
                     double seconds=((double)(sec))+((double)ms)/1000;
                     System.err.println("printing took "+seconds+" seconds and "+counter+" calls");
                }
           }
           static class PrintablePage implements Printable
           {
                public int print(Graphics g,PageFormat pageFormat,int pageIndex)
                {
                     test((Graphics2D)g);
                     return(Printable.PAGE_EXISTS);
                }          
           }
      }


      Anyway, any production-environment-acceptable solution ?