aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build.xml7
-rw-r--r--conf/fop.xconf12
-rw-r--r--src/java/META-INF/services/org.apache.fop.render.XMLHandler3
-rw-r--r--src/java/org/apache/fop/render/AbstractRenderer.java46
-rw-r--r--src/java/org/apache/fop/render/RendererContextConstants.java44
-rw-r--r--src/java/org/apache/fop/render/XMLHandler.java6
-rw-r--r--src/java/org/apache/fop/render/XMLHandlerRegistry.java63
-rw-r--r--src/java/org/apache/fop/render/java2d/Java2DRenderer.java12
-rw-r--r--src/java/org/apache/fop/render/java2d/Java2DRendererContextConstants.java32
-rw-r--r--src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java185
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRenderer.java30
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRendererContextConstants.java52
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFSVGHandler.java339
-rw-r--r--src/java/org/apache/fop/render/ps/PSRenderer.java15
-rw-r--r--src/java/org/apache/fop/render/ps/PSRendererContextConstants.java35
-rw-r--r--src/java/org/apache/fop/render/ps/PSSVGHandler.java273
-rw-r--r--src/java/org/apache/fop/render/xml/XMLXMLHandler.java7
-rw-r--r--src/sandbox/org/apache/fop/render/svg/SVGRenderer.java79
-rw-r--r--src/sandbox/org/apache/fop/render/svg/SVGRendererContextConstants.java34
-rw-r--r--src/sandbox/org/apache/fop/render/svg/SVGSVGHandler.java80
-rw-r--r--status.xml8
21 files changed, 779 insertions, 583 deletions
diff --git a/build.xml b/build.xml
index da75a8911..6f22ae3c9 100644
--- a/build.xml
+++ b/build.xml
@@ -376,6 +376,11 @@ list of possible build targets.
<patternset refid="exclude-jimi"/>
<classpath refid="libs-build-classpath"/>
</javac>
+ <copy todir="${build.classes.dir}">
+ <fileset dir="${src.java.dir}">
+ <include name="META-INF/**"/>
+ </fileset>
+ </copy>
<mkdir dir="${build.viewer.resources.dir}"/>
<copy todir="${build.viewer.resources.dir}">
<fileset dir="${src.viewer.resources.dir}"/>
@@ -451,7 +456,7 @@ list of possible build targets.
<tstamp>
<format property="ts" pattern="yyyyMMdd-HHmmss-z"/>
</tstamp>
- <jar jarfile="${build.dir}/fop.jar" basedir="${build.classes.dir}" includes="org/**">
+ <jar jarfile="${build.dir}/fop.jar" basedir="${build.classes.dir}">
<manifest>
<attribute name="Main-Class" value="org.apache.fop.cli.Main"/>
<attribute name="Build-Id" value="${ts} (${user.name} [${os.name} ${os.version} ${os.arch}, Java ${java.runtime.version}])"/>
diff --git a/conf/fop.xconf b/conf/fop.xconf
index 243226574..c542c8953 100644
--- a/conf/fop.xconf
+++ b/conf/fop.xconf
@@ -79,14 +79,18 @@ the location of this file.
-->
</fonts>
- <xmlHandler mime="text/svg+xml">
- </xmlHandler>
+ <!-- This option lets you specify additional options on an XML handler -->
+ <!--xml-handler namespace="http://www.w3.org/2000/svg">
+ <stroke-text>false</stroke-text>
+ </xml-handler-->
</renderer>
<renderer mime="application/postscript">
- <xmlHandler mime="image/svg+xml">
- </xmlHandler>
+ <!-- This option lets you specify additional options on an XML handler -->
+ <!--xml-handler namespace="http://www.w3.org/2000/svg">
+ <stroke-text>false</stroke-text>
+ </xml-handler-->
</renderer>
<renderer mime="application/vnd.hp-PCL">
diff --git a/src/java/META-INF/services/org.apache.fop.render.XMLHandler b/src/java/META-INF/services/org.apache.fop.render.XMLHandler
new file mode 100644
index 000000000..96c44118c
--- /dev/null
+++ b/src/java/META-INF/services/org.apache.fop.render.XMLHandler
@@ -0,0 +1,3 @@
+org.apache.fop.render.pdf.PDFSVGHandler
+org.apache.fop.render.ps.PSSVGHandler
+org.apache.fop.render.java2d.Java2DSVGHandler \ No newline at end of file
diff --git a/src/java/org/apache/fop/render/AbstractRenderer.java b/src/java/org/apache/fop/render/AbstractRenderer.java
index 3192cce1d..bb84fde27 100644
--- a/src/java/org/apache/fop/render/AbstractRenderer.java
+++ b/src/java/org/apache/fop/render/AbstractRenderer.java
@@ -19,7 +19,6 @@
package org.apache.fop.render;
// Java
-import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
@@ -767,6 +766,39 @@ public abstract class AbstractRenderer
}
/**
+ * Returns the configuration subtree for a specific renderer.
+ * @param cfg the renderer configuration
+ * @param namespace the namespace (i.e. the XMLHandler) for which the configuration should
+ * be returned
+ * @return the requested configuration subtree, null if there's no configuration
+ */
+ public static Configuration getHandlerConfig(Configuration cfg, String namespace) {
+
+ if (cfg == null || namespace == null) {
+ return null;
+ }
+
+ Configuration handlerConfig = null;
+
+ Configuration[] children = cfg.getChildren("xml-handler");
+ for (int i = 0; i < children.length; ++i) {
+ try {
+ if (children[i].getAttribute("namespace").equals(namespace)) {
+ handlerConfig = children[i];
+ break;
+ }
+ } catch (ConfigurationException e) {
+ // silently pass over configurations without namespace
+ }
+ }
+ if (log.isDebugEnabled()) {
+ log.debug((handlerConfig == null ? "No" : "")
+ + "XML handler configuration found for namespace " + namespace);
+ }
+ return handlerConfig;
+ }
+
+ /**
* Render the xml document with the given xml namespace.
* The Render Context is by the handle to render into the current
* rendering target.
@@ -776,11 +808,19 @@ public abstract class AbstractRenderer
*/
public void renderXML(RendererContext ctx, Document doc,
String namespace) {
- String mime = ctx.getMimeType();
XMLHandler handler = userAgent.getXMLHandlerRegistry().getXMLHandler(
- mime, namespace);
+ this, namespace);
if (handler != null) {
try {
+ //Optional XML handler configuration
+ Configuration cfg = userAgent.getUserRendererConfig(getMimeType());
+ if (cfg != null) {
+ cfg = getHandlerConfig(cfg, namespace);
+ if (cfg != null) {
+ ctx.setProperty(RendererContextConstants.HANDLER_CONFIGURATION, cfg);
+ }
+ }
+
handler.handleXML(ctx, doc, namespace);
} catch (Throwable t) {
// could not handle document
diff --git a/src/java/org/apache/fop/render/RendererContextConstants.java b/src/java/org/apache/fop/render/RendererContextConstants.java
new file mode 100644
index 000000000..1d219cab2
--- /dev/null
+++ b/src/java/org/apache/fop/render/RendererContextConstants.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2005 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.render;
+
+/**
+ * Defines a number of standard constants (keys) for use by the RendererContext class.
+ */
+public interface RendererContextConstants {
+
+ /** The output stream that the document is being sent to. */
+ String OUTPUT_STREAM = "outputStream";
+
+ /** The target width of the image being painted. */
+ String WIDTH = "width";
+
+ /** The target height of the image being painted. */
+ String HEIGHT = "height";
+
+ /** The x position that this image is being drawn at. */
+ String XPOS = "xpos";
+
+ /** The y position that this image is being drawn at. */
+ String YPOS = "ypos";
+
+ /** The configuration for the XMLHandler. */
+ String HANDLER_CONFIGURATION = "cfg";
+
+}
diff --git a/src/java/org/apache/fop/render/XMLHandler.java b/src/java/org/apache/fop/render/XMLHandler.java
index 683479e93..f1740594a 100644
--- a/src/java/org/apache/fop/render/XMLHandler.java
+++ b/src/java/org/apache/fop/render/XMLHandler.java
@@ -49,9 +49,11 @@ public interface XMLHandler {
Document doc, String ns) throws Exception;
/**
- * @return the MIME type for which this XMLHandler was written
+ * Checks if this XMLHandler supports handling an XML namespace for a particular renderer.
+ * @param renderer the renderer for which to check.
+ * @return true if this XML handler supports a particular renderer
*/
- String getMimeType();
+ boolean supportsRenderer(Renderer renderer);
/**
* @return the XML namespace for the XML dialect this XMLHandler supports,
diff --git a/src/java/org/apache/fop/render/XMLHandlerRegistry.java b/src/java/org/apache/fop/render/XMLHandlerRegistry.java
index 5712ca3fa..e033c2d4e 100644
--- a/src/java/org/apache/fop/render/XMLHandlerRegistry.java
+++ b/src/java/org/apache/fop/render/XMLHandlerRegistry.java
@@ -19,6 +19,7 @@
package org.apache.fop.render;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
@@ -38,7 +39,6 @@ public class XMLHandlerRegistry {
/** Map containing XML handlers for various document types */
private Map handlers = new java.util.HashMap();
-
/**
* Default constructor.
*/
@@ -47,13 +47,11 @@ public class XMLHandlerRegistry {
}
/**
- * Set the default XML handler for the given MIME type.
- * @param mime MIME type
+ * Add a default XML handler which is able to handle any namespace.
* @param handler XMLHandler to use
*/
- private void setDefaultXMLHandler(String mime,
- XMLHandler handler) {
- addXMLHandler(mime, XMLHandler.HANDLE_ALL, handler);
+ private void setDefaultXMLHandler(XMLHandler handler) {
+ addXMLHandler(XMLHandler.HANDLE_ALL, handler);
}
/**
@@ -62,8 +60,7 @@ public class XMLHandlerRegistry {
*/
public void addXMLHandler(String classname) {
try {
- XMLHandler handlerInstance =
- (XMLHandler)Class.forName(classname).newInstance();
+ XMLHandler handlerInstance = (XMLHandler)Class.forName(classname).newInstance();
addXMLHandler(handlerInstance);
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Could not find "
@@ -86,58 +83,53 @@ public class XMLHandlerRegistry {
* @param handler the XMLHandler instance
*/
public void addXMLHandler(XMLHandler handler) {
- String mime = handler.getMimeType();
String ns = handler.getNamespace();
if (ns == null) {
- setDefaultXMLHandler(mime, handler);
+ setDefaultXMLHandler(handler);
} else {
- addXMLHandler(mime, ns, handler);
+ addXMLHandler(ns, handler);
}
}
/**
* Add an XML handler for the given MIME type and XML namespace.
- * @param mime MIME type
* @param ns Namespace URI
* @param handler XMLHandler to use
*/
- private void addXMLHandler(String mime, String ns,
+ private void addXMLHandler(String ns,
XMLHandler handler) {
- Map mh = (Map)handlers.get(mime);
- if (mh == null) {
- mh = new java.util.HashMap();
- handlers.put(mime, mh);
+ List lst = (List)handlers.get(ns);
+ if (lst == null) {
+ lst = new java.util.ArrayList();
+ handlers.put(ns, lst);
}
- mh.put(ns, handler);
+ lst.add(handler);
}
/**
* Returns an XMLHandler which handles an XML dialect of the given namespace and for
* a specified output format defined by its MIME type.
- * @param mime the MIME type of the output format
+ * @param renderer the Renderer for which to retrieve a Renderer
* @param ns the XML namespace associated with the XML to be rendered
* @return the XMLHandler responsible for handling the XML or null if none is available
*/
- public XMLHandler getXMLHandler(String mime, String ns) {
- XMLHandler handler = null;
+ public XMLHandler getXMLHandler(Renderer renderer, String ns) {
+ XMLHandler handler;
- Map mh = (Map)handlers.get(mime);
- if (mh != null) {
- handler = (XMLHandler)mh.get(ns);
- if (handler == null) {
- handler = (XMLHandler)mh.get(XMLHandler.HANDLE_ALL);
- }
+ List lst = (List)handlers.get(ns);
+ if (lst == null) {
+ lst = (List)handlers.get(XMLHandler.HANDLE_ALL);
}
- if (handler == null) {
- mh = (Map)handlers.get(XMLHandler.HANDLE_ALL);
- if (mh != null) {
- handler = (XMLHandler)mh.get(ns);
- if (handler == null) {
- handler = (XMLHandler)mh.get(XMLHandler.HANDLE_ALL);
+ if (lst != null) {
+ for (int i = 0, c = lst.size(); i < c; i++) {
+ //TODO Maybe add priorities later
+ handler = (XMLHandler)lst.get(i);
+ if (handler.supportsRenderer(renderer)) {
+ return handler;
}
}
}
- return handler;
+ return null; //No handler found
}
@@ -147,8 +139,7 @@ public class XMLHandlerRegistry {
*/
private void discoverXMLHandlers() {
// add mappings from available services
- Iterator providers =
- Service.providers(XMLHandler.class);
+ Iterator providers = Service.providers(XMLHandler.class);
if (providers != null) {
while (providers.hasNext()) {
String str = (String)providers.next();
diff --git a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java
index b1fc3568d..9b0e76f33 100644
--- a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java
+++ b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java
@@ -155,8 +155,6 @@ public abstract class Java2DRenderer extends AbstractRenderer implements Printab
*/
public void setUserAgent(FOUserAgent foUserAgent) {
super.setUserAgent(foUserAgent);
- Java2DSVGHandler xmlHandler = new Java2DSVGHandler(getMimeType());
- userAgent.getXMLHandlerRegistry().addXMLHandler(xmlHandler);
userAgent.setRendererOverride(this); // for document regeneration
}
@@ -1148,14 +1146,14 @@ public abstract class Java2DRenderer extends AbstractRenderer implements Printab
context = new RendererContext(this, getMimeType());
context.setUserAgent(userAgent);
- context.setProperty(Java2DSVGHandler.JAVA2D_STATE, state);
- context.setProperty(Java2DSVGHandler.JAVA2D_XPOS,
+ context.setProperty(Java2DRendererContextConstants.JAVA2D_STATE, state);
+ context.setProperty(Java2DRendererContextConstants.XPOS,
new Integer(currentIPPosition + (int)pos.getX()));
- context.setProperty(Java2DSVGHandler.JAVA2D_YPOS,
+ context.setProperty(Java2DRendererContextConstants.YPOS,
new Integer(currentBPPosition + (int)pos.getY()));
- context.setProperty(Java2DSVGHandler.JAVA2D_WIDTH,
+ context.setProperty(Java2DRendererContextConstants.WIDTH,
new Integer((int)pos.getWidth()));
- context.setProperty(Java2DSVGHandler.JAVA2D_HEIGHT,
+ context.setProperty(Java2DRendererContextConstants.HEIGHT,
new Integer((int) pos.getHeight()));
renderXML(context, doc, ns);
diff --git a/src/java/org/apache/fop/render/java2d/Java2DRendererContextConstants.java b/src/java/org/apache/fop/render/java2d/Java2DRendererContextConstants.java
new file mode 100644
index 000000000..9480c1520
--- /dev/null
+++ b/src/java/org/apache/fop/render/java2d/Java2DRendererContextConstants.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2005 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.render.java2d;
+
+import org.apache.fop.render.RendererContextConstants;
+
+/**
+ * Defines a number of standard constants (keys) for use by the RendererContext class.
+ */
+public interface Java2DRendererContextConstants extends
+ RendererContextConstants {
+
+ /** The current Java2DGraphicsState. */
+ String JAVA2D_STATE = "state";
+
+}
diff --git a/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java b/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java
index fbf8382eb..c7fc7e9d3 100644
--- a/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java
+++ b/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java
@@ -18,79 +18,50 @@
package org.apache.fop.render.java2d;
+import java.awt.geom.AffineTransform;
+
+import org.w3c.dom.Document;
+
+import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.render.Renderer;
import org.apache.fop.render.XMLHandler;
import org.apache.fop.render.RendererContext;
+import org.apache.fop.render.pdf.PDFRenderer;
import org.apache.fop.svg.SVGUserAgent;
// Commons-Logging
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-/* org.w3c.dom.Document is not imported to avoid conflict with
- org.apache.fop.apps.Document */
-
import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.gvt.GraphicsNode;
-import java.awt.geom.AffineTransform;
-
/**
* Java2D XML handler for SVG (uses Apache Batik).
* This handler handles XML for foreign objects when rendering to Java2D.
* The properties from the Java2D renderer are subject to change.
*/
-public class Java2DSVGHandler implements XMLHandler {
-
- /**
- * logging instance
- */
- private Log log = LogFactory.getLog(Java2DSVGHandler.class);
-
- /**
- * The current Java2DGraphicsState.
- */
- public static final String JAVA2D_STATE = "state";
-
- /**
- * The width of the svg image/document to render.
- */
- public static final String JAVA2D_WIDTH = "width";
+public class Java2DSVGHandler implements XMLHandler, Java2DRendererContextConstants {
- /**
- * The height of the svg image/document to render.
- */
- public static final String JAVA2D_HEIGHT = "height";
-
- /**
- * The x position that this is being drawn at.
- */
- public static final String JAVA2D_XPOS = "xpos";
+ /** logging instance */
+ private static Log log = LogFactory.getLog(Java2DSVGHandler.class);
/**
- * The y position that this is being drawn at.
+ * Create a new Java2D XML handler for use by the Java2D renderer and its subclasses.
*/
- public static final String JAVA2D_YPOS = "ypos";
-
- private String mimeType;
-
- /**
- * Create a new Java2D XML handler for use by the Java2D renderer.
- * @param mime MIME type that this handler is used for
- */
- public Java2DSVGHandler(String mime) {
- this.mimeType = mime;
+ public Java2DSVGHandler() {
+ //nop
}
/** @see org.apache.fop.render.XMLHandler */
public void handleXML(RendererContext context,
- org.w3c.dom.Document doc, String ns) throws Exception {
+ Document doc, String ns) throws Exception {
Java2DInfo pdfi = getJava2DInfo(context);
if (SVGDOMImplementation.SVG_NAMESPACE_URI.equals(ns)) {
- SVGHandler svghandler = new SVGHandler();
- svghandler.renderSVGDocument(context, doc, pdfi);
+ renderSVGDocument(context, doc, pdfi);
}
}
@@ -103,10 +74,10 @@ public class Java2DSVGHandler implements XMLHandler {
public static Java2DInfo getJava2DInfo(RendererContext context) {
Java2DInfo pdfi = new Java2DInfo();
pdfi.state = (Java2DGraphicsState)context.getProperty(JAVA2D_STATE);
- pdfi.width = ((Integer)context.getProperty(JAVA2D_WIDTH)).intValue();
- pdfi.height = ((Integer)context.getProperty(JAVA2D_HEIGHT)).intValue();
- pdfi.currentXPosition = ((Integer)context.getProperty(JAVA2D_XPOS)).intValue();
- pdfi.currentYPosition = ((Integer)context.getProperty(JAVA2D_YPOS)).intValue();
+ pdfi.width = ((Integer)context.getProperty(WIDTH)).intValue();
+ pdfi.height = ((Integer)context.getProperty(HEIGHT)).intValue();
+ pdfi.currentXPosition = ((Integer)context.getProperty(XPOS)).intValue();
+ pdfi.currentYPosition = ((Integer)context.getProperty(YPOS)).intValue();
return pdfi;
}
@@ -137,75 +108,69 @@ public class Java2DSVGHandler implements XMLHandler {
}
/**
- * This method is placed in an inner class so that we don't get class
- * loading errors if batik is not present.
+ * Render the svg document.
+ * @param context the renderer context
+ * @param doc the svg document
+ * @param info the pdf information of the current context
*/
- protected class SVGHandler {
+ protected void renderSVGDocument(RendererContext context,
+ Document doc,
+ Java2DInfo info) {
+
+ log.debug("renderSVGDocument(" + context + ", " + doc + ", " + info + ")");
+
+ int x = info.currentXPosition;
+ int y = info.currentYPosition;
+
+ float ptom = context.getUserAgent().getSourcePixelUnitToMillimeter();
+ SVGUserAgent ua = new SVGUserAgent(ptom, new AffineTransform());
- /**
- * Render the svg document.
- * @param context the renderer context
- * @param doc the svg document
- * @param info the pdf information of the current context
- */
- protected void renderSVGDocument(RendererContext context,
- org.w3c.dom.Document doc,
- Java2DInfo info) {
-
- log.debug("renderSVGDocument(" + context + ", " + doc + ", " + info + ")");
-
- int x = info.currentXPosition;
- int y = info.currentYPosition;
-
- float ptom = context.getUserAgent().getSourcePixelUnitToMillimeter();
- SVGUserAgent ua = new SVGUserAgent(ptom, new AffineTransform());
-
- GVTBuilder builder = new GVTBuilder();
- BridgeContext ctx = new BridgeContext(ua);
-
- GraphicsNode root;
- try {
- root = builder.build(ctx, doc);
- } catch (Exception e) {
- log.error("SVG graphic could not be built: " + e.getMessage(), e);
- return;
- }
-
- // If no viewbox is defined in the svg file, a viewbox of 100x100 is
- // assumed, as defined in SVGUserAgent.getViewportSize()
- float iw = (float) ctx.getDocumentSize().getWidth() * 1000f;
- float ih = (float) ctx.getDocumentSize().getHeight() * 1000f;
-
- float w = (float) info.width;
- float h = (float) info.height;
-
- AffineTransform origTransform = info.state.getGraph().getTransform();
-
- // correct integer roundoff
- info.state.getGraph().translate(x / 1000f, y / 1000f);
-
- //SVGSVGElement svg = ((SVGDocument) doc).getRootElement();
- // Aspect ratio preserved by layout engine, not here
- AffineTransform at = AffineTransform.getScaleInstance(w / iw, h / ih);
- if (!at.isIdentity()) {
- info.state.getGraph().transform(at);
- }
-
- try {
- root.paint(info.state.getGraph());
- } catch (Exception e) {
- log.error("Error while painting SVG", e);
- }
-
- info.state.getGraph().setTransform(origTransform);
+ GVTBuilder builder = new GVTBuilder();
+ BridgeContext ctx = new BridgeContext(ua);
+
+ GraphicsNode root;
+ try {
+ root = builder.build(ctx, doc);
+ } catch (Exception e) {
+ log.error("SVG graphic could not be built: " + e.getMessage(), e);
+ return;
}
+
+ // If no viewbox is defined in the svg file, a viewbox of 100x100 is
+ // assumed, as defined in SVGUserAgent.getViewportSize()
+ float iw = (float) ctx.getDocumentSize().getWidth() * 1000f;
+ float ih = (float) ctx.getDocumentSize().getHeight() * 1000f;
+
+ float w = (float) info.width;
+ float h = (float) info.height;
+
+ AffineTransform origTransform = info.state.getGraph().getTransform();
+
+ // correct integer roundoff
+ info.state.getGraph().translate(x / 1000f, y / 1000f);
+
+ //SVGSVGElement svg = ((SVGDocument) doc).getRootElement();
+ // Aspect ratio preserved by layout engine, not here
+ AffineTransform at = AffineTransform.getScaleInstance(w / iw, h / ih);
+ if (!at.isIdentity()) {
+ info.state.getGraph().transform(at);
+ }
+
+ try {
+ root.paint(info.state.getGraph());
+ } catch (Exception e) {
+ log.error("Error while painting SVG", e);
+ }
+
+ info.state.getGraph().setTransform(origTransform);
}
- /** @see org.apache.fop.render.XMLHandler#getMimeType() */
- public String getMimeType() {
- return this.mimeType;
+ /** @see org.apache.fop.render.XMLHandler#supportsRenderer() */
+ public boolean supportsRenderer(Renderer renderer) {
+ return (renderer instanceof Java2DRenderer);
}
+
/** @see org.apache.fop.render.XMLHandler#getNamespace() */
public String getNamespace() {
return SVGDOMImplementation.SVG_NAMESPACE_URI;
diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java
index c2e31b0c5..66d46b7e2 100644
--- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java
+++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java
@@ -234,8 +234,6 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
*/
public void setUserAgent(FOUserAgent agent) {
super.setUserAgent(agent);
- PDFSVGHandler xmlHandler = new PDFSVGHandler();
- userAgent.getXMLHandlerRegistry().addXMLHandler(xmlHandler);
}
/**
@@ -1468,25 +1466,25 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
context = new RendererContext(this, MIME_TYPE);
context.setUserAgent(userAgent);
- context.setProperty(PDFSVGHandler.PDF_DOCUMENT, pdfDoc);
- context.setProperty(PDFSVGHandler.OUTPUT_STREAM, ostream);
- context.setProperty(PDFSVGHandler.PDF_STATE, currentState);
- context.setProperty(PDFSVGHandler.PDF_PAGE, currentPage);
- context.setProperty(PDFSVGHandler.PDF_CONTEXT,
+ context.setProperty(PDFRendererContextConstants.PDF_DOCUMENT, pdfDoc);
+ context.setProperty(PDFRendererContextConstants.OUTPUT_STREAM, ostream);
+ context.setProperty(PDFRendererContextConstants.PDF_STATE, currentState);
+ context.setProperty(PDFRendererContextConstants.PDF_PAGE, currentPage);
+ context.setProperty(PDFRendererContextConstants.PDF_CONTEXT,
currentContext == null ? currentPage : currentContext);
- context.setProperty(PDFSVGHandler.PDF_CONTEXT, currentContext);
- context.setProperty(PDFSVGHandler.PDF_STREAM, currentStream);
- context.setProperty(PDFSVGHandler.PDF_XPOS,
+ context.setProperty(PDFRendererContextConstants.PDF_CONTEXT, currentContext);
+ context.setProperty(PDFRendererContextConstants.PDF_STREAM, currentStream);
+ context.setProperty(PDFRendererContextConstants.XPOS,
new Integer(currentIPPosition + (int) pos.getX()));
- context.setProperty(PDFSVGHandler.PDF_YPOS,
+ context.setProperty(PDFRendererContextConstants.YPOS,
new Integer(currentBPPosition + (int) pos.getY()));
- context.setProperty(PDFSVGHandler.PDF_FONT_INFO, fontInfo);
- context.setProperty(PDFSVGHandler.PDF_FONT_NAME, currentFontName);
- context.setProperty(PDFSVGHandler.PDF_FONT_SIZE,
+ context.setProperty(PDFRendererContextConstants.PDF_FONT_INFO, fontInfo);
+ context.setProperty(PDFRendererContextConstants.PDF_FONT_NAME, currentFontName);
+ context.setProperty(PDFRendererContextConstants.PDF_FONT_SIZE,
new Integer(currentFontSize));
- context.setProperty(PDFSVGHandler.PDF_WIDTH,
+ context.setProperty(PDFRendererContextConstants.WIDTH,
new Integer((int) pos.getWidth()));
- context.setProperty(PDFSVGHandler.PDF_HEIGHT,
+ context.setProperty(PDFRendererContextConstants.HEIGHT,
new Integer((int) pos.getHeight()));
renderXML(context, doc, ns);
diff --git a/src/java/org/apache/fop/render/pdf/PDFRendererContextConstants.java b/src/java/org/apache/fop/render/pdf/PDFRendererContextConstants.java
new file mode 100644
index 000000000..f2144dfe3
--- /dev/null
+++ b/src/java/org/apache/fop/render/pdf/PDFRendererContextConstants.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2005 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.render.pdf;
+
+import org.apache.fop.render.RendererContextConstants;
+
+/**
+ * Defines a number of standard constants (keys) for use by the RendererContext class.
+ */
+public interface PDFRendererContextConstants extends RendererContextConstants {
+
+ /** The PDF document that this image is being drawn into. */
+ String PDF_DOCUMENT = "pdfDoc";
+
+ /** The current pdf state. */
+ String PDF_STATE = "pdfState";
+
+ /** The current PDF page for page renference and as a resource context. */
+ String PDF_PAGE = "pdfPage";
+
+ /** The current PDF page for page renference and as a resource context. */
+ String PDF_CONTEXT = "pdfContext";
+
+ /** The current PDF stream to draw directly to. */
+ String PDF_STREAM = "pdfStream";
+
+ /** The current font information for the pdf renderer. */
+ String PDF_FONT_INFO = "fontInfo";
+
+ /** The current pdf font name. */
+ String PDF_FONT_NAME = "fontName";
+
+ /** The current pdf font size. */
+ String PDF_FONT_SIZE = "fontSize";
+
+}
diff --git a/src/java/org/apache/fop/render/pdf/PDFSVGHandler.java b/src/java/org/apache/fop/render/pdf/PDFSVGHandler.java
index 673cd0cdb..af93477d5 100644
--- a/src/java/org/apache/fop/render/pdf/PDFSVGHandler.java
+++ b/src/java/org/apache/fop/render/pdf/PDFSVGHandler.java
@@ -18,6 +18,15 @@
package org.apache.fop.render.pdf;
+import java.io.OutputStream;
+import java.awt.Color;
+import java.awt.geom.AffineTransform;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.svg.SVGDocument;
+import org.w3c.dom.svg.SVGSVGElement;
+
+import org.apache.fop.render.Renderer;
import org.apache.fop.render.XMLHandler;
import org.apache.fop.render.RendererContext;
import org.apache.fop.pdf.PDFDocument;
@@ -35,102 +44,25 @@ import org.apache.fop.fonts.FontInfo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-
-/* org.w3c.dom.Document is not imported to avoid conflict with
- org.apache.fop.apps.Document */
-
-import java.io.OutputStream;
+import org.apache.avalon.framework.configuration.Configuration;
import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.ViewBox;
import org.apache.batik.dom.svg.SVGDOMImplementation;
-
import org.apache.batik.gvt.GraphicsNode;
-import org.w3c.dom.svg.SVGDocument;
-import org.w3c.dom.svg.SVGSVGElement;
-
-import java.awt.Color;
-import java.awt.geom.AffineTransform;
-
/**
* PDF XML handler for SVG (uses Apache Batik).
* This handler handles XML for foreign objects when rendering to PDF.
* It renders SVG to the PDF document using the PDFGraphics2D.
* The properties from the PDF renderer are subject to change.
*/
-public class PDFSVGHandler implements XMLHandler {
+public class PDFSVGHandler implements XMLHandler, PDFRendererContextConstants {
- /**
- * logging instance
- */
- private Log log = LogFactory.getLog(PDFSVGHandler.class);
+ /** logging instance */
+ private static Log log = LogFactory.getLog(PDFSVGHandler.class);
- /**
- * The PDF document that is being drawn into.
- */
- public static final String PDF_DOCUMENT = "pdfDoc";
-
- /**
- * The output stream that the document is being sent to.
- */
- public static final String OUTPUT_STREAM = "outputStream";
-
- /**
- * The current pdf state.
- */
- public static final String PDF_STATE = "pdfState";
-
- /**
- * The current PDF page for page renference and as a resource context.
- */
- public static final String PDF_PAGE = "pdfPage";
-
- /**
- * The current PDF page for page renference and as a resource context.
- */
- public static final String PDF_CONTEXT = "pdfContext";
-
- /**
- * The current PDF stream to draw directly to.
- */
- public static final String PDF_STREAM = "pdfStream";
-
- /**
- * The width of the current pdf page.
- */
- public static final String PDF_WIDTH = "width";
-
- /**
- * The height of the current pdf page.
- */
- public static final String PDF_HEIGHT = "height";
-
- /**
- * The current font information for the pdf renderer.
- */
- public static final String PDF_FONT_INFO = "fontInfo";
-
- /**
- * The current pdf font name.
- */
- public static final String PDF_FONT_NAME = "fontName";
-
- /**
- * The current pdf font size.
- */
- public static final String PDF_FONT_SIZE = "fontSize";
-
- /**
- * The x position that this is being drawn at.
- */
- public static final String PDF_XPOS = "xpos";
-
- /**
- * The y position that this is being drawn at.
- */
- public static final String PDF_YPOS = "ypos";
/**
* Create a new PDF XML handler for use by the PDF renderer.
@@ -140,13 +72,12 @@ public class PDFSVGHandler implements XMLHandler {
/** @see org.apache.fop.render.XMLHandler */
public void handleXML(RendererContext context,
- org.w3c.dom.Document doc, String ns) throws Exception {
+ Document doc, String ns) throws Exception {
PDFInfo pdfi = getPDFInfo(context);
String svg = "http://www.w3.org/2000/svg";
if (svg.equals(ns)) {
- SVGHandler svghandler = new SVGHandler();
- svghandler.renderSVGDocument(context, doc, pdfi);
+ renderSVGDocument(context, doc, pdfi);
}
}
@@ -164,13 +95,14 @@ public class PDFSVGHandler implements XMLHandler {
pdfi.pdfPage = (PDFPage)context.getProperty(PDF_PAGE);
pdfi.pdfContext = (PDFResourceContext)context.getProperty(PDF_CONTEXT);
pdfi.currentStream = (PDFStream)context.getProperty(PDF_STREAM);
- pdfi.width = ((Integer)context.getProperty(PDF_WIDTH)).intValue();
- pdfi.height = ((Integer)context.getProperty(PDF_HEIGHT)).intValue();
- pdfi.fi = (FontInfo) context.getProperty(PDF_FONT_INFO);
+ pdfi.width = ((Integer)context.getProperty(WIDTH)).intValue();
+ pdfi.height = ((Integer)context.getProperty(HEIGHT)).intValue();
+ pdfi.fi = (FontInfo)context.getProperty(PDF_FONT_INFO);
pdfi.currentFontName = (String)context.getProperty(PDF_FONT_NAME);
pdfi.currentFontSize = ((Integer)context.getProperty(PDF_FONT_SIZE)).intValue();
- pdfi.currentXPosition = ((Integer)context.getProperty(PDF_XPOS)).intValue();
- pdfi.currentYPosition = ((Integer)context.getProperty(PDF_YPOS)).intValue();
+ pdfi.currentXPosition = ((Integer)context.getProperty(XPOS)).intValue();
+ pdfi.currentYPosition = ((Integer)context.getProperty(YPOS)).intValue();
+ pdfi.cfg = (Configuration)context.getProperty(HANDLER_CONFIGURATION);
return pdfi;
}
@@ -204,134 +136,135 @@ public class PDFSVGHandler implements XMLHandler {
public int currentXPosition;
/** see PDF_YPOS */
public int currentYPosition;
+ /** see PDF_HANDLER_CONFIGURATION */
+ public Configuration cfg;
}
/**
- * This method is placed in an inner class so that we don't get class
- * loading errors if batik is not present.
+ * Render the svg document.
+ * @param context the renderer context
+ * @param doc the svg document
+ * @param pdfInfo the pdf information of the current context
*/
- protected class SVGHandler {
- /**
- * Render the svg document.
- * @param context the renderer context
- * @param doc the svg document
- * @param pdfInfo the pdf information of the current context
- */
- protected void renderSVGDocument(RendererContext context,
- org.w3c.dom.Document doc, PDFInfo pdfInfo) {
- int xOffset = pdfInfo.currentXPosition;
- int yOffset = pdfInfo.currentYPosition;
-
- log.debug("Generating SVG at "
- + context.getUserAgent().getTargetResolution()
- + "dpi.");
- final float deviceResolution = context.getUserAgent().getTargetResolution();
-
- final float uaResolution = context.getUserAgent().getSourceResolution();
- SVGUserAgent ua = new SVGUserAgent(25.4f / uaResolution, new AffineTransform());
-
- GVTBuilder builder = new GVTBuilder();
-
- //TODO This AffineTransform here has to be fixed!!!
- AffineTransform linkTransform = pdfInfo.pdfState.getTransform();
- linkTransform.translate(xOffset / 1000f, yOffset / 1000f);
-
- final boolean strokeText = false;
- BridgeContext ctx = new PDFBridgeContext(ua,
- (strokeText ? null : pdfInfo.fi),
- linkTransform);
-
- GraphicsNode root;
- try {
- root = builder.build(ctx, doc);
- } catch (Exception e) {
- log.error("svg graphic could not be built: "
- + e.getMessage(), e);
- return;
- }
- // get the 'width' and 'height' attributes of the SVG document
- float w = (float)ctx.getDocumentSize().getWidth() * 1000f;
- float h = (float)ctx.getDocumentSize().getHeight() * 1000f;
-
- float sx = pdfInfo.width / (float)w;
- float sy = pdfInfo.height / (float)h;
-
- ctx = null;
- builder = null;
-
- /*
- * Clip to the svg area.
- * Note: To have the svg overlay (under) a text area then use
- * an fo:block-container
- */
- PDFRenderer renderer = (PDFRenderer)context.getRenderer();
- renderer.saveGraphicsState();
- renderer.setColor(Color.black, false, null);
- renderer.setColor(Color.black, true, null);
- // transform so that the coordinates (0,0) is from the top left
- // and positive is down and to the right. (0,0) is where the
- // viewBox puts it.
- pdfInfo.currentStream.add(sx + " 0 0 " + sy + " " + xOffset / 1000f + " "
- + yOffset / 1000f + " cm\n");
-
- SVGSVGElement svg = ((SVGDocument)doc).getRootElement();
- //AffineTransform at = ViewBox.getPreserveAspectRatioTransform(
- // svg, w / 1000f, h / 1000f);
- AffineTransform at = ViewBox.getPreserveAspectRatioTransform(svg,
- pdfInfo.width / 1000f, pdfInfo.height / 1000f);
- /*
- if (!at.isIdentity()) {
- double[] vals = new double[6];
- at.getMatrix(vals);
- pdfInfo.currentStream.add(CTMHelper.toPDFString(at, false) + " cm\n");
- }*/
+ protected void renderSVGDocument(RendererContext context,
+ Document doc, PDFInfo pdfInfo) {
+ int xOffset = pdfInfo.currentXPosition;
+ int yOffset = pdfInfo.currentYPosition;
+
+ log.debug("Generating SVG at "
+ + context.getUserAgent().getTargetResolution()
+ + "dpi.");
+ final float deviceResolution = context.getUserAgent().getTargetResolution();
+
+ final float uaResolution = context.getUserAgent().getSourceResolution();
+ SVGUserAgent ua = new SVGUserAgent(25.4f / uaResolution, new AffineTransform());
+
+ GVTBuilder builder = new GVTBuilder();
+
+ //TODO This AffineTransform here has to be fixed!!!
+ AffineTransform linkTransform = pdfInfo.pdfState.getTransform();
+ linkTransform.translate(xOffset / 1000f, yOffset / 1000f);
+
+ //Controls whether text painted by Batik is generated using text or path operations
+ boolean strokeText = false;
+ Configuration cfg = pdfInfo.cfg;
+ if (cfg != null) {
+ strokeText = cfg.getChild("stroke-text", true).getValueAsBoolean(strokeText);
+ }
+
+ BridgeContext ctx = new PDFBridgeContext(ua,
+ (strokeText ? null : pdfInfo.fi),
+ linkTransform);
+
+ GraphicsNode root;
+ try {
+ root = builder.build(ctx, doc);
+ } catch (Exception e) {
+ log.error("svg graphic could not be built: "
+ + e.getMessage(), e);
+ return;
+ }
+ // get the 'width' and 'height' attributes of the SVG document
+ float w = (float)ctx.getDocumentSize().getWidth() * 1000f;
+ float h = (float)ctx.getDocumentSize().getHeight() * 1000f;
- if (pdfInfo.pdfContext == null) {
- pdfInfo.pdfContext = pdfInfo.pdfPage;
- }
- PDFGraphics2D graphics = new PDFGraphics2D(true, pdfInfo.fi, pdfInfo.pdfDoc,
- pdfInfo.pdfContext, pdfInfo.pdfPage.referencePDF(),
- pdfInfo.currentFontName,
- pdfInfo.currentFontSize);
- graphics.setGraphicContext(new org.apache.batik.ext.awt.g2d.GraphicContext());
- pdfInfo.pdfState.push();
- AffineTransform transform = new AffineTransform();
- // scale to viewbox
- transform.translate(xOffset / 1000f, yOffset / 1000f);
+ float sx = pdfInfo.width / (float)w;
+ float sy = pdfInfo.height / (float)h;
- if (deviceResolution != uaResolution) {
- //Scale for higher resolution on-the-fly images from Batik
- double s = uaResolution / deviceResolution;
- at.scale(s, s);
- pdfInfo.currentStream.add("" + PDFNumber.doubleOut(s) + " 0 0 "
- + PDFNumber.doubleOut(s) + " 0 0 cm\n");
- graphics.scale(1 / s, 1 / s);
- }
+ ctx = null;
+ builder = null;
- pdfInfo.pdfState.setTransform(transform);
- graphics.setPDFState(pdfInfo.pdfState);
- graphics.setOutputStream(pdfInfo.outputStream);
- try {
- root.paint(graphics);
- pdfInfo.currentStream.add(graphics.getString());
- } catch (Exception e) {
- log.error("svg graphic could not be rendered: "
- + e.getMessage(), e);
- }
+ /*
+ * Clip to the svg area.
+ * Note: To have the svg overlay (under) a text area then use
+ * an fo:block-container
+ */
+ PDFRenderer renderer = (PDFRenderer)context.getRenderer();
+ renderer.saveGraphicsState();
+ renderer.setColor(Color.black, false, null);
+ renderer.setColor(Color.black, true, null);
+ // transform so that the coordinates (0,0) is from the top left
+ // and positive is down and to the right. (0,0) is where the
+ // viewBox puts it.
+ pdfInfo.currentStream.add(sx + " 0 0 " + sy + " " + xOffset / 1000f + " "
+ + yOffset / 1000f + " cm\n");
+
+ SVGSVGElement svg = ((SVGDocument)doc).getRootElement();
+ //AffineTransform at = ViewBox.getPreserveAspectRatioTransform(
+ // svg, w / 1000f, h / 1000f);
+ AffineTransform at = ViewBox.getPreserveAspectRatioTransform(svg,
+ pdfInfo.width / 1000f, pdfInfo.height / 1000f);
+ /*
+ if (!at.isIdentity()) {
+ double[] vals = new double[6];
+ at.getMatrix(vals);
+ pdfInfo.currentStream.add(CTMHelper.toPDFString(at, false) + " cm\n");
+ }*/
+
+ if (pdfInfo.pdfContext == null) {
+ pdfInfo.pdfContext = pdfInfo.pdfPage;
+ }
+ PDFGraphics2D graphics = new PDFGraphics2D(true, pdfInfo.fi,
+ pdfInfo.pdfDoc,
+ pdfInfo.pdfContext, pdfInfo.pdfPage.referencePDF(),
+ pdfInfo.currentFontName, pdfInfo.currentFontSize);
+ graphics.setGraphicContext(new org.apache.batik.ext.awt.g2d.GraphicContext());
+ pdfInfo.pdfState.push();
+ AffineTransform transform = new AffineTransform();
+ // scale to viewbox
+ transform.translate(xOffset / 1000f, yOffset / 1000f);
+
+ if (deviceResolution != uaResolution) {
+ //Scale for higher resolution on-the-fly images from Batik
+ double s = uaResolution / deviceResolution;
+ at.scale(s, s);
+ pdfInfo.currentStream.add("" + PDFNumber.doubleOut(s) + " 0 0 "
+ + PDFNumber.doubleOut(s) + " 0 0 cm\n");
+ graphics.scale(1 / s, 1 / s);
+ }
- renderer.restoreGraphicsState();
- pdfInfo.pdfState.pop();
+ pdfInfo.pdfState.setTransform(transform);
+ graphics.setPDFState(pdfInfo.pdfState);
+ graphics.setOutputStream(pdfInfo.outputStream);
+ try {
+ root.paint(graphics);
+ pdfInfo.currentStream.add(graphics.getString());
+ } catch (Exception e) {
+ log.error("svg graphic could not be rendered: "
+ + e.getMessage(), e);
}
+
+ renderer.restoreGraphicsState();
+ pdfInfo.pdfState.pop();
}
- /** @see org.apache.fop.render.XMLHandler#getMimeType() */
- public String getMimeType() {
- return PDFRenderer.MIME_TYPE;
+ /** @see org.apache.fop.render.XMLHandler#supportsRenderer(org.apache.fop.render.Renderer) */
+ public boolean supportsRenderer(Renderer renderer) {
+ return (renderer instanceof PDFRenderer);
}
-
/** @see org.apache.fop.render.XMLHandler#getNamespace() */
public String getNamespace() {
return SVGDOMImplementation.SVG_NAMESPACE_URI;
}
-} \ No newline at end of file
+}
diff --git a/src/java/org/apache/fop/render/ps/PSRenderer.java b/src/java/org/apache/fop/render/ps/PSRenderer.java
index 824ff9e5c..39ce0c9b7 100644
--- a/src/java/org/apache/fop/render/ps/PSRenderer.java
+++ b/src/java/org/apache/fop/render/ps/PSRenderer.java
@@ -132,8 +132,6 @@ public class PSRenderer extends AbstractPathOrientedRenderer {
*/
public void setUserAgent(FOUserAgent agent) {
super.setUserAgent(agent);
- PSSVGHandler xmlHandler = new PSSVGHandler();
- userAgent.getXMLHandlerRegistry().addXMLHandler(xmlHandler);
}
/** @see org.apache.fop.render.Renderer#getGraphics2DAdapter() */
@@ -1070,17 +1068,16 @@ public class PSRenderer extends AbstractPathOrientedRenderer {
context = new RendererContext(this, MIME_TYPE);
context.setUserAgent(userAgent);
- context.setProperty(PSSVGHandler.PS_GENERATOR, this.gen);
- context.setProperty(PSSVGHandler.PS_FONT_INFO, fontInfo);
- context.setProperty(PSSVGHandler.PS_WIDTH,
+ context.setProperty(PSRendererContextConstants.PS_GENERATOR, this.gen);
+ context.setProperty(PSRendererContextConstants.PS_FONT_INFO, fontInfo);
+ context.setProperty(PSRendererContextConstants.WIDTH,
new Integer((int) pos.getWidth()));
- context.setProperty(PSSVGHandler.PS_HEIGHT,
+ context.setProperty(PSRendererContextConstants.HEIGHT,
new Integer((int) pos.getHeight()));
- context.setProperty(PSSVGHandler.PS_XPOS,
+ context.setProperty(PSRendererContextConstants.XPOS,
new Integer(currentIPPosition + (int) pos.getX()));
- context.setProperty(PSSVGHandler.PS_YPOS,
+ context.setProperty(PSRendererContextConstants.YPOS,
new Integer(currentBPPosition + (int) pos.getY()));
- //context.setProperty("strokeSVGText", options.get("strokeSVGText"));
renderXML(context, doc, ns);
}
diff --git a/src/java/org/apache/fop/render/ps/PSRendererContextConstants.java b/src/java/org/apache/fop/render/ps/PSRendererContextConstants.java
new file mode 100644
index 000000000..210c1b9a1
--- /dev/null
+++ b/src/java/org/apache/fop/render/ps/PSRendererContextConstants.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2005 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.render.ps;
+
+import org.apache.fop.render.RendererContextConstants;
+
+/**
+ * Defines a number of standard constants (keys) for use by the RendererContext class.
+ */
+public interface PSRendererContextConstants extends RendererContextConstants {
+
+ /** The PostScript generator that is being used to drawn into. */
+ public static final String PS_GENERATOR = "psGenerator";
+
+ /** The font information for the PostScript renderer. */
+ public static final String PS_FONT_INFO = "psFontInfo";
+
+
+}
diff --git a/src/java/org/apache/fop/render/ps/PSSVGHandler.java b/src/java/org/apache/fop/render/ps/PSSVGHandler.java
index b39ed8f83..28bfa0bf4 100644
--- a/src/java/org/apache/fop/render/ps/PSSVGHandler.java
+++ b/src/java/org/apache/fop/render/ps/PSSVGHandler.java
@@ -23,12 +23,12 @@ import java.awt.geom.AffineTransform;
import java.io.IOException;
// DOM
-/* org.w3c.dom.Document is not imported to avoid conflict with
- org.apache.fop.control.Document */
+import org.w3c.dom.Document;
import org.w3c.dom.svg.SVGDocument;
import org.w3c.dom.svg.SVGSVGElement;
// Batik
+import org.apache.avalon.framework.configuration.Configuration;
import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.ViewBox;
@@ -37,6 +37,7 @@ import org.apache.batik.gvt.GraphicsNode;
// FOP
import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.render.Renderer;
import org.apache.fop.render.XMLHandler;
import org.apache.fop.render.RendererContext;
import org.apache.fop.svg.SVGUserAgent;
@@ -51,45 +52,12 @@ import org.apache.commons.logging.LogFactory;
* It renders SVG to the PostScript document using the PSGraphics2D.
* The properties from the PostScript renderer are subject to change.
*
- * @author <a href="mailto:fop-dev@xml.apache.org">Apache XML FOP Development Team</a>
* @version $Id$
*/
-public class PSSVGHandler implements XMLHandler {
+public class PSSVGHandler implements XMLHandler, PSRendererContextConstants {
- /**
- * logging instance
- */
- private Log log = LogFactory.getLog(PSSVGHandler.class);
-
- /**
- * The PostScript generator that is being used to drawn into.
- */
- public static final String PS_GENERATOR = "psGenerator";
-
- /**
- * The font information for the PostScript renderer.
- */
- public static final String PS_FONT_INFO = "psFontInfo";
-
- /**
- * The width of the SVG graphic.
- */
- public static final String PS_WIDTH = "width";
-
- /**
- * The height of the SVG graphic.
- */
- public static final String PS_HEIGHT = "height";
-
- /**
- * The x position that this is being drawn at.
- */
- public static final String PS_XPOS = "xpos";
-
- /**
- * The y position that this is being drawn at.
- */
- public static final String PS_YPOS = "ypos";
+ /** logging instance */
+ private static Log log = LogFactory.getLog(PSSVGHandler.class);
/**
* Create a new PostScript XML handler for use by the PostScript renderer.
@@ -99,14 +67,11 @@ public class PSSVGHandler implements XMLHandler {
/** @see org.apache.fop.render.XMLHandler */
public void handleXML(RendererContext context,
- org.w3c.dom.Document doc, String ns) throws Exception {
+ Document doc, String ns) throws Exception {
PSInfo psi = getPSInfo(context);
if (SVGDOMImplementation.SVG_NAMESPACE_URI.equals(ns)) {
- SVGHandler svghandler = new SVGHandler();
- svghandler.renderSVGDocument(context, doc, psi);
- } else {
- //nop
+ renderSVGDocument(context, doc, psi);
}
}
@@ -120,10 +85,11 @@ public class PSSVGHandler implements XMLHandler {
PSInfo psi = new PSInfo();
psi.psGenerator = (PSGenerator)context.getProperty(PS_GENERATOR);
psi.fontInfo = (org.apache.fop.fonts.FontInfo) context.getProperty(PS_FONT_INFO);
- psi.width = ((Integer)context.getProperty(PS_WIDTH)).intValue();
- psi.height = ((Integer)context.getProperty(PS_HEIGHT)).intValue();
- psi.currentXPosition = ((Integer)context.getProperty(PS_XPOS)).intValue();
- psi.currentYPosition = ((Integer)context.getProperty(PS_YPOS)).intValue();
+ psi.width = ((Integer)context.getProperty(WIDTH)).intValue();
+ psi.height = ((Integer)context.getProperty(HEIGHT)).intValue();
+ psi.currentXPosition = ((Integer)context.getProperty(XPOS)).intValue();
+ psi.currentYPosition = ((Integer)context.getProperty(YPOS)).intValue();
+ psi.cfg = (Configuration)context.getProperty(HANDLER_CONFIGURATION);
return psi;
}
@@ -136,14 +102,17 @@ public class PSSVGHandler implements XMLHandler {
private PSGenerator psGenerator;
/** see PS_FONT_INFO */
private org.apache.fop.fonts.FontInfo fontInfo;
- /** see PS_PAGE_WIDTH */
+ /** see WIDTH */
private int width;
- /** see PS_PAGE_HEIGHT */
+ /** see HEIGHT */
private int height;
- /** see PS_XPOS */
+ /** see XPOS */
private int currentXPosition;
- /** see PS_YPOS */
+ /** see YPOS */
private int currentYPosition;
+ /** see HANDLER_CONFIGURATION */
+ private Configuration cfg;
+
/**
* Returns the PSGenerator.
* @return PSGenerator
@@ -240,122 +209,134 @@ public class PSSVGHandler implements XMLHandler {
this.height = height;
}
+ /**
+ * Returns the height.
+ * @return int
+ */
+ public Configuration getHandlerConfiguration() {
+ return this.cfg;
+ }
+
+ /**
+ * Sets the handler configuration.
+ * @param cfg the configuration object
+ */
+ public void setHeight(Configuration cfg) {
+ this.cfg = cfg;
+ }
+
}
/**
- * This method is placed in an inner class so that we don't get class
- * loading errors if batik is not present.
+ * Render the svg document.
+ * @param context the renderer context
+ * @param doc the svg document
+ * @param psInfo the pdf information of the current context
*/
- protected class SVGHandler {
- /**
- * Render the svg document.
- * @param context the renderer context
- * @param doc the svg document
- * @param psInfo the pdf information of the current context
- */
- protected void renderSVGDocument(RendererContext context,
- org.w3c.dom.Document doc, PSInfo psInfo) {
- int xOffset = psInfo.currentXPosition;
- int yOffset = psInfo.currentYPosition;
- PSGenerator gen = psInfo.psGenerator;
-
- SVGUserAgent ua
- = new SVGUserAgent(
- context.getUserAgent().getSourcePixelUnitToMillimeter(),
- new AffineTransform());
-
- GVTBuilder builder = new GVTBuilder();
- BridgeContext ctx = new BridgeContext(ua);
+ protected void renderSVGDocument(RendererContext context,
+ Document doc, PSInfo psInfo) {
+ int xOffset = psInfo.currentXPosition;
+ int yOffset = psInfo.currentYPosition;
+ PSGenerator gen = psInfo.psGenerator;
+
+ //Controls whether text painted by Batik is generated using text or path operations
+ boolean strokeText = false;
+ Configuration cfg = psInfo.getHandlerConfiguration();
+ if (cfg != null) {
+ strokeText = cfg.getChild("stroke-text", true).getValueAsBoolean(strokeText);
+ }
+
+ SVGUserAgent ua
+ = new SVGUserAgent(
+ context.getUserAgent().getSourcePixelUnitToMillimeter(),
+ new AffineTransform());
+
+ GVTBuilder builder = new GVTBuilder();
+ BridgeContext ctx = new BridgeContext(ua);
+ if (!strokeText) {
PSTextPainter textPainter = new PSTextPainter(psInfo.getFontInfo());
ctx.setTextPainter(textPainter);
PSTextElementBridge tBridge = new PSTextElementBridge(textPainter);
ctx.putBridge(tBridge);
+ }
- //PSAElementBridge aBridge = new PSAElementBridge();
- // to get the correct transform we need to use the PDFState
- AffineTransform transform = gen.getCurrentState().getTransform();
- transform.translate(xOffset / 1000f, yOffset / 1000f);
- //aBridge.setCurrentTransform(transform);
- //ctx.putBridge(aBridge);
-
- GraphicsNode root;
+ GraphicsNode root;
+ try {
+ root = builder.build(ctx, doc);
+ } catch (Exception e) {
+ log.error("SVG graphic could not be built: "
+ + e.getMessage(), e);
+ return;
+ }
+ // get the 'width' and 'height' attributes of the SVG document
+ float w = (float)ctx.getDocumentSize().getWidth() * 1000f;
+ float h = (float)ctx.getDocumentSize().getHeight() * 1000f;
+
+ float sx = psInfo.getWidth() / (float)w;
+ float sy = psInfo.getHeight() / (float)h;
+
+ ctx = null;
+ builder = null;
+
+ try {
+ gen.commentln("%FOPBeginSVG");
+ gen.saveGraphicsState();
+ /*
+ * Clip to the svg area.
+ * Note: To have the svg overlay (under) a text area then use
+ * an fo:block-container
+ */
+ gen.writeln("newpath");
+ gen.defineRect(xOffset / 1000f, yOffset / 1000f,
+ psInfo.getWidth() / 1000f, psInfo.getHeight() / 1000f);
+ gen.writeln("clip");
+
+ // transform so that the coordinates (0,0) is from the top left
+ // and positive is down and to the right. (0,0) is where the
+ // viewBox puts it.
+ gen.concatMatrix(sx, 0, 0, sy, xOffset / 1000f, yOffset / 1000f);
+
+ SVGSVGElement svg = ((SVGDocument)doc).getRootElement();
+ AffineTransform at = ViewBox.getPreserveAspectRatioTransform(svg,
+ psInfo.getWidth() / 1000f, psInfo.getHeight() / 1000f);
+ /*
+ if (!at.isIdentity()) {
+ double[] vals = new double[6];
+ at.getMatrix(vals);
+ gen.concatMatrix(vals);
+ }*/
+
+ final boolean textAsShapes = false;
+ PSGraphics2D graphics = new PSGraphics2D(textAsShapes, gen);
+ graphics.setGraphicContext(new org.apache.batik.ext.awt.g2d.GraphicContext());
+ AffineTransform transform = new AffineTransform();
+ // scale to viewbox
+ transform.translate(xOffset, yOffset);
+ gen.getCurrentState().concatMatrix(transform);
try {
- root = builder.build(ctx, doc);
+ root.paint(graphics);
} catch (Exception e) {
- log.error("SVG graphic could not be built: "
+ log.error("SVG graphic could not be rendered: "
+ e.getMessage(), e);
- return;
}
- // get the 'width' and 'height' attributes of the SVG document
- float w = (float)ctx.getDocumentSize().getWidth() * 1000f;
- float h = (float)ctx.getDocumentSize().getHeight() * 1000f;
- float sx = psInfo.getWidth() / (float)w;
- float sy = psInfo.getHeight() / (float)h;
-
- ctx = null;
- builder = null;
-
- try {
- gen.commentln("%FOPBeginSVG");
- gen.saveGraphicsState();
- /*
- * Clip to the svg area.
- * Note: To have the svg overlay (under) a text area then use
- * an fo:block-container
- */
- gen.writeln("newpath");
- gen.defineRect(xOffset / 1000f, yOffset / 1000f,
- psInfo.getWidth() / 1000f, psInfo.getWidth() / 1000f);
- //TODO Is the above correct? Twice getWidth??????????????
- gen.writeln("clip");
-
- // transform so that the coordinates (0,0) is from the top left
- // and positive is down and to the right. (0,0) is where the
- // viewBox puts it.
- gen.concatMatrix(sx, 0, 0, sy, xOffset / 1000f, yOffset / 1000f);
-
- SVGSVGElement svg = ((SVGDocument)doc).getRootElement();
- AffineTransform at = ViewBox.getPreserveAspectRatioTransform(svg,
- psInfo.getWidth() / 1000f, psInfo.getHeight() / 1000f);
- if (false && !at.isIdentity()) {
- double[] vals = new double[6];
- at.getMatrix(vals);
- gen.concatMatrix(vals);
- }
-
- final boolean textAsShapes = false;
- PSGraphics2D graphics = new PSGraphics2D(textAsShapes, gen);
- graphics.setGraphicContext(new org.apache.batik.ext.awt.g2d.GraphicContext());
- transform = new AffineTransform();
- // scale to viewbox
- transform.translate(xOffset, yOffset);
- gen.getCurrentState().concatMatrix(transform);
- try {
- root.paint(graphics);
- } catch (Exception e) {
- log.error("SVG graphic could not be rendered: "
- + e.getMessage(), e);
- }
-
- gen.restoreGraphicsState();
- gen.commentln("%FOPEndSVG");
- } catch (IOException ioe) {
- log.error("SVG graphic could not be rendered: "
- + ioe.getMessage(), ioe);
- }
+ gen.restoreGraphicsState();
+ gen.commentln("%FOPEndSVG");
+ } catch (IOException ioe) {
+ log.error("SVG graphic could not be rendered: "
+ + ioe.getMessage(), ioe);
}
}
- /** @see org.apache.fop.render.XMLHandler#getMimeType() */
- public String getMimeType() {
- return PSRenderer.MIME_TYPE;
+ /** @see org.apache.fop.render.XMLHandler#supportsRenderer(org.apache.fop.render.Renderer) */
+ public boolean supportsRenderer(Renderer renderer) {
+ return (renderer instanceof PSRenderer);
}
-
+
/** @see org.apache.fop.render.XMLHandler#getNamespace() */
public String getNamespace() {
return SVGDOMImplementation.SVG_NAMESPACE_URI;
}
-
+
}
diff --git a/src/java/org/apache/fop/render/xml/XMLXMLHandler.java b/src/java/org/apache/fop/render/xml/XMLXMLHandler.java
index b441322d6..9d1185903 100644
--- a/src/java/org/apache/fop/render/xml/XMLXMLHandler.java
+++ b/src/java/org/apache/fop/render/xml/XMLXMLHandler.java
@@ -20,6 +20,7 @@ package org.apache.fop.render.xml;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.fop.render.Renderer;
import org.apache.fop.render.XMLHandler;
import org.apache.fop.render.RendererContext;
@@ -132,9 +133,9 @@ public class XMLXMLHandler implements XMLHandler {
}
}
- /** @see org.apache.fop.render.XMLHandler#getMimeType() */
- public String getMimeType() {
- return XMLRenderer.XML_MIME_TYPE;
+ /** @see org.apache.fop.render.XMLHandler#supportsRenderer(org.apache.fop.render.Renderer) */
+ public boolean supportsRenderer(Renderer renderer) {
+ return (renderer instanceof XMLRenderer);
}
/** @see org.apache.fop.render.XMLHandler#getNamespace() */
diff --git a/src/sandbox/org/apache/fop/render/svg/SVGRenderer.java b/src/sandbox/org/apache/fop/render/svg/SVGRenderer.java
index 7a2b182d7..0b5d93f3d 100644
--- a/src/sandbox/org/apache/fop/render/svg/SVGRenderer.java
+++ b/src/sandbox/org/apache/fop/render/svg/SVGRenderer.java
@@ -29,21 +29,17 @@ import org.apache.fop.svg.SVGUtilities;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.apps.FOUserAgent;
-import org.w3c.dom.Node;
-import org.w3c.dom.svg.SVGSVGElement;
-import org.w3c.dom.svg.SVGDocument;
/* org.w3c.dom.Document is not imported to avoid conflict with
org.apache.fop.control.Document */
import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
import org.apache.batik.dom.svg.SVGDOMImplementation;
-import org.apache.batik.dom.util.XMLSupport;
import org.apache.batik.transcoder.svg2svg.SVGTranscoder;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.TranscoderException;
-import org.apache.batik.dom.util.DOMUtilities;
import java.awt.Color;
import java.awt.image.BufferedImage;
@@ -60,7 +56,7 @@ import org.apache.fop.render.RendererContext;
/**
* This is the SVG renderer.
*/
-public class SVGRenderer extends AbstractRenderer implements XMLHandler {
+public class SVGRenderer extends AbstractRenderer {
/** SVG MIME type */
public static final String SVG_MIME_TYPE = "image/svg+xml";
@@ -81,8 +77,6 @@ public class SVGRenderer extends AbstractRenderer implements XMLHandler {
// first sequence title
private LineArea docTitle = null;
- private RendererContext context;
-
private OutputStream ostream;
private float totalWidth = 0;
@@ -119,7 +113,6 @@ public class SVGRenderer extends AbstractRenderer implements XMLHandler {
* Creates a new SVG renderer.
*/
public SVGRenderer() {
- context = new RendererContext(this, SVG_MIME_TYPE);
}
/**
@@ -127,7 +120,15 @@ public class SVGRenderer extends AbstractRenderer implements XMLHandler {
*/
public void setUserAgent(FOUserAgent agent) {
super.setUserAgent(agent);
- userAgent.getXMLHandlerRegistry().addXMLHandler(this);
+
+ //Note: This is done here as having two service lookup files in the same IDE project
+ //will end up with one overwriting the other when all sources are compiled in to the
+ //same target directory. Remove this code and add an entry in the XMLHandler resource
+ //file when this renderer exits the sandbox.
+ XMLHandler handler = agent.getXMLHandlerRegistry().getXMLHandler(this, SVG_NAMESPACE);
+ if (handler == null) {
+ agent.getXMLHandlerRegistry().addXMLHandler("org.apache.fop.render.svg.SVGSVGHandler");
+ }
}
/**
@@ -319,36 +320,33 @@ public class SVGRenderer extends AbstractRenderer implements XMLHandler {
public void renderForeignObject(ForeignObject fo, Rectangle2D pos) {
org.w3c.dom.Document doc = fo.getDocument();
String ns = fo.getNameSpace();
- renderXML(context, doc, ns);
+ renderDocument(doc, ns, pos);
}
- /** @see org.apache.fop.render.XMLHandler */
- public void handleXML(RendererContext context,
- org.w3c.dom.Document doc, String ns) throws Exception {
- if (SVG_NAMESPACE.equals(ns)) {
- if (!(doc instanceof SVGDocument)) {
- DOMImplementation impl =
- SVGDOMImplementation.getDOMImplementation();
- doc = DOMUtilities.deepCloneDocument(doc, impl);
- }
- SVGSVGElement svg = ((SVGDocument) doc).getRootElement();
- Element view = svgDocument.createElementNS(SVG_NAMESPACE, "svg");
- Node newsvg = svgDocument.importNode(svg, true);
- //view.setAttributeNS(null, "viewBox", "0 0 ");
- view.setAttributeNS(null, "x", "" + currentIPPosition / 1000f);
- view.setAttributeNS(null, "y", "" + currentBPPosition / 1000f);
-
- // this fixes a problem where the xmlns is repeated sometimes
- Element ele = (Element) newsvg;
- ele.setAttributeNS(XMLSupport.XMLNS_NAMESPACE_URI, "xmlns",
- SVG_NAMESPACE);
- if (ele.hasAttributeNS(null, "xmlns")) {
- ele.removeAttributeNS(null, "xmlns");
- }
-
- view.appendChild(newsvg);
- currentPageG.appendChild(view);
- }
+ /**
+ * Renders an XML document (SVG for example).
+ *
+ * @param doc DOM document representing the XML document
+ * @param ns Namespace for the document
+ * @param pos Position on the page
+ */
+ public void renderDocument(Document doc, String ns, Rectangle2D pos) {
+ RendererContext context;
+ context = new RendererContext(this, getMimeType());
+ context.setUserAgent(userAgent);
+
+ context.setProperty(SVGRendererContextConstants.SVG_DOCUMENT, svgDocument);
+ context.setProperty(SVGRendererContextConstants.SVG_PAGE_G, currentPageG);
+ context.setProperty(SVGRendererContextConstants.XPOS,
+ new Integer(currentIPPosition + (int)pos.getX()));
+ context.setProperty(SVGRendererContextConstants.YPOS,
+ new Integer(currentBPPosition + (int)pos.getY()));
+ context.setProperty(SVGRendererContextConstants.WIDTH,
+ new Integer((int)pos.getWidth()));
+ context.setProperty(SVGRendererContextConstants.HEIGHT,
+ new Integer((int) pos.getHeight()));
+
+ renderXML(context, doc, ns);
}
/**
@@ -419,11 +417,6 @@ public class SVGRenderer extends AbstractRenderer implements XMLHandler {
return SVG_MIME_TYPE;
}
- /** @see org.apache.fop.render.XMLHandler#getNamespace() */
- public String getNamespace() {
- return SVG_NAMESPACE;
- }
-
/**
* @see org.apache.fop.render.AbstractRenderer#startVParea(CTM, Rectangle2D)
*/
diff --git a/src/sandbox/org/apache/fop/render/svg/SVGRendererContextConstants.java b/src/sandbox/org/apache/fop/render/svg/SVGRendererContextConstants.java
new file mode 100644
index 000000000..c86afb9ff
--- /dev/null
+++ b/src/sandbox/org/apache/fop/render/svg/SVGRendererContextConstants.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2005 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.render.svg;
+
+import org.apache.fop.render.RendererContextConstants;
+
+/**
+ * Defines a number of standard constants (keys) for use by the RendererContext class.
+ */
+public interface SVGRendererContextConstants extends RendererContextConstants {
+
+ /** The SVG document that this image is being drawn into. */
+ String SVG_DOCUMENT = "svgDoc";
+
+ /** The current SVG page g element. */
+ String SVG_PAGE_G = "svgPageG";
+
+}
diff --git a/src/sandbox/org/apache/fop/render/svg/SVGSVGHandler.java b/src/sandbox/org/apache/fop/render/svg/SVGSVGHandler.java
new file mode 100644
index 000000000..47e1b8767
--- /dev/null
+++ b/src/sandbox/org/apache/fop/render/svg/SVGSVGHandler.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2005 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.render.svg;
+
+import org.apache.batik.dom.svg.SVGDOMImplementation;
+import org.apache.batik.dom.util.DOMUtilities;
+import org.apache.batik.dom.util.XMLSupport;
+import org.apache.fop.render.Renderer;
+import org.apache.fop.render.RendererContext;
+import org.apache.fop.render.XMLHandler;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.svg.SVGDocument;
+import org.w3c.dom.svg.SVGElement;
+import org.w3c.dom.svg.SVGSVGElement;
+
+public class SVGSVGHandler implements XMLHandler, SVGRendererContextConstants {
+
+ /** @see org.apache.fop.render.XMLHandler */
+ public void handleXML(RendererContext context,
+ org.w3c.dom.Document doc, String ns) throws Exception {
+ if (getNamespace().equals(ns)) {
+ if (!(doc instanceof SVGDocument)) {
+ DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();
+ doc = DOMUtilities.deepCloneDocument(doc, impl);
+ }
+ SVGSVGElement svg = ((SVGDocument) doc).getRootElement();
+ SVGDocument targetDoc = (SVGDocument)context.getProperty(SVG_DOCUMENT);
+ SVGElement currentPageG = (SVGElement)context.getProperty(SVG_PAGE_G);
+ Element view = targetDoc.createElementNS(getNamespace(), "svg");
+ Node newsvg = targetDoc.importNode(svg, true);
+ //view.setAttributeNS(null, "viewBox", "0 0 ");
+ int xpos = ((Integer)context.getProperty(XPOS)).intValue();
+ int ypos = ((Integer)context.getProperty(YPOS)).intValue();
+ view.setAttributeNS(null, "x", "" + xpos / 1000f);
+ view.setAttributeNS(null, "y", "" + ypos / 1000f);
+
+ // this fixes a problem where the xmlns is repeated sometimes
+ Element ele = (Element) newsvg;
+ ele.setAttributeNS(XMLSupport.XMLNS_NAMESPACE_URI, "xmlns",
+ getNamespace());
+ if (ele.hasAttributeNS(null, "xmlns")) {
+ ele.removeAttributeNS(null, "xmlns");
+ }
+
+ view.appendChild(newsvg);
+ currentPageG.appendChild(view);
+ }
+ }
+
+
+ /** @see org.apache.fop.render.XMLHandler#supportsRenderer(org.apache.fop.render.Renderer) */
+ public boolean supportsRenderer(Renderer renderer) {
+ return (renderer instanceof SVGRenderer);
+ }
+
+ /** @see org.apache.fop.render.XMLHandler#getNamespace() */
+ public String getNamespace() {
+ return SVGRenderer.SVG_NAMESPACE;
+ }
+
+
+}
diff --git a/status.xml b/status.xml
index f0ccaa307..9f0b2ffc8 100644
--- a/status.xml
+++ b/status.xml
@@ -27,6 +27,14 @@
<changes>
<release version="FOP Trunk">
+ <action context="Code" dev="JM" type="update">
+ Changed the XMLHandler interface so it doesn't report the MIME type it
+ supports but instead can report whether it supports a particular Renderer
+ implementation. XMLHandlers are now configurable.
+ </action>
+ <action context="Code" dev="JM" type="fix">
+ Fixed a bug where SVG content could be clipped when rendered to PostScript.
+ </action>
<action context="Code" dev="JM" type="fix">
Changed the way resolutions are handled. The single resolution in the user
agent got split up into source and target resolutions. For more info, see