This document is part of my ongoing work on documenting the conversion process from SVG to XAML-GUI. This document is expected to change as I learn more, and/or as XAML-GUI changes thanks to our feedback.
SVG Path Data
SVG (which borrowed this from VML) takes a minimalist approach when it comes to Path declarations. In order to cut down on the perceived verboseness of SVG, the authors decided to create a shorthand version of the Path information and squeeze it into the “d” (for Data) attribute. Instead of creating a full blown element for each path segment, they gave each path segment a letter (Upper Case version for Absolute positioning, and Lower Case for relative positioning):
- MoveTo – M or m
- ClosePath – Z or z
- LineTo – L or l
- HorizontalLineTo – H or h
- VetricalLineTo – V or v
- CubicBezier – C or c
- SmoothCubicBezier – S or s
- QuadraticBezier – Q or q
- SmoothQuadraticBezier - T or t
- EllipticalArc – A or a
Each path segment has a unique set of properties that are required to complete the segment, and must follow the letter, in a specific order, and must be separated by a space or a comma.
The benefit of this approach is that it requires a lot less memory when parsing the SVG document into the DOM (because there is only one node for all the path segments).
The drawbacks to this approach are:
Readability – It is definitely not human readable (well not easily anyway).
Animation – Because everything is buried in an attribute, it is not easy to declaratively animate any point within the path data. You would have to parse the attribute, update the point(s), and then serialize it back into the correct format.
Paths in XAML-GUI
XAML-GUI Paths use the same type of model as SVG paths, but (for the most part, and I’ll get to that later) instead of using the SVG (and prior to that VML) shorthand pathing language, it uses the more verbose (and explicit) form of declaring element for each path segment.
Within the Path.Data element you have a GeometryCollection which can contain individual shape elements (LineGeometry, ElipseGeometry, etc.) and/or PathGeometry. The PathGeometry is where we are focusing. Within the PathGeometry you have PathGeometry.Figures and within them you have a PathFigureCollection which contains PathFigures. Within a PathFigure there is PathFigure.Segments and within them are the PathSegementCollection which contains the collection of path segments that we want to declare. I know that seems like a lot, but all of that is also contained within the SVG Path element, just in a shorthanded version.
The possible Path Segments are:
- StartSegment – Equivalent to the SVG M
- CloseSegement – Equivalent to the SVG Z or z
- LineSegment – Equivalent to the SVG L
- BezierSegment – Equivalent to the SVG C
- QuadraticBezierSegment – Equivalent to SVG Q
- ArcSegment – Equivalent to SVG A
- PolyBezierSegment – Draws a series of connected Bezier Segments
- PolyLineSegment – Draws a series of connected Line Segments
- PolyQuadraticBezierSegment – Draws a series of connected Quadratic Bezier Segments
By comparing the XAML-GUI and SVG Path language constructs, you can see that for the most part they map to each other pretty well. SVG has the additional Horizontal and Vertical Line Segments, and the Smooth versions of Bezier and Quadratic Bezier. XAML-GUI has the additional Poly versions of the Bezier, Line, and Quadratic Bezier segments. The only major difference is that SVG allows for relative positioning in the definition of the points, and XAML-GUI does not, and there are very valid reasons why XAML-GUI excludes this feature.
Unfortunately, XAML-GUI confuses things by also including the ability to use SVG shorthand Path syntax, but only for lines, not the curved segments, and it also lets you use relative positioning (which you can not do with the standard XAML-GUI path segments). So, you can declare a data attribute for a Path element and embed the following Path Segments:
- MoveTo – M or m
- ClosePath – Z or z
- LineTo – L or l
- HorizontalLineTo – H or h
- VetricalLineTo – V or v
So, if you have SVG Paths, and you want to convert them to XAML-GUI paths, if the paths are only lines (not likely) you can just change the attribute name from “d” to Data, and you should get the same path.
But if you are using any curved segments, you will have to convert your paths to the absolute positioned XAML-GUI PathSegments.