123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- /*
- * Copyright 1999-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- /* $Id$ */
-
- package org.apache.fop.image.analyser;
-
- // Java
- import java.io.InputStream;
- import java.io.IOException;
- import java.awt.geom.AffineTransform;
-
- // XML
- import org.w3c.dom.Element;
- import org.w3c.dom.svg.SVGDocument;
-
- // Avalon
- import org.apache.avalon.framework.logger.Logger;
-
- // Batik
- import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
- import org.apache.batik.dom.svg.SVGOMDocument;
- import org.apache.batik.bridge.BridgeContext;
- import org.apache.batik.bridge.UnitProcessor;
- import org.apache.batik.dom.svg.SVGDOMImplementation;
-
- // FOP
- import org.apache.fop.image.XMLImage;
- import org.apache.fop.image.FopImage;
- import org.apache.fop.apps.FOUserAgent;
- import org.apache.fop.svg.SVGUserAgent;
-
- /**
- * ImageReader object for SVG document image type.
- */
- public class SVGReader implements ImageReader {
-
- /** SVG's MIME type */
- public static final String SVG_MIME_TYPE = "image/svg+xml";
-
- private boolean batik = true;
-
- /** @see org.apache.fop.image.analyser.ImageReader */
- public FopImage.ImageInfo verifySignature(String uri, InputStream fis,
- FOUserAgent ua) throws IOException {
- FopImage.ImageInfo info = loadImage(uri, fis, ua);
- if (info != null) {
- try {
- fis.close();
- } catch (Exception e) {
- //ignore
- }
- }
- return info;
- }
-
- /**
- * Returns the MIME type supported by this implementation.
- *
- * @return The MIME type
- */
- public String getMimeType() {
- return SVG_MIME_TYPE;
- }
-
- /**
- * This means the external svg document will be loaded twice. Possibly need
- * a slightly different design for the image stuff.
- *
- * @param uri @todo Description of the Parameter
- * @param fis @todo Description of the Parameter
- * @param ua @todo Description of the Parameter
- * @return @todo Description of the Return Value
- */
- private FopImage.ImageInfo loadImage(String uri, InputStream bis,
- FOUserAgent ua) {
- if (batik) {
- try {
- Loader loader = new Loader();
- return loader.getImage(uri, bis, ua.getLogger(),
- ua.getPixelUnitToMillimeter());
- } catch (NoClassDefFoundError e) {
- batik = false;
- //ua.getLogger().error("Batik not in class path", e);
- return null;
- }
- }
- return null;
- }
-
- /**
- * This method is put in another class so that the classloader does not
- * attempt to load batik related classes when constructing the SVGReader
- * class.
- */
- class Loader {
- private FopImage.ImageInfo getImage(String uri, InputStream fis,
- Logger logger, float pixelUnitToMM) {
- // parse document and get the size attributes of the svg element
-
- try {
- int length = 5;
- fis.mark(length);
- byte[] b = new byte[length];
- fis.read(b);
- String start = new String(b);
- fis.reset();
-
- if (start.equals("<?xml")) {
- // we have xml, might be another doc
- // so stop batik from closing the stream
- final InputStream input = fis;
- fis =
- new InputStream() {
- public int read() throws IOException {
- return input.read();
- }
-
- public int read(byte[] b) throws IOException {
- return input.read(b);
- }
-
- public int read(byte[] b, int off, int len)
- throws IOException {
- return input.read(b, off, len);
- }
-
- public long skip(long n) throws IOException {
- return input.skip(n);
- }
-
- public int available() throws IOException {
- return input.available();
- }
-
- public void mark(int rl) {
- input.mark(rl);
- }
-
- public boolean markSupported() {
- return input.markSupported();
- }
-
- public void reset() throws IOException {
- input.reset();
- }
-
- public void close() throws IOException {
- //ignore
- }
- };
- }
-
- FopImage.ImageInfo info = new FopImage.ImageInfo();
-
- info.mimeType = getMimeType();
- info.str = SVGDOMImplementation.SVG_NAMESPACE_URI;
-
- length = fis.available();
- fis.mark(length + 1);
- SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(
- XMLImage.getParserName());
- SVGDocument doc = (SVGDocument) factory.createSVGDocument(uri, fis);
- info.data = doc;
-
- Element e = doc.getRootElement();
- String s;
- SVGUserAgent userAg = new SVGUserAgent(logger, pixelUnitToMM,
- new AffineTransform());
- BridgeContext ctx = new BridgeContext(userAg);
- UnitProcessor.Context uctx =
- UnitProcessor.createContext(ctx, e);
-
- // 'width' attribute - default is 100%
- s = e.getAttributeNS(null,
- SVGOMDocument.SVG_WIDTH_ATTRIBUTE);
- if (s.length() == 0) {
- s = SVGOMDocument.SVG_SVG_WIDTH_DEFAULT_VALUE;
- }
- info.width = (int) UnitProcessor.svgHorizontalLengthToUserSpace(
- s, SVGOMDocument.SVG_WIDTH_ATTRIBUTE, uctx);
-
- // 'height' attribute - default is 100%
- s = e.getAttributeNS(null,
- SVGOMDocument.SVG_HEIGHT_ATTRIBUTE);
- if (s.length() == 0) {
- s = SVGOMDocument.SVG_SVG_HEIGHT_DEFAULT_VALUE;
- }
- info.height = (int) UnitProcessor.svgVerticalLengthToUserSpace(
- s, SVGOMDocument.SVG_HEIGHT_ATTRIBUTE, uctx);
-
- return info;
- } catch (NoClassDefFoundError ncdfe) {
- try {
- fis.reset();
- } catch (IOException ioe) {
- // we're more interested in the original exception
- }
- batik = false;
- //ua.getLogger().error("Batik not in class path", ncdfe);
- return null;
- } catch (Exception e) {
- // If the svg is invalid then it throws an IOException
- // so there is no way of knowing if it is an svg document
-
- // ua.getLogger().error("Could not load external SVG: " +
- // e.getMessage(), e);
- // assuming any exception means this document is not svg
- // or could not be loaded for some reason
- try {
- fis.reset();
- } catch (IOException ioe) {
- // we're more interested in the original exception
- }
- return null;
- }
- }
- }
-
- }
|