From 643e0b8b683629a6bd2e3a0744fa2a80b1490c97 Mon Sep 17 00:00:00 2001 From: tcarver <tjc> Date: Thu, 15 Nov 2012 12:19:54 +0000 Subject: [PATCH] add svg support --- art | 5 +- .../artemis/components/FeatureDisplay.java | 41 ++++- uk/ac/sanger/artemis/components/Plot.java | 26 ++- .../artemis/components/PrintArtemis.java | 166 +++++++++++++++--- 4 files changed, 195 insertions(+), 43 deletions(-) mode change 100755 => 100644 art diff --git a/art b/art old mode 100755 new mode 100644 index 16cf2c2af..16f98d7dd --- a/art +++ b/art @@ -6,8 +6,6 @@ # necessary a symbolic link can be made to this script from # /usr/local/bin/ or elsewhere. -# $Header: //tmp/pathsoft/artemis/art,v 1.26 2009-09-21 15:45:47 tjc Exp $ - # resolve links - $0 may be a link PRG=$0 progname=`basename $0` @@ -30,6 +28,9 @@ LIBDIR=/nfs/pathsoft/prod/javalibs CLASSPATH=$ARTEMIS_HOME:$ARTEMIS_HOME/lib/biojava.jar:$ARTEMIS_HOME/lib/jemAlign.jar:$ARTEMIS_HOME/lib/jakarta-regexp-1.2.jar:$ARTEMIS_HOME/lib/macos.jar:$ARTEMIS_HOME/lib/postgresql-8.4-701.jdbc3.jar:$CLASSPATH +# batik jars +CLASSPATH=$CLASSPATH:$ARTEMIS_HOME/lib/batik/batik-awt-util.jar:$ARTEMIS_HOME/lib/batik/batik-dom.jar:$ARTEMIS_HOME/lib/batik/batik-ext.jar:$ARTEMIS_HOME/lib/batik/batik-svggen.jar:$ARTEMIS_HOME/lib/batik/batik-util.jar:$ARTEMIS_HOME/lib/batik/batik-xml.jar + # j2ssh jars CLASSPATH=$CLASSPATH:$ARTEMIS_HOME/lib/j2ssh/commons-logging.jar:$ARTEMIS_HOME/lib/j2ssh/j2ssh-core.jar:$ARTEMIS_HOME/lib/j2ssh/ diff --git a/uk/ac/sanger/artemis/components/FeatureDisplay.java b/uk/ac/sanger/artemis/components/FeatureDisplay.java index 8c279573a..bc6cb235c 100644 --- a/uk/ac/sanger/artemis/components/FeatureDisplay.java +++ b/uk/ac/sanger/artemis/components/FeatureDisplay.java @@ -68,6 +68,8 @@ import javax.swing.UIManager; import javax.swing.ImageIcon; import javax.swing.JFrame; +import org.apache.batik.svggen.SVGGraphics2D; + /** * This component is used for displaying an Entry. * @@ -1890,8 +1892,19 @@ public class FeatureDisplay extends EntryGroupPanel // draw fwd bases if(getScaleFactor() == 0) - g.drawString(forward_visible_bases, offset * getFontWidth(), - yposition + getFontAscent() + 1); + { + if(!(g instanceof SVGGraphics2D)) + g.drawString(forward_visible_bases, offset * getFontWidth(), + yposition + getFontAscent() + 1); + else + { + // for svg graphics + for(int i=0;i<forward_visible_bases.length();i++) + g.drawString(String.valueOf(forward_visible_bases.charAt(i)), + (offset+i)*getFontWidth(), + yposition + getFontAscent() + 1); + } + } else { for(int base_index = 0; base_index < forward_sequence_length; @@ -1914,8 +1927,19 @@ public class FeatureDisplay extends EntryGroupPanel // draw bwd bases if(getScaleFactor() == 0) - g.drawString(reverse_visible_bases, offset * getFontWidth(), - yposition + getFontAscent() + 1); + { + if(!(g instanceof SVGGraphics2D)) + g.drawString(reverse_visible_bases, offset * getFontWidth(), + yposition + getFontAscent() + 1); + else + { + // for svg graphics + for(int i=0;i<reverse_visible_bases.length();i++) + g.drawString(String.valueOf(reverse_visible_bases.charAt(i)), + (offset+i)*getFontWidth(), + yposition + getFontAscent() + 1); + } + } else { for(int base_index = 0; base_index < reverse_sequence_length; @@ -2200,8 +2224,15 @@ public class FeatureDisplay extends EntryGroupPanel else draw_x_position = (int)((offset + frame_start + 1) * getScaleValue()); - g.drawString(codons, draw_x_position, + if(!(g instanceof SVGGraphics2D)) + g.drawString(codons, draw_x_position, draw_y_position + getFontAscent() + 1); + else + { + for(int i=0;i<codons.length();i++) + g.drawString(String.valueOf(codons.charAt(i)), draw_x_position+(i*getFontWidth() ), + draw_y_position + getFontAscent() + 1); + } } /** diff --git a/uk/ac/sanger/artemis/components/Plot.java b/uk/ac/sanger/artemis/components/Plot.java index 2063ea330..5a24f1de1 100644 --- a/uk/ac/sanger/artemis/components/Plot.java +++ b/uk/ac/sanger/artemis/components/Plot.java @@ -51,6 +51,8 @@ import javax.swing.JMenuItem; import javax.swing.JScrollBar; import javax.swing.JPopupMenu; +import org.apache.batik.svggen.SVGGraphics2D; + /** * This class implements a simple plot component. * @author Kim Rutherford @@ -682,11 +684,17 @@ public abstract class Plot extends JPanel if(offscreen == null || lastPaintHeight != height) offscreen = createImage(width, height); - Graphics og = offscreen.getGraphics(); - og.setClip(0, 0, width, height); - og.setColor(Color.WHITE); - og.fillRect(0, 0, width, height); - + final Graphics og; + if(g instanceof SVGGraphics2D) + og = g; + else + { + og = offscreen.getGraphics(); + og.setClip(0, 0, width, height); + og.setColor(Color.WHITE); + og.fillRect(0, 0, width, height); + } + // Redraw the graph on the canvas using the algorithm from the // constructor. @@ -703,8 +711,12 @@ public abstract class Plot extends JPanel numPlots = drawMultiValueGraph(og,lines); drawLabels(og,numPlots); - g.drawImage(offscreen, 0, 0, null); - og.dispose(); + + if( !(g instanceof SVGGraphics2D) ) + { + g.drawImage(offscreen, 0, 0, null); + og.dispose(); + } lastPaintHeight = height; } diff --git a/uk/ac/sanger/artemis/components/PrintArtemis.java b/uk/ac/sanger/artemis/components/PrintArtemis.java index f72fef4d4..4abd4784b 100644 --- a/uk/ac/sanger/artemis/components/PrintArtemis.java +++ b/uk/ac/sanger/artemis/components/PrintArtemis.java @@ -29,9 +29,24 @@ import java.awt.print.Printable; import java.awt.print.PrinterException; import java.awt.print.PrinterJob; import java.awt.event.*; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; +import java.io.Writer; + import javax.swing.*; -import java.io.*; +import org.apache.batik.dom.GenericDOMImplementation; +import org.apache.batik.svggen.SVGGeneratorContext; +import org.apache.batik.svggen.SVGGraphics2D; +import org.apache.batik.svggen.SVGGraphics2DIOException; +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Document; + +import uk.ac.sanger.artemis.Options; import uk.ac.sanger.artemis.editor.ScrollPanel; /** @@ -66,15 +81,45 @@ public class PrintArtemis extends ScrollPanel implements Printable } /** - * * Override paintComponent to draw entry - * */ - public void paintComponent(Graphics g) + public void paintComponent(Graphics g2d) { // let UI delegate paint first (incl. background filling) - super.paintComponent(g); - Graphics2D g2d = (Graphics2D)g.create(); + super.paintComponent(g2d); + + // feature list + if(featListDisplay.isSelected()) + { + FeatureList flist = entry.getFeatureList(); + Point ploc = flist.getViewport().getViewPosition(); + try + { + int translateX = 0; + if(selectDisplay.isSelected()) + translateX += entry.getSelectionInfoDisplay().getHeight(); + if(groupsDisplay.isSelected()) + translateX += entry.getEntryGroupDisplay().getHeight(); + if(plotsDisplay.isSelected()) + translateX += entry.getBasePlotGroup().getHeight(); + if(jamDisplay.isSelected() && entry.getBamPanel() != null && entry.getBamPanel().isVisible()) + translateX += entry.getBamPanel().getHeight()-1; + if(vcfDisplay.isSelected() && entry.getVcfView() != null && entry.getVcfView().isVisible()) + translateX += entry.getVcfPanel().getHeight(); + if(onelineDisplay.isSelected()) + translateX += entry.getOneLinePerEntryDisplay().getHeight(); + if(featDisplay.isSelected()) + translateX += entry.getFeatureDisplay().getHeight(); + if(baseDisplay.isSelected()) + translateX += entry.getBaseDisplay().getHeight(); + + translateX-=2+ploc.y; + g2d.translate(0,translateX); + flist.paintComponent(g2d); + g2d.translate(0,-translateX); + } + catch(IllegalArgumentException e){} // thrown if the list is not visible + } // selection info if(selectDisplay.isSelected()) @@ -128,24 +173,9 @@ public class PrintArtemis extends ScrollPanel implements Printable entry.getBaseDisplay().paintComponent(g2d); g2d.translate(0,entry.getBaseDisplay().getHeight()); } - - // feature list - if(featListDisplay.isSelected()) - { - FeatureList flist = entry.getFeatureList(); - Point ploc = flist.getViewport().getViewPosition(); - try - { - BufferedImage offScreen = new BufferedImage(flist.getViewport().getWidth(), - flist.getViewport().getHeight(), BufferedImage.TYPE_INT_RGB); - Graphics og = offScreen.getGraphics(); - og.translate(0,-ploc.y); - flist.paintComponent(og); - g2d.drawImage(offScreen, 0, 0, null); - } - catch(IllegalArgumentException e){} // thrown if the list is not visible - } } + + /** @@ -153,7 +183,7 @@ public class PrintArtemis extends ScrollPanel implements Printable * Set the size of the image * */ - private void setImageSize() + private Dimension getImageSize() { height = 0; width = entry.getFeatureDisplay().getDisplayWidth(); @@ -185,9 +215,14 @@ public class PrintArtemis extends ScrollPanel implements Printable if(featListDisplay.isSelected()) height += entry.getFeatureList().getViewport().getExtentSize().height; - setPreferredSize(new Dimension(width,height)); + return new Dimension(width,height); } + private void setImageSize() + { + setPreferredSize(getImageSize()); + } + /** * * Display a print preview page @@ -391,6 +426,15 @@ public class PrintArtemis extends ScrollPanel implements Printable f.setVisible(true); } + private String[] getImageFormats() + { + final String fmts[] = javax.imageio.ImageIO.getWriterFormatNames(); + final String tmpFmts[] = new String[fmts.length+1]; + System.arraycopy(fmts, 0, tmpFmts, 0, fmts.length); + tmpFmts[tmpFmts.length-1] = "svg"; + return tmpFmts; + } + /** * * Print to a jpeg or png file @@ -399,7 +443,7 @@ public class PrintArtemis extends ScrollPanel implements Printable public void print() { // file chooser - StickyFileChooser fc = new StickyFileChooser(); + final StickyFileChooser fc = new StickyFileChooser(); File fselect = new File(fc.getCurrentDirectory()+ System.getProperty("file.separator")+ "artemis.png"); @@ -413,9 +457,27 @@ public class PrintArtemis extends ScrollPanel implements Printable YBox.add(labFormat); Box bacross = Box.createHorizontalBox(); - JComboBox formatSelect = - new JComboBox(javax.imageio.ImageIO.getWriterFormatNames()); + final JComboBox formatSelect = new JComboBox(getImageFormats()); formatSelect.setSelectedItem("png"); + formatSelect.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent arg0) + { + String selected; + if(fc.getSelectedFile() != null) + { + selected = fc.getSelectedFile().getAbsolutePath(); + String fmts[] = getImageFormats(); + for(int i=0; i<fmts.length; i++) + selected = selected.replaceAll("."+fmts[i]+"$", ""); + } + else + selected = "artemis"; + + fc.setSelectedFile(new File(selected+"."+ + formatSelect.getSelectedItem())); + } + }); Dimension d = formatSelect.getPreferredSize(); formatSelect.setMaximumSize(d); @@ -488,6 +550,13 @@ public class PrintArtemis extends ScrollPanel implements Printable // remove file extension String fsave = fc.getSelectedFile().getAbsolutePath().toLowerCase(); + + if(fsave.endsWith(".svg")) + { + createSVG(fc.getSelectedFile()); + return; + } + if(fsave.endsWith(".png") || fsave.endsWith(".jpg") || fsave.endsWith(".jpeg") ) @@ -514,6 +583,45 @@ public class PrintArtemis extends ScrollPanel implements Printable } } + private void createSVG(final File fout) + { + final DOMImplementation domImpl = + GenericDOMImplementation.getDOMImplementation(); + final Document doc = domImpl.createDocument( + "http://www.w3.org/2000/svg", "svg", null); + + SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(doc); + ctx.setComment("Generated by Artemis with Batik SVG Generator"); + final SVGGraphics2D svgG = new SVGGraphics2D(ctx, true); + svgG.setFont(Options.getOptions().getFont()); + final FontMetrics fm = svgG.getFontMetrics(); + final Dimension d = getImageSize(); + svgG.setSVGCanvasSize( new Dimension( + d.width+fm.stringWidth(" "), d.height+fm.getHeight()) ); + paintComponent(svgG); + + try + { + final Writer out = new OutputStreamWriter( + new FileOutputStream(fout), "UTF-8"); + svgG.stream(out, true); + } + catch (UnsupportedEncodingException e) + { + e.printStackTrace(); + } + catch (SVGGraphics2DIOException e) + { + e.printStackTrace(); + } + catch (FileNotFoundException e) + { + e.printStackTrace(); + } + + return; + } + protected void doPrintActions() { final PrinterJob pj=PrinterJob.getPrinterJob(); @@ -575,7 +683,7 @@ public class PrintArtemis extends ScrollPanel implements Printable public int print(Graphics g, PageFormat pf, int pageIndex) throws PrinterException { setImageSize(); - Graphics2D g2 = (Graphics2D) g; + Graphics2D g2 = (Graphics2D)g.create(); // RepaintManager.currentManager(this).setDoubleBufferingEnabled(false); Dimension d = this.getSize(); //get size of document -- GitLab