]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Added support for DOMSource to Preloader SVG so a URI Resolver can be written that...
authorJeremias Maerki <jeremias@apache.org>
Fri, 25 Jan 2008 08:26:54 +0000 (08:26 +0000)
committerJeremias Maerki <jeremias@apache.org>
Fri, 25 Jan 2008 08:26:54 +0000 (08:26 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@615144 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/fop/image/loader/batik/PreloaderSVG.java
test/java/org/apache/fop/image/loader/batik/ImagePreloaderTestCase.java

index e83a302da042e0b492c0f3c67505b0856868eff0..db03cbbf2ed19e6c2cb12fe789a8b5029e6f5e54 100644 (file)
@@ -25,6 +25,7 @@ import java.io.InputStream;
 
 import javax.xml.parsers.SAXParserFactory;
 import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMSource;
 
 import org.w3c.dom.Element;
 import org.w3c.dom.svg.SVGDocument;
@@ -61,14 +62,13 @@ public class PreloaderSVG extends AbstractImagePreloader {
     /** {@inheritDoc} */ 
     public ImageInfo preloadImage(String uri, Source src, ImageContext context)
             throws IOException {
-        if (!ImageUtil.hasInputStream(src)) {
-            //TODO Remove this and support DOMSource and possibly SAXSource
-            return null;
-        }
         ImageInfo info = null;
         if (batikAvailable) {
             try {
                 Loader loader = new Loader();
+                if (!loader.isSupportedSource(src)) {
+                    return null;
+                }
                 info = loader.getImage(uri, src, context);
             } catch (NoClassDefFoundError e) {
                 batikAvailable = false;
@@ -76,7 +76,7 @@ public class PreloaderSVG extends AbstractImagePreloader {
                 return null;
             }
         }
-        if (info != null) {
+        if (info != null && ImageUtil.hasInputStream(src)) {
             ImageUtil.closeQuietly(src); //Image is fully read
         }
         return info;
@@ -106,57 +106,30 @@ public class PreloaderSVG extends AbstractImagePreloader {
                 ImageContext context) {
             // parse document and get the size attributes of the svg element
 
-            InputStream in = new UnclosableInputStream(ImageUtil.needInputStream(src));
+            InputStream in = null;
             try {
-                int length = in.available();
-                in.mark(length + 1);
-                SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(
-                        getParserName());
-                SVGDocument doc = (SVGDocument) factory.createSVGDocument(src.getSystemId(), in);
-
-                Element e = doc.getRootElement();
-                float pxUnitToMillimeter = 25.4f / context.getSourceResolution(); 
-                SVGUserAgent userAg = new SVGUserAgent(pxUnitToMillimeter,
-                            new AffineTransform());
-                BridgeContext ctx = new BridgeContext(userAg);
-                UnitProcessor.Context uctx = UnitProcessor.createContext(ctx, e);
-
-                String s;
-                // 'width' attribute - default is 100%
-                s = e.getAttributeNS(null, SVGOMDocument.SVG_WIDTH_ATTRIBUTE);
-                if (s.length() == 0) {
-                    s = SVGOMDocument.SVG_SVG_WIDTH_DEFAULT_VALUE;
-                }
-                float width = 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;
+                SVGDocument doc;
+                if (src instanceof DOMSource) {
+                    DOMSource domSrc = (DOMSource)src;
+                    doc = (SVGDocument)domSrc.getNode();
+                } else {
+                    in = new UnclosableInputStream(ImageUtil.needInputStream(src));
+                    int length = in.available();
+                    in.mark(length + 1);
+                    SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(
+                            getParserName());
+                    doc = (SVGDocument) factory.createSVGDocument(src.getSystemId(), in);
                 }
-                float height = UnitProcessor.svgVerticalLengthToUserSpace(
-                        s, SVGOMDocument.SVG_HEIGHT_ATTRIBUTE, uctx);
-
-                ImageInfo info = new ImageInfo(uri, MimeConstants.MIME_SVG);
-                ImageSize size = new ImageSize();
-                size.setSizeInMillipoints(Math.round(width * 1000), Math.round(height * 1000));
-                //Set the resolution to that of the FOUserAgent
-                size.setResolution(context.getSourceResolution());
-                size.calcPixelsFromSize();
-                info.setSize(size);
-
-                //The whole image had to be loaded for this, so keep it
-                ImageXMLDOM xmlImage = new ImageXMLDOM(info,
-                        doc, SVGDOMImplementation.SVG_NAMESPACE_URI);
-                info.getCustomObjects().put(ImageInfo.ORIGINAL_IMAGE, xmlImage);
+                ImageInfo info = createImageInfo(uri, context, doc);
                 
                 return info;
             } catch (NoClassDefFoundError ncdfe) {
-                try {
-                    in.reset();
-                } catch (IOException ioe) {
-                    // we're more interested in the original exception
+                if (in != null) {
+                    try {
+                        in.reset();
+                    } catch (IOException ioe) {
+                        // we're more interested in the original exception
+                    }
                 }
                 batikAvailable = false;
                 log.warn("Batik not in class path", ncdfe);
@@ -177,6 +150,56 @@ public class PreloaderSVG extends AbstractImagePreloader {
                 return null;
             }
         }
+
+        private ImageInfo createImageInfo(String uri, ImageContext context, SVGDocument doc) {
+            Element e = doc.getRootElement();
+            float pxUnitToMillimeter = 25.4f / context.getSourceResolution(); 
+            SVGUserAgent userAg = new SVGUserAgent(pxUnitToMillimeter,
+                        new AffineTransform());
+            BridgeContext ctx = new BridgeContext(userAg);
+            UnitProcessor.Context uctx = UnitProcessor.createContext(ctx, e);
+
+            String s;
+            // 'width' attribute - default is 100%
+            s = e.getAttributeNS(null, SVGOMDocument.SVG_WIDTH_ATTRIBUTE);
+            if (s.length() == 0) {
+                s = SVGOMDocument.SVG_SVG_WIDTH_DEFAULT_VALUE;
+            }
+            float width = 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;
+            }
+            float height = UnitProcessor.svgVerticalLengthToUserSpace(
+                    s, SVGOMDocument.SVG_HEIGHT_ATTRIBUTE, uctx);
+
+            ImageInfo info = new ImageInfo(uri, MimeConstants.MIME_SVG);
+            ImageSize size = new ImageSize();
+            size.setSizeInMillipoints(Math.round(width * 1000), Math.round(height * 1000));
+            //Set the resolution to that of the FOUserAgent
+            size.setResolution(context.getSourceResolution());
+            size.calcPixelsFromSize();
+            info.setSize(size);
+
+            //The whole image had to be loaded for this, so keep it
+            ImageXMLDOM xmlImage = new ImageXMLDOM(info,
+                    doc, SVGDOMImplementation.SVG_NAMESPACE_URI);
+            info.getCustomObjects().put(ImageInfo.ORIGINAL_IMAGE, xmlImage);
+            return info;
+        }
+        
+        private boolean isSupportedSource(Source src) {
+            if (src instanceof DOMSource) {
+                DOMSource domSrc = (DOMSource)src;
+                return (domSrc.getNode() instanceof SVGDocument);
+            } else {
+                return ImageUtil.hasInputStream(src);
+            }
+        }
+
     }
 
 }
index b14dd1fb84dc3f6303b684b6941511c8297522a6..9406ed65c0ab48a9e2b91bc9461b05bff6a0916c 100644 (file)
@@ -21,8 +21,19 @@ package org.apache.fop.image.loader.batik;
 
 import java.io.IOException;
 
+import javax.xml.transform.Source;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.URIResolver;
+import javax.xml.transform.dom.DOMSource;
+
 import junit.framework.TestCase;
 
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.batik.dom.svg.SVGDOMImplementation;
+
 import org.apache.xmlgraphics.image.loader.ImageException;
 import org.apache.xmlgraphics.image.loader.ImageInfo;
 import org.apache.xmlgraphics.image.loader.ImageManager;
@@ -30,7 +41,6 @@ import org.apache.xmlgraphics.image.loader.ImageManager;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.apps.FopFactory;
 import org.apache.fop.apps.MimeConstants;
-import org.apache.fop.image.loader.batik.ImageWMF;
 
 /**
  * Tests for bundled image preloader implementations.
@@ -89,6 +99,50 @@ public class ImagePreloaderTestCase extends TestCase {
         assertEquals(100000, info.getSize().getHeightMpt());
     }
 
+    public void testSVGWithDOM() throws Exception {
+        String uri = "my:SVGImage";
+        FOUserAgent userAgent = fopFactory.newFOUserAgent();
+        
+        userAgent.setURIResolver(new URIResolver() {
+
+            public Source resolve(String href, String base) throws TransformerException {
+                if (href.startsWith("my:")) {
+                    DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();
+                    String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;
+                    Document doc = impl.createDocument(svgNS, "svg", null);
+                    Element element = doc.getDocumentElement();
+                    element.setAttribute("viewBox", "0 0 20 20");
+                    element.setAttribute("width", "20pt");
+                    element.setAttribute("height", "20pt");
+                    
+                    Element rect = doc.createElementNS(svgNS, "rect");
+                    rect.setAttribute("x", "5");
+                    rect.setAttribute("y", "5");
+                    rect.setAttribute("width", "10");
+                    rect.setAttribute("height", "10");
+                    element.appendChild(rect);
+                    
+                    DOMSource src = new DOMSource(doc);
+                    return src;
+                } else {
+                    return null;
+                }
+            }
+            
+        });
+        
+        ImageManager manager = fopFactory.getImageManager();
+        ImageInfo info = manager.preloadImage(uri, userAgent.getImageSessionContext());
+        assertNotNull("ImageInfo must not be null", info);
+        assertEquals(MimeConstants.MIME_SVG, info.getMimeType());
+        assertEquals(uri, info.getOriginalURI());
+        assertEquals(20, info.getSize().getWidthPx()); //100 = default viewport size
+        assertEquals(20, info.getSize().getHeightPx());
+        assertEquals(userAgent.getSourceResolution(), info.getSize().getDpiHorizontal(), 0.1);
+        assertEquals(20000, info.getSize().getWidthMpt());
+        assertEquals(20000, info.getSize().getHeightMpt());
+    }
+
     public void testWMF() throws Exception {
         String uri = "test/resources/images/testChart.wmf";