]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Modified to support new FontState class.
authoreschaeffer <eschaeffer@unknown>
Thu, 25 Jan 2001 15:11:05 +0000 (15:11 +0000)
committereschaeffer <eschaeffer@unknown>
Thu, 25 Jan 2001 15:11:05 +0000 (15:11 +0000)
PR:
Obtained from:
Submitted by:
Reviewed by:

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

src/org/apache/fop/render/pdf/SVGRenderer.java
src/org/apache/fop/svg/SVG.java

index 2296ce7ca34d15d2c3f8a1f30341dcb935f852ad..7470513343ae57a78f7dd056e9916f50a63d7ca6 100644 (file)
@@ -1,7 +1,7 @@
 /*-- $Id$ --
 
  ============================================================================
-                                  The Apache Software License, Version 1.1
+                                        The Apache Software License, Version 1.1
  ============================================================================
 
        Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
@@ -88,2529 +88,2531 @@ import java.util.Hashtable;
  */
 public class SVGRenderer {
 
-    /** the PDF Document being created */
-    protected PDFDocument pdfDoc;
-
-    protected FontState fontState;
-
-    /** the /Resources object of the PDF document being created */
-    // protected PDFResources pdfResources;
-
-    /** the current stream to add PDF commands to */
-    StringWriter currentStream = new StringWriter();
-
-    /** the current (internal) font name */
-    protected String currentFontName;
-
-    /** the current font size in millipoints */
-    protected int currentFontSize;
-
-    /** the current vertical position in millipoints from bottom */
-    protected int currentYPosition = 0;
-
-    /** the current horizontal position in millipoints from left */
-    protected int currentXPosition = 0;
-
-    /** the current colour for use in svg */
-    private PDFColor currentColour = new PDFColor(0, 0, 0);
-
-    /**
-     * create the SVG renderer
-     */
-    public SVGRenderer(FontState fs, PDFDocument doc, String font,
-                       int size, int xpos, int ypos) {
-        pdfDoc = doc;
-        currentFontName = font;
-        currentFontSize = size;
-        currentYPosition = ypos;
-        currentXPosition = xpos;
-        fontState = fs;
-    }
-
-    public String getString() {
-        return currentStream.toString();
-    }
-
-    /**
-     * Renders an SVG element in an SVG document.
-     * This renders each of the child elements.
-     */
-    protected void renderSVG(SVGSVGElement svg, int x, int y) {
-        NodeList nl = svg.getChildNodes();
-        for (int count = 0; count < nl.getLength(); count++) {
-            Node n = nl.item(count);
-            if (n instanceof SVGElement) {
-                renderElement((SVGElement) n, x, y);
-            }
-        }
-    }
-
-    public void renderGArea(SVGGElement area, int posx, int posy) {
-        NodeList nl = area.getChildNodes();
-        for (int count = 0; count < nl.getLength(); count++) {
-            Node n = nl.item(count);
-            if (n instanceof SVGElement) {
-                renderElement((SVGElement) n, posx, posy);
-            }
-        }
-    }
-
-    /**
-     * Handles the SVG switch element.
-     * The switch determines which of its child elements should be rendered
-     * according to the required extensions, required features and system language.
-     */
-    protected void handleSwitchElement(int posx, int posy,
-                                       SVGSwitchElement ael) {
-        SVGStringList relist = ael.getRequiredExtensions();
-        SVGStringList rflist = ael.getRequiredFeatures();
-        SVGStringList sllist = ael.getSystemLanguage();
-        NodeList nl = ael.getChildNodes();
-        choices:
-        for (int count = 0; count < nl.getLength(); count++) {
-            org.w3c.dom.Node n = nl.item(count);
-            // only render the first child that has a valid
-            // test data
-            if (n instanceof GraphicElement) {
-                GraphicElement graphic = (GraphicElement) n;
-                SVGStringList grelist = graphic.getRequiredExtensions();
-                // if null it evaluates to true
-                if (grelist != null) {
-                    if (grelist.getNumberOfItems() == 0) {
-                        if ((relist != null) &&
-                                relist.getNumberOfItems() != 0) {
-                            continue choices;
-                        }
-                    }
-                    for (int i = 0; i < grelist.getNumberOfItems(); i++) {
-                        String str = (String) grelist.getItem(i);
-                        if (relist == null) {
-                            // use default extension set
-                            // currently no extensions are supported
-                            //                                                 if(!(str.equals("http:// ??"))) {
-                            continue choices;
-                            //                                                 }
-                        } else {
-                        }
-                    }
-                }
-                SVGStringList grflist = graphic.getRequiredFeatures();
-                if (grflist != null) {
-                    if (grflist.getNumberOfItems() == 0) {
-                        if ((rflist != null) &&
-                                rflist.getNumberOfItems() != 0) {
-                            continue choices;
-                        }
-                    }
-                    for (int i = 0; i < grflist.getNumberOfItems(); i++) {
-                        String str = (String) grflist.getItem(i);
-                        if (rflist == null) {
-                            // use default feature set
-                            if (!(str.equals("org.w3c.svg.static") ||
-                                    str.equals("org.w3c.dom.svg.all"))) {
-                                continue choices;
-                            }
-                        } else {
-                            boolean found = false;
-                            for (int j = 0;
-                                    j < rflist.getNumberOfItems(); j++) {
-                                if (rflist.getItem(j).equals(str)) {
-                                    found = true;
-                                    break;
-                                }
-                            }
-                            if (!found)
-                                continue choices;
-                        }
-                    }
-                }
-                SVGStringList gsllist = graphic.getSystemLanguage();
-                if (gsllist != null) {
-                    if (gsllist.getNumberOfItems() == 0) {
-                        if ((sllist != null) &&
-                                sllist.getNumberOfItems() != 0) {
-                            continue choices;
-                        }
-                    }
-                    for (int i = 0; i < gsllist.getNumberOfItems(); i++) {
-                        String str = (String) gsllist.getItem(i);
-                        if (sllist == null) {
-                            // use default feature set
-                            if (!(str.equals("en"))) {
-                                continue choices;
-                            }
-                        } else {
-                            boolean found = false;
-                            for (int j = 0;
-                                    j < sllist.getNumberOfItems(); j++) {
-                                if (sllist.getItem(j).equals(str)) {
-                                    found = true;
-                                    break;
-                                }
-                            }
-                            if (!found)
-                                continue choices;
-                        }
-                    }
-                }
-                renderElement((SVGElement) n, posx, posy);
-                // only render the first valid one
-                break;
-            }
-        }
-    }
-
-    /**
-     * add a line to the current stream
-     *
-     * @param x1 the start x location in millipoints
-     * @param y1 the start y location in millipoints
-     * @param x2 the end x location in millipoints
-     * @param y2 the end y location in millipoints
-     * @param th the thickness in millipoints
-     * @param r the red component
-     * @param g the green component
-     * @param b the blue component
-     */
-    protected void addLine(float x1, float y1, float x2, float y2,
-                           DrawingInstruction di) {
-        String str;
-        PDFNumber pdfNumber = new PDFNumber();
-        str = "" + pdfNumber.doubleOut(x1) + " " + pdfNumber.doubleOut(y1) + " m " + pdfNumber.doubleOut(x2) + " " + pdfNumber.doubleOut(y2) + " l";
-        if (di != null && di.fill)
-            currentStream.write(str + " f\n"); // ??
-        currentStream.write(str + " S\n");
-    }
-
-    /**
-     * Add an SVG circle
-     * Uses bezier curves to approximate the shape of a circle.
-     */
-    protected void addCircle(float cx, float cy, float r,
-                             DrawingInstruction di) {
-        PDFNumber pdfNumber = new PDFNumber();
-        String str;
-        str = "" + pdfNumber.doubleOut(cx) + " " + pdfNumber.doubleOut((cy - r)) + " m\n" + "" +
-              pdfNumber.doubleOut((cx + 21 * r / 40f)) + " " + pdfNumber.doubleOut((cy - r)) + " " +
-              pdfNumber.doubleOut((cx + r)) + " " + pdfNumber.doubleOut((cy - 21 * r / 40f)) + " " +
-              pdfNumber.doubleOut((cx + r)) + " " + pdfNumber.doubleOut(cy) + " c\n" + "" + pdfNumber.doubleOut((cx + r)) + " " +
-              pdfNumber.doubleOut((cy + 21 * r / 40f)) + " " + pdfNumber.doubleOut((cx + 21 * r / 40f)) +
-              " " + pdfNumber.doubleOut((cy + r)) + " " + pdfNumber.doubleOut(cx) + " " + pdfNumber.doubleOut((cy + r)) + " c\n" +
-              "" + pdfNumber.doubleOut((cx - 21 * r / 40f)) + " " + pdfNumber.doubleOut((cy + r)) + " " +
-              pdfNumber.doubleOut(cx - r) + " " + pdfNumber.doubleOut(cy + 21 * r / 40f) + " " +
-              pdfNumber.doubleOut(cx - r) + " " + pdfNumber.doubleOut(cy) + " c\n" + "" + pdfNumber.doubleOut(cx - r) + " " +
-              pdfNumber.doubleOut(cy - 21 * r / 40f) + " " + pdfNumber.doubleOut(cx - 21 * r / 40f) +
-              " " + pdfNumber.doubleOut(cy - r) + " " + pdfNumber.doubleOut(cx) + " " + pdfNumber.doubleOut(cy - r) + " c\n";
-
-        currentStream.write(str);
-        doDrawing(di);
-    }
-
-    /**
-     * Add an SVG ellips
-     * Uses bezier curves to approximate the shape of an ellipse.
-     */
-    protected void addEllipse(float cx, float cy, float rx, float ry,
-                              DrawingInstruction di) {
-        PDFNumber pdfNumber = new PDFNumber();
-        String str;
-        str = "" + pdfNumber.doubleOut(cx) + " " + pdfNumber.doubleOut(cy - ry) + " m\n" + "" +
-              pdfNumber.doubleOut(cx + 21 * rx / 40f) + " " + pdfNumber.doubleOut(cy - ry) + " " +
-              pdfNumber.doubleOut(cx + rx) + " " + pdfNumber.doubleOut(cy - 21 * ry / 40f) + " " +
-              pdfNumber.doubleOut(cx + rx) + " " + pdfNumber.doubleOut(cy) + " c\n" + "" + pdfNumber.doubleOut(cx + rx) + " " +
-              pdfNumber.doubleOut(cy + 21 * ry / 40f) + " " + pdfNumber.doubleOut(cx + 21 * rx / 40f) +
-              " " + pdfNumber.doubleOut(cy + ry) + " " + pdfNumber.doubleOut(cx) + " " + pdfNumber.doubleOut(cy + ry) +
-              " c\n" + "" + pdfNumber.doubleOut(cx - 21 * rx / 40f) + " " + pdfNumber.doubleOut(cy + ry) +
-              " " + pdfNumber.doubleOut(cx - rx) + " " + pdfNumber.doubleOut(cy + 21 * ry / 40f) + " " +
-              pdfNumber.doubleOut(cx - rx) + " " + pdfNumber.doubleOut(cy) + " c\n" + "" + pdfNumber.doubleOut(cx - rx) + " " +
-              pdfNumber.doubleOut(cy - 21 * ry / 40f) + " " + pdfNumber.doubleOut(cx - 21 * rx / 40f) +
-              " " + pdfNumber.doubleOut(cy - ry) + " " + pdfNumber.doubleOut(cx) + " " + pdfNumber.doubleOut(cy - ry) + " c\n";
-        currentStream.write(str);
-        doDrawing(di);
-    }
-
-    /**
-     * add an SVG rectangle to the current stream.
-     * If there are curved edges then these are rendered using bezier curves.
-     *
-     * @param x the x position of left edge
-     * @param y the y position of top edge
-     * @param w the width
-     * @param h the height
-     * @param rx the x radius curved edge
-     * @param ry the y radius curved edge
-     */
-    protected void addRect(float x, float y, float w, float h,
-                           float rx, float ry, DrawingInstruction di) {
-        PDFNumber pdfNumber = new PDFNumber();
-        String str = "";
-        if (rx == 0.0 && ry == 0.0) {
-            str = "" + pdfNumber.doubleOut(x) + " " + pdfNumber.doubleOut(y) + " " + pdfNumber.doubleOut(w) + " " + pdfNumber.doubleOut(h) + " re\n";
-        } else {
-            if (ry == 0.0)
-                ry = rx;
-            if (rx > w / 2.0f)
-                rx = w / 2.0f;
-            if (ry > h / 2.0f)
-                ry = h / 2.0f;
-            str = "" + pdfNumber.doubleOut(x + rx) + " " + pdfNumber.doubleOut(y) + " m\n";
-            str += "" + pdfNumber.doubleOut(x + w - rx) + " " + pdfNumber.doubleOut(y) + " l\n";
-            str += "" + pdfNumber.doubleOut(x + w - 19 * rx / 40) + " " + pdfNumber.doubleOut(y) + " " +
-                   pdfNumber.doubleOut(x + w) + " " + pdfNumber.doubleOut(y + 19 * ry / 40) + " " +
-                   pdfNumber.doubleOut(x + w) + " " + pdfNumber.doubleOut(y + ry) + " c\n";
-            str += "" + pdfNumber.doubleOut(x + w) + " " + pdfNumber.doubleOut(y + h - ry) + " l\n";
-            str += "" + pdfNumber.doubleOut(x + w) + " " + pdfNumber.doubleOut(y + h - 19 * ry / 40) + " " +
-                   pdfNumber.doubleOut(x + w - 19 * rx / 40) + " " + pdfNumber.doubleOut(y + h) + " " +
-                   pdfNumber.doubleOut(x + w - rx) + " " + pdfNumber.doubleOut(y + h) + " c\n";
-            str += "" + pdfNumber.doubleOut(x + rx) + " " + pdfNumber.doubleOut(y + h) + " l\n";
-            str += "" + pdfNumber.doubleOut(x + 19 * rx / 40) + " " + pdfNumber.doubleOut(y + h) + " " + pdfNumber.doubleOut(x) +
-                   " " + pdfNumber.doubleOut(y + h - 19 * ry / 40) + " " + pdfNumber.doubleOut(x) + " " +
-                   pdfNumber.doubleOut(y + h - ry) + " c\n";
-            str += "" + pdfNumber.doubleOut(x) + " " + pdfNumber.doubleOut(y + ry) + " l\n";
-            str += "" + pdfNumber.doubleOut(x) + " " + pdfNumber.doubleOut(y + 19 * ry / 40) + " " +
-                   pdfNumber.doubleOut(x + 19 * rx / 40) + " " + pdfNumber.doubleOut(y) + " " + pdfNumber.doubleOut(x + rx) +
-                   " " + pdfNumber.doubleOut(y) + " c\n";
-        }
-        currentStream.write(str);
-        doDrawing(di);
-    }
-
-    /**
-     * Adds an SVG path to the current streem.
-     * An SVG path is made up of a list of drawing instructions that are rendered
-     * out in order.
-     * Arcs don't work.
-     */
-    protected void addPath(Vector points, int posx, int posy,
-                           DrawingInstruction di) {
-        PDFNumber pdfNumber = new PDFNumber();
-        SVGPathSegImpl pathmoveto = null;
-        float lastx = 0;
-        float lasty = 0;
-        float lastmovex = 0;
-        float lastmovey = 0;
-        float[] cxs;
-        float tempx;
-        float tempy;
-        float lastcx = 0;
-        float lastcy = 0;
-        for (Enumeration e = points.elements(); e.hasMoreElements();) {
-            SVGPathSegImpl pc = (SVGPathSegImpl) e.nextElement();
-            float[] vals = pc.getValues();
-            switch (pc.getPathSegType()) {
-                case SVGPathSeg.PATHSEG_MOVETO_ABS:
-                    pathmoveto = pc;
-                    lastx = vals[0];
-                    lasty = vals[1];
-                    currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " m\n");
-                    lastcx = 0;
-                    lastcy = 0;
-                    lastmovex = lastx;
-                    lastmovey = lasty;
-                    break;
-                case SVGPathSeg.PATHSEG_MOVETO_REL:
-                    // the test cases seem to interprete this command differently
-                    // it seems if there is an 'm' then the current path is closed
-                    // then the point is move to a place relative to the point
-                    // after doing the close
-                    if (pathmoveto == null) {
-                        lastx += vals[0];
-                        lasty += vals[1];
-                        pathmoveto = pc;
-                        currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " m\n");
-                    } else {
-                        lastx += vals[0];
-                        lasty += vals[1];
-                        pathmoveto = pc;
-                        currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " l\n");
-                    }
-                    lastmovex = lastx;
-                    lastmovey = lasty;
-                    lastcx = 0;
-                    lastcy = 0;
-                    break;
-                case SVGPathSeg.PATHSEG_LINETO_ABS:
-                    lastx = vals[0];
-                    lasty = vals[1];
-                    currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " l\n");
-                    lastcx = 0;
-                    lastcy = 0;
-                    break;
-                case SVGPathSeg.PATHSEG_LINETO_REL:
-                    lastx += vals[0];
-                    lasty += vals[1];
-                    currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " l\n");
-                    lastcx = 0;
-                    lastcy = 0;
-                    break;
-                case SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:
-                    lasty = vals[0];
-                    currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " l\n");
-                    lastcx = 0;
-                    lastcy = 0;
-                    break;
-                case SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:
-                    lasty += vals[0];
-                    currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " l\n");
-                    lastcx = 0;
-                    lastcy = 0;
-                    break;
-                case SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:
-                    lastx = vals[0];
-                    currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " l\n");
-                    lastcx = 0;
-                    lastcy = 0;
-                    break;
-                case SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:
-                    lastx += vals[0];
-                    currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " l\n");
-                    lastcx = 0;
-                    lastcy = 0;
-                    break;
-                case SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:
-                    lastx = vals[4];
-                    lasty = vals[5];
-                    lastcx = vals[2];
-                    lastcy = vals[3];
-                    currentStream.write(pdfNumber.doubleOut(vals[0]) + " " + pdfNumber.doubleOut(vals[1]) +
-                                        " " + pdfNumber.doubleOut(vals[2]) + " " + pdfNumber.doubleOut(vals[3]) + " " +
-                                        pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " c\n");
-                    break;
-                case SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:
-                    currentStream.write(pdfNumber.doubleOut(vals[0] + lastx) + " " +
-                                        pdfNumber.doubleOut(vals[1] + lasty) + " " +
-                                        pdfNumber.doubleOut(vals[2] + lastx) + " " +
-                                        pdfNumber.doubleOut(vals[3] + lasty) + " " +
-                                        pdfNumber.doubleOut(vals[4] + lastx) + " " +
-                                        pdfNumber.doubleOut(vals[5] + lasty) + " c\n");
-                    lastcx = vals[2] + lastx;
-                    lastcy = vals[3] + lasty;
-                    lastx += vals[4];
-                    lasty += vals[5];
-                    break;
-                case SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
-                    if (lastcx == 0) {
-                        lastcx = lastx;
-                    }
-                    if (lastcy == 0) {
-                        lastcy = lasty;
-                    }
-                    lastcx = lastx + (lastx - lastcx);
-                    lastcy = lasty + (lasty - lastcy);
-                    lastx = vals[2];
-                    lasty = vals[3];
-                    currentStream.write(pdfNumber.doubleOut(lastcx) + " " + pdfNumber.doubleOut(lastcy) + " " +
-                                        pdfNumber.doubleOut(vals[0]) + " " + pdfNumber.doubleOut(vals[1]) + " " +
-                                        pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " c\n");
-                    lastcx = vals[0];
-                    lastcy = vals[1];
-                    break;
-                case SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
-                    if (lastcx == 0) {
-                        lastcx = lastx;
-                    }
-                    if (lastcy == 0) {
-                        lastcy = lasty;
-                    }
-                    lastcx = lastx + (lastx - lastcx);
-                    lastcy = lasty + (lasty - lastcy);
-                    currentStream.write(pdfNumber.doubleOut(lastcx) + " " + pdfNumber.doubleOut(lastcy) + " " +
-                                        pdfNumber.doubleOut(vals[0] + lastx) + " " +
-                                        pdfNumber.doubleOut(vals[1] + lasty) + " " +
-                                        pdfNumber.doubleOut(vals[2] + lastx) + " " +
-                                        pdfNumber.doubleOut(vals[3] + lasty) + " c\n");
-                    lastcx = (vals[0] + lastx);
-                    lastcy = (vals[1] + lasty);
-                    lastx += vals[2];
-                    lasty += vals[3];
-                    break;
-                case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:
-                    if (lastcx == 0) {
-                        lastcx = lastx;
-                    }
-                    if (lastcy == 0) {
-                        lastcy = lasty;
-                    }
-                    tempx = lastx;
-                    tempy = lasty;
-                    lastx = vals[2];
-                    lasty = vals[3];
-                    currentStream.write(pdfNumber.doubleOut(vals[0]) + " " + pdfNumber.doubleOut(vals[1]) + " " +
-                                        pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " y\n");
-                    cxs = calculateLastControl(tempx, tempy, lastx, lasty, -tempx + vals[0], -tempy + vals[1]);
-                    lastcx = cxs[0];
-                    lastcy = cxs[1];
-                    break;
-                case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:
-                    if (lastcx == 0) {
-                        lastcx = lastx;
-                    }
-                    if (lastcy == 0) {
-                        lastcy = lasty;
-                    }
-                    currentStream.write(pdfNumber.doubleOut(vals[0] + lastx) + " " + pdfNumber.doubleOut(vals[1] + lasty) + " " +
-                                        pdfNumber.doubleOut(vals[2] + lastx) + " " +
-                                        pdfNumber.doubleOut(vals[3] + lasty) + " y\n");
-                    cxs = calculateLastControl(lastx, lasty, lastx + vals[2], lasty + vals[3], vals[0], vals[1]);
-                    lastcx = cxs[0];
-                    lastcy = cxs[1];
-                    lastx += vals[2];
-                    lasty += vals[3];
-                    break;
-                case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
-                    if (lastcx == 0) {
-                        lastcx = lastx;
-                    }
-                    if (lastcy == 0) {
-                        lastcy = lasty;
-                    }
-                    tempx = lastx;
-                    tempy = lasty;
-                    lastcx = lastx + (lastx - lastcx);
-                    lastcy = lasty + (lasty - lastcy);
-                    lastx = vals[0];
-                    lasty = vals[1];
-                    currentStream.write(pdfNumber.doubleOut(lastcx) + " " + pdfNumber.doubleOut(lastcy) + " " +
-                                        pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " y\n");
-                    cxs = calculateLastControl(tempx, tempy, lastx, lasty, -tempx + lastcx, -tempy + lastcy);
-                    lastcx = cxs[0];
-                    lastcy = cxs[1];
-                    break;
-                case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
-                    if (lastcx == 0) {
-                        lastcx = lastx;
-                    }
-                    if (lastcy == 0) {
-                        lastcy = lasty;
-                    }
-                    lastcx = lastx + (lastx - lastcx);
-                    lastcy = lasty + (lasty - lastcy);
-                    currentStream.write(pdfNumber.doubleOut(lastcx) + " " + pdfNumber.doubleOut(lastcy) + " " +
-                                        pdfNumber.doubleOut(vals[0] + lastx) + " " +
-                                        pdfNumber.doubleOut(vals[1] + lasty) + " y\n");
-                    cxs = calculateLastControl(lastx, lasty, lastx + vals[0], lasty + vals[1], -lastx + lastcx, -lasty + lastcy);
-                    lastcx = cxs[0];
-                    lastcy = cxs[1];
-                    lastx += vals[0];
-                    lasty += vals[1];
-                    break;
-                    // get angle between the two points
-                    // then get angle of points to centre (ie. both points are on the
-                    // apogee and perigee of the ellipse)
-                    // then work out the direction from flags
-                case SVGPathSeg.PATHSEG_ARC_ABS:
-                    {
+               /** the PDF Document being created */
+               protected PDFDocument pdfDoc;
+
+               protected FontState fontState;
+
+               /** the /Resources object of the PDF document being created */
+               //      protected PDFResources pdfResources;
+
+               /** the current stream to add PDF commands to */
+               StringWriter currentStream = new StringWriter();
+
+               /** the current (internal) font name */
+               protected String currentFontName;
+
+               /** the current font size in millipoints */
+               protected int currentFontSize;
+
+               /** the current vertical position in millipoints from bottom */
+               protected int currentYPosition = 0;
+
+               /** the current horizontal position in millipoints from left */
+               protected int currentXPosition = 0;
+
+               /** the current colour for use in svg */
+               private PDFColor currentColour = new PDFColor(0, 0, 0);
+
+               /**
+                * create the SVG renderer
+                */
+               public SVGRenderer(FontState fs, PDFDocument doc, String font,
+                                                                                        int size, int xpos, int ypos) {
+                               pdfDoc = doc;
+                               currentFontName = font;
+                               currentFontSize = size;
+                               currentYPosition = ypos;
+                               currentXPosition = xpos;
+                               fontState = fs;
+               }
+
+               public String getString() {
+                               return currentStream.toString();
+               }
+
+               /**
+                * Renders an SVG element in an SVG document.
+                * This renders each of the child elements.
+                */
+               protected void renderSVG(SVGSVGElement svg, int x, int y) {
+                               NodeList nl = svg.getChildNodes();
+                               for (int count = 0; count < nl.getLength(); count++) {
+                                               Node n = nl.item(count);
+                                               if (n instanceof SVGElement) {
+                                                               renderElement((SVGElement) n, x, y);
+                                               }
+                               }
+               }
+
+               public void renderGArea(SVGGElement area, int posx, int posy) {
+                               NodeList nl = area.getChildNodes();
+                               for (int count = 0; count < nl.getLength(); count++) {
+                                               Node n = nl.item(count);
+                                               if (n instanceof SVGElement) {
+                                                               renderElement((SVGElement) n, posx, posy);
+                                               }
+                               }
+               }
+
+               /**
+                * Handles the SVG switch element.
+                * The switch determines which of its child elements should be rendered
+                * according to the required extensions, required features and system language.
+                */
+               protected void handleSwitchElement(int posx, int posy,
+                                                                                                                                                        SVGSwitchElement ael) {
+                               SVGStringList relist = ael.getRequiredExtensions();
+                               SVGStringList rflist = ael.getRequiredFeatures();
+                               SVGStringList sllist = ael.getSystemLanguage();
+                               NodeList nl = ael.getChildNodes();
+                               choices:
+                               for (int count = 0; count < nl.getLength(); count++) {
+                                               org.w3c.dom.Node n = nl.item(count);
+                                               // only render the first child that has a valid
+                                               // test data
+                                               if (n instanceof GraphicElement) {
+                                                               GraphicElement graphic = (GraphicElement) n;
+                                                               SVGStringList grelist = graphic.getRequiredExtensions();
+                                                               // if null it evaluates to true
+                                                               if (grelist != null) {
+                                                                               if (grelist.getNumberOfItems() == 0) {
+                                                                                               if ((relist != null) &&
+                                                                                                                               relist.getNumberOfItems() != 0) {
+                                                                                                               continue choices;
+                                                                                               }
+                                                                               }
+                                                                               for (int i = 0; i < grelist.getNumberOfItems(); i++) {
+                                                                                               String str = (String) grelist.getItem(i);
+                                                                                               if (relist == null) {
+                                                                                                               // use default extension set
+                                                                                                               // currently no extensions are supported
+                                                                                                               //                                                      if(!(str.equals("http:// ??"))) {
+                                                                                                               continue choices;
+                                                                                                               //                                                      }
+                                                                                               } else {
+                                                                                               }
+                                                                               }
+                                                               }
+                                                               SVGStringList grflist = graphic.getRequiredFeatures();
+                                                               if (grflist != null) {
+                                                                               if (grflist.getNumberOfItems() == 0) {
+                                                                                               if ((rflist != null) &&
+                                                                                                                               rflist.getNumberOfItems() != 0) {
+                                                                                                               continue choices;
+                                                                                               }
+                                                                               }
+                                                                               for (int i = 0; i < grflist.getNumberOfItems(); i++) {
+                                                                                               String str = (String) grflist.getItem(i);
+                                                                                               if (rflist == null) {
+                                                                                                               // use default feature set
+                                                                                                               if (!(str.equals("org.w3c.svg.static") ||
+                                                                                                                                               str.equals("org.w3c.dom.svg.all"))) {
+                                                                                                                               continue choices;
+                                                                                                               }
+                                                                                               } else {
+                                                                                                               boolean found = false;
+                                                                                                               for (int j = 0;
+                                                                                                                                               j < rflist.getNumberOfItems(); j++) {
+                                                                                                                               if (rflist.getItem(j).equals(str)) {
+                                                                                                                                               found = true;
+                                                                                                                                               break;
+                                                                                                                               }
+                                                                                                               }
+                                                                                                               if (!found)
+                                                                                                                               continue choices;
+                                                                                               }
+                                                                               }
+                                                               }
+                                                               SVGStringList gsllist = graphic.getSystemLanguage();
+                                                               if (gsllist != null) {
+                                                                               if (gsllist.getNumberOfItems() == 0) {
+                                                                                               if ((sllist != null) &&
+                                                                                                                               sllist.getNumberOfItems() != 0) {
+                                                                                                               continue choices;
+                                                                                               }
+                                                                               }
+                                                                               for (int i = 0; i < gsllist.getNumberOfItems(); i++) {
+                                                                                               String str = (String) gsllist.getItem(i);
+                                                                                               if (sllist == null) {
+                                                                                                               // use default feature set
+                                                                                                               if (!(str.equals("en"))) {
+                                                                                                                               continue choices;
+                                                                                                               }
+                                                                                               } else {
+                                                                                                               boolean found = false;
+                                                                                                               for (int j = 0;
+                                                                                                                                               j < sllist.getNumberOfItems(); j++) {
+                                                                                                                               if (sllist.getItem(j).equals(str)) {
+                                                                                                                                               found = true;
+                                                                                                                                               break;
+                                                                                                                               }
+                                                                                                               }
+                                                                                                               if (!found)
+                                                                                                                               continue choices;
+                                                                                               }
+                                                                               }
+                                                               }
+                                                               renderElement((SVGElement) n, posx, posy);
+                                                               // only render the first valid one
+                                                               break;
+                                               }
+                               }
+               }
+
+               /**
+                * add a line to the current stream
+                *
+                * @param x1 the start x location in millipoints
+                * @param y1 the start y location in millipoints
+                * @param x2 the end x location in millipoints
+                * @param y2 the end y location in millipoints
+                * @param th the thickness in millipoints
+                * @param r the red component
+                * @param g the green component
+                * @param b the blue component
+                */
+               protected void addLine(float x1, float y1, float x2, float y2,
+                                                                                                        DrawingInstruction di) {
+                               String str;
+                               PDFNumber pdfNumber = new PDFNumber();
+                               str = "" + pdfNumber.doubleOut(x1) + " " + pdfNumber.doubleOut(y1) + " m " + pdfNumber.doubleOut(x2) + " " + pdfNumber.doubleOut(y2) + " l";
+                               if (di != null && di.fill)
+                                               currentStream.write(str + " f\n"); // ??
+                               currentStream.write(str + " S\n");
+               }
+
+               /**
+                * Add an SVG circle
+                * Uses bezier curves to approximate the shape of a circle.
+                */
+               protected void addCircle(float cx, float cy, float r,
+                                                                                                                DrawingInstruction di) {
+                               PDFNumber pdfNumber = new PDFNumber();
+                               String str;
+                               str = "" + pdfNumber.doubleOut(cx) + " " + pdfNumber.doubleOut((cy - r)) + " m\n" + "" +
+                                                       pdfNumber.doubleOut((cx + 21 * r / 40f)) + " " + pdfNumber.doubleOut((cy - r)) + " " +
+                                                       pdfNumber.doubleOut((cx + r)) + " " + pdfNumber.doubleOut((cy - 21 * r / 40f)) + " " +
+                                                       pdfNumber.doubleOut((cx + r)) + " " + pdfNumber.doubleOut(cy) + " c\n" + "" + pdfNumber.doubleOut((cx + r)) + " " +
+                                                       pdfNumber.doubleOut((cy + 21 * r / 40f)) + " " + pdfNumber.doubleOut((cx + 21 * r / 40f)) +
+                                                       " " + pdfNumber.doubleOut((cy + r)) + " " + pdfNumber.doubleOut(cx) + " " + pdfNumber.doubleOut((cy + r)) + " c\n" +
+                                                       "" + pdfNumber.doubleOut((cx - 21 * r / 40f)) + " " + pdfNumber.doubleOut((cy + r)) + " " +
+                                                       pdfNumber.doubleOut(cx - r) + " " + pdfNumber.doubleOut(cy + 21 * r / 40f) + " " +
+                                                       pdfNumber.doubleOut(cx - r) + " " + pdfNumber.doubleOut(cy) + " c\n" + "" + pdfNumber.doubleOut(cx - r) + " " +
+                                                       pdfNumber.doubleOut(cy - 21 * r / 40f) + " " + pdfNumber.doubleOut(cx - 21 * r / 40f) +
+                                                       " " + pdfNumber.doubleOut(cy - r) + " " + pdfNumber.doubleOut(cx) + " " + pdfNumber.doubleOut(cy - r) + " c\n";
+
+                               currentStream.write(str);
+                               doDrawing(di);
+               }
+
+               /**
+                * Add an SVG ellips
+                * Uses bezier curves to approximate the shape of an ellipse.
+                */
+               protected void addEllipse(float cx, float cy, float rx, float ry,
+                                                                                                                       DrawingInstruction di) {
+                               PDFNumber pdfNumber = new PDFNumber();
+                               String str;
+                               str = "" + pdfNumber.doubleOut(cx) + " " + pdfNumber.doubleOut(cy - ry) + " m\n" + "" +
+                                                       pdfNumber.doubleOut(cx + 21 * rx / 40f) + " " + pdfNumber.doubleOut(cy - ry) + " " +
+                                                       pdfNumber.doubleOut(cx + rx) + " " + pdfNumber.doubleOut(cy - 21 * ry / 40f) + " " +
+                                                       pdfNumber.doubleOut(cx + rx) + " " + pdfNumber.doubleOut(cy) + " c\n" + "" + pdfNumber.doubleOut(cx + rx) + " " +
+                                                       pdfNumber.doubleOut(cy + 21 * ry / 40f) + " " + pdfNumber.doubleOut(cx + 21 * rx / 40f) +
+                                                       " " + pdfNumber.doubleOut(cy + ry) + " " + pdfNumber.doubleOut(cx) + " " + pdfNumber.doubleOut(cy + ry) +
+                                                       " c\n" + "" + pdfNumber.doubleOut(cx - 21 * rx / 40f) + " " + pdfNumber.doubleOut(cy + ry) +
+                                                       " " + pdfNumber.doubleOut(cx - rx) + " " + pdfNumber.doubleOut(cy + 21 * ry / 40f) + " " +
+                                                       pdfNumber.doubleOut(cx - rx) + " " + pdfNumber.doubleOut(cy) + " c\n" + "" + pdfNumber.doubleOut(cx - rx) + " " +
+                                                       pdfNumber.doubleOut(cy - 21 * ry / 40f) + " " + pdfNumber.doubleOut(cx - 21 * rx / 40f) +
+                                                       " " + pdfNumber.doubleOut(cy - ry) + " " + pdfNumber.doubleOut(cx) + " " + pdfNumber.doubleOut(cy - ry) + " c\n";
+                               currentStream.write(str);
+                               doDrawing(di);
+               }
+
+               /**
+                * add an SVG rectangle to the current stream.
+                * If there are curved edges then these are rendered using bezier curves.
+                *
+                * @param x the x position of left edge
+                * @param y the y position of top edge
+                * @param w the width
+                * @param h the height
+                * @param rx the x radius curved edge
+                * @param ry the y radius curved edge
+                */
+               protected void addRect(float x, float y, float w, float h,
+                                                                                                        float rx, float ry, DrawingInstruction di) {
+                               PDFNumber pdfNumber = new PDFNumber();
+                               String str = "";
+                               if (rx == 0.0 && ry == 0.0) {
+                                               str = "" + pdfNumber.doubleOut(x) + " " + pdfNumber.doubleOut(y) + " " + pdfNumber.doubleOut(w) + " " + pdfNumber.doubleOut(h) + " re\n";
+                               } else {
+                                               if (ry == 0.0)
+                                                               ry = rx;
+                                               if (rx > w / 2.0f)
+                                                               rx = w / 2.0f;
+                                               if (ry > h / 2.0f)
+                                                               ry = h / 2.0f;
+                                               str = "" + pdfNumber.doubleOut(x + rx) + " " + pdfNumber.doubleOut(y) + " m\n";
+                                               str += "" + pdfNumber.doubleOut(x + w - rx) + " " + pdfNumber.doubleOut(y) + " l\n";
+                                               str += "" + pdfNumber.doubleOut(x + w - 19 * rx / 40) + " " + pdfNumber.doubleOut(y) + " " +
+                                                                        pdfNumber.doubleOut(x + w) + " " + pdfNumber.doubleOut(y + 19 * ry / 40) + " " +
+                                                                        pdfNumber.doubleOut(x + w) + " " + pdfNumber.doubleOut(y + ry) + " c\n";
+                                               str += "" + pdfNumber.doubleOut(x + w) + " " + pdfNumber.doubleOut(y + h - ry) + " l\n";
+                                               str += "" + pdfNumber.doubleOut(x + w) + " " + pdfNumber.doubleOut(y + h - 19 * ry / 40) + " " +
+                                                                        pdfNumber.doubleOut(x + w - 19 * rx / 40) + " " + pdfNumber.doubleOut(y + h) + " " +
+                                                                        pdfNumber.doubleOut(x + w - rx) + " " + pdfNumber.doubleOut(y + h) + " c\n";
+                                               str += "" + pdfNumber.doubleOut(x + rx) + " " + pdfNumber.doubleOut(y + h) + " l\n";
+                                               str += "" + pdfNumber.doubleOut(x + 19 * rx / 40) + " " + pdfNumber.doubleOut(y + h) + " " + pdfNumber.doubleOut(x) +
+                                                                        " " + pdfNumber.doubleOut(y + h - 19 * ry / 40) + " " + pdfNumber.doubleOut(x) + " " +
+                                                                        pdfNumber.doubleOut(y + h - ry) + " c\n";
+                                               str += "" + pdfNumber.doubleOut(x) + " " + pdfNumber.doubleOut(y + ry) + " l\n";
+                                               str += "" + pdfNumber.doubleOut(x) + " " + pdfNumber.doubleOut(y + 19 * ry / 40) + " " +
+                                                                        pdfNumber.doubleOut(x + 19 * rx / 40) + " " + pdfNumber.doubleOut(y) + " " + pdfNumber.doubleOut(x + rx) +
+                                                                        " " + pdfNumber.doubleOut(y) + " c\n";
+                               }
+                               currentStream.write(str);
+                               doDrawing(di);
+               }
+
+               /**
+                * Adds an SVG path to the current streem.
+                * An SVG path is made up of a list of drawing instructions that are rendered
+                * out in order.
+                * Arcs don't work.
+                */
+               protected void addPath(Vector points, int posx, int posy,
+                                                                                                        DrawingInstruction di) {
+                               PDFNumber pdfNumber = new PDFNumber();
+                               SVGPathSegImpl pathmoveto = null;
+                               float lastx = 0;
+                               float lasty = 0;
+                               float lastmovex = 0;
+                               float lastmovey = 0;
+                               float[] cxs;
+                               float tempx;
+                               float tempy;
+                               float lastcx = 0;
+                               float lastcy = 0;
+                               for (Enumeration e = points.elements(); e.hasMoreElements();) {
+                                               SVGPathSegImpl pc = (SVGPathSegImpl) e.nextElement();
+                                               float[] vals = pc.getValues();
+                                               switch (pc.getPathSegType()) {
+                                                               case SVGPathSeg.PATHSEG_MOVETO_ABS:
+                                                                               pathmoveto = pc;
+                                                                               lastx = vals[0];
+                                                                               lasty = vals[1];
+                                                                               currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " m\n");
+                                                                               lastcx = 0;
+                                                                               lastcy = 0;
+                                                                               lastmovex = lastx;
+                                                                               lastmovey = lasty;
+                                                                               break;
+                                                               case SVGPathSeg.PATHSEG_MOVETO_REL:
+                                                                               // the test cases seem to interprete this command differently
+                                                                               // it seems if there is an 'm' then the current path is closed
+                                                                               // then the point is move to a place relative to the point
+                                                                               // after doing the close
+                                                                               if (pathmoveto == null) {
+                                                                                               lastx += vals[0];
+                                                                                               lasty += vals[1];
+                                                                                               pathmoveto = pc;
+                                                                                               currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " m\n");
+                                                                               } else {
+                                                                                               lastx += vals[0];
+                                                                                               lasty += vals[1];
+                                                                                               pathmoveto = pc;
+                                                                                               currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " l\n");
+                                                                               }
+                                                                               lastmovex = lastx;
+                                                                               lastmovey = lasty;
+                                                                               lastcx = 0;
+                                                                               lastcy = 0;
+                                                                               break;
+                                                               case SVGPathSeg.PATHSEG_LINETO_ABS:
+                                                                               lastx = vals[0];
+                                                                               lasty = vals[1];
+                                                                               currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " l\n");
+                                                                               lastcx = 0;
+                                                                               lastcy = 0;
+                                                                               break;
+                                                               case SVGPathSeg.PATHSEG_LINETO_REL:
+                                                                               lastx += vals[0];
+                                                                               lasty += vals[1];
+                                                                               currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " l\n");
+                                                                               lastcx = 0;
+                                                                               lastcy = 0;
+                                                                               break;
+                                                               case SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:
+                                                                               lasty = vals[0];
+                                                                               currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " l\n");
+                                                                               lastcx = 0;
+                                                                               lastcy = 0;
+                                                                               break;
+                                                               case SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:
+                                                                               lasty += vals[0];
+                                                                               currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " l\n");
+                                                                               lastcx = 0;
+                                                                               lastcy = 0;
+                                                                               break;
+                                                               case SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:
+                                                                               lastx = vals[0];
+                                                                               currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " l\n");
+                                                                               lastcx = 0;
+                                                                               lastcy = 0;
+                                                                               break;
+                                                               case SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:
+                                                                               lastx += vals[0];
+                                                                               currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " l\n");
+                                                                               lastcx = 0;
+                                                                               lastcy = 0;
+                                                                               break;
+                                                               case SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:
+                                                                               lastx = vals[4];
+                                                                               lasty = vals[5];
+                                                                               lastcx = vals[2];
+                                                                               lastcy = vals[3];
+                                                                               currentStream.write(pdfNumber.doubleOut(vals[0]) + " " + pdfNumber.doubleOut(vals[1]) +
+                                                                                                                                                               " " + pdfNumber.doubleOut(vals[2]) + " " + pdfNumber.doubleOut(vals[3]) + " " +
+                                                                                                                                                               pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " c\n");
+                                                                               break;
+                                                               case SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:
+                                                                               currentStream.write(pdfNumber.doubleOut(vals[0] + lastx) + " " +
+                                                                                                                                                               pdfNumber.doubleOut(vals[1] + lasty) + " " +
+                                                                                                                                                               pdfNumber.doubleOut(vals[2] + lastx) + " " +
+                                                                                                                                                               pdfNumber.doubleOut(vals[3] + lasty) + " " +
+                                                                                                                                                               pdfNumber.doubleOut(vals[4] + lastx) + " " +
+                                                                                                                                                               pdfNumber.doubleOut(vals[5] + lasty) + " c\n");
+                                                                               lastcx = vals[2] + lastx;
+                                                                               lastcy = vals[3] + lasty;
+                                                                               lastx += vals[4];
+                                                                               lasty += vals[5];
+                                                                               break;
+                                                               case SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
+                                                                               if (lastcx == 0) {
+                                                                                               lastcx = lastx;
+                                                                               }
+                                                                               if (lastcy == 0) {
+                                                                                               lastcy = lasty;
+                                                                               }
+                                                                               lastcx = lastx + (lastx - lastcx);
+                                                                               lastcy = lasty + (lasty - lastcy);
+                                                                               lastx = vals[2];
+                                                                               lasty = vals[3];
+                                                                               currentStream.write(pdfNumber.doubleOut(lastcx) + " " + pdfNumber.doubleOut(lastcy) + " " +
+                                                                                                                                                               pdfNumber.doubleOut(vals[0]) + " " + pdfNumber.doubleOut(vals[1]) + " " +
+                                                                                                                                                               pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " c\n");
+                                                                               lastcx = vals[0];
+                                                                               lastcy = vals[1];
+                                                                               break;
+                                                               case SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
+                                                                               if (lastcx == 0) {
+                                                                                               lastcx = lastx;
+                                                                               }
+                                                                               if (lastcy == 0) {
+                                                                                               lastcy = lasty;
+                                                                               }
+                                                                               lastcx = lastx + (lastx - lastcx);
+                                                                               lastcy = lasty + (lasty - lastcy);
+                                                                               currentStream.write(pdfNumber.doubleOut(lastcx) + " " + pdfNumber.doubleOut(lastcy) + " " +
+                                                                                                                                                               pdfNumber.doubleOut(vals[0] + lastx) + " " +
+                                                                                                                                                               pdfNumber.doubleOut(vals[1] + lasty) + " " +
+                                                                                                                                                               pdfNumber.doubleOut(vals[2] + lastx) + " " +
+                                                                                                                                                               pdfNumber.doubleOut(vals[3] + lasty) + " c\n");
+                                                                               lastcx = (vals[0] + lastx);
+                                                                               lastcy = (vals[1] + lasty);
+                                                                               lastx += vals[2];
+                                                                               lasty += vals[3];
+                                                                               break;
+                                                               case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:
+                                                                               if (lastcx == 0) {
+                                                                                               lastcx = lastx;
+                                                                               }
+                                                                               if (lastcy == 0) {
+                                                                                               lastcy = lasty;
+                                                                               }
+                                                                               tempx = lastx;
+                                                                               tempy = lasty;
+                                                                               lastx = vals[2];
+                                                                               lasty = vals[3];
+                                                                               currentStream.write(pdfNumber.doubleOut(vals[0]) + " " + pdfNumber.doubleOut(vals[1]) + " " +
+                                                                                                                                                               pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " y\n");
+                                                                               cxs = calculateLastControl(tempx, tempy, lastx, lasty, -tempx + vals[0], -tempy + vals[1]);
+                                                                               lastcx = cxs[0];
+                                                                               lastcy = cxs[1];
+                                                                               break;
+                                                               case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:
+                                                                               if (lastcx == 0) {
+                                                                                               lastcx = lastx;
+                                                                               }
+                                                                               if (lastcy == 0) {
+                                                                                               lastcy = lasty;
+                                                                               }
+                                                                               currentStream.write(pdfNumber.doubleOut(vals[0] + lastx) + " " + pdfNumber.doubleOut(vals[1] + lasty) + " " +
+                                                                                                                                                               pdfNumber.doubleOut(vals[2] + lastx) + " " +
+                                                                                                                                                               pdfNumber.doubleOut(vals[3] + lasty) + " y\n");
+                                                                               cxs = calculateLastControl(lastx, lasty, lastx + vals[2], lasty + vals[3], vals[0], vals[1]);
+                                                                               lastcx = cxs[0];
+                                                                               lastcy = cxs[1];
+                                                                               lastx += vals[2];
+                                                                               lasty += vals[3];
+                                                                               break;
+                                                               case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
+                                                                               if (lastcx == 0) {
+                                                                                               lastcx = lastx;
+                                                                               }
+                                                                               if (lastcy == 0) {
+                                                                                               lastcy = lasty;
+                                                                               }
+                                                                               tempx = lastx;
+                                                                               tempy = lasty;
+                                                                               lastcx = lastx + (lastx - lastcx);
+                                                                               lastcy = lasty + (lasty - lastcy);
+                                                                               lastx = vals[0];
+                                                                               lasty = vals[1];
+                                                                               currentStream.write(pdfNumber.doubleOut(lastcx) + " " + pdfNumber.doubleOut(lastcy) + " " +
+                                                                                                                                                               pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " y\n");
+                                                                               cxs = calculateLastControl(tempx, tempy, lastx, lasty, -tempx + lastcx, -tempy + lastcy);
+                                                                               lastcx = cxs[0];
+                                                                               lastcy = cxs[1];
+                                                                               break;
+                                                               case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
+                                                                               if (lastcx == 0) {
+                                                                                               lastcx = lastx;
+                                                                               }
+                                                                               if (lastcy == 0) {
+                                                                                               lastcy = lasty;
+                                                                               }
+                                                                               lastcx = lastx + (lastx - lastcx);
+                                                                               lastcy = lasty + (lasty - lastcy);
+                                                                               currentStream.write(pdfNumber.doubleOut(lastcx) + " " + pdfNumber.doubleOut(lastcy) + " " +
+                                                                                                                                                               pdfNumber.doubleOut(vals[0] + lastx) + " " +
+                                                                                                                                                               pdfNumber.doubleOut(vals[1] + lasty) + " y\n");
+                                                                               cxs = calculateLastControl(lastx, lasty, lastx + vals[0], lasty + vals[1], -lastx + lastcx, -lasty + lastcy);
+                                                                               lastcx = cxs[0];
+                                                                               lastcy = cxs[1];
+                                                                               lastx += vals[0];
+                                                                               lasty += vals[1];
+                                                                               break;
+                                                                               // get angle between the two points
+                                                                               // then get angle of points to centre (ie. both points are on the
+                                                                               // apogee and perigee of the ellipse)
+                                                                               // then work out the direction from flags
+                                                               case SVGPathSeg.PATHSEG_ARC_ABS:
+                                                                               {
 /*                        double rx = vals[0];
-                        double ry = vals[1];
-                        double theta = vals[2];
-                        boolean largearcflag = (vals[3] == 1.0);
-                        boolean sweepflag = (vals[4] == 1.0);
-
-                        double angle = Math.atan((vals[6] - lasty) /
-                                                 (vals[5] - lastx));
-                        double relangle = Math.acos(rx /
-                                                    Math.sqrt((vals[6] - lasty) *
-                                                              (vals[6] - lasty) +
-                                                              (vals[5] - lastx) * (vals[5] - lastx)));
-                        double absangle = angle + relangle;
-                        // change sign depending on flags
-                        double contrx1;
-                        double contry1;
-                        double contrx2;
-                        double contry2;
-                        if (largearcflag) {
-                            if (sweepflag) {
-                                contrx1 = lastx - rx * Math.cos(absangle);
-                                contry1 = lasty + rx * Math.sin(absangle);
-                                contrx2 = vals[5] + ry * Math.cos(absangle);
-                                contry2 = vals[6] + ry * Math.sin(absangle);
-                            } else {
-                                contrx1 = lastx - rx * Math.cos(absangle);
-                                contry1 = lasty - rx * Math.sin(absangle);
-                                contrx2 = vals[5] + ry * Math.cos(absangle);
-                                contry2 = vals[6] - ry * Math.sin(absangle);
-                            }
-                        } else {
-                            if (sweepflag) {
-                                contrx1 = lastx + rx * Math.cos(absangle);
-                                contry1 = lasty + rx * Math.sin(absangle);
-                                contrx2 = contrx1;
-                                contry2 = contry1;
-                            } else {
-                                contrx1 = lastx + ry * Math.cos(absangle);
-                                contry1 = lasty - ry * Math.sin(absangle);
-                                contrx2 = contrx1;
-                                contry2 = contry1;
-                            }
-                        }
-
-                        double cx = lastx;
-                        double cy = lasty;
-                        currentStream.write(pdfNumber.doubleOut(contrx1) + " " + pdfNumber.doubleOut(contry1) +
-                                            " " + pdfNumber.doubleOut(contrx2) + " " + pdfNumber.doubleOut(contry2) + " " +
-                                            pdfNumber.doubleOut(vals[5]) + " " + pdfNumber.doubleOut(vals[6]) + " c\n");
-                        lastcx = 0; //??
-                        lastcy = 0; //??
-                        lastx = vals[5];
-                        lasty = vals[6];*/
-                    }
-                    break;
-                case SVGPathSeg.PATHSEG_ARC_REL:
-                    {
+                                                                                               double ry = vals[1];
+                                                                                               double theta = vals[2];
+                                                                                               boolean largearcflag = (vals[3] == 1.0);
+                                                                                               boolean sweepflag = (vals[4] == 1.0);
+
+                                                                                               double angle = Math.atan((vals[6] - lasty) /
+                                                                                                                                                                                                (vals[5] - lastx));
+                                                                                               double relangle = Math.acos(rx /
+                                                                                                                                                                                                               Math.sqrt((vals[6] - lasty) *
+                                                                                                                                                                                                                                                       (vals[6] - lasty) +
+                                                                                                                                                                                                                                                       (vals[5] - lastx) * (vals[5] - lastx)));
+                                                                                               double absangle = angle + relangle;
+                                                                                               // change sign depending on flags
+                                                                                               double contrx1;
+                                                                                               double contry1;
+                                                                                               double contrx2;
+                                                                                               double contry2;
+                                                                                               if (largearcflag) {
+                                                                                                               if (sweepflag) {
+                                                                                                                               contrx1 = lastx - rx * Math.cos(absangle);
+                                                                                                                               contry1 = lasty + rx * Math.sin(absangle);
+                                                                                                                               contrx2 = vals[5] + ry * Math.cos(absangle);
+                                                                                                                               contry2 = vals[6] + ry * Math.sin(absangle);
+                                                                                                               } else {
+                                                                                                                               contrx1 = lastx - rx * Math.cos(absangle);
+                                                                                                                               contry1 = lasty - rx * Math.sin(absangle);
+                                                                                                                               contrx2 = vals[5] + ry * Math.cos(absangle);
+                                                                                                                               contry2 = vals[6] - ry * Math.sin(absangle);
+                                                                                                               }
+                                                                                               } else {
+                                                                                                               if (sweepflag) {
+                                                                                                                               contrx1 = lastx + rx * Math.cos(absangle);
+                                                                                                                               contry1 = lasty + rx * Math.sin(absangle);
+                                                                                                                               contrx2 = contrx1;
+                                                                                                                               contry2 = contry1;
+                                                                                                               } else {
+                                                                                                                               contrx1 = lastx + ry * Math.cos(absangle);
+                                                                                                                               contry1 = lasty - ry * Math.sin(absangle);
+                                                                                                                               contrx2 = contrx1;
+                                                                                                                               contry2 = contry1;
+                                                                                                               }
+                                                                                               }
+
+                                                                                               double cx = lastx;
+                                                                                               double cy = lasty;
+                                                                                               currentStream.write(pdfNumber.doubleOut(contrx1) + " " + pdfNumber.doubleOut(contry1) +
+                                                                                                                                                                               " " + pdfNumber.doubleOut(contrx2) + " " + pdfNumber.doubleOut(contry2) + " " +
+                                                                                                                                                                               pdfNumber.doubleOut(vals[5]) + " " + pdfNumber.doubleOut(vals[6]) + " c\n");
+                                                                                               lastcx = 0; //??
+                                                                                               lastcy = 0; //??
+                                                                                               lastx = vals[5];
+                                                                                               lasty = vals[6];*/
+                                                                               }
+                                                                               break;
+                                                               case SVGPathSeg.PATHSEG_ARC_REL:
+                                                                               {
 /*                        double rx = vals[0];
-                        double ry = vals[1];
-                        double theta = vals[2];
-                        boolean largearcflag = (vals[3] == 1.0);
-                        boolean sweepflag = (vals[4] == 1.0);
-
-                        double angle = Math.atan(vals[6] / vals[5]);
-                        double relangle = Math.atan(ry / rx);
-                        //                                     System.out.println((theta * Math.PI / 180f) + ":" + relangle + ":" + largearcflag + ":" + sweepflag);
-                        double absangle = (theta * Math.PI / 180f);//angle + relangle;
-                        // change sign depending on flags
-                        double contrx1;
-                        double contry1;
-                        double contrx2;
-                        double contry2;
-                        if (largearcflag) {
-                            // in a large arc we need to do at least 2 and a bit
-                            // segments or curves.
-                            if (sweepflag) {
-                                contrx1 = lastx + rx * Math.cos(absangle);
-                                contry1 = lasty + rx * Math.sin(absangle);
-                                contrx2 = lastx + vals[5] +
-                                          ry * Math.cos(absangle);
-                                contry2 = lasty + vals[6] -
-                                          ry * Math.sin(absangle);
-                            } else {
-                                contrx1 = lastx + rx * Math.sin(absangle);
-                                contry1 = lasty + rx * Math.cos(absangle);
-                                contrx2 = lastx + vals[5] +
-                                          ry * Math.cos(absangle);
-                                contry2 = lasty + vals[6] +
-                                          ry * Math.sin(absangle);
-                            }
-                        } else {
-                            // only need at most two segments
-                            if (sweepflag) {
-                                contrx1 = lastx + rx * Math.cos(absangle);
-                                contry1 = lasty - rx * Math.sin(absangle);
-                                contrx2 = contrx1;
-                                contry2 = contry1;
-                            } else {
-                                contrx1 = lastx - ry * Math.cos(absangle);
-                                contry1 = lasty + ry * Math.sin(absangle);
-                                contrx2 = contrx1;
-                                contry2 = contry1;
-                            }
-                        }
-                        //System.out.println(contrx1 + ":" + contry1 + ":" + contrx2 + ":" + contry2);
-
-                        double cx = lastx;
-                        double cy = lasty;
-                        currentStream.write(pdfNumber.doubleOut(contrx1) + " " + pdfNumber.doubleOut(contry1) +
-                                            " " + pdfNumber.doubleOut(contrx2) + " " + pdfNumber.doubleOut(contry2) + " " +
-                                            pdfNumber.doubleOut(vals[5] + lastx) + " " +
-                                            pdfNumber.doubleOut(vals[6] + lasty) + " c\n");
-
-                        lastcx = 0; //??
-                        lastcy = 0; //??
-                        lastx += vals[5];
-                        lasty += vals[6];*/
-                    }
-                    break;
-                case SVGPathSeg.PATHSEG_CLOSEPATH:
-                    currentStream.write("h\n");
-                    pathmoveto = null;
-                    lastx = lastmovex;
-                    lasty = lastmovey;
-                    break;
-            }
-        }
-        doDrawing(di);
-    }
-
-    /**
-     * Calculate the last control point for a bezier curve.
-     * This is used to find the last control point for a curve where
-     * only the first control point is specified.
-     * The control point is a reflection of the first control point
-     * which results in an even smooth curve. The curve is symmetrical.
-     */
-    protected float[] calculateLastControl(float x1, float y1, float x2, float y2, float relx, float rely)
-    {
-        float vals[] = new float[2];
-        relx = -relx;
-        rely = -rely;
-        float dist = (float)Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
-        float costheta = (float)(x2 - x1) / dist;
-        float sinetheta = (float)(y2 - y1) / dist;
-        float temp = relx;
-        relx = relx * costheta + rely * sinetheta;
-        rely = -temp * sinetheta + rely * costheta;
-        relx = -relx;
-        temp = relx;
-        relx = relx * costheta - rely * sinetheta;
-        rely = temp * sinetheta + rely * costheta;
-        vals[0] = x2 - relx;
-        vals[1] = y2 - rely;
-        return vals;
-    }
-
-    /**
-     * Adds an SVG polyline or polygon.
-     * A polygon is merely a closed polyline.
-     * This is made up from a set of points that straight lines are drawn between.
-     */
-    protected void addPolyline(Vector points, DrawingInstruction di,
-                               boolean close) {
-        PDFNumber pdfNumber = new PDFNumber();
-        PathPoint pc;
-        float lastx = 0;
-        float lasty = 0;
-        Enumeration e = points.elements();
-        if (e.hasMoreElements()) {
-            pc = (PathPoint) e.nextElement();
-            lastx = pc.x;
-            lasty = pc.y;
-            currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " m\n");
-        }
-        while (e.hasMoreElements()) {
-            pc = (PathPoint) e.nextElement();
-            lastx = pc.x;
-            lasty = pc.y;
-            currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " l\n");
-        }
-        if (close)
-            currentStream.write("h\n");
-        doDrawing(di);
-    }
-
-    /**
-     * Writes the drawing instruction out to the current stream
-     * depending on what type of drawing is required.
-     */
-    protected void doDrawing(DrawingInstruction di) {
-        if (di == null) {
-            currentStream.write("S\n");
-        } else {
-            if (di.fill) {
-                if (di.stroke) {
-                    if (!di.nonzero)
-                        currentStream.write("B*\n");
-                    else
-                        currentStream.write("B\n");
-                } else {
-                    if (!di.nonzero)
-                        currentStream.write("f*\n");
-                    else
-                        currentStream.write("f\n");
-                }
-            } else {
-                //                             if(di.stroke)
-                currentStream.write("S\n");
-            }
-        }
-    }
-
-    /**
-     * Renders an svg image to the current stream.
-     * This uses the FopImageFactory to load the image and then renders it.
-     */
-    public void renderImage(String href, float x, float y, float width,
-                            float height) {
-        try {
-            if (href.indexOf(":") == -1) {
-                href = "file:" + href;
-            }
-            FopImage img = FopImageFactory.Make(href);
-            PDFNumber pdfNumber = new PDFNumber();
-            if (img instanceof SVGImage) {
-                SVGSVGElement svg =
-                  ((SVGImage) img).getSVGDocument().getRootElement();
-                currentStream.write("q\n" + pdfNumber.doubleOut(width /
-                                    svg.getWidth().getBaseVal().getValue()) + " 0 0 " +
-                                    pdfNumber.doubleOut(height /
-                                    svg.getHeight().getBaseVal().getValue()) + " 0 0 cm\n");
-                renderSVG(svg, (int) x * 1000, (int) y * 1000);
-                currentStream.write("Q\n");
-                //                             renderSVG(svg);
-            } else if (img != null) {
-                int xObjectNum = this.pdfDoc.addImage(img);
-                currentStream.write("q\n1 0 0 -1 0 " +
-                                    pdfNumber.doubleOut(2 * y + height) + " cm\n" + pdfNumber.doubleOut(width) + " 0 0 " +
-                                    pdfNumber.doubleOut(height) + " " + pdfNumber.doubleOut(x) + " " + pdfNumber.doubleOut(y) + " cm\n" + "/Im" +
-                                    xObjectNum + " Do\nQ\n");
-                //                             img.close();
-            }
-        } catch (Exception e) {
-            MessageHandler.errorln("could not add image to SVG: " + href);
-        }
-    }
-
-    /**
-     * A symbol has a viewbox and preserve aspect ratio.
-     */
-    protected void renderSymbol(SVGSymbolElement symbol, int x, int y) {
-        NodeList nl = symbol.getChildNodes();
-        for (int count = 0; count < nl.getLength(); count++) {
-            Node n = nl.item(count);
-            if (n instanceof SVGElement) {
-                renderElement((SVGElement) n, x, y);
-            }
-        }
-    }
-
-    /**
-     * Handles the construction of an SVG gradient.
-     * This gets the gradient element and creates the pdf info
-     * in the pdf document.
-     * The type of gradient is determined by what class the gradient element is.
-     */
-    protected void handleGradient(String sp, DrawingInstruction di,
-                                  boolean fill, SVGElement area) {
-        // should be a url to a gradient
-        String url = (String) sp;
-        if (url.startsWith("url(")) {
-            String address;
-            int b1 = url.indexOf("(");
-            int b2 = url.indexOf(")");
-            address = url.substring(b1 + 1, b2);
-            SVGElement gi = null;
-            gi = locateDef(address, area);
-            if (gi instanceof SVGLinearGradientElement) {
-                SVGLinearGradientElement linear =
-                  (SVGLinearGradientElement) gi;
-                handleLinearGradient(linear, di, fill, area);
-            } else if (gi instanceof SVGRadialGradientElement) {
-                SVGRadialGradientElement radial =
-                  (SVGRadialGradientElement) gi;
-                handleRadialGradient(radial, di, fill, area);
-            } else if (gi instanceof SVGPatternElement) {
-                SVGPatternElement pattern = (SVGPatternElement) gi;
-                handlePattern(pattern, di, fill, area);
-            } else {
-                MessageHandler.errorln("WARNING Invalid fill reference :" +
-                                   gi + ":" + address);
-            }
-        }
-    }
-
-    protected void handlePattern(SVGPatternElement pattern,
-                                 DrawingInstruction di, boolean fill, SVGElement area) {
-        SVGAnimatedLength x, y, width, height;
-        short pattUnits = SVGUnitTypes.SVG_UNIT_TYPE_UNKNOWN;
-        NodeList stops = null;
-        x = pattern.getX();
-        y = pattern.getY();
-        width = pattern.getWidth();
-        height = pattern.getHeight();
-        NodeList nl = pattern.getChildNodes();
-        SVGPatternElement ref = (SVGPatternElement) locateDef(
-                                  pattern.getHref().getBaseVal(), pattern);
-        while (ref != null) {
-            if (x == null) {
-                x = ref.getX();
-                pattUnits = ref.getPatternUnits().getBaseVal();
-            }
-            if (y == null) {
-                y = ref.getY();
-            }
-            if (width == null) {
-                width = ref.getWidth();
-            }
-            if (height == null) {
-                height = ref.getHeight();
-            }
-            if (nl.getLength() == 0) {
-                nl = ref.getChildNodes();
-            }
-            ref = (SVGPatternElement) locateDef(
-                    ref.getHref().getBaseVal(), ref);
-        }
-        if (x == null) {
-            SVGLength length = new SVGLengthImpl();
-            length.newValueSpecifiedUnits(
-              SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0);
-            x = new SVGAnimatedLengthImpl(length);
-        }
-        if (y == null) {
-            SVGLength length = new SVGLengthImpl();
-            length.newValueSpecifiedUnits(
-              SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0);
-            y = new SVGAnimatedLengthImpl(length);
-        }
-        if (width == null) {
-            SVGLength length = new SVGLengthImpl();
-            length.newValueSpecifiedUnits(
-              SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 1);
-            width = new SVGAnimatedLengthImpl(length);
-        }
-        if (height == null) {
-            SVGLength length = new SVGLengthImpl();
-            length.newValueSpecifiedUnits(
-              SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 1);
-            height = new SVGAnimatedLengthImpl(length);
-        }
-
-        StringWriter realStream = currentStream;
-        currentStream = new StringWriter();
-
-        currentStream.write("q\n");
-        // this makes the pattern the right way up, since it is outside the original
-        // transform around the whole svg document
-        currentStream.write("1 0 0 -1 0 " +
-                            height.getBaseVal().getValue() + " cm\n");
-        for (int count = 0; count < nl.getLength(); count++) {
-            Node n = nl.item(count);
-            if (n instanceof SVGElement) {
-                renderElement((SVGElement) n, 0, 0);
-            }
-        }
-        currentStream.write("Q\n");
-
-        double xval = x.getBaseVal().getValue() + currentXPosition / 1000f;
-        double yval = -y.getBaseVal().getValue() + currentYPosition / 1000f;
-        if (area instanceof GraphicElement) {
-            SVGRect bbox = ((GraphicElement) area).getBBox();
-            if (bbox != null) {
-                //                     xval += bbox.getX();
-                //                     yval -= bbox.getY();
-            }
-        }
-        double widthval = width.getBaseVal().getValue();
-        double heightval = height.getBaseVal().getValue();
-        Vector bbox = new Vector();
-        bbox.addElement(new Double(0));
-        bbox.addElement(new Double(0));
-        bbox.addElement(new Double(widthval));
-        bbox.addElement(new Double(heightval));
-        Vector translate = new Vector();
-        // combine with pattern transform
-        translate.addElement(new Double(1));
-        translate.addElement(new Double(0));
-        translate.addElement(new Double(0));
-        translate.addElement(new Double(1));
-        translate.addElement(new Double(xval));
-        translate.addElement(new Double(yval));
-        // need to handle PDFResources
-        PDFPattern myPat =
-          this.pdfDoc.makePattern(1, null, 1, 1, bbox, widthval,
-                                  heightval, translate, null, currentStream.getBuffer());
-
-        currentStream = realStream;
-        currentStream.write(myPat.getColorSpaceOut(fill));
-        if (fill)
-            di.fill = true;
-        else
-            di.stroke = true;
-    }
-
-    protected void handleLinearGradient(
-      SVGLinearGradientElement linear, DrawingInstruction di,
-      boolean fill, SVGElement area) {
-        // first get all the gradient values
-        // if values not present follow the href
-        // the gradient units will be where the vals are specified
-        // the spread method will be where there are stop elements
-        SVGAnimatedLength ax1, ax2, ay1, ay2;
-        short spread = SVGGradientElement.SVG_SPREADMETHOD_UNKNOWN;
-        short gradUnits = SVGUnitTypes.SVG_UNIT_TYPE_UNKNOWN;
-        NodeList stops = null;
-        ax1 = linear.getX1();
-        ax2 = linear.getX2();
-        ay1 = linear.getY1();
-        ay2 = linear.getY2();
-        stops = linear.getChildNodes();
-        SVGLinearGradientElement ref = (SVGLinearGradientElement) locateDef(
-                                         linear.getHref().getBaseVal(), linear);
-        while (ref != null) {
-            if (ax1 == null) {
-                ax1 = ref.getX1();
-                gradUnits = ref.getGradientUnits().getBaseVal();
-            }
-            if (ax2 == null) {
-                ax2 = ref.getX2();
-            }
-            if (ay1 == null) {
-                ay1 = ref.getY1();
-            }
-            if (ay2 == null) {
-                ay2 = ref.getY2();
-            }
-            if (stops.getLength() == 0) {
-                stops = ref.getChildNodes();
-            }
-            ref = (SVGLinearGradientElement) locateDef(
-                    ref.getHref().getBaseVal(), ref);
-        }
-        if (ax1 == null) {
-            SVGLength length = new SVGLengthImpl();
-            length.newValueSpecifiedUnits(
-              SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0);
-            ax1 = new SVGAnimatedLengthImpl(length);
-        }
-        if (ax2 == null) {
-            // if x2 is not specified then it should be 100%
-            SVGLength length = new SVGLengthImpl();
-            length.newValueSpecifiedUnits(
-              SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 1);
-            ax2 = new SVGAnimatedLengthImpl(length);
-        }
-        if (ay1 == null) {
-            SVGLength length = new SVGLengthImpl();
-            length.newValueSpecifiedUnits(
-              SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0);
-            ay1 = new SVGAnimatedLengthImpl(length);
-        }
-        if (ay2 == null) {
-            SVGLength length = new SVGLengthImpl();
-            length.newValueSpecifiedUnits(
-              SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0);
-            ay2 = new SVGAnimatedLengthImpl(length);
-        }
-        SVGAnimatedTransformList an = linear.getGradientTransform();
-        SVGMatrix transform = null;
-        if(an != null)
-            transform = an.getBaseVal().consolidate().getMatrix();
-        Vector theCoords = null;
-        if (gradUnits == SVGUnitTypes.SVG_UNIT_TYPE_UNKNOWN)
-            gradUnits = linear.getGradientUnits().getBaseVal();
-        // spread: pad (normal), reflect, repeat
-        spread = linear.getSpreadMethod().getBaseVal();
-        if (gradUnits == SVGUnitTypes.SVG_UNIT_TYPE_USERSPACEONUSE) {
-            if (area instanceof SVGTransformable) {
-                SVGTransformable tf = (SVGTransformable) area;
-                double x1, y1, x2, y2;
-                x1 = ax1.getBaseVal().getValue();
-                y1 = -ay1.getBaseVal().getValue();
-                x2 = ax2.getBaseVal().getValue();
-                y2 = -ay2.getBaseVal().getValue();
-                SVGMatrix matrix = tf.getScreenCTM();
-                if(transform != null)
-                    matrix = matrix.multiply(transform);
-                double oldx = x1;
-                x1 = matrix.getA() * x1 + matrix.getC() * y1 +
-                     matrix.getE();
-                y1 = matrix.getB() * oldx + matrix.getD() * y1 -
-                     matrix.getF();
-                oldx = x2;
-                x2 = matrix.getA() * x2 + matrix.getC() * y2 +
-                     matrix.getE();
-                y2 = matrix.getB() * oldx + matrix.getD() * y2 -
-                     matrix.getF();
-                theCoords = new Vector();
-                if (spread == SVGGradientElement.SVG_SPREADMETHOD_REFLECT) {
-                } else if (spread ==
-                    SVGGradientElement.SVG_SPREADMETHOD_REFLECT) {
-                } else {
-                    theCoords.addElement(
-                      new Double(currentXPosition / 1000f + x1));
-                    theCoords.addElement(
-                      new Double(currentYPosition / 1000f + y1));
-                    theCoords.addElement(
-                      new Double(currentXPosition / 1000f + x2));
-                    theCoords.addElement(
-                      new Double(currentYPosition / 1000f + y2));
-                }
-            }
-        } else if (area instanceof GraphicElement) {
-            SVGRect rect = ((GraphicElement) area).getBBox();
-            if (rect != null) {
-                theCoords = new Vector();
-                SVGLength val;
-                val = ax1.getBaseVal();
-                if (val.getUnitType() ==
-                        SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
-                        SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
-                    theCoords.addElement(
-                      new Double(currentXPosition / 1000f +
-                                 rect.getX() +
-                                 val.getValue() * rect.getWidth()));
-                } else {
-                    theCoords.addElement(
-                      new Double(currentXPosition / 1000f +
-                                 val.getValue()));
-                }
-                val = ay1.getBaseVal();
-                if (val.getUnitType() ==
-                        SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
-                        SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
-                    theCoords.addElement(
-                      new Double(currentYPosition / 1000f -
-                                 rect.getY() -
-                                 val.getValue() * rect.getHeight()));
-                } else {
-                    theCoords.addElement(
-                      new Double(currentYPosition / 1000f -
-                                 val.getValue()));
-                }
-                val = ax2.getBaseVal();
-                if (val.getUnitType() ==
-                        SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
-                        SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
-                    theCoords.addElement(
-                      new Double(currentXPosition / 1000f +
-                                 rect.getX() +
-                                 val.getValue() * rect.getWidth()));
-                } else {
-                    theCoords.addElement(
-                      new Double(currentXPosition / 1000f +
-                                 val.getValue()));
-                }
-                val = ay2.getBaseVal();
-                if (val.getUnitType() ==
-                        SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
-                        SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
-                    theCoords.addElement(
-                      new Double(currentYPosition / 1000f -
-                                 rect.getY() -
-                                 val.getValue() * rect.getHeight()));
-                } else {
-                    theCoords.addElement(
-                      new Double(currentYPosition / 1000f -
-                                 val.getValue()));
-                }
-            }
-        }
-        if (theCoords == null) {
-            theCoords = new Vector();
-            theCoords.addElement( new Double(currentXPosition / 1000f +
-                                             ax1.getBaseVal().getValue()));
-            theCoords.addElement( new Double(currentYPosition / 1000f -
-                                             ay1.getBaseVal().getValue()));
-            theCoords.addElement( new Double(currentXPosition / 1000f +
-                                             ax2.getBaseVal().getValue()));
-            theCoords.addElement( new Double(currentYPosition / 1000f -
-                                             ay2.getBaseVal().getValue()));
-        }
-
-        Vector theExtend = new Vector();
-        theExtend.addElement(new Boolean(true));
-        theExtend.addElement(new Boolean(true));
-
-        Vector theDomain = new Vector();
-        theDomain.addElement(new Double(0));
-        theDomain.addElement(new Double(1));
-
-        Vector theEncode = new Vector();
-        theEncode.addElement(new Double(0));
-        theEncode.addElement(new Double(1));
-        theEncode.addElement(new Double(0));
-        theEncode.addElement(new Double(1));
-
-        Vector theBounds = new Vector();
-        theBounds.addElement(new Double(0));
-        theBounds.addElement(new Double(1));
-
-        Vector theFunctions = new Vector();
-
-        NodeList nl = stops;
-        Vector someColors = new Vector();
-        float lastoffset = 0;
-        Vector lastVector = null;
-        SVGStopElementImpl stop;
-        if (nl.getLength() == 0) {
-            // the color should be "none"
-            if (fill)
-                di.fill = false;
-            else
-                di.stroke = false;
-            return;
-        } else if (nl.getLength() == 1) {
-            stop = (SVGStopElementImpl) nl.item(0);
-            CSSValue cv = stop.getPresentationAttribute("stop-color");
-            if (cv == null) {
-                // maybe using color
-                cv = stop.getPresentationAttribute("color");
-            }
-            if (cv == null) {
-                // problems
-                MessageHandler.errorln("no stop-color or color in stop element");
-                return;
-            }
-            PDFColor color = new PDFColor(0, 0, 0);
-            if (cv != null &&
-                    cv.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
-                if (((CSSPrimitiveValue) cv).getPrimitiveType() ==
-                        CSSPrimitiveValue.CSS_RGBCOLOR) {
-                    RGBColor col =
-                      ((CSSPrimitiveValue) cv).getRGBColorValue();
-                    CSSPrimitiveValue val;
-                    val = col.getRed();
-                    float red = val.getFloatValue(
-                                  CSSPrimitiveValue.CSS_NUMBER);
-                    val = col.getGreen();
-                    float green = val.getFloatValue(
-                                    CSSPrimitiveValue.CSS_NUMBER);
-                    val = col.getBlue();
-                    float blue = val.getFloatValue(
-                                   CSSPrimitiveValue.CSS_NUMBER);
-                    color = new PDFColor(red, green, blue);
-                }
-            }
-            currentStream.write(color.getColorSpaceOut(fill));
-            if (fill)
-                di.fill = true;
-            else
-                di.stroke = true;
-            return;
-        }
-        for (int count = 0; count < nl.getLength(); count++) {
-            stop = (SVGStopElementImpl) nl.item(count);
-            CSSValue cv = stop.getPresentationAttribute("stop-color");
-            if (cv == null) {
-                // maybe using color
-                cv = stop.getPresentationAttribute("color");
-            }
-            if (cv == null) {
-                // problems
-                MessageHandler.errorln("no stop-color or color in stop element");
-                continue;
-            }
-            PDFColor color = new PDFColor(0, 0, 0);
-            if (cv != null &&
-                    cv.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
-                if (((CSSPrimitiveValue) cv).getPrimitiveType() ==
-                        CSSPrimitiveValue.CSS_RGBCOLOR) {
-                    RGBColor col =
-                      ((CSSPrimitiveValue) cv).getRGBColorValue();
-                    CSSPrimitiveValue val;
-                    val = col.getRed();
-                    float red = val.getFloatValue(
-                                  CSSPrimitiveValue.CSS_NUMBER);
-                    val = col.getGreen();
-                    float green = val.getFloatValue(
-                                    CSSPrimitiveValue.CSS_NUMBER);
-                    val = col.getBlue();
-                    float blue = val.getFloatValue(
-                                   CSSPrimitiveValue.CSS_NUMBER);
-                    color = new PDFColor(red, green, blue);
-                    currentColour = color;
-                }
-            }
-            float offset = stop.getOffset().getBaseVal();
-            Vector colVector = color.getVector();
-            // create bounds from last to offset
-            if (lastVector != null) {
-                Vector theCzero = lastVector;
-                Vector theCone = colVector;
-                PDFFunction myfunc =
-                  this.pdfDoc.makeFunction(2, theDomain, null,
-                                           theCzero, theCone, 1.0);
-                theFunctions.addElement(myfunc);
-            }
-            lastoffset = offset;
-            lastVector = colVector;
-            someColors.addElement(color);
-        }
-        ColorSpace aColorSpace = new ColorSpace(ColorSpace.DEVICE_RGB);
-        /*                             PDFFunction myfunky = this.pdfDoc.makeFunction(3,
-                               theDomain, null,
-                               theFunctions, null,
-                               theEncode);
-                       PDFShading myShad = null;
-                       myShad = this.pdfDoc.makeShading(
-                               2, aColorSpace,
-                               null, null, false,
-                               theCoords, null, myfunky,theExtend);
-                       PDFPattern myPat = this.pdfDoc.makePattern(2, myShad, null, null, null);*/
-        PDFPattern myPat = this.pdfDoc.createGradient(false, aColorSpace,
-                           someColors, null, theCoords);
-        currentStream.write(myPat.getColorSpaceOut(fill));
-        if (fill)
-            di.fill = true;
-        else
-            di.stroke = true;
-    }
-
-    protected void handleRadialGradient(
-      SVGRadialGradientElement radial, DrawingInstruction di,
-      boolean fill, SVGElement area) {
-        // first get all the gradient values
-        // if values not present follow the href
-        // the gradient units will be where the vals are specified
-        SVGAnimatedLength acx, acy, ar, afx, afy;
-        short gradUnits = radial.getGradientUnits().getBaseVal();
-        NodeList stops = null;
-        acx = radial.getCx();
-        acy = radial.getCy();
-        ar = radial.getR();
-        afx = radial.getFx();
-        afy = radial.getFy();
-        stops = radial.getChildNodes();
-        SVGRadialGradientElement ref = (SVGRadialGradientElement) locateDef(
-                                         radial.getHref().getBaseVal(), radial);
-        while (ref != null) {
-            if (acx == null) {
-                acx = ref.getCx();
-                gradUnits = ref.getGradientUnits().getBaseVal();
-            }
-            if (acy == null) {
-                acy = ref.getCy();
-            }
-            if (ar == null) {
-                ar = ref.getR();
-            }
-            if (afx == null) {
-                afx = ref.getFx();
-            }
-            if (afy == null) {
-                afy = ref.getFy();
-            }
-            if (stops.getLength() == 0) {
-                stops = ref.getChildNodes();
-            }
-            ref = (SVGRadialGradientElement) locateDef(
-                    ref.getHref().getBaseVal(), ref);
-        }
-        if (acx == null) {
-            SVGLength length = new SVGLengthImpl();
-            length.newValueSpecifiedUnits(
-              SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0.5f);
-            acx = new SVGAnimatedLengthImpl(length);
-        }
-        if (acy == null) {
-            SVGLength length = new SVGLengthImpl();
-            length.newValueSpecifiedUnits(
-              SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0.5f);
-            acy = new SVGAnimatedLengthImpl(length);
-        }
-        if (ar == null) {
-            SVGLength length = new SVGLengthImpl();
-            length.newValueSpecifiedUnits(
-              SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 1);
-            ar = new SVGAnimatedLengthImpl(length);
-        }
-        if (afx == null) {
-            SVGLength length = new SVGLengthImpl();
-            length.newValueSpecifiedUnits(
-              SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0.5f);
-            afx = new SVGAnimatedLengthImpl(length);
-        }
-        if (afy == null) {
-            SVGLength length = new SVGLengthImpl();
-            length.newValueSpecifiedUnits(
-              SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0.5f);
-            afy = new SVGAnimatedLengthImpl(length);
-        }
-        ColorSpace aColorSpace = new ColorSpace(ColorSpace.DEVICE_RGB);
-        org.w3c.dom.NodeList nl = stops;
-        SVGStopElementImpl stop;
-        if (nl.getLength() == 0) {
-            // the color should be "none"
-            if (fill)
-                di.fill = false;
-            else
-                di.stroke = false;
-            return;
-        } else if (nl.getLength() == 1) {
-            stop = (SVGStopElementImpl) nl.item(0);
-            CSSValue cv = stop.getPresentationAttribute("stop-color");
-            if (cv == null) {
-                // maybe using color
-                cv = stop.getPresentationAttribute("color");
-            }
-            if (cv == null) {
-                // problems
-                MessageHandler.errorln("no stop-color or color in stop element");
-                return;
-            }
-            PDFColor color = new PDFColor(0, 0, 0);
-            if (cv != null &&
-                    cv.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
-                if (((CSSPrimitiveValue) cv).getPrimitiveType() ==
-                        CSSPrimitiveValue.CSS_RGBCOLOR) {
-                    RGBColor col =
-                      ((CSSPrimitiveValue) cv).getRGBColorValue();
-                    CSSPrimitiveValue val;
-                    val = col.getRed();
-                    float red = val.getFloatValue(
-                                  CSSPrimitiveValue.CSS_NUMBER);
-                    val = col.getGreen();
-                    float green = val.getFloatValue(
-                                    CSSPrimitiveValue.CSS_NUMBER);
-                    val = col.getBlue();
-                    float blue = val.getFloatValue(
-                                   CSSPrimitiveValue.CSS_NUMBER);
-                    color = new PDFColor(red, green, blue);
-                }
-            }
-            currentStream.write(color.getColorSpaceOut(fill));
-            if (fill)
-                di.fill = true;
-            else
-                di.stroke = true;
-            return;
-        }
-        Hashtable table = null;
-        Vector someColors = new Vector();
-        Vector theCoords = null;
-        Vector theBounds = new Vector();
-        // the coords should be relative to the current object
-        // check value types, eg. %
-        if (gradUnits == SVGUnitTypes.SVG_UNIT_TYPE_USERSPACEONUSE) {
-            if (area instanceof SVGTransformable) {
-                SVGTransformable tf = (SVGTransformable) area;
-                double x1, y1, x2, y2;
-                x1 = acx.getBaseVal().getValue();
-                y1 = -acy.getBaseVal().getValue();
-                x2 = afx.getBaseVal().getValue();
-                y2 = -afy.getBaseVal().getValue();
-                SVGMatrix matrix = tf.getScreenCTM();
-                double oldx = x1;
-                x1 = matrix.getA() * x1 + matrix.getB() * y1 +
-                     matrix.getE();
-                y1 = matrix.getC() * oldx + matrix.getD() * y1 +
-                     matrix.getF();
-                oldx = x2;
-                x2 = matrix.getA() * x2 + matrix.getB() * y2 +
-                     matrix.getE();
-                y2 = matrix.getC() * oldx + matrix.getD() * y2 +
-                     matrix.getF();
-                theCoords = new Vector();
-                //                             if(spread == SVGGradientElement.SVG_SPREADMETHOD_REFLECT) {
-                //                             } else if(spread== SVGGradientElement.SVG_SPREADMETHOD_REFLECT) {
-                //                             } else {
-                theCoords.addElement(
-                  new Double(currentXPosition / 1000f + x1));
-                // the y val needs to be adjust by 2 * R * rotation
-                // depending on if this value is from an x or y coord
-                // before transformation
-                theCoords.addElement(
-                  new Double(currentYPosition / 1000f - y1 +
-                             (matrix.getC() - matrix.getD()) * 2 *
-                             ar.getBaseVal().getValue()));
-                theCoords.addElement(new Double(0));
-                theCoords.addElement(
-                  new Double(currentXPosition / 1000f + x2));
-                theCoords.addElement(
-                  new Double(currentYPosition / 1000f - y2 +
-                             (matrix.getC() - matrix.getD()) * 2 *
-                             ar.getBaseVal().getValue()));
-                theCoords.addElement(
-                  new Double(ar.getBaseVal().getValue()));
-                //                             }
-            }
-        } else if (gradUnits ==
-            SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX &&
-            area instanceof GraphicElement) {
-            SVGRect rect = ((GraphicElement) area).getBBox();
-            if (rect != null) {
-                theCoords = new Vector();
-                SVGLength val;
-                val = acx.getBaseVal();
-                if (val.getUnitType() ==
-                        SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
-                        SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
-                    theCoords.addElement(
-                      new Double(currentXPosition / 1000f +
-                                 rect.getX() +
-                                 val.getValue() * rect.getWidth()));
-                } else {
-                    theCoords.addElement(
-                      new Double(currentXPosition / 1000f +
-                                 val.getValue()));
-                }
-                val = acy.getBaseVal();
-                if (val.getUnitType() ==
-                        SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
-                        SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
-                    theCoords.addElement(
-                      new Double(currentYPosition / 1000f -
-                                 rect.getY() -
-                                 val.getValue() * rect.getHeight()));
-                } else {
-                    theCoords.addElement(
-                      new Double(currentYPosition / 1000f -
-                                 val.getValue()));
-                }
-                theCoords.addElement(new Double(0));
-                val = afx.getBaseVal();
-                if (val.getUnitType() ==
-                        SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
-                        SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
-                    theCoords.addElement(
-                      new Double(currentXPosition / 1000f +
-                                 rect.getX() +
-                                 val.getValue() * rect.getWidth()));
-                } else {
-                    theCoords.addElement(
-                      new Double(currentXPosition / 1000f +
-                                 val.getValue()));
-                }
-                val = afy.getBaseVal();
-                if (val.getUnitType() ==
-                        SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
-                        SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
-                    theCoords.addElement(
-                      new Double(currentYPosition / 1000f -
-                                 rect.getY() -
-                                 val.getValue() * rect.getHeight()));
-                } else {
-                    theCoords.addElement(
-                      new Double(currentYPosition / 1000f -
-                                 val.getValue()));
-                }
-                val = ar.getBaseVal();
-                if (val.getUnitType() ==
-                        SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
-                        SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
-                    theCoords.addElement(
-                      new Double(val.getValue() * rect.getHeight()));
-                } else {
-                    theCoords.addElement(new Double(val.getValue()));
-                }
-            }
-        }
-        if (theCoords == null) {
-            // percentage values are expressed according to the viewport.
-            SVGElement vp =
-              ((GraphicElement) area).getNearestViewportElement();
-            if (area instanceof GraphicElement) {
-                SVGRect rect = ((GraphicElement) area).getBBox();
-                if (rect != null) {
-                    theCoords = new Vector();
-                    SVGLength val = acx.getBaseVal();
-                    if (val.getUnitType() ==
-                            SVGLength.SVG_LENGTHTYPE_PERCENTAGE ||
-                            gradUnits ==
-                            SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
-                        theCoords.addElement(
-                          new Double(currentXPosition / 1000f +
-                                     rect.getX() +
-                                     val.getValue() * rect.getWidth()));
-                    } else {
-                        theCoords.addElement(
-                          new Double(currentXPosition / 1000f +
-                                     val.getValue()));
-                    }
-                    val = acy.getBaseVal();
-                    if (val.getUnitType() ==
-                            SVGLength.SVG_LENGTHTYPE_PERCENTAGE ||
-                            gradUnits ==
-                            SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
-                        theCoords.addElement(
-                          new Double(currentYPosition / 1000f -
-                                     rect.getY() -
-                                     val.getValue() * rect.getHeight()));
-                    } else {
-                        theCoords.addElement(
-                          new Double(currentYPosition / 1000f -
-                                     val.getValue()));
-                    }
-                    theCoords.addElement(new Double(0));
-                    val = afx.getBaseVal();
-                    if (val.getUnitType() ==
-                            SVGLength.SVG_LENGTHTYPE_PERCENTAGE ||
-                            gradUnits ==
-                            SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
-                        theCoords.addElement(
-                          new Double(currentXPosition / 1000f +
-                                     rect.getX() +
-                                     val.getValue() * rect.getWidth()));
-                    } else {
-                        theCoords.addElement(
-                          new Double(currentXPosition / 1000f +
-                                     val.getValue()));
-                    }
-                    val = afy.getBaseVal();
-                    if (val.getUnitType() ==
-                            SVGLength.SVG_LENGTHTYPE_PERCENTAGE ||
-                            gradUnits ==
-                            SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
-                        theCoords.addElement(
-                          new Double(currentYPosition / 1000f -
-                                     rect.getY() -
-                                     val.getValue() * rect.getHeight()));
-                    } else {
-                        theCoords.addElement(
-                          new Double(currentYPosition / 1000f -
-                                     val.getValue()));
-                    }
-                    val = ar.getBaseVal();
-                    if (val.getUnitType() ==
-                            SVGLength.SVG_LENGTHTYPE_PERCENTAGE ||
-                            gradUnits ==
-                            SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
-                        theCoords.addElement( new Double(val.getValue() *
-                                                         rect.getHeight()));
-                    } else {
-                        theCoords.addElement(new Double(val.getValue()));
-                    }
-                }
-            }
-        }
-        if (theCoords == null) {
-            theCoords = new Vector();
-            theCoords.addElement( new Double(currentXPosition / 1000f +
-                                             acx.getBaseVal().getValue()));
-            theCoords.addElement( new Double(currentYPosition / 1000f -
-                                             acy.getBaseVal().getValue()));
-            theCoords.addElement(new Double(0));
-            theCoords.addElement( new Double(currentXPosition / 1000f +
-                                             afx.getBaseVal().getValue())); // Fx
-            theCoords.addElement(
-              new Double(currentYPosition / 1000f -
-                         afy.getBaseVal().getValue())); // Fy
-            theCoords.addElement(
-              new Double(ar.getBaseVal().getValue()));
-        }
-        float lastoffset = 0;
-        for (int count = 0; count < nl.getLength(); count++) {
-            stop = (SVGStopElementImpl) nl.item(count);
-            CSSValue cv = stop.getPresentationAttribute("stop-color");
-            if (cv == null) {
-                // maybe using color
-                cv = stop.getPresentationAttribute("color");
-            }
-            if (cv == null) {
-                // problems
-                MessageHandler.errorln("no stop-color or color in stop element");
-                continue;
-            }
-            PDFColor color = new PDFColor(0, 0, 0);
-            if (cv != null &&
-                    cv.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
-                if (((CSSPrimitiveValue) cv).getPrimitiveType() ==
-                        CSSPrimitiveValue.CSS_RGBCOLOR) {
-                    RGBColor col =
-                      ((CSSPrimitiveValue) cv).getRGBColorValue();
-                    CSSPrimitiveValue val;
-                    val = col.getRed();
-                    float red = val.getFloatValue(
-                                  CSSPrimitiveValue.CSS_NUMBER);
-                    val = col.getGreen();
-                    float green = val.getFloatValue(
-                                    CSSPrimitiveValue.CSS_NUMBER);
-                    val = col.getBlue();
-                    float blue = val.getFloatValue(
-                                   CSSPrimitiveValue.CSS_NUMBER);
-                    color = new PDFColor(red, green, blue);
-                }
-            }
-            float offset = stop.getOffset().getBaseVal();
-            // create bounds from last to offset
-            lastoffset = offset;
-            someColors.addElement(color);
-        }
-        PDFPattern myPat = this.pdfDoc.createGradient(true, aColorSpace,
-                           someColors, theBounds, theCoords);
-
-        currentStream.write(myPat.getColorSpaceOut(fill));
-        if (fill)
-            di.fill = true;
-        else
-            di.stroke = true;
-    }
-
-    /*
-     * This sets up the style for drawing objects.
-     * Should only set style for elements that have changes.
-     *
-     */
-    // need mask drawing
-    class DrawingInstruction {
-        boolean stroke = false;
-        boolean nonzero = false; // non-zero fill rule "f*", "B*" operator
-        boolean fill = false;
-        int linecap = 0; // butt
-        int linejoin = 0; // miter
-        int miterwidth = 8;
-    }
-    protected DrawingInstruction applyStyle(SVGElement area,
-                                            SVGStylable style) {
-        DrawingInstruction di = new DrawingInstruction();
-        CSSValue sp;
-        sp = style.getPresentationAttribute("fill");
-        if (sp != null) {
-            if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
-                if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
-                        CSSPrimitiveValue.CSS_RGBCOLOR) {
-                    RGBColor col =
-                      ((CSSPrimitiveValue) sp).getRGBColorValue();
-                    CSSPrimitiveValue val;
-                    val = col.getRed();
-                    float red = val.getFloatValue(
-                                  CSSPrimitiveValue.CSS_NUMBER);
-                    val = col.getGreen();
-                    float green = val.getFloatValue(
-                                    CSSPrimitiveValue.CSS_NUMBER);
-                    val = col.getBlue();
-                    float blue = val.getFloatValue(
-                                   CSSPrimitiveValue.CSS_NUMBER);
-                    PDFColor fillColour = new PDFColor(red, green, blue);
-                    currentColour = fillColour;
-                    currentStream.write(fillColour.getColorSpaceOut(true));
-                    di.fill = true;
-                } else if ( ((CSSPrimitiveValue) sp).getPrimitiveType() ==
-                    CSSPrimitiveValue.CSS_URI) {
-                    // gradient
-                    String str = ((CSSPrimitiveValue) sp).getCssText();
-                    handleGradient(str, di, true, area);
-                } else if ( ((CSSPrimitiveValue) sp).getPrimitiveType() ==
-                    CSSPrimitiveValue.CSS_STRING) {
-                    String str = ((CSSPrimitiveValue) sp).getCssText();
-                    if (str.equals("none")) {
-                        di.fill = false;
-                    } else if (str.equals("currentColor")) {
-                        currentStream.write(
-                          currentColour.getColorSpaceOut(true));
-                        di.fill = true;
-                        //                             } else {
-                        //                                     handleGradient(str, true, area);
-                    }
-                }
-            }
-        } else {
-            PDFColor fillColour = new PDFColor(0, 0, 0);
-            currentStream.write(fillColour.getColorSpaceOut(true));
-        }
-        sp = style.getPresentationAttribute("fill-rule");
-        if (sp != null) {
-            if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
-                if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
-                        CSSPrimitiveValue.CSS_STRING) {
-                    if (sp.getCssText().equals("nonzero")) {
-                        di.nonzero = true;
-                    }
-                }
-            }
-        } else {
-        }
-        sp = style.getPresentationAttribute("stroke");
-        if (sp != null) {
-            if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
-                if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
-                        CSSPrimitiveValue.CSS_RGBCOLOR) {
-                    RGBColor col =
-                      ((CSSPrimitiveValue) sp).getRGBColorValue();
-                    CSSPrimitiveValue val;
-                    val = col.getRed();
-                    float red = val.getFloatValue(
-                                  CSSPrimitiveValue.CSS_NUMBER);
-                    val = col.getGreen();
-                    float green = val.getFloatValue(
-                                    CSSPrimitiveValue.CSS_NUMBER);
-                    val = col.getBlue();
-                    float blue = val.getFloatValue(
-                                   CSSPrimitiveValue.CSS_NUMBER);
-                    PDFColor fillColour = new PDFColor(red, green, blue);
-                    currentStream.write(
-                      fillColour.getColorSpaceOut(false));
-                    di.stroke = true;
-                } else if ( ((CSSPrimitiveValue) sp).getPrimitiveType() ==
-                    CSSPrimitiveValue.CSS_URI) {
-                    // gradient
-                    String str = ((CSSPrimitiveValue) sp).getCssText();
-                    handleGradient(str, di, false, area);
-                } else if ( ((CSSPrimitiveValue) sp).getPrimitiveType() ==
-                    CSSPrimitiveValue.CSS_STRING) {
-                    String str = ((CSSPrimitiveValue) sp).getCssText();
-                    if (str.equals("none")) {
-                        di.stroke = false;
-                        //                             } else {
-                        //                                     handleGradient(str, false, area);
-                    }
-                }
-            }
-        } else {
-            PDFColor fillColour = new PDFColor(0, 0, 0);
-            currentStream.write(fillColour.getColorSpaceOut(false));
-        }
-        sp = style.getPresentationAttribute("stroke-linecap");
-        if (sp != null) {
-            if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
-                if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
-                        CSSPrimitiveValue.CSS_STRING) {
-                    String str = sp.getCssText();
-                    // butt, round ,square
-                    if (str.equals("butt")) {
-                        currentStream.write(0 + " J\n");
-                    } else if (str.equals("round")) {
-                        currentStream.write(1 + " J\n");
-                    } else if (str.equals("square")) {
-                        currentStream.write(2 + " J\n");
-                    }
-                }
-            }
-        } else {
-        }
-        sp = style.getPresentationAttribute("stroke-linejoin");
-        if (sp != null) {
-            if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
-                if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
-                        CSSPrimitiveValue.CSS_STRING) {
-                    String str = sp.getCssText();
-                    if (str.equals("miter")) {
-                        currentStream.write(0 + " j\n");
-                    } else if (str.equals("round")) {
-                        currentStream.write(1 + " j\n");
-                    } else if (str.equals("bevel")) {
-                        currentStream.write(2 + " j\n");
-                    }
-                }
-            }
-        } else {
-        }
-        sp = style.getPresentationAttribute("stroke-miterlimit");
-        if (sp != null) {
-            if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
-                float width;
-                width = ((CSSPrimitiveValue) sp).getFloatValue(
-                          CSSPrimitiveValue.CSS_PT);
-                PDFNumber pdfNumber = new PDFNumber();
-                currentStream.write(pdfNumber.doubleOut(width) + " M\n");
-            }
-        } else {
-        }
-        sp = style.getPresentationAttribute("stroke-width");
-        if (sp != null) {
-            if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
-                float width;
-                width = ((CSSPrimitiveValue) sp).getFloatValue(
-                          CSSPrimitiveValue.CSS_PT);
-                PDFNumber pdfNumber = new PDFNumber();
-                currentStream.write(pdfNumber.doubleOut(width) + " w\n");
-            }
-        }
-        sp = style.getPresentationAttribute("stroke-dasharray");
-        if (sp != null) {
-            if (sp.getValueType() == CSSValue.CSS_VALUE_LIST) {
-                currentStream.write("[ ");
-                CSSValueList list = (CSSValueList) sp;
-                for (int count = 0; count < list.getLength(); count++) {
-                    CSSValue val = list.item(count);
-                    if (val.getValueType() ==
-                            CSSValue.CSS_PRIMITIVE_VALUE) {
-                        currentStream.write(
-                          ((CSSPrimitiveValue) val).getFloatValue(
-                            CSSPrimitiveValue.CSS_NUMBER) + " ");
-                    }
-                }
-                currentStream.write("] ");
-                sp = style.getPresentationAttribute("stroke-dashoffset");
-                if (sp != null && sp.getValueType() ==
-                        CSSValue.CSS_PRIMITIVE_VALUE) {
-                    currentStream.write(
-                      ((CSSPrimitiveValue) sp).getFloatValue(
-                        CSSPrimitiveValue.CSS_NUMBER) + " d\n");
-                } else {
-                    currentStream.write("0 d\n");
-                }
-            }
-        }
-        sp = style.getPresentationAttribute("clip-path");
-        if (sp != null) {
-            String clipurl;
-            if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
-                if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
-                        CSSPrimitiveValue.CSS_URI) {
-                    clipurl = ((CSSPrimitiveValue) sp).getCssText();
-                    if (clipurl.startsWith("url(")) {
-                        int b1 = clipurl.indexOf("(");
-                        int b2 = clipurl.indexOf(")");
-                        clipurl = clipurl.substring(b1 + 1, b2);
-                    }
-                    // get def of mask and set mask
-                    SVGElement graph = null;
-                    graph = locateDef(clipurl, area);
-                    if (graph != null) {
-                        MessageHandler.logln("clip path: " + graph);
-                        // render the clip path elements and make it the clip
-                        // renderElement(svgarea, graph, posx, posy);
-                    }
-                }
-            }
-        }
-        sp = style.getPresentationAttribute("mask");
-        if (sp != null) {
-            String maskurl;
-            if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
-                if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
-                        CSSPrimitiveValue.CSS_URI) {
-                    maskurl = ((CSSPrimitiveValue) sp).getCssText();
-                    //                                 System.out.println("mask: " + maskurl);
-                    // get def of mask and set mask
-                    if (maskurl.startsWith("url(")) {
-                        int b1 = maskurl.indexOf("(");
-                        int b2 = maskurl.indexOf(")");
-                        maskurl = maskurl.substring(b1 + 1, b2);
-                    }
-                    SVGElement graph = null;
-                    graph = locateDef(maskurl, area);
-                    if (graph != null) {
-                        MessageHandler.logln("mask: " + graph);
-                        //                                             SVGElement parent = graph.getGraphicParent();
-                        //                                             graph.setParent(area);
-                        //                                             renderElement(svgarea, graph, posx, posy);
-                        //                                             graph.setParent(parent);
-                    }
-                }
-            }
-        }
-        return di;
-    }
-
-    protected void applyTransform(SVGAnimatedTransformList trans) {
-        PDFNumber pdfNumber = new PDFNumber();
-        SVGTransformList list = trans.getBaseVal();
-        for (int count = 0; count < list.getNumberOfItems(); count++) {
-            SVGMatrix matrix =
-              ((SVGTransform) list.getItem(count)).getMatrix();
-            currentStream.write(pdfNumber.doubleOut(matrix.getA()) +
-                                " " + pdfNumber.doubleOut(matrix.getB()) + " " +
-                                pdfNumber.doubleOut(matrix.getC()) + " " +
-                                pdfNumber.doubleOut(matrix.getD()) + " " +
-                                pdfNumber.doubleOut(matrix.getE()) + " " +
-                                pdfNumber.doubleOut(matrix.getF()) + " cm\n");
-        }
-    }
-
-    /**
-     * Main rendering selection.
-     * This applies any transform and style and then calls the appropriate
-     * rendering method depending on the type of element.
-     */
-    public void renderElement(SVGElement area, int posx, int posy) {
-        int x = posx;
-        int y = posy;
-        //             CSSStyleDeclaration style = null;
-        //             if(area instanceof SVGStylable)
-        //                     style = ((SVGStylable)area).getStyle();
-        DrawingInstruction di = null;
-
-        currentStream.write("q\n");
-        if (area instanceof SVGTransformable) {
-            SVGTransformable tf = (SVGTransformable) area;
-            SVGAnimatedTransformList trans = tf.getTransform();
-            if (trans != null) {
-                applyTransform(trans);
-            }
-        }
-
-        if (area instanceof SVGStylable) {
-            di = applyStyle(area, (SVGStylable) area);
-        }
-
-        if (area instanceof SVGRectElement) {
-            SVGRectElement rg = (SVGRectElement) area;
-            float rectx = rg.getX().getBaseVal().getValue();
-            float recty = rg.getY().getBaseVal().getValue();
-            float rx = rg.getRx().getBaseVal().getValue();
-            float ry = rg.getRy().getBaseVal().getValue();
-            float rw = rg.getWidth().getBaseVal().getValue();
-            float rh = rg.getHeight().getBaseVal().getValue();
-            addRect(rectx, recty, rw, rh, rx, ry, di);
-        } else if (area instanceof SVGLineElement) {
-            SVGLineElement lg = (SVGLineElement) area;
-            float x1 = lg.getX1().getBaseVal().getValue();
-            float y1 = lg.getY1().getBaseVal().getValue();
-            float x2 = lg.getX2().getBaseVal().getValue();
-            float y2 = lg.getY2().getBaseVal().getValue();
-            addLine(x1, y1, x2, y2, di);
-        } else if (area instanceof SVGTextElementImpl) {
-            //                 currentStream.add("q\n");
-            //                 currentStream.add(1 + " " + 0 + " " + 0 + " " + 1 + " " + 0 + " " + 0 + " cm\n");
-            currentStream.write("BT\n");
-            renderText((SVGTextElementImpl) area, 0, 0, di);
-            currentStream.write("ET\n");
-            //                 currentStream.add("Q\n");
-        } else if (area instanceof SVGCircleElement) {
-            SVGCircleElement cg = (SVGCircleElement) area;
-            float cx = cg.getCx().getBaseVal().getValue();
-            float cy = cg.getCy().getBaseVal().getValue();
-            float r = cg.getR().getBaseVal().getValue();
-            addCircle(cx, cy, r, di);
-        } else if (area instanceof SVGEllipseElement) {
-            SVGEllipseElement cg = (SVGEllipseElement) area;
-            float cx = cg.getCx().getBaseVal().getValue();
-            float cy = cg.getCy().getBaseVal().getValue();
-            float rx = cg.getRx().getBaseVal().getValue();
-            float ry = cg.getRy().getBaseVal().getValue();
-            addEllipse(cx, cy, rx, ry, di);
-        } else if (area instanceof SVGPathElementImpl) {
-            addPath(((SVGPathElementImpl) area).pathElements, posx,
-                    posy, di);
-        } else if (area instanceof SVGPolylineElementImpl) {
-            addPolyline(((SVGPolylineElementImpl) area).points, di, false);
-        } else if (area instanceof SVGPolygonElementImpl) {
-            addPolyline(((SVGPolygonElementImpl) area).points, di, true);
-        } else if (area instanceof SVGGElementImpl) {
-            renderGArea((SVGGElementImpl) area, x, y);
-        } else if (area instanceof SVGUseElementImpl) {
-            SVGUseElementImpl ug = (SVGUseElementImpl) area;
-            String ref = ug.link;
-            //                 ref = ref.substring(1, ref.length());
-            SVGElement graph = null;
-            graph = locateDef(ref, ug);
-            if (graph != null) {
-                // probably not the best way to do this, should be able
-                // to render without the style being set.
-                //                             SVGElement parent = graph.getGraphicParent();
-                //                             graph.setParent(area);
-                // need to clip (if necessary) to the use area
-                // the style of the linked element is as if it was
-                // a direct descendant of the use element.
-
-                // scale to the viewBox
-
-                if (graph instanceof SVGSymbolElement) {
-                    currentStream.write("q\n");
-                    SVGSymbolElement symbol = (SVGSymbolElement) graph;
-                    SVGRect view = symbol.getViewBox().getBaseVal();
-                    float usex = ug.getX().getBaseVal().getValue();
-                    float usey = ug.getY().getBaseVal().getValue();
-                    float usewidth = ug.getWidth().getBaseVal().getValue();
-                    float useheight =
-                      ug.getHeight().getBaseVal().getValue();
-                    float scaleX;
-                    float scaleY;
-                    scaleX = usewidth / view.getWidth();
-                    scaleY = useheight / view.getHeight();
-                    currentStream.write(usex + " " + usey + " m\n");
-                    currentStream.write((usex + usewidth) + " " +
-                                        usey + " l\n");
-                    currentStream.write((usex + usewidth) + " " +
-                                        (usey + useheight) + " l\n");
-                    currentStream.write(usex + " " +
-                                        (usey + useheight) + " l\n");
-                    currentStream.write("h\n");
-                    currentStream.write("W\n");
-                    currentStream.write("n\n");
-                    currentStream.write(scaleX + " 0 0 " + scaleY +
-                                        " " + usex + " " + usey + " cm\n");
-                    renderSymbol(symbol, posx, posy);
-                    currentStream.write("Q\n");
-                } else {
-                    renderElement(graph, posx, posy);
-                }
-                //                             graph.setParent(parent);
-            }
-            else {
-                MessageHandler.logln("Use Element: " + ref + " not found");
-            }
-        } else if (area instanceof SVGImageElementImpl) {
-            SVGImageElementImpl ig = (SVGImageElementImpl) area;
-            renderImage(ig.link, ig.x, ig.y, ig.width, ig.height);
-        } else if (area instanceof SVGSVGElement) {
-            currentStream.write("q\n");
-            SVGSVGElement svgel = (SVGSVGElement) area;
-            float svgx = 0;
-            if (svgel.getX() != null)
-                svgx = svgel.getX().getBaseVal().getValue();
-            float svgy = 0;
-            if (svgel.getY() != null)
-                svgy = svgel.getY().getBaseVal().getValue();
-            currentStream.write(1 + " 0 0 " + 1 + " " + svgx + " " +
-                                svgy + " cm\n");
-            renderSVG(svgel, (int)(x + 1000 * svgx),
-                      (int)(y + 1000 * svgy));
-            currentStream.write("Q\n");
-            //         } else if (area instanceof SVGSymbolElement) {
-            // 'symbol' element is not rendered (except by 'use')
-        } else if (area instanceof SVGAElement) {
-            SVGAElement ael = (SVGAElement) area;
-            org.w3c.dom.NodeList nl = ael.getChildNodes();
-            for (int count = 0; count < nl.getLength(); count++) {
-                org.w3c.dom.Node n = nl.item(count);
-                if (n instanceof SVGElement) {
-                    if (n instanceof GraphicElement) {
-                        SVGRect rect = ((GraphicElement) n).getBBox();
-                        if (rect != null) {
-                            /*                                                 currentAnnotList = this.pdfDoc.makeAnnotList();
-                                                                               currentPage.setAnnotList(currentAnnotList);
-                                                                               String dest = linkSet.getDest();
-                                                                               int linkType = linkSet.getLinkType();
-                                                                               currentAnnotList.addLink(
-                                                                                       this.pdfDoc.makeLink(lrect.getRectangle(), dest, linkType));
-                                                                               currentAnnotList = null;
-                             */ }
-                    }
-                    renderElement((SVGElement) n, posx, posy);
-                }
-            }
-        } else if (area instanceof SVGSwitchElement) {
-            handleSwitchElement(posx, posy, (SVGSwitchElement) area);
-        }
-        // should be done with some cleanup code, so only
-        // required values are reset.
-        currentStream.write("Q\n");
-    }
-
-    /**
-     * Todo: underline, linethrough, textpath
-     */
-    public void renderText(SVGTextElementImpl tg, float x, float y,
-                           DrawingInstruction di) {
-        SVGTextRenderer str = new SVGTextRenderer(fontState, tg, x, y);
-        if (di.fill) {
-            if (di.stroke) {
-                currentStream.write("2 Tr\n");
-            } else {
-                currentStream.write("0 Tr\n");
-            }
-        } else if (di.stroke) {
-            currentStream.write("1 Tr\n");
-        }
-        str.renderText(tg);
-    }
-
-    /**
-     * Adds an svg string to the output.
-     * This handles the escaping of special pdf chars and deals with
-     * whitespace.
-     */
-    protected float addSVGStr(FontState fs, float currentX, String str,
-                              boolean spacing) {
-        boolean inbetween = false;
-        boolean addedspace = false;
-        StringBuffer pdf = new StringBuffer();
-        for (int i = 0; i < str.length(); i++) {
-            char ch = str.charAt(i);
-            if (ch > 127) {
-                pdf = pdf.append("\\");
-                pdf = pdf.append(Integer.toOctalString((int) ch));
-                currentX += fs.width(ch) / 1000f;
-                inbetween = true;
-                addedspace = false;
-            } else {
-                switch (ch) {
-                    case '(' :
-                        pdf = pdf.append("\\(");
-                        currentX += fs.width(ch) / 1000f;
-                        inbetween = true;
-                        addedspace = false;
-                        break;
-                    case ')' :
-                        pdf = pdf.append("\\)");
-                        currentX += fs.width(ch) / 1000f;
-                        inbetween = true;
-                        addedspace = false;
-                        break;
-                    case '\\' :
-                        pdf = pdf.append("\\\\");
-                        currentX += fs.width(ch) / 1000f;
-                        inbetween = true;
-                        addedspace = false;
-                        break;
-                    case '\t':
-                    case ' ':
-                        if (spacing) {
-                            pdf = pdf.append(' ');
-                            currentX += fs.width(' ') / 1000f;
-                        } else {
-                            if (inbetween && !addedspace) {
-                                addedspace = true;
-                                pdf = pdf.append(' ');
-                                currentX += fs.width(' ') / 1000f;
-                            }
-                        }
-                        break;
-                    case '\n':
-                    case '\r':
-                        if (spacing) {
-                            pdf = pdf.append(' ');
-                            currentX += fs.width(' ') / 1000f;
-                        }
-                        break;
-                    default:
-                        addedspace = false;
-                        pdf = pdf.append(ch);
-                        currentX += fs.width(ch) / 1000f;
-                        inbetween = true;
-                        break;
-                }
-            }
-        }
-        currentStream.write(pdf.toString());
-        return currentX;
-    }
-
-    /**
-     * Locates a defined element in an svg document.
-     * Either gets the element defined by its "id" in the current
-     * SVGDocument, or if the uri reference is to an external
-     * document it loads the document and returns the element.
-     */
-    protected SVGElement locateDef(String ref, SVGElement currentElement) {
-        int pos;
-        ref = ref.trim();
-        pos = ref.indexOf("#");
-        if (pos == 0) {
-            // local doc
-            Document doc = currentElement.getOwnerDocument();
-            Element ele =
-              doc.getElementById(ref.substring(1, ref.length()));
-            if (ele instanceof SVGElement) {
-                return (SVGElement) ele;
-            }
-        } else if (pos != -1) {
-            String href = ref.substring(0, pos);
-            if (href.indexOf(":") == -1) {
-                href = "file:" + href;
-            }
-            try {
-                // this is really only to get a cached svg image
-                FopImage img = FopImageFactory.Make(href);
-                if (img instanceof SVGImage) {
-                    SVGDocument doc = ((SVGImage) img).getSVGDocument();
-                    Element ele = doc.getElementById(
-                                    ref.substring(pos + 1, ref.length()));
-                    if (ele instanceof SVGElement) {
-                        return (SVGElement) ele;
-                    }
-                }
-            } catch (Exception e) {
-                MessageHandler.errorln(e.toString());
-            }
-        }
-        return null;
-    }
-
-    /**
-     * This class is used to handle the rendering of svg text.
-     * This is so that it can deal with the recursive rendering
-     * of text markup, while keeping track of the state and position.
-     */
-    class SVGTextRenderer {
-        FontState fs;
-        String transstr;
-        float currentX;
-        float currentY;
-        float baseX;
-        float baseY;
-        SVGMatrix matrix;
-        float x;
-        float y;
-
-        SVGTextRenderer(FontState fontState, SVGTextElementImpl tg,
-                        float x, float y) {
-            fs = fontState;
-
-            PDFNumber pdfNumber = new PDFNumber();
-            SVGTransformList trans = tg.getTransform().getBaseVal();
-            matrix = trans.consolidate().getMatrix();
-            transstr = (pdfNumber.doubleOut(matrix.getA()) + " " +
-                        pdfNumber.doubleOut(matrix.getB()) + " " +
-                        pdfNumber.doubleOut(matrix.getC()) + " " +
-                        pdfNumber.doubleOut(-matrix.getD()) + " ");
-            this.x = x;
-            this.y = y;
-        }
-
-        void renderText(SVGTextElementImpl te) {
-            DrawingInstruction di = applyStyle(te, te);
-            if (di.fill) {
-                if (di.stroke) {
-                    currentStream.write("2 Tr\n");
-                } else {
-                    currentStream.write("0 Tr\n");
-                }
-            } else if (di.stroke) {
-                currentStream.write("1 Tr\n");
-            }
-            updateFont(te, fs);
-
-            float tx = te.x;
-            float ty = te.y;
-            currentX = x + tx;
-            currentY = y + ty;
-            baseX = currentX;
-            baseY = currentY;
-            NodeList nodel = te.getChildNodes();
-            //         Vector list = te.textList;
-            for (int count = 0; count < nodel.getLength(); count++) {
-                Object o = nodel.item(count);
-                applyStyle(te, te);
-                if (o instanceof CharacterData) {
-                    String str = ((CharacterData) o).getData();
-                    currentStream.write(transstr +
-                                        (currentX + matrix.getE()) + " " +
-                                        (baseY + matrix.getF()) + " Tm " + "(");
-                    boolean spacing = "preserve".equals(te.getXMLspace());
-                    currentX = addSVGStr(fs, currentX, str, spacing);
-                    currentStream.write(") Tj\n");
-                } else if (o instanceof SVGTextPathElementImpl) {
-                    SVGTextPathElementImpl tpg = (SVGTextPathElementImpl) o;
-                    String ref = tpg.str;
-                    SVGElement graph = null;
-                    graph = locateDef(ref, tpg);
-                    if (graph instanceof SVGPathElementImpl) {
-                        // probably not the best way to do this, should be able
-                        // to render without the style being set.
-                        //                                     GraphicImpl parent = graph.getGraphicParent();
-                        //                                     graph.setParent(tpg);
-                        // set text path??
-                        // how should this work
-                        //                                     graph.setParent(parent);
-                    }
-                } else if (o instanceof SVGTRefElementImpl) {
-                    SVGTRefElementImpl trg = (SVGTRefElementImpl) o;
-                    String ref = trg.ref;
-                    SVGElement element = locateDef(ref, trg);
-                    if (element instanceof SVGTextElementImpl) {
-                        //                                     GraphicImpl parent = graph.getGraphicParent();
-                        //                                     graph.setParent(trg);
-                        SVGTextElementImpl tele =
-                          (SVGTextElementImpl) element;
-                        // the style should be from tele, but it needs to be placed as a child
-                        // of trg to work
-                        di = applyStyle(trg, trg);
-                        if (di.fill) {
-                            if (di.stroke) {
-                                currentStream.write("2 Tr\n");
-                            } else {
-                                currentStream.write("0 Tr\n");
-                            }
-                        } else if (di.stroke) {
-                            currentStream.write("1 Tr\n");
-                        }
-                        boolean changed = false;
-                        FontState oldfs = fs;
-                        changed = updateFont(te, fs);
-                        NodeList nl = tele.getChildNodes();
-                        boolean spacing =
-                          "preserve".equals(trg.getXMLspace());
-                        renderTextNodes(spacing, nl,
-                                        trg.getX().getBaseVal(),
-                                        trg.getY().getBaseVal(),
-                                        trg.getDx().getBaseVal(),
-                                        trg.getDy().getBaseVal());
-
-                        if (changed) {
-                            fs = oldfs;
-                            currentStream.write("/" +
-                                                fs.getFontName() + " " +
-                                                fs.getFontSize() / 1000f + " Tf\n");
-                        }
-                        //                                     graph.setParent(parent);
-                    }
-                } else if (o instanceof SVGTSpanElementImpl) {
-                    SVGTSpanElementImpl tsg = (SVGTSpanElementImpl) o;
-                    applyStyle(tsg, tsg);
-                    boolean changed = false;
-                    FontState oldfs = fs;
-                    changed = updateFont(tsg, fs);
-                    boolean spacing = "preserve".equals(tsg.getXMLspace());
-                    renderTextNodes(spacing, tsg.getChildNodes(),
-                                    tsg.getX().getBaseVal(),
-                                    tsg.getY().getBaseVal(),
-                                    tsg.getDx().getBaseVal(),
-                                    tsg.getDy().getBaseVal());
-
-                    //                         currentX += fs.width(' ') / 1000f;
-                    if (changed) {
-                        fs = oldfs;
-                        currentStream.write("/" + fs.getFontName() +
-                                            " " + fs.getFontSize() / 1000f + " Tf\n");
-                    }
-                } else {
-                    MessageHandler.errorln("Error: unknown text element " + o);
-                }
-            }
-        }
-
-        void renderTextNodes(boolean spacing, NodeList nl,
-                             SVGLengthList xlist, SVGLengthList ylist,
-                             SVGLengthList dxlist, SVGLengthList dylist) {
-            boolean inbetween = false;
-            boolean addedspace = false;
-            int charPos = 0;
-            float xpos = currentX;
-            float ypos = currentY;
-
-            for (int count = 0; count < nl.getLength(); count++) {
-                Node n = nl.item(count);
-                if (n instanceof CharacterData) {
-                    StringBuffer pdf = new StringBuffer();
-                    String str = ((CharacterData) n).getData();
-                    for (int i = 0; i < str.length(); i++) {
-                        char ch = str.charAt(i);
-                        xpos = currentX;
-                        ypos = currentY;
-                        if (ylist.getNumberOfItems() > charPos) {
-                            ypos = baseY + (ylist.getItem(charPos)).
-                                   getValue();
-                        }
-                        if (dylist.getNumberOfItems() > charPos) {
-                            ypos = ypos + (dylist.getItem(charPos)).
-                                   getValue();
-                        }
-                        if (xlist.getNumberOfItems() > charPos) {
-                            xpos = baseX + (xlist.getItem(charPos)).
-                                   getValue();
-                        }
-                        if (dxlist.getNumberOfItems() > charPos) {
-                            xpos = xpos + (dxlist.getItem(charPos)).
-                                   getValue();
-                        }
-                        if (ch > 127) {
-                            pdf = pdf.append(transstr +
-                                             (xpos + matrix.getE()) + " " +
-                                             (ypos + matrix.getF()) + " Tm " +
-                                             "(" + "\\" +
-                                             Integer.toOctalString((int) ch) +
-                                             ") Tj\n");
-                            currentX = xpos + fs.width(ch) / 1000f;
-                            currentY = ypos;
-                            charPos++;
-                            inbetween = true;
-                            addedspace = false;
-                        } else {
-                            switch (ch) {
-                                case '(' :
-                                    pdf = pdf.append(transstr +
-                                                     (xpos + matrix.getE()) +
-                                                     " " + (ypos +
-                                                            matrix.getF()) + " Tm " +
-                                                     "(" + "\\(" + ") Tj\n");
-                                    currentX = xpos + fs.width(ch) / 1000f;
-                                    currentY = ypos;
-                                    charPos++;
-                                    inbetween = true;
-                                    addedspace = false;
-                                    break;
-                                case ')' :
-                                    pdf = pdf.append(transstr +
-                                                     (xpos + matrix.getE()) +
-                                                     " " + (ypos +
-                                                            matrix.getF()) + " Tm " +
-                                                     "(" + "\\)" + ") Tj\n");
-                                    currentX = xpos + fs.width(ch) / 1000f;
-                                    currentY = ypos;
-                                    charPos++;
-                                    inbetween = true;
-                                    addedspace = false;
-                                    break;
-                                case '\\' :
-                                    pdf = pdf.append(transstr +
-                                                     (xpos + matrix.getE()) +
-                                                     " " + (ypos +
-                                                            matrix.getF()) + " Tm " +
-                                                     "(" + "\\\\" + ") Tj\n");
-                                    currentX = xpos + fs.width(ch) / 1000f;
-                                    currentY = ypos;
-                                    charPos++;
-                                    inbetween = true;
-                                    addedspace = false;
-                                    break;
-                                case '\t':
-                                case ' ':
-                                    if (spacing) {
-                                        currentX = xpos + fs.width(' ') /
-                                                   1000f;
-                                        currentY = ypos;
-                                        charPos++;
-                                    } else {
-                                        if (inbetween && !addedspace) {
-                                            addedspace = true;
-                                            currentX = xpos + fs.width(' ')
-                                                       / 1000f;
-                                            currentY = ypos;
-                                            charPos++;
-                                        }
-                                    }
-                                    break;
-                                case '\n':
-                                case '\r':
-                                    if (spacing) {
-                                        currentX = xpos + fs.width(' ') /
-                                                   1000f;
-                                        currentY = ypos;
-                                        charPos++;
-                                    }
-                                    break;
-                                default:
-                                    addedspace = false;
-                                    pdf = pdf.append(transstr +
-                                                     (xpos + matrix.getE()) +
-                                                     " " + (ypos +
-                                                            matrix.getF()) + " Tm " +
-                                                     "(" + ch + ") Tj\n");
-                                    currentX = xpos + fs.width(ch) / 1000f;
-                                    currentY = ypos;
-                                    charPos++;
-                                    inbetween = true;
-                                    break;
-                            }
-                        }
-                        currentStream.write(pdf.toString());
-                    }
-                }
-            }
-        }
-
-        protected boolean updateFont(SVGStylable style, FontState fs) {
-            boolean changed = false;
-            String fontFamily = fs.getFontFamily();
-            CSSValue sp = style.getPresentationAttribute("font-family");
-            if (sp != null &&
-                    sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
-                if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
-                        CSSPrimitiveValue.CSS_STRING) {
-                    fontFamily = sp.getCssText();
-                }
-            }
-            if (!fontFamily.equals(fs.getFontFamily())) {
-                changed = true;
-            }
-            String fontStyle = fs.getFontStyle();
-            sp = style.getPresentationAttribute("font-style");
-            if (sp != null &&
-                    sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
-                if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
-                        CSSPrimitiveValue.CSS_STRING) {
-                    fontStyle = sp.getCssText();
-                }
-            }
-            if (!fontStyle.equals(fs.getFontStyle())) {
-                changed = true;
-            }
-            String fontWeight = fs.getFontWeight();
-            sp = style.getPresentationAttribute("font-weight");
-            if (sp != null &&
-                    sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
-                if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
-                        CSSPrimitiveValue.CSS_STRING) {
-                    fontWeight = sp.getCssText();
-                }
-            }
-            if (!fontWeight.equals(fs.getFontWeight())) {
-                changed = true;
-            }
-            float newSize = fs.getFontSize() / 1000f;
-            sp = style.getPresentationAttribute("font-size");
-            if (sp != null &&
-                    sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
-                //                 if(((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_NUMBER) {
-                newSize = ((CSSPrimitiveValue) sp).getFloatValue(
-                            CSSPrimitiveValue.CSS_PT);
-                //                 }
-            }
-            if (fs.getFontSize() / 1000f != newSize) {
-                changed = true;
-            }
-            if (changed) {
-                try {
-                    fs = new FontState(fs.getFontInfo(), fontFamily,
-                                       fontStyle, fontWeight, (int)(newSize * 1000));
-                } catch (Exception fope) {
-                }
-                this.fs = fs;
-
-                currentStream.write("/" + fs.getFontName() + " " +
-                                    newSize + " Tf\n");
-            } else {
-                if (!currentFontName.equals(fs.getFontName()) ||
-                        currentFontSize != fs.getFontSize()) {
-                    //                         currentFontName = fs.getFontName();
-                    //                         currentFontSize = fs.getFontSize();
-                    currentStream.write("/" + fs.getFontName() + " " +
-                                        (fs.getFontSize() / 1000) + " Tf\n");
-                }
-            }
-            return changed;
-        }
-    }
+                                                                                               double ry = vals[1];
+                                                                                               double theta = vals[2];
+                                                                                               boolean largearcflag = (vals[3] == 1.0);
+                                                                                               boolean sweepflag = (vals[4] == 1.0);
+
+                                                                                               double angle = Math.atan(vals[6] / vals[5]);
+                                                                                               double relangle = Math.atan(ry / rx);
+                                                                                               //                                      System.out.println((theta * Math.PI / 180f) + ":" + relangle + ":" + largearcflag + ":" + sweepflag);
+                                                                                               double absangle = (theta * Math.PI / 180f);//angle + relangle;
+                                                                                               // change sign depending on flags
+                                                                                               double contrx1;
+                                                                                               double contry1;
+                                                                                               double contrx2;
+                                                                                               double contry2;
+                                                                                               if (largearcflag) {
+                                                                                                               // in a large arc we need to do at least 2 and a bit
+                                                                                                               // segments or curves.
+                                                                                                               if (sweepflag) {
+                                                                                                                               contrx1 = lastx + rx * Math.cos(absangle);
+                                                                                                                               contry1 = lasty + rx * Math.sin(absangle);
+                                                                                                                               contrx2 = lastx + vals[5] +
+                                                                                                                                                                       ry * Math.cos(absangle);
+                                                                                                                               contry2 = lasty + vals[6] -
+                                                                                                                                                                       ry * Math.sin(absangle);
+                                                                                                               } else {
+                                                                                                                               contrx1 = lastx + rx * Math.sin(absangle);
+                                                                                                                               contry1 = lasty + rx * Math.cos(absangle);
+                                                                                                                               contrx2 = lastx + vals[5] +
+                                                                                                                                                                       ry * Math.cos(absangle);
+                                                                                                                               contry2 = lasty + vals[6] +
+                                                                                                                                                                       ry * Math.sin(absangle);
+                                                                                                               }
+                                                                                               } else {
+                                                                                                               // only need at most two segments
+                                                                                                               if (sweepflag) {
+                                                                                                                               contrx1 = lastx + rx * Math.cos(absangle);
+                                                                                                                               contry1 = lasty - rx * Math.sin(absangle);
+                                                                                                                               contrx2 = contrx1;
+                                                                                                                               contry2 = contry1;
+                                                                                                               } else {
+                                                                                                                               contrx1 = lastx - ry * Math.cos(absangle);
+                                                                                                                               contry1 = lasty + ry * Math.sin(absangle);
+                                                                                                                               contrx2 = contrx1;
+                                                                                                                               contry2 = contry1;
+                                                                                                               }
+                                                                                               }
+                                                                                               //System.out.println(contrx1 + ":" + contry1 + ":" + contrx2 + ":" + contry2);
+
+                                                                                               double cx = lastx;
+                                                                                               double cy = lasty;
+                                                                                               currentStream.write(pdfNumber.doubleOut(contrx1) + " " + pdfNumber.doubleOut(contry1) +
+                                                                                                                                                                               " " + pdfNumber.doubleOut(contrx2) + " " + pdfNumber.doubleOut(contry2) + " " +
+                                                                                                                                                                               pdfNumber.doubleOut(vals[5] + lastx) + " " +
+                                                                                                                                                                               pdfNumber.doubleOut(vals[6] + lasty) + " c\n");
+
+                                                                                               lastcx = 0; //??
+                                                                                               lastcy = 0; //??
+                                                                                               lastx += vals[5];
+                                                                                               lasty += vals[6];*/
+                                                                               }
+                                                                               break;
+                                                               case SVGPathSeg.PATHSEG_CLOSEPATH:
+                                                                               currentStream.write("h\n");
+                                                                               pathmoveto = null;
+                                                                               lastx = lastmovex;
+                                                                               lasty = lastmovey;
+                                                                               break;
+                                               }
+                               }
+                               doDrawing(di);
+               }
+
+               /**
+                * Calculate the last control point for a bezier curve.
+                * This is used to find the last control point for a curve where
+                * only the first control point is specified.
+                * The control point is a reflection of the first control point
+                * which results in an even smooth curve. The curve is symmetrical.
+                */
+               protected float[] calculateLastControl(float x1, float y1, float x2, float y2, float relx, float rely)
+               {
+                               float vals[] = new float[2];
+                               relx = -relx;
+                               rely = -rely;
+                               float dist = (float)Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
+                               float costheta = (float)(x2 - x1) / dist;
+                               float sinetheta = (float)(y2 - y1) / dist;
+                               float temp = relx;
+                               relx = relx * costheta + rely * sinetheta;
+                               rely = -temp * sinetheta + rely * costheta;
+                               relx = -relx;
+                               temp = relx;
+                               relx = relx * costheta - rely * sinetheta;
+                               rely = temp * sinetheta + rely * costheta;
+                               vals[0] = x2 - relx;
+                               vals[1] = y2 - rely;
+                               return vals;
+               }
+
+               /**
+                * Adds an SVG polyline or polygon.
+                * A polygon is merely a closed polyline.
+                * This is made up from a set of points that straight lines are drawn between.
+                */
+               protected void addPolyline(Vector points, DrawingInstruction di,
+                                                                                                                        boolean close) {
+                               PDFNumber pdfNumber = new PDFNumber();
+                               PathPoint pc;
+                               float lastx = 0;
+                               float lasty = 0;
+                               Enumeration e = points.elements();
+                               if (e.hasMoreElements()) {
+                                               pc = (PathPoint) e.nextElement();
+                                               lastx = pc.x;
+                                               lasty = pc.y;
+                                               currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " m\n");
+                               }
+                               while (e.hasMoreElements()) {
+                                               pc = (PathPoint) e.nextElement();
+                                               lastx = pc.x;
+                                               lasty = pc.y;
+                                               currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " l\n");
+                               }
+                               if (close)
+                                               currentStream.write("h\n");
+                               doDrawing(di);
+               }
+
+               /**
+                * Writes the drawing instruction out to the current stream
+                * depending on what type of drawing is required.
+                */
+               protected void doDrawing(DrawingInstruction di) {
+                               if (di == null) {
+                                               currentStream.write("S\n");
+                               } else {
+                                               if (di.fill) {
+                                                               if (di.stroke) {
+                                                                               if (!di.nonzero)
+                                                                                               currentStream.write("B*\n");
+                                                                               else
+                                                                                               currentStream.write("B\n");
+                                                               } else {
+                                                                               if (!di.nonzero)
+                                                                                               currentStream.write("f*\n");
+                                                                               else
+                                                                                               currentStream.write("f\n");
+                                                               }
+                                               } else {
+                                                               //                              if(di.stroke)
+                                                               currentStream.write("S\n");
+                                               }
+                               }
+               }
+
+               /**
+                * Renders an svg image to the current stream.
+                * This uses the FopImageFactory to load the image and then renders it.
+                */
+               public void renderImage(String href, float x, float y, float width,
+                                                                                                               float height) {
+                               try {
+                                               if (href.indexOf(":") == -1) {
+                                                               href = "file:" + href;
+                                               }
+                                               FopImage img = FopImageFactory.Make(href);
+                                               PDFNumber pdfNumber = new PDFNumber();
+                                               if (img instanceof SVGImage) {
+                                                               SVGSVGElement svg =
+                                                                       ((SVGImage) img).getSVGDocument().getRootElement();
+                                                               currentStream.write("q\n" + pdfNumber.doubleOut(width /
+                                                                                                                                               svg.getWidth().getBaseVal().getValue()) + " 0 0 " +
+                                                                                                                                               pdfNumber.doubleOut(height /
+                                                                                                                                               svg.getHeight().getBaseVal().getValue()) + " 0 0 cm\n");
+                                                               renderSVG(svg, (int) x * 1000, (int) y * 1000);
+                                                               currentStream.write("Q\n");
+                                                               //                              renderSVG(svg);
+                                               } else if (img != null) {
+                                                               int xObjectNum = this.pdfDoc.addImage(img);
+                                                               currentStream.write("q\n1 0 0 -1 0 " +
+                                                                                                                                               pdfNumber.doubleOut(2 * y + height) + " cm\n" + pdfNumber.doubleOut(width) + " 0 0 " +
+                                                                                                                                               pdfNumber.doubleOut(height) + " " + pdfNumber.doubleOut(x) + " " + pdfNumber.doubleOut(y) + " cm\n" + "/Im" +
+                                                                                                                                               xObjectNum + " Do\nQ\n");
+                                                               //                              img.close();
+                                               }
+                               } catch (Exception e) {
+                                               MessageHandler.errorln("could not add image to SVG: " + href);
+                               }
+               }
+
+               /**
+                * A symbol has a viewbox and preserve aspect ratio.
+                */
+               protected void renderSymbol(SVGSymbolElement symbol, int x, int y) {
+                               NodeList nl = symbol.getChildNodes();
+                               for (int count = 0; count < nl.getLength(); count++) {
+                                               Node n = nl.item(count);
+                                               if (n instanceof SVGElement) {
+                                                               renderElement((SVGElement) n, x, y);
+                                               }
+                               }
+               }
+
+               /**
+                * Handles the construction of an SVG gradient.
+                * This gets the gradient element and creates the pdf info
+                * in the pdf document.
+                * The type of gradient is determined by what class the gradient element is.
+                */
+               protected void handleGradient(String sp, DrawingInstruction di,
+                                                                                                                                       boolean fill, SVGElement area) {
+                               // should be a url to a gradient
+                               String url = (String) sp;
+                               if (url.startsWith("url(")) {
+                                               String address;
+                                               int b1 = url.indexOf("(");
+                                               int b2 = url.indexOf(")");
+                                               address = url.substring(b1 + 1, b2);
+                                               SVGElement gi = null;
+                                               gi = locateDef(address, area);
+                                               if (gi instanceof SVGLinearGradientElement) {
+                                                               SVGLinearGradientElement linear =
+                                                                       (SVGLinearGradientElement) gi;
+                                                               handleLinearGradient(linear, di, fill, area);
+                                               } else if (gi instanceof SVGRadialGradientElement) {
+                                                               SVGRadialGradientElement radial =
+                                                                       (SVGRadialGradientElement) gi;
+                                                               handleRadialGradient(radial, di, fill, area);
+                                               } else if (gi instanceof SVGPatternElement) {
+                                                               SVGPatternElement pattern = (SVGPatternElement) gi;
+                                                               handlePattern(pattern, di, fill, area);
+                                               } else {
+                                                               MessageHandler.errorln("WARNING Invalid fill reference :" +
+                                                                                                                                        gi + ":" + address);
+                                               }
+                               }
+               }
+
+               protected void handlePattern(SVGPatternElement pattern,
+                                                                                                                                DrawingInstruction di, boolean fill, SVGElement area) {
+                               SVGAnimatedLength x, y, width, height;
+                               short pattUnits = SVGUnitTypes.SVG_UNIT_TYPE_UNKNOWN;
+                               NodeList stops = null;
+                               x = pattern.getX();
+                               y = pattern.getY();
+                               width = pattern.getWidth();
+                               height = pattern.getHeight();
+                               NodeList nl = pattern.getChildNodes();
+                               SVGPatternElement ref = (SVGPatternElement) locateDef(
+                                                                                                                                       pattern.getHref().getBaseVal(), pattern);
+                               while (ref != null) {
+                                               if (x == null) {
+                                                               x = ref.getX();
+                                                               pattUnits = ref.getPatternUnits().getBaseVal();
+                                               }
+                                               if (y == null) {
+                                                               y = ref.getY();
+                                               }
+                                               if (width == null) {
+                                                               width = ref.getWidth();
+                                               }
+                                               if (height == null) {
+                                                               height = ref.getHeight();
+                                               }
+                                               if (nl.getLength() == 0) {
+                                                               nl = ref.getChildNodes();
+                                               }
+                                               ref = (SVGPatternElement) locateDef(
+                                                                               ref.getHref().getBaseVal(), ref);
+                               }
+                               if (x == null) {
+                                               SVGLength length = new SVGLengthImpl();
+                                               length.newValueSpecifiedUnits(
+                                                       SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0);
+                                               x = new SVGAnimatedLengthImpl(length);
+                               }
+                               if (y == null) {
+                                               SVGLength length = new SVGLengthImpl();
+                                               length.newValueSpecifiedUnits(
+                                                       SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0);
+                                               y = new SVGAnimatedLengthImpl(length);
+                               }
+                               if (width == null) {
+                                               SVGLength length = new SVGLengthImpl();
+                                               length.newValueSpecifiedUnits(
+                                                       SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 1);
+                                               width = new SVGAnimatedLengthImpl(length);
+                               }
+                               if (height == null) {
+                                               SVGLength length = new SVGLengthImpl();
+                                               length.newValueSpecifiedUnits(
+                                                       SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 1);
+                                               height = new SVGAnimatedLengthImpl(length);
+                               }
+
+                               StringWriter realStream = currentStream;
+                               currentStream = new StringWriter();
+
+                               currentStream.write("q\n");
+                               // this makes the pattern the right way up, since it is outside the original
+                               // transform around the whole svg document
+                               currentStream.write("1 0 0 -1 0 " +
+                                                                                                               height.getBaseVal().getValue() + " cm\n");
+                               for (int count = 0; count < nl.getLength(); count++) {
+                                               Node n = nl.item(count);
+                                               if (n instanceof SVGElement) {
+                                                               renderElement((SVGElement) n, 0, 0);
+                                               }
+                               }
+                               currentStream.write("Q\n");
+
+                               double xval = x.getBaseVal().getValue() + currentXPosition / 1000f;
+                               double yval = -y.getBaseVal().getValue() + currentYPosition / 1000f;
+                               if (area instanceof GraphicElement) {
+                                               SVGRect bbox = ((GraphicElement) area).getBBox();
+                                               if (bbox != null) {
+                                                               //                      xval += bbox.getX();
+                                                               //                      yval -= bbox.getY();
+                                               }
+                               }
+                               double widthval = width.getBaseVal().getValue();
+                               double heightval = height.getBaseVal().getValue();
+                               Vector bbox = new Vector();
+                               bbox.addElement(new Double(0));
+                               bbox.addElement(new Double(0));
+                               bbox.addElement(new Double(widthval));
+                               bbox.addElement(new Double(heightval));
+                               Vector translate = new Vector();
+                               // combine with pattern transform
+                               translate.addElement(new Double(1));
+                               translate.addElement(new Double(0));
+                               translate.addElement(new Double(0));
+                               translate.addElement(new Double(1));
+                               translate.addElement(new Double(xval));
+                               translate.addElement(new Double(yval));
+                               // need to handle PDFResources
+                               PDFPattern myPat =
+                                       this.pdfDoc.makePattern(1, null, 1, 1, bbox, widthval,
+                                                                                                                                       heightval, translate, null, currentStream.getBuffer());
+
+                               currentStream = realStream;
+                               currentStream.write(myPat.getColorSpaceOut(fill));
+                               if (fill)
+                                               di.fill = true;
+                               else
+                                               di.stroke = true;
+               }
+
+               protected void handleLinearGradient(
+                       SVGLinearGradientElement linear, DrawingInstruction di,
+                       boolean fill, SVGElement area) {
+                               // first get all the gradient values
+                               // if values not present follow the href
+                               // the gradient units will be where the vals are specified
+                               // the spread method will be where there are stop elements
+                               SVGAnimatedLength ax1, ax2, ay1, ay2;
+                               short spread = SVGGradientElement.SVG_SPREADMETHOD_UNKNOWN;
+                               short gradUnits = SVGUnitTypes.SVG_UNIT_TYPE_UNKNOWN;
+                               NodeList stops = null;
+                               ax1 = linear.getX1();
+                               ax2 = linear.getX2();
+                               ay1 = linear.getY1();
+                               ay2 = linear.getY2();
+                               stops = linear.getChildNodes();
+                               SVGLinearGradientElement ref = (SVGLinearGradientElement) locateDef(
+                                                                                                                                                                linear.getHref().getBaseVal(), linear);
+                               while (ref != null) {
+                                               if (ax1 == null) {
+                                                               ax1 = ref.getX1();
+                                                               gradUnits = ref.getGradientUnits().getBaseVal();
+                                               }
+                                               if (ax2 == null) {
+                                                               ax2 = ref.getX2();
+                                               }
+                                               if (ay1 == null) {
+                                                               ay1 = ref.getY1();
+                                               }
+                                               if (ay2 == null) {
+                                                               ay2 = ref.getY2();
+                                               }
+                                               if (stops.getLength() == 0) {
+                                                               stops = ref.getChildNodes();
+                                               }
+                                               ref = (SVGLinearGradientElement) locateDef(
+                                                                               ref.getHref().getBaseVal(), ref);
+                               }
+                               if (ax1 == null) {
+                                               SVGLength length = new SVGLengthImpl();
+                                               length.newValueSpecifiedUnits(
+                                                       SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0);
+                                               ax1 = new SVGAnimatedLengthImpl(length);
+                               }
+                               if (ax2 == null) {
+                                               // if x2 is not specified then it should be 100%
+                                               SVGLength length = new SVGLengthImpl();
+                                               length.newValueSpecifiedUnits(
+                                                       SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 1);
+                                               ax2 = new SVGAnimatedLengthImpl(length);
+                               }
+                               if (ay1 == null) {
+                                               SVGLength length = new SVGLengthImpl();
+                                               length.newValueSpecifiedUnits(
+                                                       SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0);
+                                               ay1 = new SVGAnimatedLengthImpl(length);
+                               }
+                               if (ay2 == null) {
+                                               SVGLength length = new SVGLengthImpl();
+                                               length.newValueSpecifiedUnits(
+                                                       SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0);
+                                               ay2 = new SVGAnimatedLengthImpl(length);
+                               }
+                               SVGAnimatedTransformList an = linear.getGradientTransform();
+                               SVGMatrix transform = null;
+                               if(an != null)
+                                               transform = an.getBaseVal().consolidate().getMatrix();
+                               Vector theCoords = null;
+                               if (gradUnits == SVGUnitTypes.SVG_UNIT_TYPE_UNKNOWN)
+                                               gradUnits = linear.getGradientUnits().getBaseVal();
+                               // spread: pad (normal), reflect, repeat
+                               spread = linear.getSpreadMethod().getBaseVal();
+                               if (gradUnits == SVGUnitTypes.SVG_UNIT_TYPE_USERSPACEONUSE) {
+                                               if (area instanceof SVGTransformable) {
+                                                               SVGTransformable tf = (SVGTransformable) area;
+                                                               double x1, y1, x2, y2;
+                                                               x1 = ax1.getBaseVal().getValue();
+                                                               y1 = -ay1.getBaseVal().getValue();
+                                                               x2 = ax2.getBaseVal().getValue();
+                                                               y2 = -ay2.getBaseVal().getValue();
+                                                               SVGMatrix matrix = tf.getScreenCTM();
+                                                               if(transform != null)
+                                                                               matrix = matrix.multiply(transform);
+                                                               double oldx = x1;
+                                                               x1 = matrix.getA() * x1 + matrix.getC() * y1 +
+                                                                                matrix.getE();
+                                                               y1 = matrix.getB() * oldx + matrix.getD() * y1 -
+                                                                                matrix.getF();
+                                                               oldx = x2;
+                                                               x2 = matrix.getA() * x2 + matrix.getC() * y2 +
+                                                                                matrix.getE();
+                                                               y2 = matrix.getB() * oldx + matrix.getD() * y2 -
+                                                                                matrix.getF();
+                                                               theCoords = new Vector();
+                                                               if (spread == SVGGradientElement.SVG_SPREADMETHOD_REFLECT) {
+                                                               } else if (spread ==
+                                                                               SVGGradientElement.SVG_SPREADMETHOD_REFLECT) {
+                                                               } else {
+                                                                               theCoords.addElement(
+                                                                                       new Double(currentXPosition / 1000f + x1));
+                                                                               theCoords.addElement(
+                                                                                       new Double(currentYPosition / 1000f + y1));
+                                                                               theCoords.addElement(
+                                                                                       new Double(currentXPosition / 1000f + x2));
+                                                                               theCoords.addElement(
+                                                                                       new Double(currentYPosition / 1000f + y2));
+                                                               }
+                                               }
+                               } else if (area instanceof GraphicElement) {
+                                               SVGRect rect = ((GraphicElement) area).getBBox();
+                                               if (rect != null) {
+                                                               theCoords = new Vector();
+                                                               SVGLength val;
+                                                               val = ax1.getBaseVal();
+                                                               if (val.getUnitType() ==
+                                                                                               SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
+                                                                                               SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+                                                                               theCoords.addElement(
+                                                                                       new Double(currentXPosition / 1000f +
+                                                                                                                                rect.getX() +
+                                                                                                                                val.getValue() * rect.getWidth()));
+                                                               } else {
+                                                                               theCoords.addElement(
+                                                                                       new Double(currentXPosition / 1000f +
+                                                                                                                                val.getValue()));
+                                                               }
+                                                               val = ay1.getBaseVal();
+                                                               if (val.getUnitType() ==
+                                                                                               SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
+                                                                                               SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+                                                                               theCoords.addElement(
+                                                                                       new Double(currentYPosition / 1000f -
+                                                                                                                                rect.getY() -
+                                                                                                                                val.getValue() * rect.getHeight()));
+                                                               } else {
+                                                                               theCoords.addElement(
+                                                                                       new Double(currentYPosition / 1000f -
+                                                                                                                                val.getValue()));
+                                                               }
+                                                               val = ax2.getBaseVal();
+                                                               if (val.getUnitType() ==
+                                                                                               SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
+                                                                                               SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+                                                                               theCoords.addElement(
+                                                                                       new Double(currentXPosition / 1000f +
+                                                                                                                                rect.getX() +
+                                                                                                                                val.getValue() * rect.getWidth()));
+                                                               } else {
+                                                                               theCoords.addElement(
+                                                                                       new Double(currentXPosition / 1000f +
+                                                                                                                                val.getValue()));
+                                                               }
+                                                               val = ay2.getBaseVal();
+                                                               if (val.getUnitType() ==
+                                                                                               SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
+                                                                                               SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+                                                                               theCoords.addElement(
+                                                                                       new Double(currentYPosition / 1000f -
+                                                                                                                                rect.getY() -
+                                                                                                                                val.getValue() * rect.getHeight()));
+                                                               } else {
+                                                                               theCoords.addElement(
+                                                                                       new Double(currentYPosition / 1000f -
+                                                                                                                                val.getValue()));
+                                                               }
+                                               }
+                               }
+                               if (theCoords == null) {
+                                               theCoords = new Vector();
+                                               theCoords.addElement( new Double(currentXPosition / 1000f +
+                                                                                                                                                                                ax1.getBaseVal().getValue()));
+                                               theCoords.addElement( new Double(currentYPosition / 1000f -
+                                                                                                                                                                                ay1.getBaseVal().getValue()));
+                                               theCoords.addElement( new Double(currentXPosition / 1000f +
+                                                                                                                                                                                ax2.getBaseVal().getValue()));
+                                               theCoords.addElement( new Double(currentYPosition / 1000f -
+                                                                                                                                                                                ay2.getBaseVal().getValue()));
+                               }
+
+                               Vector theExtend = new Vector();
+                               theExtend.addElement(new Boolean(true));
+                               theExtend.addElement(new Boolean(true));
+
+                               Vector theDomain = new Vector();
+                               theDomain.addElement(new Double(0));
+                               theDomain.addElement(new Double(1));
+
+                               Vector theEncode = new Vector();
+                               theEncode.addElement(new Double(0));
+                               theEncode.addElement(new Double(1));
+                               theEncode.addElement(new Double(0));
+                               theEncode.addElement(new Double(1));
+
+                               Vector theBounds = new Vector();
+                               theBounds.addElement(new Double(0));
+                               theBounds.addElement(new Double(1));
+
+                               Vector theFunctions = new Vector();
+
+                               NodeList nl = stops;
+                               Vector someColors = new Vector();
+                               float lastoffset = 0;
+                               Vector lastVector = null;
+                               SVGStopElementImpl stop;
+                               if (nl.getLength() == 0) {
+                                               // the color should be "none"
+                                               if (fill)
+                                                               di.fill = false;
+                                               else
+                                                               di.stroke = false;
+                                               return;
+                               } else if (nl.getLength() == 1) {
+                                               stop = (SVGStopElementImpl) nl.item(0);
+                                               CSSValue cv = stop.getPresentationAttribute("stop-color");
+                                               if (cv == null) {
+                                                               // maybe using color
+                                                               cv = stop.getPresentationAttribute("color");
+                                               }
+                                               if (cv == null) {
+                                                               // problems
+                                                               MessageHandler.errorln("no stop-color or color in stop element");
+                                                               return;
+                                               }
+                                               PDFColor color = new PDFColor(0, 0, 0);
+                                               if (cv != null &&
+                                                                               cv.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+                                                               if (((CSSPrimitiveValue) cv).getPrimitiveType() ==
+                                                                                               CSSPrimitiveValue.CSS_RGBCOLOR) {
+                                                                               RGBColor col =
+                                                                                       ((CSSPrimitiveValue) cv).getRGBColorValue();
+                                                                               CSSPrimitiveValue val;
+                                                                               val = col.getRed();
+                                                                               float red = val.getFloatValue(
+                                                                                                                                       CSSPrimitiveValue.CSS_NUMBER);
+                                                                               val = col.getGreen();
+                                                                               float green = val.getFloatValue(
+                                                                                                                                               CSSPrimitiveValue.CSS_NUMBER);
+                                                                               val = col.getBlue();
+                                                                               float blue = val.getFloatValue(
+                                                                                                                                        CSSPrimitiveValue.CSS_NUMBER);
+                                                                               color = new PDFColor(red, green, blue);
+                                                               }
+                                               }
+                                               currentStream.write(color.getColorSpaceOut(fill));
+                                               if (fill)
+                                                               di.fill = true;
+                                               else
+                                                               di.stroke = true;
+                                               return;
+                               }
+                               for (int count = 0; count < nl.getLength(); count++) {
+                                               stop = (SVGStopElementImpl) nl.item(count);
+                                               CSSValue cv = stop.getPresentationAttribute("stop-color");
+                                               if (cv == null) {
+                                                               // maybe using color
+                                                               cv = stop.getPresentationAttribute("color");
+                                               }
+                                               if (cv == null) {
+                                                               // problems
+                                                               MessageHandler.errorln("no stop-color or color in stop element");
+                                                               continue;
+                                               }
+                                               PDFColor color = new PDFColor(0, 0, 0);
+                                               if (cv != null &&
+                                                                               cv.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+                                                               if (((CSSPrimitiveValue) cv).getPrimitiveType() ==
+                                                                                               CSSPrimitiveValue.CSS_RGBCOLOR) {
+                                                                               RGBColor col =
+                                                                                       ((CSSPrimitiveValue) cv).getRGBColorValue();
+                                                                               CSSPrimitiveValue val;
+                                                                               val = col.getRed();
+                                                                               float red = val.getFloatValue(
+                                                                                                                                       CSSPrimitiveValue.CSS_NUMBER);
+                                                                               val = col.getGreen();
+                                                                               float green = val.getFloatValue(
+                                                                                                                                               CSSPrimitiveValue.CSS_NUMBER);
+                                                                               val = col.getBlue();
+                                                                               float blue = val.getFloatValue(
+                                                                                                                                        CSSPrimitiveValue.CSS_NUMBER);
+                                                                               color = new PDFColor(red, green, blue);
+                                                                               currentColour = color;
+                                                               }
+                                               }
+                                               float offset = stop.getOffset().getBaseVal();
+                                               Vector colVector = color.getVector();
+                                               // create bounds from last to offset
+                                               if (lastVector != null) {
+                                                               Vector theCzero = lastVector;
+                                                               Vector theCone = colVector;
+                                                               PDFFunction myfunc =
+                                                                       this.pdfDoc.makeFunction(2, theDomain, null,
+                                                                                                                                                                        theCzero, theCone, 1.0);
+                                                               theFunctions.addElement(myfunc);
+                                               }
+                                               lastoffset = offset;
+                                               lastVector = colVector;
+                                               someColors.addElement(color);
+                               }
+                               ColorSpace aColorSpace = new ColorSpace(ColorSpace.DEVICE_RGB);
+                               /*                              PDFFunction myfunky = this.pdfDoc.makeFunction(3,
+                                                       theDomain, null,
+                                                       theFunctions, null,
+                                                       theEncode);
+                                               PDFShading myShad = null;
+                                               myShad = this.pdfDoc.makeShading(
+                                                       2, aColorSpace,
+                                                       null, null, false,
+                                                       theCoords, null, myfunky,theExtend);
+                                               PDFPattern myPat = this.pdfDoc.makePattern(2, myShad, null, null, null);*/
+                               PDFPattern myPat = this.pdfDoc.createGradient(false, aColorSpace,
+                                                                                                        someColors, null, theCoords);
+                               currentStream.write(myPat.getColorSpaceOut(fill));
+                               if (fill)
+                                               di.fill = true;
+                               else
+                                               di.stroke = true;
+               }
+
+               protected void handleRadialGradient(
+                       SVGRadialGradientElement radial, DrawingInstruction di,
+                       boolean fill, SVGElement area) {
+                               // first get all the gradient values
+                               // if values not present follow the href
+                               // the gradient units will be where the vals are specified
+                               SVGAnimatedLength acx, acy, ar, afx, afy;
+                               short gradUnits = radial.getGradientUnits().getBaseVal();
+                               NodeList stops = null;
+                               acx = radial.getCx();
+                               acy = radial.getCy();
+                               ar = radial.getR();
+                               afx = radial.getFx();
+                               afy = radial.getFy();
+                               stops = radial.getChildNodes();
+                               SVGRadialGradientElement ref = (SVGRadialGradientElement) locateDef(
+                                                                                                                                                                radial.getHref().getBaseVal(), radial);
+                               while (ref != null) {
+                                               if (acx == null) {
+                                                               acx = ref.getCx();
+                                                               gradUnits = ref.getGradientUnits().getBaseVal();
+                                               }
+                                               if (acy == null) {
+                                                               acy = ref.getCy();
+                                               }
+                                               if (ar == null) {
+                                                               ar = ref.getR();
+                                               }
+                                               if (afx == null) {
+                                                               afx = ref.getFx();
+                                               }
+                                               if (afy == null) {
+                                                               afy = ref.getFy();
+                                               }
+                                               if (stops.getLength() == 0) {
+                                                               stops = ref.getChildNodes();
+                                               }
+                                               ref = (SVGRadialGradientElement) locateDef(
+                                                                               ref.getHref().getBaseVal(), ref);
+                               }
+                               if (acx == null) {
+                                               SVGLength length = new SVGLengthImpl();
+                                               length.newValueSpecifiedUnits(
+                                                       SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0.5f);
+                                               acx = new SVGAnimatedLengthImpl(length);
+                               }
+                               if (acy == null) {
+                                               SVGLength length = new SVGLengthImpl();
+                                               length.newValueSpecifiedUnits(
+                                                       SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0.5f);
+                                               acy = new SVGAnimatedLengthImpl(length);
+                               }
+                               if (ar == null) {
+                                               SVGLength length = new SVGLengthImpl();
+                                               length.newValueSpecifiedUnits(
+                                                       SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 1);
+                                               ar = new SVGAnimatedLengthImpl(length);
+                               }
+                               if (afx == null) {
+                                               SVGLength length = new SVGLengthImpl();
+                                               length.newValueSpecifiedUnits(
+                                                       SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0.5f);
+                                               afx = new SVGAnimatedLengthImpl(length);
+                               }
+                               if (afy == null) {
+                                               SVGLength length = new SVGLengthImpl();
+                                               length.newValueSpecifiedUnits(
+                                                       SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0.5f);
+                                               afy = new SVGAnimatedLengthImpl(length);
+                               }
+                               ColorSpace aColorSpace = new ColorSpace(ColorSpace.DEVICE_RGB);
+                               org.w3c.dom.NodeList nl = stops;
+                               SVGStopElementImpl stop;
+                               if (nl.getLength() == 0) {
+                                               // the color should be "none"
+                                               if (fill)
+                                                               di.fill = false;
+                                               else
+                                                               di.stroke = false;
+                                               return;
+                               } else if (nl.getLength() == 1) {
+                                               stop = (SVGStopElementImpl) nl.item(0);
+                                               CSSValue cv = stop.getPresentationAttribute("stop-color");
+                                               if (cv == null) {
+                                                               // maybe using color
+                                                               cv = stop.getPresentationAttribute("color");
+                                               }
+                                               if (cv == null) {
+                                                               // problems
+                                                               MessageHandler.errorln("no stop-color or color in stop element");
+                                                               return;
+                                               }
+                                               PDFColor color = new PDFColor(0, 0, 0);
+                                               if (cv != null &&
+                                                                               cv.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+                                                               if (((CSSPrimitiveValue) cv).getPrimitiveType() ==
+                                                                                               CSSPrimitiveValue.CSS_RGBCOLOR) {
+                                                                               RGBColor col =
+                                                                                       ((CSSPrimitiveValue) cv).getRGBColorValue();
+                                                                               CSSPrimitiveValue val;
+                                                                               val = col.getRed();
+                                                                               float red = val.getFloatValue(
+                                                                                                                                       CSSPrimitiveValue.CSS_NUMBER);
+                                                                               val = col.getGreen();
+                                                                               float green = val.getFloatValue(
+                                                                                                                                               CSSPrimitiveValue.CSS_NUMBER);
+                                                                               val = col.getBlue();
+                                                                               float blue = val.getFloatValue(
+                                                                                                                                        CSSPrimitiveValue.CSS_NUMBER);
+                                                                               color = new PDFColor(red, green, blue);
+                                                               }
+                                               }
+                                               currentStream.write(color.getColorSpaceOut(fill));
+                                               if (fill)
+                                                               di.fill = true;
+                                               else
+                                                               di.stroke = true;
+                                               return;
+                               }
+                               Hashtable table = null;
+                               Vector someColors = new Vector();
+                               Vector theCoords = null;
+                               Vector theBounds = new Vector();
+                               // the coords should be relative to the current object
+                               // check value types, eg. %
+                               if (gradUnits == SVGUnitTypes.SVG_UNIT_TYPE_USERSPACEONUSE) {
+                                               if (area instanceof SVGTransformable) {
+                                                               SVGTransformable tf = (SVGTransformable) area;
+                                                               double x1, y1, x2, y2;
+                                                               x1 = acx.getBaseVal().getValue();
+                                                               y1 = -acy.getBaseVal().getValue();
+                                                               x2 = afx.getBaseVal().getValue();
+                                                               y2 = -afy.getBaseVal().getValue();
+                                                               SVGMatrix matrix = tf.getScreenCTM();
+                                                               double oldx = x1;
+                                                               x1 = matrix.getA() * x1 + matrix.getB() * y1 +
+                                                                                matrix.getE();
+                                                               y1 = matrix.getC() * oldx + matrix.getD() * y1 +
+                                                                                matrix.getF();
+                                                               oldx = x2;
+                                                               x2 = matrix.getA() * x2 + matrix.getB() * y2 +
+                                                                                matrix.getE();
+                                                               y2 = matrix.getC() * oldx + matrix.getD() * y2 +
+                                                                                matrix.getF();
+                                                               theCoords = new Vector();
+                                                               //                              if(spread == SVGGradientElement.SVG_SPREADMETHOD_REFLECT) {
+                                                               //                              } else if(spread== SVGGradientElement.SVG_SPREADMETHOD_REFLECT) {
+                                                               //                              } else {
+                                                               theCoords.addElement(
+                                                                       new Double(currentXPosition / 1000f + x1));
+                                                               // the y val needs to be adjust by 2 * R * rotation
+                                                               // depending on if this value is from an x or y coord
+                                                               // before transformation
+                                                               theCoords.addElement(
+                                                                       new Double(currentYPosition / 1000f - y1 +
+                                                                                                                (matrix.getC() - matrix.getD()) * 2 *
+                                                                                                                ar.getBaseVal().getValue()));
+                                                               theCoords.addElement(new Double(0));
+                                                               theCoords.addElement(
+                                                                       new Double(currentXPosition / 1000f + x2));
+                                                               theCoords.addElement(
+                                                                       new Double(currentYPosition / 1000f - y2 +
+                                                                                                                (matrix.getC() - matrix.getD()) * 2 *
+                                                                                                                ar.getBaseVal().getValue()));
+                                                               theCoords.addElement(
+                                                                       new Double(ar.getBaseVal().getValue()));
+                                                               //                              }
+                                               }
+                               } else if (gradUnits ==
+                                               SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX &&
+                                               area instanceof GraphicElement) {
+                                               SVGRect rect = ((GraphicElement) area).getBBox();
+                                               if (rect != null) {
+                                                               theCoords = new Vector();
+                                                               SVGLength val;
+                                                               val = acx.getBaseVal();
+                                                               if (val.getUnitType() ==
+                                                                                               SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
+                                                                                               SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+                                                                               theCoords.addElement(
+                                                                                       new Double(currentXPosition / 1000f +
+                                                                                                                                rect.getX() +
+                                                                                                                                val.getValue() * rect.getWidth()));
+                                                               } else {
+                                                                               theCoords.addElement(
+                                                                                       new Double(currentXPosition / 1000f +
+                                                                                                                                val.getValue()));
+                                                               }
+                                                               val = acy.getBaseVal();
+                                                               if (val.getUnitType() ==
+                                                                                               SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
+                                                                                               SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+                                                                               theCoords.addElement(
+                                                                                       new Double(currentYPosition / 1000f -
+                                                                                                                                rect.getY() -
+                                                                                                                                val.getValue() * rect.getHeight()));
+                                                               } else {
+                                                                               theCoords.addElement(
+                                                                                       new Double(currentYPosition / 1000f -
+                                                                                                                                val.getValue()));
+                                                               }
+                                                               theCoords.addElement(new Double(0));
+                                                               val = afx.getBaseVal();
+                                                               if (val.getUnitType() ==
+                                                                                               SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
+                                                                                               SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+                                                                               theCoords.addElement(
+                                                                                       new Double(currentXPosition / 1000f +
+                                                                                                                                rect.getX() +
+                                                                                                                                val.getValue() * rect.getWidth()));
+                                                               } else {
+                                                                               theCoords.addElement(
+                                                                                       new Double(currentXPosition / 1000f +
+                                                                                                                                val.getValue()));
+                                                               }
+                                                               val = afy.getBaseVal();
+                                                               if (val.getUnitType() ==
+                                                                                               SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
+                                                                                               SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+                                                                               theCoords.addElement(
+                                                                                       new Double(currentYPosition / 1000f -
+                                                                                                                                rect.getY() -
+                                                                                                                                val.getValue() * rect.getHeight()));
+                                                               } else {
+                                                                               theCoords.addElement(
+                                                                                       new Double(currentYPosition / 1000f -
+                                                                                                                                val.getValue()));
+                                                               }
+                                                               val = ar.getBaseVal();
+                                                               if (val.getUnitType() ==
+                                                                                               SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
+                                                                                               SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+                                                                               theCoords.addElement(
+                                                                                       new Double(val.getValue() * rect.getHeight()));
+                                                               } else {
+                                                                               theCoords.addElement(new Double(val.getValue()));
+                                                               }
+                                               }
+                               }
+                               if (theCoords == null) {
+                                               // percentage values are expressed according to the viewport.
+                                               SVGElement vp =
+                                                       ((GraphicElement) area).getNearestViewportElement();
+                                               if (area instanceof GraphicElement) {
+                                                               SVGRect rect = ((GraphicElement) area).getBBox();
+                                                               if (rect != null) {
+                                                                               theCoords = new Vector();
+                                                                               SVGLength val = acx.getBaseVal();
+                                                                               if (val.getUnitType() ==
+                                                                                                               SVGLength.SVG_LENGTHTYPE_PERCENTAGE ||
+                                                                                                               gradUnits ==
+                                                                                                               SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+                                                                                               theCoords.addElement(
+                                                                                                       new Double(currentXPosition / 1000f +
+                                                                                                                                                rect.getX() +
+                                                                                                                                                val.getValue() * rect.getWidth()));
+                                                                               } else {
+                                                                                               theCoords.addElement(
+                                                                                                       new Double(currentXPosition / 1000f +
+                                                                                                                                                val.getValue()));
+                                                                               }
+                                                                               val = acy.getBaseVal();
+                                                                               if (val.getUnitType() ==
+                                                                                                               SVGLength.SVG_LENGTHTYPE_PERCENTAGE ||
+                                                                                                               gradUnits ==
+                                                                                                               SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+                                                                                               theCoords.addElement(
+                                                                                                       new Double(currentYPosition / 1000f -
+                                                                                                                                                rect.getY() -
+                                                                                                                                                val.getValue() * rect.getHeight()));
+                                                                               } else {
+                                                                                               theCoords.addElement(
+                                                                                                       new Double(currentYPosition / 1000f -
+                                                                                                                                                val.getValue()));
+                                                                               }
+                                                                               theCoords.addElement(new Double(0));
+                                                                               val = afx.getBaseVal();
+                                                                               if (val.getUnitType() ==
+                                                                                                               SVGLength.SVG_LENGTHTYPE_PERCENTAGE ||
+                                                                                                               gradUnits ==
+                                                                                                               SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+                                                                                               theCoords.addElement(
+                                                                                                       new Double(currentXPosition / 1000f +
+                                                                                                                                                rect.getX() +
+                                                                                                                                                val.getValue() * rect.getWidth()));
+                                                                               } else {
+                                                                                               theCoords.addElement(
+                                                                                                       new Double(currentXPosition / 1000f +
+                                                                                                                                                val.getValue()));
+                                                                               }
+                                                                               val = afy.getBaseVal();
+                                                                               if (val.getUnitType() ==
+                                                                                                               SVGLength.SVG_LENGTHTYPE_PERCENTAGE ||
+                                                                                                               gradUnits ==
+                                                                                                               SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+                                                                                               theCoords.addElement(
+                                                                                                       new Double(currentYPosition / 1000f -
+                                                                                                                                                rect.getY() -
+                                                                                                                                                val.getValue() * rect.getHeight()));
+                                                                               } else {
+                                                                                               theCoords.addElement(
+                                                                                                       new Double(currentYPosition / 1000f -
+                                                                                                                                                val.getValue()));
+                                                                               }
+                                                                               val = ar.getBaseVal();
+                                                                               if (val.getUnitType() ==
+                                                                                                               SVGLength.SVG_LENGTHTYPE_PERCENTAGE ||
+                                                                                                               gradUnits ==
+                                                                                                               SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+                                                                                               theCoords.addElement( new Double(val.getValue() *
+                                                                                                                                                                                                                                rect.getHeight()));
+                                                                               } else {
+                                                                                               theCoords.addElement(new Double(val.getValue()));
+                                                                               }
+                                                               }
+                                               }
+                               }
+                               if (theCoords == null) {
+                                               theCoords = new Vector();
+                                               theCoords.addElement( new Double(currentXPosition / 1000f +
+                                                                                                                                                                                acx.getBaseVal().getValue()));
+                                               theCoords.addElement( new Double(currentYPosition / 1000f -
+                                                                                                                                                                                acy.getBaseVal().getValue()));
+                                               theCoords.addElement(new Double(0));
+                                               theCoords.addElement( new Double(currentXPosition / 1000f +
+                                                                                                                                                                                afx.getBaseVal().getValue())); // Fx
+                                               theCoords.addElement(
+                                                       new Double(currentYPosition / 1000f -
+                                                                                                afy.getBaseVal().getValue())); // Fy
+                                               theCoords.addElement(
+                                                       new Double(ar.getBaseVal().getValue()));
+                               }
+                               float lastoffset = 0;
+                               for (int count = 0; count < nl.getLength(); count++) {
+                                               stop = (SVGStopElementImpl) nl.item(count);
+                                               CSSValue cv = stop.getPresentationAttribute("stop-color");
+                                               if (cv == null) {
+                                                               // maybe using color
+                                                               cv = stop.getPresentationAttribute("color");
+                                               }
+                                               if (cv == null) {
+                                                               // problems
+                                                               MessageHandler.errorln("no stop-color or color in stop element");
+                                                               continue;
+                                               }
+                                               PDFColor color = new PDFColor(0, 0, 0);
+                                               if (cv != null &&
+                                                                               cv.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+                                                               if (((CSSPrimitiveValue) cv).getPrimitiveType() ==
+                                                                                               CSSPrimitiveValue.CSS_RGBCOLOR) {
+                                                                               RGBColor col =
+                                                                                       ((CSSPrimitiveValue) cv).getRGBColorValue();
+                                                                               CSSPrimitiveValue val;
+                                                                               val = col.getRed();
+                                                                               float red = val.getFloatValue(
+                                                                                                                                       CSSPrimitiveValue.CSS_NUMBER);
+                                                                               val = col.getGreen();
+                                                                               float green = val.getFloatValue(
+                                                                                                                                               CSSPrimitiveValue.CSS_NUMBER);
+                                                                               val = col.getBlue();
+                                                                               float blue = val.getFloatValue(
+                                                                                                                                        CSSPrimitiveValue.CSS_NUMBER);
+                                                                               color = new PDFColor(red, green, blue);
+                                                               }
+                                               }
+                                               float offset = stop.getOffset().getBaseVal();
+                                               // create bounds from last to offset
+                                               lastoffset = offset;
+                                               someColors.addElement(color);
+                               }
+                               PDFPattern myPat = this.pdfDoc.createGradient(true, aColorSpace,
+                                                                                                        someColors, theBounds, theCoords);
+
+                               currentStream.write(myPat.getColorSpaceOut(fill));
+                               if (fill)
+                                               di.fill = true;
+                               else
+                                               di.stroke = true;
+               }
+
+               /*
+                * This sets up the style for drawing objects.
+                * Should only set style for elements that have changes.
+                *
+                */
+               // need mask drawing
+               class DrawingInstruction {
+                               boolean stroke = false;
+                               boolean nonzero = false; // non-zero fill rule "f*", "B*" operator
+                               boolean fill = false;
+                               int linecap = 0; // butt
+                               int linejoin = 0; // miter
+                               int miterwidth = 8;
+               }
+               protected DrawingInstruction applyStyle(SVGElement area,
+                                                                                                                                                                               SVGStylable style) {
+                               DrawingInstruction di = new DrawingInstruction();
+                               CSSValue sp;
+                               sp = style.getPresentationAttribute("fill");
+                               if (sp != null) {
+                                               if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+                                                               if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
+                                                                                               CSSPrimitiveValue.CSS_RGBCOLOR) {
+                                                                               RGBColor col =
+                                                                                       ((CSSPrimitiveValue) sp).getRGBColorValue();
+                                                                               CSSPrimitiveValue val;
+                                                                               val = col.getRed();
+                                                                               float red = val.getFloatValue(
+                                                                                                                                       CSSPrimitiveValue.CSS_NUMBER);
+                                                                               val = col.getGreen();
+                                                                               float green = val.getFloatValue(
+                                                                                                                                               CSSPrimitiveValue.CSS_NUMBER);
+                                                                               val = col.getBlue();
+                                                                               float blue = val.getFloatValue(
+                                                                                                                                        CSSPrimitiveValue.CSS_NUMBER);
+                                                                               PDFColor fillColour = new PDFColor(red, green, blue);
+                                                                               currentColour = fillColour;
+                                                                               currentStream.write(fillColour.getColorSpaceOut(true));
+                                                                               di.fill = true;
+                                                               } else if ( ((CSSPrimitiveValue) sp).getPrimitiveType() ==
+                                                                               CSSPrimitiveValue.CSS_URI) {
+                                                                               // gradient
+                                                                               String str = ((CSSPrimitiveValue) sp).getCssText();
+                                                                               handleGradient(str, di, true, area);
+                                                               } else if ( ((CSSPrimitiveValue) sp).getPrimitiveType() ==
+                                                                               CSSPrimitiveValue.CSS_STRING) {
+                                                                               String str = ((CSSPrimitiveValue) sp).getCssText();
+                                                                               if (str.equals("none")) {
+                                                                                               di.fill = false;
+                                                                               } else if (str.equals("currentColor")) {
+                                                                                               currentStream.write(
+                                                                                                       currentColour.getColorSpaceOut(true));
+                                                                                               di.fill = true;
+                                                                                               //                              } else {
+                                                                                               //                                      handleGradient(str, true, area);
+                                                                               }
+                                                               }
+                                               }
+                               } else {
+                                               PDFColor fillColour = new PDFColor(0, 0, 0);
+                                               currentStream.write(fillColour.getColorSpaceOut(true));
+                               }
+                               sp = style.getPresentationAttribute("fill-rule");
+                               if (sp != null) {
+                                               if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+                                                               if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
+                                                                                               CSSPrimitiveValue.CSS_STRING) {
+                                                                               if (sp.getCssText().equals("nonzero")) {
+                                                                                               di.nonzero = true;
+                                                                               }
+                                                               }
+                                               }
+                               } else {
+                               }
+                               sp = style.getPresentationAttribute("stroke");
+                               if (sp != null) {
+                                               if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+                                                               if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
+                                                                                               CSSPrimitiveValue.CSS_RGBCOLOR) {
+                                                                               RGBColor col =
+                                                                                       ((CSSPrimitiveValue) sp).getRGBColorValue();
+                                                                               CSSPrimitiveValue val;
+                                                                               val = col.getRed();
+                                                                               float red = val.getFloatValue(
+                                                                                                                                       CSSPrimitiveValue.CSS_NUMBER);
+                                                                               val = col.getGreen();
+                                                                               float green = val.getFloatValue(
+                                                                                                                                               CSSPrimitiveValue.CSS_NUMBER);
+                                                                               val = col.getBlue();
+                                                                               float blue = val.getFloatValue(
+                                                                                                                                        CSSPrimitiveValue.CSS_NUMBER);
+                                                                               PDFColor fillColour = new PDFColor(red, green, blue);
+                                                                               currentStream.write(
+                                                                                       fillColour.getColorSpaceOut(false));
+                                                                               di.stroke = true;
+                                                               } else if ( ((CSSPrimitiveValue) sp).getPrimitiveType() ==
+                                                                               CSSPrimitiveValue.CSS_URI) {
+                                                                               // gradient
+                                                                               String str = ((CSSPrimitiveValue) sp).getCssText();
+                                                                               handleGradient(str, di, false, area);
+                                                               } else if ( ((CSSPrimitiveValue) sp).getPrimitiveType() ==
+                                                                               CSSPrimitiveValue.CSS_STRING) {
+                                                                               String str = ((CSSPrimitiveValue) sp).getCssText();
+                                                                               if (str.equals("none")) {
+                                                                                               di.stroke = false;
+                                                                                               //                              } else {
+                                                                                               //                                      handleGradient(str, false, area);
+                                                                               }
+                                                               }
+                                               }
+                               } else {
+                                               PDFColor fillColour = new PDFColor(0, 0, 0);
+                                               currentStream.write(fillColour.getColorSpaceOut(false));
+                               }
+                               sp = style.getPresentationAttribute("stroke-linecap");
+                               if (sp != null) {
+                                               if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+                                                               if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
+                                                                                               CSSPrimitiveValue.CSS_STRING) {
+                                                                               String str = sp.getCssText();
+                                                                               // butt, round ,square
+                                                                               if (str.equals("butt")) {
+                                                                                               currentStream.write(0 + " J\n");
+                                                                               } else if (str.equals("round")) {
+                                                                                               currentStream.write(1 + " J\n");
+                                                                               } else if (str.equals("square")) {
+                                                                                               currentStream.write(2 + " J\n");
+                                                                               }
+                                                               }
+                                               }
+                               } else {
+                               }
+                               sp = style.getPresentationAttribute("stroke-linejoin");
+                               if (sp != null) {
+                                               if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+                                                               if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
+                                                                                               CSSPrimitiveValue.CSS_STRING) {
+                                                                               String str = sp.getCssText();
+                                                                               if (str.equals("miter")) {
+                                                                                               currentStream.write(0 + " j\n");
+                                                                               } else if (str.equals("round")) {
+                                                                                               currentStream.write(1 + " j\n");
+                                                                               } else if (str.equals("bevel")) {
+                                                                                               currentStream.write(2 + " j\n");
+                                                                               }
+                                                               }
+                                               }
+                               } else {
+                               }
+                               sp = style.getPresentationAttribute("stroke-miterlimit");
+                               if (sp != null) {
+                                               if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+                                                               float width;
+                                                               width = ((CSSPrimitiveValue) sp).getFloatValue(
+                                                                                                       CSSPrimitiveValue.CSS_PT);
+                                                               PDFNumber pdfNumber = new PDFNumber();
+                                                               currentStream.write(pdfNumber.doubleOut(width) + " M\n");
+                                               }
+                               } else {
+                               }
+                               sp = style.getPresentationAttribute("stroke-width");
+                               if (sp != null) {
+                                               if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+                                                               float width;
+                                                               width = ((CSSPrimitiveValue) sp).getFloatValue(
+                                                                                                       CSSPrimitiveValue.CSS_PT);
+                                                               PDFNumber pdfNumber = new PDFNumber();
+                                                               currentStream.write(pdfNumber.doubleOut(width) + " w\n");
+                                               }
+                               }
+                               sp = style.getPresentationAttribute("stroke-dasharray");
+                               if (sp != null) {
+                                               if (sp.getValueType() == CSSValue.CSS_VALUE_LIST) {
+                                                               currentStream.write("[ ");
+                                                               CSSValueList list = (CSSValueList) sp;
+                                                               for (int count = 0; count < list.getLength(); count++) {
+                                                                               CSSValue val = list.item(count);
+                                                                               if (val.getValueType() ==
+                                                                                                               CSSValue.CSS_PRIMITIVE_VALUE) {
+                                                                                               currentStream.write(
+                                                                                                       ((CSSPrimitiveValue) val).getFloatValue(
+                                                                                                               CSSPrimitiveValue.CSS_NUMBER) + " ");
+                                                                               }
+                                                               }
+                                                               currentStream.write("] ");
+                                                               sp = style.getPresentationAttribute("stroke-dashoffset");
+                                                               if (sp != null && sp.getValueType() ==
+                                                                                               CSSValue.CSS_PRIMITIVE_VALUE) {
+                                                                               currentStream.write(
+                                                                                       ((CSSPrimitiveValue) sp).getFloatValue(
+                                                                                               CSSPrimitiveValue.CSS_NUMBER) + " d\n");
+                                                               } else {
+                                                                               currentStream.write("0 d\n");
+                                                               }
+                                               }
+                               }
+                               sp = style.getPresentationAttribute("clip-path");
+                               if (sp != null) {
+                                               String clipurl;
+                                               if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+                                                               if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
+                                                                                               CSSPrimitiveValue.CSS_URI) {
+                                                                               clipurl = ((CSSPrimitiveValue) sp).getCssText();
+                                                                               if (clipurl.startsWith("url(")) {
+                                                                                               int b1 = clipurl.indexOf("(");
+                                                                                               int b2 = clipurl.indexOf(")");
+                                                                                               clipurl = clipurl.substring(b1 + 1, b2);
+                                                                               }
+                                                                               // get def of mask and set mask
+                                                                               SVGElement graph = null;
+                                                                               graph = locateDef(clipurl, area);
+                                                                               if (graph != null) {
+                                                                                               MessageHandler.logln("clip path: " + graph);
+                                                                                               // render the clip path elements and make it the clip
+                                                                                               // renderElement(svgarea, graph, posx, posy);
+                                                                               }
+                                                               }
+                                               }
+                               }
+                               sp = style.getPresentationAttribute("mask");
+                               if (sp != null) {
+                                               String maskurl;
+                                               if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+                                                               if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
+                                                                                               CSSPrimitiveValue.CSS_URI) {
+                                                                               maskurl = ((CSSPrimitiveValue) sp).getCssText();
+                                                                               //                                      System.out.println("mask: " + maskurl);
+                                                                               // get def of mask and set mask
+                                                                               if (maskurl.startsWith("url(")) {
+                                                                                               int b1 = maskurl.indexOf("(");
+                                                                                               int b2 = maskurl.indexOf(")");
+                                                                                               maskurl = maskurl.substring(b1 + 1, b2);
+                                                                               }
+                                                                               SVGElement graph = null;
+                                                                               graph = locateDef(maskurl, area);
+                                                                               if (graph != null) {
+                                                                                               MessageHandler.logln("mask: " + graph);
+                                                                                               //                                              SVGElement parent = graph.getGraphicParent();
+                                                                                               //                                              graph.setParent(area);
+                                                                                               //                                              renderElement(svgarea, graph, posx, posy);
+                                                                                               //                                              graph.setParent(parent);
+                                                                               }
+                                                               }
+                                               }
+                               }
+                               return di;
+               }
+
+               protected void applyTransform(SVGAnimatedTransformList trans) {
+                               PDFNumber pdfNumber = new PDFNumber();
+                               SVGTransformList list = trans.getBaseVal();
+                               for (int count = 0; count < list.getNumberOfItems(); count++) {
+                                               SVGMatrix matrix =
+                                                       ((SVGTransform) list.getItem(count)).getMatrix();
+                                               currentStream.write(pdfNumber.doubleOut(matrix.getA()) +
+                                                                                                                               " " + pdfNumber.doubleOut(matrix.getB()) + " " +
+                                                                                                                               pdfNumber.doubleOut(matrix.getC()) + " " +
+                                                                                                                               pdfNumber.doubleOut(matrix.getD()) + " " +
+                                                                                                                               pdfNumber.doubleOut(matrix.getE()) + " " +
+                                                                                                                               pdfNumber.doubleOut(matrix.getF()) + " cm\n");
+                               }
+               }
+
+               /**
+                * Main rendering selection.
+                * This applies any transform and style and then calls the appropriate
+                * rendering method depending on the type of element.
+                */
+               public void renderElement(SVGElement area, int posx, int posy) {
+                               int x = posx;
+                               int y = posy;
+                               //              CSSStyleDeclaration style = null;
+                               //              if(area instanceof SVGStylable)
+                               //                      style = ((SVGStylable)area).getStyle();
+                               DrawingInstruction di = null;
+
+                               currentStream.write("q\n");
+                               if (area instanceof SVGTransformable) {
+                                               SVGTransformable tf = (SVGTransformable) area;
+                                               SVGAnimatedTransformList trans = tf.getTransform();
+                                               if (trans != null) {
+                                                               applyTransform(trans);
+                                               }
+                               }
+
+                               if (area instanceof SVGStylable) {
+                                               di = applyStyle(area, (SVGStylable) area);
+                               }
+
+                               if (area instanceof SVGRectElement) {
+                                               SVGRectElement rg = (SVGRectElement) area;
+                                               float rectx = rg.getX().getBaseVal().getValue();
+                                               float recty = rg.getY().getBaseVal().getValue();
+                                               float rx = rg.getRx().getBaseVal().getValue();
+                                               float ry = rg.getRy().getBaseVal().getValue();
+                                               float rw = rg.getWidth().getBaseVal().getValue();
+                                               float rh = rg.getHeight().getBaseVal().getValue();
+                                               addRect(rectx, recty, rw, rh, rx, ry, di);
+                               } else if (area instanceof SVGLineElement) {
+                                               SVGLineElement lg = (SVGLineElement) area;
+                                               float x1 = lg.getX1().getBaseVal().getValue();
+                                               float y1 = lg.getY1().getBaseVal().getValue();
+                                               float x2 = lg.getX2().getBaseVal().getValue();
+                                               float y2 = lg.getY2().getBaseVal().getValue();
+                                               addLine(x1, y1, x2, y2, di);
+                               } else if (area instanceof SVGTextElementImpl) {
+                                               //                      currentStream.add("q\n");
+                                               //                      currentStream.add(1 + " " + 0 + " " + 0 + " " + 1 + " " + 0 + " " + 0 + " cm\n");
+                                               currentStream.write("BT\n");
+                                               renderText((SVGTextElementImpl) area, 0, 0, di);
+                                               currentStream.write("ET\n");
+                                               //                      currentStream.add("Q\n");
+                               } else if (area instanceof SVGCircleElement) {
+                                               SVGCircleElement cg = (SVGCircleElement) area;
+                                               float cx = cg.getCx().getBaseVal().getValue();
+                                               float cy = cg.getCy().getBaseVal().getValue();
+                                               float r = cg.getR().getBaseVal().getValue();
+                                               addCircle(cx, cy, r, di);
+                               } else if (area instanceof SVGEllipseElement) {
+                                               SVGEllipseElement cg = (SVGEllipseElement) area;
+                                               float cx = cg.getCx().getBaseVal().getValue();
+                                               float cy = cg.getCy().getBaseVal().getValue();
+                                               float rx = cg.getRx().getBaseVal().getValue();
+                                               float ry = cg.getRy().getBaseVal().getValue();
+                                               addEllipse(cx, cy, rx, ry, di);
+                               } else if (area instanceof SVGPathElementImpl) {
+                                               addPath(((SVGPathElementImpl) area).pathElements, posx,
+                                                                               posy, di);
+                               } else if (area instanceof SVGPolylineElementImpl) {
+                                               addPolyline(((SVGPolylineElementImpl) area).points, di, false);
+                               } else if (area instanceof SVGPolygonElementImpl) {
+                                               addPolyline(((SVGPolygonElementImpl) area).points, di, true);
+                               } else if (area instanceof SVGGElementImpl) {
+                                               renderGArea((SVGGElementImpl) area, x, y);
+                               } else if (area instanceof SVGUseElementImpl) {
+                                               SVGUseElementImpl ug = (SVGUseElementImpl) area;
+                                               String ref = ug.link;
+                                               //                      ref = ref.substring(1, ref.length());
+                                               SVGElement graph = null;
+                                               graph = locateDef(ref, ug);
+                                               if (graph != null) {
+                                                               // probably not the best way to do this, should be able
+                                                               // to render without the style being set.
+                                                               //                              SVGElement parent = graph.getGraphicParent();
+                                                               //                              graph.setParent(area);
+                                                               // need to clip (if necessary) to the use area
+                                                               // the style of the linked element is as if it was
+                                                               // a direct descendant of the use element.
+
+                                                               // scale to the viewBox
+
+                                                               if (graph instanceof SVGSymbolElement) {
+                                                                               currentStream.write("q\n");
+                                                                               SVGSymbolElement symbol = (SVGSymbolElement) graph;
+                                                                               SVGRect view = symbol.getViewBox().getBaseVal();
+                                                                               float usex = ug.getX().getBaseVal().getValue();
+                                                                               float usey = ug.getY().getBaseVal().getValue();
+                                                                               float usewidth = ug.getWidth().getBaseVal().getValue();
+                                                                               float useheight =
+                                                                                       ug.getHeight().getBaseVal().getValue();
+                                                                               float scaleX;
+                                                                               float scaleY;
+                                                                               scaleX = usewidth / view.getWidth();
+                                                                               scaleY = useheight / view.getHeight();
+                                                                               currentStream.write(usex + " " + usey + " m\n");
+                                                                               currentStream.write((usex + usewidth) + " " +
+                                                                                                                                                               usey + " l\n");
+                                                                               currentStream.write((usex + usewidth) + " " +
+                                                                                                                                                               (usey + useheight) + " l\n");
+                                                                               currentStream.write(usex + " " +
+                                                                                                                                                               (usey + useheight) + " l\n");
+                                                                               currentStream.write("h\n");
+                                                                               currentStream.write("W\n");
+                                                                               currentStream.write("n\n");
+                                                                               currentStream.write(scaleX + " 0 0 " + scaleY +
+                                                                                                                                                               " " + usex + " " + usey + " cm\n");
+                                                                               renderSymbol(symbol, posx, posy);
+                                                                               currentStream.write("Q\n");
+                                                               } else {
+                                                                               renderElement(graph, posx, posy);
+                                                               }
+                                                               //                              graph.setParent(parent);
+                                               }
+                                               else {
+                                                               MessageHandler.logln("Use Element: " + ref + " not found");
+                                               }
+                               } else if (area instanceof SVGImageElementImpl) {
+                                               SVGImageElementImpl ig = (SVGImageElementImpl) area;
+                                               renderImage(ig.link, ig.x, ig.y, ig.width, ig.height);
+                               } else if (area instanceof SVGSVGElement) {
+                                               currentStream.write("q\n");
+                                               SVGSVGElement svgel = (SVGSVGElement) area;
+                                               float svgx = 0;
+                                               if (svgel.getX() != null)
+                                                               svgx = svgel.getX().getBaseVal().getValue();
+                                               float svgy = 0;
+                                               if (svgel.getY() != null)
+                                                               svgy = svgel.getY().getBaseVal().getValue();
+                                               currentStream.write(1 + " 0 0 " + 1 + " " + svgx + " " +
+                                                                                                                               svgy + " cm\n");
+                                               renderSVG(svgel, (int)(x + 1000 * svgx),
+                                                                                       (int)(y + 1000 * svgy));
+                                               currentStream.write("Q\n");
+                                               //              } else if (area instanceof SVGSymbolElement) {
+                                               // 'symbol' element is not rendered (except by 'use')
+                               } else if (area instanceof SVGAElement) {
+                                               SVGAElement ael = (SVGAElement) area;
+                                               org.w3c.dom.NodeList nl = ael.getChildNodes();
+                                               for (int count = 0; count < nl.getLength(); count++) {
+                                                               org.w3c.dom.Node n = nl.item(count);
+                                                               if (n instanceof SVGElement) {
+                                                                               if (n instanceof GraphicElement) {
+                                                                                               SVGRect rect = ((GraphicElement) n).getBBox();
+                                                                                               if (rect != null) {
+                                                                                                               /*                                                      currentAnnotList = this.pdfDoc.makeAnnotList();
+                                                                                                                                                                       currentPage.setAnnotList(currentAnnotList);
+                                                                                                                                                                       String dest = linkSet.getDest();
+                                                                                                                                                                       int linkType = linkSet.getLinkType();
+                                                                                                                                                                       currentAnnotList.addLink(
+                                                                                                                                                                               this.pdfDoc.makeLink(lrect.getRectangle(), dest, linkType));
+                                                                                                                                                                       currentAnnotList = null;
+                                                                                                                */ }
+                                                                               }
+                                                                               renderElement((SVGElement) n, posx, posy);
+                                                               }
+                                               }
+                               } else if (area instanceof SVGSwitchElement) {
+                                               handleSwitchElement(posx, posy, (SVGSwitchElement) area);
+                               }
+                               // should be done with some cleanup code, so only
+                               // required values are reset.
+                               currentStream.write("Q\n");
+               }
+
+               /**
+                * Todo: underline, linethrough, textpath
+                */
+               public void renderText(SVGTextElementImpl tg, float x, float y,
+                                                                                                        DrawingInstruction di) {
+                               SVGTextRenderer str = new SVGTextRenderer(fontState, tg, x, y);
+                               if (di.fill) {
+                                               if (di.stroke) {
+                                                               currentStream.write("2 Tr\n");
+                                               } else {
+                                                               currentStream.write("0 Tr\n");
+                                               }
+                               } else if (di.stroke) {
+                                               currentStream.write("1 Tr\n");
+                               }
+                               str.renderText(tg);
+               }
+
+               /**
+                * Adds an svg string to the output.
+                * This handles the escaping of special pdf chars and deals with
+                * whitespace.
+                */
+               protected float addSVGStr(FontState fs, float currentX, String str,
+                                                                                                                       boolean spacing) {
+                               boolean inbetween = false;
+                               boolean addedspace = false;
+                               StringBuffer pdf = new StringBuffer();
+                               for (int i = 0; i < str.length(); i++) {
+                                               char ch = str.charAt(i);
+                                               if (ch > 127) {
+                                                               pdf = pdf.append("\\");
+                                                               pdf = pdf.append(Integer.toOctalString((int) ch));
+                                                               currentX += fs.width(ch) / 1000f;
+                                                               inbetween = true;
+                                                               addedspace = false;
+                                               } else {
+                                                               switch (ch) {
+                                                                               case '(' :
+                                                                                               pdf = pdf.append("\\(");
+                                                                                               currentX += fs.width(ch) / 1000f;
+                                                                                               inbetween = true;
+                                                                                               addedspace = false;
+                                                                                               break;
+                                                                               case ')' :
+                                                                                               pdf = pdf.append("\\)");
+                                                                                               currentX += fs.width(ch) / 1000f;
+                                                                                               inbetween = true;
+                                                                                               addedspace = false;
+                                                                                               break;
+                                                                               case '\\' :
+                                                                                               pdf = pdf.append("\\\\");
+                                                                                               currentX += fs.width(ch) / 1000f;
+                                                                                               inbetween = true;
+                                                                                               addedspace = false;
+                                                                                               break;
+                                                                               case '\t':
+                                                                               case ' ':
+                                                                                               if (spacing) {
+                                                                                                               pdf = pdf.append(' ');
+                                                                                                               currentX += fs.width(' ') / 1000f;
+                                                                                               } else {
+                                                                                                               if (inbetween && !addedspace) {
+                                                                                                                               addedspace = true;
+                                                                                                                               pdf = pdf.append(' ');
+                                                                                                                               currentX += fs.width(' ') / 1000f;
+                                                                                                               }
+                                                                                               }
+                                                                                               break;
+                                                                               case '\n':
+                                                                               case '\r':
+                                                                                               if (spacing) {
+                                                                                                               pdf = pdf.append(' ');
+                                                                                                               currentX += fs.width(' ') / 1000f;
+                                                                                               }
+                                                                                               break;
+                                                                               default:
+                                                                                               addedspace = false;
+                                                                                               pdf = pdf.append(ch);
+                                                                                               currentX += fs.width(ch) / 1000f;
+                                                                                               inbetween = true;
+                                                                                               break;
+                                                               }
+                                               }
+                               }
+                               currentStream.write(pdf.toString());
+                               return currentX;
+               }
+
+               /**
+                * Locates a defined element in an svg document.
+                * Either gets the element defined by its "id" in the current
+                * SVGDocument, or if the uri reference is to an external
+                * document it loads the document and returns the element.
+                */
+               protected SVGElement locateDef(String ref, SVGElement currentElement) {
+                               int pos;
+                               ref = ref.trim();
+                               pos = ref.indexOf("#");
+                               if (pos == 0) {
+                                               // local doc
+                                               Document doc = currentElement.getOwnerDocument();
+                                               Element ele =
+                                                       doc.getElementById(ref.substring(1, ref.length()));
+                                               if (ele instanceof SVGElement) {
+                                                               return (SVGElement) ele;
+                                               }
+                               } else if (pos != -1) {
+                                               String href = ref.substring(0, pos);
+                                               if (href.indexOf(":") == -1) {
+                                                               href = "file:" + href;
+                                               }
+                                               try {
+                                                               // this is really only to get a cached svg image
+                                                               FopImage img = FopImageFactory.Make(href);
+                                                               if (img instanceof SVGImage) {
+                                                                               SVGDocument doc = ((SVGImage) img).getSVGDocument();
+                                                                               Element ele = doc.getElementById(
+                                                                                                                                               ref.substring(pos + 1, ref.length()));
+                                                                               if (ele instanceof SVGElement) {
+                                                                                               return (SVGElement) ele;
+                                                                               }
+                                                               }
+                                               } catch (Exception e) {
+                                                               MessageHandler.errorln(e.toString());
+                                               }
+                               }
+                               return null;
+               }
+
+               /**
+                * This class is used to handle the rendering of svg text.
+                * This is so that it can deal with the recursive rendering
+                * of text markup, while keeping track of the state and position.
+                */
+               class SVGTextRenderer {
+                               FontState fs;
+                               String transstr;
+                               float currentX;
+                               float currentY;
+                               float baseX;
+                               float baseY;
+                               SVGMatrix matrix;
+                               float x;
+                               float y;
+
+                               SVGTextRenderer(FontState fontState, SVGTextElementImpl tg,
+                                                                                               float x, float y) {
+                                               fs = fontState;
+
+                                               PDFNumber pdfNumber = new PDFNumber();
+                                               SVGTransformList trans = tg.getTransform().getBaseVal();
+                                               matrix = trans.consolidate().getMatrix();
+                                               transstr = (pdfNumber.doubleOut(matrix.getA()) + " " +
+                                                                                               pdfNumber.doubleOut(matrix.getB()) + " " +
+                                                                                               pdfNumber.doubleOut(matrix.getC()) + " " +
+                                                                                               pdfNumber.doubleOut(-matrix.getD()) + " ");
+                                               this.x = x;
+                                               this.y = y;
+                               }
+
+                               void renderText(SVGTextElementImpl te) {
+                                               DrawingInstruction di = applyStyle(te, te);
+                                               if (di.fill) {
+                                                               if (di.stroke) {
+                                                                               currentStream.write("2 Tr\n");
+                                                               } else {
+                                                                               currentStream.write("0 Tr\n");
+                                                               }
+                                               } else if (di.stroke) {
+                                                               currentStream.write("1 Tr\n");
+                                               }
+                                               updateFont(te, fs);
+
+                                               float tx = te.x;
+                                               float ty = te.y;
+                                               currentX = x + tx;
+                                               currentY = y + ty;
+                                               baseX = currentX;
+                                               baseY = currentY;
+                                               NodeList nodel = te.getChildNodes();
+                                               //              Vector list = te.textList;
+                                               for (int count = 0; count < nodel.getLength(); count++) {
+                                                               Object o = nodel.item(count);
+                                                               applyStyle(te, te);
+                                                               if (o instanceof CharacterData) {
+                                                                               String str = ((CharacterData) o).getData();
+                                                                               currentStream.write(transstr +
+                                                                                                                                                               (currentX + matrix.getE()) + " " +
+                                                                                                                                                               (baseY + matrix.getF()) + " Tm " + "(");
+                                                                               boolean spacing = "preserve".equals(te.getXMLspace());
+                                                                               currentX = addSVGStr(fs, currentX, str, spacing);
+                                                                               currentStream.write(") Tj\n");
+                                                               } else if (o instanceof SVGTextPathElementImpl) {
+                                                                               SVGTextPathElementImpl tpg = (SVGTextPathElementImpl) o;
+                                                                               String ref = tpg.str;
+                                                                               SVGElement graph = null;
+                                                                               graph = locateDef(ref, tpg);
+                                                                               if (graph instanceof SVGPathElementImpl) {
+                                                                                               // probably not the best way to do this, should be able
+                                                                                               // to render without the style being set.
+                                                                                               //                                      GraphicImpl parent = graph.getGraphicParent();
+                                                                                               //                                      graph.setParent(tpg);
+                                                                                               // set text path??
+                                                                                               // how should this work
+                                                                                               //                                      graph.setParent(parent);
+                                                                               }
+                                                               } else if (o instanceof SVGTRefElementImpl) {
+                                                                               SVGTRefElementImpl trg = (SVGTRefElementImpl) o;
+                                                                               String ref = trg.ref;
+                                                                               SVGElement element = locateDef(ref, trg);
+                                                                               if (element instanceof SVGTextElementImpl) {
+                                                                                               //                                      GraphicImpl parent = graph.getGraphicParent();
+                                                                                               //                                      graph.setParent(trg);
+                                                                                               SVGTextElementImpl tele =
+                                                                                                       (SVGTextElementImpl) element;
+                                                                                               // the style should be from tele, but it needs to be placed as a child
+                                                                                               // of trg to work
+                                                                                               di = applyStyle(trg, trg);
+                                                                                               if (di.fill) {
+                                                                                                               if (di.stroke) {
+                                                                                                                               currentStream.write("2 Tr\n");
+                                                                                                               } else {
+                                                                                                                               currentStream.write("0 Tr\n");
+                                                                                                               }
+                                                                                               } else if (di.stroke) {
+                                                                                                               currentStream.write("1 Tr\n");
+                                                                                               }
+                                                                                               boolean changed = false;
+                                                                                               FontState oldfs = fs;
+                                                                                               changed = updateFont(te, fs);
+                                                                                               NodeList nl = tele.getChildNodes();
+                                                                                               boolean spacing =
+                                                                                                       "preserve".equals(trg.getXMLspace());
+                                                                                               renderTextNodes(spacing, nl,
+                                                                                                                                                               trg.getX().getBaseVal(),
+                                                                                                                                                               trg.getY().getBaseVal(),
+                                                                                                                                                               trg.getDx().getBaseVal(),
+                                                                                                                                                               trg.getDy().getBaseVal());
+
+                                                                                               if (changed) {
+                                                                                                               fs = oldfs;
+                                                                                                               currentStream.write("/" +
+                                                                                                                                                                                               fs.getFontName() + " " +
+                                                                                                                                                                                               fs.getFontSize() / 1000f + " Tf\n");
+                                                                                               }
+                                                                                               //                                      graph.setParent(parent);
+                                                                               }
+                                                               } else if (o instanceof SVGTSpanElementImpl) {
+                                                                               SVGTSpanElementImpl tsg = (SVGTSpanElementImpl) o;
+                                                                               applyStyle(tsg, tsg);
+                                                                               boolean changed = false;
+                                                                               FontState oldfs = fs;
+                                                                               changed = updateFont(tsg, fs);
+                                                                               boolean spacing = "preserve".equals(tsg.getXMLspace());
+                                                                               renderTextNodes(spacing, tsg.getChildNodes(),
+                                                                                                                                               tsg.getX().getBaseVal(),
+                                                                                                                                               tsg.getY().getBaseVal(),
+                                                                                                                                               tsg.getDx().getBaseVal(),
+                                                                                                                                               tsg.getDy().getBaseVal());
+
+                                                                               //                              currentX += fs.width(' ') / 1000f;
+                                                                               if (changed) {
+                                                                                               fs = oldfs;
+                                                                                               currentStream.write("/" + fs.getFontName() +
+                                                                                                                                                                               " " + fs.getFontSize() / 1000f + " Tf\n");
+                                                                               }
+                                                               } else {
+                                                                               MessageHandler.errorln("Error: unknown text element " + o);
+                                                               }
+                                               }
+                               }
+
+                               void renderTextNodes(boolean spacing, NodeList nl,
+                                                                                                                SVGLengthList xlist, SVGLengthList ylist,
+                                                                                                                SVGLengthList dxlist, SVGLengthList dylist) {
+                                               boolean inbetween = false;
+                                               boolean addedspace = false;
+                                               int charPos = 0;
+                                               float xpos = currentX;
+                                               float ypos = currentY;
+
+                                               for (int count = 0; count < nl.getLength(); count++) {
+                                                               Node n = nl.item(count);
+                                                               if (n instanceof CharacterData) {
+                                                                               StringBuffer pdf = new StringBuffer();
+                                                                               String str = ((CharacterData) n).getData();
+                                                                               for (int i = 0; i < str.length(); i++) {
+                                                                                               char ch = str.charAt(i);
+                                                                                               xpos = currentX;
+                                                                                               ypos = currentY;
+                                                                                               if (ylist.getNumberOfItems() > charPos) {
+                                                                                                               ypos = baseY + (ylist.getItem(charPos)).
+                                                                                                                                        getValue();
+                                                                                               }
+                                                                                               if (dylist.getNumberOfItems() > charPos) {
+                                                                                                               ypos = ypos + (dylist.getItem(charPos)).
+                                                                                                                                        getValue();
+                                                                                               }
+                                                                                               if (xlist.getNumberOfItems() > charPos) {
+                                                                                                               xpos = baseX + (xlist.getItem(charPos)).
+                                                                                                                                        getValue();
+                                                                                               }
+                                                                                               if (dxlist.getNumberOfItems() > charPos) {
+                                                                                                               xpos = xpos + (dxlist.getItem(charPos)).
+                                                                                                                                        getValue();
+                                                                                               }
+                                                                                               if (ch > 127) {
+                                                                                                               pdf = pdf.append(transstr +
+                                                                                                                                                                                (xpos + matrix.getE()) + " " +
+                                                                                                                                                                                (ypos + matrix.getF()) + " Tm " +
+                                                                                                                                                                                "(" + "\\" +
+                                                                                                                                                                                Integer.toOctalString((int) ch) +
+                                                                                                                                                                                ") Tj\n");
+                                                                                                               currentX = xpos + fs.width(ch) / 1000f;
+                                                                                                               currentY = ypos;
+                                                                                                               charPos++;
+                                                                                                               inbetween = true;
+                                                                                                               addedspace = false;
+                                                                                               } else {
+                                                                                                               switch (ch) {
+                                                                                                                               case '(' :
+                                                                                                                                               pdf = pdf.append(transstr +
+                                                                                                                                                                                                                (xpos + matrix.getE()) +
+                                                                                                                                                                                                                " " + (ypos +
+                                                                                                                                                                                                                                               matrix.getF()) + " Tm " +
+                                                                                                                                                                                                                "(" + "\\(" + ") Tj\n");
+                                                                                                                                               currentX = xpos + fs.width(ch) / 1000f;
+                                                                                                                                               currentY = ypos;
+                                                                                                                                               charPos++;
+                                                                                                                                               inbetween = true;
+                                                                                                                                               addedspace = false;
+                                                                                                                                               break;
+                                                                                                                               case ')' :
+                                                                                                                                               pdf = pdf.append(transstr +
+                                                                                                                                                                                                                (xpos + matrix.getE()) +
+                                                                                                                                                                                                                " " + (ypos +
+                                                                                                                                                                                                                                               matrix.getF()) + " Tm " +
+                                                                                                                                                                                                                "(" + "\\)" + ") Tj\n");
+                                                                                                                                               currentX = xpos + fs.width(ch) / 1000f;
+                                                                                                                                               currentY = ypos;
+                                                                                                                                               charPos++;
+                                                                                                                                               inbetween = true;
+                                                                                                                                               addedspace = false;
+                                                                                                                                               break;
+                                                                                                                               case '\\' :
+                                                                                                                                               pdf = pdf.append(transstr +
+                                                                                                                                                                                                                (xpos + matrix.getE()) +
+                                                                                                                                                                                                                " " + (ypos +
+                                                                                                                                                                                                                                               matrix.getF()) + " Tm " +
+                                                                                                                                                                                                                "(" + "\\\\" + ") Tj\n");
+                                                                                                                                               currentX = xpos + fs.width(ch) / 1000f;
+                                                                                                                                               currentY = ypos;
+                                                                                                                                               charPos++;
+                                                                                                                                               inbetween = true;
+                                                                                                                                               addedspace = false;
+                                                                                                                                               break;
+                                                                                                                               case '\t':
+                                                                                                                               case ' ':
+                                                                                                                                               if (spacing) {
+                                                                                                                                                               currentX = xpos + fs.width(' ') /
+                                                                                                                                                                                                        1000f;
+                                                                                                                                                               currentY = ypos;
+                                                                                                                                                               charPos++;
+                                                                                                                                               } else {
+                                                                                                                                                               if (inbetween && !addedspace) {
+                                                                                                                                                                               addedspace = true;
+                                                                                                                                                                               currentX = xpos + fs.width(' ')
+                                                                                                                                                                                                                        / 1000f;
+                                                                                                                                                                               currentY = ypos;
+                                                                                                                                                                               charPos++;
+                                                                                                                                                               }
+                                                                                                                                               }
+                                                                                                                                               break;
+                                                                                                                               case '\n':
+                                                                                                                               case '\r':
+                                                                                                                                               if (spacing) {
+                                                                                                                                                               currentX = xpos + fs.width(' ') /
+                                                                                                                                                                                                        1000f;
+                                                                                                                                                               currentY = ypos;
+                                                                                                                                                               charPos++;
+                                                                                                                                               }
+                                                                                                                                               break;
+                                                                                                                               default:
+                                                                                                                                               addedspace = false;
+                                                                                                                                               pdf = pdf.append(transstr +
+                                                                                                                                                                                                                (xpos + matrix.getE()) +
+                                                                                                                                                                                                                " " + (ypos +
+                                                                                                                                                                                                                                               matrix.getF()) + " Tm " +
+                                                                                                                                                                                                                "(" + ch + ") Tj\n");
+                                                                                                                                               currentX = xpos + fs.width(ch) / 1000f;
+                                                                                                                                               currentY = ypos;
+                                                                                                                                               charPos++;
+                                                                                                                                               inbetween = true;
+                                                                                                                                               break;
+                                                                                                               }
+                                                                                               }
+                                                                                               currentStream.write(pdf.toString());
+                                                                               }
+                                                               }
+                                               }
+                               }
+
+                               protected boolean updateFont(SVGStylable style, FontState fs) {
+                                               boolean changed = false;
+                                               String fontFamily = fs.getFontFamily();
+                                               CSSValue sp = style.getPresentationAttribute("font-family");
+                                               if (sp != null &&
+                                                                               sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+                                                               if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
+                                                                                               CSSPrimitiveValue.CSS_STRING) {
+                                                                               fontFamily = sp.getCssText();
+                                                               }
+                                               }
+                                               if (!fontFamily.equals(fs.getFontFamily())) {
+                                                               changed = true;
+                                               }
+                                               String fontStyle = fs.getFontStyle();
+                                               sp = style.getPresentationAttribute("font-style");
+                                               if (sp != null &&
+                                                                               sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+                                                               if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
+                                                                                               CSSPrimitiveValue.CSS_STRING) {
+                                                                               fontStyle = sp.getCssText();
+                                                               }
+                                               }
+                                               if (!fontStyle.equals(fs.getFontStyle())) {
+                                                               changed = true;
+                                               }
+                                               String fontWeight = fs.getFontWeight();
+                                               sp = style.getPresentationAttribute("font-weight");
+                                               if (sp != null &&
+                                                                               sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+                                                               if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
+                                                                                               CSSPrimitiveValue.CSS_STRING) {
+                                                                               fontWeight = sp.getCssText();
+                                                               }
+                                               }
+                                               if (!fontWeight.equals(fs.getFontWeight())) {
+                                                               changed = true;
+                                               }
+                                               float newSize = fs.getFontSize() / 1000f;
+                                               sp = style.getPresentationAttribute("font-size");
+                                               if (sp != null &&
+                                                                               sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+                                                               //                  if(((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_NUMBER) {
+                                                               newSize = ((CSSPrimitiveValue) sp).getFloatValue(
+                                                                                                               CSSPrimitiveValue.CSS_PT);
+                                                               //                  }
+                                               }
+                                               if (fs.getFontSize() / 1000f != newSize) {
+                                                               changed = true;
+                                               }
+                                               if (changed) {
+                                                               try {
+                                                                               // FIX-ME: should get the font-variant property
+                                                                               fs = new FontState(fs.getFontInfo(), fontFamily,
+                                                                                                                                                        fontStyle, fontWeight, (int)(newSize * 1000),
+                                                                                                                                                        FontVariant.NORMAL);
+                                                               } catch (Exception fope) {
+                                                               }
+                                                               this.fs = fs;
+
+                                                               currentStream.write("/" + fs.getFontName() + " " +
+                                                                                                                                               newSize + " Tf\n");
+                                               } else {
+                                                               if (!currentFontName.equals(fs.getFontName()) ||
+                                                                                               currentFontSize != fs.getFontSize()) {
+                                                                               //                              currentFontName = fs.getFontName();
+                                                                               //                              currentFontSize = fs.getFontSize();
+                                                                               currentStream.write("/" + fs.getFontName() + " " +
+                                                                                                                                                               (fs.getFontSize() / 1000) + " Tf\n");
+                                                               }
+                                               }
+                                               return changed;
+                               }
+               }
 }
index b67b8c04eee7a1d3c278ae80511f386ecccb8abe..1d52fed3be0eafd47af9d699993a88d5b0aae94f 100644 (file)
@@ -1,35 +1,35 @@
 /*-- $Id$ --
 
  ============================================================================
-                   The Apache Software License, Version 1.1
+                                                                        The Apache Software License, Version 1.1
  ============================================================================
 
-    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+               Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
 
  Redistribution and use in source and binary forms, with or without modifica-
  tion, are permitted provided that the following conditions are met:
 
  1. Redistributions of  source code must  retain the above copyright  notice,
-    this list of conditions and the following disclaimer.
+               this list of conditions and the following disclaimer.
 
  2. Redistributions in binary form must reproduce the above copyright notice,
-    this list of conditions and the following disclaimer in the documentation
-    and/or other materials provided with the distribution.
+               this list of conditions and the following disclaimer in the documentation
+               and/or other materials provided with the distribution.
 
  3. The end-user documentation included with the redistribution, if any, must
-    include  the following  acknowledgment:  "This product includes  software
-    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
-    Alternately, this  acknowledgment may  appear in the software itself,  if
-    and wherever such third-party acknowledgments normally appear.
+               include  the following  acknowledgment:  "This product includes  software
+               developed  by the  Apache Software Foundation  (http://www.apache.org/)."
+               Alternately, this  acknowledgment may  appear in the software itself,  if
+               and wherever such third-party acknowledgments normally appear.
 
  4. The names "FOP" and  "Apache Software Foundation"  must not be used to
-    endorse  or promote  products derived  from this  software without  prior
-    written permission. For written permission, please contact
-    apache@apache.org.
+               endorse  or promote  products derived  from this  software without  prior
+               written permission. For written permission, please contact
+               apache@apache.org.
 
  5. Products  derived from this software may not  be called "Apache", nor may
-    "Apache" appear  in their name,  without prior written permission  of the
-    Apache Software Foundation.
+               "Apache" appear  in their name,  without prior written permission  of the
+               Apache Software Foundation.
 
  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
@@ -69,174 +69,175 @@ import org.apache.fop.dom.svg.SVGArea;
  */
 public class SVG extends FObj implements GraphicsCreator {
 
-    /**
-     * inner class for making SVG objects.
-     */
-    public static class Maker extends FObj.Maker {
-
-        /**
-         * make an SVG object.
-         *
-         * @param parent the parent formatting object
-         * @param propertyList the explicit properties of this object
-         *
-         * @return the SVG object
-         */
-        public FObj make(FObj parent,
-                         PropertyList propertyList) throws FOPException {
-            return new SVG(parent, propertyList);
-        }
-    }
-
-    /**
-     * returns the maker for this object.
-     *
-     * @return the maker for SVG objects
-     */
-    public static FObj.Maker maker() {
-        return new SVG.Maker();
-    }
-
-    FontState fs;
-    float width;
-    float height;
-
-    /**
-     * constructs an SVG object (called by Maker).
-     *
-     * @param parent the parent formatting object
-     * @param propertyList the explicit properties of this object
-     */
-    public SVG(FObj parent, PropertyList propertyList) {
-        super(parent, propertyList);
-        this.name = "svg:svg";
-    }
-
-    public SVGElement createGraphic() {
-        SVGSVGElementImpl svgArea = null;
-        SVGLength w = ((SVGLengthProperty) this.properties.get("width")).
-                      getSVGLength();
-        SVGLength h = ((SVGLengthProperty) this.properties.get("height")).
-                      getSVGLength();
-        svgArea = new SVGSVGElementImpl();
-        SVGAnimatedLengthImpl sal;
-        if (w == null)
-            w = new SVGLengthImpl();
-        sal = new SVGAnimatedLengthImpl(w);
-        sal.setBaseVal(w);
-        svgArea.setWidth(sal);
-        if (h == null)
-            h = new SVGLengthImpl();
-        sal = new SVGAnimatedLengthImpl(h);
-        sal.setBaseVal(h);
-        svgArea.setHeight(sal);
-        SVGLength lengthProp =
-          ((SVGLengthProperty) this.properties.get("x")).
-          getSVGLength();
-        SVGLength x = lengthProp == null ? new SVGLengthImpl() : lengthProp;
-        sal = new SVGAnimatedLengthImpl(x);
-        sal.setBaseVal(x);
-        svgArea.setX(sal);
-        lengthProp = ((SVGLengthProperty) this.properties.get("y")).
-                     getSVGLength();
-        SVGLength y = lengthProp == null ? new SVGLengthImpl() : lengthProp;
-        sal = new SVGAnimatedLengthImpl(y);
-        sal.setBaseVal(y);
-        svgArea.setY(sal);
-
-        svgArea.setStyle(
-          ((SVGStyle) this.properties.get("style")).getStyle());
-        svgArea.setTransform(
-          ((SVGTransform) this.properties.get("transform")).
-          getTransform());
-        svgArea.setId(this.properties.get("id").getString());
-        int numChildren = this.children.size();
-        for (int i = 0; i < numChildren; i++) {
-            FONode fo = (FONode) children.elementAt(i);
-            if (fo instanceof GraphicsCreator) {
-                SVGElement impl = ((GraphicsCreator) fo).createGraphic();
-                if (impl != null) {
-                    if (impl instanceof SVGElementImpl)
-                        ((SVGElementImpl) impl).setClassName(
-                          new SVGAnimatedStringImpl(
-                            ((FObj) fo).getProperty(
-                              "class").getString()));
-                    svgArea.appendChild((org.w3c.dom.Node) impl);
-                }
-                //                     } else if(fo instanceof Defs) {
-                //                             svgArea.addDefs(((Defs)fo).createDefs());
-            }
-            Status status;
-        }
-        return svgArea;
-    }
-
-    /**
-     * layout this formatting object.
-     *
-     * @param area the area to layout the object into
-     *
-     * @return the status of the layout
-     */
-    public Status layout(Area area) throws FOPException {
-
-        if (!(area instanceof ForeignObjectArea)) {
-            // this is an error
-            throw new FOPException("SVG not in fo:instream-foreign-object");
-        }
-
-        if (this.marker == BREAK_AFTER) {
-            return new Status(Status.OK);
-        }
-
-        if (this.marker == START) {
-            /* retrieve properties */
-            String id = this.properties.get("id").getString();
-            String fontFamily =
-              this.properties.get("font-family").getString();
-            String fontStyle =
-              this.properties.get("font-style").getString();
-            String fontWeight =
-              this.properties.get("font-weight").getString();
-            int fontSize =
-              this.properties.get("font-size").getLength().mvalue();
-
-            this.fs = new FontState(area.getFontInfo(), fontFamily,
-                                    fontStyle, fontWeight, fontSize);
-            SVGLength length;
-            length = ((SVGLengthProperty) this.properties.get("width")).
-                     getSVGLength();
-            if (length == null)
-                length = new SVGLengthImpl();
-            this.width = length.getValue();
-            length = ((SVGLengthProperty) this.properties.get("height")).
-                     getSVGLength();
-            if (length == null)
-                length = new SVGLengthImpl();
-            this.height = length.getValue();
-
-            this.marker = 0;
-        }
-
-        /* create an SVG area */
-        /* if width and height are zero, may want to get the bounds of the content. */
-        SVGArea svg = new SVGArea(fs, width, height);
-        SVGDocument doc = new SVGDocumentImpl();
-        svg.setSVGDocument(doc);
-        svg.start();
-
-        /* add the SVG area to the containing area */
-        ForeignObjectArea foa = (ForeignObjectArea) area;
-        foa.setObject(svg);
-        foa.setIntrinsicWidth(svg.getWidth());
-        foa.setIntrinsicHeight(svg.getHeight());
-
-        doc.appendChild((SVGSVGElement) createGraphic());
-
-        /* finish off the SVG area */
-        svg.end();
-
-        /* return status */
-        return new Status(Status.OK);
-    }
+               /**
+                * inner class for making SVG objects.
+                */
+               public static class Maker extends FObj.Maker {
+
+                               /**
+                                * make an SVG object.
+                                *
+                                * @param parent the parent formatting object
+                                * @param propertyList the explicit properties of this object
+                                *
+                                * @return the SVG object
+                                */
+                               public FObj make(FObj parent,
+                                                                                                PropertyList propertyList) throws FOPException {
+                                               return new SVG(parent, propertyList);
+                               }
+               }
+
+               /**
+                * returns the maker for this object.
+                *
+                * @return the maker for SVG objects
+                */
+               public static FObj.Maker maker() {
+                               return new SVG.Maker();
+               }
+
+               FontState fs;
+               float width;
+               float height;
+
+               /**
+                * constructs an SVG object (called by Maker).
+                *
+                * @param parent the parent formatting object
+                * @param propertyList the explicit properties of this object
+                */
+               public SVG(FObj parent, PropertyList propertyList) {
+                               super(parent, propertyList);
+                               this.name = "svg:svg";
+               }
+
+               public SVGElement createGraphic() {
+                               SVGSVGElementImpl svgArea = null;
+                               SVGLength w = ((SVGLengthProperty) this.properties.get("width")).
+                                                                                       getSVGLength();
+                               SVGLength h = ((SVGLengthProperty) this.properties.get("height")).
+                                                                                       getSVGLength();
+                               svgArea = new SVGSVGElementImpl();
+                               SVGAnimatedLengthImpl sal;
+                               if (w == null)
+                                               w = new SVGLengthImpl();
+                               sal = new SVGAnimatedLengthImpl(w);
+                               sal.setBaseVal(w);
+                               svgArea.setWidth(sal);
+                               if (h == null)
+                                               h = new SVGLengthImpl();
+                               sal = new SVGAnimatedLengthImpl(h);
+                               sal.setBaseVal(h);
+                               svgArea.setHeight(sal);
+                               SVGLength lengthProp =
+                                       ((SVGLengthProperty) this.properties.get("x")).
+                                       getSVGLength();
+                               SVGLength x = lengthProp == null ? new SVGLengthImpl() : lengthProp;
+                               sal = new SVGAnimatedLengthImpl(x);
+                               sal.setBaseVal(x);
+                               svgArea.setX(sal);
+                               lengthProp = ((SVGLengthProperty) this.properties.get("y")).
+                                                                                getSVGLength();
+                               SVGLength y = lengthProp == null ? new SVGLengthImpl() : lengthProp;
+                               sal = new SVGAnimatedLengthImpl(y);
+                               sal.setBaseVal(y);
+                               svgArea.setY(sal);
+
+                               svgArea.setStyle(
+                                       ((SVGStyle) this.properties.get("style")).getStyle());
+                               svgArea.setTransform(
+                                       ((SVGTransform) this.properties.get("transform")).
+                                       getTransform());
+                               svgArea.setId(this.properties.get("id").getString());
+                               int numChildren = this.children.size();
+                               for (int i = 0; i < numChildren; i++) {
+                                               FONode fo = (FONode) children.elementAt(i);
+                                               if (fo instanceof GraphicsCreator) {
+                                                               SVGElement impl = ((GraphicsCreator) fo).createGraphic();
+                                                               if (impl != null) {
+                                                                               if (impl instanceof SVGElementImpl)
+                                                                                               ((SVGElementImpl) impl).setClassName(
+                                                                                                       new SVGAnimatedStringImpl(
+                                                                                                               ((FObj) fo).getProperty(
+                                                                                                                       "class").getString()));
+                                                                               svgArea.appendChild((org.w3c.dom.Node) impl);
+                                                               }
+                                                               //                      } else if(fo instanceof Defs) {
+                                                               //                              svgArea.addDefs(((Defs)fo).createDefs());
+                                               }
+                                               Status status;
+                               }
+                               return svgArea;
+               }
+
+               /**
+                * layout this formatting object.
+                *
+                * @param area the area to layout the object into
+                *
+                * @return the status of the layout
+                */
+               public Status layout(Area area) throws FOPException {
+
+                               if (!(area instanceof ForeignObjectArea)) {
+                                               // this is an error
+                                               throw new FOPException("SVG not in fo:instream-foreign-object");
+                               }
+
+                               if (this.marker == BREAK_AFTER) {
+                                               return new Status(Status.OK);
+                               }
+
+                               if (this.marker == START) {
+                                               /* retrieve properties */
+                                               String id = this.properties.get("id").getString();
+                                               String fontFamily =
+                                                       this.properties.get("font-family").getString();
+                                               String fontStyle =
+                                                       this.properties.get("font-style").getString();
+                                               String fontWeight =
+                                                       this.properties.get("font-weight").getString();
+                                               int fontSize =
+                                                       this.properties.get("font-size").getLength().mvalue();
+
+                                               // FIX-ME: should get the font-variant property
+                                               this.fs = new FontState(area.getFontInfo(), fontFamily,
+                                                                                                                                               fontStyle, fontWeight, fontSize, FontVariant.NORMAL);
+
+                                               SVGLength length;
+                                               length = ((SVGLengthProperty) this.properties.get("width")).getSVGLength();
+                                               if (length == null)
+                                                               length = new SVGLengthImpl();
+                                               this.width = length.getValue();
+                                               length = ((SVGLengthProperty) this.properties.get("height")).
+                                                                                getSVGLength();
+                                               if (length == null)
+                                                               length = new SVGLengthImpl();
+                                               this.height = length.getValue();
+
+                                               this.marker = 0;
+                               }
+
+                               /* create an SVG area */
+                               /* if width and height are zero, may want to get the bounds of the content. */
+                               SVGArea svg = new SVGArea(fs, width, height);
+                               SVGDocument doc = new SVGDocumentImpl();
+                               svg.setSVGDocument(doc);
+                               svg.start();
+
+                               /* add the SVG area to the containing area */
+                               ForeignObjectArea foa = (ForeignObjectArea) area;
+                               foa.setObject(svg);
+                               foa.setIntrinsicWidth(svg.getWidth());
+                               foa.setIntrinsicHeight(svg.getHeight());
+
+                               doc.appendChild((SVGSVGElement) createGraphic());
+
+                               /* finish off the SVG area */
+                               svg.end();
+
+                               /* return status */
+                               return new Status(Status.OK);
+               }
 }