1    import java.awt.event.*;
2    import java.awt.*;
3    import java.awt.geom.*;
4    import java.util.*;
5    import java.io.*;
6    import java.awt.print.*;
7    import java.awt.image.*;
8    import javax.swing.*;
9    import java.lang.ref.*;
10   //import org.freehep.graphics2d.*;
11   import java.awt.event.*;
12   import java.awt.*;
13   import java.util.*;
14   
15   public class Print extends PrefEditor implements Serializable,Printable,Pageable,ActionListener {
16     private static final long serialVersionUID = Version.getSUID();
17   
18     public static Print printer =null;
19   
20     public boolean oldpng = true;
21     public boolean fhpng = false;
22     public boolean fhjpg = false;
23     public boolean fhgif = false;
24     public boolean fhpdf = false;
25     public boolean fhps = false;
26     public boolean fhsvg = false;
27     public boolean fhswf = false;
28     public boolean jprinter = false;
29   
30     public boolean onefile = false;
31     public File file = null;
32   
33     public int compress = 3;
34   
35   //  transient int[] reserve;
36   //  public int rsize=0;
37   
38     transient JLabel filelab = null;
39     public transient Vector jobpages = null;
40   //  public Vector ipages = new Vector();
41     public static PageFormat format = PrinterJob.getPrinterJob().defaultPage();
42   //  public SavableRectangle2D pagerect = new SavableRectangle2D(Page.getDefaultBox());
43   
44     public static int sliceincrement = 2;
45     public static double imagescale = 1.0/5000;
46   
47     public Print() {
48       name = "Print";
49     }
50   
51     public void newPane() throws NoSuchFieldException {
52       pane = new javax.swing.Box(BoxLayout.Y_AXIS);
53   //    pane.setLayout(new GridLayout(4,1));
54       ButtonGroup group = new ButtonGroup();
55       pane.add(new JLabel("Carto's own implementation:"));
56       JPanel pbox = new JPanel();
57       pbox.setLayout(new BoxLayout(pbox,BoxLayout.X_AXIS));
58   
59       group.add(setRadio(pbox,"oldpng","Old png"));
60       setParm(pbox,"compress","compression (0-10)");
61       pane.add(pbox);
62   //    setParm(pane,"rsize","Memory reserve (for debug)");
63       pane.add(new JLabel("graphics implementation from freehep:"));
64       pane.add(new JLabel("Very experimental! Do not use yet."));
65       group.add(setRadio(pane,"fhpng","png"));
66       group.add(setRadio(pane,"fhjpg","jpg"));
67       group.add(setRadio(pane,"fhgif","gif"));
68       group.add(setRadio(pane,"fhsvg","svg"));
69       group.add(setRadio(pane,"fhswf","swf"));
70       group.add(setRadio(pane,"fhpdf","pdf"));
71       group.add(setRadio(pane,"fhps","postscript"));
72       pane.add(new JLabel("Printing that comes with java:"));
73       group.add(setRadio(pane,"jprinter","Java printing"));
74       pane.add(new JLabel(" "));
75       
76       setParm(pane,"onefile","Print to one file (not implemented)");
77       pbox = new JPanel();
78       pbox.setLayout(new BoxLayout(pbox,BoxLayout.X_AXIS));
79   
80       if (file==null)
81         filelab = new JLabel("");
82       else filelab = new JLabel(file.getName());
83       pbox.add(filelab);
84   
85       JButton filebutton = new JButton("Change File (not implemented)");
86       filebutton.addActionListener(this);
87       pbox.add(filebutton);
88       pane.add(pbox);
89     }
90   
91     public void actionPerformed(ActionEvent e) {
92       file = pickFile();
93       filelab.setText(file.getName());
94     }
95   
96     public static File pickFile() {
97       JFileChooser choose = Persist.current.getFileChooser();
98   
99       choose.setFileFilter(new FileTypes(FileTypes.PRINT));
100      choose.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
101      choose.rescanCurrentDirectory();
102      if (choose.showOpenDialog(null)!=choose.APPROVE_OPTION) {
103        Persist.current.clearChooser();
104        return(null);
105      }
106      File res = choose.getSelectedFile();
107      Persist.current.clearChooser();
108      return(res);
109    }
110  
111    public void save() {
112      if (pane==null) return;
113      super.save();
114      apply();
115    }
116  
117    public void apply() {
118      Print.printer = this;
119      PngEncoder.compress = compress;
120    }
121  
122    public void printAll(Carto source,ThreadMessage status) {
123      Vector pages = new Vector();
124      for (Iterator it = source.complist.iterator();it.hasNext();) {
125        Comp comp = (Comp)it.next();
126        Set cpages = comp.getPages();
127        for (Iterator pit = cpages.iterator();pit.hasNext();) {
128          Page p = (Page)pit.next();
129          if (p.image)
130            pages.add(p);
131        }
132      }
133  
134      if (pages.size()==0) ErrorLog.log("No pages have prinitng enabled.");
135      printPages(source,pages,status);
136    }
137  
138    public void printSelected(CartoFrame source,ThreadMessage status) {
139      Vector pages = new Vector();
140      Editor ed = source.lastselected;
141      if (ed instanceof CompEditor) 
142        for (Iterator it = ((CompEditor)ed).pane.sel.selection.iterator();it.hasNext();) {
143          Symbol p = (Symbol)it.next();
144          if (p instanceof Page) pages.add(p);
145        }
146  
147      if (pages.size()==0) ErrorLog.log("No pages are selected.");
148      System.out.println("pages = "+pages.size());
149      printPages(source.carto,pages,status);
150    }
151  
152    public void printPages(Carto source,Vector pages,ThreadMessage status) {
153  //    reserve = new int[rsize/4];
154      if (oldpng) iPrint(source,pages,status);
155      else if (fhps|fhpng|fhjpg|fhgif|fhpdf|fhsvg|fhswf) hepPrint(source,pages,status);
156      else if (jprinter) pPrint(source,pages,status);    
157    }
158  
159    public static void printSetup() {
160      PrinterJob job = PrinterJob.getPrinterJob();
161      format = job.pageDialog(format);
162    }
163  
164  
165    public void hepPrint(final Carto source,final Vector pages,final ThreadMessage status) {
166  /*    System.out.println("hepPrint");
167      Carto.startBackground(
168        (new Thread() {
169            public void run() {
170              System.out.println("thread started");
171              Page p=null;
172              try {
173                for (Iterator pit = pages.iterator();pit.hasNext();) {
174          	if (Carto.kill==Carto.PRINTKILL) break;
175          	p = (Page)pit.next();
176          	System.out.println("page = "+p);
177          	VectorGraphics2D gr = null;
178          	Dimension size = null;
179          	Rectangle rect = null;
180          	if (fhps || fhpdf){
181          	  size = p.getPSSize(source.mapunit);
182          	  rect = new Rectangle(0,0,(int)(72*size.getWidth()),
183          					 (int)(72*size.getHeight()));
184          	  if (fhps)
185          	    gr = new PSGraphics2D(p.getFile(),rect);
186          	  else
187          	    gr = new PDFGraphics2D(p.getFile(),rect);
188          	}
189          	else if (fhgif||fhjpg|fhpng|fhsvg) {
190          	  size = p.getSize(source.mapunit);
191          	  rect = new Rectangle(0,0,(int)size.getWidth(),
192          					 (int)size.getHeight());
193          	  if (fhgif)
194          	    gr = new GIFGraphics2D(p.getFile(),rect);
195          	  if (fhjpg)
196          	    gr = new GIFGraphics2D(p.getFile(),rect);
197          	  if (fhpng)
198          	    gr = new GIFGraphics2D(p.getFile(),rect);
199          	  if (fhsvg)
200          	    gr = new SVGGraphics2D(p.getFile(),rect);
201          	  if (fhswf)
202          	    gr = new SWFGraphics2D(p.getFile(),rect);
203          	}
204          	if (gr==null) return;
205          	System.out.println("size = "+size);
206          	gr.writeHeader();
207                  status.setText("Printing "+p.file.getName());
208          	View view = new View();
209          	view.mapunit = source.mapunit;
210          	view.wait = true;
211          	view.draw = gr;
212          	view.setClip(rect);
213          	view.draw.setColor(Color.black);
214          	if (Carto.kill==Carto.PRINTKILL) break;
215          	
216          	p.print(view,p.getFormat(view.mapunit),size.height);
217          	if (Carto.kill==Carto.PRINTKILL) break;
218  
219          	gr.donePrinting();
220                }
221              } catch (Throwable e) {
222                ErrorLog.exception(e,"Error while printing to image file:"+p.getFile());
223              } finally {
224                status.setText("");
225                Carto.cleanBackground();
226              }
227            }}));
228  */
229    }
230  
231  
232    public void pPrint(final Carto source,final Vector pages,final ThreadMessage status) {
233      jobpages = pages;
234      PrinterJob job = PrinterJob.getPrinterJob();
235      if (!job.printDialog()) return;
236      job.setPageable(this);
237      try {
238        job.print();
239      } catch (Throwable e) {
240        ErrorLog.exception(e,"error printing (to printer)");
241      }
242      jobpages = null;
243    }
244  
245    public void iPrint(final Carto source,final Vector pages,final ThreadMessage status) {
246      System.out.println("iPrint pagers = "+pages);
247      Carto.startBackground(
248        (new Thread() {
249            public void run() {
250              try {
251                for (Iterator pit = pages.iterator();pit.hasNext();) {
252          	Page p = (Page)pit.next();
253          	FileOutputStream stream = null;
254                  status.setText("Printing "+p.file.getName());
255      System.out.println("Printing "+p.file.getName());
256  
257          	View view = null;
258          	Dimension size = p.getSize(source.mapunit);
259          	PngEncoder encode=null;
260          	for (int slices=1; slices!=0&&slices<size.height;slices*=sliceincrement) {
261          	  try {
262          	    stream = new FileOutputStream(p.getFile());
263          	    encode = new PngEncoder(size.width,size.height,stream);
264  
265          	    encode.start();
266          	    for (int slice = 0;slice<slices;slice++) {
267          	      BufferedImage pageimage;
268          	      try {
269          		view = new View();
270          		view.wait = true;
271          		view.mapunit = source.mapunit;
272          		int low = (slice*size.height)/slices;
273          		int high = ((slice+1)*size.height)/slices;
274  
275          		pageimage = new BufferedImage(size.width,high-low,
276          					     BufferedImage.TYPE_INT_ARGB);
277          		view.draw = pageimage.createGraphics();
278          		view.draw.setColor(Color.white);
279          		view.draw.fillRect(0,0,size.width,high-low);
280          		view.draw.setClip(new Rectangle(0,0,size.width,high-low));
281          		view.draw.setColor(Color.black);
282          		
283          		p.print(view,p.getFormat(view.mapunit),low);
284          		
285          		encode.addSlice(pageimage,status,"Compressing "+p.file.getName()+
286          				(slices>1?(" slice "+(slice+1)+" (of "+slices+") "):" "));
287          	      } finally {
288          		pageimage = null;
289          		view.draw = null;
290          		System.gc();
291          	      }
292          	    }
293          	    encode.finish();
294          	    slices = 0;
295          	  } catch (OutOfMemoryError e) {
296          	    encode.clean();
297          	    stream = null;
298          	    status.setText("Cutting "+p.file.getName()+" into "+(slices*sliceincrement)+" slices");
299          	    encode =null;
300          	    System.gc();
301          	    System.gc();
302          	    System.gc();
303          	    System.gc();
304          	  } finally {
305          	    encode=null;
306          	    if (stream!=null) {
307          	      stream.close();
308          	      stream=null;
309          	    }
310          	  }
311          	}
312                }
313              } catch (CookKillException killex) {
314              } catch (Throwable e) {
315                ErrorLog.exception(e,"Error while printing to image file");
316              } finally {
317                status.setText("");
318                Carto.cleanBackground();
319              }
320            }}));
321    }
322  
323    public void preview() {
324  /*    PageFormat format = PrinterJob.getPrinterJob().defaultPage();
325      for (Iterator it = carto.complist.iterator();it.hasNext();) {
326        Comp comp = (Comp)it.next();
327        Set cpages = comp.getPages();
328        for (Iterator pit = cpages.iterator();pit.hasNext();) {
329          Page p = (Page)pit.next();
330                 View view = new View();
331          view.printing=true;
332          JFrame frame = new JFrame();
333          frame.getContentPane().add(new Previewer(p,format));
334          frame.setSize(400,400);
335          frame.show();
336        }
337        }*/
338    }
339  
340    public int getNumberOfPages() {
341      if (format==null) format = PrinterJob.getPrinterJob().defaultPage();
342  //    getAllPages();
343      return(jobpages.size());
344    }
345  
346    public Printable getPrintable(int pageindex) {return(this);}
347  
348    public PageFormat getPageFormat(int pageindex) {return(format);}
349  
350    public int print(Graphics g,PageFormat format,int pageindex) {
351      if (pageindex>=jobpages.size()) return(Printable.NO_SUCH_PAGE);
352      View view = new View();
353      view.wait = true;
354      view.draw = (Graphics2D)g;
355      view.printing=true;
356      AffineTransform oldtrans = new AffineTransform(view.draw.getTransform());
357      ((Page)jobpages.elementAt(pageindex)).print(view,format);
358      ((Graphics2D)g).setTransform(oldtrans);
359      return(Printable.PAGE_EXISTS);
360    }
361  }
362