diff options
author | Jeremias Maerki <jeremias@apache.org> | 2005-09-06 14:23:31 +0000 |
---|---|---|
committer | Jeremias Maerki <jeremias@apache.org> | 2005-09-06 14:23:31 +0000 |
commit | 1ab8f0165a658047da694aa32978f3b9238bea7e (patch) | |
tree | 98b0aa229939180959ce795b825d2e52b8ac4bca /src/java/org/apache/fop | |
parent | 775a1b4bb3c85586792222c8bd43bdd24acc201d (diff) | |
download | xmlgraphics-fop-1ab8f0165a658047da694aa32978f3b9238bea7e.tar.gz xmlgraphics-fop-1ab8f0165a658047da694aa32978f3b9238bea7e.zip |
Bugzilla #36520:
Cleaner transformation matrix handling.
SVG painting extracted into an XMLHandler subclass like for the other renderers.
Submitted by: Richard Wheeldon <richardw.at.geoquip-rnd.demon.co.uk>
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@279005 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/fop')
-rw-r--r-- | src/java/org/apache/fop/render/java2d/Java2DRenderer.java | 117 | ||||
-rw-r--r-- | src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java | 209 |
2 files changed, 227 insertions, 99 deletions
diff --git a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java index 56c30ac7f..060624384 100644 --- a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java +++ b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java @@ -46,10 +46,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import org.apache.batik.bridge.BridgeContext; -import org.apache.batik.bridge.GVTBuilder; -import org.apache.batik.dom.svg.SVGDOMImplementation; -import org.apache.batik.gvt.GraphicsNode; import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.area.Area; @@ -75,11 +71,8 @@ import org.apache.fop.image.XMLImage; import org.apache.fop.render.AbstractRenderer; import org.apache.fop.render.RendererContext; import org.apache.fop.render.pdf.CTMHelper; -import org.apache.fop.svg.SVGUserAgent; import org.apache.fop.traits.BorderProps; import org.w3c.dom.Document; -import org.w3c.dom.svg.SVGDocument; -import org.w3c.dom.svg.SVGSVGElement; /** * The <code>Java2DRenderer</code> class provides the abstract technical @@ -159,6 +152,8 @@ public abstract class Java2DRenderer extends AbstractRenderer implements Printab */ public void setUserAgent(FOUserAgent foUserAgent) { super.setUserAgent(foUserAgent); + Java2DSVGHandler xmlHandler = new Java2DSVGHandler(); + userAgent.getXMLHandlerRegistry().addXMLHandler(xmlHandler); userAgent.setRendererOverride(this); // for document regeneration } @@ -932,9 +927,9 @@ public abstract class Java2DRenderer extends AbstractRenderer implements Printab } /** - * draws an image + * Draws an image * - * @param url URL of the bitmap + * @param pUrl URL of the bitmap * @param pos Position of the bitmap */ protected void putImage(String pUrl, Rectangle2D pos) { @@ -968,8 +963,9 @@ public abstract class Java2DRenderer extends AbstractRenderer implements Printab return; } Document doc = ((XMLImage) fopimage).getDocument(); - renderSVGDocument(doc, pos); // TODO check if ok. + String ns = ((XMLImage) fopimage).getNameSpace(); + renderDocument(doc, ns, pos); } else if ("image/eps".equals(mime)) { log.warn("EPS images are not supported by this renderer"); currentBPPosition += (h * 1000); @@ -1028,12 +1024,7 @@ public abstract class Java2DRenderer extends AbstractRenderer implements Printab public void renderForeignObject(ForeignObject fo, Rectangle2D pos) { Document doc = fo.getDocument(); String ns = fo.getNameSpace(); - if (SVGDOMImplementation.SVG_NAMESPACE_URI.equals(ns)) { - renderSVGDocument(doc, pos); - } else { - renderDocument(doc, ns, pos); - } - // this.currentXPosition += area.getContentWidth(); + renderDocument(doc, ns, pos); } /** @@ -1047,90 +1038,18 @@ public abstract class Java2DRenderer extends AbstractRenderer implements Printab RendererContext context; context = new RendererContext(this, MIME_TYPE); context.setUserAgent(userAgent); - // TODO implement - /* - * 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, currentContext == null ? - * currentPage : currentContext); - * context.setProperty(PDFSVGHandler.PDF_CONTEXT, currentContext); - * context.setProperty(PDFSVGHandler.PDF_STREAM, currentStream); - * context.setProperty(PDFSVGHandler.PDF_XPOS, new - * Integer(currentIPPosition + (int) pos.getX())); - * context.setProperty(PDFSVGHandler.PDF_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, new - * Integer(currentFontSize)); - * context.setProperty(PDFSVGHandler.PDF_WIDTH, new Integer((int) - * pos.getWidth())); context.setProperty(PDFSVGHandler.PDF_HEIGHT, new - * Integer((int) pos.getHeight())); renderXML(userAgent, context, doc, - * ns); - */ - } - - protected void renderSVGDocument(Document doc, Rectangle2D pos) { - int x = currentIPPosition; // TODO + area.getXOffset(); - int y = currentBPPosition; - - RendererContext context; - context = new RendererContext(this, MIME_TYPE); - context.setUserAgent(userAgent); - - SVGUserAgent ua = new SVGUserAgent(context.getUserAgent() - .getPixelUnitToMillimeter(), 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) pos.getWidth(); - float h = (float) pos.getHeight(); - - // correct integer roundoff - state.getGraph().translate(x / 1000, y / 1000); - - SVGSVGElement svg = ((SVGDocument) doc).getRootElement(); - // Aspect ratio preserved by layout engine, not here - AffineTransform at = AffineTransform.getScaleInstance(w / iw, h / ih); - AffineTransform inverse = null; - try { - inverse = at.createInverse(); - } catch (NoninvertibleTransformException e) { - log.warn(e); - } - if (!at.isIdentity()) { - state.getGraph().transform(at); - } - - try { - root.paint(state.getGraph()); - } catch (Exception e) { - e.printStackTrace(); - } - - if (inverse != null && !inverse.isIdentity()) { - state.getGraph().transform(inverse); - } - // correct integer roundoff - state.getGraph().translate(-(x + 500) / 1000, -(y + 500) / 1000); + context.setProperty(Java2DSVGHandler.JAVA2D_STATE, state); + context.setProperty(Java2DSVGHandler.JAVA2D_XPOS, + new Integer(currentIPPosition + (int)pos.getX())); + context.setProperty(Java2DSVGHandler.JAVA2D_YPOS, + new Integer(currentBPPosition + (int)pos.getY())); + context.setProperty(Java2DSVGHandler.JAVA2D_WIDTH, + new Integer((int)pos.getWidth())); + context.setProperty(Java2DSVGHandler.JAVA2D_HEIGHT, + new Integer((int) pos.getHeight())); + + renderXML(context, doc, ns); } /** diff --git a/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java b/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java new file mode 100644 index 000000000..d89adf63d --- /dev/null +++ b/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java @@ -0,0 +1,209 @@ +/* + * Copyright 1999-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.XMLHandler; +import org.apache.fop.render.RendererContext; +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"; + + /** + * 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"; + + /** + * The y position that this is being drawn at. + */ + public static final String JAVA2D_YPOS = "ypos"; + + /** + * Create a new Java2D XML handler for use by the Java2D renderer. + */ + public Java2DSVGHandler() { + } + + /** @see org.apache.fop.render.XMLHandler */ + public void handleXML(RendererContext context, + org.w3c.dom.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); + } + } + + /** + * Get the pdf information from the render context. + * + * @param context the renderer context + * @return the pdf information retrieved from the context + */ + 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(); + return pdfi; + } + + /** + * Java2D information structure for drawing the XML document. + */ + public static class Java2DInfo { + /** see Java2D_STATE */ + public Java2DGraphicsState state; + /** see Java2D_WIDTH */ + public int width; + /** see Java2D_HEIGHT */ + public int height; + /** see Java2D_XPOS */ + public int currentXPosition; + /** see Java2D_YPOS */ + public int currentYPosition; + + /** @see java.lang.Object#toString() */ + public String toString() { + return "Java2DInfo {" + + "state = " + state + ", " + + "width = " + width + ", " + + "height = " + height + ", " + + "currentXPosition = " + currentXPosition + ", " + + "currentYPosition = " + currentYPosition + "}"; + } + } + + /** + * This method is placed in an inner class so that we don't get class + * loading errors if batik is not present. + */ + protected class SVGHandler { + + /** + * 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().getPixelUnitToMillimeter(); + 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 / 1000, y / 1000); + + //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 Java2DRenderer.MIME_TYPE; + } + + /** @see org.apache.fop.render.XMLHandler#getNamespace() */ + public String getNamespace() { + return SVGDOMImplementation.SVG_NAMESPACE_URI; + } +} |