/*
* {{{ header & license
* Copyright (c) 2006 Patrick Wright
* Copyright (c) 2007 Wisconsin Court System
*
* 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.
* }}}
*/
package org.xhtmlrenderer.demo.svg;
import com.kitfox.svg.SVGException;
import com.kitfox.svg.app.beans.SVGPanel;
import org.w3c.dom.Element;
import org.xhtmlrenderer.extend.FSCanvas;
import org.xhtmlrenderer.extend.ReplacedElement;
import org.xhtmlrenderer.extend.ReplacedElementFactory;
import org.xhtmlrenderer.extend.UserAgentCallback;
import org.xhtmlrenderer.layout.LayoutContext;
import org.xhtmlrenderer.render.BlockBox;
import org.xhtmlrenderer.simple.extend.FormSubmissionListener;
import org.xhtmlrenderer.swing.SwingReplacedElement;
import org.xhtmlrenderer.util.XRLog;
import javax.swing.*;
import java.util.logging.Level;
import java.awt.*;
/**
* Factory to create ReplacedElements for SVG embedded in our XML file, using
* the Salamander library. Salamander in this case will return a Swing JPanel.
*/
public class SVGSalamanderReplacedElementFactory implements ReplacedElementFactory {
public ReplacedElement createReplacedElement(
LayoutContext c,
BlockBox box,
UserAgentCallback uac,
int cssWidth,
int cssHeight) {
SVGPanel panel = new SVGPanel();
String content = null;
JComponent cc = null;
try {
Element elem = box.getElement();
if (elem == null || ! isSVGEmbedded(elem)) {
return null;
}
// HACK: the easiest way to integrate with Salamander is to have it read
// our SVG from a file--so, push the content to a temporary file, yuck!
content = getSVGElementContent(elem);
String path = elem.getAttribute("data");
XRLog.general(Level.FINE, "Rendering embedded SVG via object tag from: " + path);
XRLog.general(Level.FINE, "Content is: " + content);
panel.setAntiAlias(true);
panel.setSvgResourcePath(path);
int width = panel.getSVGWidth();
int height = panel.getSVGHeight();
if ( cssWidth > 0 ) width = cssWidth;
if ( cssHeight > 0 ) height = cssHeight;
String val = elem.getAttribute("width");
if ( val != null && val.length() > 0 ) {
width = Integer.valueOf(val).intValue();
}
val = elem.getAttribute("height");
if ( val != null && val.length() > 0 ) {
height = Integer.valueOf(val).intValue();
}
panel.setScaleToFit(true);
panel.setPreferredSize(new Dimension(width, height));
panel.setSize(panel.getPreferredSize());
cc = panel;
} catch (SVGException e) {
XRLog.general(Level.WARNING, "Could not replace SVG element; rendering failed" +
" in SVG renderer. Skipping and using blank JPanel.", e);
cc = getDefaultJComponent(content, cssWidth, cssHeight);
}
if (cc == null) {
return null;
} else {
SwingReplacedElement result = new SwingReplacedElement(cc);
if (c.isInteractive()) {
FSCanvas canvas = c.getCanvas();
if (canvas instanceof JComponent) {
((JComponent) canvas).add(cc);
}
}
return result;
}
}
private String getSVGElementContent(Element elem) {
if ( elem.getChildNodes().getLength() > 0 ) {
return elem.getFirstChild().getNodeValue();
} else {
return "SVG";
}
}
private boolean isSVGEmbedded(Element elem) {
return elem.getNodeName().equals("object") && elem.getAttribute("type").equals("image/svg+xml");
}
private JComponent getDefaultJComponent(String content, int width, int height) {
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
JLabel comp = new JLabel(content);
panel.add(comp, BorderLayout.CENTER);
panel.setOpaque(false);
if ( width > 0 && height > 0 ) {
panel.setPreferredSize(new Dimension(width, height));
panel.setSize(panel.getPreferredSize());
} else {
panel.setPreferredSize(comp.getPreferredSize());
panel.setSize(comp.getPreferredSize());
}
return panel;
}
public void reset() {
}
public void remove(Element e) {
}
public void setFormSubmissionListener(FormSubmissionListener listener) {
// nothing to do ?
}
}