/**
* Copyright (c) 2008 Borland Software Corporation
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Dmitry Stadnik - initial API and implementation
*/
package org.eclipse.gmf.internal.runtime.lite.svg;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.dom.svg.SVGOMDocument;
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.apache.batik.transcoder.image.ImageTranscoder;
import org.w3c.dom.Document;
public class SimpleImageTranscoder extends SVGAbstractTranscoder {
private BufferedImage bufferedImage;
private Document document;
private int canvasWidth = -1, canvasHeight = -1;
private Rectangle2D canvasAOI;
private RenderingHints renderingHints;
public SimpleImageTranscoder(Document document) {
this.document = document;
renderingHints = new RenderingHints(null);
}
public final Document getDocument() {
return document;
}
public final RenderingHints getRenderingHints() {
return renderingHints;
}
public final int getCanvasWidth() {
return canvasWidth;
}
public final int getCanvasHeight() {
return canvasHeight;
}
public void setCanvasSize(int width, int height) {
if (this.canvasWidth == width && this.canvasHeight == height) {
return;
}
this.canvasWidth = width;
this.canvasHeight = height;
contentChanged();
}
public final Rectangle2D getCanvasAreaOfInterest() {
if (canvasAOI == null) {
return null;
}
Rectangle2D result = new Rectangle2D.Float();
result.setRect(canvasAOI);
return result;
}
public void setCanvasAreaOfInterest(Rectangle2D value) {
if (value == null) {
if (canvasAOI == null) {
return;
}
canvasAOI = null;
contentChanged();
return;
}
if (value.equals(canvasAOI)) {
return;
}
canvasAOI = new Rectangle2D.Float();
canvasAOI.setRect(value);
contentChanged();
}
/**
* Call before querying for CSS properties. If document has CSS engine installed returns null. Client is responsible to
* dispose bridge context if it was returned by this method.
*/
public BridgeContext initCSSEngine() {
if (this.document == null) {
return null;
}
SVGOMDocument sd = (SVGOMDocument) this.document;
if (sd.getCSSEngine() != null) {
return null;
}
class BridgeContextEx extends BridgeContext {
public BridgeContextEx() {
super(SimpleImageTranscoder.this.userAgent);
BridgeContextEx.this.setDocument(SimpleImageTranscoder.this.document);
BridgeContextEx.this.initializeDocument(SimpleImageTranscoder.this.document);
}
}
return new BridgeContextEx();
}
public void contentChanged() {
bufferedImage = null;
}
private void updateImage() {
if (document == null) {
return;
}
try {
if (canvasWidth >= 0) {
addTranscodingHint(ImageTranscoder.KEY_WIDTH, new Float(canvasWidth));
} else {
removeTranscodingHint(ImageTranscoder.KEY_WIDTH);
}
if (canvasHeight >= 0) {
addTranscodingHint(ImageTranscoder.KEY_HEIGHT, new Float(canvasHeight));
} else {
removeTranscodingHint(ImageTranscoder.KEY_HEIGHT);
}
if (canvasAOI != null) {
addTranscodingHint(ImageTranscoder.KEY_AOI, canvasAOI);
} else {
removeTranscodingHint(ImageTranscoder.KEY_AOI);
}
transcode(new TranscoderInput(document), new TranscoderOutput());
} catch (TranscoderException e) {
Activator.logError("Error transcoding SVG image", e);
}
}
protected void transcode(Document document, String uri, TranscoderOutput output) throws TranscoderException {
super.transcode(document, uri, output);
int w = (int) (width + 0.5);
int h = (int) (height + 0.5);
ImageRenderer renderer = createImageRenderer();
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 {
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 = renderer.getOffScreen();
} catch (Exception ex) {
throw new TranscoderException(ex);
}
}
protected ImageRenderer createImageRenderer() {
StaticRenderer renderer = new StaticRenderer();
renderer.getRenderingHints().add(renderingHints);
return renderer;
}
public final BufferedImage getBufferedImage() {
if (bufferedImage == null) {
updateImage();
}
return bufferedImage;
}
}