package de.latlon.deejump.plugin.style; import static org.apache.batik.transcoder.SVGAbstractTranscoder.KEY_HEIGHT; import static org.apache.batik.transcoder.SVGAbstractTranscoder.KEY_WIDTH; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Toolkit; import java.awt.geom.Point2D; import java.awt.image.BufferedImage; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import java.net.MalformedURLException; import javax.media.jai.JAI; import javax.media.jai.RenderedOp; import org.apache.batik.transcoder.TranscoderException; import org.apache.batik.transcoder.TranscoderInput; import org.apache.batik.transcoder.TranscoderOutput; import org.apache.batik.transcoder.image.PNGTranscoder; import com.sun.media.jai.codec.MemoryCacheSeekableStream; import com.vividsolutions.jump.workbench.ui.renderer.style.VertexStyle; /** * <code>BitmapVertexStyle</code> * * @author <a href="mailto:schmitz@lat-lon.de">Andreas Schmitz</a> * @author last edited by: $Author: stranger $ * * @version $Revision: 1528 $, $Date: 2008-02-14 14:37:00 +0100 (Thu, 14 Feb * 2008) $ */ public class BitmapVertexStyle extends VertexStyle { private Image image; private Point2D point; private String fileName; /** * */ public BitmapVertexStyle() { // for java2xml } /** * @param fileName */ public BitmapVertexStyle(String fileName) { // init with a this.shape = poly with 1 point (?) super(null); if (fileName == null) { throw new NullPointerException("Image URL cannot be null."); } setFileName(fileName); } @Override public void paint(Graphics2D g, Point2D p) { // don't use this, use this.shape // this.polygon.xpoints = new int [] { (int) p.getX()}; // this.polygon.ypoints = new int [] { (int) p.getY() }; // this.polygon.npoints=1; this.point = p; render(g); } @Override protected void render(Graphics2D g) { g.drawImage(image, (int) point.getX() - ((image.getWidth(null)) / 2), (int) point.getY() - ((image.getHeight(null)) / 2), null); } /** * @return the image */ public Image getImage() { return image; } /** * @return the image */ public String getFileName() { return fileName; } @Override public void setFillColor(Color c) { super.setFillColor(c); if (fileName.toLowerCase().endsWith(".svg")) { setFileName(fileName); } } @Override public void setLineColor(Color c) { super.setLineColor(c); if (fileName.toLowerCase().endsWith(".svg")) { setFileName(fileName); } } @Override public void setSize(int size) { super.setSize(size); if (fileName != null && fileName.toLowerCase().endsWith(".svg")) { setFileName(fileName); } } /** * @param col * @return a #rrggbb string */ public static String toHexColor(Color col) { if (col == null) { col = Color.black; } String scol = Integer.toHexString(col.getRGB() & 0xffffff); while (scol.length() < 6) { scol = "0" + scol; } return "#" + scol; } // due to the lack of xpaths, this is VERY crude /** * @param file * @param stroke * @param fill * @return the new svg code * @throws IOException */ public static StringBuffer updateSVGColors(File file, String stroke, String fill) throws IOException { BufferedReader in = new BufferedReader(new FileReader(file)); StringWriter sout = new StringWriter((int) file.length()); PrintWriter out = new PrintWriter(sout); String s; while ((s = in.readLine()) != null) { s = s.replace("fill:#000000", "fill:" + fill); s = s.replace("fill:black", "fill:" + fill); s = s.replace("stroke:#000000", "stroke:" + stroke); s = s.replace("stroke:black", "stroke:" + stroke); out.println(s); } out.close(); in.close(); return sout.getBuffer(); } /** * @param fileName * @param stroke * @param fill * @param size * @return a SVG image with black colors overwritten with the given colors */ public static BufferedImage getUpdatedSVGImage(String fileName, String stroke, String fill, int size) { ByteArrayOutputStream bos = new ByteArrayOutputStream(size * size * 4); TranscoderOutput output = new TranscoderOutput(bos); PNGTranscoder trc = new PNGTranscoder(); try { Reader in = new StringReader(updateSVGColors(new File(fileName), stroke, fill).toString()); TranscoderInput input = new TranscoderInput(in); if (size > 0) { trc.addTranscodingHint(KEY_HEIGHT, new Float(size)); trc.addTranscodingHint(KEY_WIDTH, new Float(size)); } trc.transcode(input, output); bos.close(); ByteArrayInputStream is = new ByteArrayInputStream(bos.toByteArray()); MemoryCacheSeekableStream mcss = new MemoryCacheSeekableStream(is); RenderedOp rop = JAI.create("stream", mcss); return rop.getAsBufferedImage(); } catch (TranscoderException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } /** * @param fileName */ public void setFileName(String fileName) { this.fileName = fileName; if (fileName.toLowerCase().endsWith(".svg")) { image = getUpdatedSVGImage(fileName, toHexColor(getLineColor()), toHexColor(getFillColor()), getSize()); } else { image = Toolkit.getDefaultToolkit().getImage(fileName); } } }