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