set PNG antialiasing on
[jalview.git] / src / jalview / gui / AlignmentPanel.java
1 package jalview.gui;\r
2 \r
3 import jalview.jbgui.GAlignmentPanel;\r
4 import jalview.schemes.*;\r
5 import jalview.analysis.*;\r
6 import jalview.datamodel.*;\r
7 import java.awt.*;\r
8 import java.awt.event.*;\r
9 import java.awt.print.*;\r
10 import java.io.*;\r
11 import java.awt.image.*;\r
12 import org.jibble.epsgraphics.*;\r
13 import javax.imageio.*;\r
14 \r
15 \r
16 \r
17 public class AlignmentPanel extends GAlignmentPanel implements AdjustmentListener, Printable\r
18 {\r
19 \r
20   AlignViewport     av;\r
21   OverviewPanel overviewPanel;\r
22   SeqPanel   seqPanel;\r
23   IdPanel    idPanel;\r
24   IdwidthAdjuster idwidthAdjuster;\r
25   public AlignFrame alignFrame;\r
26   ScalePanel scalePanel;\r
27   AnnotationPanel annotationPanel;\r
28   AnnotationLabels alabels;\r
29 \r
30   // this value is set false when selection area being dragged\r
31   boolean fastPaint = true;\r
32 \r
33   public AlignmentPanel(AlignFrame af, final AlignViewport av)\r
34   {\r
35     alignFrame = af;\r
36     this.av         = av;\r
37     seqPanel        = new SeqPanel  (av, this);\r
38     idPanel         = new IdPanel   (av, this);\r
39 \r
40     scalePanel = new ScalePanel(av, this);\r
41 \r
42     idPanelHolder.add(idPanel, BorderLayout.CENTER);\r
43     idwidthAdjuster = new IdwidthAdjuster(this);\r
44     idSpaceFillerPanel1.add(idwidthAdjuster, BorderLayout.CENTER);\r
45 \r
46     annotationPanel = new AnnotationPanel(this);\r
47     alabels = new AnnotationLabels(this);\r
48 \r
49     annotationSpaceFillerHolder.setPreferredSize(annotationPanel.getPreferredSize());\r
50     annotationScroller.setPreferredSize(annotationPanel.getPreferredSize());\r
51     annotationScroller.setViewportView(annotationPanel);\r
52     annotationSpaceFillerHolder.add(alabels, BorderLayout.CENTER);\r
53 \r
54     fontChanged();\r
55 \r
56     scalePanelHolder.add(scalePanel, BorderLayout.CENTER);\r
57     seqPanelHolder.add(seqPanel, BorderLayout.CENTER);\r
58 \r
59     setScrollValues(0, 0);\r
60 \r
61     hscroll.addAdjustmentListener(this);\r
62     vscroll.addAdjustmentListener(this);\r
63 \r
64    setFocusable(true);\r
65    addKeyListener(new KeyAdapter()\r
66    {\r
67      public void keyPressed(KeyEvent evt)\r
68      {\r
69        switch(evt.getKeyCode())\r
70        {\r
71          case  27: // escape key\r
72            av.setSelectionGroup(null);\r
73            repaint();\r
74            break;\r
75          case KeyEvent.VK_X:\r
76            if(evt.isControlDown())\r
77            alignFrame.cut_actionPerformed(null);\r
78            break;\r
79          case KeyEvent.VK_C:\r
80          if(evt.isControlDown())\r
81            alignFrame.copy_actionPerformed(null);\r
82            break;\r
83          case KeyEvent.VK_V:\r
84           if(evt.isControlDown())\r
85            alignFrame.paste(true);\r
86            break;\r
87          case KeyEvent.VK_A:\r
88          if(evt.isControlDown())\r
89            alignFrame.selectAllSequenceMenuItem_actionPerformed(null);\r
90            break;\r
91         case KeyEvent.VK_DOWN:\r
92           alignFrame.moveSelectedSequences(false);\r
93           break;\r
94         case KeyEvent.VK_UP:\r
95           alignFrame.moveSelectedSequences(true);\r
96           break;\r
97         case KeyEvent.VK_F:\r
98          if(evt.isControlDown())\r
99           alignFrame.findMenuItem_actionPerformed(null);\r
100           break;\r
101        }\r
102      }\r
103    });\r
104   }\r
105 \r
106   public void fontChanged()\r
107   {\r
108     // set idCanvas bufferedImage to null\r
109     // to prevent drawing old image\r
110     idPanel.idCanvas.gg = null;\r
111     annotationPanel.adjustPanelHeight();\r
112     Dimension d = calculateIdWidth();\r
113     d.setSize(d.width + 4, d.height);\r
114     idPanel.idCanvas.setPreferredSize(d);\r
115     hscrollFillerPanel.setPreferredSize(d);\r
116     repaint();\r
117   }\r
118 \r
119 \r
120   Dimension calculateIdWidth()\r
121   {\r
122     Graphics g = this.getGraphics();\r
123     if(g==null)\r
124     {\r
125       javax.swing.JFrame f = new javax.swing.JFrame();\r
126       f.addNotify();\r
127       g = f.getGraphics();\r
128     }\r
129 \r
130     FontMetrics fm = g.getFontMetrics(av.font);\r
131     AlignmentI al = av.getAlignment();\r
132 \r
133        int i   = 0;\r
134        int idWidth = 0;\r
135        String id;\r
136        while (i < al.getHeight() && al.getSequenceAt(i) != null)\r
137        {\r
138          SequenceI s   = al.getSequenceAt(i);\r
139          if(av.getShowFullId())\r
140            id   = s.getDisplayId();\r
141          else\r
142            id = s.getName();\r
143 \r
144          if (fm.stringWidth(id) > idWidth)\r
145            idWidth = fm.stringWidth(id);\r
146          i++;\r
147        }\r
148 \r
149        // Also check annotation label widths\r
150        i=0;\r
151        if(al.getAlignmentAnnotation()!=null)\r
152        {\r
153          fm = g.getFontMetrics(alabels.getFont());\r
154          while (i < al.getAlignmentAnnotation().length)\r
155          {\r
156            String label = al.getAlignmentAnnotation()[i].label;\r
157            if (fm.stringWidth(label) > idWidth)\r
158              idWidth = fm.stringWidth(label);\r
159            i++;\r
160          }\r
161        }\r
162 \r
163        return new Dimension(idWidth, 12);\r
164   }\r
165 \r
166 \r
167  public void highlightSearchResults(int [] results)\r
168  {\r
169    seqPanel.seqCanvas.highlightSearchResults( results );\r
170 \r
171    // do we need to scroll the panel?\r
172    if(results!=null && (av.getStartSeq()>results[0]\r
173                         || av.getEndSeq()<results[0]\r
174                         || av.getStartRes()>results[1]\r
175                         || av.getEndRes()<results[2]))\r
176        setScrollValues(results[1], results[0]);\r
177 \r
178 \r
179  }\r
180 \r
181 \r
182  public OverviewPanel getOverviewPanel()\r
183  {\r
184    return overviewPanel;\r
185  }\r
186 \r
187  public void setOverviewPanel(OverviewPanel op)\r
188  {\r
189    overviewPanel = op;\r
190  }\r
191 \r
192 \r
193   public void setAnnotationVisible(boolean b)\r
194   {\r
195     annotationSpaceFillerHolder.setVisible(b);\r
196     annotationScroller.setVisible(b);\r
197   }\r
198 \r
199 \r
200   public void setWrapAlignment(boolean wrap)\r
201   {\r
202     scalePanelHolder.setVisible(!wrap);\r
203     hscroll.setVisible(!wrap);\r
204     idwidthAdjuster.setVisible(!wrap);\r
205 \r
206     av.setShowAnnotation(!wrap);\r
207     annotationScroller.setVisible(!wrap);\r
208     annotationSpaceFillerHolder.setVisible(!wrap);\r
209     idSpaceFillerPanel1.setVisible(!wrap);\r
210 \r
211     repaint();\r
212 \r
213   }\r
214 \r
215 \r
216   public void setColourScheme()\r
217   {\r
218     ColourSchemeI cs = av.getGlobalColourScheme();\r
219 \r
220     if(av.getConservationSelected())\r
221     {\r
222 \r
223        Alignment al = (Alignment)av.getAlignment();\r
224        Conservation c = new Conservation("All",\r
225                             ResidueProperties.propHash, 3, al.getSequences(), 0,\r
226                             al.getWidth() );\r
227 \r
228        c.calculate();\r
229        c.verdict(false, av.ConsPercGaps);\r
230        ConservationColourScheme ccs = new ConservationColourScheme(c, cs);\r
231 \r
232        av.setGlobalColourScheme( ccs );\r
233 \r
234     }\r
235 \r
236     repaint();\r
237   }\r
238 \r
239 \r
240   int hextent = 0;\r
241   int vextent = 0;\r
242 \r
243   // return value is true if the scroll is valid\r
244   public boolean scrollUp(boolean up)\r
245   {\r
246     if(up)\r
247     {\r
248       if(vscroll.getValue()<1)\r
249         return false;\r
250       fastPaint  = false;\r
251       vscroll.setValue(vscroll.getValue() - 1);\r
252     }\r
253     else\r
254     {\r
255      if(vextent+vscroll.getValue() >= av.getAlignment().getHeight())\r
256        return false;\r
257       fastPaint  = false;\r
258       vscroll.setValue(vscroll.getValue() + 1);\r
259     }\r
260     fastPaint = true;\r
261     return true;\r
262   }\r
263 \r
264   public boolean scrollRight(boolean right)\r
265   {\r
266 \r
267     if (right)\r
268     {\r
269       if (hscroll.getValue() < 1)\r
270         return false;\r
271       fastPaint = false;\r
272       hscroll.setValue(hscroll.getValue() - 1);\r
273     }\r
274     else\r
275     {\r
276       if (hextent + hscroll.getValue() >= av.getAlignment().getWidth())\r
277         return false;\r
278       fastPaint = false;\r
279       hscroll.setValue(hscroll.getValue() + 1);\r
280     }\r
281     fastPaint = true;\r
282     return true;\r
283   }\r
284 \r
285 \r
286   public void setScrollValues(int x, int y)\r
287   {\r
288     av.setEndRes(x + seqPanel.seqCanvas.getWidth()/av.getCharWidth()-1);\r
289 \r
290     hextent = seqPanel.seqCanvas.getWidth()/av.charWidth;\r
291     vextent = seqPanel.seqCanvas.getHeight()/av.charHeight;\r
292 \r
293     if(hextent > av.alignment.getWidth())\r
294       hextent = av.alignment.getWidth();\r
295     if(vextent > av.alignment.getHeight())\r
296       vextent = av.alignment.getHeight();\r
297 \r
298     if(hextent+x  >  av.getAlignment().getWidth())\r
299       x =  av.getAlignment().getWidth()- hextent;\r
300 \r
301     if(vextent+y > av.getAlignment().getHeight())\r
302       y = av.getAlignment().getHeight() - vextent;\r
303 \r
304     if(y<0)\r
305       y = 0;\r
306 \r
307     if(x<0)\r
308       x=0;\r
309 \r
310     hscroll.setValues(x,hextent,0,av.getAlignment().getWidth());\r
311     vscroll.setValues(y,vextent,0,av.getAlignment().getHeight() );\r
312 \r
313 \r
314 \r
315   }\r
316 \r
317 \r
318   public void adjustmentValueChanged(AdjustmentEvent evt)\r
319   {\r
320     int oldX = av.getStartRes();\r
321     int oldY = av.getStartSeq();\r
322 \r
323     if (evt.getSource() == hscroll)\r
324     {\r
325       int x = hscroll.getValue();\r
326       av.setStartRes(x);\r
327       av.setEndRes(x + seqPanel.seqCanvas.getWidth()/av.getCharWidth()-1);\r
328     }\r
329 \r
330     if (evt.getSource() == vscroll)\r
331     {\r
332       int offy = vscroll.getValue();\r
333       if (av.getWrapAlignment())\r
334       {\r
335         int rowSize = seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());\r
336         av.setStartRes( vscroll.getValue() * rowSize );\r
337         av.setEndRes( (vscroll.getValue()+1) * rowSize );\r
338       }\r
339       else\r
340       {\r
341         av.setStartSeq(offy);\r
342         av.setEndSeq(offy + seqPanel.seqCanvas.getHeight() / av.getCharHeight());\r
343       }\r
344     }\r
345 \r
346     if(overviewPanel!=null)\r
347       overviewPanel.setBoxPosition();\r
348 \r
349     if(av.getWrapAlignment() || !fastPaint)\r
350       repaint();\r
351     else\r
352     {\r
353       idPanel.idCanvas.fastPaint(av.getStartSeq() - oldY);\r
354       seqPanel.seqCanvas.fastPaint(av.getStartRes() - oldX,\r
355                                    av.getStartSeq() - oldY);\r
356 \r
357       scalePanel.repaint();\r
358       if (av.getShowAnnotation())\r
359         annotationPanel.fastPaint(av.getStartRes() - oldX);\r
360     }\r
361 \r
362   }\r
363 \r
364 \r
365   public void paintComponent(Graphics g)\r
366   {\r
367     invalidate();\r
368     Dimension d = idPanel.idCanvas.getPreferredSize();\r
369     idPanelHolder.setPreferredSize(d);\r
370     hscrollFillerPanel.setPreferredSize(new Dimension(d.width, 12));\r
371     validate();\r
372 \r
373     if (av.getWrapAlignment())\r
374     {\r
375       int max = av.alignment.getWidth() / seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());\r
376       vscroll.setMaximum(max);\r
377       vscroll.setUnitIncrement(1);\r
378       vscroll.setVisibleAmount(1);\r
379     }\r
380     else\r
381     {\r
382       if (overviewPanel != null)\r
383         overviewPanel.updateOverviewImage();\r
384       setScrollValues(av.getStartRes(), av.getStartSeq());\r
385     }\r
386 \r
387 \r
388 \r
389   }\r
390 \r
391   public int print(Graphics pg, PageFormat pf, int pi) throws PrinterException\r
392   {\r
393     pg.translate((int)pf.getImageableX(), (int)pf.getImageableY());\r
394 \r
395     int pwidth = (int) pf.getImageableWidth();\r
396     int pheight = (int) pf.getImageableHeight();\r
397 \r
398     if (av.getWrapAlignment())\r
399       return printWrappedAlignment(pg, pwidth,pheight, pi);\r
400     else\r
401       return printUnwrapped(pg,pwidth, pheight,pi);\r
402   }\r
403 \r
404   public int printUnwrapped(Graphics pg, int pwidth, int pheight, int pi) throws PrinterException\r
405   {\r
406 \r
407     int idWidth = calculateIdWidth().width + 4;\r
408 \r
409 \r
410     pg.setColor(Color.white);\r
411     pg.fillRect(0,0,pwidth, pheight);\r
412     pg.setFont( av.getFont() );\r
413 \r
414     ////////////////////////////////////\r
415     /// How many sequences and residues can we fit on a printable page?\r
416     int totalRes = (pwidth - idWidth)/av.getCharWidth();\r
417     int totalSeq = (int)((pheight - 30)/av.getCharHeight())-1;\r
418     int pagesWide = av.getAlignment().getWidth() / totalRes +1;\r
419     int pagesHigh = av.getAlignment().getHeight() / totalSeq +1;\r
420 \r
421     if (pi >= pagesWide*pagesHigh)\r
422      return Printable.NO_SUCH_PAGE;\r
423 \r
424     /////////////////////////////\r
425     /// Only print these sequences and residues on this page\r
426     int startRes, endRes, startSeq, endSeq;\r
427     startRes = (pi % pagesWide) * totalRes;\r
428     endRes = startRes + totalRes-1;\r
429     if(endRes>av.getAlignment().getWidth())\r
430       endRes = av.getAlignment().getWidth();\r
431 \r
432      startSeq = (pi / pagesWide) * totalSeq;\r
433      endSeq = startSeq + totalSeq;\r
434      if(endSeq > av.getAlignment().getHeight())\r
435        endSeq = av.getAlignment().getHeight();\r
436 \r
437 \r
438     ////////////////\r
439     //draw Scale\r
440     pg.translate(idWidth,0);\r
441     scalePanel.drawScale(pg, startRes, endRes, pwidth-idWidth);\r
442 \r
443     pg.translate(-idWidth, 30);\r
444     ////////////////\r
445     // Draw the ids\r
446     Color currentColor=null;\r
447     Color currentTextColor=null;\r
448     for(int i=startSeq; i<endSeq; i++)\r
449     {\r
450       if (av.getSelectionGroup()!=null && av.getSelectionGroup().sequences.contains(av.getAlignment().getSequenceAt(i)))\r
451       {\r
452         currentColor = Color.gray;\r
453         currentTextColor = Color.black;\r
454       }\r
455       else\r
456       {\r
457         currentColor = av.getAlignment().getSequenceAt(i).getColor();\r
458         currentTextColor = Color.black;\r
459       }\r
460 \r
461       pg.setColor(currentColor);\r
462       pg.fillRect(0,  jalview.analysis.AlignmentUtil.getPixelHeight(startSeq, i, av.getCharHeight()),\r
463                               idWidth,\r
464                               av.getCharHeight());\r
465 \r
466       pg.setColor(currentTextColor);\r
467 \r
468       String string = av.getAlignment().getSequenceAt(i).getName();\r
469       if(av.getShowFullId())\r
470         string = av.getAlignment().getSequenceAt(i).getDisplayId();\r
471 \r
472       pg.drawString(string, 0,  jalview.analysis.AlignmentUtil.getPixelHeight\r
473                     (startSeq, i, av.getCharHeight()) + av.getCharHeight() - (av.getCharHeight() / 5));\r
474     }\r
475 \r
476     // draw main sequence panel\r
477     pg.translate(idWidth,0);\r
478     seqPanel.seqCanvas.drawPanel(pg,startRes,endRes,startSeq,endSeq,startRes,startSeq,0);\r
479 \r
480 \r
481     if(av.getShowAnnotation())\r
482       {\r
483         pg.translate(-idWidth,(endSeq-startSeq)*av.charHeight);\r
484         alabels.drawComponent((Graphics2D)pg);\r
485         pg.translate(idWidth,0);\r
486         annotationPanel.drawComponent((Graphics2D) pg, startRes, endRes+1);\r
487       }\r
488 \r
489     return Printable.PAGE_EXISTS;\r
490   }\r
491 \r
492 \r
493   public int printWrappedAlignment(Graphics pg, int pwidth, int pheight, int pi) throws PrinterException\r
494   {\r
495 \r
496     int idWidth = calculateIdWidth().width+4;\r
497 \r
498     if( seqPanel.seqCanvas.getWidth() < pwidth-idWidth)\r
499       pwidth = seqPanel.seqCanvas.getWidth() + idWidth;\r
500 \r
501 \r
502     pg.setColor(Color.white);\r
503     pg.fillRect(0,0,pwidth, pheight);\r
504     pg.setFont( av.getFont() );\r
505 \r
506     ////////////////////////////////////\r
507     /// How many sequences and residues can we fit on a printable page?\r
508     AlignmentI da = av.alignment;\r
509     int endy   = da.getHeight();\r
510     int chunkHeight =  (da.getHeight() + 2)*av.charHeight;\r
511     int chunkWidth  =   (pwidth-idWidth)/av.charWidth;\r
512 \r
513     int noChunksOnPage = pheight / chunkHeight;\r
514     int totalChunks = da.getWidth() / chunkWidth;\r
515 \r
516     if ( pi*noChunksOnPage > totalChunks )\r
517      return Printable.NO_SUCH_PAGE;\r
518 \r
519     ////////////////\r
520     // Draw the ids\r
521 //    pg.setClip(0,0,pwidth, noChunksOnPage*chunkHeight);\r
522 \r
523     pg.setColor(Color.black);\r
524 \r
525     int rowSize =  av.getEndRes() - av.getStartRes();\r
526     for(int ypos=2*av.charHeight, row=av.getEndRes()-rowSize;\r
527               ypos <= pheight && row<av.alignment.getWidth();\r
528               ypos += av.chunkHeight, row+=rowSize )\r
529     {\r
530       for (int i = 0; i < endy; i++)\r
531       {\r
532         SequenceI s = da.getSequenceAt(i);\r
533         String string = s.getName();\r
534         if (av.getShowFullId())\r
535           string = s.getDisplayId();\r
536 \r
537         pg.drawString(string, 0,\r
538                       AlignmentUtil.getPixelHeight(0, i, av.charHeight) + ypos +\r
539                       av.charHeight - (av.charHeight / 5));\r
540       }\r
541     }\r
542 \r
543     // draw main sequence panel\r
544     pg.translate(idWidth,0);\r
545     seqPanel.seqCanvas.drawWrappedPanel(pg, pwidth-idWidth, pheight, pi*noChunksOnPage*chunkWidth);\r
546 \r
547 \r
548     return Printable.PAGE_EXISTS;\r
549 \r
550   }\r
551 \r
552 \r
553   public void makeEPS()\r
554   {\r
555     int height = (av.alignment.getWidth() / av.getChunkWidth() +1) * av.chunkHeight;\r
556     int width = seqPanel.getWidth() + idPanel.getWidth();\r
557 \r
558     if (!av.getWrapAlignment())\r
559     {\r
560       height = (av.alignment.getHeight()+1) * av.charHeight + 30;\r
561       width = idPanel.getWidth() + av.alignment.getWidth() * av.charWidth;\r
562     }\r
563     if(av.getShowAnnotation())\r
564    {\r
565      height += annotationPanel.getPreferredSize().height;\r
566    }\r
567 \r
568     try\r
569     {\r
570       jalview.io.JalviewFileChooser chooser = new jalview.io.JalviewFileChooser(jalview.bin.Cache.getProperty(\r
571           "LAST_DIRECTORY"), new String[]{"eps"}, "Encapsulated Postscript");\r
572       chooser.setFileView(new jalview.io.JalviewFileView());\r
573       chooser.setDialogTitle("Create EPS file from alignment");\r
574       chooser.setToolTipText("Save");\r
575 \r
576       int value = chooser.showSaveDialog(this);\r
577       if (value != jalview.io.JalviewFileChooser.APPROVE_OPTION)\r
578         return;\r
579 \r
580       jalview.bin.Cache.setProperty("LAST_DIRECTORY",chooser.getSelectedFile().getPath());\r
581       FileOutputStream out = new FileOutputStream(chooser.getSelectedFile());\r
582       EpsGraphics2D pg = new EpsGraphics2D("Example", out, 0, 0, width, height);\r
583 \r
584         if (av.getWrapAlignment())\r
585           printWrappedAlignment(pg, width, height, 0);\r
586         else\r
587           printUnwrapped(pg, width, height, 0);\r
588 \r
589 \r
590         pg.flush();\r
591         pg.close();\r
592     }\r
593     catch (Exception ex)\r
594     {\r
595       ex.printStackTrace();\r
596     }\r
597   }\r
598 \r
599   public void makePNG()\r
600   {\r
601       int height = (av.alignment.getWidth() / av.getChunkWidth() +1) * av.chunkHeight;\r
602       int width = seqPanel.getWidth() + idPanel.getWidth();\r
603 \r
604       if (!av.getWrapAlignment())\r
605       {\r
606         height = (av.alignment.getHeight()+1) * av.charHeight + 30;\r
607         width = idPanel.getWidth() + av.alignment.getWidth() * av.charWidth;\r
608       }\r
609 \r
610       if(av.getShowAnnotation())\r
611       {\r
612         height += annotationPanel.getPreferredSize().height;\r
613       }\r
614 \r
615 \r
616 \r
617     try\r
618     {\r
619       jalview.io.JalviewFileChooser chooser = new jalview.io.JalviewFileChooser(jalview.bin.Cache.getProperty(\r
620           "LAST_DIRECTORY"), new String[]{"png"}, "Portable network graphics");\r
621       chooser.setFileView(new jalview.io.JalviewFileView());\r
622       chooser.setDialogTitle("Create EPS file from alignment");\r
623       chooser.setToolTipText("Save");\r
624 \r
625       int value = chooser.showSaveDialog(this);\r
626       if (value != jalview.io.JalviewFileChooser.APPROVE_OPTION)\r
627         return;\r
628 \r
629       jalview.bin.Cache.setProperty("LAST_DIRECTORY",chooser.getSelectedFile().getPath());\r
630       FileOutputStream out = new FileOutputStream(chooser.getSelectedFile());\r
631 \r
632       BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);\r
633       Graphics2D png = (Graphics2D)bi.getGraphics();\r
634 \r
635       png.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);\r
636 \r
637         if (av.getWrapAlignment())\r
638           printWrappedAlignment(png, width, height, 0);\r
639         else\r
640           printUnwrapped(png, width, height, 0);\r
641 \r
642         ImageIO.write(bi, "png", out);\r
643         out.close();\r
644     }\r
645     catch (Exception ex)\r
646     {\r
647       ex.printStackTrace();\r
648     }\r
649   }\r
650 \r
651 }\r
652 \r
653 \r
654 \r
655 \r