11 Paths


11.1 Introduction

Path objects are used to represent an outline which can be filled, stroked (see Filling, Stroking and Paint Servers) or used as a clipping path (see Clipping, Masking and Compositing), or for any combination of the three.

A path is described using the concept of a current point. In an analogy with drawing on paper, the current point can be thought of as the location of the pen. The position of the pen can be changed, and the outline of a shape (open or closed) can be traced by dragging the pen in either straight lines or curves.

Paths represent an outline of an object which is defined in terms of moveto (set a new current point), lineto (draw a straight line), curveto (draw a curve using a cubic bezier), arc (elliptical or circular arc) and closepath (close the current shape by drawing a line to the last moveto) elements. Compound paths (i.e., a path with subpaths, each consisting of a single moveto followed by one or more line or curve operations) are possible to allow effects such as "donut holes" in objects.

11.2 Path Data

A path is defined by including a <path> element which contains a d="(path data)" attribute, where the d attribute contains the moveto, line, curve (both cubic and quadratic beziers), arc and closepath instructions. The following example specifies a path in the shape of a triangle. (The M indicates a moveto, the L's indicate lineto's, and the z indicates a closepath:

<?xml version="1.0" standalone="yes"?>
<svg width="4in" height="3in"
 xmlns = 'http://www.w3.org/Graphics/SVG/svg-19990412.dtd'>
<path d="M 100 100 L 140 100 L 120 140 z"/>
</svg>

Download this example

A <path> element can also contain child <data> elements which also contain d="(path data)" attributes. This ability to have child <data> elements allows for very long path data strings to be broken up into more manageable smaller strings. It also allows for arrowheads and marker symbols to be controlled. Here is a <path> element equivalent to the <path> element above, but whose path data is divided into four pieces:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG April 1999//EN" 
  "http://www.w3.org/Graphics/SVG/svg-19990412.dtd">
<svg width="4in" height="3in">
  <path d="M 100 100">
    <data d="L 140 100"/>
    <data d="L 120 140"/>
    <data d="z"/>
  </path>
</svg>

Download this example

All d= attributes are concatenated together to yield a single path specification. The d= attribute on the <path> element precedes the d= attributes on the <data> elements.

The syntax of path data is very abbreviated in order to allow for minimal file size and efficient downloads, since many SVG files will be dominated by their path data. Here are some of the ways that SVG attempts to minimize the size of path data:

The path data syntax is a prefix notation (i.e., commands followed by parameters). The following table lists the commands:
Command Name Parameters Description Defaults
M (absolute)
m (relative)
moveto (x y)* Start a new sub-path at the given (x,y) coordinate. M (uppercase) indicates that absolute coordinates will follow; m (lowercase) indicates that relative coordinates will follow. If a relative moveto (m) appears as the first element of the path, then it is treated as a pair of absolute coordinates. If a moveto is followed by multiple pairs of coordinates, the subsequent pairs are treated as implicit lineto commands. zero
L (absolute)
l (relative)
lineto (x y)* Draw a line from the current point to the given (x,y) coordinate which becomes the new current point. L (uppercase) indicates that absolute coordinates will follow; l (lowercase) indicates that relative coordinates will follow. A number of coordinates pairs may be specified to draw a polyline. At the end of the command, the new current point becomes the last set of coordinates provided. zero
C (absolute)
c (relative)
curveto (x1 y1 x2 y2 x y)* Draws a cubic bezier curve from the current point to (x,y) using (x1,y1) as the control point at the beginning of the curve and (x2,y2) as the control point at the end of the curve. C (uppercase) indicates that absolute coordinates will follow; c (lowercase) indicates that relative coordinates will follow. Multiple sets of coordinates may be specified to draw a polybezier. At the end of the command, the new current point becomes the final (x,y) set of coordinates used in the polybezier. zero
z closepath (none) Close the current subpath by drawing a straight line from the current point to current subpath's most recent starting point (usually, the most recent moveto point). N/A
A Absolute coordinates (none) An A can appear anywhere between coordinates within any path data command to indicate that all subsequent coordinates are absolute. N/A
r Relative coordinates (none) An r can appear anywhere between coordinates within any path data command to indicate that all subsequent coordinates are relative to the current point at the start of the command. N/A
S (absolute)
s (relative)
smooth curveto (x2 y2 x y)* Draws a cubic bezier curve from the current point to (x,y). The first control point is assumed to be the reflection of the second control point on the previous command relative to the current point. (If there is no previous command or if the previous command was not a curve, assume the first control point is coincident with the current point.) (x2,y2) is the second control point (i.e., the control point at the end of the curve). S (uppercase) indicates that absolute coordinates will follow; s (lowercase) indicates that relative coordinates will follow. Multiple sets of coordinates may be specified to draw a polybezier. At the end of the command, the new current point becomes the final (x,y) set of coordinates used in the polybezier. zero
H (absolute)
h (relative)
horizontal lineto x* Draws a horizontal line from the current point (cpx, cpy) to (x, cpy). H (uppercase) indicates that absolute coordinates will follow; h (lowercase) indicates that relative coordinates will follow. Multiple x values can be provided (although usually this doesn't make sense). At the end of the command, the new current point becomes (x, cpy) for the final value of x. N/A
V (absolute)
v (relative)
vertical lineto y* Draws a vertical line from the current point (cpx, cpy) to (cpx, y). V (uppercase) indicates that absolute coordinates will follow; v (lowercase) indicates that relative coordinates will follow. Multiple y values can be provided (although usually this doesn't make sense). At the end of the command, the new current point becomes (cpx, y) for the final value of y. N/A
D (absolute)
d (relative)
counterclockwise elliptical arc
(moveto)
(cx cy a1 a2 r1 r2 a3)* Draws a counterclockwise elliptical arc described by its center (cx, cy), start angle in degrees (a1), end angle in degrees (a2), radius along X-axis (r1), radius along Y-axis (r2), and ellipse rotate angle in degrees (a3). All angles are converted to modula 360 degrees before processing, after which if a1=a2, then a complete ellipse is drawn. If r2 is not provided, it is assumed to be equal to r1 (circular arc). If a3 is not provided, it is assumed that the ellipse aligns with the axes of the current coordinate system. There is an implicit moveto from the current point to the start of the first arc. D (uppercase) indicates that absolute coordinates will follow; d (lowercase) indicates that relative coordinates will follow. Multiple values can be provided (although usually this doesn't make sense). At the end of the command, the new current point becomes the end point of the final arc. cx=0 cy=0 a1=0 a2=0 r1=0 r2=r1 a3=0
E (absolute)
e (relative)
counterclockwise elliptical arc
(lineto)
(cx cy a1 a2 r1 r2 a3)* Same as D/d, except that there is an implicit lineto from the current point to the start of the first arc. cx=0 cy=0 a1=0 a2=0 r1=0 r2=r1 a3=0
F (absolute)
f (relative)
clockwise elliptical arc
(moveto)
(cx cy a1 a2 r1 r2 a3)* Same as D/d, except that the arc is drawn in a clockwise direction. cx=0 cy=0 a1=0 a2=0 r1=0 r2=r1 a3=0
G (absolute)
g (relative)
clockwise elliptical arc
(lineto)
(cx cy a1 a2 r1 r2 a3)* Same as E/e, except that the arc is drawn in a clockwise direction. cx=0 cy=0 a1=0 a2=0 r1=0 r2=r1 a3=0
J (absolute)
j (relative)
elliptical quadrant x (x y angle)* A quarter ellipse is drawn from the current point to the given end point. The elliptical segment is initially tangential to a line pointing in direction <angle> at the current point and ends up tangential to a perpendicular line to <angle> going through (x,y). x=0 y=0 angle=0
Q (absolute)
q (relative)
quadratic bezier curveto (x1 y1 x y)* Draws a quadratic bezier curve from the current point to (x,y) using (x1,y1) as the control point. Q (uppercase) indicates that absolute coordinates will follow; q (lowercase) indicates that relative coordinates will follow. Multiple sets of coordinates may be specified to draw a polybezier. At the end of the command, the new current point becomes the final (x,y) set of coordinates used in the polybezier. x=0 y=0 angle=0
T (absolute)
t (relative)
Truetype quadratic bezier curveto (x1 y1)* (x y) Draws one or more quadratic bezier curves by means of multiple control points (can be as few as one set) and a single end point. Intermediate (on-curve) points are obtained by interpolation between successive control points as in the TrueType documentation within the OpenType font specification. (??? More details needed.) The subpath need not be started in which case the subpath will be closed. In this case the last point of the subpath defines the start point of the quadratic bezier. T (uppercase) indicates that absolute coordinates will follow; t (lowercase) indicates that relative coordinates will follow. At the end of the command, the new current point becomes the final (x,y) set of coordinates used in the polybezier. Zero

The DOM for SVG exposes an API will allows individual points to be enumerated, created, deleted and modified within a given path without the calling routine having to parse the path data stream.

11.3 The <marker> element

The <marker> element is used to incorporate arrowheads and marker symbols to a path. The <marker> element includes an href= attribute which references a symbol which should be drawn at all subsequent vertices on the path. The sizing, positioning and orientation of the given symbol are determined by the same text properties that control text on a path. (See Text on a path.) A <marker> element with no href= attribute indicates that no marker should be drawn for subsequent vertices on the path.

The following shows how a custom arrowhead can be drawn at both the start and end of a path, with the arrow pointing in opposite directions at each end:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG April 1999//EN" 
  "http://www.w3.org/Graphics/SVG/svg-19990412.dtd">
<svg width="4in" height="3in">
  <defs>
    <symbol id="Triangle" min-x="0" min-y="0" max-x="100" 
      max-y="100" ref-x="0" ref-y="50">
      <path d="M 0 0 L 0 100 L 100 50 z"/>
     </symbol>
   </defs>
  <desc>An double-headed arrow example using markers
  </desc>
  <path d="M0 0">
    <!-- Place an arrowhead rotated 180 degrees at the 
         beginning of the path -->
    <marker href="#Triangle" width="200" height="200" 
          style="text-transform: rotate(180)"/>
    <data d="M 2000 2000"/>

    <!-- Turn off markers in the middle of the path -->
    <marker href=""/>
    <data d="L 4000 2000 L 4000 4000"/>

    <!-- Place an arrowhead at the end of the path-->
    <marker href="#Triangle" width="200" height="200"/>
    <data d="L 6000 4000"/>
  </path>
</svg>

Download this example