Skip to content

Using SVG images

MWstudios edited this page Jul 19, 2021 · 1 revision

How to do it

SVG in Direct2D is pretty much unexplored territory. Nobody knows it exists, documentation on Microsoft is vague and partially missing, and very few questions exist on StackOverflow. Even less explored is the SharpDX implementation, however of the little information I found, I've put together a SvgImage class.

The creation and use of SVGs is straight-forward: Load a SVG, change its position, size and rotation, then draw it. If you wish to modify more than just this, you have access to SVG's individual elements. However, in Direct2D you can't create elements or attributes, just delete them, so you'll have to call Rebuild() in that case to load the SVG again.

SvgImage svg = new SvgImage(Global.DCs[0], "your image.svg");
svg.X = 200; svg.Y = 200;
svg.Rebuild(); //we've changed the position, so we have to rebuild before rendering
Global.DCs[0].DrawSvgDocument(svg);

svg.Dispose();

How does it work?

The new SvgImage class is what I've dedicated the most time into. It contains two XML classes in parallel: the Direct2D one and an XMLDocument from System.Xml. Direc2D's XML isn't very keen to outside code and has very little accessibility, whereas XMLDocument is what SvgImage relies on.

An SVG document is (optionally) loaded from a file and the string is then turned into a MemoryStream - the only way to load a document in Direct2D. All elements and attributes are read from XMLDocument's side, and are written into both Direct2D and XMLDocument simultaneously. However, the Direct2D side doesn't allow for new attributes to be created, which is why Rebuild() and the Outdated control exists. The Outdated property keeps track of every action that could make the Direct2D side go out of sync, and the UpdateIfOutdated property automatically calls Rebuild() if Outdated is set to true. Of course, calling Rebuild() on every SVG modification is unnecessary, and that's why UpdateIfOutdated is off by default and why you should call Rebuild() only once per frame.

Now about the transforming. Direct2D by itself can't move or rotate an SVG, but the SVG itself can. Every <g> element can have a transform attribute which sets the translation, rotation and scale of its contents. Some SVGs (such as the ones exported from Adobe Illustrator) have more than one <g> element, and as such, the transform attribute is applied to every <g> in the document. Moving shapes inside a SVG can have unexpected results if the <svg overflow> attribute isn't set to "visible", so remember to do that first, because some SVGs (such as those exported from MS Office) have it set to "hidden".

Another reminder to those who use MS Office for exporting SVGs: MS Office also exports the page behind the shapes. In that case you'll have to manually remove the <defs> element and the very first <rect> element in the file, which is the background.

In this wiki you can find out all the information on how to use the Ensoftener library. For more information on how to add Ensoftener to your project, see "Installing and running". The rest is dedicated to the library's features.

Notice: This wiki shows information for Ensoftener 5.0 and is currently outdated.

Clone this wiki locally