View Javadoc

1   /*
2    * Copyright 2002 - 2008 JEuclid, http://jeuclid.sf.net
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  /* $Id: PreloaderMathML.java,v 32023847f457 2009/03/20 14:20:15 maxberger $ */
18  
19  package net.sourceforge.jeuclid.xmlgraphics;
20  
21  import java.awt.Graphics2D;
22  import java.awt.Image;
23  import java.awt.image.BufferedImage;
24  import java.io.IOException;
25  import java.io.InputStream;
26  
27  import javax.xml.transform.Source;
28  import javax.xml.transform.dom.DOMSource;
29  import javax.xml.transform.stream.StreamSource;
30  
31  import net.sourceforge.jeuclid.Constants;
32  import net.sourceforge.jeuclid.context.LayoutContextImpl;
33  import net.sourceforge.jeuclid.elements.AbstractJEuclidElement;
34  import net.sourceforge.jeuclid.elements.generic.MathImpl;
35  import net.sourceforge.jeuclid.layout.JEuclidView;
36  import net.sourceforge.jeuclid.parser.Parser;
37  
38  import org.apache.commons.logging.Log;
39  import org.apache.commons.logging.LogFactory;
40  import org.apache.fop.util.UnclosableInputStream;
41  import org.apache.xmlgraphics.image.loader.ImageContext;
42  import org.apache.xmlgraphics.image.loader.ImageException;
43  import org.apache.xmlgraphics.image.loader.ImageInfo;
44  import org.apache.xmlgraphics.image.loader.ImageSize;
45  import org.apache.xmlgraphics.image.loader.impl.AbstractImagePreloader;
46  import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM;
47  import org.apache.xmlgraphics.image.loader.util.ImageUtil;
48  import org.w3c.dom.Document;
49  import org.w3c.dom.Element;
50  import org.xml.sax.SAXException;
51  
52  /**
53   * @version $Revision: 32023847f457 $
54   */
55  public class PreloaderMathML extends AbstractImagePreloader {
56      /**
57       * Convert from point to millipoint.
58       */
59      public static final float MPT_FACTOR = 1000.0f;
60  
61      /**
62       * Logger for this class
63       */
64      private static final Log LOGGER = LogFactory
65              .getLog(PreloaderMathML.class);
66  
67      /**
68       * Default Constructor.
69       */
70      public PreloaderMathML() {
71          // Empty on purpose
72      }
73  
74      /** {@inheritDoc} */
75      public ImageInfo preloadImage(final String uri, final Source src,
76              final ImageContext context) throws ImageException, IOException {
77          final Document n = this.parseSource(src);
78          if (n != null) {
79              return this.createImageInfo(uri, context, n);
80          }
81  
82          return null;
83      }
84  
85      @SuppressWarnings("unchecked")
86      private ImageInfo createImageInfo(final String uri,
87              final ImageContext context, final Document n) {
88          final ImageInfo info = new ImageInfo(uri, Constants.MATHML_MIMETYPE);
89          final ImageSize size = new ImageSize();
90          final Image tempimage = new BufferedImage(1, 1,
91                  BufferedImage.TYPE_INT_ARGB);
92          final Graphics2D tempg = (Graphics2D) tempimage.getGraphics();
93          final JEuclidView view = new JEuclidView(n, LayoutContextImpl
94                  .getDefaultLayoutContext(), tempg);
95          final int descentMpt = (int) (view.getDescentHeight() * PreloaderMathML.MPT_FACTOR);
96          final int ascentMpt = (int) (view.getAscentHeight() * PreloaderMathML.MPT_FACTOR);
97  
98          size.setSizeInMillipoints(
99                  (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 }