package org.freeplane.plugin.svg;
import java.awt.Dimension;
import java.net.URI;
import javax.swing.JComponent;
import org.apache.batik.swing.JSVGCanvas;
import org.apache.batik.swing.gvt.GVTTreeRendererAdapter;
import org.apache.batik.swing.gvt.GVTTreeRendererEvent;
import org.apache.batik.util.SVGConstants;
import org.freeplane.core.resources.ResourceController;
import org.freeplane.core.util.TextUtils;
import org.freeplane.view.swing.features.filepreview.ExternalResource;
import org.freeplane.view.swing.features.filepreview.IViewerFactory;
import org.freeplane.view.swing.features.filepreview.ViewerLayoutManager;
import org.w3c.dom.svg.SVGDocument;
import org.w3c.dom.svg.SVGLength;
import org.w3c.dom.svg.SVGSVGElement;
public class SvgViewerFactory implements IViewerFactory {
private final class ViewerComponent extends JSVGCanvas {
/**
*
*/
private static final long serialVersionUID = 1L;
private Dimension originalSize = null;
protected Dimension getOriginalSize() {
return new Dimension(originalSize);
}
public ViewerComponent(final URI uri) {
super(null, false, false);
setDocumentState(ALWAYS_STATIC);
setSize(1, 1);
addGVTTreeRendererListener(new GVTTreeRendererAdapter() {
@Override
public void gvtRenderingStarted(final GVTTreeRendererEvent e) {
super.gvtRenderingStarted(e);
final SVGDocument document = getSVGDocument();
final SVGSVGElement rootElement = document.getRootElement();
final SVGLength width = rootElement.getWidth().getBaseVal();
final SVGLength height = rootElement.getHeight().getBaseVal();
float defaultWidth = (float) Math.ceil(width.getValue());
float defaultHeigth = (float) Math.ceil(height.getValue());
if (defaultWidth == 1f && defaultHeigth == 1f) {
defaultWidth = ResourceController.getResourceController().getIntProperty(
"default_external_component_width", 200);
defaultHeigth = ResourceController.getResourceController().getIntProperty(
"default_external_component_height", 200);
}
originalSize = new Dimension((int) defaultWidth, (int) defaultHeigth);
if ("".equals(rootElement.getAttributeNS(null, SVGConstants.SVG_VIEW_BOX_ATTRIBUTE))) {
rootElement.setAttributeNS(null, SVGConstants.SVG_VIEW_BOX_ATTRIBUTE, "0 0 " + defaultWidth
+ " " + defaultHeigth);
}
setSize(originalSize);
removeGVTTreeRendererListener(this);
}
});
setURI(uri.toString());
}
@Override
public Dimension getPreferredSize() {
if (originalSize == null) {
return new Dimension(1, 1);
}
return super.getPreferredSize();
}
}
public boolean accept(final URI uri) {
return uri.getRawPath().endsWith(".svg");
}
public String getDescription() {
return TextUtils.getText("svg");
};
public JComponent createViewer(final ExternalResource resource, final URI uri, final int maximumWidth) {
final ViewerComponent canvas = new ViewerComponent(uri);
canvas.addGVTTreeRendererListener(new GVTTreeRendererAdapter() {
@Override
public void gvtRenderingCompleted(final GVTTreeRendererEvent e) {
final Dimension preferredSize = canvas.getOriginalSize();
float r = resource.getZoom();
final int originalWidth = preferredSize.width;
if(r == -1){
r = resource.setZoom(originalWidth, maximumWidth);
}
preferredSize.width = (int) (Math.rint(originalWidth * r));
preferredSize.height = (int) (Math.rint(preferredSize.height * r));
canvas.setPreferredSize(preferredSize);
canvas.setLayout(new ViewerLayoutManager(1f));
canvas.revalidate();
canvas.removeGVTTreeRendererListener(this);
}
});
return canvas;
}
public JComponent createViewer(final URI uri, final Dimension preferredSize) {
final ViewerComponent canvas = new ViewerComponent(uri);
canvas.setPreferredSize(preferredSize);
canvas.setSize(preferredSize);
canvas.addGVTTreeRendererListener(new GVTTreeRendererAdapter() {
@Override
public void gvtRenderingCompleted(final GVTTreeRendererEvent e) {
canvas.setMySize(preferredSize);
canvas.setSize(preferredSize);
canvas.revalidate();
canvas.removeGVTTreeRendererListener(this);
}
});
return canvas;
}
public Dimension getOriginalSize(final JComponent viewer) {
final ViewerComponent canvas = (ViewerComponent) viewer;
return canvas.getOriginalSize();
}
public void setFinalViewerSize(final JComponent viewer, final Dimension size) {
final JSVGCanvas canvas = (JSVGCanvas) viewer;
canvas.setMySize(size);
}
public void setDraftViewerSize(JComponent viewer, Dimension size) {
setFinalViewerSize(viewer, size);
}
}