You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by es...@apache.org on 2001/01/25 16:11:07 UTC

cvs commit: xml-fop/src/org/apache/fop/render/pdf SVGRenderer.java

eschaeffer    01/01/25 07:11:07

  Modified:    src/org/apache/fop/render/pdf SVGRenderer.java
  Log:
  Modified to support new FontState class.
  
  Revision  Changes    Path
  1.5       +2524 -2522xml-fop/src/org/apache/fop/render/pdf/SVGRenderer.java
  
  Index: SVGRenderer.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/org/apache/fop/render/pdf/SVGRenderer.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- SVGRenderer.java	2000/12/27 05:06:00	1.4
  +++ SVGRenderer.java	2001/01/25 15:11:05	1.5
  @@ -1,7 +1,7 @@
  -/*-- $Id: SVGRenderer.java,v 1.4 2000/12/27 05:06:00 keiron Exp $ --
  +/*-- $Id: SVGRenderer.java,v 1.5 2001/01/25 15:11:05 eschaeffer Exp $ --
   
    ============================================================================
  -				   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 @@
    */
   public class SVGRenderer {
   
  -    /** the PDF Document being created */
  -    protected PDFDocument pdfDoc;
  +		/** the PDF Document being created */
  +		protected PDFDocument pdfDoc;
   
  -    protected FontState fontState;
  +		protected FontState fontState;
   
  -    /** the /Resources object of the PDF document being created */
  -    //	protected PDFResources pdfResources;
  +		/** 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 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;
  +				}
  +		}
   }