001 /* 002 * Copyright 2002 - 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: PreloaderMathML.java,v 371548310efa 2010/08/09 21:15:33 max $ */ 018 019 package net.sourceforge.jeuclid.xmlgraphics; 020 021 import java.io.IOException; 022 import java.io.InputStream; 023 024 import javax.xml.transform.Source; 025 import javax.xml.transform.dom.DOMSource; 026 import javax.xml.transform.stream.StreamSource; 027 028 import net.sourceforge.jeuclid.Constants; 029 import net.sourceforge.jeuclid.context.LayoutContextImpl; 030 import net.sourceforge.jeuclid.elements.AbstractJEuclidElement; 031 import net.sourceforge.jeuclid.elements.generic.MathImpl; 032 import net.sourceforge.jeuclid.layout.JEuclidView; 033 import net.sourceforge.jeuclid.parser.Parser; 034 035 import org.apache.commons.logging.Log; 036 import org.apache.commons.logging.LogFactory; 037 import org.apache.fop.util.UnclosableInputStream; 038 import org.apache.xmlgraphics.image.loader.ImageContext; 039 import org.apache.xmlgraphics.image.loader.ImageException; 040 import org.apache.xmlgraphics.image.loader.ImageInfo; 041 import org.apache.xmlgraphics.image.loader.ImageSize; 042 import org.apache.xmlgraphics.image.loader.impl.AbstractImagePreloader; 043 import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM; 044 import org.apache.xmlgraphics.image.loader.util.ImageUtil; 045 import org.w3c.dom.Document; 046 import org.w3c.dom.Element; 047 import org.xml.sax.SAXException; 048 049 /** 050 * @version $Revision: 371548310efa $ 051 */ 052 public class PreloaderMathML extends AbstractImagePreloader { 053 /** 054 * Convert from point to millipoint. 055 */ 056 public static final float MPT_FACTOR = 1000.0f; 057 058 /** 059 * Logger for this class 060 */ 061 private static final Log LOGGER = LogFactory 062 .getLog(PreloaderMathML.class); 063 064 /** 065 * Default Constructor. 066 */ 067 public PreloaderMathML() { 068 // Empty on purpose 069 } 070 071 /** {@inheritDoc} */ 072 public ImageInfo preloadImage(final String uri, final Source src, 073 final ImageContext context) throws ImageException, IOException { 074 final Document n = this.parseSource(src); 075 if (n != null) { 076 return this.createImageInfo(uri, context, n); 077 } 078 079 return null; 080 } 081 082 @SuppressWarnings("unchecked") 083 private ImageInfo createImageInfo(final String uri, 084 final ImageContext context, final Document n) { 085 final ImageInfo info = new ImageInfo(uri, Constants.MATHML_MIMETYPE); 086 final ImageSize size = new ImageSize(); 087 final JEuclidView view = new JEuclidView(n, LayoutContextImpl 088 .getDefaultLayoutContext(), null); 089 final int descentMpt = (int) (view.getDescentHeight() * PreloaderMathML.MPT_FACTOR); 090 final int ascentMpt = (int) (view.getAscentHeight() * PreloaderMathML.MPT_FACTOR); 091 092 size.setSizeInMillipoints( 093 (int) (view.getWidth() * PreloaderMathML.MPT_FACTOR), 094 ascentMpt + descentMpt); 095 size.setBaselinePositionFromBottom(descentMpt); 096 // Set the resolution to that of the FOUserAgent 097 size.setResolution(context.getSourceResolution()); 098 size.calcPixelsFromSize(); 099 info.setSize(size); 100 101 // The whole image had to be loaded for this, so keep it 102 final ImageXMLDOM xmlImage = new ImageXMLDOM(info, n, 103 AbstractJEuclidElement.URI); 104 info.getCustomObjects().put(ImageInfo.ORIGINAL_IMAGE, xmlImage); 105 return info; 106 } 107 108 private Document parseSource(final Source src) { 109 Document n = null; 110 InputStream in = null; 111 try { 112 if (src instanceof DOMSource) { 113 final DOMSource domSrc = (DOMSource) src; 114 n = (Document) domSrc.getNode(); 115 } else { 116 in = new UnclosableInputStream(ImageUtil.needInputStream(src)); 117 final int length = in.available(); 118 in.mark(length + 1); 119 n = Parser.getInstance().parseStreamSource( 120 new StreamSource(in)); 121 } 122 final Element rootNode = n.getDocumentElement(); 123 if (!(AbstractJEuclidElement.URI.equals(rootNode 124 .getNamespaceURI()) || MathImpl.ELEMENT.equals(rootNode 125 .getNodeName()))) { 126 n = null; 127 } 128 } catch (final IOException e) { 129 n = null; 130 } catch (final SAXException e) { 131 n = null; 132 } catch (final IllegalArgumentException e) { 133 n = null; 134 } catch (final NullPointerException e) { 135 // Due to a bug in xmlgraphics-commons 1.3.1 which sometimes 136 // creates wrapper around null streams if files do not exist. 137 n = null; 138 } 139 try { 140 if (in != null) { 141 in.reset(); 142 } 143 } catch (final IOException ioe) { 144 PreloaderMathML.LOGGER.warn("Should never happen: " 145 + ioe.getMessage()); 146 } catch (final NullPointerException e) { 147 // Due to a bug in xmlgraphics-commons 1.3.1 which sometimes 148 // creates wrapper around null streams if files do not exist. 149 n = null; 150 } 151 return n; 152 } 153 }