/* ========================
* JSynoptic : a free Synoptic editor
* ========================
*
* Project Info: http://jsynoptic.sourceforge.net/index.html
*
* This program is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2001-2005, by :
* Corporate:
* EADS Astrium SAS
* EADS CRC
* Individual:
* Claude Cazenave
*
* $Id: FactoryTranscoder.java,v 1.2 2006/01/04 17:24:54 cazenave Exp $
*
* Changes
* -------
* 20 d�c. 2005 : Initial public release (CC);
*
*/
package simtools.images.svg;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import org.apache.batik.ext.awt.image.GraphicsUtil;
import org.apache.batik.gvt.renderer.ImageRenderer;
import org.apache.batik.gvt.renderer.StaticRenderer;
import org.apache.batik.transcoder.SVGAbstractTranscoder;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.w3c.dom.Document;
import simtools.images.svg.SVGImageFactory.FactoryListener;
/**
* The transcoder is in charge of processing an SVG file to paint
* an image
* @see <code>SVGAbstractTranscoder</code>
* @author cazenave_c
*/
public class FactoryTranscoder extends SVGAbstractTranscoder {
protected final ImageHolder imageHolder;
protected int requestedWidth;
protected int requestedHeight;
protected int originalWidth;
protected int originalHeight;
public FactoryTranscoder(ImageHolder ie) {
imageHolder = ie;
}
/**
* Generate the image
* @param tinput the input document
* @param w the image width
* @param h the image height
* @throws TranscoderException
*/
public void rasterize(TranscoderInput tinput, int w, int h)
throws TranscoderException {
requestedWidth = w;
requestedHeight = h;
transcode(tinput, null);
}
/**
* @return the orginal document width
*/
public int getWidth(){
return originalWidth;
}
/**
* @return the orginal document height
*/
public int getHeight(){
return originalHeight;
}
/**
* Transcodes the specified Document as an image in the specified output.
*
* @param document
* the document to transcode
* @param uri
* the uri of the document or null if any
* @param output
* the ouput where to transcode
* @exception TranscoderException
* if an error occured while transcoding
*/
protected void transcode(Document document, String uri,
TranscoderOutput output) throws TranscoderException {
// Sets up root, curTxf & curAoi
super.transcode(document, uri, output);
// prepare the image to be painted : update the size if needed
int w = (int) (width + 0.5);
originalWidth=w;
if (requestedWidth > 0) {
w = requestedWidth;
curTxf.scale(w / width, 1.);
width = w;
}
int h = (int) (height + 0.5);
originalHeight=h;
if (requestedHeight > 0) {
h = requestedHeight;
curTxf.scale(1., h / height);
height = h;
}
// paint the SVG document using the bridge package
// create the appropriate renderer
// TODO : optimization could reuse renderers
ImageRenderer renderer = new StaticRenderer();
renderer.updateOffScreen(w, h);
// curTxf.translate(0.5, 0.5);
renderer.setTransform(curTxf);
renderer.setTree(this.root);
this.root = null; // We're done with it...
try {
// now we are sure that the aoi is the image size
Shape raoi = new Rectangle2D.Float(0, 0, width, height);
// Warning: the renderer's AOI must be in user space
renderer.repaint(curTxf.createInverse()
.createTransformedShape(raoi));
BufferedImage rend = renderer.getOffScreen();
renderer = null; // We're done with it...
BufferedImage dest = createImage(w, h);
Graphics2D g2d = GraphicsUtil.createGraphics(dest);
g2d.drawRenderedImage(rend, new AffineTransform());
g2d.dispose();
rend = null; // We're done with it...
sendImage(dest);
} catch (Exception ex) {
throw new TranscoderException(ex);
}
}
/**
* Generate the image to be painted
* This default implementation generates an ARGB image i.e. with
* tansparency features
* @param width the image width
* @param height the image height
* @return the image
*/
protected BufferedImage createImage(int width, int height) {
return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
}
/**
* Send the image to all the users
* @param img the painted image
* @throws TranscoderException
*/
protected void sendImage(BufferedImage img) {
imageHolder.image = img;
for (int i = 0; i < imageHolder.listeners.size(); i++) {
((FactoryListener) imageHolder.listeners.get(i)).done(img);
}
}
}