]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
SVG (for PS renderer) works (to a certain degree)
authorJeremias Maerki <jeremias@apache.org>
Thu, 30 Jan 2003 17:31:20 +0000 (17:31 +0000)
committerJeremias Maerki <jeremias@apache.org>
Thu, 30 Jan 2003 17:31:20 +0000 (17:31 +0000)
No TextPainter, yet (disabled in PSTextElementBridge)
No transcoder, yet.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@195915 13f79535-47bb-0310-9956-ffa450edef68

src/org/apache/fop/render/ps/PSGenerator.java
src/org/apache/fop/render/ps/PSGraphics2D.java
src/org/apache/fop/render/ps/PSRenderer.java
src/org/apache/fop/render/ps/PSState.java [new file with mode: 0644]
src/org/apache/fop/render/ps/PSTextElementBridge.java [new file with mode: 0644]
src/org/apache/fop/render/ps/PSXMLHandler.java

index 3181f203d863cfbf5139874491388e30325d726d..5e335e351aa83de6ac443e4e3cf001ad4fba0f54 100644 (file)
@@ -11,6 +11,7 @@ import java.io.IOException;
 import java.text.DateFormat;
 import java.text.NumberFormat;
 import java.util.Date;
+import java.util.Stack;
 
 /**
  * This class is used to output PostScript code to an OutputStream.
@@ -28,12 +29,17 @@ public class PSGenerator {
     public static final AtendIndicator ATEND = new AtendIndicator() {};
 
     private OutputStream out;
+    
+    private Stack graphicsStateStack = new Stack();
+    private PSState currentState;
 
     private StringBuffer tempBuffer = new StringBuffer(256);
 
     /** @see java.io.FilterOutputStream **/
     public PSGenerator(OutputStream out) {
         this.out = out;
+        this.currentState = new PSState();
+        this.graphicsStateStack.push(this.currentState);
     }
 
     /**
@@ -252,6 +258,68 @@ public class PSGenerator {
     }
     
     
+    /**
+     * Saves the graphics state of the rendering engine.
+     * @exception IOException In case of an I/O problem
+     */
+    public void saveGraphicsState() throws IOException {
+        writeln("gsave");
+        
+        PSState state = (PSState)this.currentState.clone();
+        this.graphicsStateStack.push(this.currentState);
+        this.currentState = state;
+    }
+    
+    /** 
+     * Restores the last graphics state of the rendering engine.
+     * @exception IOException In case of an I/O problem
+     */
+    public void restoreGraphicsState() throws IOException {
+        writeln("grestore");
+        this.currentState = (PSState)this.graphicsStateStack.pop();
+    }
+    
+    /**
+     * Concats the transformation matrix.
+     * @param a A part
+     * @param b B part
+     * @param c C part
+     * @param d D part
+     * @param e E part
+     * @param f F part
+     * @exception IOException In case of an I/O problem
+     */
+    public void concatMatrix(double a, double b,
+                                double c, double d, 
+                                double e, double f) throws IOException {
+        writeln("[" + formatDouble(a) + " "
+                    + formatDouble(b) + " "
+                    + formatDouble(c) + " "
+                    + formatDouble(d) + " "
+                    + formatDouble(e) + " "
+                    + formatDouble(f) + "] concat");
+    }
+    
+    /**
+     * Concats the transformations matrix.
+     * @param matrix Matrix to use
+     * @exception IOException In case of an I/O problem
+     */
+    public void concatMatrix(double[] matrix) throws IOException {
+        concatMatrix(matrix[0], matrix[1], 
+                     matrix[2], matrix[3], 
+                     matrix[4], matrix[5]);
+    }
+                                
+    /**
+     * Returns the current graphics state.
+     * @return the current graphics state
+     */
+    public PSState getCurrentState() {
+        return this.currentState;
+    }
+
+    
     /** Used for the ATEND constant. See there. */
     private static interface AtendIndicator {
     }
index 93b2d78f0ae08328f5b0b33e6426fdd56bd4c77e..d4241cbfb72d44f8dc4b6d2663f7442e47734b23 100644 (file)
@@ -103,31 +103,12 @@ public class PSGraphics2D extends AbstractGraphics2D {
     /**
      * Create a new Graphics2D that generates PostScript code.
      * @param textAsShapes True if text should be rendered as graphics
-     * @param fs currently valid FontState object
      * @param gen PostScript generator to use for output
-     * @param font current font name
-     * @param size current font size
-     * @param xpos current x pos
-     * @param ypos current y pos
      * @see org.apache.batik.ext.awt.g2d.AbstractGraphics2D#AbstractGraphics2D(boolean)
      */
-    public PSGraphics2D(boolean textAsShapes, FontState fs, PSGenerator gen,
-                        String font, int size, int xpos, int ypos) {
+    public PSGraphics2D(boolean textAsShapes, PSGenerator gen) {
         super(textAsShapes);
         this.gen = gen;
-        currentFontName = font;
-        currentFontSize = size;
-        currentYPosition = ypos;
-        currentXPosition = xpos;
-        fontState = fs;
-    }
-
-    /**
-     * Create a new Graphics2D that generates PostScript code.
-     * @see org.apache.batik.ext.awt.g2d.AbstractGraphics2D#AbstractGraphics2D(boolean)
-     */
-    public PSGraphics2D(boolean textAsShapes) {
-        super(textAsShapes);
     }
 
     /**
@@ -473,7 +454,7 @@ public class PSGraphics2D extends AbstractGraphics2D {
     public void draw(Shape s) {
         try {
             // System.out.println("draw(Shape)");
-            gen.writeln("gsave");
+            gen.saveGraphicsState();
             Shape imclip = getClip();
             writeClip(imclip);
             Color c = getColor();
@@ -523,7 +504,7 @@ public class PSGraphics2D extends AbstractGraphics2D {
                 iter.next();
             }
             doDrawing(false, true, false);
-            gen.writeln("grestore");
+            gen.restoreGraphicsState();
         } catch (IOException ioe) {
             handleIOException(ioe);
         }
index b3d1a37116c1ed7b492ab624f85ca516beee0190..d8b1be3c1c6b11d332f711aad94876c93ed9d721 100644 (file)
@@ -25,6 +25,7 @@ import org.apache.fop.area.Trait;
 import org.apache.fop.area.inline.ForeignObject;
 import org.apache.fop.area.inline.Word;
 import org.apache.fop.datatypes.ColorType;
+import org.apache.fop.fo.FOUserAgent;
 import org.apache.fop.fonts.Font;
 import org.apache.fop.layout.FontInfo;
 import org.apache.fop.render.AbstractRenderer;
@@ -86,6 +87,17 @@ public class PSRenderer extends AbstractRenderer {
         this.producer = producer;
     }
 
+    /**
+     * @see org.apache.fop.render.Renderer#setUserAgent(FOUserAgent)
+     */
+    public void setUserAgent(FOUserAgent agent) {
+        super.setUserAgent(agent);
+        PSXMLHandler xmlHandler = new PSXMLHandler();
+        //userAgent.setDefaultXMLHandler(MIME_TYPE, xmlHandler);
+        String svg = "http://www.w3.org/2000/svg";
+        userAgent.addXMLHandler(MIME_TYPE, svg, xmlHandler);
+    }
+
     /**
      * Write out a command
      * @param cmd PostScript command
@@ -98,6 +110,10 @@ public class PSRenderer extends AbstractRenderer {
         }
     }
 
+    /**
+     * Central exception handler for I/O exceptions.
+     * @param ioe IOException to handle
+     */
     protected void handleIOTrouble(IOException ioe) {
         if (!ioTrouble) {
             getLogger().error("Error while writing to target file", ioe);
@@ -166,13 +182,23 @@ public class PSRenderer extends AbstractRenderer {
     }
 
     /** Saves the graphics state of the rendering engine. */
-    protected void saveGraphicsState() {
-        writeln("gsave");
+    public void saveGraphicsState() {
+        try {
+            //delegate
+            gen.saveGraphicsState();
+        } catch (IOException ioe) {
+            handleIOTrouble(ioe);
+        }
     }
     
     /** Restores the last graphics state of the rendering engine. */
-    protected void restoreGraphicsState() {
-        writeln("grestore");
+    public void restoreGraphicsState() {
+        try {
+            //delegate
+            gen.restoreGraphicsState();
+        } catch (IOException ioe) {
+            handleIOTrouble(ioe);
+        }
     }
     
     /** Indicates the beginning of a text object. */
@@ -184,7 +210,38 @@ public class PSRenderer extends AbstractRenderer {
     protected void endTextObject() {
         writeln("ET");
     }
-        
+
+    /**
+     * Concats the transformation matrix.
+     * @param a A part
+     * @param b B part
+     * @param c C part
+     * @param d D part
+     * @param e E part
+     * @param f F part
+     */
+    protected void concatMatrix(double a, double b,
+                                double c, double d, 
+                                double e, double f) {
+        try {
+            gen.concatMatrix(a, b, c, d, e, f);
+        } catch (IOException ioe) {
+            handleIOTrouble(ioe);
+        }
+    }
+    
+    /**
+     * Concats the transformations matrix.
+     * @param matrix Matrix to use
+     */
+    protected void concatMatrix(double[] matrix) {
+        try {
+            gen.concatMatrix(matrix);
+        } catch (IOException ioe) {
+            handleIOTrouble(ioe);
+        }
+    }
+                                
     /**
      * Set up the font info
      *
@@ -210,6 +267,13 @@ public class PSRenderer extends AbstractRenderer {
         writeln(x + " " + y + " " + w + " " + h + " rectfill");
     }
 
+    /**
+     * Draws a stroked rectangle with the current stroke settings.
+     * @param x x-coordinate
+     * @param y y-coordinate
+     * @param w width
+     * @param h height
+     */
     protected void drawRect(int x, int y, int w, int h) {
         writeln(x + " " + y + " " + w + " " + h + " rectstroke");
     }
@@ -315,7 +379,7 @@ public class PSRenderer extends AbstractRenderer {
                 {zero, zero, pagewidth, pageheight});
         gen.writeDSCComment(DSCConstants.BEGIN_PAGE_SETUP);         
         gen.writeln("FOPFonts begin");
-        gen.writeln("[1 0 0 -1 0 " + pageheight + "] concat");
+        concatMatrix(1, 0, 0, -1, 0, pageheight.doubleValue());
         gen.writeln("0.001 0.001 scale");
         gen.writeDSCComment(DSCConstants.END_PAGE_SETUP);         
         
@@ -327,6 +391,13 @@ public class PSRenderer extends AbstractRenderer {
         gen.writeDSCComment(DSCConstants.END_PAGE);
     }
 
+    /**
+     * Paints text.
+     * @param rx X coordinate
+     * @param bl Y coordinate
+     * @param text Text to paint
+     * @param font Font to use
+     */
     protected void paintText(int rx, int bl, String text, Font font) {
         saveGraphicsState();
         writeln("1 0 0 -1 " + rx + " " + bl + " Tm");
@@ -366,7 +437,8 @@ public class PSRenderer extends AbstractRenderer {
 /*
         String psString = null;
         if (area.getFontState().getLetterSpacing() > 0) {
-            //float f = area.getFontState().getLetterSpacing() * 1000 / this.currentFontSize;
+            //float f = area.getFontState().getLetterSpacing() 
+            //    * 1000 / this.currentFontSize;
             float f = area.getFontState().getLetterSpacing();
             psString = (new StringBuffer().append(f).append(" 0.0 (")
               .append(sb.toString()).append(") A")).toString();
@@ -511,17 +583,12 @@ public class PSRenderer extends AbstractRenderer {
         // Set the given CTM in the graphics state
         //currentState.push();
         //currentState.setTransform(new AffineTransform(CTMHelper.toPDFArray(ctm)));
-
+        
         saveGraphicsState();
         // multiply with current CTM
         //currentStream.add(CTMHelper.toPDFString(ctm) + " cm\n");
         final double matrix[] = ctm.toArray();
-        writeln("[" + gen.formatDouble(matrix[0]) 
-                + " " + gen.formatDouble(matrix[1])
-                + " " + gen.formatDouble(matrix[2]) 
-                + " " + gen.formatDouble(matrix[3])
-                + " " + gen.formatDouble(matrix[4])
-                + " " + gen.formatDouble(matrix[5]) + "] concat");
+        concatMatrix(matrix);
         
         // Set clip?
         beginTextObject();        
@@ -551,6 +618,16 @@ public class PSRenderer extends AbstractRenderer {
         context = new RendererContext(MIME_TYPE);
         context.setUserAgent(userAgent);
 
+        context.setProperty(PSXMLHandler.PS_GENERATOR, this.gen);
+        context.setProperty(PSXMLHandler.PS_FONT_INFO, fontInfo);
+        context.setProperty(PSXMLHandler.PS_WIDTH,
+                            new Integer((int) pos.getWidth()));
+        context.setProperty(PSXMLHandler.PS_HEIGHT,
+                            new Integer((int) pos.getHeight()));
+        context.setProperty(PSXMLHandler.PS_XPOS,
+                            new Integer(currentBlockIPPosition + (int) pos.getX()));
+        context.setProperty(PSXMLHandler.PS_YPOS,
+                            new Integer(currentBPPosition + (int) pos.getY()));
         /*
         context.setProperty(PDFXMLHandler.PDF_DOCUMENT, pdfDoc);
         context.setProperty(PDFXMLHandler.OUTPUT_STREAM, ostream);
diff --git a/src/org/apache/fop/render/ps/PSState.java b/src/org/apache/fop/render/ps/PSState.java
new file mode 100644 (file)
index 0000000..8b9b926
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * $Id$
+ * Copyright (C) 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 java.io.Serializable;
+import java.awt.geom.AffineTransform;
+
+/**
+ * This class holds the current state of the PostScript interpreter.
+ * 
+ * @author <a href="mailto:fop-dev@xml.apache.org">Apache XML FOP Development Team</a>
+ * @author <a href="mailto:jeremias@apache.org">Jeremias Maerki</a>
+ * @version $Id$
+ */
+public class PSState implements Serializable, Cloneable {
+
+    private AffineTransform transform = new AffineTransform();
+    /**
+     * Returns the transform.
+     * @return the current transformation matrix
+     */
+    public AffineTransform getTransform() {
+        return this.transform;
+    }
+
+    /**
+     * Concats the given transformation matrix with the current one.
+     * @param transform The new transformation matrix
+     */
+    public void concatMatrix(AffineTransform transform) {
+        this.transform.concatenate(transform);
+    }
+
+    /**
+     * @see java.lang.Object#clone()
+     */
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) { 
+            // this shouldn't happen, since we are Cloneable
+            throw new InternalError();
+        }
+    }
+    
+}
diff --git a/src/org/apache/fop/render/ps/PSTextElementBridge.java b/src/org/apache/fop/render/ps/PSTextElementBridge.java
new file mode 100644 (file)
index 0000000..801ba8a
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * $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.batik.gvt.TextNode;
+import org.apache.batik.bridge.SVGTextElementBridge;
+import org.apache.batik.bridge.BridgeContext;
+//import org.apache.batik.bridge.TextUtilities;
+import org.apache.batik.gvt.GraphicsNode;
+
+import org.apache.fop.layout.FontInfo;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Bridge class for the &lt;text> element.
+ * This bridge will use the direct text painter if the text
+ * for the element is simple.
+ *
+ * @author <a href="mailto:fop-dev@xml.apache.org">Apache XML FOP Development Team</a>
+ * @version $Id$
+ */
+public class PSTextElementBridge extends SVGTextElementBridge {
+    
+    //private PSTextPainter textPainter;
+
+    /**
+     * Constructs a new bridge for the &lt;text> element.
+     * @param fi the font infomration
+     */
+    public PSTextElementBridge(FontInfo fi) {
+        //textPainter = new PSTextPainter(fi);
+    }
+
+    /**
+     * Create a text element bridge.
+     * This set the text painter on the node if the text is simple.
+     * @param ctx the bridge context
+     * @param e the svg element
+     * @return the text graphics node created by the super class
+     */
+    public GraphicsNode createGraphicsNode(BridgeContext ctx, Element e) {
+        GraphicsNode node = super.createGraphicsNode(ctx, e);
+        /*
+        if (node != null && isSimple(ctx, e, node)) {
+            ((TextNode)node).setTextPainter(getTextPainter());
+        }*/
+        return node;
+    }
+
+    /*
+    private PSTextPainter getTextPainter() {
+        return textPainter;
+    }
+    */
+
+    /**
+     * Check if text element contains simple text.
+     * This checks the children of the text element to determine
+     * if the text is simple. The text is simple if it can be rendered
+     * with basic text drawing algorithms. This means there are no
+     * alternate characters, the font is known and there are no effects
+     * applied to the text.
+     *
+     * @param ctx the bridge context
+     * @param element the svg text element
+     * @param node the graphics node
+     * @return true if this text is simple of false if it cannot be
+     *         easily rendered using normal drawString on the PDFGraphics2D
+     */
+    private boolean isSimple(BridgeContext ctx, Element element, GraphicsNode node) {
+        /*
+        // Font size, in user space units.
+        float fs = TextUtilities.convertFontSize(element).floatValue();
+        // PDF cannot display fonts over 36pt
+        if (fs > 36) {
+            return false;
+        }
+        */
+
+        
+        for (Node n = element.getFirstChild();
+                n != null;
+                n = n.getNextSibling()) {
+
+            switch (n.getNodeType()) {
+            case Node.ELEMENT_NODE:
+
+                if (n.getLocalName().equals(SVG_TSPAN_TAG)
+                    || n.getLocalName().equals(SVG_ALT_GLYPH_TAG)) {
+                    return false;
+                } else if (n.getLocalName().equals(SVG_TEXT_PATH_TAG)) {
+                    return false;
+                } else if (n.getLocalName().equals(SVG_TREF_TAG)) {
+                    return false;
+                }
+                break;
+            case Node.TEXT_NODE:
+            case Node.CDATA_SECTION_NODE:
+            }
+        }
+
+        /*if (CSSUtilities.convertFilter(element, node, ctx) != null) {
+            return false;
+        }*/
+
+        return true;
+    }
+}
+
index 6601a43bda6baf015b7797ac548e79c05d814365..d03e353badbadb399bf2b9c5f89b4af7f629c0f6 100644 (file)
@@ -9,22 +9,11 @@ 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;
@@ -35,6 +24,7 @@ import org.w3c.dom.svg.SVGDocument;
 import org.w3c.dom.svg.SVGSVGElement;
 
 import java.awt.geom.AffineTransform;
+import java.io.IOException;
 
 /**
  * PostScript XML handler.
@@ -46,73 +36,39 @@ import java.awt.geom.AffineTransform;
  * @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.
+     * The PostScript generator that is being used to drawn into.
      */
-    public static final String PDF_STREAM = "pdfStream";
+    public static final String PS_GENERATOR = "psGenerator";
 
     /**
-     * The width of the current pdf page.
+     * The font information for the PostScript renderer.
      */
-    public static final String PDF_WIDTH = "width";
+    public static final String PS_FONT_INFO = "psFontInfo";
 
     /**
-     * The height of the current pdf page.
+     * The width of the SVG graphic.
      */
-    public static final String PDF_HEIGHT = "height";
+    public static final String PS_WIDTH = "width";
 
     /**
-     * The current font information for the pdf renderer.
+     * The height of the SVG graphic.
      */
-    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";
+    public static final String PS_HEIGHT = "height";
 
     /**
      * The x position that this is being drawn at.
      */
-    public static final String PDF_XPOS = "xpos";
+    public static final String PS_XPOS = "xpos";
 
     /**
      * The y position that this is being drawn at.
      */
-    public static final String PDF_YPOS = "ypos";
+    public static final String PS_YPOS = "ypos";
 
     /**
-     * Create a new PDF XML handler for use by the PDF renderer.
+     * Create a new PostScript XML handler for use by the PostScript renderer.
      */
     public PSXMLHandler() {
     }
@@ -146,21 +102,12 @@ public class PSXMLHandler implements XMLHandler {
      */
     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();
-        */
+        psi.psGenerator = (PSGenerator)context.getProperty(PS_GENERATOR);
+        psi.fontInfo = (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();
         return psi;
     }
 
@@ -169,32 +116,114 @@ public class PSXMLHandler implements XMLHandler {
      */
     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;
+        /** see PS_GENERATOR */
+        private PSGenerator psGenerator;
+        /** see PS_FONT_INFO */
+        private FontInfo fontInfo;
+        /** see PS_PAGE_WIDTH */
+        private int width;
+        /** see PS_PAGE_HEIGHT */
+        private int height;
+        /** see PS_XPOS */
+        private int currentXPosition;
+        /** see PS_YPOS */
+        private int currentYPosition;
+        /**
+         * Returns the PSGenerator.
+         * @return PSGenerator
+         */
+        public PSGenerator getPSGenerator() {
+            return psGenerator;
+        }
+
+        /**
+         * Sets the PSGenerator.
+         * @param psGenerator The PSGenerator to set
+         */
+        public void setPsGenerator(PSGenerator psGenerator) {
+            this.psGenerator = psGenerator;
+        }
+
+        /**
+         * Returns the fontInfo.
+         * @return FontInfo
+         */
+        public FontInfo getFontInfo() {
+            return fontInfo;
+        }
+
+        /**
+         * Sets the fontInfo.
+         * @param fontInfo The fontInfo to set
+         */
+        public void setFontInfo(FontInfo fontInfo) {
+            this.fontInfo = fontInfo;
+        }
+
+        /**
+         * Returns the currentXPosition.
+         * @return int
+         */
+        public int getCurrentXPosition() {
+            return currentXPosition;
+        }
+
+        /**
+         * Sets the currentXPosition.
+         * @param currentXPosition The currentXPosition to set
+         */
+        public void setCurrentXPosition(int currentXPosition) {
+            this.currentXPosition = currentXPosition;
+        }
+
+        /**
+         * Returns the currentYPosition.
+         * @return int
+         */
+        public int getCurrentYPosition() {
+            return currentYPosition;
+        }
+
+        /**
+         * Sets the currentYPosition.
+         * @param currentYPosition The currentYPosition to set
+         */
+        public void setCurrentYPosition(int currentYPosition) {
+            this.currentYPosition = currentYPosition;
+        }
+
+        /**
+         * Returns the width.
+         * @return int
+         */
+        public int getWidth() {
+            return width;
+        }
+
+        /**
+         * Sets the width.
+         * @param width The pageWidth to set
+         */
+        public void setWidth(int width) {
+            this.width = width;
+        }
+
+        /**
+         * Returns the height.
+         * @return int
+         */
+        public int getHeight() {
+            return height;
+        }
+
+        /**
+         * Sets the height.
+         * @param height The height to set
+         */
+        public void setHeight(int height) {
+            this.height = height;
+        }
+
     }
 
     /**
@@ -206,32 +235,34 @@ public class PSXMLHandler implements XMLHandler {
          * Render the svg document.
          * @param context the renderer context
          * @param doc the svg document
-         * @param pdfInfo the pdf information of the current context
+         * @param psInfo the pdf information of the current context
          */
         protected void renderSVGDocument(RendererContext context, Document doc, PSInfo psInfo) {
             int xOffset = psInfo.currentXPosition;
             int yOffset = psInfo.currentYPosition;
+            PSGenerator gen = psInfo.psGenerator;
 
             SVGUserAgent ua
                  = new SVGUserAgent(context.getUserAgent(), new AffineTransform());
 
+
             GVTBuilder builder = new GVTBuilder();
             BridgeContext ctx = new BridgeContext(ua);
-            PDFTextElementBridge tBridge = new PDFTextElementBridge(psInfo.fi);
+            PSTextElementBridge tBridge = new PSTextElementBridge(psInfo.getFontInfo());
             ctx.putBridge(tBridge);
 
-            PDFAElementBridge aBridge = new PDFAElementBridge();
+            //PSAElementBridge aBridge = new PSAElementBridge();
             // to get the correct transform we need to use the PDFState
-            AffineTransform transform = psInfo.pdfState.getTransform();
+            AffineTransform transform = gen.getCurrentState().getTransform();
             transform.translate(xOffset / 1000f, yOffset / 1000f);
-            aBridge.setCurrentTransform(transform);
-            ctx.putBridge(aBridge);
+            //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: "
+                context.getUserAgent().getLogger().error("SVG graphic could not be built: "
                                        + e.getMessage(), e);
                 return;
             }
@@ -239,62 +270,61 @@ public class PSXMLHandler implements XMLHandler {
             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;
+            float sx = psInfo.getWidth() / (float)w;
+            float sy = psInfo.getHeight() / (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);
+                gen.writeln("%SVG graphic start ---");
+                /*
+                 * Clip to the svg area.
+                 * Note: To have the svg overlay (under) a text area then use
+                 * an fo:block-container
+                 */
+                gen.saveGraphicsState();
+                // 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, yOffset);
+                
+                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);
+                    gen.concatMatrix(vals);
+                }
+                
+                /*
+                if (psInfo.pdfContext == null) {
+                    psInfo.pdfContext = psInfo.pdfPage;
+                }*/
+                PSGraphics2D graphics = new PSGraphics2D(true, gen);
+                graphics.setGraphicContext(new org.apache.batik.ext.awt.g2d.GraphicContext());
+                //psInfo.pdfState.push();
+                transform = new AffineTransform();
+                // scale to viewbox
+                transform.translate(xOffset, yOffset);
+                gen.getCurrentState().concatMatrix(transform);
+                //graphics.setPDFState(psInfo.pdfState);
+                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.psGenerator.restoreGraphicsState();
+                //psInfo.pdfState.pop();
+                gen.writeln("%SVG graphic end ---");
+            } catch (IOException ioe) {
+                context.getUserAgent().getLogger().error("SVG graphic could not be rendered: "
+                                       + ioe.getMessage(), ioe);
             }
-
-            psInfo.currentStream.add("Q\n");
-            psInfo.pdfState.pop();
         }
     }
 }