src/main/java/org/jfree/graphics2d/svg/SVGGraphics2D.java
@Override
    public void draw(Shape s) {
        // if the current stroke is not a BasicStroke then it is handled as
        // a special case
        if (!(this.stroke instanceof BasicStroke)) {
            fill(this.stroke.createStrokedShape(s));
            return;
        }
        if (s instanceof Line2D) {
            Line2D l = (Line2D) s;
            this.sb.append("<line ");
            appendOptionalElementIDFromHint(this.sb);
            this.sb.append("x1=\"").append(geomDP(l.getX1()))
                    .append("\" y1=\"").append(geomDP(l.getY1()))
                    .append("\" x2=\"").append(geomDP(l.getX2()))
                    .append("\" y2=\"").append(geomDP(l.getY2()))
                    .append("\" ");
            this.sb.append("style=\"").append(strokeStyle()).append("\" ");
            if (!this.transform.isIdentity()) {
            	this.sb.append("transform=\"").append(getSVGTransform(
            		this.transform)).append("\" ");
            }
            this.sb.append(getClipPathRef());
            this.sb.append("/>");
        } else if (s instanceof Rectangle2D) {
            Rectangle2D r = (Rectangle2D) s;
            this.sb.append("<rect ");
            appendOptionalElementIDFromHint(this.sb);
            this.sb.append("x=\"").append(geomDP(r.getX()))
                    .append("\" y=\"").append(geomDP(r.getY()))
                    .append("\" width=\"").append(geomDP(r.getWidth()))
                    .append("\" height=\"").append(geomDP(r.getHeight()))
                    .append("\" ");
            this.sb.append("style=\"").append(strokeStyle())
                    .append("; fill: none").append("\" ");
            if (!this.transform.isIdentity()) {
            	this.sb.append("transform=\"").append(getSVGTransform(
            		this.transform)).append("\" ");
            }
            this.sb.append(getClipPathRef());
            this.sb.append("/>");
        } else if (s instanceof Ellipse2D) {
            Ellipse2D e = (Ellipse2D) s;
            this.sb.append("<ellipse ");
            appendOptionalElementIDFromHint(this.sb);
            this.sb.append("cx=\"").append(geomDP(e.getCenterX()))
                    .append("\" cy=\"").append(geomDP(e.getCenterY()))
                    .append("\" rx=\"").append(geomDP(e.getWidth() / 2.0))
                    .append("\" ry=\"").append(geomDP(e.getHeight() / 2.0))
                    .append("\" ");
            this.sb.append("style=\"").append(strokeStyle())
                    .append("; fill: none").append("\" ");
            if (!this.transform.isIdentity()) {
            	this.sb.append("transform=\"").append(getSVGTransform(
            		this.transform)).append("\" ");
            }
            this.sb.append(getClipPathRef());
            this.sb.append("/>");        
        } else if (s instanceof Path2D) {
            Path2D path = (Path2D) s;
            this.sb.append("<g ");
            appendOptionalElementIDFromHint(this.sb);
            this.sb.append("style=\"").append(strokeStyle())
                    .append("; fill: none").append("\" ");
            if (!this.transform.isIdentity()) {
            	this.sb.append("transform=\"").append(getSVGTransform(
            		this.transform)).append("\" ");
            }
            this.sb.append(getClipPathRef());
            this.sb.append(">");
            this.sb.append("<path ").append(getSVGPathData(path)).append("/>");
            this.sb.append("</g>");
        } else {
            draw(new GeneralPath(s)); // handled as a Path2D next time through
        }
    }
@Override
    public void draw(Shape s) {
        // if the current stroke is not a BasicStroke then it is handled as
        // a special case
        if (!(this.stroke instanceof BasicStroke)) {
            fill(this.stroke.createStrokedShape(s));
            return;
        }
        if (s instanceof Line2D) {
            Line2D l = (Line2D) s;
            this.sb.append("<line ");
            appendOptionalElementIDFromHint(this.sb);
            this.sb.append("x1=\"").append(geomDP(l.getX1()))
                    .append("\" y1=\"").append(geomDP(l.getY1()))
                    .append("\" x2=\"").append(geomDP(l.getX2()))
                    .append("\" y2=\"").append(geomDP(l.getY2()))
                    .append("\" ");
            this.sb.append("style=\"").append(strokeStyle()).append("\" ");
            if (!this.transform.isIdentity()) {
            	this.sb.append("transform=\"").append(getSVGTransform(
            		this.transform)).append("\" ");
            }
            this.sb.append(getClipPathRef());
            this.sb.append("/>");
        } else if (s instanceof Rectangle2D) {
            Rectangle2D r = (Rectangle2D) s;
            this.sb.append("<rect ");
            appendOptionalElementIDFromHint(this.sb);
            this.sb.append("x=\"").append(geomDP(r.getX()))
                    .append("\" y=\"").append(geomDP(r.getY()))
                    .append("\" width=\"").append(geomDP(r.getWidth()))
                    .append("\" height=\"").append(geomDP(r.getHeight()))
                    .append("\" ");
            this.sb.append("style=\"").append(strokeStyle())
                    .append("; fill: none").append("\" ");
            if (!this.transform.isIdentity()) {
            	this.sb.append("transform=\"").append(getSVGTransform(
            		this.transform)).append("\" ");
            }
            this.sb.append(getClipPathRef());
            this.sb.append("/>");
        } else if (s instanceof Ellipse2D) {
            Ellipse2D e = (Ellipse2D) s;
            this.sb.append("<ellipse ");
            appendOptionalElementIDFromHint(this.sb);
            this.sb.append("cx=\"").append(geomDP(e.getCenterX()))
                    .append("\" cy=\"").append(geomDP(e.getCenterY()))
                    .append("\" rx=\"").append(geomDP(e.getWidth() / 2.0))
                    .append("\" ry=\"").append(geomDP(e.getHeight() / 2.0))
                    .append("\" ");
            this.sb.append("style=\"").append(strokeStyle())
                    .append("; fill: none").append("\" ");
            if (!this.transform.isIdentity()) {
            	this.sb.append("transform=\"").append(getSVGTransform(
            		this.transform)).append("\" ");
            }
            this.sb.append(getClipPathRef());
            this.sb.append("/>");        
        } else if (s instanceof Path2D) {
            Path2D path = (Path2D) s;
            this.sb.append("<g ");
            appendOptionalElementIDFromHint(this.sb);
            this.sb.append("style=\"").append(strokeStyle())
                    .append("; fill: none").append("\" ");
            if (!this.transform.isIdentity()) {
            	this.sb.append("transform=\"").append(getSVGTransform(
            		this.transform)).append("\" ");
            }
            this.sb.append(getClipPathRef());
            this.sb.append(">");
            this.sb.append("<path ").append(getSVGPathData(path)).append("/>");
            this.sb.append("</g>");
        } else {
            draw(new GeneralPath(s)); // handled as a Path2D next time through
        }
    }
Draws the specified shape with the current {@code paint} and
{@code stroke}.  There is direct handling for {@code Line2D},
{@code Rectangle2D}, {@code Ellipse2D} and {@code Path2D}.  All other
shapes are mapped to a {@code GeneralPath} and then drawn (effectively
as {@code Path2D} objects).

@param s  the shape ({@code null} not permitted).

@see #fill(java.awt.Shape)