]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Forgot this one. This is not much more than work in progress. (a copy from PDF)
authorJeremias Maerki <jeremias@apache.org>
Mon, 27 Jan 2003 09:17:56 +0000 (09:17 +0000)
committerJeremias Maerki <jeremias@apache.org>
Mon, 27 Jan 2003 09:17:56 +0000 (09:17 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@195895 13f79535-47bb-0310-9956-ffa450edef68

src/org/apache/fop/render/ps/PSXMLHandler.java [new file with mode: 0644]

diff --git a/src/org/apache/fop/render/ps/PSXMLHandler.java b/src/org/apache/fop/render/ps/PSXMLHandler.java
new file mode 100644 (file)
index 0000000..6601a43
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ * $Id$
+ * Copyright (C) 2001-2003 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.render.ps;
+
+import org.apache.fop.render.XMLHandler;
+import org.apache.fop.render.RendererContext;
+import org.apache.fop.pdf.PDFDocument;
+import org.apache.fop.pdf.PDFPage;
+import org.apache.fop.pdf.PDFState;
+import org.apache.fop.pdf.PDFStream;
+import org.apache.fop.pdf.PDFNumber;
+import org.apache.fop.pdf.PDFResourceContext;
+import org.apache.fop.svg.PDFTextElementBridge;
+import org.apache.fop.svg.PDFAElementBridge;
+import org.apache.fop.svg.PDFGraphics2D;
+import org.apache.fop.svg.SVGUserAgent;
+import org.apache.fop.layout.FontInfo;
+
+import org.w3c.dom.Document;
+
+import java.io.OutputStream;
+
+import org.apache.batik.bridge.GVTBuilder;
+import org.apache.batik.bridge.BridgeContext;
+import org.apache.batik.bridge.ViewBox;
+
+import org.apache.batik.gvt.GraphicsNode;
+
+import org.w3c.dom.svg.SVGDocument;
+import org.w3c.dom.svg.SVGSVGElement;
+
+import java.awt.geom.AffineTransform;
+
+/**
+ * PostScript XML handler.
+ * This handler handles XML for foreign objects when rendering to PostScript.
+ * 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 PSXMLHandler implements XMLHandler {
+    /**
+     * 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.
+     */
+    public PSXMLHandler() {
+    }
+
+    /**
+     * Handle the XML.
+     * This checks the type of XML and handles appropraitely.
+     *
+     * @param context the renderer context
+     * @param doc the XML document to render
+     * @param ns the namespace of the XML document
+     * @throws Exception any sort of exception could be thrown and shuld be handled
+     */
+    public void handleXML(RendererContext context, Document doc,
+                          String ns) throws Exception {
+        PSInfo psi = getPSInfo(context);
+
+        String svg = "http://www.w3.org/2000/svg";
+        if (svg.equals(ns)) {
+            SVGHandler svghandler = new SVGHandler();
+            svghandler.renderSVGDocument(context, doc, psi);
+        } else {
+        }
+    }
+
+    /**
+     * Get the pdf information from the render context.
+     *
+     * @param context the renderer context
+     * @return the pdf information retrieved from the context
+     */
+    public static PSInfo getPSInfo(RendererContext context) {
+        PSInfo psi = new PSInfo();
+        /*
+        pdfi.pdfDoc = (PDFDocument)context.getProperty(PDF_DOCUMENT);
+        pdfi.outputStream = (OutputStream)context.getProperty(OUTPUT_STREAM);
+        pdfi.pdfState = (PDFState)context.getProperty(PDF_STATE);
+        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.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();
+        */
+        return psi;
+    }
+
+    /**
+     * PostScript information structure for drawing the XML document.
+     */
+    public static class PSInfo {
+        
+        /** see PDF_DOCUMENT */
+        public PDFDocument pdfDoc;
+        /** see OUTPUT_STREAM */
+        public OutputStream outputStream;
+        /** see PDF_STATE */
+        public PDFState pdfState;
+        /** see PDF_PAGE */
+        public PDFPage pdfPage;
+        /** see PDF_CONTEXT */
+        public PDFResourceContext pdfContext;
+        /** see PDF_STREAM */
+        public PDFStream currentStream;
+        /** see PDF_WIDTH */
+        public int width;
+        /** see PDF_HEIGHT */
+        public int height;
+        /** see PDF_FONT_INFO */
+        public FontInfo fi;
+        /** see PDF_FONT_NAME */
+        public String currentFontName;
+        /** see PDF_FONT_SIZE */
+        public int currentFontSize;
+        /** see PDF_XPOS */
+        public int currentXPosition;
+        /** see PDF_YPOS */
+        public int 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 pdfInfo the pdf information of the current context
+         */
+        protected void renderSVGDocument(RendererContext context, Document doc, PSInfo psInfo) {
+            int xOffset = psInfo.currentXPosition;
+            int yOffset = psInfo.currentYPosition;
+
+            SVGUserAgent ua
+                 = new SVGUserAgent(context.getUserAgent(), new AffineTransform());
+
+            GVTBuilder builder = new GVTBuilder();
+            BridgeContext ctx = new BridgeContext(ua);
+            PDFTextElementBridge tBridge = new PDFTextElementBridge(psInfo.fi);
+            ctx.putBridge(tBridge);
+
+            PDFAElementBridge aBridge = new PDFAElementBridge();
+            // to get the correct transform we need to use the PDFState
+            AffineTransform transform = psInfo.pdfState.getTransform();
+            transform.translate(xOffset / 1000f, yOffset / 1000f);
+            aBridge.setCurrentTransform(transform);
+            ctx.putBridge(aBridge);
+
+            GraphicsNode root;
+            try {
+                root = builder.build(ctx, doc);
+            } catch (Exception e) {
+                context.getUserAgent().getLogger().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.width / (float)w;
+            float sy = psInfo.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
+             */
+            psInfo.currentStream.add("q\n");
+            // 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.
+            psInfo.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);
+            if (!at.isIdentity()) {
+                double[] vals = new double[6];
+                at.getMatrix(vals);
+                psInfo.currentStream.add(PDFNumber.doubleOut(vals[0], 5) + " "
+                                + PDFNumber.doubleOut(vals[1], 5) + " "
+                                + PDFNumber.doubleOut(vals[2], 5) + " "
+                                + PDFNumber.doubleOut(vals[3], 5) + " "
+                                + PDFNumber.doubleOut(vals[4]) + " "
+                                + PDFNumber.doubleOut(vals[5]) + " cm\n");
+            }
+
+            if (psInfo.pdfContext == null) {
+                psInfo.pdfContext = psInfo.pdfPage;
+            }
+            PDFGraphics2D graphics = new PDFGraphics2D(true, psInfo.fi, psInfo.pdfDoc,
+                                     psInfo.pdfContext, psInfo.pdfPage.referencePDF(),
+                                     psInfo.currentFontName,
+                                     psInfo.currentFontSize);
+            graphics.setGraphicContext(new org.apache.batik.ext.awt.g2d.GraphicContext());
+            psInfo.pdfState.push();
+            transform = new AffineTransform();
+            // scale to viewbox
+            transform.translate(xOffset / 1000f, yOffset / 1000f);
+            psInfo.pdfState.setTransform(transform);
+            graphics.setPDFState(psInfo.pdfState);
+            graphics.setOutputStream(psInfo.outputStream);
+            try {
+                root.paint(graphics);
+                psInfo.currentStream.add(graphics.getString());
+            } catch (Exception e) {
+                context.getUserAgent().getLogger().error("svg graphic could not be rendered: "
+                                       + e.getMessage(), e);
+            }
+
+            psInfo.currentStream.add("Q\n");
+            psInfo.pdfState.pop();
+        }
+    }
+}
+