Rasterizes SVG image, returns RGBA image (non-premultiplied alpha).
The shapes in the SVG images are transformed by the viewBox and converted to specified units. That is, you should get the same looking data as your designed in your favorite app.
NanoVega.SVG can return the paths in few different units. For example if you want to render an image, you may choose to get the paths in pixels, or if you are feeding the data into a CNC-cutter, you may want to use millimeters.
The units passed to NanoVega.SVG should be one of: 'px', 'pt', 'pc', 'mm', 'cm', 'in'. DPI (dots-per-inch) controls how the unit conversion is done.
If you don't know or care about the units stuff, "px" and 96 should get you going.
Example Usage:
The easiest way to use it is to rasterize a SVG to a arsd.color.TrueColorImage, and from there you can work with it same as any other memory image. For example, to turn a SVG into a png:
import arsd.svg; import arsd.png; void main() { // Load NSVG* image = nsvgParseFromFile("test.svg", "px", 96); int w = cast(int) image.width; int h = cast(int) image.height; NSVGrasterizer rast = nsvgCreateRasterizer(); // Allocate memory for image auto img = new TrueColorImage(w, h); // Rasterize rasterize(rast, image, 0, 0, 1, img.imageData.bytes.ptr, w, h, w*4); // Delete image.kill(); writePng("test.png", img); }
You can also dig into the individual commands of the svg without rasterizing it. Note that this is fairly complicated - svgs have a lot of settings, and even this example only does the basics.
1 import core.stdc.stdio; 2 import core.stdc.stdlib; 3 import arsd.svg; 4 import arsd.nanovega; 5 6 void main() { 7 8 // we'll create a NanoVega window to display the image 9 int w = 800; 10 int h = 600; 11 auto window = new NVGWindow(w, h, "SVG Test"); 12 13 // Load the file and can look at its info 14 NSVG* image = nsvgParseFromFile("/home/me/svgs/arsd.svg", "px", 96); 15 printf("size: %f x %f\n", image.width, image.height); 16 17 // and then use the data when the window asks us to redraw 18 // note that is is far from complete; svgs can have shapes, clips, caps, joins... 19 // we're only doing the bare minimum here. 20 window.redrawNVGScene = delegate(nvg) { 21 22 // clear the screen with white so we can see the images on top of it 23 nvg.beginPath(); 24 nvg.fillColor = NVGColor.white; 25 nvg.rect(0, 0, window.width, window.height); 26 nvg.fill(); 27 nvg.closePath(); 28 29 image.forEachShape((in ref NSVG.Shape shape) { 30 if (!shape.visible) return; 31 32 nvg.beginPath(); 33 34 // load the stroke 35 nvg.strokeWidth = shape.strokeWidth; 36 debug import std.stdio; 37 38 final switch(shape.stroke.type) { 39 case NSVG.PaintType.None: 40 // no stroke 41 break; 42 case NSVG.PaintType.Color: 43 with(shape.stroke) 44 nvg.strokeColor = NVGColor(r, g, b, a); 45 debug writefln("%08x", shape.fill.color); 46 break; 47 case NSVG.PaintType.LinearGradient: 48 case NSVG.PaintType.RadialGradient: 49 // FIXME: set the nvg stroke paint to shape.stroke.gradient 50 } 51 52 // load the fill 53 final switch(shape.fill.type) { 54 case NSVG.PaintType.None: 55 // no fill set 56 break; 57 case NSVG.PaintType.Color: 58 with(shape.fill) 59 nvg.fillColor = NVGColor(r, g, b, a); 60 break; 61 case NSVG.PaintType.LinearGradient: 62 case NSVG.PaintType.RadialGradient: 63 // FIXME: set the nvg fill paint to shape.stroke.gradient 64 } 65 66 shape.forEachPath((in ref NSVG.Path path) { 67 // this will issue final `LineTo` for closed pathes 68 path.forEachCommand!true(delegate (NSVG.Command cmd, const(float)[] args) nothrow @trusted @nogc { 69 debug writeln(cmd, args); 70 final switch (cmd) { 71 case NSVG.Command.MoveTo: nvg.moveTo(args); break; 72 case NSVG.Command.LineTo: nvg.lineTo(args); break; 73 case NSVG.Command.QuadTo: nvg.quadTo(args); break; 74 case NSVG.Command.BezierTo: nvg.bezierTo(args); break; 75 } 76 }); 77 }); 78 79 nvg.fill(); 80 nvg.stroke(); 81 82 nvg.closePath(); 83 }); 84 }; 85 86 window.eventLoop(0); 87 88 // Delete the image 89 image.kill(); 90 }
TODO: maybe merge https://github.com/memononen/nanosvg/pull/94 too
NanoVega.SVG is a simple stupid SVG parser. The output of the parser is a list of drawing commands.
The library suits well for anything from rendering scalable icons in your editor application to prototyping a game.
NanoVega.SVG supports a wide range of SVG features, but several are be missing. Among the most notable known missing features: <use>, <text>, <def> for shapes (it does work for gradients), <script>, <style> (minimal inline style attributes work, but style blocks do not), and animations. Note that <clipPath> is new and may be buggy (but anything in here may be buggy!) and the css support is fairly rudimentary.