Selaa lähdekoodia

Added support for DOMSource to Preloader SVG so a URI Resolver can be written that provides the SVG as a W3C SVG DOM.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@615144 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-0_95beta
Jeremias Maerki 16 vuotta sitten
vanhempi
commit
8b281b7c15

+ 74
- 51
src/java/org/apache/fop/image/loader/batik/PreloaderSVG.java Näytä tiedosto

@@ -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);
}
}

}

}

+ 55
- 1
test/java/org/apache/fop/image/loader/batik/ImagePreloaderTestCase.java Näytä tiedosto

@@ -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";

Loading…
Peruuta
Tallenna