package org.activiti.crystalball.diagram.svg; import org.activiti.crystalball.diagram.ImageTypes; import org.activiti.crystalball.diagram.ProcessDiagramCanvas; import org.activiti.engine.ActivitiException; import org.apache.batik.dom.GenericDOMImplementation; import org.apache.batik.svggen.SVGGraphics2D; import org.apache.batik.svggen.SVGGraphics2DIOException; import org.apache.batik.transcoder.TranscoderException; import org.apache.batik.transcoder.TranscoderInput; import org.apache.batik.transcoder.TranscoderOutput; import org.apache.batik.transcoder.image.ImageTranscoder; import org.apache.batik.transcoder.image.JPEGTranscoder; import org.apache.batik.transcoder.image.PNGTranscoder; import org.apache.batik.transcoder.image.TIFFTranscoder; import org.w3c.dom.DOMImplementation; import org.w3c.dom.Document; import java.awt.*; import java.io.*; /** * SVG implementation of process diagram canvas. */ public class SVGProcessDiagramCanvas extends ProcessDiagramCanvas{ public SVGProcessDiagramCanvas(int width, int height) { this(width, height, -1, -1); } public SVGProcessDiagramCanvas(int width, int height, int minX, int minY) { super(width, height, minX, minY); DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation(); // Create an instance of org.w3c.dom.Document. String svgNS = "http://www.w3.org/2000/svg"; Document document = domImpl.createDocument(svgNS, "svg", null); this.g = new SVGGraphics2D( document ); ((SVGGraphics2D) this.g).setSVGCanvasSize( new Dimension( canvasWidth, canvasHeight)); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setPaint(Color.black); Font font = new Font("Arial", Font.BOLD, FONT_SIZE); g.setFont(font); } @Override public InputStream generateImage(String imageType) { if (closed) { throw new ActivitiException("ProcessDiagramGenerator already closed"); } // Create the transcoder input. ByteArrayOutputStream ostream = null; ByteArrayOutputStream out = new ByteArrayOutputStream(); Writer writer = null; InputStream in = null; TranscoderOutput output = null; try { writer = new OutputStreamWriter(out, "UTF-8"); ((SVGGraphics2D) g).stream(writer); } catch (SVGGraphics2DIOException e) { try { writer.close(); } catch (IOException e1) { } throw new ActivitiException("Unable to generate image", e); } catch (UnsupportedEncodingException e) { throw new ActivitiException("Unsupported encoding for output stream", e); } in = new ByteArrayInputStream(out.toByteArray()); if ((ImageTypes.SVG.equalsType(imageType))) { // SVG image is generated return in; } // Use trascoder to generate "real" image ostream = new ByteArrayOutputStream(); TranscoderInput input = new TranscoderInput(in); // Create the transcoder output. output = new TranscoderOutput(ostream); // Save the image. ImageTranscoder t = null; if (ImageTypes.JPG.equalsType(imageType)) { // Create a JPEG transcoder t = new JPEGTranscoder(); // Set the transcoding hints. t.addTranscodingHint(JPEGTranscoder.KEY_QUALITY, new Float(.8)); } else if (ImageTypes.PNG.equalsType(imageType)) { t = new PNGTranscoder(); } else if (ImageTypes.TIFF.equalsType(imageType)) { t = new TIFFTranscoder(); } try { t.transcode(input, output); return new ByteArrayInputStream(ostream.toByteArray()); } catch (TranscoderException e) { throw new ActivitiException("Unable to transcode image", e); } finally { try { if (ostream != null) { ostream.flush(); ostream.close(); } if (!ImageTypes.SVG.equalsType(imageType)) // close in stream only in the case when it is not needed anymore in.close(); writer.close(); } catch (IOException e) { e.printStackTrace(); } } } }