001    /*
002     * Copyright 2007 - 2008 JEuclid, http://jeuclid.sf.net
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    /* $Id: BatikConverter.java,v 70597ba9d706 2008/02/18 19:42:05 maxberger $ */
018    
019    package net.sourceforge.jeuclid.converter;
020    
021    import java.awt.Dimension;
022    import java.io.IOException;
023    import java.io.OutputStream;
024    
025    import javax.xml.transform.Transformer;
026    import javax.xml.transform.TransformerException;
027    import javax.xml.transform.TransformerFactory;
028    import javax.xml.transform.dom.DOMSource;
029    import javax.xml.transform.stream.StreamResult;
030    
031    import net.sourceforge.jeuclid.LayoutContext;
032    import net.sourceforge.jeuclid.layout.JEuclidView;
033    
034    import org.apache.batik.svggen.SVGGeneratorContext;
035    import org.apache.batik.svggen.SVGGraphics2D;
036    import org.apache.commons.logging.Log;
037    import org.apache.commons.logging.LogFactory;
038    import org.w3c.dom.DOMImplementation;
039    import org.w3c.dom.Document;
040    import org.w3c.dom.Node;
041    
042    /**
043     * supports conversion to SVG output through Batik.
044     * 
045     * @version $Revision: 70597ba9d706 $
046     */
047    public class BatikConverter implements ConverterPlugin {
048    
049        /**
050         * Logger for this class
051         */
052        private static final Log LOGGER = LogFactory.getLog(BatikConverter.class);
053    
054        private final DOMImplementation domImplementation;
055    
056        BatikConverter(final DOMImplementation domImpl) {
057            this.domImplementation = domImpl;
058        }
059    
060        /** {@inheritDoc} */
061        public Dimension convert(final Node doc, final LayoutContext context,
062                final OutputStream outStream) throws IOException {
063            final DocumentWithDimension svgDocDim = this.convert(doc, context);
064            if (svgDocDim != null) {
065                try {
066                    final Transformer transformer = TransformerFactory
067                            .newInstance().newTransformer();
068                    final DOMSource source = new DOMSource(svgDocDim
069                            .getDocument());
070                    final StreamResult result = new StreamResult(outStream);
071                    transformer.transform(source, result);
072                } catch (final TransformerException e) {
073                    BatikConverter.LOGGER.warn(e);
074                }
075                return svgDocDim.getDimension();
076            }
077            return null;
078        }
079    
080        /** {@inheritDoc} */
081        public DocumentWithDimension convert(final Node doc,
082                final LayoutContext context) {
083    
084            Document document = null;
085            final String svgNS = "http://www.w3.org/2000/svg";
086            document = this.domImplementation.createDocument(svgNS, "svg", null);
087            if (document != null) {
088                final SVGGeneratorContext svgContext = SVGGeneratorContext
089                        .createDefault(document);
090                svgContext.setComment("Converted from MathML using JEuclid");
091                final SVGGraphics2D svgGenerator = new SVGGraphics2D(svgContext,
092                        true);
093                final JEuclidView view = new JEuclidView(doc, context,
094                        svgGenerator);
095                final int ascent = (int) Math.ceil(view.getAscentHeight());
096                final int descent = (int) Math.ceil(view.getDescentHeight());
097                final int height = ascent + descent;
098                final int width = (int) Math.ceil(view.getWidth());
099                final Dimension size = new Dimension(width, height);
100                svgGenerator.setSVGCanvasSize(size);
101                view.draw(svgGenerator, 0, ascent);
102                document.replaceChild(svgGenerator.getRoot(), document
103                        .getFirstChild());
104                return new DocumentWithDimension(document, new Dimension(width,
105                        height), descent);
106            }
107            return null;
108        }
109    }