From fc3f1a4c0a64e7f5559e30fbd2664900326d8359 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Wed, 3 May 2006 13:47:18 +0000 Subject: [PATCH] Some refactoring in the XML handling area which results in more code reuse and less redundancy. Support for i-f-o for the AFPRenderer including a Graphics2DAdapter so extensions like Barcode4J can paint barcodes more efficiently (i.e. not via SVG). The SVGConverter class could now be removed except for the writeImage() method because the same functionality is now covered by the Graphics2DAdapter via renderDocument() in the renderer. PCL and AFP now use practically the same extension painting code (both render to bitmap images). git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@399306 13f79535-47bb-0310-9956-ffa450edef68 --- .../fop/render/AbstractGenericSVGHandler.java | 131 ++++++++++++++++++ .../fop/render/AbstractGraphics2DAdapter.java | 92 ++++++++++++ .../render/AbstractPathOrientedRenderer.java | 25 +++- .../org/apache/fop/render/PrintRenderer.java | 51 +++++++ .../apache/fop/render/RendererContext.java | 63 ++++++++- .../fop/render/java2d/Java2DRenderer.java | 49 ++----- .../apache/fop/render/pdf/PDFRenderer.java | 44 ++---- .../org/apache/fop/render/ps/PSRenderer.java | 46 ++---- .../apache/fop/render/txt/TXTRenderer.java | 11 +- .../services/org.apache.fop.render.XMLHandler | 1 + .../fop/render/afp/AFPGraphics2DAdapter.java | 54 ++++++++ .../apache/fop/render/afp/AFPRenderer.java | 58 +++++++- .../apache/fop/render/afp/AFPSVGHandler.java | 38 +++++ .../apache/fop/render/afp/SVGConverter.java | 27 +++- .../fop/render/pcl/PCLGraphics2DAdapter.java | 41 +----- .../apache/fop/render/pcl/PCLRenderer.java | 48 ------- .../fop/render/pcl/PCLRendererContext.java | 36 +---- .../apache/fop/render/pcl/PCLSVGHandler.java | 113 +-------------- 18 files changed, 578 insertions(+), 350 deletions(-) create mode 100644 src/java/org/apache/fop/render/AbstractGenericSVGHandler.java create mode 100644 src/java/org/apache/fop/render/AbstractGraphics2DAdapter.java create mode 100644 src/sandbox/org/apache/fop/render/afp/AFPGraphics2DAdapter.java create mode 100644 src/sandbox/org/apache/fop/render/afp/AFPSVGHandler.java diff --git a/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java b/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java new file mode 100644 index 000000000..a54f6b9b8 --- /dev/null +++ b/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java @@ -0,0 +1,131 @@ +/* + * Copyright 2006 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; + +// Java +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.io.IOException; + +// DOM +import org.w3c.dom.Document; + +// Batik +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; + +// FOP +import org.apache.fop.render.Graphics2DAdapter; +import org.apache.fop.render.Graphics2DImagePainter; +import org.apache.fop.render.RendererContextConstants; +import org.apache.fop.render.XMLHandler; +import org.apache.fop.render.RendererContext; +import org.apache.fop.render.RendererContext.RendererContextWrapper; +import org.apache.fop.svg.SVGUserAgent; + +// Commons-Logging +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Generic XML handler for SVG. Uses Apache Batik for SVG processing and simply paints to + * a Graphics2DAdapter and thus ultimatively to Graphics2D interface that is presented. + *

+ * To use this class, subclass it and implement the missing methods (supportsRenderer, for example). + */ +public abstract class AbstractGenericSVGHandler implements XMLHandler, RendererContextConstants { + + /** logging instance */ + private static Log log = LogFactory.getLog(AbstractGenericSVGHandler.class); + + /** @see org.apache.fop.render.XMLHandler */ + public void handleXML(RendererContext context, + Document doc, String ns) throws Exception { + + if (SVGDOMImplementation.SVG_NAMESPACE_URI.equals(ns)) { + renderSVGDocument(context, doc); + } + } + + /** + * Render the SVG document. + * @param context the renderer context + * @param doc the SVG document + * @throws IOException In case of an I/O error while painting the image + */ + protected void renderSVGDocument(final RendererContext context, + final Document doc) throws IOException { + final RendererContextWrapper wrappedContext = RendererContext.wrapRendererContext(context); + int x = wrappedContext.getCurrentXPosition(); + int y = wrappedContext.getCurrentYPosition(); + + //Prepare + SVGUserAgent ua = new SVGUserAgent( + context.getUserAgent().getSourcePixelUnitToMillimeter(), + new AffineTransform()); + GVTBuilder builder = new GVTBuilder(); + final BridgeContext ctx = new BridgeContext(ua); + + //Build the GVT tree + final GraphicsNode root; + try { + root = builder.build(ctx, doc); + } catch (Exception e) { + log.error("SVG graphic could not be built: " + e.getMessage(), e); + return; + } + + //Create the painter + Graphics2DImagePainter painter = new Graphics2DImagePainter() { + + public void paint(Graphics2D g2d, Rectangle2D area) { + // 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(); + float ih = (float) ctx.getDocumentSize().getHeight(); + float w = (float) area.getWidth(); + float h = (float) area.getHeight(); + g2d.scale(w / iw, h / ih); + + root.paint(g2d); + } + + public Dimension getImageSize() { + return new Dimension(wrappedContext.getWidth(), wrappedContext.getHeight()); + } + + }; + + //Let the painter paint the SVG on the Graphics2D instance + Graphics2DAdapter adapter = context.getRenderer().getGraphics2DAdapter(); + adapter.paintImage(painter, context, + x, y, wrappedContext.getWidth(), wrappedContext.getHeight()); + } + + /** @see org.apache.fop.render.XMLHandler#getNamespace() */ + public String getNamespace() { + return SVGDOMImplementation.SVG_NAMESPACE_URI; + } + +} + diff --git a/src/java/org/apache/fop/render/AbstractGraphics2DAdapter.java b/src/java/org/apache/fop/render/AbstractGraphics2DAdapter.java new file mode 100644 index 000000000..af5343f33 --- /dev/null +++ b/src/java/org/apache/fop/render/AbstractGraphics2DAdapter.java @@ -0,0 +1,92 @@ +/* + * Copyright 2006 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; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.fop.render.Graphics2DAdapter; +import org.apache.fop.render.Graphics2DImagePainter; +import org.apache.fop.render.RendererContext.RendererContextWrapper; +import org.apache.fop.util.UnitConv; + +/** + * Graphics2DAdapter implementation for PCL and HP GL/2. + */ +public abstract class AbstractGraphics2DAdapter implements Graphics2DAdapter { + + /** + * Paints the image to a BufferedImage and returns that. + * @param painter the painter which will paint the actual image + * @param context the renderer context for the current renderer + * @param resolution the requested bitmap resolution + * @param gray true if the generated image should be in grayscales + * @return the generated BufferedImage + */ + protected BufferedImage paintToBufferedImage(Graphics2DImagePainter painter, + RendererContextWrapper context, int resolution, boolean gray) { + int bmw = UnitConv.mpt2px(context.getWidth(), resolution); + int bmh = UnitConv.mpt2px(context.getHeight(), resolution); + BufferedImage bi; + if (gray) { + bi = new BufferedImage(bmw, bmh, BufferedImage.TYPE_BYTE_GRAY); + } else { + bi = new BufferedImage(bmw, bmh, BufferedImage.TYPE_INT_ARGB); + } + Graphics2D g2d = bi.createGraphics(); + try { + g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, + RenderingHints.VALUE_FRACTIONALMETRICS_ON); + setRenderingHintsForBufferedImage(g2d); + + g2d.setBackground(Color.white); + g2d.setColor(Color.black); + g2d.clearRect(0, 0, bmw, bmh); + double sx = (double)bmw / context.getWidth(); + double sy = (double)bmh / context.getHeight(); + g2d.scale(sx, sy); + + //Paint the image on the BufferedImage + Rectangle2D area = new Rectangle2D.Double( + 0.0, 0.0, context.getWidth(), context.getHeight()); + painter.paint(g2d, area); + } finally { + g2d.dispose(); + } + return bi; + } + + /** + * Sets rendering hints on the Graphics2D created for painting to a BufferedImage. Subclasses + * can modify the settings to customize the behaviour. + * @param g2d the Graphics2D instance + */ + protected void setRenderingHintsForBufferedImage(Graphics2D g2d) { + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_OFF); + g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); + } + +} diff --git a/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java b/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java index d843de5ae..54accb5b8 100644 --- a/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java +++ b/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java @@ -22,6 +22,7 @@ import java.awt.Color; import java.awt.Rectangle; import java.awt.geom.Rectangle2D; import java.util.List; +import java.util.Map; import org.apache.fop.area.Area; import org.apache.fop.area.Block; @@ -29,12 +30,14 @@ import org.apache.fop.area.BlockViewport; import org.apache.fop.area.CTM; import org.apache.fop.area.RegionViewport; import org.apache.fop.area.Trait; +import org.apache.fop.area.inline.ForeignObject; import org.apache.fop.area.inline.InlineArea; import org.apache.fop.area.inline.Viewport; import org.apache.fop.fo.Constants; import org.apache.fop.fonts.FontMetrics; import org.apache.fop.image.FopImage; import org.apache.fop.traits.BorderProps; +import org.w3c.dom.Document; /** * Abstract base class for renderers like PDF and PostScript where many painting operations @@ -661,8 +664,18 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { * Draw an image at the indicated location. * @param url the URI/URL of the image * @param pos the position of the image + * @param foreignAttributes an optional Map with foreign attributes, may be null */ - protected abstract void drawImage(String url, Rectangle2D pos); + protected abstract void drawImage(String url, Rectangle2D pos, Map foreignAttributes); + + /** + * Draw an image at the indicated location. + * @param url the URI/URL of the image + * @param pos the position of the image + */ + protected final void drawImage(String url, Rectangle2D pos) { + drawImage(url, pos, null); + } /** * Draw a border segment of an XSL-FO style border. @@ -678,5 +691,15 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { */ protected abstract void drawBorderLine(float x1, float y1, float x2, float y2, boolean horz, boolean startOrBefore, int style, Color col); + + /** + * @see org.apache.fop.render.AbstractRenderer#renderForeignObject(ForeignObject, Rectangle2D) + */ + public void renderForeignObject(ForeignObject fo, Rectangle2D pos) { + endTextObject(); + Document doc = fo.getDocument(); + String ns = fo.getNameSpace(); + renderDocument(doc, ns, pos, fo.getForeignAttributes()); + } } diff --git a/src/java/org/apache/fop/render/PrintRenderer.java b/src/java/org/apache/fop/render/PrintRenderer.java index d782a7eed..4e0718a72 100644 --- a/src/java/org/apache/fop/render/PrintRenderer.java +++ b/src/java/org/apache/fop/render/PrintRenderer.java @@ -26,10 +26,13 @@ import org.apache.fop.fonts.FontInfo; import org.apache.fop.fonts.FontResolver; import org.apache.fop.fonts.FontSetup; import org.apache.fop.fonts.FontTriplet; +import org.w3c.dom.Document; // Java import java.awt.Color; +import java.awt.geom.Rectangle2D; import java.util.List; +import java.util.Map; /** Abstract base class of "Print" type renderers. */ public abstract class PrintRenderer extends AbstractRenderer { @@ -96,4 +99,52 @@ public abstract class PrintRenderer extends AbstractRenderer { return new Color(cols[0], cols[1], cols[2], cols[3]); } + /** + * Creates a RendererContext for an image. + * @param x the x coordinate (in millipoints) + * @param y the y coordinate (in millipoints) + * @param width the width of the image (in millipoints) + * @param height the height of the image (in millipoints) + * @param foreignAttributes a Map or foreign attributes, may be null + * @return the RendererContext + */ + protected RendererContext createRendererContext(int x, int y, int width, int height, + Map foreignAttributes) { + RendererContext context; + context = new RendererContext(this, getMimeType()); + context.setUserAgent(userAgent); + + context.setProperty(RendererContextConstants.WIDTH, + new Integer(width)); + context.setProperty(RendererContextConstants.HEIGHT, + new Integer(height)); + context.setProperty(RendererContextConstants.XPOS, + new Integer(x)); + context.setProperty(RendererContextConstants.YPOS, + new Integer(y)); + context.setProperty(RendererContextConstants.PAGE_VIEWPORT, + getCurrentPageViewport()); + if (foreignAttributes != null) { + context.setProperty(RendererContextConstants.FOREIGN_ATTRIBUTES, foreignAttributes); + } + return context; + } + + /** + * Renders an XML document (SVG for example). + * @param doc the DOM Document containing the XML document to be rendered + * @param ns the namespace URI for the XML document + * @param pos the position for the generated graphic/image + * @param foreignAttributes the foreign attributes containing rendering hints, or null + */ + public void renderDocument(Document doc, String ns, Rectangle2D pos, Map foreignAttributes) { + int x = currentIPPosition + (int) pos.getX(); + int y = currentBPPosition + (int) pos.getY(); + int width = (int)pos.getWidth(); + int height = (int)pos.getHeight(); + RendererContext context = createRendererContext(x, y, width, height, foreignAttributes); + + renderXML(context, doc, ns); + } + } diff --git a/src/java/org/apache/fop/render/RendererContext.java b/src/java/org/apache/fop/render/RendererContext.java index b81e10f69..0fdb74a1a 100644 --- a/src/java/org/apache/fop/render/RendererContext.java +++ b/src/java/org/apache/fop/render/RendererContext.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2005 The Apache Software Foundation. + * Copyright 1999-2006 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. @@ -22,6 +22,7 @@ package org.apache.fop.render; import java.util.Map; //FOP +import org.apache.avalon.framework.configuration.Configuration; import org.apache.fop.apps.FOUserAgent; /** @@ -101,5 +102,65 @@ public class RendererContext { return props.get(prop); } + /** + * Wrap the render context to allow easier access to its values. + * + * @param context the renderer context + * @return the generic renderer context wrapper + */ + public static RendererContextWrapper wrapRendererContext(RendererContext context) { + RendererContextWrapper wrapper = new RendererContextWrapper(context); + return wrapper; + } + + /** + * Base class for a wrapper around RendererContext to access its properties in a type-safe, + * renderer-specific way. + */ + public static class RendererContextWrapper { + + /** The wrapped RendererContext */ + protected RendererContext context; + + /** + * Main constructor + * @param context the RendererContent instance + */ + public RendererContextWrapper(RendererContext context) { + this.context = context; + } + + /** @return the currentXPosition */ + public int getCurrentXPosition() { + return ((Integer)context.getProperty(RendererContextConstants.XPOS)).intValue(); + } + + /** @return the currentYPosition */ + public int getCurrentYPosition() { + return ((Integer)context.getProperty(RendererContextConstants.YPOS)).intValue(); + } + + /** @return the width of the image */ + public int getWidth() { + return ((Integer)context.getProperty(RendererContextConstants.WIDTH)).intValue(); + } + + /** @return the height of the image */ + public int getHeight() { + return ((Integer)context.getProperty(RendererContextConstants.HEIGHT)).intValue(); + } + + /** @return the handler configuration */ + public Configuration getHandlerConfiguration() { + return (Configuration)context.getProperty( + RendererContextConstants.HANDLER_CONFIGURATION); + } + + /** @return the foreign attributes */ + public Map getForeignAttributes() { + return (Map)context.getProperty(RendererContextConstants.FOREIGN_ATTRIBUTES); + } + + } } diff --git a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java index a2cdce9ab..d8b8312b3 100644 --- a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java +++ b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java @@ -45,6 +45,7 @@ import java.io.IOException; import java.io.OutputStream; import java.util.Iterator; import java.util.List; +import java.util.Map; import org.w3c.dom.Document; @@ -68,6 +69,7 @@ import org.apache.fop.render.AbstractPathOrientedRenderer; import org.apache.fop.render.Graphics2DAdapter; import org.apache.fop.render.RendererContext; import org.apache.fop.render.pdf.CTMHelper; +import org.apache.fop.render.pdf.PDFRendererContextConstants; /** * The Java2DRenderer class provides the abstract technical @@ -770,9 +772,9 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem /** * @see org.apache.fop.render.AbstractPathOrientedRenderer#drawImage( - * java.lang.String, java.awt.geom.Rectangle2D) + * java.lang.String, java.awt.geom.Rectangle2D, java.util.Map) */ - protected void drawImage(String url, Rectangle2D pos) { + protected void drawImage(String url, Rectangle2D pos, Map foreignAttributes) { int x = currentIPPosition + (int)Math.round(pos.getX()); int y = currentBPPosition + (int)Math.round(pos.getY()); @@ -796,7 +798,7 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem } Document doc = ((XMLImage) fopimage).getDocument(); String ns = ((XMLImage) fopimage).getNameSpace(); - renderDocument(doc, ns, pos); + renderDocument(doc, ns, pos, foreignAttributes); } else if ("image/svg+xml".equals(mime)) { if (!fopimage.load(FopImage.ORIGINAL_DATA)) { @@ -805,7 +807,7 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem Document doc = ((XMLImage) fopimage).getDocument(); String ns = ((XMLImage) fopimage).getNameSpace(); - renderDocument(doc, ns, pos); + renderDocument(doc, ns, pos, foreignAttributes); } else if ("image/eps".equals(mime)) { log.warn("EPS images are not supported by this renderer"); } else { @@ -840,40 +842,15 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem } /** - * @see org.apache.fop.render.AbstractRenderer#renderForeignObject(ForeignObject, - * Rectangle2D) - */ - public void renderForeignObject(ForeignObject fo, Rectangle2D pos) { - Document doc = fo.getDocument(); - String ns = fo.getNameSpace(); - renderDocument(doc, ns, pos); - } - - /** - * 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 + * @see org.apache.fop.render.PrintRenderer#createRendererContext( + * int, int, int, int, java.util.Map) */ - public void renderDocument(Document doc, String ns, Rectangle2D pos) { - RendererContext context; - context = new RendererContext(this, getMimeType()); - context.setUserAgent(userAgent); - + protected RendererContext createRendererContext(int x, int y, int width, int height, + Map foreignAttributes) { + RendererContext context = super.createRendererContext( + x, y, width, height, foreignAttributes); context.setProperty(Java2DRendererContextConstants.JAVA2D_STATE, state); - context.setProperty(Java2DRendererContextConstants.XPOS, - new Integer(currentIPPosition + (int)pos.getX())); - context.setProperty(Java2DRendererContextConstants.YPOS, - new Integer(currentBPPosition + (int)pos.getY())); - context.setProperty(Java2DRendererContextConstants.WIDTH, - new Integer((int)pos.getWidth())); - context.setProperty(Java2DRendererContextConstants.HEIGHT, - new Integer((int) pos.getHeight())); - context.setProperty(Java2DRendererContextConstants.PAGE_VIEWPORT, - getCurrentPageViewport()); - - renderXML(context, doc, ns); + return context; } /** diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java index 0852eda39..fbc7049ca 100644 --- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java @@ -54,7 +54,6 @@ import org.apache.fop.area.OffDocumentItem; import org.apache.fop.area.BookmarkData; import org.apache.fop.area.inline.AbstractTextArea; import org.apache.fop.area.inline.TextArea; -import org.apache.fop.area.inline.ForeignObject; import org.apache.fop.area.inline.Image; import org.apache.fop.area.inline.Leader; import org.apache.fop.area.inline.InlineParent; @@ -1323,7 +1322,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { } /** @see org.apache.fop.render.AbstractPathOrientedRenderer */ - protected void drawImage(String url, Rectangle2D pos) { + protected void drawImage(String url, Rectangle2D pos, Map foreignAttributes) { endTextObject(); putImage(url, pos); } @@ -1360,7 +1359,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { Document doc = ((XMLImage) fopimage).getDocument(); String ns = ((XMLImage) fopimage).getNameSpace(); - renderDocument(doc, ns, pos); + renderDocument(doc, ns, pos, null); } else if ("image/svg+xml".equals(mime)) { if (!fopimage.load(FopImage.ORIGINAL_DATA)) { return; @@ -1368,7 +1367,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { Document doc = ((XMLImage) fopimage).getDocument(); String ns = ((XMLImage) fopimage).getNameSpace(); - renderDocument(doc, ns, pos); + renderDocument(doc, ns, pos, null); } else if ("image/eps".equals(mime)) { FopPDFImage pdfimage = new FopPDFImage(fopimage, url); int xobj = pdfDoc.addImage(currentContext, pdfimage).getXNumber(); @@ -1428,49 +1427,26 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { } /** - * @see org.apache.fop.render.AbstractRenderer#renderForeignObject(ForeignObject, Rectangle2D) + * @see org.apache.fop.render.PrintRenderer#createRendererContext( + * int, int, int, int, java.util.Map) */ - public void renderForeignObject(ForeignObject fo, Rectangle2D pos) { - endTextObject(); - Document doc = fo.getDocument(); - String ns = fo.getNameSpace(); - renderDocument(doc, ns, pos); - } - - /** - * 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, MIME_TYPE); - context.setUserAgent(userAgent); - + protected RendererContext createRendererContext(int x, int y, int width, int height, + Map foreignAttributes) { + RendererContext context = super.createRendererContext( + x, y, width, height, foreignAttributes); context.setProperty(PDFRendererContextConstants.PDF_DOCUMENT, pdfDoc); context.setProperty(PDFRendererContextConstants.OUTPUT_STREAM, ostream); - context.setProperty(PDFRendererContextConstants.PAGE_VIEWPORT, getCurrentPageViewport()); context.setProperty(PDFRendererContextConstants.PDF_STATE, currentState); context.setProperty(PDFRendererContextConstants.PDF_PAGE, currentPage); context.setProperty(PDFRendererContextConstants.PDF_CONTEXT, currentContext == null ? currentPage : currentContext); context.setProperty(PDFRendererContextConstants.PDF_CONTEXT, currentContext); context.setProperty(PDFRendererContextConstants.PDF_STREAM, currentStream); - context.setProperty(PDFRendererContextConstants.XPOS, - new Integer(currentIPPosition + (int) pos.getX())); - context.setProperty(PDFRendererContextConstants.YPOS, - new Integer(currentBPPosition + (int) pos.getY())); 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(PDFRendererContextConstants.WIDTH, - new Integer((int) pos.getWidth())); - context.setProperty(PDFRendererContextConstants.HEIGHT, - new Integer((int) pos.getHeight())); - renderXML(context, doc, ns); - + return context; } /** diff --git a/src/java/org/apache/fop/render/ps/PSRenderer.java b/src/java/org/apache/fop/render/ps/PSRenderer.java index 71c3bbcc2..e37e3734c 100644 --- a/src/java/org/apache/fop/render/ps/PSRenderer.java +++ b/src/java/org/apache/fop/render/ps/PSRenderer.java @@ -45,7 +45,6 @@ import org.apache.fop.area.PageViewport; import org.apache.fop.area.RegionViewport; import org.apache.fop.area.Trait; import org.apache.fop.area.inline.AbstractTextArea; -import org.apache.fop.area.inline.ForeignObject; import org.apache.fop.area.inline.Image; import org.apache.fop.area.inline.InlineParent; import org.apache.fop.area.inline.Leader; @@ -66,6 +65,7 @@ import org.apache.fop.render.Graphics2DAdapter; import org.apache.fop.render.AbstractPathOrientedRenderer; import org.apache.fop.render.ImageAdapter; import org.apache.fop.render.RendererContext; +import org.apache.fop.render.pdf.PDFRendererContextConstants; import org.apache.fop.render.ps.extensions.PSSetupCode; import org.apache.fop.util.CharUtilities; @@ -281,7 +281,7 @@ public class PSRenderer extends AbstractPathOrientedRenderer implements ImageAda } /** @see org.apache.fop.render.AbstractPathOrientedRenderer */ - protected void drawImage(String url, Rectangle2D pos) { + protected void drawImage(String url, Rectangle2D pos, Map foreignAttributes) { endTextObject(); url = ImageFactory.getURL(url); ImageFactory fact = userAgent.getFactory().getImageFactory(); @@ -307,7 +307,7 @@ public class PSRenderer extends AbstractPathOrientedRenderer implements ImageAda Document doc = ((XMLImage) fopimage).getDocument(); String ns = ((XMLImage) fopimage).getNameSpace(); - renderDocument(doc, ns, pos); + renderDocument(doc, ns, pos, foreignAttributes); } else if ("image/svg+xml".equals(mime)) { if (!fopimage.load(FopImage.ORIGINAL_DATA)) { return; @@ -315,7 +315,7 @@ public class PSRenderer extends AbstractPathOrientedRenderer implements ImageAda Document doc = ((XMLImage) fopimage).getDocument(); String ns = ((XMLImage) fopimage).getNameSpace(); - renderDocument(doc, ns, pos); + renderDocument(doc, ns, pos, foreignAttributes); } else if (fopimage instanceof EPSImage) { PSImageUtils.renderEPS((EPSImage)fopimage, x, y, w, h, gen); } else { @@ -1108,40 +1108,16 @@ public class PSRenderer extends AbstractPathOrientedRenderer implements ImageAda } /** - * @see org.apache.fop.render.AbstractRenderer#renderForeignObject(ForeignObject, Rectangle2D) + * @see org.apache.fop.render.PrintRenderer#createRendererContext( + * int, int, int, int, java.util.Map) */ - public void renderForeignObject(ForeignObject fo, Rectangle2D pos) { - Document doc = fo.getDocument(); - String ns = fo.getNameSpace(); - renderDocument(doc, ns, pos); - } - - /** - * Renders an XML document (SVG for example). - * @param doc DOM Document containing the XML document to be rendered - * @param ns Namespace for the XML document - * @param pos Position for the generated graphic/image - */ - public void renderDocument(Document doc, String ns, Rectangle2D pos) { - endTextObject(); - RendererContext context; - context = new RendererContext(this, MIME_TYPE); - context.setUserAgent(userAgent); - + protected RendererContext createRendererContext(int x, int y, int width, int height, + Map foreignAttributes) { + RendererContext context = super.createRendererContext( + x, y, width, height, foreignAttributes); 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(PSRendererContextConstants.HEIGHT, - new Integer((int) pos.getHeight())); - context.setProperty(PSRendererContextConstants.XPOS, - new Integer(currentIPPosition + (int) pos.getX())); - context.setProperty(PSRendererContextConstants.YPOS, - new Integer(currentBPPosition + (int) pos.getY())); - context.setProperty(PSRendererContextConstants.PAGE_VIEWPORT, - getCurrentPageViewport()); - - renderXML(context, doc, ns); + return context; } /** @see org.apache.fop.render.AbstractRenderer */ diff --git a/src/java/org/apache/fop/render/txt/TXTRenderer.java b/src/java/org/apache/fop/render/txt/TXTRenderer.java index f2f2c770b..a45199242 100644 --- a/src/java/org/apache/fop/render/txt/TXTRenderer.java +++ b/src/java/org/apache/fop/render/txt/TXTRenderer.java @@ -24,6 +24,7 @@ import java.awt.geom.Rectangle2D; import java.io.IOException; import java.io.OutputStream; import java.util.List; +import java.util.Map; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; @@ -444,12 +445,12 @@ public class TXTRenderer extends AbstractPathOrientedRenderer { } } - /** - * Does nothing. - * @param url String - * @param pos Rectangle2D + /** + * @see org.apache.fop.render.AbstractPathOrientedRenderer#drawImage( + * java.lang.String, java.awt.geom.Rectangle2D, java.util.Map) */ - protected void drawImage(String url, Rectangle2D pos) { + protected void drawImage(String url, Rectangle2D pos, Map foreignAttributes) { + //No images are painted here } /** diff --git a/src/sandbox/META-INF/services/org.apache.fop.render.XMLHandler b/src/sandbox/META-INF/services/org.apache.fop.render.XMLHandler index cbb7eaa67..3b85504a1 100644 --- a/src/sandbox/META-INF/services/org.apache.fop.render.XMLHandler +++ b/src/sandbox/META-INF/services/org.apache.fop.render.XMLHandler @@ -1 +1,2 @@ org.apache.fop.render.pcl.PCLSVGHandler +org.apache.fop.render.afp.AFPSVGHandler diff --git a/src/sandbox/org/apache/fop/render/afp/AFPGraphics2DAdapter.java b/src/sandbox/org/apache/fop/render/afp/AFPGraphics2DAdapter.java new file mode 100644 index 000000000..7aa68fe33 --- /dev/null +++ b/src/sandbox/org/apache/fop/render/afp/AFPGraphics2DAdapter.java @@ -0,0 +1,54 @@ +/* + * Copyright 2006 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.afp; + +import java.awt.image.BufferedImage; +import java.io.IOException; + +import org.apache.fop.render.AbstractGraphics2DAdapter; +import org.apache.fop.render.Graphics2DImagePainter; +import org.apache.fop.render.RendererContext; + +/** + * Graphics2DAdapter implementation for AFP. + */ +public class AFPGraphics2DAdapter extends AbstractGraphics2DAdapter { + + /** + * Main constructor + */ + public AFPGraphics2DAdapter() { + } + + /** @see org.apache.fop.render.Graphics2DAdapter */ + public void paintImage(Graphics2DImagePainter painter, + RendererContext context, + int x, int y, int width, int height) throws IOException { + RendererContext.RendererContextWrapper wrappedContext + = new RendererContext.RendererContextWrapper(context); + AFPRenderer afp = (AFPRenderer)context.getRenderer(); + + //Paint to a BufferedImage + int resolution = (int)Math.round(context.getUserAgent().getTargetResolution()); + BufferedImage bi = paintToBufferedImage(painter, wrappedContext, resolution, false); + + afp.drawBufferedImage(bi, resolution, x, y, width, height); + } + +} diff --git a/src/sandbox/org/apache/fop/render/afp/AFPRenderer.java b/src/sandbox/org/apache/fop/render/afp/AFPRenderer.java index fafaf6b6d..2a514d1a1 100644 --- a/src/sandbox/org/apache/fop/render/afp/AFPRenderer.java +++ b/src/sandbox/org/apache/fop/render/afp/AFPRenderer.java @@ -21,6 +21,7 @@ package org.apache.fop.render.afp; import java.awt.Color; import java.awt.Rectangle; import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; @@ -33,6 +34,7 @@ import java.util.Map; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; +import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.MimeConstants; import org.apache.fop.area.Block; @@ -77,6 +79,7 @@ import org.apache.fop.render.afp.modca.AFPConstants; import org.apache.fop.render.afp.modca.AFPDataStream; import org.apache.fop.render.afp.modca.ImageObject; import org.apache.fop.render.afp.modca.PageObject; +import org.w3c.dom.Document; /** @@ -565,8 +568,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { /** @see org.apache.fop.render.Renderer#getGraphics2DAdapter() */ public Graphics2DAdapter getGraphics2DAdapter() { - // TODO - return null; + return new AFPGraphics2DAdapter(); } /** @@ -1053,9 +1055,9 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { /** * Draw an image at the indicated location. - * @see org.apache.fop.render.AbstractRenderer#drawImage(String, Rectangle2D) + * @see org.apache.fop.render.AbstractRenderer#drawImage(String, Rectangle2D, Map) */ - public void drawImage(String url, Rectangle2D pos) { + public void drawImage(String url, Rectangle2D pos, Map foreignAttributes) { String name = null; if (_pageSegmentsMap != null) { name = (String)_pageSegmentsMap.get(url); @@ -1076,6 +1078,13 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { } String mime = fopimage.getMimeType(); if ("text/xml".equals(mime)) { + if (!fopimage.load(FopImage.ORIGINAL_DATA)) { + return; + } + Document doc = ((XMLImage) fopimage).getDocument(); + String ns = ((XMLImage) fopimage).getNameSpace(); + + renderDocument(doc, ns, pos, foreignAttributes); } else if (MimeConstants.MIME_SVG.equals(mime)) { if (!fopimage.load(FopImage.ORIGINAL_DATA)) { return; @@ -1098,6 +1107,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { convertToGrayScaleImage(io, SVGConverter.convertToTIFF((XMLImage)fopimage)); } } else if (MimeConstants.MIME_EPS.equals(mime)) { + log.warn("EPS images are not supported by this renderer"); /* } else if (MimeConstants.MIME_JPEG.equals(mime)) { if (!fopimage.load(FopImage.ORIGINAL_DATA)) { @@ -1188,6 +1198,46 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { } } + /** + * Draws a BufferedImage to AFP. + * @param bi the BufferedImage + * @param resolution the resolution of the BufferedImage + * @param x the x coordinate (in mpt) + * @param y the y coordinate (in mpt) + * @param w the width of the viewport (in mpt) + * @param h the height of the viewport (in mpt) + */ + public void drawBufferedImage(BufferedImage bi, int resolution, int x, int y, int w, int h) { + int afpx = mpts2units(x); + int afpy = mpts2units(y); + int afpw = mpts2units(w); + int afph = mpts2units(h); + ByteArrayOutputStream baout = new ByteArrayOutputStream(); + try { + //Serialize image + SVGConverter.writeImage(bi, baout); + byte[] buf = baout.toByteArray(); + + //Generate image + ImageObject io = _afpDataStream.getImageObject(afpx, afpy, afpw, afph); + io.setImageParameters( + resolution, resolution, + bi.getWidth(), + bi.getHeight() + ); + if (colorImages) { + io.setImageIDESize((byte)24); + io.setImageData(buf); + } else { + //TODO Teach it how to handle grayscale BufferedImages directly + //because this is pretty inefficient + convertToGrayScaleImage(io, buf); + } + } catch (IOException ioe) { + log.error("Error while serializing bitmap: " + ioe.getMessage(), ioe); + } + } + /** * Establishes a new foreground or fill color. * @see org.apache.fop.render.AbstractRenderer#updateColor(Color, boolean) diff --git a/src/sandbox/org/apache/fop/render/afp/AFPSVGHandler.java b/src/sandbox/org/apache/fop/render/afp/AFPSVGHandler.java new file mode 100644 index 000000000..8640486ce --- /dev/null +++ b/src/sandbox/org/apache/fop/render/afp/AFPSVGHandler.java @@ -0,0 +1,38 @@ +/* + * Copyright 2006 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.afp; + +// FOP +import org.apache.fop.render.AbstractGenericSVGHandler; +import org.apache.fop.render.Renderer; + +/** + * AFP XML handler for SVG. Uses Apache Batik for SVG processing. + * This handler handles XML for foreign objects and delegates to AFPGraphics2DAdapter. + * @see AFPGraphics2DAdapter + */ +public class AFPSVGHandler extends AbstractGenericSVGHandler { + + /** @see org.apache.fop.render.XMLHandler#supportsRenderer(org.apache.fop.render.Renderer) */ + public boolean supportsRenderer(Renderer renderer) { + return (renderer instanceof AFPRenderer); + } + +} + diff --git a/src/sandbox/org/apache/fop/render/afp/SVGConverter.java b/src/sandbox/org/apache/fop/render/afp/SVGConverter.java index a8c0e23ca..0adc32a53 100644 --- a/src/sandbox/org/apache/fop/render/afp/SVGConverter.java +++ b/src/sandbox/org/apache/fop/render/afp/SVGConverter.java @@ -19,6 +19,7 @@ package org.apache.fop.render.afp; import java.awt.image.BufferedImage; +import java.io.IOException; import java.io.OutputStream; import org.apache.batik.transcoder.TranscoderException; import org.apache.batik.transcoder.TranscoderInput; @@ -38,6 +39,21 @@ public class SVGConverter extends ImageTranscoder { public void writeImage(BufferedImage img, TranscoderOutput output) { OutputStream os = output.getOutputStream(); + try { + writeImage(img, os); + } catch (IOException ioe) { + //ignore + //TODO Handle IOException properly! + } + } + + /** + * Writes a BufferedImage to an OutputStream as raw sRGB bitmaps. + * @param img the BufferedImage + * @param out the OutputStream + * @throws IOException In case of an I/O error. + */ + public static void writeImage(BufferedImage img, OutputStream out) throws IOException { int w = img.getWidth(); int h = img.getHeight(); int[] tmpMap = img.getRGB(0, 0, w, h, null, 0, w); @@ -47,13 +63,9 @@ public class SVGConverter extends ImageTranscoder { int r = (p >> 16) & 0xFF; int g = (p >> 8) & 0xFF; int b = (p) & 0xFF; - try { - os.write((byte)(r & 0xFF)); - os.write((byte)(g & 0xFF)); - os.write((byte)(b & 0xFF)); - } catch (java.io.IOException ioex) { - - } + out.write((byte)(r & 0xFF)); + out.write((byte)(g & 0xFF)); + out.write((byte)(b & 0xFF)); } } } @@ -69,6 +81,7 @@ public class SVGConverter extends ImageTranscoder { * Converts a SVG image to a TIFF bitmap. * @param image the SVG image * @return a byte array containing the TIFF image + * @todo Please rename! The method name is misleading. */ public static byte[] convertToTIFF(XMLImage image) { // TIFFTranscoder transcoder = new TIFFTranscoder(); diff --git a/src/sandbox/org/apache/fop/render/pcl/PCLGraphics2DAdapter.java b/src/sandbox/org/apache/fop/render/pcl/PCLGraphics2DAdapter.java index 7f2c9d6cf..665eb6d6c 100644 --- a/src/sandbox/org/apache/fop/render/pcl/PCLGraphics2DAdapter.java +++ b/src/sandbox/org/apache/fop/render/pcl/PCLGraphics2DAdapter.java @@ -18,10 +18,7 @@ package org.apache.fop.render.pcl; -import java.awt.Color; import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.RenderingHints; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; @@ -30,7 +27,7 @@ import java.io.IOException; import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.fop.render.Graphics2DAdapter; +import org.apache.fop.render.AbstractGraphics2DAdapter; import org.apache.fop.render.Graphics2DImagePainter; import org.apache.fop.render.RendererContext; import org.apache.fop.util.UnitConv; @@ -39,7 +36,7 @@ import org.apache.xmlgraphics.java2d.GraphicContext; /** * Graphics2DAdapter implementation for PCL and HP GL/2. */ -public class PCLGraphics2DAdapter implements Graphics2DAdapter { +public class PCLGraphics2DAdapter extends AbstractGraphics2DAdapter { /** logging instance */ private static Log log = LogFactory.getLog(PCLGraphics2DAdapter.class); @@ -58,7 +55,7 @@ public class PCLGraphics2DAdapter implements Graphics2DAdapter { PCLRenderer pcl = (PCLRenderer)context.getRenderer(); PCLGenerator gen = pcl.gen; - // get the 'width' and 'height' attributes of the SVG document + // get the 'width' and 'height' attributes of the image/document Dimension dim = painter.getImageSize(); float imw = (float)dim.getWidth(); float imh = (float)dim.getHeight(); @@ -109,35 +106,9 @@ public class PCLGraphics2DAdapter implements Graphics2DAdapter { } if (!painted) { - int resolution = 300; //TODO not hard-coded, please! - int bmw = UnitConv.mpt2px(pclContext.getWidth(), resolution); - int bmh = UnitConv.mpt2px(pclContext.getHeight(), resolution); - BufferedImage bi = new BufferedImage( - bmw, bmh, - BufferedImage.TYPE_BYTE_GRAY); - Graphics2D g2d = bi.createGraphics(); - try { - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_OFF); - g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, - RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); - g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, - RenderingHints.VALUE_FRACTIONALMETRICS_ON); - - g2d.setBackground(Color.white); - g2d.setColor(Color.black); - g2d.clearRect(0, 0, bmw, bmh); - double sx = (double)bmw / pclContext.getWidth(); - double sy = (double)bmh / pclContext.getHeight(); - g2d.scale(sx, sy); - - //Paint the SVG on the BufferedImage - Rectangle2D area = new Rectangle2D.Double( - 0.0, 0.0, pclContext.getWidth(), pclContext.getHeight()); - painter.paint(g2d, area); - } finally { - g2d.dispose(); - } + //Fallback solution: Paint to a BufferedImage + int resolution = (int)Math.round(context.getUserAgent().getTargetResolution()); + BufferedImage bi = paintToBufferedImage(painter, pclContext, resolution, true); pcl.setCursorPos(x, y); gen.paintBitmap(bi, resolution); diff --git a/src/sandbox/org/apache/fop/render/pcl/PCLRenderer.java b/src/sandbox/org/apache/fop/render/pcl/PCLRenderer.java index 903d3eec7..450fb5852 100644 --- a/src/sandbox/org/apache/fop/render/pcl/PCLRenderer.java +++ b/src/sandbox/org/apache/fop/render/pcl/PCLRenderer.java @@ -776,54 +776,6 @@ public class PCLRenderer extends PrintRenderer { renderDocument(doc, ns, pos, fo.getForeignAttributes()); } - /** - * Renders an XML document (SVG for example). - * @param doc the DOM Document containing the XML document to be rendered - * @param ns the namespace URI for the XML document - * @param pos the position for the generated graphic/image - * @param foreignAttributes the foreign attributes containing rendering hints, or null - */ - public void renderDocument(Document doc, String ns, Rectangle2D pos, Map foreignAttributes) { - int x = currentIPPosition + (int) pos.getX(); - int y = currentBPPosition + (int) pos.getY(); - int width = (int)pos.getWidth(); - int height = (int)pos.getHeight(); - RendererContext context = createRendererContext(x, y, width, height, foreignAttributes); - - renderXML(context, doc, ns); - } - - /** - * Creates a RendererContext for an image. - * @param x the x coordinate (in millipoints) - * @param y the y coordinate (in millipoints) - * @param width the width of the image (in millipoints) - * @param height the height of the image (in millipoints) - * @param foreignAttributes a Map or foreign attributes, may be null - * @return the RendererContext - */ - protected RendererContext createRendererContext(int x, int y, int width, int height, - Map foreignAttributes) { - RendererContext context; - context = new RendererContext(this, MIME_TYPE); - context.setUserAgent(userAgent); - - context.setProperty(RendererContextConstants.WIDTH, - new Integer(width)); - context.setProperty(RendererContextConstants.HEIGHT, - new Integer(height)); - context.setProperty(RendererContextConstants.XPOS, - new Integer(x)); - context.setProperty(RendererContextConstants.YPOS, - new Integer(y)); - context.setProperty(RendererContextConstants.PAGE_VIEWPORT, - getCurrentPageViewport()); - if (foreignAttributes != null) { - context.setProperty(RendererContextConstants.FOREIGN_ATTRIBUTES, foreignAttributes); - } - return context; - } - /** * Common method to render the background and borders for any inline area. * The all borders and padding are drawn outside the specified area. diff --git a/src/sandbox/org/apache/fop/render/pcl/PCLRendererContext.java b/src/sandbox/org/apache/fop/render/pcl/PCLRendererContext.java index 73e27bcac..2f77dd4aa 100644 --- a/src/sandbox/org/apache/fop/render/pcl/PCLRendererContext.java +++ b/src/sandbox/org/apache/fop/render/pcl/PCLRendererContext.java @@ -29,10 +29,8 @@ import org.apache.fop.util.QName; * Wrapper on the RendererContext to access the information structure for drawing * the XML document. */ -public class PCLRendererContext { +public class PCLRendererContext extends RendererContext.RendererContextWrapper { - private RendererContext context; - /** * Wrap the render context to allow easier access to its values. * @@ -49,37 +47,7 @@ public class PCLRendererContext { * @param context the RendererContent instance */ public PCLRendererContext(RendererContext context) { - this.context = context; - } - - /** @return the currentXPosition */ - public int getCurrentXPosition() { - return ((Integer)context.getProperty(PCLSVGHandler.XPOS)).intValue(); - } - - /** @return the currentYPosition */ - public int getCurrentYPosition() { - return ((Integer)context.getProperty(PCLSVGHandler.YPOS)).intValue(); - } - - /** @return the width of the image */ - public int getWidth() { - return ((Integer)context.getProperty(PCLSVGHandler.WIDTH)).intValue(); - } - - /** @return the height of the image */ - public int getHeight() { - return ((Integer)context.getProperty(PCLSVGHandler.HEIGHT)).intValue(); - } - - /** @return the handler configuration */ - public Configuration getHandlerConfiguration() { - return (Configuration)context.getProperty(PCLSVGHandler.HANDLER_CONFIGURATION); - } - - /** @return the foreign attributes */ - public Map getForeignAttributes() { - return (Map)context.getProperty(PCLSVGHandler.FOREIGN_ATTRIBUTES); + super(context); } /** @return true if the SVG image should be rendered as a bitmap */ diff --git a/src/sandbox/org/apache/fop/render/pcl/PCLSVGHandler.java b/src/sandbox/org/apache/fop/render/pcl/PCLSVGHandler.java index 7eec5169d..7c1a45a0d 100644 --- a/src/sandbox/org/apache/fop/render/pcl/PCLSVGHandler.java +++ b/src/sandbox/org/apache/fop/render/pcl/PCLSVGHandler.java @@ -18,129 +18,22 @@ package org.apache.fop.render.pcl; -// Java -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; -import java.io.IOException; - -// DOM -import org.w3c.dom.Document; - -// Batik -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; - // FOP -import org.apache.fop.render.Graphics2DAdapter; -import org.apache.fop.render.Graphics2DImagePainter; +import org.apache.fop.render.AbstractGenericSVGHandler; import org.apache.fop.render.Renderer; -import org.apache.fop.render.RendererContextConstants; -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; /** * PCL XML handler for SVG. Uses Apache Batik for SVG processing. * This handler handles XML for foreign objects when rendering to HP GL/2. * It renders SVG to HP GL/2 using the PCLGraphics2D. - * - * @version $Id$ + * @see PCLGraphics2DAdapter */ -public class PCLSVGHandler implements XMLHandler, RendererContextConstants { - - /** logging instance */ - private static Log log = LogFactory.getLog(PCLSVGHandler.class); - - /** - * Create a new XML handler for use by the PCL renderer. - */ - public PCLSVGHandler() { - } - - /** @see org.apache.fop.render.XMLHandler */ - public void handleXML(RendererContext context, - Document doc, String ns) throws Exception { - PCLRendererContext pclContext = PCLRendererContext.wrapRendererContext(context); - - if (SVGDOMImplementation.SVG_NAMESPACE_URI.equals(ns)) { - renderSVGDocument(context, doc, pclContext); - } - } - - /** - * Render the SVG document. - * @param context the renderer context - * @param doc the SVG document - * @param pclContext the information of the current context - */ - protected void renderSVGDocument(final RendererContext context, - final Document doc, final PCLRendererContext pclContext) { - int x = pclContext.getCurrentXPosition(); - int y = pclContext.getCurrentYPosition(); - - SVGUserAgent ua = new SVGUserAgent( - context.getUserAgent().getSourcePixelUnitToMillimeter(), - new AffineTransform()); - GVTBuilder builder = new GVTBuilder(); - final BridgeContext ctx = new BridgeContext(ua); - - final GraphicsNode root; - try { - root = builder.build(ctx, doc); - - } catch (Exception e) { - log.error("SVG graphic could not be built: " - + e.getMessage(), e); - return; - } - - Graphics2DImagePainter painter = new Graphics2DImagePainter() { - - public void paint(Graphics2D g2d, Rectangle2D area) { - - // 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(); - float ih = (float) ctx.getDocumentSize().getHeight(); - float w = (float) area.getWidth(); - float h = (float) area.getHeight(); - g2d.scale(w / iw, h / ih); - - root.paint(g2d); - } - - public Dimension getImageSize() { - return new Dimension(pclContext.getWidth(), pclContext.getHeight()); - } - - }; - - try { - Graphics2DAdapter adapter = context.getRenderer().getGraphics2DAdapter(); - adapter.paintImage(painter, context, - x, y, pclContext.getWidth(), pclContext.getHeight()); - } catch (IOException ioe) { - ((PCLRenderer)context.getRenderer()).handleIOTrouble(ioe); - } - } +public class PCLSVGHandler extends AbstractGenericSVGHandler { /** @see org.apache.fop.render.XMLHandler#supportsRenderer(org.apache.fop.render.Renderer) */ public boolean supportsRenderer(Renderer renderer) { return (renderer instanceof PCLRenderer); } - /** @see org.apache.fop.render.XMLHandler#getNamespace() */ - public String getNamespace() { - return SVGDOMImplementation.SVG_NAMESPACE_URI; - } - } -- 2.39.5