Search code examples
svglanguage-specifications

SVG path spec: moveTo and implicit lineTo


I am trying to write a little SVG path parser / normalizer and got one last issue with the spec:

As far as I understood the most commands support additional implicit commands and when they do so and are in relative mode, the "current point" will be updated after the last implicit command, not in between them.

But the "moveTo" command is something special and allows implicit "lineTo" commands. While the "lineTo" command it self will only update the "current point" after the last implicit command:

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 is set to the final set of coordinates provided.

I am not sure what the "moveTo" with additional "lineTo" does. Extract of the SVG Path Spec:

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 moveto is followed by multiple pairs of coordinates, the subsequent pairs are treated as implicit lineto commands. Hence, implicit lineto commands will be relative if the moveto is relative, and absolute if the moveto is absolute. If a relative moveto (m) appears as the first element of the path, then it is treated as a pair of absolute coordinates. In this case, subsequent pairs of coordinates are treated as relative even though the initial moveto is interpreted as an absolute moveto.

Especially the last sentence is confusing.

And even worse, in SVGTiny Path Spec they wrote another description, while almost everything else is the same:

A new sub-path at the given (x,y) coordinate shall be started. This shall also establish a new current point at the given coordinate. If a relative 'moveto' (m) appears as the first element of the 'path', then it shall treated as a pair of absolute coordinates. If a 'moveto' is followed by multiple pairs of coordinates, the subsequent pairs shall be treated as implicit 'lineto' commands.

Does it mean that the "current point" is updated in between (which would be inconsistent to everything else) or was it just a ambiguous description which they corrected in newer versions?


Solution

  • Well it all seems perfectly clear to me.

    Here's an illustration of the two modes being used to draw two square (100px × 100px) boxes. The first uses absolute coordinates, and the second uses relative coordinates. As the spec states, when the first coordinate is specified with a lower-case 'm', then it is treated as an absolute coordinate, but all the coordinates that follow it are treated as relative.

    <svg widtn="250" height="140" viewBox="0 0 250 140">
      <g fill="none" stroke-width="5">
        <!-- 1. Move with implicit LineTo (absolute) -->
        <path d="M10,10 110,10 110,110 10,110z" stroke="blue" />
        <!-- 2. Move with implicit LineTo (relative) -->
        <path d="m120,10 100,0 0,100 -100,0z" stroke="red" />
        </g>
      </svg>