Initial revision


git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/batik/trunk@198777 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/sources/org/apache/batik/parser/AWTPathProducer.java b/sources/org/apache/batik/parser/AWTPathProducer.java
new file mode 100644
index 0000000..d53743f
--- /dev/null
+++ b/sources/org/apache/batik/parser/AWTPathProducer.java
@@ -0,0 +1,295 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+import java.awt.Shape;
+import java.awt.geom.Point2D;
+import java.io.IOException;
+import java.io.Reader;
+import org.apache.batik.gvt.ExtendedGeneralPath;
+
+/**
+ * This class provides an implementation of the PathHandler that initializes
+ * a Shape from the value of a path's 'd' attribute.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public class AWTPathProducer implements PathHandler, ShapeProducer {
+    /**
+     * The temporary value of extendedGeneralPath.
+     */
+    protected ExtendedGeneralPath path;
+
+    /**
+     * The current x position.
+     */
+    protected float currentX;
+
+    /**
+     * The current y position.
+     */
+    protected float currentY;
+
+    /**
+     * The reference x point for smooth arcs.
+     */
+    protected float xCenter;
+
+    /**
+     * The reference y point for smooth arcs.
+     */
+    protected float yCenter;
+
+    /**
+     * The winding rule to use to construct the path.
+     */
+    protected int windingRule;
+
+    /**
+     * Utility method for creating an ExtendedGeneralPath.
+     * @param r The reader used to read the path specification.
+     * @param wr The winding rule to use for creating the path.
+     * @param pf The parser factory to use.
+     */
+    public static Shape createShape(Reader r, int wr, ParserFactory pf)
+	throws IOException,
+	       ParseException {
+	PathParser p = pf.createPathParser();
+	AWTPathProducer ph = new AWTPathProducer();
+
+	ph.setWindingRule(wr);
+	p.setPathHandler(ph);
+	p.parse(r);
+
+	return ph.getShape();
+    }
+
+    /**
+     * Sets the winding rule used to construct the path.
+     */
+    public void setWindingRule(int i) {
+	windingRule = i;
+    }
+
+    /**
+     * Returns the current winding rule.
+     */
+    public int getWindingRule() {
+	return windingRule;
+    }
+
+    /**
+     * Returns the Shape object initialized during the last parsing.
+     * @return the shape or null if this handler has not been used by
+     *         a parser.
+     */
+    public Shape getShape() {
+	return path;
+    }
+
+    /**
+     * Implements {@link PathHandler#startPath()}.
+     */
+    public void startPath() throws ParseException {
+	currentX = 0;
+	currentY = 0;
+	xCenter = 0;
+	yCenter = 0;
+	path = new ExtendedGeneralPath(windingRule);
+    }
+
+    /**
+     * Implements {@link PathHandler#endPath()}.
+     */
+    public void endPath() throws ParseException {
+    }
+
+    /**
+     * Implements {@link PathHandler#movetoRel(float,float)}.
+     */
+    public void movetoRel(float x, float y) throws ParseException {
+	path.moveTo(xCenter = currentX += x, yCenter = currentY += y);
+    }
+
+    /**
+     * Implements {@link PathHandler#movetoAbs(float,float)}.
+     */
+    public void movetoAbs(float x, float y) throws ParseException {
+	path.moveTo(xCenter = currentX = x, yCenter = currentY = y);
+    }
+
+    /**
+     * Implements {@link PathHandler#closePath()}.
+     */
+    public void closePath() throws ParseException {
+	path.closePath();
+	Point2D pt = path.getCurrentPoint();
+	currentX = (float)pt.getX();
+	currentY = (float)pt.getY();
+    }
+
+    /**
+     * Implements {@link PathHandler#linetoRel(float,float)}.
+     */
+    public void linetoRel(float x, float y) throws ParseException {
+	path.lineTo(xCenter = currentX += x, yCenter = currentY += y);
+    }
+
+    /**
+     * Implements {@link PathHandler#linetoAbs(float,float)}.
+     */
+    public void linetoAbs(float x, float y) throws ParseException {
+	path.lineTo(xCenter = currentX = x, yCenter = currentY = y);
+    }
+
+    /**
+     * Implements {@link PathHandler#linetoHorizontalRel(float)}.
+     */
+    public void linetoHorizontalRel(float x) throws ParseException {
+	path.lineTo(xCenter = currentX += x, yCenter = currentY);
+    }
+
+    /**
+     * Implements {@link PathHandler#linetoHorizontalAbs(float)}.
+     */
+    public void linetoHorizontalAbs(float x) throws ParseException {
+	path.lineTo(xCenter = currentX = x, yCenter = currentY);
+    }
+
+    /**
+     * Implements {@link PathHandler#linetoVerticalRel(float)}.
+     */
+    public void linetoVerticalRel(float y) throws ParseException {
+	path.lineTo(xCenter = currentX, yCenter = currentY += y);
+    }
+
+    /**
+     * Implements {@link PathHandler#linetoVerticalAbs(float)}.
+     */
+    public void linetoVerticalAbs(float y) throws ParseException {
+	path.lineTo(xCenter = currentX, yCenter = currentY = y);
+    }
+
+    /**
+     * Implements {@link
+     * PathHandler#curvetoCubicRel(float,float,float,float,float,float)}.
+     */
+    public void curvetoCubicRel(float x1, float y1, 
+				float x2, float y2, 
+				float x, float y) throws ParseException {
+	path.curveTo(currentX + x1, currentY + y1,
+		     xCenter = currentX + x2, yCenter = currentY + y2,
+		     currentX += x, currentY += y);
+    }
+
+    /**
+     * Implements {@link
+     * PathHandler#curvetoCubicAbs(float,float,float,float,float,float)}.
+     */
+    public void curvetoCubicAbs(float x1, float y1, 
+				float x2, float y2, 
+				float x, float y) throws ParseException {
+	path.curveTo(x1, y1, xCenter = x2, yCenter = y2, currentX = x,
+                     currentY = y);
+    }
+
+    /**
+     * Implements
+     * {@link PathHandler#curvetoCubicSmoothRel(float,float,float,float)}.
+     */
+    public void curvetoCubicSmoothRel(float x2, float y2, 
+				      float x, float y) throws ParseException {
+	path.curveTo(currentX * 2 - xCenter,
+		     currentY * 2 - yCenter,
+		     xCenter = currentX + x2,
+		     yCenter = currentY + y2,
+		     currentX += x,
+		     currentY += y);
+    }
+
+    /**
+     * Implements
+     * {@link PathHandler#curvetoCubicSmoothAbs(float,float,float,float)}.
+     */
+    public void curvetoCubicSmoothAbs(float x2, float y2, 
+				      float x, float y) throws ParseException {
+	path.curveTo(currentX * 2 - xCenter,
+		     currentY * 2 - yCenter,
+		     xCenter = x2,
+		     yCenter = y2,
+		     currentX = x,
+		     currentY = y);
+    }
+
+    /**
+     * Implements
+     * {@link PathHandler#curvetoQuadraticRel(float,float,float,float)}.
+     */
+    public void curvetoQuadraticRel(float x1, float y1, 
+				    float x, float y) throws ParseException {
+	path.quadTo(xCenter = currentX + x1, yCenter = currentY + y1,
+		    currentX += x, currentY += y);
+    }
+
+    /**
+     * Implements
+     * {@link PathHandler#curvetoQuadraticAbs(float,float,float,float)}.
+     */
+    public void curvetoQuadraticAbs(float x1, float y1, 
+				    float x, float y) throws ParseException {
+	path.quadTo(xCenter = x1, yCenter = y1, currentX = x, currentY = y);
+    }
+
+    /**
+     * Implements {@link PathHandler#curvetoQuadraticSmoothRel(float,float)}.
+     */
+    public void curvetoQuadraticSmoothRel(float x, float y)
+        throws ParseException {
+	path.quadTo(xCenter = currentX * 2 - xCenter,
+		    yCenter = currentY * 2 - yCenter,
+		    currentX += x,
+		    currentY += y);
+    }
+
+    /**
+     * Implements {@link PathHandler#curvetoQuadraticSmoothAbs(float,float)}.
+     */
+    public void curvetoQuadraticSmoothAbs(float x, float y)
+        throws ParseException {
+	path.quadTo(xCenter = currentX * 2 - xCenter,
+		    yCenter = currentY * 2 - yCenter,
+		    currentX = x,
+		    currentY = y);
+    }
+
+    /**
+     * Implements {@link
+     * PathHandler#arcRel(float,float,float,boolean,boolean,float,float)}.
+     */
+    public void arcRel(float rx, float ry, 
+		       float xAxisRotation, 
+		       boolean largeArcFlag, boolean sweepFlag, 
+		       float x, float y) throws ParseException {
+	path.arcTo(rx, ry, xAxisRotation, largeArcFlag, sweepFlag,
+		   xCenter = currentX += x, yCenter = currentY += y);
+    }
+
+    /**
+     * Implements {@link
+     * PathHandler#arcAbs(float,float,float,boolean,boolean,float,float)}.
+     */
+    public void arcAbs(float rx, float ry, 
+		       float xAxisRotation, 
+		       boolean largeArcFlag, boolean sweepFlag, 
+		       float x, float y) throws ParseException {
+	path.arcTo(rx, ry, xAxisRotation, largeArcFlag, sweepFlag,
+		   xCenter = currentX = x, yCenter = currentY = y);
+    }
+}
diff --git a/sources/org/apache/batik/parser/AWTPolygonProducer.java b/sources/org/apache/batik/parser/AWTPolygonProducer.java
new file mode 100644
index 0000000..136b26a
--- /dev/null
+++ b/sources/org/apache/batik/parser/AWTPolygonProducer.java
@@ -0,0 +1,48 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+import java.awt.Shape;
+import java.awt.geom.GeneralPath;
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ * This class produces a polygon shape from a reader.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public class AWTPolygonProducer extends AWTPolylineProducer {
+    /**
+     * Utility method for creating an ExtendedGeneralPath.
+     * @param r The reader used to read the path specification.
+     * @param wr The winding rule to use for creating the path.
+     * @param pf The parser factory to use.
+     */
+    public static Shape createShape(Reader r, int wr, ParserFactory pf)
+        throws IOException,
+               ParseException {
+        PointsParser p = pf.createPointsParser();
+        AWTPolygonProducer ph = new AWTPolygonProducer();
+
+        ph.setWindingRule(wr);
+        p.setPointsHandler(ph);
+        p.parse(r);
+
+        return ph.getShape();
+    }
+
+    /**
+     * Implements {@link PointsHandler#endPoints()}.
+     */
+    public void endPoints() throws ParseException {
+        path.closePath();
+    }
+}
diff --git a/sources/org/apache/batik/parser/AWTPolylineProducer.java b/sources/org/apache/batik/parser/AWTPolylineProducer.java
new file mode 100644
index 0000000..b8a1a36
--- /dev/null
+++ b/sources/org/apache/batik/parser/AWTPolylineProducer.java
@@ -0,0 +1,105 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+import java.awt.Shape;
+import java.awt.geom.GeneralPath;
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ * This class produces a polyline shape from a reader.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public class AWTPolylineProducer implements PointsHandler, ShapeProducer {
+    /**
+     * The current path.
+     */
+    protected GeneralPath path;
+
+    /**
+     * Is the current path a new one?
+     */
+    protected boolean newPath;
+
+    /**
+     * The winding rule to use to construct the path.
+     */
+    protected int windingRule;
+
+    /**
+     * Utility method for creating an ExtendedGeneralPath.
+     * @param r The reader used to read the path specification.
+     * @param wr The winding rule to use for creating the path.
+     * @param pf The parser factory to use.
+     */
+    public static Shape createShape(Reader r, int wr, ParserFactory pf)
+        throws IOException,
+               ParseException {
+        PointsParser p = pf.createPointsParser();
+        AWTPolylineProducer ph = new AWTPolylineProducer();
+
+        ph.setWindingRule(wr);
+        p.setPointsHandler(ph);
+        p.parse(r);
+
+        return ph.getShape();
+    }
+
+    /**
+     * Sets the winding rule used to construct the path.
+     */
+    public void setWindingRule(int i) {
+        windingRule = i;
+    }
+
+    /**
+     * Returns the current winding rule.
+     */
+    public int getWindingRule() {
+        return windingRule;
+    }
+
+    /**
+     * Returns the Shape object initialized during the last parsing.
+     * @return the shape or null if this handler has not been used by
+     *         a parser.
+     */
+    public Shape getShape() {
+        return path;
+    }
+
+    /**
+     * Implements {@link PointsHandler#startPoints()}.
+     */
+    public void startPoints() throws ParseException {
+        path = new GeneralPath(windingRule);
+        newPath = true;
+    }
+
+    /**
+     * Implements {@link PointsHandler#point(float,float)}.
+     */
+    public void point(float x, float y) throws ParseException {
+        if (newPath) {
+            newPath = false;
+            path.moveTo(x, y);
+        } else {
+            path.lineTo(x, y);
+        }
+    }
+
+    /**
+     * Implements {@link PointsHandler#endPoints()}.
+     */
+    public void endPoints() throws ParseException {
+    }
+}
diff --git a/sources/org/apache/batik/parser/AWTTransformProducer.java b/sources/org/apache/batik/parser/AWTTransformProducer.java
new file mode 100644
index 0000000..536f14c
--- /dev/null
+++ b/sources/org/apache/batik/parser/AWTTransformProducer.java
@@ -0,0 +1,138 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+import java.awt.geom.AffineTransform;
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ * This class provides an implementation of the PathHandler that initializes
+ * an AffineTransform from the value of a 'transform' attribute.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public class AWTTransformProducer implements TransformListHandler {
+    /**
+     * The value of the current affine transform.
+     */
+    protected AffineTransform affineTransform;
+
+    /**
+     * Utility method for creating an AffineTransform.
+     * @param r The reader used to read the transform specification.
+     * @param pf The parser factory to use.
+     */
+    public static AffineTransform createAffineTransform(Reader r,
+                                                        ParserFactory pf)
+        throws ParseException {
+        TransformListParser p = pf.createTransformListParser();
+        AWTTransformProducer th = new AWTTransformProducer();
+        
+        p.setTransformListHandler(th);
+        p.parse(r);
+
+        return th.getAffineTransform();
+    }
+
+    /**
+     * Returns the AffineTransform object initialized during the last parsing.
+     * @return the transform or null if this handler has not been used by
+     *         a parser.
+     */
+    public AffineTransform getAffineTransform() {
+        return affineTransform;
+    }
+
+    /**
+     * Implements {@link TransformListHandler#startTransformList()}.
+     */
+    public void startTransformList() throws ParseException {
+        affineTransform = new AffineTransform();
+    }
+
+    /**
+     * Implements {@link
+     * TransformListHandler#matrix(float,float,float,float,float,float)}.
+     */
+    public void matrix(float a, float b, float c, float d, float e, float f)
+	throws ParseException {
+        affineTransform.concatenate(new AffineTransform(a, b, c, d, e, f));
+    }
+
+    /**
+     * Implements {@link TransformListHandler#rotate(float)}.
+     */
+    public void rotate(float theta) throws ParseException {
+        affineTransform.concatenate
+            (AffineTransform.getRotateInstance(Math.PI * theta / 180));
+    }
+
+    /**
+     * Implements {@link TransformListHandler#rotate(float,float,float)}.
+     */
+    public void rotate(float theta, float cx, float cy) throws ParseException {
+        AffineTransform at 
+            = AffineTransform.getRotateInstance(Math.PI * theta / 180, cx, cy);
+        affineTransform.concatenate(at);
+    }
+
+    /**
+     * Implements {@link TransformListHandler#translate(float)}.
+     */
+    public void translate(float tx) throws ParseException {
+        AffineTransform at = AffineTransform.getTranslateInstance(tx, 0);
+        affineTransform.concatenate(at);
+    }
+
+    /**
+     * Implements {@link TransformListHandler#translate(float,float)}.
+     */
+    public void translate(float tx, float ty) throws ParseException {
+        AffineTransform at = AffineTransform.getTranslateInstance(tx, ty);
+        affineTransform.concatenate(at);
+    }
+
+    /**
+     * Implements {@link TransformListHandler#scale(float)}.
+     */
+    public void scale(float sx) throws ParseException {
+        affineTransform.concatenate(AffineTransform.getScaleInstance(sx, sx));
+    }
+
+    /**
+     * Implements {@link TransformListHandler#scale(float,float)}.
+     */
+    public void scale(float sx, float sy) throws ParseException {
+        affineTransform.concatenate(AffineTransform.getScaleInstance(sx, sy));
+    }
+
+    /**
+     * Implements {@link TransformListHandler#skewX(float)}.
+     */
+    public void skewX(float skx) throws ParseException {
+        affineTransform.concatenate
+            (AffineTransform.getShearInstance(Math.PI * skx / 180, 0));
+    }
+
+    /**
+     * Implements {@link TransformListHandler#skewY(float)}.
+     */
+    public void skewY(float sky) throws ParseException {
+        affineTransform.concatenate
+            (AffineTransform.getShearInstance(0, Math.PI * sky / 180));
+    }
+
+    /**
+     * Implements {@link TransformListHandler#endTransformList()}.
+     */
+    public void endTransformList() throws ParseException {
+    }
+}
diff --git a/sources/org/apache/batik/parser/Angle.java b/sources/org/apache/batik/parser/Angle.java
new file mode 100644
index 0000000..b0f1f0d
--- /dev/null
+++ b/sources/org/apache/batik/parser/Angle.java
@@ -0,0 +1,44 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface represents objects which hold informations about
+ * SVG angles.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface Angle {
+    // The values returned by getType(). 
+    /**
+     * To represent an angle in degrees.
+     */
+    int DEG = 0;
+    
+    /**
+     * To represent an angle in radians.
+     */
+    int RAD = 1;
+    
+    /**
+     * To represent an angle in gradians.
+     */
+    int GRAD = 2;
+    
+    /**
+     * Returns this angle type.
+     */
+    int getType();
+
+    /**
+     * Returns this angle value.
+     */
+    float getValue();
+}
diff --git a/sources/org/apache/batik/parser/AngleHandler.java b/sources/org/apache/batik/parser/AngleHandler.java
new file mode 100644
index 0000000..0e30cb7
--- /dev/null
+++ b/sources/org/apache/batik/parser/AngleHandler.java
@@ -0,0 +1,55 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface must be implemented and then registred as the
+ * handler of a <code>AngleParser</code> instance in order to be
+ * notified of parsing events.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface AngleHandler {
+    /**
+     * Invoked when the angle attribute parsing starts.
+     * @exception ParseException if an error occured while processing the angle
+     */
+    void startAngle() throws ParseException;
+
+    /**
+     * Invoked when a float value has been parsed.
+     * @exception ParseException if an error occured while processing the angle
+     */
+    void angleValue(float v) throws ParseException;
+
+    /**
+     * Invoked when 'deg' has been parsed.
+     * @exception ParseException if an error occured while processing the angle
+     */
+    void deg() throws ParseException;
+
+    /**
+     * Invoked when 'grad' has been parsed.
+     * @exception ParseException if an error occured while processing the angle
+     */
+    void grad() throws ParseException;
+
+    /**
+     * Invoked when 'rad' has been parsed.
+     * @exception ParseException if an error occured while processing the angle
+     */
+    void rad() throws ParseException;
+
+    /**
+     * Invoked when the angle attribute parsing ends.
+     * @exception ParseException if an error occured while processing the angle
+     */
+    void endAngle() throws ParseException;
+}
diff --git a/sources/org/apache/batik/parser/AngleParser.java b/sources/org/apache/batik/parser/AngleParser.java
new file mode 100644
index 0000000..ca50719
--- /dev/null
+++ b/sources/org/apache/batik/parser/AngleParser.java
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface represents an event-based parser for the SVG angle
+ * values.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface AngleParser extends Parser {
+    /**
+     * Allows an application to register an angle handler.
+     *
+     * <p>If the application does not register a handler, all
+     * events reported by the parser will be silently ignored.
+     *
+     * <p>Applications may register a new or different handler in the
+     * middle of a parse, and the parser must begin using the new
+     * handler immediately.</p>
+     * @param handler The angle handler.
+     */
+    void setAngleHandler(AngleHandler handler);
+
+    /**
+     * Returns the angle handler in use.
+     */
+    AngleHandler getAngleHandler();
+}
diff --git a/sources/org/apache/batik/parser/Clock.java b/sources/org/apache/batik/parser/Clock.java
new file mode 100644
index 0000000..d27abd5
--- /dev/null
+++ b/sources/org/apache/batik/parser/Clock.java
@@ -0,0 +1,38 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface represents objects which hold informations about
+ * SVG clock values.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface Clock {
+    /**
+     * Returns the int value representing the hours.
+     */
+    int getHours();
+
+    /**
+     * Returns the int value representing the minutes.
+     */
+    int getMinutes();
+
+    /**
+     * Returns the int value representing the seconds.
+     */
+    int getSeconds();
+
+    /**
+     * Returns the float value representing the milliseconds.
+     */
+    float getMilliseconds();
+}
diff --git a/sources/org/apache/batik/parser/ClockHandler.java b/sources/org/apache/batik/parser/ClockHandler.java
new file mode 100644
index 0000000..ff98c22
--- /dev/null
+++ b/sources/org/apache/batik/parser/ClockHandler.java
@@ -0,0 +1,73 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface must be implemented and then registred as the
+ * handler of a <code>ClockParser</code> instance in order to be
+ * notified of parsing events.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface ClockHandler {
+    /**
+     * Invoked when the clock attribute parsing starts.
+     * @exception ParseException if an error occured while processing the clock
+     */
+    void startClock() throws ParseException;
+
+    /**
+     * Invoked when an int value has been parsed.
+     * @exception ParseException if an error occured while processing the clock
+     */
+    void intValue(int v) throws ParseException;
+
+    /**
+     * Invoked when ':' has been parsed.
+     * @exception ParseException if an error occured while processing the clock
+     */
+    void colon() throws ParseException;
+
+    /**
+     * Invoked when '.' has been parsed.
+     * @exception ParseException if an error occured while processing the clock
+     */
+    void dot() throws ParseException;
+
+    /**
+     * Invoked when 'h' has been parsed.
+     * @exception ParseException if an error occured while processing the clock
+     */
+    void h() throws ParseException;
+
+    /**
+     * Invoked when 'min' has been parsed.
+     * @exception ParseException if an error occured while processing the clock
+     */
+    void min() throws ParseException;
+
+    /**
+     * Invoked when 's' has been parsed.
+     * @exception ParseException if an error occured while processing the clock
+     */
+    void s() throws ParseException;
+
+    /**
+     * Invoked when 'ms' has been parsed.
+     * @exception ParseException if an error occured while processing the clock
+     */
+    void ms() throws ParseException;
+
+    /**
+     * Invoked when the clock attribute parsing ends.
+     * @exception ParseException if an error occured while processing the clock
+     */
+    void endClock() throws ParseException;
+}
diff --git a/sources/org/apache/batik/parser/ClockParser.java b/sources/org/apache/batik/parser/ClockParser.java
new file mode 100644
index 0000000..3709ddb
--- /dev/null
+++ b/sources/org/apache/batik/parser/ClockParser.java
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface represents an event-based parser for the SVG clock
+ * values.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface ClockParser extends Parser {
+    /**
+     * Allows an application to register an clock handler.
+     *
+     * <p>If the application does not register a handler, all
+     * events reported by the parser will be silently ignored.
+     *
+     * <p>Applications may register a new or different handler in the
+     * middle of a parse, and the parser must begin using the new
+     * handler immediately.</p>
+     * @param handler The clock handler.
+     */
+    void setClockHandler(ClockHandler handler);
+
+    /**
+     * Returns the clock handler in use.
+     */
+    ClockHandler getClockHandler();
+}
diff --git a/sources/org/apache/batik/parser/ErrorHandler.java b/sources/org/apache/batik/parser/ErrorHandler.java
new file mode 100644
index 0000000..36d5288
--- /dev/null
+++ b/sources/org/apache/batik/parser/ErrorHandler.java
@@ -0,0 +1,23 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface must be implemented and then registred as the error handler
+ * in order to be notified of parsing errors. 
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface ErrorHandler {
+    /**
+     * Called when a parse error occurs.
+     */
+    void error(ParseException e) throws ParseException;
+}
diff --git a/sources/org/apache/batik/parser/FragmentIdentifierHandler.java b/sources/org/apache/batik/parser/FragmentIdentifierHandler.java
new file mode 100644
index 0000000..263cd80
--- /dev/null
+++ b/sources/org/apache/batik/parser/FragmentIdentifierHandler.java
@@ -0,0 +1,58 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface must be implemented and then registred as the
+ * handler of a <code>PreserveAspectRatioParser</code> instance
+ * in order to be notified of parsing events.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface FragmentIdentifierHandler {
+    /**
+     * Invoked when the fragment identifier attribute starts.
+     * @exception ParseException if an error occured while processing the
+     *                           fragment identifier
+     */
+    void startFragmentIdentifier() throws ParseException;
+
+    /**
+     * Invoked when an ID has been parsed.
+     * @param s The string that represents the parsed ID.
+     * @exception ParseException if an error occured while processing the
+     *                           fragment identifier
+     */
+    void idReference(String s) throws ParseException;
+
+    /**
+     * Invoked when 'viewBox(x,y,width,height)' has been parsed.
+     * @param x&nbsp;y&nbsp;width&nbsp;height the coordinates of the viewbox.
+     * @exception ParseException if an error occured while processing the
+     *                           fragment identifier
+     */
+    void viewBox(float x, float y, float width, float height)
+        throws ParseException;
+
+    /**
+     * Invoked when 'viewTarget(name)' has been parsed.
+     * @param name the target name.
+     * @exception ParseException if an error occured while processing the
+     *                           fragment identifier
+     */
+    void viewTarget(String name) throws ParseException;
+
+    /**
+     * Invoked when the points attribute ends.
+     * @exception ParseException if an error occured while processing the
+     *                           fragment identifier
+     */
+    void endFragmentIdentifier() throws ParseException;
+}
diff --git a/sources/org/apache/batik/parser/FragmentIdentifierParser.java b/sources/org/apache/batik/parser/FragmentIdentifierParser.java
new file mode 100644
index 0000000..f9ef9b2
--- /dev/null
+++ b/sources/org/apache/batik/parser/FragmentIdentifierParser.java
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface represents an event-based parser for the SVG
+ * fragment identifier (used with polyline and polygon elements).
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface FragmentIdentifierParser extends Parser {
+    /**
+     * Allows an application to register a fragment identifier handler.
+     *
+     * <p>If the application does not register a handler, all
+     * events reported by the parser will be silently ignored.
+     *
+     * <p>Applications may register a new or different handler in the
+     * middle of a parse, and the parser must begin using the new
+     * handler immediately.</p>
+     * @param handler The transform list handler.
+     */
+    void setPointsHandler(FragmentIdentifierHandler handler);
+
+    /**
+     * Returns the points handler in use.
+     */
+    FragmentIdentifierHandler getPointsHandler();
+}
diff --git a/sources/org/apache/batik/parser/Length.java b/sources/org/apache/batik/parser/Length.java
new file mode 100644
index 0000000..21eb593
--- /dev/null
+++ b/sources/org/apache/batik/parser/Length.java
@@ -0,0 +1,74 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface represents objects which hold informations about
+ * SVG lengths.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface Length {
+    // The values returned by getType(). 
+    /**
+     * To represent an length in centimeters.
+     */
+    int CM = 0;
+    
+    /**
+     * To represent an length in ems.
+     */
+    int EM = 1;
+    
+    /**
+     * To represent an length in exs.
+     */
+    int EX = 2;
+    
+    /**
+     * To represent an length in inches.
+     */
+    int IN = 3;
+    
+    /**
+     * To represent an length in millimeters.
+     */
+    int MM = 4;
+    
+    /**
+     * To represent an length in picas.
+     */
+    int PC = 5;
+    
+    /**
+     * To represent an length in points.
+     */
+    int PT = 6;
+    
+    /**
+     * To represent an length in pixels.
+     */
+    int PX = 7;
+    
+    /**
+     * To represent an length in percentage.
+     */
+    int PERCENTAGE = 8;
+    
+    /**
+     * Returns this length type.
+     */
+    int getType();
+
+    /**
+     * Returns this length value.
+     */
+    float getValue();
+}
diff --git a/sources/org/apache/batik/parser/LengthHandler.java b/sources/org/apache/batik/parser/LengthHandler.java
new file mode 100644
index 0000000..2410663
--- /dev/null
+++ b/sources/org/apache/batik/parser/LengthHandler.java
@@ -0,0 +1,103 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface must be implemented and then registred as the
+ * handler of a <code>LengthParser</code> instance in order to be
+ * notified of parsing events.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface LengthHandler {
+    /**
+     * Invoked when the length attribute starts.
+     * @exception ParseException if an error occures while processing
+     *                           the length
+     */
+    void startLength() throws ParseException;
+
+    /**
+     * Invoked when a float value has been parsed.
+     * @exception ParseException if an error occures while processing
+     *                           the length
+     */
+    void lengthValue(float v) throws ParseException;
+
+    /**
+     * Invoked when 'em' has been parsed.
+     * @exception ParseException if an error occures while processing
+     *                           the length
+     */
+    void em() throws ParseException;
+
+    /**
+     * Invoked when 'ex' has been parsed.
+     * @exception ParseException if an error occures while processing
+     *                           the length
+     */
+    void ex() throws ParseException;
+
+    /**
+     * Invoked when 'in' has been parsed.
+     * @exception ParseException if an error occures while processing
+     *                           the length
+     */
+    void in() throws ParseException;
+
+    /**
+     * Invoked when 'cm' has been parsed.
+     * @exception ParseException if an error occures while processing
+     *                           the length
+     */
+    void cm() throws ParseException;
+
+    /**
+     * Invoked when 'mm' has been parsed.
+     * @exception ParseException if an error occures while processing
+     *                           the length
+     */
+    void mm() throws ParseException;
+
+    /**
+     * Invoked when 'pc' has been parsed.
+     * @exception ParseException if an error occures while processing
+     *                           the length
+     */
+    void pc() throws ParseException;
+
+    /**
+     * Invoked when 'pt' has been parsed.
+     * @exception ParseException if an error occures while processing
+     *                           the length
+     */
+    void pt() throws ParseException;
+
+    /**
+     * Invoked when 'px' has been parsed.
+     * @exception ParseException if an error occures while processing
+     *                           the length
+     */
+    void px() throws ParseException;
+
+    /**
+     * Invoked when '%' has been parsed.
+     * @exception ParseException if an error occures while processing
+     *                           the length
+     */
+    void percentage() throws ParseException;
+
+    /**
+     * Invoked when the length attribute ends.
+     * @exception ParseException if an error occures while processing
+     *                           the length
+     */
+    void endLength() throws ParseException;
+}
diff --git a/sources/org/apache/batik/parser/LengthListHandler.java b/sources/org/apache/batik/parser/LengthListHandler.java
new file mode 100644
index 0000000..5978097
--- /dev/null
+++ b/sources/org/apache/batik/parser/LengthListHandler.java
@@ -0,0 +1,34 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface must be implemented and then registred as the
+ * handler of a <code>LengthListParser</code> instance in order to be
+ * notified of parsing events.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+
+public interface LengthListHandler extends LengthHandler {
+    /**
+     * Invoked when the length list attribute starts.
+     * @exception ParseException if an error occures while processing the
+     *                           length list.
+     */
+    void startLengthList() throws ParseException;
+
+    /**
+     * Invoked when the length attribute ends.
+     * @exception ParseException if an error occures while processing the
+     *                           length list.
+     */
+    void endLengthList() throws ParseException;
+}
diff --git a/sources/org/apache/batik/parser/LengthListParser.java b/sources/org/apache/batik/parser/LengthListParser.java
new file mode 100644
index 0000000..94e646f
--- /dev/null
+++ b/sources/org/apache/batik/parser/LengthListParser.java
@@ -0,0 +1,39 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ * This interface represents an event-based parser for the SVG length
+ * list values.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface LengthListParser extends Parser {
+    /**
+     * Allows an application to register a length list handler.
+     *
+     * <p>If the application does not register a handler, all
+     * events reported by the parser will be silently ignored.
+     *
+     * <p>Applications may register a new or different handler in the
+     * middle of a parse, and the parser must begin using the new
+     * handler immediately.</p>
+     * @param handler The transform list handler.
+     */
+    void setLengthListHandler(LengthListHandler handler);
+
+    /**
+     * Returns the length list handler in use.
+     */
+    LengthListHandler getLengthListHandler();
+}
diff --git a/sources/org/apache/batik/parser/LengthParser.java b/sources/org/apache/batik/parser/LengthParser.java
new file mode 100644
index 0000000..7b591cb
--- /dev/null
+++ b/sources/org/apache/batik/parser/LengthParser.java
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface represents an event-based parser for the SVG length
+ * values.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface LengthParser extends Parser {
+    /**
+     * Allows an application to register a length handler.
+     *
+     * <p>If the application does not register a handler, all
+     * events reported by the parser will be silently ignored.
+     *
+     * <p>Applications may register a new or different handler in the
+     * middle of a parse, and the parser must begin using the new
+     * handler immediately.</p>
+     * @param handler The transform list handler.
+     */
+    void setLengthHandler(LengthHandler handler);
+
+    /**
+     * Returns the length handler in use.
+     */
+    LengthHandler getLengthHandler();
+}
diff --git a/sources/org/apache/batik/parser/ParseException.java b/sources/org/apache/batik/parser/ParseException.java
new file mode 100644
index 0000000..fd81f4b
--- /dev/null
+++ b/sources/org/apache/batik/parser/ParseException.java
@@ -0,0 +1,118 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This class encapsulates a general parse error or warning.
+ *
+ * <p>This class can contain basic error or warning information from
+ * either the parser or the application.
+ *
+ * <p>If the application needs to pass through other types of
+ * exceptions, it must wrap those exceptions in a ParseException.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public class ParseException extends RuntimeException {
+    /**
+     * @serial The embedded exception if tunnelling, or null.
+     */    
+    protected Exception exception;
+    
+    /**
+     * @serial The line number.
+     */
+    protected int lineNumber;
+
+    /**
+     * @serial The column number.
+     */
+    protected int columnNumber;
+
+    /**
+     * Creates a new ParseException.
+     * @param message The error or warning message.
+     * @param line The line of the last parsed character.
+     * @param column The column of the last parsed character.
+     */
+    public ParseException (String message, int line, int column) {
+	super(message);
+	exception = null;
+	lineNumber = line;
+	columnNumber = column;
+    }
+    
+    /**
+     * Creates a new ParseException wrapping an existing exception.
+     *
+     * <p>The existing exception will be embedded in the new
+     * one, and its message will become the default message for
+     * the ParseException.
+     * @param e The exception to be wrapped in a ParseException.
+     */
+    public ParseException (Exception e) {
+	exception = e;
+	lineNumber = -1;
+	columnNumber = -1;
+    }
+    
+    /**
+     * Creates a new ParseException from an existing exception.
+     *
+     * <p>The existing exception will be embedded in the new
+     * one, but the new exception will have its own message.
+     * @param message The detail message.
+     * @param e The exception to be wrapped in a SAXException.
+     */
+    public ParseException (String message, Exception e) {
+	super(message);
+	this.exception = e;
+    }
+    
+    /**
+     * Return a detail message for this exception.
+     *
+     * <p>If there is a embedded exception, and if the ParseException
+     * has no detail message of its own, this method will return
+     * the detail message from the embedded exception.
+     * @return The error or warning message.
+     */
+    public String getMessage () {
+	String message = super.getMessage();
+	
+	if (message == null && exception != null) {
+	    return exception.getMessage();
+	} else {
+	    return message;
+	}
+    }
+    
+    /**
+     * Return the embedded exception, if any.
+     * @return The embedded exception, or null if there is none.
+     */
+    public Exception getException () {
+	return exception;
+    }
+
+    /**
+     * Returns the line of the last parsed character.
+     */
+    public int getLineNumber() {
+	return lineNumber;
+    }
+
+    /**
+     * Returns the column of the last parsed character.
+     */
+    public int getColumnNumber() {
+	return columnNumber;
+    }
+}
diff --git a/sources/org/apache/batik/parser/Parser.java b/sources/org/apache/batik/parser/Parser.java
new file mode 100644
index 0000000..3fa7a75
--- /dev/null
+++ b/sources/org/apache/batik/parser/Parser.java
@@ -0,0 +1,41 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Locale;
+import org.apache.batik.i18n.Localizable;
+
+/**
+ * This interface represents a parser.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface Parser extends Localizable {
+    /**
+     * Parses the given reader representing an angle.
+     */
+    void parse(Reader r) throws ParseException;
+
+    /**
+     * Allows an application to register an error event handler.
+     *
+     * <p>If the application does not register an error event handler,
+     * all error events reported by the parser will cause an exception
+     * to be thrown.
+     *
+     * <p>Applications may register a new or different handler in the
+     * middle of a parse, and the parser must begin using the new
+     * handler immediately.</p>
+     * @param handler The error handler.
+     */
+    void setErrorHandler(ErrorHandler handler);
+}
diff --git a/sources/org/apache/batik/parser/ParserFactory.java b/sources/org/apache/batik/parser/ParserFactory.java
new file mode 100644
index 0000000..e205a52
--- /dev/null
+++ b/sources/org/apache/batik/parser/ParserFactory.java
@@ -0,0 +1,62 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface represents a factory of micro-parser.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface ParserFactory {
+    /**
+     * Creates and returns an angle parser.
+     */
+    AngleParser createAngleParser();
+
+    /**
+     * Creates and returns a clock parser.
+     */
+    ClockParser createClockParser();
+
+    /**
+     * Creates and returns a fragment identifier parser.
+     */
+    FragmentIdentifierParser createFragmentIdentifierParser();
+
+    /**
+     * Creates and returns a length parser.
+     */
+    LengthParser createLengthParser();
+    
+    /**
+     * Creates and returns a length list parser.
+     */
+    LengthParser createLengthListParser();
+
+    /**
+     * Creates and returns a path parser.
+     */
+    PathParser createPathParser();
+
+    /**
+     * Creates and returns a points parser.
+     */
+    PointsParser createPointsParser();
+
+    /**
+     * Creates and returns a points parser.
+     */
+    PreserveAspectRatioParser createPreserveAspectRatioParser();
+
+    /**
+     * Creates and returns a transform list parser.
+     */
+    TransformListParser createTransformListParser();
+}
diff --git a/sources/org/apache/batik/parser/PathHandler.java b/sources/org/apache/batik/parser/PathHandler.java
new file mode 100644
index 0000000..c2b0d17
--- /dev/null
+++ b/sources/org/apache/batik/parser/PathHandler.java
@@ -0,0 +1,230 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface must be implemented and then registred as the
+ * handler of a <code>PathParser</code> instance in order to be
+ * notified of parsing events.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface PathHandler {
+    /**
+     * Invoked when the path starts.
+     * @exception ParseException if an error occured while processing the path
+     */
+    void startPath() throws ParseException;
+
+    /**
+     * Invoked when the path ends.
+     * @exception ParseException if an error occured while processing the path
+     */
+    void endPath() throws ParseException;
+
+    /**
+     * Invoked when a relative moveto command has been parsed.
+     * <p>Command : <b>m</b>
+     * @param x,&nbsp;y the relative coordinates for the end point
+     * @exception ParseException if an error occured while processing the path
+     */
+    void movetoRel(float x, float y) throws ParseException;
+
+    /**
+     * Invoked when an absolute moveto command has been parsed.
+     * <p>Command : <b>M</b>
+     * @param x,&nbsp;y the absolute coordinates for the end point
+     * @exception ParseException if an error occured while processing the path
+     */
+    void movetoAbs(float x, float y) throws ParseException;
+
+    /**
+     * Invoked when a closepath has been parsed.
+     * <p>Command : <b>z</b> | <b>Z</b>
+     * @exception ParseException if an error occured while processing the path
+     */
+    void closePath() throws ParseException;
+
+    /**
+     * Invoked when a relative line command has been parsed.
+     * <p>Command : <b>l</b>
+     * @param x,&nbsp;y the relative coordinates for the end point
+     * @exception ParseException if an error occured while processing the path
+     */
+    void linetoRel(float x, float y) throws ParseException;
+
+    /**
+     * Invoked when an absolute line command has been parsed.
+     * <p>Command : <b>L</b>
+     * @param x,&nbsp;y the absolute coordinates for the end point
+     * @exception ParseException if an error occured while processing the path
+     */
+    void linetoAbs(float x, float y) throws ParseException;
+
+    /**
+     * Invoked when an horizontal relative line command has been parsed.
+     * <p>Command : <b>h</b>
+     * @param x the relative X coordinate of the end point
+     * @exception ParseException if an error occured while processing the path
+     */
+    void linetoHorizontalRel(float x) throws ParseException;
+
+    /**
+     * Invoked when an horizontal absolute line command has been parsed.
+     * <p>Command : <b>H</b>
+     * @param x the absolute X coordinate of the end point
+     * @exception ParseException if an error occured while processing the path
+     */
+    void linetoHorizontalAbs(float x) throws ParseException;
+
+    /**
+     * Invoked when a vertical relative line command has been parsed.
+     * <p>Command : <b>v</b>
+     * @param y the relative Y coordinate of the end point
+     * @exception ParseException if an error occured while processing the path
+     */
+    void linetoVerticalRel(float y) throws ParseException;
+
+    /**
+     * Invoked when a vertical absolute line command has been parsed.
+     * <p>Command : <b>V</b>
+     * @param y the absolute Y coordinate of the end point
+     * @exception ParseException if an error occured while processing the path
+     */
+    void linetoVerticalAbs(float y) throws ParseException;
+
+    /**
+     * Invoked when a relative cubic bezier curve command has been parsed.
+     * <p>Command : <b>c</b>
+     * @param x1,&nbsp;y1 the relative coordinates for the first control point
+     * @param x2,&nbsp;y2 the relative coordinates for the second control point
+     * @param x,&nbsp;y the relative coordinates for the end point
+     * @exception ParseException if an error occured while processing the path
+     */
+    void curvetoCubicRel(float x1, float y1, 
+			 float x2, float y2, 
+			 float x, float y) throws ParseException;
+
+
+    /**
+     * Invoked when an absolute cubic bezier curve command has been parsed.
+     * <p>Command : <b>C</b>
+     * @param x1,&nbsp;y1 the absolute coordinates for the first control point
+     * @param x2,&nbsp;y2 the absolute coordinates for the second control point
+     * @param x,&nbsp;y the absolute coordinates for the end point
+     * @exception ParseException if an error occured while processing the path
+     */
+    void curvetoCubicAbs(float x1, float y1, 
+			 float x2, float y2, 
+			 float x, float y) throws ParseException;
+
+    /**
+     * Invoked when a relative smooth cubic bezier curve command has
+     * been parsed. The first control point is assumed to be the
+     * reflection of the second control point on the previous command
+     * relative to the current point.
+     * <p>Command : <b>s</b>
+     * @param x2,&nbsp;y2 the relative coordinates for the second control point
+     * @param x,&nbsp;y the relative coordinates for the end point
+     * @exception ParseException if an error occured while processing the path
+     */
+    void curvetoCubicSmoothRel(float x2, float y2, 
+			       float x, float y) throws ParseException;
+
+    /**
+     * Invoked when an absolute smooth cubic bezier curve command has
+     * been parsed. The first control point is assumed to be the
+     * reflection of the second control point on the previous command
+     * relative to the current point.
+     * <p>Command : <b>S</b>
+     * @param x2,&nbsp;y2 the absolute coordinates for the second control point
+     * @param x,&nbsp;y the absolute coordinates for the end point 
+     * @exception ParseException if an error occured while processing the path
+     */
+    void curvetoCubicSmoothAbs(float x2, float y2, 
+			       float x, float y) throws ParseException;
+
+    /**
+     * Invoked when a relative quadratic bezier curve command has been parsed.
+     * <p>Command : <b>q</b>
+     * @param x1,&nbsp;y1 the relative coordinates for the control point
+     * @param x,&nbsp;y the relative coordinates for the end point
+     * @exception ParseException if an error occured while processing the path
+     */
+    void curvetoQuadraticRel(float x1, float y1, 
+			     float x, float y) throws ParseException;
+
+    /**
+     * Invoked when an absolute quadratic bezier curve command has been parsed.
+     * <p>Command : <b>Q</b>
+     * @param x1,&nbsp;y1 the absolute coordinates for the control point
+     * @param x,&nbsp;y the absolute coordinates for the end point
+     * @exception ParseException if an error occured while processing the path
+     */
+    void curvetoQuadraticAbs(float x1, float y1, 
+			     float x, float y) throws ParseException;
+
+    /**
+     * Invoked when a relative smooth quadratic bezier curve command
+     * has been parsed. The control point is assumed to be the
+     * reflection of the control point on the previous command
+     * relative to the current point.
+     * <p>Command : <b>t</b>
+     * @param x,&nbsp;y the relative coordinates for the end point 
+     * @exception ParseException if an error occured while processing the path
+     */
+    void curvetoQuadraticSmoothRel(float x, float y) throws ParseException;
+
+    /**
+     * Invoked when an absolute smooth quadratic bezier curve command
+     * has been parsed. The control point is assumed to be the
+     * reflection of the control point on the previous command
+     * relative to the current point.
+     * <p>Command : <b>T</b>
+     * @param x,&nbsp;y the absolute coordinates for the end point 
+     * @exception ParseException if an error occured while processing the path
+     */
+    void curvetoQuadraticSmoothAbs(float x, float y) throws ParseException;
+
+    /**
+     * Invoked when a relative elliptical arc command has been parsed. 
+     * <p>Command : <b>a</b>
+     * @param rx the X axis radius for the ellipse
+     * @param ry the Y axis radius for the ellipse 
+     * @param angle the rotation angle in degrees for the ellipse's X-axis
+     * relative to the X-axis
+     * @param largeArcFlag the value of the large-arc-flag 
+     * @param sweepFlag the value of the sweep-flag 
+     * @param x,&nbsp;y the relative coordinates for the end point
+     * @exception ParseException if an error occured while processing the path
+     */
+    void arcRel(float rx, float ry, 
+		float xAxisRotation, 
+		boolean largeArcFlag, boolean sweepFlag, 
+		float x, float y) throws ParseException;
+
+
+    /**
+     * Invoked when an absolute elliptical arc command has been parsed.
+     * <p>Command : <b>A</b>
+     * @param rx the X axis radius for the ellipse
+     * @param ry the Y axis radius for the ellipse 
+     * @param angle the rotation angle in degrees for the ellipse's X-axis
+     * relative to the X-axis
+     * @param largeArcFlag the value of the large-arc-flag 
+     * @param sweepFlag the value of the sweep-flag 
+     * @param x,&nbsp;y the absolute coordinates for the end point
+     * @exception ParseException if an error occured while processing the path
+     */
+    void arcAbs(float rx, float ry, 
+		float xAxisRotation, 
+		boolean largeArcFlag, boolean sweepFlag, 
+		float x, float y) throws ParseException;
+}
diff --git a/sources/org/apache/batik/parser/PathParser.java b/sources/org/apache/batik/parser/PathParser.java
new file mode 100644
index 0000000..6c368e6
--- /dev/null
+++ b/sources/org/apache/batik/parser/PathParser.java
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface represents an event-based parser for the SVG path's d
+ * attribute values.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface PathParser extends Parser {
+    /**
+     * Allows an application to register a path handler.
+     *
+     * <p>If the application does not register a handler, all
+     * events reported by the parser will be silently ignored.
+     *
+     * <p>Applications may register a new or different handler in the
+     * middle of a parse, and the parser must begin using the new
+     * handler immediately.</p>
+     * @param handler The transform list handler.
+     */
+    void setPathHandler(PathHandler handler);
+
+    /**
+     * Returns the path handler in use.
+     */
+    PathHandler getPathHandler();
+}
diff --git a/sources/org/apache/batik/parser/PathSegment.java b/sources/org/apache/batik/parser/PathSegment.java
new file mode 100644
index 0000000..3c8b2f0
--- /dev/null
+++ b/sources/org/apache/batik/parser/PathSegment.java
@@ -0,0 +1,205 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface represents objects which hold informations about
+ * SVG path segments.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface PathSegment {
+    // The values returned by getType(). 
+    /**
+     * To represent a 'z' command.
+     */
+    char CLOSEPATH = 'z';
+
+    /**
+     * To represent a 'M' command.
+     */
+    char MOVETO_ABS = 'M';
+
+    /**
+     * To represent a 'm' command.
+     */
+    char MOVETO_REL = 'm';
+
+    /**
+     * To represent a 'L' command.
+     */
+    char LINETO_ABS = 'L';
+
+    /**
+     * To represent a 'l' command.
+     */
+    char LINETO_REL = 'l';
+
+    /**
+     * To represent a 'C' command.
+     */
+    char CURVETO_CUBIC_ABS = 'C';
+
+    /**
+     * To represent a 'c' command.
+     */
+    char CURVETO_CUBIC_REL = 'c';
+
+    /**
+     * To represent a 'Q' command.
+     */
+    char CURVETO_QUADRATIC_ABS = 'Q';
+
+    /**
+     * To represent a 'q' command.
+     */
+    char CURVETO_QUADRATIC_REL = 'q';
+
+    /**
+     * To represent a 'A' command.
+     */
+    char ARC_ABS = 'A';
+
+    /**
+     * To represent a 'a' command.
+     */
+    char ARC_REL = 'a';
+
+    /**
+     * To represent a 'H' command.
+     */
+    char LINETO_HORIZONTAL_ABS = 'H';
+
+    /**
+     * To represent a 'h' command.
+     */
+    char LINETO_HORIZONTAL_REL = 'h';
+
+    /**
+     * To represent a 'V' command.
+     */
+    char LINETO_VERTICAL_ABS = 'V';
+
+    /**
+     * To represent a 'v' command.
+     */
+    char LINETO_VERTICAL_REL = 'v';
+
+    /**
+     * To represent a 'S' command.
+     */
+    char CURVETO_CUBIC_SMOOTH_ABS = 'S';
+
+    /**
+     * To represent a 's' command.
+     */
+    char CURVETO_CUBIC_SMOOTH_REL = 's';
+
+    /**
+     * To represent a 'T' command.
+     */
+    char CURVETO_QUADRATIC_SMOOTH_ABS = 'T';
+
+    /**
+     * To represent a 't' command.
+     */
+    char CURVETO_QUADRATIC_SMOOTH_REL = 't';
+
+    /**
+     * Returns the type of this segment. It is also the command character.
+     */
+    char getType();
+
+    /**
+     * Returns the x coordinate of this segment's end point.
+     * @exception IllegalStateException if this segment type is CLOSEPATH,
+     *            LINETO_VERTICAL_ABS or LINETO_VERTICAL_REL. 
+     */
+    float getX();
+
+    /**
+     * Returns the y coordinate of this segment's end point.
+     * @exception IllegalStateException if this segment type is CLOSEPATH,
+     *            LINETO_HORIZONTAL_ABS or LINETO_HORIZONTAL_REL. 
+     */
+    float getY();
+
+    /**
+     * Returns the x coordinate of this segment's first control point if the
+     * type is CURVETO_CUBIC_ABS, CURVETO_CUBIC_REL, CURVETO_QUADRATIC_ABS
+     * or CURVETO_QUADRATIC_REL.
+     * @exception IllegalStateException if this segment type is not an
+     *            allowed one.
+     */
+    float getX1();
+
+    /**
+     * Returns the y coordinate of this segment's first control point if the
+     * type is CURVETO_CUBIC_ABS, CURVETO_CUBIC_REL, CURVETO_QUADRATIC_ABS
+     * or CURVETO_QUADRATIC_REL.
+     * @exception IllegalStateException if this segment type is not an
+     *            allowed one.
+     */
+    float getY1();
+
+    /**
+     * Returns the x coordinate of this segment's second control point if the
+     * type is CURVETO_CUBIC_ABS, CURVETO_CUBIC_REL, CURVETO_CUBIC_SMOOTH_ABS
+     * or CURVETO_CUBIC_SMOOTH_REL.
+     * @exception IllegalStateException if this segment type is not an
+     *            allowed one.
+     */
+    float getX2();
+
+    /**
+     * Returns the y coordinate of this segment's second control point if the
+     * type is CURVETO_CUBIC_ABS, CURVETO_CUBIC_REL, CURVETO_CUBIC_SMOOTH_ABS
+     * or CURVETO_CUBIC_SMOOTH_REL.
+     * @exception IllegalStateException if this segment type is not an
+     *            allowed one.
+     */
+    float getY2();
+
+    /**
+     * Returns the x-axis radius for the ellipse if this segment type is
+     * ARC_ABS or ARC_REL.
+     * @exception IllegalStateException if this segment is not arc.
+     */
+    float getR1();
+
+    /**
+     * Returns the y-axis radius for the ellipse if this segment type is
+     * ARC_ABS or ARC_REL.
+     * @exception IllegalStateException if this segment is not an arc.
+     */
+    float getR2();
+
+    /**
+     * Returns the rotation angle in degrees for the ellipse's x-axis relative
+     * to the x-axis of the user coordinate system if this segment type is
+     * ARC_ABS or ARC_REL.
+     * @exception IllegalStateException if this segment is not an arc.
+     */
+    float getAngle();
+
+    /**
+     * Returns the large-arc-flag parameter value if this segment type is
+     * ARC_ABS or ARC_REL.
+     * @exception IllegalStateException if this segment is not an arc.
+     */
+    boolean getLargeArcFlag();
+
+    /**
+     * Returns the sweep-flag parameter value if this segment type is ARC_ABS
+     * or ARC_REL.
+     * @exception IllegalStateException if this segment is not an arc.
+     */
+    boolean getSweepFlag();
+}
diff --git a/sources/org/apache/batik/parser/PointsHandler.java b/sources/org/apache/batik/parser/PointsHandler.java
new file mode 100644
index 0000000..e612e30
--- /dev/null
+++ b/sources/org/apache/batik/parser/PointsHandler.java
@@ -0,0 +1,41 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface must be implemented and then registred as the
+ * handler of a <code>PointsParser</code> instance in order to be
+ * notified of parsing events.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface PointsHandler {
+    /**
+     * Invoked when the points attribute starts.
+     * @exception ParseException if an error occured while processing the
+     *                           points
+     */
+    void startPoints() throws ParseException;
+
+    /**
+     * Invoked when a point has been parsed.
+     * @param x,&nbsp;y the coordinates of the point
+     * @exception ParseException if an error occured while processing the
+     *                           points
+     */
+    void point(float x, float y) throws ParseException;
+
+    /**
+     * Invoked when the points attribute ends.
+     * @exception ParseException if an error occured while processing the
+     *                           points
+     */
+    void endPoints() throws ParseException;
+}
diff --git a/sources/org/apache/batik/parser/PointsParser.java b/sources/org/apache/batik/parser/PointsParser.java
new file mode 100644
index 0000000..cc683e7
--- /dev/null
+++ b/sources/org/apache/batik/parser/PointsParser.java
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface represents an event-based parser for the SVG points
+ * attribute values (used with polyline and polygon elements).
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface PointsParser extends Parser {
+    /**
+     * Allows an application to register a points handler.
+     *
+     * <p>If the application does not register a handler, all
+     * events reported by the parser will be silently ignored.
+     *
+     * <p>Applications may register a new or different handler in the
+     * middle of a parse, and the parser must begin using the new
+     * handler immediately.</p>
+     * @param handler The transform list handler.
+     */
+    void setPointsHandler(PointsHandler handler);
+
+    /**
+     * Returns the points handler in use.
+     */
+    PointsHandler getPointsHandler();
+}
diff --git a/sources/org/apache/batik/parser/PreserveAspectRatio.java b/sources/org/apache/batik/parser/PreserveAspectRatio.java
new file mode 100644
index 0000000..b8f60c0
--- /dev/null
+++ b/sources/org/apache/batik/parser/PreserveAspectRatio.java
@@ -0,0 +1,90 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface represents objects which hold informations about
+ * SVG preserveAspectRatio attribute value.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface PreserveAspectRatio {
+    // The values returned by getAlign().
+    /**
+     * To represent the 'none' alignment.
+     */
+    int NONE = 0;
+    
+    /**
+     * To represent the 'xMinYMin' alignment.
+     */
+    int XMINYMIN = 1;
+    
+    /**
+     * To represent the 'xMidYMin' alignment.
+     */
+    int XMIDYMIN = 2;
+    
+    /**
+     * To represent the 'xMaxYMin' alignment.
+     */
+    int XMAXYMIN = 3;
+    
+    /**
+     * To represent the 'xMinYMid' alignment.
+     */
+    int XMINYMID = 4;
+    
+    /**
+     * To represent the 'xMidYMid' alignment.
+     */
+    int XMIDYMID = 5;
+    
+    /**
+     * To represent the 'xMaxYMid' alignment.
+     */
+    int XMAXYMID = 6;
+    
+    /**
+     * To represent the 'xMinYMax' alignment.
+     */
+    int XMINYMAX = 7;
+    
+    /**
+     * To represent the 'xMidYMax' alignment.
+     */
+    int XMIDYMAX = 8;
+    
+    /**
+     * To represent the 'xMaxYMax' alignment.
+     */
+    int XMAXYMAX = 9;
+    
+    // The values returned by getMeetOrSlice().
+    /**
+     * To represent the 'meet' value.
+     */
+    int MEET = 0;
+    
+    /**
+     * To represent the 'slice' value.
+     */
+    int SLICE = 1;
+
+    /**
+     * Returns the align value of the represented attribute.
+     */
+    int getAlign();
+
+    /**
+     * Returns the meet or slice value of the represented attribute.
+     */
+    int getMeetOrSlice();
+}
diff --git a/sources/org/apache/batik/parser/PreserveAspectRatioHandler.java b/sources/org/apache/batik/parser/PreserveAspectRatioHandler.java
new file mode 100644
index 0000000..2dcb732
--- /dev/null
+++ b/sources/org/apache/batik/parser/PreserveAspectRatioHandler.java
@@ -0,0 +1,117 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface must be implemented and then registred as the
+ * handler of a <code>PreserveAspectRatioParser</code> instance in order to
+ * be notified of parsing events.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface PreserveAspectRatioHandler {
+    /**
+     * Invoked when the PreserveAspectRatio parsing starts.
+     * @exception ParseException if an error occured while processing
+     * the transform 
+     */
+    void startPreserveAspectRatio() throws ParseException;
+
+    /**
+     * Invoked when 'none' been parsed.
+     * @exception ParseException if an error occured while processing
+     * the transform 
+     */
+    void none() throws ParseException;
+
+    /**
+     * Invoked when 'xMaxYMax' has been parsed.
+     * @exception ParseException if an error occured while processing
+     * the transform 
+     */
+    void xMaxYMax() throws ParseException;
+
+    /**
+     * Invoked when 'xMaxYMid' has been parsed.
+     * @exception ParseException if an error occured while processing
+     * the transform 
+     */
+    void xMaxYMid() throws ParseException;
+
+    /**
+     * Invoked when 'xMaxYMin' has been parsed.
+     * @exception ParseException if an error occured while processing
+     * the transform 
+     */
+    void xMaxYMin() throws ParseException;
+
+    /**
+     * Invoked when 'xMidYMax' has been parsed.
+     * @exception ParseException if an error occured while processing
+     * the transform 
+     */
+    void xMidYMax() throws ParseException;
+
+    /**
+     * Invoked when 'xMidYMid' has been parsed.
+     * @exception ParseException if an error occured while processing
+     * the transform 
+     */
+    void xMidYMid() throws ParseException;
+
+    /**
+     * Invoked when 'xMidYMin' has been parsed.
+     * @exception ParseException if an error occured while processing
+     * the transform 
+     */
+    void xMidYMin() throws ParseException;
+
+    /**
+     * Invoked when 'xMinYMax' has been parsed.
+     * @exception ParseException if an error occured while processing
+     * the transform 
+     */
+    void xMinYMax() throws ParseException;
+
+    /**
+     * Invoked when 'xMinYMid' has been parsed.
+     * @exception ParseException if an error occured while processing
+     * the transform 
+     */
+    void xMinYMid() throws ParseException;
+
+    /**
+     * Invoked when 'xMinYMin' has been parsed.
+     * @exception ParseException if an error occured while processing
+     * the transform 
+     */
+    void xMinYMin() throws ParseException;
+
+    /**
+     * Invoked when 'meet' has been parsed.
+     * @exception ParseException if an error occured while processing
+     * the transform 
+     */
+    void meet() throws ParseException;
+
+    /**
+     * Invoked when 'slice' has been parsed.
+     * @exception ParseException if an error occured while processing
+     * the transform 
+     */
+    void slice() throws ParseException;
+
+    /**
+     * Invoked when the PreserveAspectRatio parsing ends.
+     * @exception ParseException if an error occured while processing
+     * the transform
+     */
+    void endPreserveAspectRatio() throws ParseException;
+}
diff --git a/sources/org/apache/batik/parser/PreserveAspectRatioParser.java b/sources/org/apache/batik/parser/PreserveAspectRatioParser.java
new file mode 100644
index 0000000..f1f5e27
--- /dev/null
+++ b/sources/org/apache/batik/parser/PreserveAspectRatioParser.java
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface represents an event-based parser for the SVG
+ * preserveAspectRatio attribute values.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface PreserveAspectRatioParser extends Parser {
+    /**
+     * Allows an application to register a PreserveAspectRatioParser handler.
+     *
+     * <p>If the application does not register a handler, all
+     * events reported by the parser will be silently ignored.
+     *
+     * <p>Applications may register a new or different handler in the
+     * middle of a parse, and the parser must begin using the new
+     * handler immediately.</p>
+     * @param handler The transform list handler.
+     */
+    void setPreserveAspectRatioHandler(PreserveAspectRatioHandler handler);
+
+    /**
+     * Returns the length handler in use.
+     */
+    PreserveAspectRatioHandler getPreserveAspectRatioHandler();
+}
diff --git a/sources/org/apache/batik/parser/ShapeProducer.java b/sources/org/apache/batik/parser/ShapeProducer.java
new file mode 100644
index 0000000..42a6c26
--- /dev/null
+++ b/sources/org/apache/batik/parser/ShapeProducer.java
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+import java.awt.Shape;
+
+/**
+ * This interface represents objects which creates Shape objects.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface ShapeProducer {
+    /**
+     * Returns the Shape object initialized during the last parsing.
+     * @return the shape or null if this handler has not been used to
+     *         parse a path.
+     */
+    Shape getShape();
+
+    /**
+     * Sets the winding rule used to construct the path.
+     */
+    void setWindingRule(int i);
+
+    /**
+     * Returns the current winding rule.
+     */
+    int getWindingRule();
+}
diff --git a/sources/org/apache/batik/parser/Transform.java b/sources/org/apache/batik/parser/Transform.java
new file mode 100644
index 0000000..c11af58
--- /dev/null
+++ b/sources/org/apache/batik/parser/Transform.java
@@ -0,0 +1,122 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface represents objects which hold informations about
+ * SVG transform values.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface Transform {
+    // The types of transforms.
+    /**
+     * To represent a generic matrix.
+     */
+    int MATRIX = 0;
+
+    /**
+     * To represent a rotation matrix.
+     */
+    int ROTATE = 1;
+
+    /**
+     * To represent a scaling matrix.
+     */
+    int SCALE = 2;
+
+    /**
+     * To represent a x shearing matrix.
+     */
+    int SKEWX = 3;
+
+    /**
+     * To represent a y shearing matrix.
+     */
+    int SKEWY = 4;
+
+    /**
+     * To represent a translation matrix.
+     */
+    int TRANSLATE = 5;
+
+    /**
+     * Returns the type of this matrix.
+     */
+    int getType();
+
+    /**
+     * Returns the angle in case the type of this transform is one of
+     * ROTATE, SKEWX or SKEWY.
+     * @exception IllegalStateException if the matrix type is not one
+     *            of ROTATE, SKEWX or SKEWY.
+     */
+    float getAngle();
+
+    /**
+     * Returns the content of the cell (0, 0).
+     */
+    float getA();
+
+    /**
+     * An alias for getA().
+     */
+    float getScaleX();
+
+    /**
+     * Returns the content of the cell (0, 1).
+     */
+    float getB();
+
+    /**
+     * An alias for getB().
+     */
+    float getSkewX();
+
+    /**
+     * Returns the content of the cell (0, 2).
+     */
+    float getC();
+
+    /**
+     * An alias for getC().
+     */
+    float getTranslateX();
+
+    /**
+     * Returns the content of the cell (1, 0).
+     */
+    float getD();
+
+    /**
+     * An alias for getD().
+     */
+    float getSkewY();
+
+    /**
+     * Returns the content of the cell (1, 1).
+     */
+    float getE();
+
+    /**
+     * An alias for getE().
+     */
+    float getScaleY();
+
+    /**
+     * Returns the content of the cell (1, 2).
+     */
+    float getF();
+
+    /**
+     * An alias for getF().
+     */
+    float getTranslateY();
+}
diff --git a/sources/org/apache/batik/parser/TransformListHandler.java b/sources/org/apache/batik/parser/TransformListHandler.java
new file mode 100644
index 0000000..6a664ff
--- /dev/null
+++ b/sources/org/apache/batik/parser/TransformListHandler.java
@@ -0,0 +1,108 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface must be implemented and then registred as the
+ * handler of a <code>TransformParser</code> instance in order to
+ * be notified of parsing events.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface TransformListHandler {
+    /**
+     * Invoked when the tranform starts.
+     *
+     * @exception ParseException if an error occured while processing
+     * the transform 
+     */
+    void startTransformList() throws ParseException;
+
+    /**
+     * Invoked when 'matrix(a, b, c, d, e, f)' has been parsed.
+     *
+     * @exception ParseException if an error occured while processing
+     * the transform 
+     */
+    void matrix(float a, float b, float c, float d, float e, float f)
+	throws ParseException;
+
+    /**
+     * Invoked when 'rotate(theta)' has been parsed.
+     *
+     * @exception ParseException if an error occured while processing
+     * the transform 
+     */
+    void rotate(float theta) throws ParseException;
+
+    /**
+     * Invoked when 'rotate(theta, cx, cy)' has been parsed.
+     *
+     * @exception ParseException if an error occured while processing
+     * the transform 
+     */
+    void rotate(float theta, float cx, float cy) throws ParseException;
+
+    /**
+     * Invoked when 'translate(tx)' has been parsed.
+     *
+     * @exception ParseException if an error occured while processing
+     * the transform 
+     */
+    void translate(float tx) throws ParseException;
+
+    /**
+     * Invoked when 'translate(tx, ty)' has been parsed.
+     *
+     * @exception ParseException if an error occured while processing
+     * the transform 
+     */
+    void translate(float tx, float ty) throws ParseException;
+
+    /**
+     * Invoked when 'scale(sx)' has been parsed.
+     *
+     * @exception ParseException if an error occured while processing
+     * the transform 
+     */
+    void scale(float sx) throws ParseException;
+
+    /**
+     * Invoked when 'scale(sx, sy)' has been parsed.
+     *
+     * @exception ParseException if an error occured while processing
+     * the transform 
+     */
+    void scale(float sx, float sy) throws ParseException;
+
+    /**
+     * Invoked when 'skewX(skx)' has been parsed.
+     *
+     * @exception ParseException if an error occured while processing
+     * the transform 
+     */
+    void skewX(float skx) throws ParseException;
+
+    /**
+     * Invoked when 'skewY(sky)' has been parsed.
+     *
+     * @exception ParseException if an error occured while processing
+     * the transform
+     */
+    void skewY(float sky) throws ParseException;
+
+    /**
+     * Invoked when the transform ends.
+     *
+     * @exception ParseException if an error occured while processing
+     * the transform
+     */
+    void endTransformList() throws ParseException;
+}
diff --git a/sources/org/apache/batik/parser/TransformListParser.java b/sources/org/apache/batik/parser/TransformListParser.java
new file mode 100644
index 0000000..111cc0e
--- /dev/null
+++ b/sources/org/apache/batik/parser/TransformListParser.java
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser;
+
+/**
+ * This interface represents an event-based parser for the SVG transform
+ * attribute values.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface TransformListParser extends Parser {
+    /**
+     * Allows an application to register a transform list handler.
+     *
+     * <p>If the application does not register a handler, all
+     * events reported by the parser will be silently ignored.
+     *
+     * <p>Applications may register a new or different handler in the
+     * middle of a parse, and the parser must begin using the new
+     * handler immediately.</p>
+     * @param handler The transform handler.
+     */
+    void setTransformListHandler(TransformListHandler handler);
+
+    /**
+     * Returns the transform list handler in use.
+     */
+    TransformListHandler getTransformListHandler();
+}
diff --git a/sources/org/apache/batik/parser/package.html b/sources/org/apache/batik/parser/package.html
new file mode 100644
index 0000000..bebf59f
--- /dev/null
+++ b/sources/org/apache/batik/parser/package.html
@@ -0,0 +1,7 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
+        "http://www.w3.org/TR/REC-html40/loose.dtd">
+<html>
+  <body bgcolor="#FFFFFF">
+    Provides a set of parsers and objects to manipulate SVG attributes.
+  </body>
+</html>
diff --git a/sources/org/apache/batik/parser/style/AbstractCSSValue.java b/sources/org/apache/batik/parser/style/AbstractCSSValue.java
new file mode 100644
index 0000000..085a047
--- /dev/null
+++ b/sources/org/apache/batik/parser/style/AbstractCSSValue.java
@@ -0,0 +1,164 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser.style;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.css.Counter;
+import org.w3c.dom.css.CSSPrimitiveValue;
+import org.w3c.dom.css.CSSValue;
+import org.w3c.dom.css.CSSValueList;
+import org.w3c.dom.css.Rect;
+import org.w3c.dom.css.RGBColor;
+
+/**
+ * This class implements the {@link org.w3c.dom.css.CSSValue},
+ * {@link org.w3c.dom.css.CSSPrimitiveValue},
+ * {@link org.w3c.dom.css.CSSValueList} interfaces.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public abstract class AbstractCSSValue
+    implements CSSPrimitiveValue,
+               CSSValueList {
+    /**
+     * <b>DOM</b>: Implements {@link
+     * org.w3c.dom.css.CSSPrimitiveValue#getPrimitiveType()}.
+     */
+    public short getPrimitiveType() {
+	throw new DOMException
+            (DOMException.INVALID_ACCESS_ERR,
+             StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+             ("illegal.operation",
+              null));
+    }
+
+    /**
+     * <b>DOM</b>: Implements
+     * {@link org.w3c.dom.css.CSSValue#setCssText(String)}.
+     * Throws a NO_MODIFICATION_ALLOWED_ERR {@link org.w3c.dom.DOMException}.
+     */
+    public void setCssText(String cssText) throws DOMException {
+	throw new DOMException
+            (DOMException.INVALID_ACCESS_ERR,
+             StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+             ("readonly.value",
+              null));
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link
+     * org.w3c.dom.css.CSSPrimitiveValue#setFloatValue(short,float)}.
+     * Throws a NO_MODIFICATION_ALLOWED_ERR {@link org.w3c.dom.DOMException}.
+     */
+    public void setFloatValue(short unitType, float floatValue)
+        throws DOMException {
+	throw new DOMException
+            (DOMException.INVALID_ACCESS_ERR,
+             StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+             ("readonly.value",
+              null));
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link
+     * org.w3c.dom.css.CSSPrimitiveValue#getFloatValue(short)}.
+     */
+    public float getFloatValue(short unitType) throws DOMException {
+	throw new DOMException
+            (DOMException.INVALID_ACCESS_ERR,
+             StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+             ("illegal.operation",
+              null));
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link
+     * org.w3c.dom.css.CSSPrimitiveValue#setStringValue(short,String)}.
+     * Throws a NO_MODIFICATION_ALLOWED_ERR {@link org.w3c.dom.DOMException}.
+     */
+    public void setStringValue(short stringType, String stringValue)
+        throws DOMException {
+	throw new DOMException
+            (DOMException.INVALID_ACCESS_ERR,
+             StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+             ("readonly.value",
+              new Object[] {}));
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link
+     * org.w3c.dom.css.CSSPrimitiveValue#getStringValue()}.
+     */
+    public String getStringValue() throws DOMException {
+	throw new DOMException
+            (DOMException.INVALID_ACCESS_ERR,
+             StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+             ("illegal.operation",
+              null));
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link
+     * org.w3c.dom.css.CSSPrimitiveValue#getCounterValue()}.
+     */
+    public Counter getCounterValue() throws DOMException {
+	throw new DOMException
+            (DOMException.INVALID_ACCESS_ERR,
+             StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+             ("illegal.operation",
+              null));
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link
+     * org.w3c.dom.css.CSSPrimitiveValue#getRectValue()}.
+     */
+    public Rect getRectValue() throws DOMException {
+	throw new DOMException
+            (DOMException.INVALID_ACCESS_ERR,
+             StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+             ("illegal.operation",
+              null));
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link
+     * org.w3c.dom.css.CSSPrimitiveValue#getRGBColorValue()}.
+     */
+    public RGBColor getRGBColorValue() throws DOMException {
+	throw new DOMException
+            (DOMException.INVALID_ACCESS_ERR,
+             StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+             ("illegal.operation",
+              null));
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link org.w3c.dom.css.CSSValueList#getLength()}.
+     */
+    public int getLength() {
+	throw new DOMException
+            (DOMException.INVALID_ACCESS_ERR,
+             StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+             ("illegal.operation",
+              null));
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link org.w3c.dom.css.CSSValueList#item(int)}.
+     */
+    public CSSValue item(int index) {
+	throw new DOMException
+            (DOMException.INVALID_ACCESS_ERR,
+             StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+             ("illegal.operation",
+              null));
+    }
+}
diff --git a/sources/org/apache/batik/parser/style/AbstractCSSValueFactory.java b/sources/org/apache/batik/parser/style/AbstractCSSValueFactory.java
new file mode 100644
index 0000000..2e35c8a
--- /dev/null
+++ b/sources/org/apache/batik/parser/style/AbstractCSSValueFactory.java
@@ -0,0 +1,43 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser.style;
+
+import org.w3c.css.sac.LexicalUnit;
+import org.w3c.dom.css.CSSPrimitiveValue;
+import org.w3c.dom.css.CSSValue;
+
+/**
+ * This class is the abstract superclass of all factories.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public abstract class AbstractCSSValueFactory implements CSSValueFactory {
+    /**
+     * The 'inherit' value.
+     */
+    public final static CSSValue INHERIT = CSSInheritValue.INSTANCE;
+
+    /**
+     * The 'auto' identifier string representation.
+     */
+    public final static String AUTO = "auto";
+
+    /**
+     * The 'auto' identifier.
+     */
+    public final static CSSValue AUTO_VALUE =
+        new CSSStringValue(CSSPrimitiveValue.CSS_IDENT, AUTO);
+
+    /**
+     * Creates a new AbstractCSSValueFactory object.
+     */
+    protected AbstractCSSValueFactory() {
+    }
+}
diff --git a/sources/org/apache/batik/parser/style/AbstractLengthFactory.java b/sources/org/apache/batik/parser/style/AbstractLengthFactory.java
new file mode 100644
index 0000000..3a8f3e1
--- /dev/null
+++ b/sources/org/apache/batik/parser/style/AbstractLengthFactory.java
@@ -0,0 +1,77 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser.style;
+
+import org.w3c.css.sac.LexicalUnit;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.css.CSSValue;
+import org.w3c.dom.css.CSSPrimitiveValue;
+
+/**
+ * This class provides an abstract factory for CSS lengths.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public abstract class AbstractLengthFactory extends AbstractCSSValueFactory {
+    /**
+     * Creates a new LengthFactory object.
+     */
+    protected AbstractLengthFactory() {
+    }
+
+    /**
+     * Returns a CSSValue built from the given SAC lexical unit.
+     * @param lu The SAC lexical unit used to create the value.
+     */
+    public CSSValue createCSSValue(LexicalUnit lu) {
+	switch (lu.getLexicalUnitType()) {
+	case LexicalUnit.SAC_INHERIT:
+	    return INHERIT;
+	case LexicalUnit.SAC_EM:
+	    return new CSSFloatValue(CSSPrimitiveValue.CSS_EMS,
+                                     lu.getFloatValue());
+	case LexicalUnit.SAC_EX:
+	    return new CSSFloatValue(CSSPrimitiveValue.CSS_EXS,
+                                     lu.getFloatValue());
+	case LexicalUnit.SAC_PIXEL:
+	    return new CSSFloatValue(CSSPrimitiveValue.CSS_PX,
+                                     lu.getFloatValue());
+	case LexicalUnit.SAC_CENTIMETER:
+	    return new CSSFloatValue(CSSPrimitiveValue.CSS_CM,
+                                     lu.getFloatValue());
+	case LexicalUnit.SAC_MILLIMETER:
+	    return new CSSFloatValue(CSSPrimitiveValue.CSS_MM,
+                                     lu.getFloatValue());
+	case LexicalUnit.SAC_INCH:
+	    return new CSSFloatValue(CSSPrimitiveValue.CSS_IN,
+                                     lu.getFloatValue());
+	case LexicalUnit.SAC_POINT:
+	    return new CSSFloatValue(CSSPrimitiveValue.CSS_PT,
+                                     lu.getFloatValue());
+	case LexicalUnit.SAC_PICA:
+	    return new CSSFloatValue(CSSPrimitiveValue.CSS_PC,
+                                     lu.getFloatValue());
+	case LexicalUnit.SAC_INTEGER:
+	    return new CSSFloatValue(CSSPrimitiveValue.CSS_NUMBER,
+                                     lu.getIntegerValue());
+	case LexicalUnit.SAC_REAL:
+	    return new CSSFloatValue(CSSPrimitiveValue.CSS_NUMBER,
+                                     lu.getFloatValue());
+	case LexicalUnit.SAC_DIMENSION:
+	    return new CSSFloatValue(CSSPrimitiveValue.CSS_DIMENSION,
+                                     lu.getFloatValue());
+	}
+	throw new DOMException
+	    (DOMException.INVALID_ACCESS_ERR,
+             StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+             ("invalid.lexical.unit",
+              new Object[] { new Integer(lu.getLexicalUnitType()) }));
+    }
+}
diff --git a/sources/org/apache/batik/parser/style/AbstractRectFactory.java b/sources/org/apache/batik/parser/style/AbstractRectFactory.java
new file mode 100644
index 0000000..7a64689
--- /dev/null
+++ b/sources/org/apache/batik/parser/style/AbstractRectFactory.java
@@ -0,0 +1,91 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser.style;
+
+import org.w3c.css.sac.LexicalUnit;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.css.CSSPrimitiveValue;
+import org.w3c.dom.css.CSSValue;
+
+/**
+ * This class represents the factories for the rect CSS values.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public abstract class AbstractRectFactory extends AbstractCSSValueFactory {
+    /**
+     * The factory for the parameters.
+     */
+    protected LengthFactory factory = new LengthFactory();
+
+    /**
+     * Creates a new AbstractRectFactory object.
+     */
+    protected AbstractRectFactory() {
+    }
+
+    /**
+     * Returns a CSSValue built from the given SAC lexical unit.
+     */
+    public CSSValue createCSSValue(LexicalUnit lu) {
+        switch (lu.getLexicalUnitType()) {
+        case LexicalUnit.SAC_FUNCTION:
+            if (!lu.getFunctionName().equalsIgnoreCase("rect")) {
+                break;
+            }
+        case LexicalUnit.SAC_RECT_FUNCTION:
+            lu = lu.getParameters();
+            CSSPrimitiveValue t;
+            t = (CSSPrimitiveValue)factory.createCSSValue(lu);
+            lu = lu.getNextLexicalUnit();
+            if (lu == null ||
+                lu.getLexicalUnitType() != LexicalUnit.SAC_OPERATOR_COMMA) {
+                throw new DOMException
+                    (DOMException.INVALID_ACCESS_ERR,
+                     StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+                     ("invalid.lexical.unit",
+                      new Object[] { new Integer(lu.getLexicalUnitType()) }));
+            }
+            lu = lu.getNextLexicalUnit();
+            CSSPrimitiveValue r;
+            r = (CSSPrimitiveValue)factory.createCSSValue(lu);
+            lu = lu.getNextLexicalUnit();
+            if (lu == null ||
+                lu.getLexicalUnitType() != LexicalUnit.SAC_OPERATOR_COMMA) {
+                throw new DOMException
+                    (DOMException.INVALID_ACCESS_ERR,
+                     StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+                     ("invalid.lexical.unit",
+                      new Object[] { new Integer(lu.getLexicalUnitType()) }));
+            }
+            lu = lu.getNextLexicalUnit();
+            CSSPrimitiveValue b;
+            b = (CSSPrimitiveValue)factory.createCSSValue(lu);
+            lu = lu.getNextLexicalUnit();
+            if (lu == null ||
+                lu.getLexicalUnitType() != LexicalUnit.SAC_OPERATOR_COMMA) {
+                throw new DOMException
+                    (DOMException.INVALID_ACCESS_ERR,
+                     StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+                     ("invalid.lexical.unit",
+                      new Object[] { new Integer(lu.getLexicalUnitType()) }));
+            }
+            lu = lu.getNextLexicalUnit();
+            CSSPrimitiveValue l;
+            l = (CSSPrimitiveValue)factory.createCSSValue(lu);
+            return new CSSRectValue(t, r, b, l);
+        }
+        throw new DOMException
+            (DOMException.INVALID_ACCESS_ERR,
+             StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+             ("invalid.lexical.unit",
+              new Object[] { new Integer(lu.getLexicalUnitType()) }));
+    }
+}
diff --git a/sources/org/apache/batik/parser/style/CSSFloatValue.java b/sources/org/apache/batik/parser/style/CSSFloatValue.java
new file mode 100644
index 0000000..f093c7e
--- /dev/null
+++ b/sources/org/apache/batik/parser/style/CSSFloatValue.java
@@ -0,0 +1,387 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser.style;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.css.CSSPrimitiveValue;
+import org.w3c.dom.css.CSSValue;
+
+/**
+ * This class represents CSS float values
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public class CSSFloatValue extends AbstractCSSValue {
+    /**
+     * The unit types representations
+     */
+    protected final static String[] UNITS = {
+        "", "%", "em", "es", "px", "cm", "mm", "in", "pt",
+        "pc", "deg", "rad", "grad", "ms", "s", "Hz", "kHz", ""
+    };
+
+    /**
+     * The float value
+     */
+    protected float floatValue;
+
+    /**
+     * The unit type
+     */
+    protected short unitType;
+
+    /**
+     * Creates a new value.
+     */
+    public CSSFloatValue(short unitType, float floatValue) {
+	this.unitType   = unitType;
+	this.floatValue = floatValue;
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link org.w3c.dom.css.CSSValue#getCssValueType()}.
+     */
+    public short getCssValueType() {
+        return CSSValue.CSS_PRIMITIVE_VALUE;
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link
+     * org.w3c.dom.css.CSSPrimitiveValue#getPrimitiveType()}.
+     */
+    public short getPrimitiveType() {
+	return unitType;
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link org.w3c.dom.css.CSSValue#getCssText()}.
+     */
+    public String getCssText() {
+	return floatValue + getUnitRepresentation(unitType);
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link
+     * org.w3c.dom.css.CSSPrimitiveValue#getFloatValue(short)}.
+     */
+    public float getFloatValue(short unitType) throws DOMException {
+	switch (unitType) {
+	case CSSPrimitiveValue.CSS_NUMBER:
+	case CSSPrimitiveValue.CSS_PERCENTAGE:
+	case CSSPrimitiveValue.CSS_EMS:
+	case CSSPrimitiveValue.CSS_EXS:
+	case CSSPrimitiveValue.CSS_DIMENSION:
+	case CSSPrimitiveValue.CSS_PX:
+	    if (this.unitType == unitType) {
+		return floatValue;
+	    }
+	    break;
+	case CSSPrimitiveValue.CSS_CM:
+	    return toCentimeters();
+	case CSSPrimitiveValue.CSS_MM:
+	    return toMillimeters();
+	case CSSPrimitiveValue.CSS_IN:
+	    return toInches();
+	case CSSPrimitiveValue.CSS_PT:
+	    return toPoints();
+	case CSSPrimitiveValue.CSS_PC:
+	    return toPicas();
+	case CSSPrimitiveValue.CSS_DEG:
+	    return toDegrees();
+	case CSSPrimitiveValue.CSS_RAD:
+	    return toRadians();
+	case CSSPrimitiveValue.CSS_GRAD:
+	    return toGradians();
+	case CSSPrimitiveValue.CSS_MS:
+	    return toMilliseconds();
+	case CSSPrimitiveValue.CSS_S:
+	    return toSeconds();
+	case CSSPrimitiveValue.CSS_HZ:
+	    return toHertz();
+	case CSSPrimitiveValue.CSS_KHZ:
+	    return tokHertz();
+	}
+	throw new DOMException
+            (DOMException.INVALID_ACCESS_ERR,
+             StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+             ("invalid.conversion",
+              new Object[] { new Integer(unitType) }));
+    }
+    
+    /**
+     * Returns the representation for the given unit type.
+     * @param unitType The unit type like specified in the CSSPrimitiveValue
+     *                 interface.
+     */
+    protected String getUnitRepresentation(short unitType)
+        throws DOMException {
+        if (unitType < CSSPrimitiveValue.CSS_NUMBER &&
+            unitType > CSSPrimitiveValue.CSS_DIMENSION) {
+            throw new DOMException
+                (DOMException.INVALID_ACCESS_ERR,
+                 StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+                 ("illegal.unit.type",
+                  new Object[] { new Integer(unitType) }));
+        }
+        return UNITS[unitType - CSSPrimitiveValue.CSS_NUMBER];
+    }
+
+    /**
+     * Converts the current value into centimeters.
+     */
+    protected float toCentimeters() {
+	switch (unitType) {
+	case CSSPrimitiveValue.CSS_CM:
+	    return floatValue;
+	case CSSPrimitiveValue.CSS_MM:
+	    return (float)(floatValue / 10);
+	case CSSPrimitiveValue.CSS_IN:
+	    return (float)(floatValue * 2.54);
+	case CSSPrimitiveValue.CSS_PT:
+	    return (float)(floatValue * 2.54 / 72);
+	case CSSPrimitiveValue.CSS_PC:
+	    return (float)(floatValue * 2.54 / 6);
+	default:
+            throw new DOMException
+                (DOMException.INVALID_ACCESS_ERR,
+                 StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+                 ("invalid.conversion",
+                  new Object[] { new Integer(unitType) }));
+	}
+    }
+
+    /**
+     * Converts the current value into inches.
+     */
+    protected float toInches() {
+	switch (unitType) {
+	case CSSPrimitiveValue.CSS_CM:
+	    return (float)(floatValue / 2.54);
+	case CSSPrimitiveValue.CSS_MM:
+	    return (float)(floatValue / 25.4);
+	case CSSPrimitiveValue.CSS_IN:
+	    return floatValue;
+	case CSSPrimitiveValue.CSS_PT:
+	    return (float)(floatValue / 72);
+	case CSSPrimitiveValue.CSS_PC:
+	    return (float) (floatValue / 6);
+	default:
+            throw new DOMException
+                (DOMException.INVALID_ACCESS_ERR,
+                 StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+                 ("invalid.conversion",
+                  new Object[] { new Integer(unitType) }));
+	}
+    }
+
+    /**
+     * Converts the current value into millimeters.
+     */
+    protected float toMillimeters() {
+	switch (unitType) {
+	case CSSPrimitiveValue.CSS_CM:
+	    return (float)(floatValue * 10);
+	case CSSPrimitiveValue.CSS_MM:
+	    return floatValue;
+	case CSSPrimitiveValue.CSS_IN:
+	    return (float)(floatValue * 25.4);
+	case CSSPrimitiveValue.CSS_PT:
+	    return (float)(floatValue * 25.4 / 72);
+	case CSSPrimitiveValue.CSS_PC:
+	    return (float)(floatValue * 25.4 / 6);
+	default:
+            throw new DOMException
+                (DOMException.INVALID_ACCESS_ERR,
+                 StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+                 ("invalid.conversion",
+                  new Object[] { new Integer(unitType) }));
+	}
+    }
+
+    /**
+     * Converts the current value into points.
+     */
+    protected float toPoints() {
+	switch (unitType) {
+	case CSSPrimitiveValue.CSS_CM:
+	    return (float)(floatValue * 72 / 2.54);
+	case CSSPrimitiveValue.CSS_MM:
+	    return (float)(floatValue * 72 / 25.4);
+	case CSSPrimitiveValue.CSS_IN:
+	    return (float)(floatValue * 72);
+	case CSSPrimitiveValue.CSS_PT:
+	    return floatValue;
+	case CSSPrimitiveValue.CSS_PC:
+	    return (float)(floatValue * 12);
+	default:
+            throw new DOMException
+                (DOMException.INVALID_ACCESS_ERR,
+                 StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+                 ("invalid.conversion",
+                  new Object[] { new Integer(unitType) }));
+	}
+    }
+
+    /**
+     * Converts the current value into picas.
+     */
+    protected float toPicas() {
+	switch (unitType) {
+	case CSSPrimitiveValue.CSS_CM:
+	    return (float)(floatValue * 6 / 2.54);
+	case CSSPrimitiveValue.CSS_MM:
+	    return (float)(floatValue * 6 / 25.4);
+	case CSSPrimitiveValue.CSS_IN:
+	    return (float)(floatValue * 6);
+	case CSSPrimitiveValue.CSS_PT:
+	    return (float)(floatValue / 12);
+	case CSSPrimitiveValue.CSS_PC:
+	    return floatValue;
+	default:
+            throw new DOMException
+                (DOMException.INVALID_ACCESS_ERR,
+                 StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+                 ("invalid.conversion",
+                  new Object[] { new Integer(unitType) }));
+	}
+    }
+
+    /**
+     * Converts the current value into degrees.
+     */
+    protected float toDegrees() {
+	switch (unitType) {
+	case CSSPrimitiveValue.CSS_DEG:
+	    return floatValue;
+	case CSSPrimitiveValue.CSS_RAD:
+	    return (float)(floatValue * 180 / Math.PI);
+	case CSSPrimitiveValue.CSS_GRAD:
+	    return (float)(floatValue * 9 / 5);
+	default:
+            throw new DOMException
+                (DOMException.INVALID_ACCESS_ERR,
+                 StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+                 ("invalid.conversion",
+                  new Object[] { new Integer(unitType) }));
+	}
+    }
+
+    /**
+     * Converts the current value into radians.
+     */
+    protected float toRadians() {
+	switch (unitType) {
+	case CSSPrimitiveValue.CSS_DEG:
+	    return (float)(floatValue * 5 / 9);
+	case CSSPrimitiveValue.CSS_RAD:
+	    return floatValue;
+	case CSSPrimitiveValue.CSS_GRAD:
+	    return (float)(floatValue * 100 / Math.PI);
+	default:
+            throw new DOMException
+                (DOMException.INVALID_ACCESS_ERR,
+                 StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+                 ("invalid.conversion",
+                  new Object[] { new Integer(unitType) }));
+	}
+    }
+
+    /**
+     * Converts the current value into gradians.
+     */
+    protected float toGradians() {
+	switch (unitType) {
+	case CSSPrimitiveValue.CSS_DEG:
+	    return (float)(floatValue * Math.PI / 180);
+	case CSSPrimitiveValue.CSS_RAD:
+	    return (float)(floatValue * Math.PI / 100);
+	case CSSPrimitiveValue.CSS_GRAD:
+	    return floatValue;
+	default:
+            throw new DOMException
+                (DOMException.INVALID_ACCESS_ERR,
+                 StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+                 ("invalid.conversion",
+                  new Object[] { new Integer(unitType) }));
+	}
+    }
+
+    /**
+     * Converts the current value into milliseconds.
+     */
+    protected float toMilliseconds() {
+	switch (unitType) {
+	case CSSPrimitiveValue.CSS_MS:
+	    return floatValue;
+	case CSSPrimitiveValue.CSS_S:
+	    return (float)(floatValue * 1000);
+	default:
+            throw new DOMException
+                (DOMException.INVALID_ACCESS_ERR,
+                 StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+                 ("invalid.conversion",
+                  new Object[] { new Integer(unitType) }));
+	}
+    }
+	
+    /**
+     * Converts the current value into seconds.
+     */
+    protected float toSeconds() {
+	switch (unitType) {
+	case CSSPrimitiveValue.CSS_MS:
+	    return (float)(floatValue / 1000);
+	case CSSPrimitiveValue.CSS_S:
+	    return floatValue;
+	default:
+            throw new DOMException
+                (DOMException.INVALID_ACCESS_ERR,
+                 StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+                 ("invalid.conversion",
+                  new Object[] { new Integer(unitType) }));
+	}
+    }
+	
+    /**
+     * Converts the current value into Hertz.
+     */
+    protected float toHertz() {
+	switch (unitType) {
+	case CSSPrimitiveValue.CSS_HZ:
+	    return floatValue;
+	case CSSPrimitiveValue.CSS_KHZ:
+	    return (float)(floatValue / 1000);
+	default:
+            throw new DOMException
+                (DOMException.INVALID_ACCESS_ERR,
+                 StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+                 ("invalid.conversion",
+                  new Object[] { new Integer(unitType) }));
+	}
+    }
+
+    /**
+     * Converts the current value into kHertz.
+     */
+    protected float tokHertz() {
+	switch (unitType) {
+	case CSSPrimitiveValue.CSS_HZ:
+	    return (float)(floatValue * 1000);
+	case CSSPrimitiveValue.CSS_KHZ:
+	    return floatValue;
+	default:
+            throw new DOMException
+                (DOMException.INVALID_ACCESS_ERR,
+                 StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+                 ("invalid.conversion",
+                  new Object[] { new Integer(unitType) }));
+	}
+    }
+}
diff --git a/sources/org/apache/batik/parser/style/CSSInheritValue.java b/sources/org/apache/batik/parser/style/CSSInheritValue.java
new file mode 100644
index 0000000..f805043
--- /dev/null
+++ b/sources/org/apache/batik/parser/style/CSSInheritValue.java
@@ -0,0 +1,44 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser.style;
+
+import org.w3c.dom.css.CSSValue;
+
+/**
+ * This class represents CSS 'inherit' values
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public class CSSInheritValue extends AbstractCSSValue {
+    /**
+     * The instance of this class.
+     */
+    public final static CSSInheritValue INSTANCE = new CSSInheritValue();
+
+    /**
+     * This class do not need to be instantiated.
+     */
+    protected CSSInheritValue() {
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link org.w3c.dom.css.CSSValue#getCssValueType()}.
+     */
+    public short getCssValueType() {
+        return CSSValue.CSS_INHERIT;
+    }
+    
+    /**
+     * <b>DOM</b>: Implements {@link org.w3c.dom.css.CSSValue#getCssText()}.
+     */
+    public String getCssText() {
+	return "inherit";
+    }
+}
diff --git a/sources/org/apache/batik/parser/style/CSSRGBColorValue.java b/sources/org/apache/batik/parser/style/CSSRGBColorValue.java
new file mode 100644
index 0000000..12d5625
--- /dev/null
+++ b/sources/org/apache/batik/parser/style/CSSRGBColorValue.java
@@ -0,0 +1,108 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser.style;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.css.CSSPrimitiveValue;
+import org.w3c.dom.css.CSSValue;
+import org.w3c.dom.css.RGBColor;
+
+/**
+ * This class represents CSS color values
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public class CSSRGBColorValue
+    extends    AbstractCSSValue
+    implements RGBColor {
+    /**
+     * The red value
+     */
+    protected CSSPrimitiveValue red;
+
+    /**
+     * The green value
+     */
+    protected CSSPrimitiveValue green;
+
+    /**
+     * The blue value
+     */
+    protected CSSPrimitiveValue blue;
+
+    /**
+     * Creates a new color value.
+     * @param r The red component.
+     * @param g The green component.
+     * @param b The blue component.
+     */
+    public CSSRGBColorValue(CSSPrimitiveValue r,
+                            CSSPrimitiveValue g,
+                            CSSPrimitiveValue b) {
+        red   = r;
+        green = g;
+        blue  = b;
+    }
+
+
+    /**
+     * <b>DOM</b>: Implements {@link org.w3c.dom.css.CSSValue#getCssValueType()}.
+     */
+    public short getCssValueType() {
+        return CSSValue.CSS_PRIMITIVE_VALUE;
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link
+     * org.w3c.dom.css.CSSPrimitiveValue#getPrimitiveType()}.
+     */
+    public short getPrimitiveType() {
+	return CSSPrimitiveValue.CSS_RGBCOLOR;
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link org.w3c.dom.css.CSSValue#getCssText()}.
+     */
+    public String getCssText() {
+        return "rgb("
+            + red.getCssText() + ", "
+            + green.getCssText() + ", "
+            + blue.getCssText() + ")";
+    }
+    
+    /**
+     * <b>DOM</b>: Implements {@link org.w3c.dom.css.RGBColor#getRed()}.
+     */
+    public CSSPrimitiveValue getRed() {
+        return red;
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link org.w3c.dom.css.RGBColor#getGreen()}.
+     */
+    public CSSPrimitiveValue getGreen() {
+        return green;
+    }
+    
+    /**
+     * <b>DOM</b>: Implements {@link org.w3c.dom.css.RGBColor#getBlue()}.
+     */
+    public CSSPrimitiveValue getBlue() {
+        return blue;
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link
+     * org.w3c.dom.css.CSSPrimitiveValue#getRGBColorValue()}.
+     */
+    public RGBColor getRGBColorValue() throws DOMException {
+        return this;
+    }
+}
diff --git a/sources/org/apache/batik/parser/style/CSSRectValue.java b/sources/org/apache/batik/parser/style/CSSRectValue.java
new file mode 100644
index 0000000..d86fd2d
--- /dev/null
+++ b/sources/org/apache/batik/parser/style/CSSRectValue.java
@@ -0,0 +1,122 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser.style;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.css.CSSPrimitiveValue;
+import org.w3c.dom.css.CSSValue;
+import org.w3c.dom.css.Rect;
+
+/**
+ * This class represents CSS rect values
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public class CSSRectValue
+    extends    AbstractCSSValue
+    implements Rect {
+    /**
+     * The top value.
+     */
+    protected CSSPrimitiveValue top;
+
+    /**
+     * The right value.
+     */
+    protected CSSPrimitiveValue right;
+
+    /**
+     * The bottom value.
+     */
+    protected CSSPrimitiveValue bottom;
+
+    /**
+     * The left value.
+     */
+    protected CSSPrimitiveValue left;
+
+    /**
+     * Creates a new rect value.
+     * @param t The top length.
+     * @param t The right length.
+     * @param t The bottom length.
+     * @param t The left length.
+     */
+    public CSSRectValue(CSSPrimitiveValue t,
+                        CSSPrimitiveValue r,
+                        CSSPrimitiveValue b,
+                        CSSPrimitiveValue l) {
+        top = t;
+        right = r;
+        bottom = b;
+        left = l;
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link org.w3c.dom.css.CSSValue#getCssValueType()}.
+     */
+    public short getCssValueType() {
+        return CSSValue.CSS_PRIMITIVE_VALUE;
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link
+     * org.w3c.dom.css.CSSPrimitiveValue#getPrimitiveType()}.
+     */
+    public short getPrimitiveType() {
+	return CSSPrimitiveValue.CSS_RECT;
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link org.w3c.dom.css.CSSValue#getCssText()}.
+     */
+    public String getCssText() {
+        return "rect(" + top.getCssText() + ", "
+            +  right.getCssText() + ", "
+            +  bottom.getCssText() + ", "
+            +  left.getCssText() + ")";
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link
+     * org.w3c.dom.css.CSSPrimitiveValue#getRectValue()}.
+     */
+    public Rect getRectValue() throws DOMException {
+        return this;
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link org.w3c.dom.css.Rect#getTop()}.
+     */
+    public CSSPrimitiveValue getTop() {
+        return top;
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link org.w3c.dom.css.Rect#getRight()}.
+     */
+    public CSSPrimitiveValue getRight() {
+        return right;
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link org.w3c.dom.css.Rect#getBottom()}.
+     */
+    public CSSPrimitiveValue getBottom() {
+        return bottom;
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link org.w3c.dom.css.Rect#getLeft()}.
+     */
+    public CSSPrimitiveValue getLeft() {
+        return left;
+    }
+}
diff --git a/sources/org/apache/batik/parser/style/CSSStringValue.java b/sources/org/apache/batik/parser/style/CSSStringValue.java
new file mode 100644
index 0000000..f0e9509
--- /dev/null
+++ b/sources/org/apache/batik/parser/style/CSSStringValue.java
@@ -0,0 +1,79 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser.style;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.css.CSSPrimitiveValue;
+import org.w3c.dom.css.CSSValue;
+
+/**
+ * This class represents CSS string values
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public class CSSStringValue extends AbstractCSSValue {
+    /**
+     * The string value
+     */
+    protected String stringValue;
+
+    /**
+     * The unit type
+     */
+    protected short unitType;
+
+    /**
+     * Creates a new value.
+     */
+    public CSSStringValue(short unitType, String stringValue) {
+	this.unitType   = unitType;
+	this.stringValue = stringValue;
+        this.stringValue = (unitType == CSSPrimitiveValue.CSS_IDENT)
+            ? stringValue.toLowerCase().intern() : stringValue;
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link org.w3c.dom.css.CSSValue#getCssValueType()}.
+     */
+    public short getCssValueType() {
+        return CSSValue.CSS_PRIMITIVE_VALUE;
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link
+     * org.w3c.dom.css.CSSPrimitiveValue#getPrimitiveType()}.
+     */
+    public short getPrimitiveType() {
+	return unitType;
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link org.w3c.dom.css.CSSValue#getCssText()}.
+     */
+    public String getCssText() {
+        switch (unitType) {
+        case CSSPrimitiveValue.CSS_URI:
+            return "url(" + stringValue + ")";
+        case CSSPrimitiveValue.CSS_STRING:
+            // !!! See this point
+            char q = (stringValue.indexOf('"') != -1) ? '\'' : '"';
+            return q + stringValue + q;
+        }
+        return stringValue;
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link
+     * org.w3c.dom.css.CSSPrimitiveValue#getStringValue()}.
+     */
+    public String getStringValue() throws DOMException {
+        return stringValue;
+    }
+}
diff --git a/sources/org/apache/batik/parser/style/CSSValueFactory.java b/sources/org/apache/batik/parser/style/CSSValueFactory.java
new file mode 100644
index 0000000..6b6a5f1
--- /dev/null
+++ b/sources/org/apache/batik/parser/style/CSSValueFactory.java
@@ -0,0 +1,27 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser.style;
+
+import org.w3c.css.sac.LexicalUnit;
+import org.w3c.dom.css.CSSValue;
+
+/**
+ * This is the interface to implement in order to allow the parsing of
+ * a custom style attribute by a StyleAttributeParser. 
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public interface CSSValueFactory {
+    /**
+     * Returns a CSSValue built from the given SAC lexical unit.
+     * @param l The lexical unit representing the value.
+     */
+    CSSValue createCSSValue(LexicalUnit l);
+}
diff --git a/sources/org/apache/batik/parser/style/CSSValueListValue.java b/sources/org/apache/batik/parser/style/CSSValueListValue.java
new file mode 100644
index 0000000..515a7a5
--- /dev/null
+++ b/sources/org/apache/batik/parser/style/CSSValueListValue.java
@@ -0,0 +1,94 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser.style;
+
+import org.w3c.dom.css.CSSValue;
+
+/**
+ * This class represents CSS list of values
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public class CSSValueListValue extends AbstractCSSValue {
+    /**
+     * The table that contains the values.
+     */
+    protected CSSValue[] table = new CSSValue[5];
+
+    /**
+     * The list length.
+     */
+    protected int length;
+
+    /**
+     * The separator character.
+     */
+    protected char separator;
+
+    /**
+     * Creates a new list value.
+     * @param c The list separator.
+     */
+    public CSSValueListValue(char c) {
+        separator = c;
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link org.w3c.dom.css.CSSValue#getCssValueType()}.
+     */
+    public short getCssValueType() {
+        return CSSValue.CSS_VALUE_LIST;
+    }
+    
+    /**
+     * <b>DOM</b>: Implements {@link org.w3c.dom.css.CSSValue#getCssText()}.
+     */
+    public String getCssText() {
+        String result = "";
+        if (length > 0) {
+            result += table[0].getCssText();
+        }
+        for (int i = 1; i < length; i++) {
+            result += separator + table[i].getCssText();
+        }
+        return result;
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link org.w3c.dom.css.CSSValueList#getLength()}.
+     */
+    public int getLength() {
+        return length;
+    }
+
+    /**
+     * <b>DOM</b>: Implements {@link org.w3c.dom.css.CSSValueList#item(int)}.
+     */
+    public CSSValue item(int index) {
+        if (index < 0 || index > length) {
+            return null;
+        }
+        return table[index];
+    }
+
+    /**
+     * Appends an item to the list.
+     */
+    public void append(CSSValue item) {
+        if (table.length == length) {
+            CSSValue[] old = table;
+            table = new CSSValue[length * 2 + 1];
+            for (int i = 0; i < length; i++) {
+                table[i] = old[i];
+            }
+        }
+        table[length++] = item;
+    }
+}
diff --git a/sources/org/apache/batik/parser/style/ClipFactory.java b/sources/org/apache/batik/parser/style/ClipFactory.java
new file mode 100644
index 0000000..31df267
--- /dev/null
+++ b/sources/org/apache/batik/parser/style/ClipFactory.java
@@ -0,0 +1,48 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser.style;
+
+import org.w3c.css.sac.LexicalUnit;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.css.CSSValue;
+
+/**
+ * This class represents the factories for the "clip" attribute value.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public class ClipFactory extends AbstractRectFactory {
+    /**
+     * Creates a new ClipFactory object.
+     */
+    public ClipFactory() {
+    }
+
+    /**
+     * Returns a CSSValue built from the given SAC lexical unit.
+     */
+    public CSSValue createCSSValue(LexicalUnit lu) {
+        switch (lu.getLexicalUnitType()) {
+        case LexicalUnit.SAC_INHERIT:
+            return INHERIT;
+        case LexicalUnit.SAC_IDENT:
+            if (!lu.getStringValue().equalsIgnoreCase(AUTO)) {
+                throw new DOMException
+                    (DOMException.INVALID_ACCESS_ERR,
+                     StyleAttributeParser.LOCALIZABLE_SUPPORT.formatMessage
+                     ("invalid.identifier",
+                      new Object[] { lu.getStringValue() }));
+            }
+            return AUTO_VALUE;
+        default:
+            return super.createCSSValue(lu);
+        }
+    }
+}
diff --git a/sources/org/apache/batik/parser/style/DefaultStyleAttributeParser.java b/sources/org/apache/batik/parser/style/DefaultStyleAttributeParser.java
new file mode 100644
index 0000000..d56a690
--- /dev/null
+++ b/sources/org/apache/batik/parser/style/DefaultStyleAttributeParser.java
@@ -0,0 +1,30 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser.style;
+
+import org.apache.batik.parser.ParseException;
+
+/**
+ * This class represents a style attribute parser initialized for the SVG
+ * style attributes.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public class DefaultStyleAttributeParser extends StyleAttributeParser {
+    /**
+     * Creates a new StyleAttributeParser object.
+     * @param s The name of a SAC compliant CSS parser class.
+     */
+    public DefaultStyleAttributeParser(String s)
+        throws ParseException {
+        super(s);
+        putCSSValueFactory(null, "clip", new ClipFactory());
+    }
+}
diff --git a/sources/org/apache/batik/parser/style/LengthFactory.java b/sources/org/apache/batik/parser/style/LengthFactory.java
new file mode 100644
index 0000000..3d1d4ce
--- /dev/null
+++ b/sources/org/apache/batik/parser/style/LengthFactory.java
@@ -0,0 +1,45 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser.style;
+
+import org.w3c.css.sac.LexicalUnit;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.css.CSSPrimitiveValue;
+import org.w3c.dom.css.CSSValue;
+
+/**
+ * This class provides a factory for CSS lengths.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public class LengthFactory extends AbstractLengthFactory {
+    /**
+     * Creates a new LengthFactory object.
+     */
+    public LengthFactory() {
+    }
+
+    /**
+     * Returns a CSSValue built from the given SAC lexical unit.
+     * @param lu The SAC lexical unit used to create the value.
+     */
+    public CSSValue createCSSValue(LexicalUnit lu) {
+        switch (lu.getLexicalUnitType()) {
+        case LexicalUnit.SAC_PERCENTAGE:
+            return new CSSFloatValue(CSSPrimitiveValue.CSS_PERCENTAGE,
+                                     lu.getFloatValue());
+        case LexicalUnit.SAC_IDENT:
+            if (lu.getStringValue().equalsIgnoreCase(AUTO)) {
+                return AUTO_VALUE;
+            }
+        }
+        return super.createCSSValue(lu);
+    }
+}
diff --git a/sources/org/apache/batik/parser/style/StyleAttributeParser.java b/sources/org/apache/batik/parser/style/StyleAttributeParser.java
new file mode 100644
index 0000000..78312ba
--- /dev/null
+++ b/sources/org/apache/batik/parser/style/StyleAttributeParser.java
@@ -0,0 +1,182 @@
+/*****************************************************************************
+ * Copyright (C) The Apache Software Foundation. All rights reserved.        *
+ * ------------------------------------------------------------------------- *
+ * This software is published under the terms of the Apache Software License *
+ * version 1.1, a copy of which has been included with this distribution in  *
+ * the LICENSE file.                                                         *
+ *****************************************************************************/
+
+package org.apache.batik.parser.style;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import org.apache.batik.i18n.Localizable;
+import org.apache.batik.i18n.LocalizableSupport;
+import org.apache.batik.parser.ParseException;
+import org.w3c.css.sac.ErrorHandler;
+import org.w3c.css.sac.InputSource;
+import org.w3c.css.sac.LexicalUnit;
+import org.w3c.css.sac.Parser;
+import org.w3c.dom.css.CSSValue;
+
+/**
+ * This class represents a parser for SVG style attributes.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public class StyleAttributeParser implements Localizable {
+    /**
+     * The resources bundle classname.
+     */
+    public final static String BUNDLE_CLASSNAME =
+        "org.apache.batik.parser.style.resources.Messages";
+
+    /**
+     * The localizable support.
+     */
+    final static LocalizableSupport LOCALIZABLE_SUPPORT =
+        new LocalizableSupport(BUNDLE_CLASSNAME);
+
+    /**
+     * The underlying CSS parser.
+     */
+    protected Parser parser;
+
+    /**
+     * The ErrorHandler.
+     */
+    protected ErrorHandler errorHandler;
+
+    /**
+     * The value factories.
+     */
+    protected Map factories = new HashMap(5);
+
+    /**
+     * Creates a new StyleAttributeParser object.
+     * @param s The name of a SAC compliant CSS parser class.
+     */
+    public StyleAttributeParser(String s)
+        throws ParseException {
+        try {
+            parser = (Parser)Class.forName(s).newInstance();
+        } catch (Exception e) {
+            throw new ParseException
+                (formatMessage("creation.exception",
+                               new Object[] { e.getMessage() }),
+                 e);
+        }
+    }
+
+    /**
+     * Implements {@link org.apache.batik.i18n.Localizable#setLocale(Locale)}.
+     */
+    public void setLocale(Locale l) {
+        parser.setLocale(l);
+        LOCALIZABLE_SUPPORT.setLocale(l);
+    }
+
+    /**
+     * Implements {@link org.apache.batik.i18n.Localizable#getLocale()}.
+     */
+    public Locale getLocale() {
+        Locale l;
+        return ((l = LOCALIZABLE_SUPPORT.getLocale()) == null)
+            ? Locale.getDefault()
+            : l;
+    }
+
+    /**
+     * Implements {@link
+     * org.apache.batik.i18n.Localizable#formatMessage(String,Object[])}.
+     */
+    public String formatMessage(String key, Object[] args) {
+        return LOCALIZABLE_SUPPORT.formatMessage(key, args);
+    }
+
+    /**
+     * Parses the given reader and returns the CSSValue object
+     * corresponding to the attribute with the given namespaceURI
+     * and localName.
+     * @param ns The namespace URI of the attribute to parse.
+     * @param ln The local name of the attribute to parse.
+     */
+    public CSSValue parse(Reader r, String ns, String ln)
+        throws ParseException {
+        ns = (ns == null) ? "" : ns;
+        Map m = (Map)factories.get(ns);
+        if (m == null) {
+            throw new ParseException
+                (formatMessage("unknown.attribute",
+                               new Object[] { ns, ln }),
+                 -1, -1);
+        }
+        CSSValueFactory f = (CSSValueFactory)m.get(ln);
+        if (f == null) {
+            throw new ParseException
+                (formatMessage("unknown.attribute",
+                               new Object[] { ns, ln }),
+                 -1, -1);
+        }
+        try {
+            LexicalUnit lu = parser.parsePropertyValue(new InputSource(r));
+            return f.createCSSValue(lu);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new ParseException
+                (formatMessage("parser.exception",
+                               new Object[] { e.getMessage() }),
+                 e);
+        }
+    }
+
+    /**
+     * Sets the ErrorHandler.
+     */
+    public void setErrorHandler(ErrorHandler e) {
+        parser.setErrorHandler(errorHandler = e);
+    }
+
+    /**
+     * Gets the ErrorHandler.
+     */
+    public ErrorHandler getErrorHandler() {
+        return errorHandler;
+    }
+
+    /**
+     * Allows the user to register its own ValueFactory to create a
+     * style attribute value. 
+     * @param ns The namespace URI of the attribute associated with
+     *           the given factory.
+     * @param ln The local name of the attribute associated with
+     *           the given factory.
+     */
+    public void putCSSValueFactory(String ns, String ln, CSSValueFactory vf) {
+        ns = (ns == null) ? "" : ns;
+        Map m = (Map)factories.get(ns);
+        if (m == null) {
+            factories.put(ns, m = new HashMap(5));
+        }
+        m.put(ln, vf);
+    }
+
+    /**
+     * Allows the user to unregister a CSSValueFactory.
+     * @param ns The namespace URI of the attribute associated with
+     *           the factory to remove.
+     * @param ln The local name of the attribute associated with
+     *           the factory to remove.
+     */
+    public void removeCSSValueFactory(String ns, String ln) {
+        ns = (ns == null) ? "" : ns;
+        Map m = (Map)factories.get(ns);
+        if (m != null) {
+            m.remove(ln);
+        }
+    }
+}
diff --git a/sources/org/apache/batik/parser/style/package.html b/sources/org/apache/batik/parser/style/package.html
new file mode 100644
index 0000000..2d553c2
--- /dev/null
+++ b/sources/org/apache/batik/parser/style/package.html
@@ -0,0 +1,7 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
+        "http://www.w3.org/TR/REC-html40/loose.dtd">
+<html>
+  <body bgcolor="#FFFFFF">
+    Provides an extensible framework for style attributes parsing.
+  </body>
+</html>