From 1c472d80856d4c7cedf66bc3d35f0dfece250552 Mon Sep 17 00:00:00 2001 From: Leon Styhre Date: Mon, 7 Jun 2021 21:39:15 +0200 Subject: [PATCH] Squashed 'external/nanosvg/' content from commit 3cdd4a9d git-subtree-dir: external/nanosvg git-subtree-split: 3cdd4a9d788695699799b37d492e45e2c3625790 --- .gitignore | 31 + LICENSE.txt | 18 + README.md | 102 ++ example/23.svg | 730 +++++++++ example/drawing.svg | 97 ++ example/example1.c | 258 ++++ example/example2.c | 69 + example/nano.svg | 27 + example/screenshot-1.png | Bin 0 -> 60837 bytes example/screenshot-2.png | Bin 0 -> 158111 bytes example/stb_image_write.h | 511 +++++++ premake4.lua | 56 + src/nanosvg.h | 3021 +++++++++++++++++++++++++++++++++++++ src/nanosvgrast.h | 1452 ++++++++++++++++++ 14 files changed, 6372 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE.txt create mode 100644 README.md create mode 100644 example/23.svg create mode 100644 example/drawing.svg create mode 100644 example/example1.c create mode 100644 example/example2.c create mode 100644 example/nano.svg create mode 100644 example/screenshot-1.png create mode 100644 example/screenshot-2.png create mode 100644 example/stb_image_write.h create mode 100644 premake4.lua create mode 100644 src/nanosvg.h create mode 100644 src/nanosvgrast.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..5b3d1a084 --- /dev/null +++ b/.gitignore @@ -0,0 +1,31 @@ +## Compiled source # +*.com +*.class +*.dll +*.exe +*.o +*.so +test + +## Logs and databases # +*.log +*.sql +*.sqlite + +## OS generated files # +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +## Build dir +build/* + +## Stuff in example +example/_* + +## xcode specific +*xcuserdata* diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 000000000..6fde401cb --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,18 @@ +Copyright (c) 2013-14 Mikko Mononen memon@inside.org + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software +in a product, an acknowledgment in the product documentation would be +appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + diff --git a/README.md b/README.md new file mode 100644 index 000000000..0865cbe26 --- /dev/null +++ b/README.md @@ -0,0 +1,102 @@ +*This project is not actively maintained.* + +Nano SVG +========== + +## Parser + +![screenshot of some splines rendered with the sample program](/example/screenshot-1.png?raw=true) + +NanoSVG is a simple stupid single-header-file SVG parse. The output of the parser is a list of cubic bezier shapes. + +The library suits well for anything from rendering scalable icons in your editor application to prototyping a game. + +NanoSVG supports a wide range of SVG features, but something may be missing, feel free to create a pull request! + +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. + +NanoSVG 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 NanoSVG should be one of: 'px', 'pt', 'pc' 'mm', 'cm', or '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. + +## Rasterizer + +![screenshot of tiger.svg rendered with NanoSVG rasterizer](/example/screenshot-2.png?raw=true) + +The parser library is accompanied with really simpler SVG rasterizer. Currently it only renders flat filled shapes. + +The intended usage for the rasterizer is to for example bake icons of different size into a texture. The rasterizer is not particular fast or accurate, but it's small and packed in one header file. + + +## Example Usage + +``` C +// Load +struct NSVGimage* image; +image = nsvgParseFromFile("test.svg", "px", 96); +printf("size: %f x %f\n", image->width, image->height); +// Use... +for (shape = image->shapes; shape != NULL; shape = shape->next) { + for (path = shape->paths; path != NULL; path = path->next) { + for (i = 0; i < path->npts-1; i += 3) { + float* p = &path->pts[i*2]; + drawCubicBez(p[0],p[1], p[2],p[3], p[4],p[5], p[6],p[7]); + } + } +} +// Delete +nsvgDelete(image); +``` + +## Using NanoSVG in your project + +In order to use NanoSVG in your own project, just copy nanosvg.h to your project. +In one C/C++ define `NANOSVG_IMPLEMENTATION` before including the library to expand the NanoSVG implementation in that file. +NanoSVG depends on `stdio.h` ,`string.h` and `math.h`, they should be included where the implementation is expanded before including NanoSVG. + +``` C +#include +#include +#include +#define NANOSVG_IMPLEMENTATION // Expands implementation +#include "nanosvg.h" +``` + +By default, NanoSVG parses only the most common colors. In order to get support for full list of [SVG color keywords](http://www.w3.org/TR/SVG11/types.html#ColorKeywords), define `NANOSVG_ALL_COLOR_KEYWORDS` before expanding the implementation. + +``` C +#include +#include +#include +#define NANOSVG_ALL_COLOR_KEYWORDS // Include full list of color keywords. +#define NANOSVG_IMPLEMENTATION // Expands implementation +#include "nanosvg.h" +``` + +## Compiling Example Project + +In order to compile the demo project, your will need to install [GLFW](http://www.glfw.org/) to compile. + +NanoSVG demo project uses [premake4](http://industriousone.com/premake) to build platform specific projects, now is good time to install it if you don't have it already. To build the example, navigate into the root folder in your favorite terminal, then: + +- *OS X*: `premake4 xcode4` +- *Windows*: `premake4 vs2010` +- *Linux*: `premake4 gmake` + +See premake4 documentation for full list of supported build file types. The projects will be created in `build` folder. An example of building and running the example on OS X: + +```bash +$ premake4 gmake +$ cd build/ +$ make +$ ./example +``` + +# License + +The library is licensed under [zlib license](LICENSE.txt) diff --git a/example/23.svg b/example/23.svg new file mode 100644 index 000000000..983e57026 --- /dev/null +++ b/example/23.svg @@ -0,0 +1,730 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/drawing.svg b/example/drawing.svg new file mode 100644 index 000000000..428a8e13d --- /dev/null +++ b/example/drawing.svg @@ -0,0 +1,97 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/example/example1.c b/example/example1.c new file mode 100644 index 000000000..100831be0 --- /dev/null +++ b/example/example1.c @@ -0,0 +1,258 @@ +// +// Copyright (c) 2013 Mikko Mononen memon@inside.org +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// + +#include +#include +#include +#include + +#define NANOSVG_IMPLEMENTATION +#include "nanosvg.h" + +NSVGimage* g_image = NULL; + +static unsigned char bgColor[4] = {205,202,200,255}; +static unsigned char lineColor[4] = {0,160,192,255}; + +static float distPtSeg(float x, float y, float px, float py, float qx, float qy) +{ + float pqx, pqy, dx, dy, d, t; + pqx = qx-px; + pqy = qy-py; + dx = x-px; + dy = y-py; + d = pqx*pqx + pqy*pqy; + t = pqx*dx + pqy*dy; + if (d > 0) t /= d; + if (t < 0) t = 0; + else if (t > 1) t = 1; + dx = px + t*pqx - x; + dy = py + t*pqy - y; + return dx*dx + dy*dy; +} + +static void cubicBez(float x1, float y1, float x2, float y2, + float x3, float y3, float x4, float y4, + float tol, int level) +{ + float x12,y12,x23,y23,x34,y34,x123,y123,x234,y234,x1234,y1234; + float d; + + if (level > 12) return; + + x12 = (x1+x2)*0.5f; + y12 = (y1+y2)*0.5f; + x23 = (x2+x3)*0.5f; + y23 = (y2+y3)*0.5f; + x34 = (x3+x4)*0.5f; + y34 = (y3+y4)*0.5f; + x123 = (x12+x23)*0.5f; + y123 = (y12+y23)*0.5f; + x234 = (x23+x34)*0.5f; + y234 = (y23+y34)*0.5f; + x1234 = (x123+x234)*0.5f; + y1234 = (y123+y234)*0.5f; + + d = distPtSeg(x1234, y1234, x1,y1, x4,y4); + if (d > tol*tol) { + cubicBez(x1,y1, x12,y12, x123,y123, x1234,y1234, tol, level+1); + cubicBez(x1234,y1234, x234,y234, x34,y34, x4,y4, tol, level+1); + } else { + glVertex2f(x4, y4); + } +} + +void drawPath(float* pts, int npts, char closed, float tol) +{ + int i; + glBegin(GL_LINE_STRIP); + glColor4ubv(lineColor); + glVertex2f(pts[0], pts[1]); + for (i = 0; i < npts-1; i += 3) { + float* p = &pts[i*2]; + cubicBez(p[0],p[1], p[2],p[3], p[4],p[5], p[6],p[7], tol, 0); + } + if (closed) { + glVertex2f(pts[0], pts[1]); + } + glEnd(); +} + +void drawControlPts(float* pts, int npts) +{ + int i; + + // Control lines + glColor4ubv(lineColor); + glBegin(GL_LINES); + for (i = 0; i < npts-1; i += 3) { + float* p = &pts[i*2]; + glVertex2f(p[0],p[1]); + glVertex2f(p[2],p[3]); + glVertex2f(p[4],p[5]); + glVertex2f(p[6],p[7]); + } + glEnd(); + + // Points + glPointSize(6.0f); + glColor4ubv(lineColor); + + glBegin(GL_POINTS); + glVertex2f(pts[0],pts[1]); + for (i = 0; i < npts-1; i += 3) { + float* p = &pts[i*2]; + glVertex2f(p[6],p[7]); + } + glEnd(); + + // Points + glPointSize(3.0f); + + glBegin(GL_POINTS); + glColor4ubv(bgColor); + glVertex2f(pts[0],pts[1]); + for (i = 0; i < npts-1; i += 3) { + float* p = &pts[i*2]; + glColor4ubv(lineColor); + glVertex2f(p[2],p[3]); + glVertex2f(p[4],p[5]); + glColor4ubv(bgColor); + glVertex2f(p[6],p[7]); + } + glEnd(); +} + +void drawframe(GLFWwindow* window) +{ + int width = 0, height = 0; + float view[4], cx, cy, hw, hh, aspect, px; + NSVGshape* shape; + NSVGpath* path; + + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + glfwGetFramebufferSize(window, &width, &height); + + glViewport(0, 0, width, height); + glClearColor(220.0f/255.0f, 220.0f/255.0f, 220.0f/255.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_TEXTURE_2D); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + // Fit view to bounds + cx = g_image->width*0.5f; + cy = g_image->height*0.5f; + hw = g_image->width*0.5f; + hh = g_image->height*0.5f; + + if (width/hw < height/hh) { + aspect = (float)height / (float)width; + view[0] = cx - hw * 1.2f; + view[2] = cx + hw * 1.2f; + view[1] = cy - hw * 1.2f * aspect; + view[3] = cy + hw * 1.2f * aspect; + } else { + aspect = (float)width / (float)height; + view[0] = cx - hh * 1.2f * aspect; + view[2] = cx + hh * 1.2f * aspect; + view[1] = cy - hh * 1.2f; + view[3] = cy + hh * 1.2f; + } + // Size of one pixel. + px = (view[2] - view[1]) / (float)width; + + glOrtho(view[0], view[2], view[3], view[1], -1, 1); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glDisable(GL_DEPTH_TEST); + glColor4ub(255,255,255,255); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + // Draw bounds + glColor4ub(0,0,0,64); + glBegin(GL_LINE_LOOP); + glVertex2f(0, 0); + glVertex2f(g_image->width, 0); + glVertex2f(g_image->width, g_image->height); + glVertex2f(0, g_image->height); + glEnd(); + + for (shape = g_image->shapes; shape != NULL; shape = shape->next) { + for (path = shape->paths; path != NULL; path = path->next) { + drawPath(path->pts, path->npts, path->closed, px * 1.5f); + drawControlPts(path->pts, path->npts); + } + } + + glfwSwapBuffers(window); +} + +void resizecb(GLFWwindow* window, int width, int height) +{ + // Update and render + NSVG_NOTUSED(width); + NSVG_NOTUSED(height); + drawframe(window); +} + +int main() +{ + GLFWwindow* window; + const GLFWvidmode* mode; + + if (!glfwInit()) + return -1; + + mode = glfwGetVideoMode(glfwGetPrimaryMonitor()); + window = glfwCreateWindow(mode->width - 40, mode->height - 80, "Nano SVG", NULL, NULL); + if (!window) + { + printf("Could not open window\n"); + glfwTerminate(); + return -1; + } + + glfwSetFramebufferSizeCallback(window, resizecb); + glfwMakeContextCurrent(window); + glEnable(GL_POINT_SMOOTH); + glEnable(GL_LINE_SMOOTH); + + + g_image = nsvgParseFromFile("../example/nano.svg", "px", 96.0f); + if (g_image == NULL) { + printf("Could not open SVG image.\n"); + glfwTerminate(); + return -1; + } + + while (!glfwWindowShouldClose(window)) + { + drawframe(window); + glfwPollEvents(); + } + + nsvgDelete(g_image); + + glfwTerminate(); + return 0; +} diff --git a/example/example2.c b/example/example2.c new file mode 100644 index 000000000..9ae9b5952 --- /dev/null +++ b/example/example2.c @@ -0,0 +1,69 @@ +// +// Copyright (c) 2013 Mikko Mononen memon@inside.org +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// + +#include +#include +#include +#define STB_IMAGE_WRITE_IMPLEMENTATION +#include "stb_image_write.h" +#define NANOSVG_IMPLEMENTATION +#include "nanosvg.h" +#define NANOSVGRAST_IMPLEMENTATION +#include "nanosvgrast.h" + +int main() +{ + NSVGimage *image = NULL; + NSVGrasterizer *rast = NULL; + unsigned char* img = NULL; + int w, h; + const char* filename = "../example/23.svg"; + + printf("parsing %s\n", filename); + image = nsvgParseFromFile(filename, "px", 96.0f); + if (image == NULL) { + printf("Could not open SVG image.\n"); + goto error; + } + w = (int)image->width; + h = (int)image->height; + + rast = nsvgCreateRasterizer(); + if (rast == NULL) { + printf("Could not init rasterizer.\n"); + goto error; + } + + img = malloc(w*h*4); + if (img == NULL) { + printf("Could not alloc image buffer.\n"); + goto error; + } + + printf("rasterizing image %d x %d\n", w, h); + nsvgRasterize(rast, image, 0,0,1, img, w, h, w*4); + + printf("writing svg.png\n"); + stbi_write_png("svg.png", w, h, 4, img, w*4); + +error: + nsvgDeleteRasterizer(rast); + nsvgDelete(image); + + return 0; +} diff --git a/example/nano.svg b/example/nano.svg new file mode 100644 index 000000000..15635a16f --- /dev/null +++ b/example/nano.svg @@ -0,0 +1,27 @@ + + + + + + diff --git a/example/screenshot-1.png b/example/screenshot-1.png new file mode 100644 index 0000000000000000000000000000000000000000..f6526cfb47c1be351562c5884840f27b4eeb65d8 GIT binary patch literal 60837 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

`(r_ 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 z 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 iusA{#cX88zZrDcxpL#2*FDu~ze;TUVD& +#include +#include +#include +#include + +typedef unsigned int stbiw_uint32; +typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1]; + +static void writefv(FILE *f, const char *fmt, va_list v) +{ + while (*fmt) { + switch (*fmt++) { + case ' ': break; + case '1': { unsigned char x = (unsigned char) va_arg(v, int); fputc(x,f); break; } + case '2': { int x = va_arg(v,int); unsigned char b[2]; + b[0] = (unsigned char) x; b[1] = (unsigned char) (x>>8); + fwrite(b,2,1,f); break; } + case '4': { stbiw_uint32 x = va_arg(v,int); unsigned char b[4]; + b[0]=(unsigned char)x; b[1]=(unsigned char)(x>>8); + b[2]=(unsigned char)(x>>16); b[3]=(unsigned char)(x>>24); + fwrite(b,4,1,f); break; } + default: + assert(0); + return; + } + } +} + +static void write3(FILE *f, unsigned char a, unsigned char b, unsigned char c) +{ + unsigned char arr[3]; + arr[0] = a, arr[1] = b, arr[2] = c; + fwrite(arr, 3, 1, f); +} + +static void write_pixels(FILE *f, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad) +{ + unsigned char bg[3] = { 255, 0, 255}, px[3]; + stbiw_uint32 zero = 0; + int i,j,k, j_end; + + if (y <= 0) + return; + + if (vdir < 0) + j_end = -1, j = y-1; + else + j_end = y, j = 0; + + for (; j != j_end; j += vdir) { + for (i=0; i < x; ++i) { + unsigned char *d = (unsigned char *) data + (j*x+i)*comp; + if (write_alpha < 0) + fwrite(&d[comp-1], 1, 1, f); + switch (comp) { + case 1: + case 2: write3(f, d[0],d[0],d[0]); + break; + case 4: + if (!write_alpha) { + // composite against pink background + for (k=0; k < 3; ++k) + px[k] = bg[k] + ((d[k] - bg[k]) * d[3])/255; + write3(f, px[1-rgb_dir],px[1],px[1+rgb_dir]); + break; + } + /* FALLTHROUGH */ + case 3: + write3(f, d[1-rgb_dir],d[1],d[1+rgb_dir]); + break; + } + if (write_alpha > 0) + fwrite(&d[comp-1], 1, 1, f); + } + fwrite(&zero,scanline_pad,1,f); + } +} + +static int outfile(char const *filename, int rgb_dir, int vdir, int x, int y, int comp, void *data, int alpha, int pad, const char *fmt, ...) +{ + FILE *f; + if (y < 0 || x < 0) return 0; + f = fopen(filename, "wb"); + if (f) { + va_list v; + va_start(v, fmt); + writefv(f, fmt, v); + va_end(v); + write_pixels(f,rgb_dir,vdir,x,y,comp,data,alpha,pad); + fclose(f); + } + return f != NULL; +} + +int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data) +{ + int pad = (-x*3) & 3; + return outfile(filename,-1,-1,x,y,comp,(void *) data,0,pad, + "11 4 22 4" "4 44 22 444444", + 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header + 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header +} + +int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data) +{ + int has_alpha = !(comp & 1); + return outfile(filename, -1,-1, x, y, comp, (void *) data, has_alpha, 0, + "111 221 2222 11", 0,0,2, 0,0,0, 0,0,x,y, 24+8*has_alpha, 8*has_alpha); +} + +// stretchy buffer; stbi__sbpush() == vector<>::push_back() -- stbi__sbcount() == vector<>::size() +#define stbi__sbraw(a) ((int *) (a) - 2) +#define stbi__sbm(a) stbi__sbraw(a)[0] +#define stbi__sbn(a) stbi__sbraw(a)[1] + +#define stbi__sbneedgrow(a,n) ((a)==0 || stbi__sbn(a)+n >= stbi__sbm(a)) +#define stbi__sbmaybegrow(a,n) (stbi__sbneedgrow(a,(n)) ? stbi__sbgrow(a,n) : 0) +#define stbi__sbgrow(a,n) stbi__sbgrowf((void **) &(a), (n), sizeof(*(a))) + +#define stbi__sbpush(a, v) (stbi__sbmaybegrow(a,1), (a)[stbi__sbn(a)++] = (v)) +#define stbi__sbcount(a) ((a) ? stbi__sbn(a) : 0) +#define stbi__sbfree(a) ((a) ? free(stbi__sbraw(a)),0 : 0) + +static void *stbi__sbgrowf(void **arr, int increment, int itemsize) +{ + int m = *arr ? 2*stbi__sbm(*arr)+increment : increment+1; + void *p = realloc(*arr ? stbi__sbraw(*arr) : 0, itemsize * m + sizeof(int)*2); + assert(p); + if (p) { + if (!*arr) ((int *) p)[1] = 0; + *arr = (void *) ((int *) p + 2); + stbi__sbm(*arr) = m; + } + return *arr; +} + +static unsigned char *stbi__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount) +{ + while (*bitcount >= 8) { + stbi__sbpush(data, (unsigned char) *bitbuffer); + *bitbuffer >>= 8; + *bitcount -= 8; + } + return data; +} + +static int stbi__zlib_bitrev(int code, int codebits) +{ + int res=0; + while (codebits--) { + res = (res << 1) | (code & 1); + code >>= 1; + } + return res; +} + +static unsigned int stbi__zlib_countm(unsigned char *a, unsigned char *b, int limit) +{ + int i; + for (i=0; i < limit && i < 258; ++i) + if (a[i] != b[i]) break; + return i; +} + +static unsigned int stbi__zhash(unsigned char *data) +{ + stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16); + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 4; + hash += hash >> 17; + hash ^= hash << 25; + hash += hash >> 6; + return hash; +} + +#define stbi__zlib_flush() (out = stbi__zlib_flushf(out, &bitbuf, &bitcount)) +#define stbi__zlib_add(code,codebits) \ + (bitbuf |= (code) << bitcount, bitcount += (codebits), stbi__zlib_flush()) +#define stbi__zlib_huffa(b,c) stbi__zlib_add(stbi__zlib_bitrev(b,c),c) +// default huffman tables +#define stbi__zlib_huff1(n) stbi__zlib_huffa(0x30 + (n), 8) +#define stbi__zlib_huff2(n) stbi__zlib_huffa(0x190 + (n)-144, 9) +#define stbi__zlib_huff3(n) stbi__zlib_huffa(0 + (n)-256,7) +#define stbi__zlib_huff4(n) stbi__zlib_huffa(0xc0 + (n)-280,8) +#define stbi__zlib_huff(n) ((n) <= 143 ? stbi__zlib_huff1(n) : (n) <= 255 ? stbi__zlib_huff2(n) : (n) <= 279 ? stbi__zlib_huff3(n) : stbi__zlib_huff4(n)) +#define stbi__zlib_huffb(n) ((n) <= 143 ? stbi__zlib_huff1(n) : stbi__zlib_huff2(n)) + +#define stbi__ZHASH 16384 + +unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality) +{ + static unsigned short lengthc[] = { 3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258, 259 }; + static unsigned char lengtheb[]= { 0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 }; + static unsigned short distc[] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577, 32768 }; + static unsigned char disteb[] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 }; + unsigned int bitbuf=0; + int i,j, bitcount=0; + unsigned char *out = NULL; + unsigned char **hash_table[stbi__ZHASH]; // 64KB on the stack! + if (quality < 5) quality = 5; + + stbi__sbpush(out, 0x78); // DEFLATE 32K window + stbi__sbpush(out, 0x5e); // FLEVEL = 1 + stbi__zlib_add(1,1); // BFINAL = 1 + stbi__zlib_add(1,2); // BTYPE = 1 -- fixed huffman + + for (i=0; i < stbi__ZHASH; ++i) + hash_table[i] = NULL; + + i=0; + while (i < data_len-3) { + // hash next 3 bytes of data to be compressed + int h = stbi__zhash(data+i)&(stbi__ZHASH-1), best=3; + unsigned char *bestloc = 0; + unsigned char **hlist = hash_table[h]; + int n = stbi__sbcount(hlist); + for (j=0; j < n; ++j) { + if (hlist[j]-data > i-32768) { // if entry lies within window + int d = stbi__zlib_countm(hlist[j], data+i, data_len-i); + if (d >= best) best=d,bestloc=hlist[j]; + } + } + // when hash table entry is too long, delete half the entries + if (hash_table[h] && stbi__sbn(hash_table[h]) == 2*quality) { + memcpy(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality); + stbi__sbn(hash_table[h]) = quality; + } + stbi__sbpush(hash_table[h],data+i); + + if (bestloc) { + // "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal + h = stbi__zhash(data+i+1)&(stbi__ZHASH-1); + hlist = hash_table[h]; + n = stbi__sbcount(hlist); + for (j=0; j < n; ++j) { + if (hlist[j]-data > i-32767) { + int e = stbi__zlib_countm(hlist[j], data+i+1, data_len-i-1); + if (e > best) { // if next match is better, bail on current match + bestloc = NULL; + break; + } + } + } + } + + if (bestloc) { + int d = data+i - bestloc; // distance back + assert(d <= 32767 && best <= 258); + for (j=0; best > lengthc[j+1]-1; ++j); + stbi__zlib_huff(j+257); + if (lengtheb[j]) stbi__zlib_add(best - lengthc[j], lengtheb[j]); + for (j=0; d > distc[j+1]-1; ++j); + stbi__zlib_add(stbi__zlib_bitrev(j,5),5); + if (disteb[j]) stbi__zlib_add(d - distc[j], disteb[j]); + i += best; + } else { + stbi__zlib_huffb(data[i]); + ++i; + } + } + // write out final bytes + for (;i < data_len; ++i) + stbi__zlib_huffb(data[i]); + stbi__zlib_huff(256); // end of block + // pad with 0 bits to byte boundary + while (bitcount) + stbi__zlib_add(0,1); + + for (i=0; i < stbi__ZHASH; ++i) + (void) stbi__sbfree(hash_table[i]); + + { + // compute adler32 on input + unsigned int i=0, s1=1, s2=0, blocklen = data_len % 5552; + int j=0; + while (j < data_len) { + for (i=0; i < blocklen; ++i) s1 += data[j+i], s2 += s1; + s1 %= 65521, s2 %= 65521; + j += blocklen; + blocklen = 5552; + } + stbi__sbpush(out, (unsigned char) (s2 >> 8)); + stbi__sbpush(out, (unsigned char) s2); + stbi__sbpush(out, (unsigned char) (s1 >> 8)); + stbi__sbpush(out, (unsigned char) s1); + } + *out_len = stbi__sbn(out); + // make returned pointer freeable + memmove(stbi__sbraw(out), out, *out_len); + return (unsigned char *) stbi__sbraw(out); +} + +unsigned int stbi__crc32(unsigned char *buffer, int len) +{ + static unsigned int crc_table[256]; + unsigned int crc = ~0u; + int i,j; + if (crc_table[1] == 0) + for(i=0; i < 256; i++) + for (crc_table[i]=i, j=0; j < 8; ++j) + crc_table[i] = (crc_table[i] >> 1) ^ (crc_table[i] & 1 ? 0xedb88320 : 0); + for (i=0; i < len; ++i) + crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)]; + return ~crc; +} + +#define stbi__wpng4(o,a,b,c,d) ((o)[0]=(unsigned char)(a),(o)[1]=(unsigned char)(b),(o)[2]=(unsigned char)(c),(o)[3]=(unsigned char)(d),(o)+=4) +#define stbi__wp32(data,v) stbi__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v)); +#define stbi__wptag(data,s) stbi__wpng4(data, s[0],s[1],s[2],s[3]) + +static void stbi__wpcrc(unsigned char **data, int len) +{ + unsigned int crc = stbi__crc32(*data - len - 4, len+4); + stbi__wp32(*data, crc); +} + +static unsigned char stbi__paeth(int a, int b, int c) +{ + int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c); + if (pa <= pb && pa <= pc) return (unsigned char) a; + if (pb <= pc) return (unsigned char) b; + return (unsigned char) c; +} + +unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len) +{ + int ctype[5] = { -1, 0, 4, 2, 6 }; + unsigned char sig[8] = { 137,80,78,71,13,10,26,10 }; + unsigned char *out,*o, *filt, *zlib; + signed char *line_buffer; + int i,j,k,p,zlen; + + if (stride_bytes == 0) + stride_bytes = x * n; + + filt = (unsigned char *) malloc((x*n+1) * y); if (!filt) return 0; + line_buffer = (signed char *) malloc(x * n); if (!line_buffer) { free(filt); return 0; } + for (j=0; j < y; ++j) { + static int mapping[] = { 0,1,2,3,4 }; + static int firstmap[] = { 0,1,0,5,6 }; + int *mymap = j ? mapping : firstmap; + int best = 0, bestval = 0x7fffffff; + for (p=0; p < 2; ++p) { + for (k= p?best:0; k < 5; ++k) { + int type = mymap[k],est=0; + unsigned char *z = pixels + stride_bytes*j; + for (i=0; i < n; ++i) + switch (type) { + case 0: line_buffer[i] = z[i]; break; + case 1: line_buffer[i] = z[i]; break; + case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break; + case 3: line_buffer[i] = z[i] - (z[i-stride_bytes]>>1); break; + case 4: line_buffer[i] = (signed char) (z[i] - stbi__paeth(0,z[i-stride_bytes],0)); break; + case 5: line_buffer[i] = z[i]; break; + case 6: line_buffer[i] = z[i]; break; + } + for (i=n; i < x*n; ++i) { + switch (type) { + case 0: line_buffer[i] = z[i]; break; + case 1: line_buffer[i] = z[i] - z[i-n]; break; + case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break; + case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-stride_bytes])>>1); break; + case 4: line_buffer[i] = z[i] - stbi__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]); break; + case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break; + case 6: line_buffer[i] = z[i] - stbi__paeth(z[i-n], 0,0); break; + } + } + if (p) break; + for (i=0; i < x*n; ++i) + est += abs((signed char) line_buffer[i]); + if (est < bestval) { bestval = est; best = k; } + } + } + // when we get here, best contains the filter type, and line_buffer contains the data + filt[j*(x*n+1)] = (unsigned char) best; + memcpy(filt+j*(x*n+1)+1, line_buffer, x*n); + } + free(line_buffer); + zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, 8); // increase 8 to get smaller but use more memory + free(filt); + if (!zlib) return 0; + + // each tag requires 12 bytes of overhead + out = (unsigned char *) malloc(8 + 12+13 + 12+zlen + 12); + if (!out) return 0; + *out_len = 8 + 12+13 + 12+zlen + 12; + + o=out; + memcpy(o,sig,8); o+= 8; + stbi__wp32(o, 13); // header length + stbi__wptag(o, "IHDR"); + stbi__wp32(o, x); + stbi__wp32(o, y); + *o++ = 8; + *o++ = (unsigned char) ctype[n]; + *o++ = 0; + *o++ = 0; + *o++ = 0; + stbi__wpcrc(&o,13); + + stbi__wp32(o, zlen); + stbi__wptag(o, "IDAT"); + memcpy(o, zlib, zlen); o += zlen; free(zlib); + stbi__wpcrc(&o, zlen); + + stbi__wp32(o,0); + stbi__wptag(o, "IEND"); + stbi__wpcrc(&o,0); + + assert(o == out + *out_len); + + return out; +} + +int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes) +{ + FILE *f; + int len; + unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len); + if (!png) return 0; + f = fopen(filename, "wb"); + if (!f) { free(png); return 0; } + fwrite(png, 1, len, f); + fclose(f); + free(png); + return 1; +} +#endif // STB_IMAGE_WRITE_IMPLEMENTATION + +/* Revision history + + 0.92 (2010-08-01) + casts to unsigned char to fix warnings + 0.91 (2010-07-17) + first public release + 0.90 first internal release +*/ diff --git a/premake4.lua b/premake4.lua new file mode 100644 index 000000000..8befd82ef --- /dev/null +++ b/premake4.lua @@ -0,0 +1,56 @@ + +local action = _ACTION or "" + +solution "nanosvg" + location ( "build" ) + configurations { "Debug", "Release" } + platforms {"native", "x64", "x32"} + + project "example1" + kind "ConsoleApp" + language "C++" + files { "example/example1.c", "example/*.h", "src/*.h" } + includedirs { "example", "src" } + targetdir("build") + + configuration { "linux" } + links { "X11","Xrandr", "rt", "GL", "GLU", "pthread", "glfw" } + + configuration { "windows" } + links { "glu32","opengl32", "gdi32", "winmm", "user32" } + + configuration { "macosx" } + links { "glfw3" } + linkoptions { "-framework OpenGL", "-framework Cocoa", "-framework IOKit", "-framework CoreVideo" } + + configuration "Debug" + defines { "DEBUG" } + flags { "Symbols", "ExtraWarnings"} + + configuration "Release" + defines { "NDEBUG" } + flags { "Optimize", "ExtraWarnings"} + + project "example2" + kind "ConsoleApp" + language "C++" + files { "example/example2.c", "example/*.h", "src/*.h" } + includedirs { "example", "src" } + targetdir("build") + + configuration { "linux" } + links { "X11","Xrandr", "rt", "pthread" } + + configuration { "windows" } + links { "winmm", "user32" } + + configuration { "macosx" } + linkoptions { "-framework Cocoa", "-framework IOKit" } + + configuration "Debug" + defines { "DEBUG" } + flags { "Symbols", "ExtraWarnings"} + + configuration "Release" + defines { "NDEBUG" } + flags { "Optimize", "ExtraWarnings"} diff --git a/src/nanosvg.h b/src/nanosvg.h new file mode 100644 index 000000000..3511664aa --- /dev/null +++ b/src/nanosvg.h @@ -0,0 +1,3021 @@ +/* + * Copyright (c) 2013-14 Mikko Mononen memon@inside.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + * The SVG parser is based on Anti-Grain Geometry 2.4 SVG example + * Copyright (C) 2002-2004 Maxim Shemanarev (McSeem) (http://www.antigrain.com/) + * + * Arc calculation code based on canvg (https://code.google.com/p/canvg/) + * + * Bounding box calculation based on http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html + * + */ + +#ifndef NANOSVG_H +#define NANOSVG_H + +#ifndef NANOSVG_CPLUSPLUS +#ifdef __cplusplus +extern "C" { +#endif +#endif + +// NanoSVG is a simple stupid single-header-file SVG parse. The output of the parser is a list of cubic bezier shapes. +// +// The library suits well for anything from rendering scalable icons in your editor application to prototyping a game. +// +// NanoSVG supports a wide range of SVG features, but something may be missing, feel free to create a pull request! +// +// 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. +// +// NanoSVG 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 NanoSVG should be one of: 'px', 'pt', 'pc' 'mm', 'cm', or '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: + // Load SVG + NSVGimage* image; + image = nsvgParseFromFile("test.svg", "px", 96); + printf("size: %f x %f\n", image->width, image->height); + // Use... + for (NSVGshape *shape = image->shapes; shape != NULL; shape = shape->next) { + for (NSVGpath *path = shape->paths; path != NULL; path = path->next) { + for (int i = 0; i < path->npts-1; i += 3) { + float* p = &path->pts[i*2]; + drawCubicBez(p[0],p[1], p[2],p[3], p[4],p[5], p[6],p[7]); + } + } + } + // Delete + nsvgDelete(image); +*/ + +enum NSVGpaintType { + NSVG_PAINT_NONE = 0, + NSVG_PAINT_COLOR = 1, + NSVG_PAINT_LINEAR_GRADIENT = 2, + NSVG_PAINT_RADIAL_GRADIENT = 3 +}; + +enum NSVGspreadType { + NSVG_SPREAD_PAD = 0, + NSVG_SPREAD_REFLECT = 1, + NSVG_SPREAD_REPEAT = 2 +}; + +enum NSVGlineJoin { + NSVG_JOIN_MITER = 0, + NSVG_JOIN_ROUND = 1, + NSVG_JOIN_BEVEL = 2 +}; + +enum NSVGlineCap { + NSVG_CAP_BUTT = 0, + NSVG_CAP_ROUND = 1, + NSVG_CAP_SQUARE = 2 +}; + +enum NSVGfillRule { + NSVG_FILLRULE_NONZERO = 0, + NSVG_FILLRULE_EVENODD = 1 +}; + +enum NSVGflags { + NSVG_FLAGS_VISIBLE = 0x01 +}; + +typedef struct NSVGgradientStop { + unsigned int color; + float offset; +} NSVGgradientStop; + +typedef struct NSVGgradient { + float xform[6]; + char spread; + float fx, fy; + int nstops; + NSVGgradientStop stops[1]; +} NSVGgradient; + +typedef struct NSVGpaint { + char type; + union { + unsigned int color; + NSVGgradient* gradient; + }; +} NSVGpaint; + +typedef struct NSVGpath +{ + float* pts; // Cubic bezier points: x0,y0, [cpx1,cpx1,cpx2,cpy2,x1,y1], ... + int npts; // Total number of bezier points. + char closed; // Flag indicating if shapes should be treated as closed. + float bounds[4]; // Tight bounding box of the shape [minx,miny,maxx,maxy]. + struct NSVGpath* next; // Pointer to next path, or NULL if last element. +} NSVGpath; + +typedef struct NSVGshape +{ + char id[64]; // Optional 'id' attr of the shape or its group + NSVGpaint fill; // Fill paint + NSVGpaint stroke; // Stroke paint + float opacity; // Opacity of the shape. + float strokeWidth; // Stroke width (scaled). + float strokeDashOffset; // Stroke dash offset (scaled). + float strokeDashArray[8]; // Stroke dash array (scaled). + char strokeDashCount; // Number of dash values in dash array. + char strokeLineJoin; // Stroke join type. + char strokeLineCap; // Stroke cap type. + float miterLimit; // Miter limit + char fillRule; // Fill rule, see NSVGfillRule. + unsigned char flags; // Logical or of NSVG_FLAGS_* flags + float bounds[4]; // Tight bounding box of the shape [minx,miny,maxx,maxy]. + NSVGpath* paths; // Linked list of paths in the image. + struct NSVGshape* next; // Pointer to next shape, or NULL if last element. +} NSVGshape; + +typedef struct NSVGimage +{ + float width; // Width of the image. + float height; // Height of the image. + NSVGshape* shapes; // Linked list of shapes in the image. +} NSVGimage; + +// Parses SVG file from a file, returns SVG image as paths. +NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi); + +// Parses SVG file from a null terminated string, returns SVG image as paths. +// Important note: changes the string. +NSVGimage* nsvgParse(char* input, const char* units, float dpi); + +// Duplicates a path. +NSVGpath* nsvgDuplicatePath(NSVGpath* p); + +// Deletes an image. +void nsvgDelete(NSVGimage* image); + +#ifndef NANOSVG_CPLUSPLUS +#ifdef __cplusplus +} +#endif +#endif + +#endif // NANOSVG_H + +#ifdef NANOSVG_IMPLEMENTATION + +#include +#include +#include + +#define NSVG_PI (3.14159265358979323846264338327f) +#define NSVG_KAPPA90 (0.5522847493f) // Length proportional to radius of a cubic bezier handle for 90deg arcs. + +#define NSVG_ALIGN_MIN 0 +#define NSVG_ALIGN_MID 1 +#define NSVG_ALIGN_MAX 2 +#define NSVG_ALIGN_NONE 0 +#define NSVG_ALIGN_MEET 1 +#define NSVG_ALIGN_SLICE 2 + +#define NSVG_NOTUSED(v) do { (void)(1 ? (void)0 : ( (void)(v) ) ); } while(0) +#define NSVG_RGB(r, g, b) (((unsigned int)r) | ((unsigned int)g << 8) | ((unsigned int)b << 16)) + +#ifdef _MSC_VER + #pragma warning (disable: 4996) // Switch off security warnings + #pragma warning (disable: 4100) // Switch off unreferenced formal parameter warnings + #ifdef __cplusplus + #define NSVG_INLINE inline + #else + #define NSVG_INLINE + #endif +#else + #define NSVG_INLINE inline +#endif + + +static int nsvg__isspace(char c) +{ + return strchr(" \t\n\v\f\r", c) != 0; +} + +static int nsvg__isdigit(char c) +{ + return c >= '0' && c <= '9'; +} + +static NSVG_INLINE float nsvg__minf(float a, float b) { return a < b ? a : b; } +static NSVG_INLINE float nsvg__maxf(float a, float b) { return a > b ? a : b; } + + +// Simple XML parser + +#define NSVG_XML_TAG 1 +#define NSVG_XML_CONTENT 2 +#define NSVG_XML_MAX_ATTRIBS 256 + +static void nsvg__parseContent(char* s, + void (*contentCb)(void* ud, const char* s), + void* ud) +{ + // Trim start white spaces + while (*s && nsvg__isspace(*s)) s++; + if (!*s) return; + + if (contentCb) + (*contentCb)(ud, s); +} + +static void nsvg__parseElement(char* s, + void (*startelCb)(void* ud, const char* el, const char** attr), + void (*endelCb)(void* ud, const char* el), + void* ud) +{ + const char* attr[NSVG_XML_MAX_ATTRIBS]; + int nattr = 0; + char* name; + int start = 0; + int end = 0; + char quote; + + // Skip white space after the '<' + while (*s && nsvg__isspace(*s)) s++; + + // Check if the tag is end tag + if (*s == '/') { + s++; + end = 1; + } else { + start = 1; + } + + // Skip comments, data and preprocessor stuff. + if (!*s || *s == '?' || *s == '!') + return; + + // Get tag name + name = s; + while (*s && !nsvg__isspace(*s)) s++; + if (*s) { *s++ = '\0'; } + + // Get attribs + while (!end && *s && nattr < NSVG_XML_MAX_ATTRIBS-3) { + char* name = NULL; + char* value = NULL; + + // Skip white space before the attrib name + while (*s && nsvg__isspace(*s)) s++; + if (!*s) break; + if (*s == '/') { + end = 1; + break; + } + name = s; + // Find end of the attrib name. + while (*s && !nsvg__isspace(*s) && *s != '=') s++; + if (*s) { *s++ = '\0'; } + // Skip until the beginning of the value. + while (*s && *s != '\"' && *s != '\'') s++; + if (!*s) break; + quote = *s; + s++; + // Store value and find the end of it. + value = s; + while (*s && *s != quote) s++; + if (*s) { *s++ = '\0'; } + + // Store only well formed attributes + if (name && value) { + attr[nattr++] = name; + attr[nattr++] = value; + } + } + + // List terminator + attr[nattr++] = 0; + attr[nattr++] = 0; + + // Call callbacks. + if (start && startelCb) + (*startelCb)(ud, name, attr); + if (end && endelCb) + (*endelCb)(ud, name); +} + +int nsvg__parseXML(char* input, + void (*startelCb)(void* ud, const char* el, const char** attr), + void (*endelCb)(void* ud, const char* el), + void (*contentCb)(void* ud, const char* s), + void* ud) +{ + char* s = input; + char* mark = s; + int state = NSVG_XML_CONTENT; + while (*s) { + if (*s == '<' && state == NSVG_XML_CONTENT) { + // Start of a tag + *s++ = '\0'; + nsvg__parseContent(mark, contentCb, ud); + mark = s; + state = NSVG_XML_TAG; + } else if (*s == '>' && state == NSVG_XML_TAG) { + // Start of a content or new tag. + *s++ = '\0'; + nsvg__parseElement(mark, startelCb, endelCb, ud); + mark = s; + state = NSVG_XML_CONTENT; + } else { + s++; + } + } + + return 1; +} + + +/* Simple SVG parser. */ + +#define NSVG_MAX_ATTR 128 + +enum NSVGgradientUnits { + NSVG_USER_SPACE = 0, + NSVG_OBJECT_SPACE = 1 +}; + +#define NSVG_MAX_DASHES 8 + +enum NSVGunits { + NSVG_UNITS_USER, + NSVG_UNITS_PX, + NSVG_UNITS_PT, + NSVG_UNITS_PC, + NSVG_UNITS_MM, + NSVG_UNITS_CM, + NSVG_UNITS_IN, + NSVG_UNITS_PERCENT, + NSVG_UNITS_EM, + NSVG_UNITS_EX +}; + +typedef struct NSVGcoordinate { + float value; + int units; +} NSVGcoordinate; + +typedef struct NSVGlinearData { + NSVGcoordinate x1, y1, x2, y2; +} NSVGlinearData; + +typedef struct NSVGradialData { + NSVGcoordinate cx, cy, r, fx, fy; +} NSVGradialData; + +typedef struct NSVGgradientData +{ + char id[64]; + char ref[64]; + char type; + union { + NSVGlinearData linear; + NSVGradialData radial; + }; + char spread; + char units; + float xform[6]; + int nstops; + NSVGgradientStop* stops; + struct NSVGgradientData* next; +} NSVGgradientData; + +typedef struct NSVGattrib +{ + char id[64]; + float xform[6]; + unsigned int fillColor; + unsigned int strokeColor; + float opacity; + float fillOpacity; + float strokeOpacity; + char fillGradient[64]; + char strokeGradient[64]; + float strokeWidth; + float strokeDashOffset; + float strokeDashArray[NSVG_MAX_DASHES]; + int strokeDashCount; + char strokeLineJoin; + char strokeLineCap; + float miterLimit; + char fillRule; + float fontSize; + unsigned int stopColor; + float stopOpacity; + float stopOffset; + char hasFill; + char hasStroke; + char visible; +} NSVGattrib; + +typedef struct NSVGparser +{ + NSVGattrib attr[NSVG_MAX_ATTR]; + int attrHead; + float* pts; + int npts; + int cpts; + NSVGpath* plist; + NSVGimage* image; + NSVGgradientData* gradients; + NSVGshape* shapesTail; + float viewMinx, viewMiny, viewWidth, viewHeight; + int alignX, alignY, alignType; + float dpi; + char pathFlag; + char defsFlag; +} NSVGparser; + +static void nsvg__xformIdentity(float* t) +{ + t[0] = 1.0f; t[1] = 0.0f; + t[2] = 0.0f; t[3] = 1.0f; + t[4] = 0.0f; t[5] = 0.0f; +} + +static void nsvg__xformSetTranslation(float* t, float tx, float ty) +{ + t[0] = 1.0f; t[1] = 0.0f; + t[2] = 0.0f; t[3] = 1.0f; + t[4] = tx; t[5] = ty; +} + +static void nsvg__xformSetScale(float* t, float sx, float sy) +{ + t[0] = sx; t[1] = 0.0f; + t[2] = 0.0f; t[3] = sy; + t[4] = 0.0f; t[5] = 0.0f; +} + +static void nsvg__xformSetSkewX(float* t, float a) +{ + t[0] = 1.0f; t[1] = 0.0f; + t[2] = tanf(a); t[3] = 1.0f; + t[4] = 0.0f; t[5] = 0.0f; +} + +static void nsvg__xformSetSkewY(float* t, float a) +{ + t[0] = 1.0f; t[1] = tanf(a); + t[2] = 0.0f; t[3] = 1.0f; + t[4] = 0.0f; t[5] = 0.0f; +} + +static void nsvg__xformSetRotation(float* t, float a) +{ + float cs = cosf(a), sn = sinf(a); + t[0] = cs; t[1] = sn; + t[2] = -sn; t[3] = cs; + t[4] = 0.0f; t[5] = 0.0f; +} + +static void nsvg__xformMultiply(float* t, float* s) +{ + float t0 = t[0] * s[0] + t[1] * s[2]; + float t2 = t[2] * s[0] + t[3] * s[2]; + float t4 = t[4] * s[0] + t[5] * s[2] + s[4]; + t[1] = t[0] * s[1] + t[1] * s[3]; + t[3] = t[2] * s[1] + t[3] * s[3]; + t[5] = t[4] * s[1] + t[5] * s[3] + s[5]; + t[0] = t0; + t[2] = t2; + t[4] = t4; +} + +static void nsvg__xformInverse(float* inv, float* t) +{ + double invdet, det = (double)t[0] * t[3] - (double)t[2] * t[1]; + if (det > -1e-6 && det < 1e-6) { + nsvg__xformIdentity(t); + return; + } + invdet = 1.0 / det; + inv[0] = (float)(t[3] * invdet); + inv[2] = (float)(-t[2] * invdet); + inv[4] = (float)(((double)t[2] * t[5] - (double)t[3] * t[4]) * invdet); + inv[1] = (float)(-t[1] * invdet); + inv[3] = (float)(t[0] * invdet); + inv[5] = (float)(((double)t[1] * t[4] - (double)t[0] * t[5]) * invdet); +} + +static void nsvg__xformPremultiply(float* t, float* s) +{ + float s2[6]; + memcpy(s2, s, sizeof(float)*6); + nsvg__xformMultiply(s2, t); + memcpy(t, s2, sizeof(float)*6); +} + +static void nsvg__xformPoint(float* dx, float* dy, float x, float y, float* t) +{ + *dx = x*t[0] + y*t[2] + t[4]; + *dy = x*t[1] + y*t[3] + t[5]; +} + +static void nsvg__xformVec(float* dx, float* dy, float x, float y, float* t) +{ + *dx = x*t[0] + y*t[2]; + *dy = x*t[1] + y*t[3]; +} + +#define NSVG_EPSILON (1e-12) + +static int nsvg__ptInBounds(float* pt, float* bounds) +{ + return pt[0] >= bounds[0] && pt[0] <= bounds[2] && pt[1] >= bounds[1] && pt[1] <= bounds[3]; +} + + +static double nsvg__evalBezier(double t, double p0, double p1, double p2, double p3) +{ + double it = 1.0-t; + return it*it*it*p0 + 3.0*it*it*t*p1 + 3.0*it*t*t*p2 + t*t*t*p3; +} + +static void nsvg__curveBounds(float* bounds, float* curve) +{ + int i, j, count; + double roots[2], a, b, c, b2ac, t, v; + float* v0 = &curve[0]; + float* v1 = &curve[2]; + float* v2 = &curve[4]; + float* v3 = &curve[6]; + + // Start the bounding box by end points + bounds[0] = nsvg__minf(v0[0], v3[0]); + bounds[1] = nsvg__minf(v0[1], v3[1]); + bounds[2] = nsvg__maxf(v0[0], v3[0]); + bounds[3] = nsvg__maxf(v0[1], v3[1]); + + // Bezier curve fits inside the convex hull of it's control points. + // If control points are inside the bounds, we're done. + if (nsvg__ptInBounds(v1, bounds) && nsvg__ptInBounds(v2, bounds)) + return; + + // Add bezier curve inflection points in X and Y. + for (i = 0; i < 2; i++) { + a = -3.0 * v0[i] + 9.0 * v1[i] - 9.0 * v2[i] + 3.0 * v3[i]; + b = 6.0 * v0[i] - 12.0 * v1[i] + 6.0 * v2[i]; + c = 3.0 * v1[i] - 3.0 * v0[i]; + count = 0; + if (fabs(a) < NSVG_EPSILON) { + if (fabs(b) > NSVG_EPSILON) { + t = -c / b; + if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON) + roots[count++] = t; + } + } else { + b2ac = b*b - 4.0*c*a; + if (b2ac > NSVG_EPSILON) { + t = (-b + sqrt(b2ac)) / (2.0 * a); + if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON) + roots[count++] = t; + t = (-b - sqrt(b2ac)) / (2.0 * a); + if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON) + roots[count++] = t; + } + } + for (j = 0; j < count; j++) { + v = nsvg__evalBezier(roots[j], v0[i], v1[i], v2[i], v3[i]); + bounds[0+i] = nsvg__minf(bounds[0+i], (float)v); + bounds[2+i] = nsvg__maxf(bounds[2+i], (float)v); + } + } +} + +static NSVGparser* nsvg__createParser() +{ + NSVGparser* p; + p = (NSVGparser*)malloc(sizeof(NSVGparser)); + if (p == NULL) goto error; + memset(p, 0, sizeof(NSVGparser)); + + p->image = (NSVGimage*)malloc(sizeof(NSVGimage)); + if (p->image == NULL) goto error; + memset(p->image, 0, sizeof(NSVGimage)); + + // Init style + nsvg__xformIdentity(p->attr[0].xform); + memset(p->attr[0].id, 0, sizeof p->attr[0].id); + p->attr[0].fillColor = NSVG_RGB(0,0,0); + p->attr[0].strokeColor = NSVG_RGB(0,0,0); + p->attr[0].opacity = 1; + p->attr[0].fillOpacity = 1; + p->attr[0].strokeOpacity = 1; + p->attr[0].stopOpacity = 1; + p->attr[0].strokeWidth = 1; + p->attr[0].strokeLineJoin = NSVG_JOIN_MITER; + p->attr[0].strokeLineCap = NSVG_CAP_BUTT; + p->attr[0].miterLimit = 4; + p->attr[0].fillRule = NSVG_FILLRULE_NONZERO; + p->attr[0].hasFill = 1; + p->attr[0].visible = 1; + + return p; + +error: + if (p) { + if (p->image) free(p->image); + free(p); + } + return NULL; +} + +static void nsvg__deletePaths(NSVGpath* path) +{ + while (path) { + NSVGpath *next = path->next; + if (path->pts != NULL) + free(path->pts); + free(path); + path = next; + } +} + +static void nsvg__deletePaint(NSVGpaint* paint) +{ + if (paint->type == NSVG_PAINT_LINEAR_GRADIENT || paint->type == NSVG_PAINT_RADIAL_GRADIENT) + free(paint->gradient); +} + +static void nsvg__deleteGradientData(NSVGgradientData* grad) +{ + NSVGgradientData* next; + while (grad != NULL) { + next = grad->next; + free(grad->stops); + free(grad); + grad = next; + } +} + +static void nsvg__deleteParser(NSVGparser* p) +{ + if (p != NULL) { + nsvg__deletePaths(p->plist); + nsvg__deleteGradientData(p->gradients); + nsvgDelete(p->image); + free(p->pts); + free(p); + } +} + +static void nsvg__resetPath(NSVGparser* p) +{ + p->npts = 0; +} + +static void nsvg__addPoint(NSVGparser* p, float x, float y) +{ + if (p->npts+1 > p->cpts) { + p->cpts = p->cpts ? p->cpts*2 : 8; + p->pts = (float*)realloc(p->pts, p->cpts*2*sizeof(float)); + if (!p->pts) return; + } + p->pts[p->npts*2+0] = x; + p->pts[p->npts*2+1] = y; + p->npts++; +} + +static void nsvg__moveTo(NSVGparser* p, float x, float y) +{ + if (p->npts > 0) { + p->pts[(p->npts-1)*2+0] = x; + p->pts[(p->npts-1)*2+1] = y; + } else { + nsvg__addPoint(p, x, y); + } +} + +static void nsvg__lineTo(NSVGparser* p, float x, float y) +{ + float px,py, dx,dy; + if (p->npts > 0) { + px = p->pts[(p->npts-1)*2+0]; + py = p->pts[(p->npts-1)*2+1]; + dx = x - px; + dy = y - py; + nsvg__addPoint(p, px + dx/3.0f, py + dy/3.0f); + nsvg__addPoint(p, x - dx/3.0f, y - dy/3.0f); + nsvg__addPoint(p, x, y); + } +} + +static void nsvg__cubicBezTo(NSVGparser* p, float cpx1, float cpy1, float cpx2, float cpy2, float x, float y) +{ + if (p->npts > 0) { + nsvg__addPoint(p, cpx1, cpy1); + nsvg__addPoint(p, cpx2, cpy2); + nsvg__addPoint(p, x, y); + } +} + +static NSVGattrib* nsvg__getAttr(NSVGparser* p) +{ + return &p->attr[p->attrHead]; +} + +static void nsvg__pushAttr(NSVGparser* p) +{ + if (p->attrHead < NSVG_MAX_ATTR-1) { + p->attrHead++; + memcpy(&p->attr[p->attrHead], &p->attr[p->attrHead-1], sizeof(NSVGattrib)); + } +} + +static void nsvg__popAttr(NSVGparser* p) +{ + if (p->attrHead > 0) + p->attrHead--; +} + +static float nsvg__actualOrigX(NSVGparser* p) +{ + return p->viewMinx; +} + +static float nsvg__actualOrigY(NSVGparser* p) +{ + return p->viewMiny; +} + +static float nsvg__actualWidth(NSVGparser* p) +{ + return p->viewWidth; +} + +static float nsvg__actualHeight(NSVGparser* p) +{ + return p->viewHeight; +} + +static float nsvg__actualLength(NSVGparser* p) +{ + float w = nsvg__actualWidth(p), h = nsvg__actualHeight(p); + return sqrtf(w*w + h*h) / sqrtf(2.0f); +} + +static float nsvg__convertToPixels(NSVGparser* p, NSVGcoordinate c, float orig, float length) +{ + NSVGattrib* attr = nsvg__getAttr(p); + switch (c.units) { + case NSVG_UNITS_USER: return c.value; + case NSVG_UNITS_PX: return c.value; + case NSVG_UNITS_PT: return c.value / 72.0f * p->dpi; + case NSVG_UNITS_PC: return c.value / 6.0f * p->dpi; + case NSVG_UNITS_MM: return c.value / 25.4f * p->dpi; + case NSVG_UNITS_CM: return c.value / 2.54f * p->dpi; + case NSVG_UNITS_IN: return c.value * p->dpi; + case NSVG_UNITS_EM: return c.value * attr->fontSize; + case NSVG_UNITS_EX: return c.value * attr->fontSize * 0.52f; // x-height of Helvetica. + case NSVG_UNITS_PERCENT: return orig + c.value / 100.0f * length; + default: return c.value; + } + return c.value; +} + +static NSVGgradientData* nsvg__findGradientData(NSVGparser* p, const char* id) +{ + NSVGgradientData* grad = p->gradients; + if (id == NULL || *id == '\0') + return NULL; + while (grad != NULL) { + if (strcmp(grad->id, id) == 0) + return grad; + grad = grad->next; + } + return NULL; +} + +static NSVGgradient* nsvg__createGradient(NSVGparser* p, const char* id, const float* localBounds, char* paintType) +{ + NSVGattrib* attr = nsvg__getAttr(p); + NSVGgradientData* data = NULL; + NSVGgradientData* ref = NULL; + NSVGgradientStop* stops = NULL; + NSVGgradient* grad; + float ox, oy, sw, sh, sl; + int nstops = 0; + int refIter; + + data = nsvg__findGradientData(p, id); + if (data == NULL) return NULL; + + // TODO: use ref to fill in all unset values too. + ref = data; + refIter = 0; + while (ref != NULL) { + NSVGgradientData* nextRef = NULL; + if (stops == NULL && ref->stops != NULL) { + stops = ref->stops; + nstops = ref->nstops; + break; + } + nextRef = nsvg__findGradientData(p, ref->ref); + if (nextRef == ref) break; // prevent infite loops on malformed data + ref = nextRef; + refIter++; + if (refIter > 32) break; // prevent infite loops on malformed data + } + if (stops == NULL) return NULL; + + grad = (NSVGgradient*)malloc(sizeof(NSVGgradient) + sizeof(NSVGgradientStop)*(nstops-1)); + if (grad == NULL) return NULL; + + // The shape width and height. + if (data->units == NSVG_OBJECT_SPACE) { + ox = localBounds[0]; + oy = localBounds[1]; + sw = localBounds[2] - localBounds[0]; + sh = localBounds[3] - localBounds[1]; + } else { + ox = nsvg__actualOrigX(p); + oy = nsvg__actualOrigY(p); + sw = nsvg__actualWidth(p); + sh = nsvg__actualHeight(p); + } + sl = sqrtf(sw*sw + sh*sh) / sqrtf(2.0f); + + if (data->type == NSVG_PAINT_LINEAR_GRADIENT) { + float x1, y1, x2, y2, dx, dy; + x1 = nsvg__convertToPixels(p, data->linear.x1, ox, sw); + y1 = nsvg__convertToPixels(p, data->linear.y1, oy, sh); + x2 = nsvg__convertToPixels(p, data->linear.x2, ox, sw); + y2 = nsvg__convertToPixels(p, data->linear.y2, oy, sh); + // Calculate transform aligned to the line + dx = x2 - x1; + dy = y2 - y1; + grad->xform[0] = dy; grad->xform[1] = -dx; + grad->xform[2] = dx; grad->xform[3] = dy; + grad->xform[4] = x1; grad->xform[5] = y1; + } else { + float cx, cy, fx, fy, r; + cx = nsvg__convertToPixels(p, data->radial.cx, ox, sw); + cy = nsvg__convertToPixels(p, data->radial.cy, oy, sh); + fx = nsvg__convertToPixels(p, data->radial.fx, ox, sw); + fy = nsvg__convertToPixels(p, data->radial.fy, oy, sh); + r = nsvg__convertToPixels(p, data->radial.r, 0, sl); + // Calculate transform aligned to the circle + grad->xform[0] = r; grad->xform[1] = 0; + grad->xform[2] = 0; grad->xform[3] = r; + grad->xform[4] = cx; grad->xform[5] = cy; + grad->fx = fx / r; + grad->fy = fy / r; + } + + nsvg__xformMultiply(grad->xform, data->xform); + nsvg__xformMultiply(grad->xform, attr->xform); + + grad->spread = data->spread; + memcpy(grad->stops, stops, nstops*sizeof(NSVGgradientStop)); + grad->nstops = nstops; + + *paintType = data->type; + + return grad; +} + +static float nsvg__getAverageScale(float* t) +{ + float sx = sqrtf(t[0]*t[0] + t[2]*t[2]); + float sy = sqrtf(t[1]*t[1] + t[3]*t[3]); + return (sx + sy) * 0.5f; +} + +static void nsvg__getLocalBounds(float* bounds, NSVGshape *shape, float* xform) +{ + NSVGpath* path; + float curve[4*2], curveBounds[4]; + int i, first = 1; + for (path = shape->paths; path != NULL; path = path->next) { + nsvg__xformPoint(&curve[0], &curve[1], path->pts[0], path->pts[1], xform); + for (i = 0; i < path->npts-1; i += 3) { + nsvg__xformPoint(&curve[2], &curve[3], path->pts[(i+1)*2], path->pts[(i+1)*2+1], xform); + nsvg__xformPoint(&curve[4], &curve[5], path->pts[(i+2)*2], path->pts[(i+2)*2+1], xform); + nsvg__xformPoint(&curve[6], &curve[7], path->pts[(i+3)*2], path->pts[(i+3)*2+1], xform); + nsvg__curveBounds(curveBounds, curve); + if (first) { + bounds[0] = curveBounds[0]; + bounds[1] = curveBounds[1]; + bounds[2] = curveBounds[2]; + bounds[3] = curveBounds[3]; + first = 0; + } else { + bounds[0] = nsvg__minf(bounds[0], curveBounds[0]); + bounds[1] = nsvg__minf(bounds[1], curveBounds[1]); + bounds[2] = nsvg__maxf(bounds[2], curveBounds[2]); + bounds[3] = nsvg__maxf(bounds[3], curveBounds[3]); + } + curve[0] = curve[6]; + curve[1] = curve[7]; + } + } +} + +static void nsvg__addShape(NSVGparser* p) +{ + NSVGattrib* attr = nsvg__getAttr(p); + float scale = 1.0f; + NSVGshape* shape; + NSVGpath* path; + int i; + + if (p->plist == NULL) + return; + + shape = (NSVGshape*)malloc(sizeof(NSVGshape)); + if (shape == NULL) goto error; + memset(shape, 0, sizeof(NSVGshape)); + + memcpy(shape->id, attr->id, sizeof shape->id); + scale = nsvg__getAverageScale(attr->xform); + shape->strokeWidth = attr->strokeWidth * scale; + shape->strokeDashOffset = attr->strokeDashOffset * scale; + shape->strokeDashCount = (char)attr->strokeDashCount; + for (i = 0; i < attr->strokeDashCount; i++) + shape->strokeDashArray[i] = attr->strokeDashArray[i] * scale; + shape->strokeLineJoin = attr->strokeLineJoin; + shape->strokeLineCap = attr->strokeLineCap; + shape->miterLimit = attr->miterLimit; + shape->fillRule = attr->fillRule; + shape->opacity = attr->opacity; + + shape->paths = p->plist; + p->plist = NULL; + + // Calculate shape bounds + shape->bounds[0] = shape->paths->bounds[0]; + shape->bounds[1] = shape->paths->bounds[1]; + shape->bounds[2] = shape->paths->bounds[2]; + shape->bounds[3] = shape->paths->bounds[3]; + for (path = shape->paths->next; path != NULL; path = path->next) { + shape->bounds[0] = nsvg__minf(shape->bounds[0], path->bounds[0]); + shape->bounds[1] = nsvg__minf(shape->bounds[1], path->bounds[1]); + shape->bounds[2] = nsvg__maxf(shape->bounds[2], path->bounds[2]); + shape->bounds[3] = nsvg__maxf(shape->bounds[3], path->bounds[3]); + } + + // Set fill + if (attr->hasFill == 0) { + shape->fill.type = NSVG_PAINT_NONE; + } else if (attr->hasFill == 1) { + shape->fill.type = NSVG_PAINT_COLOR; + shape->fill.color = attr->fillColor; + shape->fill.color |= (unsigned int)(attr->fillOpacity*255) << 24; + } else if (attr->hasFill == 2) { + float inv[6], localBounds[4]; + nsvg__xformInverse(inv, attr->xform); + nsvg__getLocalBounds(localBounds, shape, inv); + shape->fill.gradient = nsvg__createGradient(p, attr->fillGradient, localBounds, &shape->fill.type); + if (shape->fill.gradient == NULL) { + shape->fill.type = NSVG_PAINT_NONE; + } + } + + // Set stroke + if (attr->hasStroke == 0) { + shape->stroke.type = NSVG_PAINT_NONE; + } else if (attr->hasStroke == 1) { + shape->stroke.type = NSVG_PAINT_COLOR; + shape->stroke.color = attr->strokeColor; + shape->stroke.color |= (unsigned int)(attr->strokeOpacity*255) << 24; + } else if (attr->hasStroke == 2) { + float inv[6], localBounds[4]; + nsvg__xformInverse(inv, attr->xform); + nsvg__getLocalBounds(localBounds, shape, inv); + shape->stroke.gradient = nsvg__createGradient(p, attr->strokeGradient, localBounds, &shape->stroke.type); + if (shape->stroke.gradient == NULL) + shape->stroke.type = NSVG_PAINT_NONE; + } + + // Set flags + shape->flags = (attr->visible ? NSVG_FLAGS_VISIBLE : 0x00); + + // Add to tail + if (p->image->shapes == NULL) + p->image->shapes = shape; + else + p->shapesTail->next = shape; + p->shapesTail = shape; + + return; + +error: + if (shape) free(shape); +} + +static void nsvg__addPath(NSVGparser* p, char closed) +{ + NSVGattrib* attr = nsvg__getAttr(p); + NSVGpath* path = NULL; + float bounds[4]; + float* curve; + int i; + + if (p->npts < 4) + return; + + if (closed) + nsvg__lineTo(p, p->pts[0], p->pts[1]); + + // Expect 1 + N*3 points (N = number of cubic bezier segments). + if ((p->npts % 3) != 1) + return; + + path = (NSVGpath*)malloc(sizeof(NSVGpath)); + if (path == NULL) goto error; + memset(path, 0, sizeof(NSVGpath)); + + path->pts = (float*)malloc(p->npts*2*sizeof(float)); + if (path->pts == NULL) goto error; + path->closed = closed; + path->npts = p->npts; + + // Transform path. + for (i = 0; i < p->npts; ++i) + nsvg__xformPoint(&path->pts[i*2], &path->pts[i*2+1], p->pts[i*2], p->pts[i*2+1], attr->xform); + + // Find bounds + for (i = 0; i < path->npts-1; i += 3) { + curve = &path->pts[i*2]; + nsvg__curveBounds(bounds, curve); + if (i == 0) { + path->bounds[0] = bounds[0]; + path->bounds[1] = bounds[1]; + path->bounds[2] = bounds[2]; + path->bounds[3] = bounds[3]; + } else { + path->bounds[0] = nsvg__minf(path->bounds[0], bounds[0]); + path->bounds[1] = nsvg__minf(path->bounds[1], bounds[1]); + path->bounds[2] = nsvg__maxf(path->bounds[2], bounds[2]); + path->bounds[3] = nsvg__maxf(path->bounds[3], bounds[3]); + } + } + + path->next = p->plist; + p->plist = path; + + return; + +error: + if (path != NULL) { + if (path->pts != NULL) free(path->pts); + free(path); + } +} + +// We roll our own string to float because the std library one uses locale and messes things up. +static double nsvg__atof(const char* s) +{ + char* cur = (char*)s; + char* end = NULL; + double res = 0.0, sign = 1.0; + long long intPart = 0, fracPart = 0; + char hasIntPart = 0, hasFracPart = 0; + + // Parse optional sign + if (*cur == '+') { + cur++; + } else if (*cur == '-') { + sign = -1; + cur++; + } + + // Parse integer part + if (nsvg__isdigit(*cur)) { + // Parse digit sequence + intPart = strtoll(cur, &end, 10); + if (cur != end) { + res = (double)intPart; + hasIntPart = 1; + cur = end; + } + } + + // Parse fractional part. + if (*cur == '.') { + cur++; // Skip '.' + if (nsvg__isdigit(*cur)) { + // Parse digit sequence + fracPart = strtoll(cur, &end, 10); + if (cur != end) { + res += (double)fracPart / pow(10.0, (double)(end - cur)); + hasFracPart = 1; + cur = end; + } + } + } + + // A valid number should have integer or fractional part. + if (!hasIntPart && !hasFracPart) + return 0.0; + + // Parse optional exponent + if (*cur == 'e' || *cur == 'E') { + long expPart = 0; + cur++; // skip 'E' + expPart = strtol(cur, &end, 10); // Parse digit sequence with sign + if (cur != end) { + res *= pow(10.0, (double)expPart); + } + } + + return res * sign; +} + + +static const char* nsvg__parseNumber(const char* s, char* it, const int size) +{ + const int last = size-1; + int i = 0; + + // sign + if (*s == '-' || *s == '+') { + if (i < last) it[i++] = *s; + s++; + } + // integer part + while (*s && nsvg__isdigit(*s)) { + if (i < last) it[i++] = *s; + s++; + } + if (*s == '.') { + // decimal point + if (i < last) it[i++] = *s; + s++; + // fraction part + while (*s && nsvg__isdigit(*s)) { + if (i < last) it[i++] = *s; + s++; + } + } + // exponent + if ((*s == 'e' || *s == 'E') && (s[1] != 'm' && s[1] != 'x')) { + if (i < last) it[i++] = *s; + s++; + if (*s == '-' || *s == '+') { + if (i < last) it[i++] = *s; + s++; + } + while (*s && nsvg__isdigit(*s)) { + if (i < last) it[i++] = *s; + s++; + } + } + it[i] = '\0'; + + return s; +} + +static const char* nsvg__getNextPathItem(const char* s, char* it) +{ + it[0] = '\0'; + // Skip white spaces and commas + while (*s && (nsvg__isspace(*s) || *s == ',')) s++; + if (!*s) return s; + if (*s == '-' || *s == '+' || *s == '.' || nsvg__isdigit(*s)) { + s = nsvg__parseNumber(s, it, 64); + } else { + // Parse command + it[0] = *s++; + it[1] = '\0'; + return s; + } + + return s; +} + +static unsigned int nsvg__parseColorHex(const char* str) +{ + unsigned int c = 0, r = 0, g = 0, b = 0; + int n = 0; + str++; // skip # + // Calculate number of characters. + while(str[n] && !nsvg__isspace(str[n])) + n++; + if (n == 6) { + sscanf(str, "%x", &c); + } else if (n == 3) { + sscanf(str, "%x", &c); + c = (c&0xf) | ((c&0xf0) << 4) | ((c&0xf00) << 8); + c |= c<<4; + } + r = (c >> 16) & 0xff; + g = (c >> 8) & 0xff; + b = c & 0xff; + return NSVG_RGB(r,g,b); +} + +static unsigned int nsvg__parseColorRGB(const char* str) +{ + int r = -1, g = -1, b = -1; + char s1[32]="", s2[32]=""; + sscanf(str + 4, "%d%[%%, \t]%d%[%%, \t]%d", &r, s1, &g, s2, &b); + if (strchr(s1, '%')) { + return NSVG_RGB((r*255)/100,(g*255)/100,(b*255)/100); + } else { + return NSVG_RGB(r,g,b); + } +} + +typedef struct NSVGNamedColor { + const char* name; + unsigned int color; +} NSVGNamedColor; + +NSVGNamedColor nsvg__colors[] = { + + { "red", NSVG_RGB(255, 0, 0) }, + { "green", NSVG_RGB( 0, 128, 0) }, + { "blue", NSVG_RGB( 0, 0, 255) }, + { "yellow", NSVG_RGB(255, 255, 0) }, + { "cyan", NSVG_RGB( 0, 255, 255) }, + { "magenta", NSVG_RGB(255, 0, 255) }, + { "black", NSVG_RGB( 0, 0, 0) }, + { "grey", NSVG_RGB(128, 128, 128) }, + { "gray", NSVG_RGB(128, 128, 128) }, + { "white", NSVG_RGB(255, 255, 255) }, + +#ifdef NANOSVG_ALL_COLOR_KEYWORDS + { "aliceblue", NSVG_RGB(240, 248, 255) }, + { "antiquewhite", NSVG_RGB(250, 235, 215) }, + { "aqua", NSVG_RGB( 0, 255, 255) }, + { "aquamarine", NSVG_RGB(127, 255, 212) }, + { "azure", NSVG_RGB(240, 255, 255) }, + { "beige", NSVG_RGB(245, 245, 220) }, + { "bisque", NSVG_RGB(255, 228, 196) }, + { "blanchedalmond", NSVG_RGB(255, 235, 205) }, + { "blueviolet", NSVG_RGB(138, 43, 226) }, + { "brown", NSVG_RGB(165, 42, 42) }, + { "burlywood", NSVG_RGB(222, 184, 135) }, + { "cadetblue", NSVG_RGB( 95, 158, 160) }, + { "chartreuse", NSVG_RGB(127, 255, 0) }, + { "chocolate", NSVG_RGB(210, 105, 30) }, + { "coral", NSVG_RGB(255, 127, 80) }, + { "cornflowerblue", NSVG_RGB(100, 149, 237) }, + { "cornsilk", NSVG_RGB(255, 248, 220) }, + { "crimson", NSVG_RGB(220, 20, 60) }, + { "darkblue", NSVG_RGB( 0, 0, 139) }, + { "darkcyan", NSVG_RGB( 0, 139, 139) }, + { "darkgoldenrod", NSVG_RGB(184, 134, 11) }, + { "darkgray", NSVG_RGB(169, 169, 169) }, + { "darkgreen", NSVG_RGB( 0, 100, 0) }, + { "darkgrey", NSVG_RGB(169, 169, 169) }, + { "darkkhaki", NSVG_RGB(189, 183, 107) }, + { "darkmagenta", NSVG_RGB(139, 0, 139) }, + { "darkolivegreen", NSVG_RGB( 85, 107, 47) }, + { "darkorange", NSVG_RGB(255, 140, 0) }, + { "darkorchid", NSVG_RGB(153, 50, 204) }, + { "darkred", NSVG_RGB(139, 0, 0) }, + { "darksalmon", NSVG_RGB(233, 150, 122) }, + { "darkseagreen", NSVG_RGB(143, 188, 143) }, + { "darkslateblue", NSVG_RGB( 72, 61, 139) }, + { "darkslategray", NSVG_RGB( 47, 79, 79) }, + { "darkslategrey", NSVG_RGB( 47, 79, 79) }, + { "darkturquoise", NSVG_RGB( 0, 206, 209) }, + { "darkviolet", NSVG_RGB(148, 0, 211) }, + { "deeppink", NSVG_RGB(255, 20, 147) }, + { "deepskyblue", NSVG_RGB( 0, 191, 255) }, + { "dimgray", NSVG_RGB(105, 105, 105) }, + { "dimgrey", NSVG_RGB(105, 105, 105) }, + { "dodgerblue", NSVG_RGB( 30, 144, 255) }, + { "firebrick", NSVG_RGB(178, 34, 34) }, + { "floralwhite", NSVG_RGB(255, 250, 240) }, + { "forestgreen", NSVG_RGB( 34, 139, 34) }, + { "fuchsia", NSVG_RGB(255, 0, 255) }, + { "gainsboro", NSVG_RGB(220, 220, 220) }, + { "ghostwhite", NSVG_RGB(248, 248, 255) }, + { "gold", NSVG_RGB(255, 215, 0) }, + { "goldenrod", NSVG_RGB(218, 165, 32) }, + { "greenyellow", NSVG_RGB(173, 255, 47) }, + { "honeydew", NSVG_RGB(240, 255, 240) }, + { "hotpink", NSVG_RGB(255, 105, 180) }, + { "indianred", NSVG_RGB(205, 92, 92) }, + { "indigo", NSVG_RGB( 75, 0, 130) }, + { "ivory", NSVG_RGB(255, 255, 240) }, + { "khaki", NSVG_RGB(240, 230, 140) }, + { "lavender", NSVG_RGB(230, 230, 250) }, + { "lavenderblush", NSVG_RGB(255, 240, 245) }, + { "lawngreen", NSVG_RGB(124, 252, 0) }, + { "lemonchiffon", NSVG_RGB(255, 250, 205) }, + { "lightblue", NSVG_RGB(173, 216, 230) }, + { "lightcoral", NSVG_RGB(240, 128, 128) }, + { "lightcyan", NSVG_RGB(224, 255, 255) }, + { "lightgoldenrodyellow", NSVG_RGB(250, 250, 210) }, + { "lightgray", NSVG_RGB(211, 211, 211) }, + { "lightgreen", NSVG_RGB(144, 238, 144) }, + { "lightgrey", NSVG_RGB(211, 211, 211) }, + { "lightpink", NSVG_RGB(255, 182, 193) }, + { "lightsalmon", NSVG_RGB(255, 160, 122) }, + { "lightseagreen", NSVG_RGB( 32, 178, 170) }, + { "lightskyblue", NSVG_RGB(135, 206, 250) }, + { "lightslategray", NSVG_RGB(119, 136, 153) }, + { "lightslategrey", NSVG_RGB(119, 136, 153) }, + { "lightsteelblue", NSVG_RGB(176, 196, 222) }, + { "lightyellow", NSVG_RGB(255, 255, 224) }, + { "lime", NSVG_RGB( 0, 255, 0) }, + { "limegreen", NSVG_RGB( 50, 205, 50) }, + { "linen", NSVG_RGB(250, 240, 230) }, + { "maroon", NSVG_RGB(128, 0, 0) }, + { "mediumaquamarine", NSVG_RGB(102, 205, 170) }, + { "mediumblue", NSVG_RGB( 0, 0, 205) }, + { "mediumorchid", NSVG_RGB(186, 85, 211) }, + { "mediumpurple", NSVG_RGB(147, 112, 219) }, + { "mediumseagreen", NSVG_RGB( 60, 179, 113) }, + { "mediumslateblue", NSVG_RGB(123, 104, 238) }, + { "mediumspringgreen", NSVG_RGB( 0, 250, 154) }, + { "mediumturquoise", NSVG_RGB( 72, 209, 204) }, + { "mediumvioletred", NSVG_RGB(199, 21, 133) }, + { "midnightblue", NSVG_RGB( 25, 25, 112) }, + { "mintcream", NSVG_RGB(245, 255, 250) }, + { "mistyrose", NSVG_RGB(255, 228, 225) }, + { "moccasin", NSVG_RGB(255, 228, 181) }, + { "navajowhite", NSVG_RGB(255, 222, 173) }, + { "navy", NSVG_RGB( 0, 0, 128) }, + { "oldlace", NSVG_RGB(253, 245, 230) }, + { "olive", NSVG_RGB(128, 128, 0) }, + { "olivedrab", NSVG_RGB(107, 142, 35) }, + { "orange", NSVG_RGB(255, 165, 0) }, + { "orangered", NSVG_RGB(255, 69, 0) }, + { "orchid", NSVG_RGB(218, 112, 214) }, + { "palegoldenrod", NSVG_RGB(238, 232, 170) }, + { "palegreen", NSVG_RGB(152, 251, 152) }, + { "paleturquoise", NSVG_RGB(175, 238, 238) }, + { "palevioletred", NSVG_RGB(219, 112, 147) }, + { "papayawhip", NSVG_RGB(255, 239, 213) }, + { "peachpuff", NSVG_RGB(255, 218, 185) }, + { "peru", NSVG_RGB(205, 133, 63) }, + { "pink", NSVG_RGB(255, 192, 203) }, + { "plum", NSVG_RGB(221, 160, 221) }, + { "powderblue", NSVG_RGB(176, 224, 230) }, + { "purple", NSVG_RGB(128, 0, 128) }, + { "rosybrown", NSVG_RGB(188, 143, 143) }, + { "royalblue", NSVG_RGB( 65, 105, 225) }, + { "saddlebrown", NSVG_RGB(139, 69, 19) }, + { "salmon", NSVG_RGB(250, 128, 114) }, + { "sandybrown", NSVG_RGB(244, 164, 96) }, + { "seagreen", NSVG_RGB( 46, 139, 87) }, + { "seashell", NSVG_RGB(255, 245, 238) }, + { "sienna", NSVG_RGB(160, 82, 45) }, + { "silver", NSVG_RGB(192, 192, 192) }, + { "skyblue", NSVG_RGB(135, 206, 235) }, + { "slateblue", NSVG_RGB(106, 90, 205) }, + { "slategray", NSVG_RGB(112, 128, 144) }, + { "slategrey", NSVG_RGB(112, 128, 144) }, + { "snow", NSVG_RGB(255, 250, 250) }, + { "springgreen", NSVG_RGB( 0, 255, 127) }, + { "steelblue", NSVG_RGB( 70, 130, 180) }, + { "tan", NSVG_RGB(210, 180, 140) }, + { "teal", NSVG_RGB( 0, 128, 128) }, + { "thistle", NSVG_RGB(216, 191, 216) }, + { "tomato", NSVG_RGB(255, 99, 71) }, + { "turquoise", NSVG_RGB( 64, 224, 208) }, + { "violet", NSVG_RGB(238, 130, 238) }, + { "wheat", NSVG_RGB(245, 222, 179) }, + { "whitesmoke", NSVG_RGB(245, 245, 245) }, + { "yellowgreen", NSVG_RGB(154, 205, 50) }, +#endif +}; + +static unsigned int nsvg__parseColorName(const char* str) +{ + int i, ncolors = sizeof(nsvg__colors) / sizeof(NSVGNamedColor); + + for (i = 0; i < ncolors; i++) { + if (strcmp(nsvg__colors[i].name, str) == 0) { + return nsvg__colors[i].color; + } + } + + return NSVG_RGB(128, 128, 128); +} + +static unsigned int nsvg__parseColor(const char* str) +{ + size_t len = 0; + while(*str == ' ') ++str; + len = strlen(str); + if (len >= 1 && *str == '#') + return nsvg__parseColorHex(str); + else if (len >= 4 && str[0] == 'r' && str[1] == 'g' && str[2] == 'b' && str[3] == '(') + return nsvg__parseColorRGB(str); + return nsvg__parseColorName(str); +} + +static float nsvg__parseOpacity(const char* str) +{ + float val = nsvg__atof(str); + if (val < 0.0f) val = 0.0f; + if (val > 1.0f) val = 1.0f; + return val; +} + +static float nsvg__parseMiterLimit(const char* str) +{ + float val = nsvg__atof(str); + if (val < 0.0f) val = 0.0f; + return val; +} + +static int nsvg__parseUnits(const char* units) +{ + if (units[0] == 'p' && units[1] == 'x') + return NSVG_UNITS_PX; + else if (units[0] == 'p' && units[1] == 't') + return NSVG_UNITS_PT; + else if (units[0] == 'p' && units[1] == 'c') + return NSVG_UNITS_PC; + else if (units[0] == 'm' && units[1] == 'm') + return NSVG_UNITS_MM; + else if (units[0] == 'c' && units[1] == 'm') + return NSVG_UNITS_CM; + else if (units[0] == 'i' && units[1] == 'n') + return NSVG_UNITS_IN; + else if (units[0] == '%') + return NSVG_UNITS_PERCENT; + else if (units[0] == 'e' && units[1] == 'm') + return NSVG_UNITS_EM; + else if (units[0] == 'e' && units[1] == 'x') + return NSVG_UNITS_EX; + return NSVG_UNITS_USER; +} + +static int nsvg__isCoordinate(const char* s) +{ + // optional sign + if (*s == '-' || *s == '+') + s++; + // must have at least one digit, or start by a dot + return (nsvg__isdigit(*s) || *s == '.'); +} + +static NSVGcoordinate nsvg__parseCoordinateRaw(const char* str) +{ + NSVGcoordinate coord = {0, NSVG_UNITS_USER}; + char buf[64]; + coord.units = nsvg__parseUnits(nsvg__parseNumber(str, buf, 64)); + coord.value = nsvg__atof(buf); + return coord; +} + +static NSVGcoordinate nsvg__coord(float v, int units) +{ + NSVGcoordinate coord = {v, units}; + return coord; +} + +static float nsvg__parseCoordinate(NSVGparser* p, const char* str, float orig, float length) +{ + NSVGcoordinate coord = nsvg__parseCoordinateRaw(str); + return nsvg__convertToPixels(p, coord, orig, length); +} + +static int nsvg__parseTransformArgs(const char* str, float* args, int maxNa, int* na) +{ + const char* end; + const char* ptr; + char it[64]; + + *na = 0; + ptr = str; + while (*ptr && *ptr != '(') ++ptr; + if (*ptr == 0) + return 1; + end = ptr; + while (*end && *end != ')') ++end; + if (*end == 0) + return 1; + + while (ptr < end) { + if (*ptr == '-' || *ptr == '+' || *ptr == '.' || nsvg__isdigit(*ptr)) { + if (*na >= maxNa) return 0; + ptr = nsvg__parseNumber(ptr, it, 64); + args[(*na)++] = (float)nsvg__atof(it); + } else { + ++ptr; + } + } + return (int)(end - str); +} + + +static int nsvg__parseMatrix(float* xform, const char* str) +{ + float t[6]; + int na = 0; + int len = nsvg__parseTransformArgs(str, t, 6, &na); + if (na != 6) return len; + memcpy(xform, t, sizeof(float)*6); + return len; +} + +static int nsvg__parseTranslate(float* xform, const char* str) +{ + float args[2]; + float t[6]; + int na = 0; + int len = nsvg__parseTransformArgs(str, args, 2, &na); + if (na == 1) args[1] = 0.0; + + nsvg__xformSetTranslation(t, args[0], args[1]); + memcpy(xform, t, sizeof(float)*6); + return len; +} + +static int nsvg__parseScale(float* xform, const char* str) +{ + float args[2]; + int na = 0; + float t[6]; + int len = nsvg__parseTransformArgs(str, args, 2, &na); + if (na == 1) args[1] = args[0]; + nsvg__xformSetScale(t, args[0], args[1]); + memcpy(xform, t, sizeof(float)*6); + return len; +} + +static int nsvg__parseSkewX(float* xform, const char* str) +{ + float args[1]; + int na = 0; + float t[6]; + int len = nsvg__parseTransformArgs(str, args, 1, &na); + nsvg__xformSetSkewX(t, args[0]/180.0f*NSVG_PI); + memcpy(xform, t, sizeof(float)*6); + return len; +} + +static int nsvg__parseSkewY(float* xform, const char* str) +{ + float args[1]; + int na = 0; + float t[6]; + int len = nsvg__parseTransformArgs(str, args, 1, &na); + nsvg__xformSetSkewY(t, args[0]/180.0f*NSVG_PI); + memcpy(xform, t, sizeof(float)*6); + return len; +} + +static int nsvg__parseRotate(float* xform, const char* str) +{ + float args[3]; + int na = 0; + float m[6]; + float t[6]; + int len = nsvg__parseTransformArgs(str, args, 3, &na); + if (na == 1) + args[1] = args[2] = 0.0f; + nsvg__xformIdentity(m); + + if (na > 1) { + nsvg__xformSetTranslation(t, -args[1], -args[2]); + nsvg__xformMultiply(m, t); + } + + nsvg__xformSetRotation(t, args[0]/180.0f*NSVG_PI); + nsvg__xformMultiply(m, t); + + if (na > 1) { + nsvg__xformSetTranslation(t, args[1], args[2]); + nsvg__xformMultiply(m, t); + } + + memcpy(xform, m, sizeof(float)*6); + + return len; +} + +static void nsvg__parseTransform(float* xform, const char* str) +{ + float t[6]; + int len; + nsvg__xformIdentity(xform); + while (*str) + { + if (strncmp(str, "matrix", 6) == 0) + len = nsvg__parseMatrix(t, str); + else if (strncmp(str, "translate", 9) == 0) + len = nsvg__parseTranslate(t, str); + else if (strncmp(str, "scale", 5) == 0) + len = nsvg__parseScale(t, str); + else if (strncmp(str, "rotate", 6) == 0) + len = nsvg__parseRotate(t, str); + else if (strncmp(str, "skewX", 5) == 0) + len = nsvg__parseSkewX(t, str); + else if (strncmp(str, "skewY", 5) == 0) + len = nsvg__parseSkewY(t, str); + else{ + ++str; + continue; + } + if (len != 0) { + str += len; + } else { + ++str; + continue; + } + + nsvg__xformPremultiply(xform, t); + } +} + +static void nsvg__parseUrl(char* id, const char* str) +{ + int i = 0; + str += 4; // "url("; + if (*str == '#') + str++; + while (i < 63 && *str != ')') { + id[i] = *str++; + i++; + } + id[i] = '\0'; +} + +static char nsvg__parseLineCap(const char* str) +{ + if (strcmp(str, "butt") == 0) + return NSVG_CAP_BUTT; + else if (strcmp(str, "round") == 0) + return NSVG_CAP_ROUND; + else if (strcmp(str, "square") == 0) + return NSVG_CAP_SQUARE; + // TODO: handle inherit. + return NSVG_CAP_BUTT; +} + +static char nsvg__parseLineJoin(const char* str) +{ + if (strcmp(str, "miter") == 0) + return NSVG_JOIN_MITER; + else if (strcmp(str, "round") == 0) + return NSVG_JOIN_ROUND; + else if (strcmp(str, "bevel") == 0) + return NSVG_JOIN_BEVEL; + // TODO: handle inherit. + return NSVG_JOIN_MITER; +} + +static char nsvg__parseFillRule(const char* str) +{ + if (strcmp(str, "nonzero") == 0) + return NSVG_FILLRULE_NONZERO; + else if (strcmp(str, "evenodd") == 0) + return NSVG_FILLRULE_EVENODD; + // TODO: handle inherit. + return NSVG_FILLRULE_NONZERO; +} + +static const char* nsvg__getNextDashItem(const char* s, char* it) +{ + int n = 0; + it[0] = '\0'; + // Skip white spaces and commas + while (*s && (nsvg__isspace(*s) || *s == ',')) s++; + // Advance until whitespace, comma or end. + while (*s && (!nsvg__isspace(*s) && *s != ',')) { + if (n < 63) + it[n++] = *s; + s++; + } + it[n++] = '\0'; + return s; +} + +static int nsvg__parseStrokeDashArray(NSVGparser* p, const char* str, float* strokeDashArray) +{ + char item[64]; + int count = 0, i; + float sum = 0.0f; + + // Handle "none" + if (str[0] == 'n') + return 0; + + // Parse dashes + while (*str) { + str = nsvg__getNextDashItem(str, item); + if (!*item) break; + if (count < NSVG_MAX_DASHES) + strokeDashArray[count++] = fabsf(nsvg__parseCoordinate(p, item, 0.0f, nsvg__actualLength(p))); + } + + for (i = 0; i < count; i++) + sum += strokeDashArray[i]; + if (sum <= 1e-6f) + count = 0; + + return count; +} + +static void nsvg__parseStyle(NSVGparser* p, const char* str); + +static int nsvg__parseAttr(NSVGparser* p, const char* name, const char* value) +{ + float xform[6]; + NSVGattrib* attr = nsvg__getAttr(p); + if (!attr) return 0; + + if (strcmp(name, "style") == 0) { + nsvg__parseStyle(p, value); + } else if (strcmp(name, "display") == 0) { + if (strcmp(value, "none") == 0) + attr->visible = 0; + // Don't reset ->visible on display:inline, one display:none hides the whole subtree + + } else if (strcmp(name, "fill") == 0) { + if (strcmp(value, "none") == 0) { + attr->hasFill = 0; + } else if (strncmp(value, "url(", 4) == 0) { + attr->hasFill = 2; + nsvg__parseUrl(attr->fillGradient, value); + } else { + attr->hasFill = 1; + attr->fillColor = nsvg__parseColor(value); + } + } else if (strcmp(name, "opacity") == 0) { + attr->opacity = nsvg__parseOpacity(value); + } else if (strcmp(name, "fill-opacity") == 0) { + attr->fillOpacity = nsvg__parseOpacity(value); + } else if (strcmp(name, "stroke") == 0) { + if (strcmp(value, "none") == 0) { + attr->hasStroke = 0; + } else if (strncmp(value, "url(", 4) == 0) { + attr->hasStroke = 2; + nsvg__parseUrl(attr->strokeGradient, value); + } else { + attr->hasStroke = 1; + attr->strokeColor = nsvg__parseColor(value); + } + } else if (strcmp(name, "stroke-width") == 0) { + attr->strokeWidth = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p)); + } else if (strcmp(name, "stroke-dasharray") == 0) { + attr->strokeDashCount = nsvg__parseStrokeDashArray(p, value, attr->strokeDashArray); + } else if (strcmp(name, "stroke-dashoffset") == 0) { + attr->strokeDashOffset = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p)); + } else if (strcmp(name, "stroke-opacity") == 0) { + attr->strokeOpacity = nsvg__parseOpacity(value); + } else if (strcmp(name, "stroke-linecap") == 0) { + attr->strokeLineCap = nsvg__parseLineCap(value); + } else if (strcmp(name, "stroke-linejoin") == 0) { + attr->strokeLineJoin = nsvg__parseLineJoin(value); + } else if (strcmp(name, "stroke-miterlimit") == 0) { + attr->miterLimit = nsvg__parseMiterLimit(value); + } else if (strcmp(name, "fill-rule") == 0) { + attr->fillRule = nsvg__parseFillRule(value); + } else if (strcmp(name, "font-size") == 0) { + attr->fontSize = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p)); + } else if (strcmp(name, "transform") == 0) { + nsvg__parseTransform(xform, value); + nsvg__xformPremultiply(attr->xform, xform); + } else if (strcmp(name, "stop-color") == 0) { + attr->stopColor = nsvg__parseColor(value); + } else if (strcmp(name, "stop-opacity") == 0) { + attr->stopOpacity = nsvg__parseOpacity(value); + } else if (strcmp(name, "offset") == 0) { + attr->stopOffset = nsvg__parseCoordinate(p, value, 0.0f, 1.0f); + } else if (strcmp(name, "id") == 0) { + strncpy(attr->id, value, 63); + attr->id[63] = '\0'; + } else { + return 0; + } + return 1; +} + +static int nsvg__parseNameValue(NSVGparser* p, const char* start, const char* end) +{ + const char* str; + const char* val; + char name[512]; + char value[512]; + int n; + + str = start; + while (str < end && *str != ':') ++str; + + val = str; + + // Right Trim + while (str > start && (*str == ':' || nsvg__isspace(*str))) --str; + ++str; + + n = (int)(str - start); + if (n > 511) n = 511; + if (n) memcpy(name, start, n); + name[n] = 0; + + while (val < end && (*val == ':' || nsvg__isspace(*val))) ++val; + + n = (int)(end - val); + if (n > 511) n = 511; + if (n) memcpy(value, val, n); + value[n] = 0; + + return nsvg__parseAttr(p, name, value); +} + +static void nsvg__parseStyle(NSVGparser* p, const char* str) +{ + const char* start; + const char* end; + + while (*str) { + // Left Trim + while(*str && nsvg__isspace(*str)) ++str; + start = str; + while(*str && *str != ';') ++str; + end = str; + + // Right Trim + while (end > start && (*end == ';' || nsvg__isspace(*end))) --end; + ++end; + + nsvg__parseNameValue(p, start, end); + if (*str) ++str; + } +} + +static void nsvg__parseAttribs(NSVGparser* p, const char** attr) +{ + int i; + for (i = 0; attr[i]; i += 2) + { + if (strcmp(attr[i], "style") == 0) + nsvg__parseStyle(p, attr[i + 1]); + else + nsvg__parseAttr(p, attr[i], attr[i + 1]); + } +} + +static int nsvg__getArgsPerElement(char cmd) +{ + switch (cmd) { + case 'v': + case 'V': + case 'h': + case 'H': + return 1; + case 'm': + case 'M': + case 'l': + case 'L': + case 't': + case 'T': + return 2; + case 'q': + case 'Q': + case 's': + case 'S': + return 4; + case 'c': + case 'C': + return 6; + case 'a': + case 'A': + return 7; + case 'z': + case 'Z': + return 0; + } + return -1; +} + +static void nsvg__pathMoveTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) +{ + if (rel) { + *cpx += args[0]; + *cpy += args[1]; + } else { + *cpx = args[0]; + *cpy = args[1]; + } + nsvg__moveTo(p, *cpx, *cpy); +} + +static void nsvg__pathLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) +{ + if (rel) { + *cpx += args[0]; + *cpy += args[1]; + } else { + *cpx = args[0]; + *cpy = args[1]; + } + nsvg__lineTo(p, *cpx, *cpy); +} + +static void nsvg__pathHLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) +{ + if (rel) + *cpx += args[0]; + else + *cpx = args[0]; + nsvg__lineTo(p, *cpx, *cpy); +} + +static void nsvg__pathVLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) +{ + if (rel) + *cpy += args[0]; + else + *cpy = args[0]; + nsvg__lineTo(p, *cpx, *cpy); +} + +static void nsvg__pathCubicBezTo(NSVGparser* p, float* cpx, float* cpy, + float* cpx2, float* cpy2, float* args, int rel) +{ + float x2, y2, cx1, cy1, cx2, cy2; + + if (rel) { + cx1 = *cpx + args[0]; + cy1 = *cpy + args[1]; + cx2 = *cpx + args[2]; + cy2 = *cpy + args[3]; + x2 = *cpx + args[4]; + y2 = *cpy + args[5]; + } else { + cx1 = args[0]; + cy1 = args[1]; + cx2 = args[2]; + cy2 = args[3]; + x2 = args[4]; + y2 = args[5]; + } + + nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2); + + *cpx2 = cx2; + *cpy2 = cy2; + *cpx = x2; + *cpy = y2; +} + +static void nsvg__pathCubicBezShortTo(NSVGparser* p, float* cpx, float* cpy, + float* cpx2, float* cpy2, float* args, int rel) +{ + float x1, y1, x2, y2, cx1, cy1, cx2, cy2; + + x1 = *cpx; + y1 = *cpy; + if (rel) { + cx2 = *cpx + args[0]; + cy2 = *cpy + args[1]; + x2 = *cpx + args[2]; + y2 = *cpy + args[3]; + } else { + cx2 = args[0]; + cy2 = args[1]; + x2 = args[2]; + y2 = args[3]; + } + + cx1 = 2*x1 - *cpx2; + cy1 = 2*y1 - *cpy2; + + nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2); + + *cpx2 = cx2; + *cpy2 = cy2; + *cpx = x2; + *cpy = y2; +} + +static void nsvg__pathQuadBezTo(NSVGparser* p, float* cpx, float* cpy, + float* cpx2, float* cpy2, float* args, int rel) +{ + float x1, y1, x2, y2, cx, cy; + float cx1, cy1, cx2, cy2; + + x1 = *cpx; + y1 = *cpy; + if (rel) { + cx = *cpx + args[0]; + cy = *cpy + args[1]; + x2 = *cpx + args[2]; + y2 = *cpy + args[3]; + } else { + cx = args[0]; + cy = args[1]; + x2 = args[2]; + y2 = args[3]; + } + + // Convert to cubic bezier + cx1 = x1 + 2.0f/3.0f*(cx - x1); + cy1 = y1 + 2.0f/3.0f*(cy - y1); + cx2 = x2 + 2.0f/3.0f*(cx - x2); + cy2 = y2 + 2.0f/3.0f*(cy - y2); + + nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2); + + *cpx2 = cx; + *cpy2 = cy; + *cpx = x2; + *cpy = y2; +} + +static void nsvg__pathQuadBezShortTo(NSVGparser* p, float* cpx, float* cpy, + float* cpx2, float* cpy2, float* args, int rel) +{ + float x1, y1, x2, y2, cx, cy; + float cx1, cy1, cx2, cy2; + + x1 = *cpx; + y1 = *cpy; + if (rel) { + x2 = *cpx + args[0]; + y2 = *cpy + args[1]; + } else { + x2 = args[0]; + y2 = args[1]; + } + + cx = 2*x1 - *cpx2; + cy = 2*y1 - *cpy2; + + // Convert to cubix bezier + cx1 = x1 + 2.0f/3.0f*(cx - x1); + cy1 = y1 + 2.0f/3.0f*(cy - y1); + cx2 = x2 + 2.0f/3.0f*(cx - x2); + cy2 = y2 + 2.0f/3.0f*(cy - y2); + + nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2); + + *cpx2 = cx; + *cpy2 = cy; + *cpx = x2; + *cpy = y2; +} + +static float nsvg__sqr(float x) { return x*x; } +static float nsvg__vmag(float x, float y) { return sqrtf(x*x + y*y); } + +static float nsvg__vecrat(float ux, float uy, float vx, float vy) +{ + return (ux*vx + uy*vy) / (nsvg__vmag(ux,uy) * nsvg__vmag(vx,vy)); +} + +static float nsvg__vecang(float ux, float uy, float vx, float vy) +{ + float r = nsvg__vecrat(ux,uy, vx,vy); + if (r < -1.0f) r = -1.0f; + if (r > 1.0f) r = 1.0f; + return ((ux*vy < uy*vx) ? -1.0f : 1.0f) * acosf(r); +} + +static void nsvg__pathArcTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) +{ + // Ported from canvg (https://code.google.com/p/canvg/) + float rx, ry, rotx; + float x1, y1, x2, y2, cx, cy, dx, dy, d; + float x1p, y1p, cxp, cyp, s, sa, sb; + float ux, uy, vx, vy, a1, da; + float x, y, tanx, tany, a, px = 0, py = 0, ptanx = 0, ptany = 0, t[6]; + float sinrx, cosrx; + int fa, fs; + int i, ndivs; + float hda, kappa; + + rx = fabsf(args[0]); // y radius + ry = fabsf(args[1]); // x radius + rotx = args[2] / 180.0f * NSVG_PI; // x rotation angle + fa = fabsf(args[3]) > 1e-6 ? 1 : 0; // Large arc + fs = fabsf(args[4]) > 1e-6 ? 1 : 0; // Sweep direction + x1 = *cpx; // start point + y1 = *cpy; + if (rel) { // end point + x2 = *cpx + args[5]; + y2 = *cpy + args[6]; + } else { + x2 = args[5]; + y2 = args[6]; + } + + dx = x1 - x2; + dy = y1 - y2; + d = sqrtf(dx*dx + dy*dy); + if (d < 1e-6f || rx < 1e-6f || ry < 1e-6f) { + // The arc degenerates to a line + nsvg__lineTo(p, x2, y2); + *cpx = x2; + *cpy = y2; + return; + } + + sinrx = sinf(rotx); + cosrx = cosf(rotx); + + // Convert to center point parameterization. + // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes + // 1) Compute x1', y1' + x1p = cosrx * dx / 2.0f + sinrx * dy / 2.0f; + y1p = -sinrx * dx / 2.0f + cosrx * dy / 2.0f; + d = nsvg__sqr(x1p)/nsvg__sqr(rx) + nsvg__sqr(y1p)/nsvg__sqr(ry); + if (d > 1) { + d = sqrtf(d); + rx *= d; + ry *= d; + } + // 2) Compute cx', cy' + s = 0.0f; + sa = nsvg__sqr(rx)*nsvg__sqr(ry) - nsvg__sqr(rx)*nsvg__sqr(y1p) - nsvg__sqr(ry)*nsvg__sqr(x1p); + sb = nsvg__sqr(rx)*nsvg__sqr(y1p) + nsvg__sqr(ry)*nsvg__sqr(x1p); + if (sa < 0.0f) sa = 0.0f; + if (sb > 0.0f) + s = sqrtf(sa / sb); + if (fa == fs) + s = -s; + cxp = s * rx * y1p / ry; + cyp = s * -ry * x1p / rx; + + // 3) Compute cx,cy from cx',cy' + cx = (x1 + x2)/2.0f + cosrx*cxp - sinrx*cyp; + cy = (y1 + y2)/2.0f + sinrx*cxp + cosrx*cyp; + + // 4) Calculate theta1, and delta theta. + ux = (x1p - cxp) / rx; + uy = (y1p - cyp) / ry; + vx = (-x1p - cxp) / rx; + vy = (-y1p - cyp) / ry; + a1 = nsvg__vecang(1.0f,0.0f, ux,uy); // Initial angle + da = nsvg__vecang(ux,uy, vx,vy); // Delta angle + +// if (vecrat(ux,uy,vx,vy) <= -1.0f) da = NSVG_PI; +// if (vecrat(ux,uy,vx,vy) >= 1.0f) da = 0; + + if (fs == 0 && da > 0) + da -= 2 * NSVG_PI; + else if (fs == 1 && da < 0) + da += 2 * NSVG_PI; + + // Approximate the arc using cubic spline segments. + t[0] = cosrx; t[1] = sinrx; + t[2] = -sinrx; t[3] = cosrx; + t[4] = cx; t[5] = cy; + + // Split arc into max 90 degree segments. + // The loop assumes an iteration per end point (including start and end), this +1. + ndivs = (int)(fabsf(da) / (NSVG_PI*0.5f) + 1.0f); + hda = (da / (float)ndivs) / 2.0f; + // Fix for ticket #179: division by 0: avoid cotangens around 0 (infinite) + if ((hda < 1e-3f) && (hda > -1e-3f)) + hda *= 0.5f; + else + hda = (1.0f - cosf(hda)) / sinf(hda); + kappa = fabsf(4.0f / 3.0f * hda); + if (da < 0.0f) + kappa = -kappa; + + for (i = 0; i <= ndivs; i++) { + a = a1 + da * ((float)i/(float)ndivs); + dx = cosf(a); + dy = sinf(a); + nsvg__xformPoint(&x, &y, dx*rx, dy*ry, t); // position + nsvg__xformVec(&tanx, &tany, -dy*rx * kappa, dx*ry * kappa, t); // tangent + if (i > 0) + nsvg__cubicBezTo(p, px+ptanx,py+ptany, x-tanx, y-tany, x, y); + px = x; + py = y; + ptanx = tanx; + ptany = tany; + } + + *cpx = x2; + *cpy = y2; +} + +static void nsvg__parsePath(NSVGparser* p, const char** attr) +{ + const char* s = NULL; + char cmd = '\0'; + float args[10]; + int nargs; + int rargs = 0; + char initPoint; + float cpx, cpy, cpx2, cpy2; + const char* tmp[4]; + char closedFlag; + int i; + char item[64]; + + for (i = 0; attr[i]; i += 2) { + if (strcmp(attr[i], "d") == 0) { + s = attr[i + 1]; + } else { + tmp[0] = attr[i]; + tmp[1] = attr[i + 1]; + tmp[2] = 0; + tmp[3] = 0; + nsvg__parseAttribs(p, tmp); + } + } + + if (s) { + nsvg__resetPath(p); + cpx = 0; cpy = 0; + cpx2 = 0; cpy2 = 0; + initPoint = 0; + closedFlag = 0; + nargs = 0; + + while (*s) { + s = nsvg__getNextPathItem(s, item); + if (!*item) break; + if (cmd != '\0' && nsvg__isCoordinate(item)) { + if (nargs < 10) + args[nargs++] = (float)nsvg__atof(item); + if (nargs >= rargs) { + switch (cmd) { + case 'm': + case 'M': + nsvg__pathMoveTo(p, &cpx, &cpy, args, cmd == 'm' ? 1 : 0); + // Moveto can be followed by multiple coordinate pairs, + // which should be treated as linetos. + cmd = (cmd == 'm') ? 'l' : 'L'; + rargs = nsvg__getArgsPerElement(cmd); + cpx2 = cpx; cpy2 = cpy; + initPoint = 1; + break; + case 'l': + case 'L': + nsvg__pathLineTo(p, &cpx, &cpy, args, cmd == 'l' ? 1 : 0); + cpx2 = cpx; cpy2 = cpy; + break; + case 'H': + case 'h': + nsvg__pathHLineTo(p, &cpx, &cpy, args, cmd == 'h' ? 1 : 0); + cpx2 = cpx; cpy2 = cpy; + break; + case 'V': + case 'v': + nsvg__pathVLineTo(p, &cpx, &cpy, args, cmd == 'v' ? 1 : 0); + cpx2 = cpx; cpy2 = cpy; + break; + case 'C': + case 'c': + nsvg__pathCubicBezTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 'c' ? 1 : 0); + break; + case 'S': + case 's': + nsvg__pathCubicBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 's' ? 1 : 0); + break; + case 'Q': + case 'q': + nsvg__pathQuadBezTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 'q' ? 1 : 0); + break; + case 'T': + case 't': + nsvg__pathQuadBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 't' ? 1 : 0); + break; + case 'A': + case 'a': + nsvg__pathArcTo(p, &cpx, &cpy, args, cmd == 'a' ? 1 : 0); + cpx2 = cpx; cpy2 = cpy; + break; + default: + if (nargs >= 2) { + cpx = args[nargs-2]; + cpy = args[nargs-1]; + cpx2 = cpx; cpy2 = cpy; + } + break; + } + nargs = 0; + } + } else { + cmd = item[0]; + if (cmd == 'M' || cmd == 'm') { + // Commit path. + if (p->npts > 0) + nsvg__addPath(p, closedFlag); + // Start new subpath. + nsvg__resetPath(p); + closedFlag = 0; + nargs = 0; + } else if (initPoint == 0) { + // Do not allow other commands until initial point has been set (moveTo called once). + cmd = '\0'; + } + if (cmd == 'Z' || cmd == 'z') { + closedFlag = 1; + // Commit path. + if (p->npts > 0) { + // Move current point to first point + cpx = p->pts[0]; + cpy = p->pts[1]; + cpx2 = cpx; cpy2 = cpy; + nsvg__addPath(p, closedFlag); + } + // Start new subpath. + nsvg__resetPath(p); + nsvg__moveTo(p, cpx, cpy); + closedFlag = 0; + nargs = 0; + } + rargs = nsvg__getArgsPerElement(cmd); + if (rargs == -1) { + // Command not recognized + cmd = '\0'; + rargs = 0; + } + } + } + // Commit path. + if (p->npts) + nsvg__addPath(p, closedFlag); + } + + nsvg__addShape(p); +} + +static void nsvg__parseRect(NSVGparser* p, const char** attr) +{ + float x = 0.0f; + float y = 0.0f; + float w = 0.0f; + float h = 0.0f; + float rx = -1.0f; // marks not set + float ry = -1.0f; + int i; + + for (i = 0; attr[i]; i += 2) { + if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { + if (strcmp(attr[i], "x") == 0) x = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); + if (strcmp(attr[i], "y") == 0) y = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); + if (strcmp(attr[i], "width") == 0) w = nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p)); + if (strcmp(attr[i], "height") == 0) h = nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p)); + if (strcmp(attr[i], "rx") == 0) rx = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p))); + if (strcmp(attr[i], "ry") == 0) ry = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p))); + } + } + + if (rx < 0.0f && ry > 0.0f) rx = ry; + if (ry < 0.0f && rx > 0.0f) ry = rx; + if (rx < 0.0f) rx = 0.0f; + if (ry < 0.0f) ry = 0.0f; + if (rx > w/2.0f) rx = w/2.0f; + if (ry > h/2.0f) ry = h/2.0f; + + if (w != 0.0f && h != 0.0f) { + nsvg__resetPath(p); + + if (rx < 0.00001f || ry < 0.0001f) { + nsvg__moveTo(p, x, y); + nsvg__lineTo(p, x+w, y); + nsvg__lineTo(p, x+w, y+h); + nsvg__lineTo(p, x, y+h); + } else { + // Rounded rectangle + nsvg__moveTo(p, x+rx, y); + nsvg__lineTo(p, x+w-rx, y); + nsvg__cubicBezTo(p, x+w-rx*(1-NSVG_KAPPA90), y, x+w, y+ry*(1-NSVG_KAPPA90), x+w, y+ry); + nsvg__lineTo(p, x+w, y+h-ry); + nsvg__cubicBezTo(p, x+w, y+h-ry*(1-NSVG_KAPPA90), x+w-rx*(1-NSVG_KAPPA90), y+h, x+w-rx, y+h); + nsvg__lineTo(p, x+rx, y+h); + nsvg__cubicBezTo(p, x+rx*(1-NSVG_KAPPA90), y+h, x, y+h-ry*(1-NSVG_KAPPA90), x, y+h-ry); + nsvg__lineTo(p, x, y+ry); + nsvg__cubicBezTo(p, x, y+ry*(1-NSVG_KAPPA90), x+rx*(1-NSVG_KAPPA90), y, x+rx, y); + } + + nsvg__addPath(p, 1); + + nsvg__addShape(p); + } +} + +static void nsvg__parseCircle(NSVGparser* p, const char** attr) +{ + float cx = 0.0f; + float cy = 0.0f; + float r = 0.0f; + int i; + + for (i = 0; attr[i]; i += 2) { + if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { + if (strcmp(attr[i], "cx") == 0) cx = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); + if (strcmp(attr[i], "cy") == 0) cy = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); + if (strcmp(attr[i], "r") == 0) r = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualLength(p))); + } + } + + if (r > 0.0f) { + nsvg__resetPath(p); + + nsvg__moveTo(p, cx+r, cy); + nsvg__cubicBezTo(p, cx+r, cy+r*NSVG_KAPPA90, cx+r*NSVG_KAPPA90, cy+r, cx, cy+r); + nsvg__cubicBezTo(p, cx-r*NSVG_KAPPA90, cy+r, cx-r, cy+r*NSVG_KAPPA90, cx-r, cy); + nsvg__cubicBezTo(p, cx-r, cy-r*NSVG_KAPPA90, cx-r*NSVG_KAPPA90, cy-r, cx, cy-r); + nsvg__cubicBezTo(p, cx+r*NSVG_KAPPA90, cy-r, cx+r, cy-r*NSVG_KAPPA90, cx+r, cy); + + nsvg__addPath(p, 1); + + nsvg__addShape(p); + } +} + +static void nsvg__parseEllipse(NSVGparser* p, const char** attr) +{ + float cx = 0.0f; + float cy = 0.0f; + float rx = 0.0f; + float ry = 0.0f; + int i; + + for (i = 0; attr[i]; i += 2) { + if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { + if (strcmp(attr[i], "cx") == 0) cx = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); + if (strcmp(attr[i], "cy") == 0) cy = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); + if (strcmp(attr[i], "rx") == 0) rx = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p))); + if (strcmp(attr[i], "ry") == 0) ry = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p))); + } + } + + if (rx > 0.0f && ry > 0.0f) { + + nsvg__resetPath(p); + + nsvg__moveTo(p, cx+rx, cy); + nsvg__cubicBezTo(p, cx+rx, cy+ry*NSVG_KAPPA90, cx+rx*NSVG_KAPPA90, cy+ry, cx, cy+ry); + nsvg__cubicBezTo(p, cx-rx*NSVG_KAPPA90, cy+ry, cx-rx, cy+ry*NSVG_KAPPA90, cx-rx, cy); + nsvg__cubicBezTo(p, cx-rx, cy-ry*NSVG_KAPPA90, cx-rx*NSVG_KAPPA90, cy-ry, cx, cy-ry); + nsvg__cubicBezTo(p, cx+rx*NSVG_KAPPA90, cy-ry, cx+rx, cy-ry*NSVG_KAPPA90, cx+rx, cy); + + nsvg__addPath(p, 1); + + nsvg__addShape(p); + } +} + +static void nsvg__parseLine(NSVGparser* p, const char** attr) +{ + float x1 = 0.0; + float y1 = 0.0; + float x2 = 0.0; + float y2 = 0.0; + int i; + + for (i = 0; attr[i]; i += 2) { + if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { + if (strcmp(attr[i], "x1") == 0) x1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); + if (strcmp(attr[i], "y1") == 0) y1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); + if (strcmp(attr[i], "x2") == 0) x2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); + if (strcmp(attr[i], "y2") == 0) y2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); + } + } + + nsvg__resetPath(p); + + nsvg__moveTo(p, x1, y1); + nsvg__lineTo(p, x2, y2); + + nsvg__addPath(p, 0); + + nsvg__addShape(p); +} + +static void nsvg__parsePoly(NSVGparser* p, const char** attr, int closeFlag) +{ + int i; + const char* s; + float args[2]; + int nargs, npts = 0; + char item[64]; + + nsvg__resetPath(p); + + for (i = 0; attr[i]; i += 2) { + if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { + if (strcmp(attr[i], "points") == 0) { + s = attr[i + 1]; + nargs = 0; + while (*s) { + s = nsvg__getNextPathItem(s, item); + args[nargs++] = (float)nsvg__atof(item); + if (nargs >= 2) { + if (npts == 0) + nsvg__moveTo(p, args[0], args[1]); + else + nsvg__lineTo(p, args[0], args[1]); + nargs = 0; + npts++; + } + } + } + } + } + + nsvg__addPath(p, (char)closeFlag); + + nsvg__addShape(p); +} + +static void nsvg__parseSVG(NSVGparser* p, const char** attr) +{ + int i; + for (i = 0; attr[i]; i += 2) { + if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { + if (strcmp(attr[i], "width") == 0) { + p->image->width = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f); + } else if (strcmp(attr[i], "height") == 0) { + p->image->height = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f); + } else if (strcmp(attr[i], "viewBox") == 0) { + const char *s = attr[i + 1]; + char buf[64]; + s = nsvg__parseNumber(s, buf, 64); + p->viewMinx = nsvg__atof(buf); + while (*s && (nsvg__isspace(*s) || *s == '%' || *s == ',')) s++; + if (!*s) return; + s = nsvg__parseNumber(s, buf, 64); + p->viewMiny = nsvg__atof(buf); + while (*s && (nsvg__isspace(*s) || *s == '%' || *s == ',')) s++; + if (!*s) return; + s = nsvg__parseNumber(s, buf, 64); + p->viewWidth = nsvg__atof(buf); + while (*s && (nsvg__isspace(*s) || *s == '%' || *s == ',')) s++; + if (!*s) return; + s = nsvg__parseNumber(s, buf, 64); + p->viewHeight = nsvg__atof(buf); + } else if (strcmp(attr[i], "preserveAspectRatio") == 0) { + if (strstr(attr[i + 1], "none") != 0) { + // No uniform scaling + p->alignType = NSVG_ALIGN_NONE; + } else { + // Parse X align + if (strstr(attr[i + 1], "xMin") != 0) + p->alignX = NSVG_ALIGN_MIN; + else if (strstr(attr[i + 1], "xMid") != 0) + p->alignX = NSVG_ALIGN_MID; + else if (strstr(attr[i + 1], "xMax") != 0) + p->alignX = NSVG_ALIGN_MAX; + // Parse X align + if (strstr(attr[i + 1], "yMin") != 0) + p->alignY = NSVG_ALIGN_MIN; + else if (strstr(attr[i + 1], "yMid") != 0) + p->alignY = NSVG_ALIGN_MID; + else if (strstr(attr[i + 1], "yMax") != 0) + p->alignY = NSVG_ALIGN_MAX; + // Parse meet/slice + p->alignType = NSVG_ALIGN_MEET; + if (strstr(attr[i + 1], "slice") != 0) + p->alignType = NSVG_ALIGN_SLICE; + } + } + } + } +} + +static void nsvg__parseGradient(NSVGparser* p, const char** attr, char type) +{ + int i; + NSVGgradientData* grad = (NSVGgradientData*)malloc(sizeof(NSVGgradientData)); + if (grad == NULL) return; + memset(grad, 0, sizeof(NSVGgradientData)); + grad->units = NSVG_OBJECT_SPACE; + grad->type = type; + if (grad->type == NSVG_PAINT_LINEAR_GRADIENT) { + grad->linear.x1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT); + grad->linear.y1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT); + grad->linear.x2 = nsvg__coord(100.0f, NSVG_UNITS_PERCENT); + grad->linear.y2 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT); + } else if (grad->type == NSVG_PAINT_RADIAL_GRADIENT) { + grad->radial.cx = nsvg__coord(50.0f, NSVG_UNITS_PERCENT); + grad->radial.cy = nsvg__coord(50.0f, NSVG_UNITS_PERCENT); + grad->radial.r = nsvg__coord(50.0f, NSVG_UNITS_PERCENT); + } + + nsvg__xformIdentity(grad->xform); + + for (i = 0; attr[i]; i += 2) { + if (strcmp(attr[i], "id") == 0) { + strncpy(grad->id, attr[i+1], 63); + grad->id[63] = '\0'; + } else if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { + if (strcmp(attr[i], "gradientUnits") == 0) { + if (strcmp(attr[i+1], "objectBoundingBox") == 0) + grad->units = NSVG_OBJECT_SPACE; + else + grad->units = NSVG_USER_SPACE; + } else if (strcmp(attr[i], "gradientTransform") == 0) { + nsvg__parseTransform(grad->xform, attr[i + 1]); + } else if (strcmp(attr[i], "cx") == 0) { + grad->radial.cx = nsvg__parseCoordinateRaw(attr[i + 1]); + } else if (strcmp(attr[i], "cy") == 0) { + grad->radial.cy = nsvg__parseCoordinateRaw(attr[i + 1]); + } else if (strcmp(attr[i], "r") == 0) { + grad->radial.r = nsvg__parseCoordinateRaw(attr[i + 1]); + } else if (strcmp(attr[i], "fx") == 0) { + grad->radial.fx = nsvg__parseCoordinateRaw(attr[i + 1]); + } else if (strcmp(attr[i], "fy") == 0) { + grad->radial.fy = nsvg__parseCoordinateRaw(attr[i + 1]); + } else if (strcmp(attr[i], "x1") == 0) { + grad->linear.x1 = nsvg__parseCoordinateRaw(attr[i + 1]); + } else if (strcmp(attr[i], "y1") == 0) { + grad->linear.y1 = nsvg__parseCoordinateRaw(attr[i + 1]); + } else if (strcmp(attr[i], "x2") == 0) { + grad->linear.x2 = nsvg__parseCoordinateRaw(attr[i + 1]); + } else if (strcmp(attr[i], "y2") == 0) { + grad->linear.y2 = nsvg__parseCoordinateRaw(attr[i + 1]); + } else if (strcmp(attr[i], "spreadMethod") == 0) { + if (strcmp(attr[i+1], "pad") == 0) + grad->spread = NSVG_SPREAD_PAD; + else if (strcmp(attr[i+1], "reflect") == 0) + grad->spread = NSVG_SPREAD_REFLECT; + else if (strcmp(attr[i+1], "repeat") == 0) + grad->spread = NSVG_SPREAD_REPEAT; + } else if (strcmp(attr[i], "xlink:href") == 0) { + const char *href = attr[i+1]; + strncpy(grad->ref, href+1, 62); + grad->ref[62] = '\0'; + } + } + } + + grad->next = p->gradients; + p->gradients = grad; +} + +static void nsvg__parseGradientStop(NSVGparser* p, const char** attr) +{ + NSVGattrib* curAttr = nsvg__getAttr(p); + NSVGgradientData* grad; + NSVGgradientStop* stop; + int i, idx; + + curAttr->stopOffset = 0; + curAttr->stopColor = 0; + curAttr->stopOpacity = 1.0f; + + for (i = 0; attr[i]; i += 2) { + nsvg__parseAttr(p, attr[i], attr[i + 1]); + } + + // Add stop to the last gradient. + grad = p->gradients; + if (grad == NULL) return; + + grad->nstops++; + grad->stops = (NSVGgradientStop*)realloc(grad->stops, sizeof(NSVGgradientStop)*grad->nstops); + if (grad->stops == NULL) return; + + // Insert + idx = grad->nstops-1; + for (i = 0; i < grad->nstops-1; i++) { + if (curAttr->stopOffset < grad->stops[i].offset) { + idx = i; + break; + } + } + if (idx != grad->nstops-1) { + for (i = grad->nstops-1; i > idx; i--) + grad->stops[i] = grad->stops[i-1]; + } + + stop = &grad->stops[idx]; + stop->color = curAttr->stopColor; + stop->color |= (unsigned int)(curAttr->stopOpacity*255) << 24; + stop->offset = curAttr->stopOffset; +} + +static void nsvg__startElement(void* ud, const char* el, const char** attr) +{ + NSVGparser* p = (NSVGparser*)ud; + + if (p->defsFlag) { + // Skip everything but gradients in defs + if (strcmp(el, "linearGradient") == 0) { + nsvg__parseGradient(p, attr, NSVG_PAINT_LINEAR_GRADIENT); + } else if (strcmp(el, "radialGradient") == 0) { + nsvg__parseGradient(p, attr, NSVG_PAINT_RADIAL_GRADIENT); + } else if (strcmp(el, "stop") == 0) { + nsvg__parseGradientStop(p, attr); + } + return; + } + + if (strcmp(el, "g") == 0) { + nsvg__pushAttr(p); + nsvg__parseAttribs(p, attr); + } else if (strcmp(el, "path") == 0) { + if (p->pathFlag) // Do not allow nested paths. + return; + nsvg__pushAttr(p); + nsvg__parsePath(p, attr); + nsvg__popAttr(p); + } else if (strcmp(el, "rect") == 0) { + nsvg__pushAttr(p); + nsvg__parseRect(p, attr); + nsvg__popAttr(p); + } else if (strcmp(el, "circle") == 0) { + nsvg__pushAttr(p); + nsvg__parseCircle(p, attr); + nsvg__popAttr(p); + } else if (strcmp(el, "ellipse") == 0) { + nsvg__pushAttr(p); + nsvg__parseEllipse(p, attr); + nsvg__popAttr(p); + } else if (strcmp(el, "line") == 0) { + nsvg__pushAttr(p); + nsvg__parseLine(p, attr); + nsvg__popAttr(p); + } else if (strcmp(el, "polyline") == 0) { + nsvg__pushAttr(p); + nsvg__parsePoly(p, attr, 0); + nsvg__popAttr(p); + } else if (strcmp(el, "polygon") == 0) { + nsvg__pushAttr(p); + nsvg__parsePoly(p, attr, 1); + nsvg__popAttr(p); + } else if (strcmp(el, "linearGradient") == 0) { + nsvg__parseGradient(p, attr, NSVG_PAINT_LINEAR_GRADIENT); + } else if (strcmp(el, "radialGradient") == 0) { + nsvg__parseGradient(p, attr, NSVG_PAINT_RADIAL_GRADIENT); + } else if (strcmp(el, "stop") == 0) { + nsvg__parseGradientStop(p, attr); + } else if (strcmp(el, "defs") == 0) { + p->defsFlag = 1; + } else if (strcmp(el, "svg") == 0) { + nsvg__parseSVG(p, attr); + } +} + +static void nsvg__endElement(void* ud, const char* el) +{ + NSVGparser* p = (NSVGparser*)ud; + + if (strcmp(el, "g") == 0) { + nsvg__popAttr(p); + } else if (strcmp(el, "path") == 0) { + p->pathFlag = 0; + } else if (strcmp(el, "defs") == 0) { + p->defsFlag = 0; + } +} + +static void nsvg__content(void* ud, const char* s) +{ + NSVG_NOTUSED(ud); + NSVG_NOTUSED(s); + // empty +} + +static void nsvg__imageBounds(NSVGparser* p, float* bounds) +{ + NSVGshape* shape; + shape = p->image->shapes; + if (shape == NULL) { + bounds[0] = bounds[1] = bounds[2] = bounds[3] = 0.0; + return; + } + bounds[0] = shape->bounds[0]; + bounds[1] = shape->bounds[1]; + bounds[2] = shape->bounds[2]; + bounds[3] = shape->bounds[3]; + for (shape = shape->next; shape != NULL; shape = shape->next) { + bounds[0] = nsvg__minf(bounds[0], shape->bounds[0]); + bounds[1] = nsvg__minf(bounds[1], shape->bounds[1]); + bounds[2] = nsvg__maxf(bounds[2], shape->bounds[2]); + bounds[3] = nsvg__maxf(bounds[3], shape->bounds[3]); + } +} + +static float nsvg__viewAlign(float content, float container, int type) +{ + if (type == NSVG_ALIGN_MIN) + return 0; + else if (type == NSVG_ALIGN_MAX) + return container - content; + // mid + return (container - content) * 0.5f; +} + +static void nsvg__scaleGradient(NSVGgradient* grad, float tx, float ty, float sx, float sy) +{ + float t[6]; + nsvg__xformSetTranslation(t, tx, ty); + nsvg__xformMultiply (grad->xform, t); + + nsvg__xformSetScale(t, sx, sy); + nsvg__xformMultiply (grad->xform, t); +} + +static void nsvg__scaleToViewbox(NSVGparser* p, const char* units) +{ + NSVGshape* shape; + NSVGpath* path; + float tx, ty, sx, sy, us, bounds[4], t[6], avgs; + int i; + float* pt; + + // Guess image size if not set completely. + nsvg__imageBounds(p, bounds); + + if (p->viewWidth == 0) { + if (p->image->width > 0) { + p->viewWidth = p->image->width; + } else { + p->viewMinx = bounds[0]; + p->viewWidth = bounds[2] - bounds[0]; + } + } + if (p->viewHeight == 0) { + if (p->image->height > 0) { + p->viewHeight = p->image->height; + } else { + p->viewMiny = bounds[1]; + p->viewHeight = bounds[3] - bounds[1]; + } + } + if (p->image->width == 0) + p->image->width = p->viewWidth; + if (p->image->height == 0) + p->image->height = p->viewHeight; + + tx = -p->viewMinx; + ty = -p->viewMiny; + sx = p->viewWidth > 0 ? p->image->width / p->viewWidth : 0; + sy = p->viewHeight > 0 ? p->image->height / p->viewHeight : 0; + // Unit scaling + us = 1.0f / nsvg__convertToPixels(p, nsvg__coord(1.0f, nsvg__parseUnits(units)), 0.0f, 1.0f); + + // Fix aspect ratio + if (p->alignType == NSVG_ALIGN_MEET) { + // fit whole image into viewbox + sx = sy = nsvg__minf(sx, sy); + tx += nsvg__viewAlign(p->viewWidth*sx, p->image->width, p->alignX) / sx; + ty += nsvg__viewAlign(p->viewHeight*sy, p->image->height, p->alignY) / sy; + } else if (p->alignType == NSVG_ALIGN_SLICE) { + // fill whole viewbox with image + sx = sy = nsvg__maxf(sx, sy); + tx += nsvg__viewAlign(p->viewWidth*sx, p->image->width, p->alignX) / sx; + ty += nsvg__viewAlign(p->viewHeight*sy, p->image->height, p->alignY) / sy; + } + + // Transform + sx *= us; + sy *= us; + avgs = (sx+sy) / 2.0f; + for (shape = p->image->shapes; shape != NULL; shape = shape->next) { + shape->bounds[0] = (shape->bounds[0] + tx) * sx; + shape->bounds[1] = (shape->bounds[1] + ty) * sy; + shape->bounds[2] = (shape->bounds[2] + tx) * sx; + shape->bounds[3] = (shape->bounds[3] + ty) * sy; + for (path = shape->paths; path != NULL; path = path->next) { + path->bounds[0] = (path->bounds[0] + tx) * sx; + path->bounds[1] = (path->bounds[1] + ty) * sy; + path->bounds[2] = (path->bounds[2] + tx) * sx; + path->bounds[3] = (path->bounds[3] + ty) * sy; + for (i =0; i < path->npts; i++) { + pt = &path->pts[i*2]; + pt[0] = (pt[0] + tx) * sx; + pt[1] = (pt[1] + ty) * sy; + } + } + + if (shape->fill.type == NSVG_PAINT_LINEAR_GRADIENT || shape->fill.type == NSVG_PAINT_RADIAL_GRADIENT) { + nsvg__scaleGradient(shape->fill.gradient, tx,ty, sx,sy); + memcpy(t, shape->fill.gradient->xform, sizeof(float)*6); + nsvg__xformInverse(shape->fill.gradient->xform, t); + } + if (shape->stroke.type == NSVG_PAINT_LINEAR_GRADIENT || shape->stroke.type == NSVG_PAINT_RADIAL_GRADIENT) { + nsvg__scaleGradient(shape->stroke.gradient, tx,ty, sx,sy); + memcpy(t, shape->stroke.gradient->xform, sizeof(float)*6); + nsvg__xformInverse(shape->stroke.gradient->xform, t); + } + + shape->strokeWidth *= avgs; + shape->strokeDashOffset *= avgs; + for (i = 0; i < shape->strokeDashCount; i++) + shape->strokeDashArray[i] *= avgs; + } +} + +NSVGimage* nsvgParse(char* input, const char* units, float dpi) +{ + NSVGparser* p; + NSVGimage* ret = 0; + + p = nsvg__createParser(); + if (p == NULL) { + return NULL; + } + p->dpi = dpi; + + nsvg__parseXML(input, nsvg__startElement, nsvg__endElement, nsvg__content, p); + + // Scale to viewBox + nsvg__scaleToViewbox(p, units); + + ret = p->image; + p->image = NULL; + + nsvg__deleteParser(p); + + return ret; +} + +NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi) +{ + FILE* fp = NULL; + size_t size; + char* data = NULL; + NSVGimage* image = NULL; + + fp = fopen(filename, "rb"); + if (!fp) goto error; + fseek(fp, 0, SEEK_END); + size = ftell(fp); + fseek(fp, 0, SEEK_SET); + data = (char*)malloc(size+1); + if (data == NULL) goto error; + if (fread(data, 1, size, fp) != size) goto error; + data[size] = '\0'; // Must be null terminated. + fclose(fp); + image = nsvgParse(data, units, dpi); + free(data); + + return image; + +error: + if (fp) fclose(fp); + if (data) free(data); + if (image) nsvgDelete(image); + return NULL; +} + +NSVGpath* nsvgDuplicatePath(NSVGpath* p) +{ + NSVGpath* res = NULL; + + if (p == NULL) + return NULL; + + res = (NSVGpath*)malloc(sizeof(NSVGpath)); + if (res == NULL) goto error; + memset(res, 0, sizeof(NSVGpath)); + + res->pts = (float*)malloc(p->npts*2*sizeof(float)); + if (res->pts == NULL) goto error; + memcpy(res->pts, p->pts, p->npts * sizeof(float) * 2); + res->npts = p->npts; + + memcpy(res->bounds, p->bounds, sizeof(p->bounds)); + + res->closed = p->closed; + + return res; + +error: + if (res != NULL) { + free(res->pts); + free(res); + } + return NULL; +} + +void nsvgDelete(NSVGimage* image) +{ + NSVGshape *snext, *shape; + if (image == NULL) return; + shape = image->shapes; + while (shape != NULL) { + snext = shape->next; + nsvg__deletePaths(shape->paths); + nsvg__deletePaint(&shape->fill); + nsvg__deletePaint(&shape->stroke); + free(shape); + shape = snext; + } + free(image); +} + +#endif diff --git a/src/nanosvgrast.h b/src/nanosvgrast.h new file mode 100644 index 000000000..b740c316c --- /dev/null +++ b/src/nanosvgrast.h @@ -0,0 +1,1452 @@ +/* + * Copyright (c) 2013-14 Mikko Mononen memon@inside.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + * The polygon rasterization is heavily based on stb_truetype rasterizer + * by Sean Barrett - http://nothings.org/ + * + */ + +#ifndef NANOSVGRAST_H +#define NANOSVGRAST_H + +#ifndef NANOSVGRAST_CPLUSPLUS +#ifdef __cplusplus +extern "C" { +#endif +#endif + +typedef struct NSVGrasterizer NSVGrasterizer; + +/* Example Usage: + // Load SVG + NSVGimage* image; + image = nsvgParseFromFile("test.svg", "px", 96); + + // Create rasterizer (can be used to render multiple images). + struct NSVGrasterizer* rast = nsvgCreateRasterizer(); + // Allocate memory for image + unsigned char* img = malloc(w*h*4); + // Rasterize + nsvgRasterize(rast, image, 0,0,1, img, w, h, w*4); +*/ + +// Allocated rasterizer context. +NSVGrasterizer* nsvgCreateRasterizer(); + +// Rasterizes SVG image, returns RGBA image (non-premultiplied alpha) +// r - pointer to rasterizer context +// image - pointer to image to rasterize +// tx,ty - image offset (applied after scaling) +// scale - image scale +// dst - pointer to destination image data, 4 bytes per pixel (RGBA) +// w - width of the image to render +// h - height of the image to render +// stride - number of bytes per scaleline in the destination buffer +void nsvgRasterize(NSVGrasterizer* r, + NSVGimage* image, float tx, float ty, float scale, + unsigned char* dst, int w, int h, int stride); + +// Deletes rasterizer context. +void nsvgDeleteRasterizer(NSVGrasterizer*); + + +#ifndef NANOSVGRAST_CPLUSPLUS +#ifdef __cplusplus +} +#endif +#endif + +#endif // NANOSVGRAST_H + +#ifdef NANOSVGRAST_IMPLEMENTATION + +#include + +#define NSVG__SUBSAMPLES 5 +#define NSVG__FIXSHIFT 10 +#define NSVG__FIX (1 << NSVG__FIXSHIFT) +#define NSVG__FIXMASK (NSVG__FIX-1) +#define NSVG__MEMPAGE_SIZE 1024 + +typedef struct NSVGedge { + float x0,y0, x1,y1; + int dir; + struct NSVGedge* next; +} NSVGedge; + +typedef struct NSVGpoint { + float x, y; + float dx, dy; + float len; + float dmx, dmy; + unsigned char flags; +} NSVGpoint; + +typedef struct NSVGactiveEdge { + int x,dx; + float ey; + int dir; + struct NSVGactiveEdge *next; +} NSVGactiveEdge; + +typedef struct NSVGmemPage { + unsigned char mem[NSVG__MEMPAGE_SIZE]; + int size; + struct NSVGmemPage* next; +} NSVGmemPage; + +typedef struct NSVGcachedPaint { + char type; + char spread; + float xform[6]; + unsigned int colors[256]; +} NSVGcachedPaint; + +struct NSVGrasterizer +{ + float px, py; + + float tessTol; + float distTol; + + NSVGedge* edges; + int nedges; + int cedges; + + NSVGpoint* points; + int npoints; + int cpoints; + + NSVGpoint* points2; + int npoints2; + int cpoints2; + + NSVGactiveEdge* freelist; + NSVGmemPage* pages; + NSVGmemPage* curpage; + + unsigned char* scanline; + int cscanline; + + unsigned char* bitmap; + int width, height, stride; +}; + +NSVGrasterizer* nsvgCreateRasterizer() +{ + NSVGrasterizer* r = (NSVGrasterizer*)malloc(sizeof(NSVGrasterizer)); + if (r == NULL) goto error; + memset(r, 0, sizeof(NSVGrasterizer)); + + r->tessTol = 0.25f; + r->distTol = 0.01f; + + return r; + +error: + nsvgDeleteRasterizer(r); + return NULL; +} + +void nsvgDeleteRasterizer(NSVGrasterizer* r) +{ + NSVGmemPage* p; + + if (r == NULL) return; + + p = r->pages; + while (p != NULL) { + NSVGmemPage* next = p->next; + free(p); + p = next; + } + + if (r->edges) free(r->edges); + if (r->points) free(r->points); + if (r->points2) free(r->points2); + if (r->scanline) free(r->scanline); + + free(r); +} + +static NSVGmemPage* nsvg__nextPage(NSVGrasterizer* r, NSVGmemPage* cur) +{ + NSVGmemPage *newp; + + // If using existing chain, return the next page in chain + if (cur != NULL && cur->next != NULL) { + return cur->next; + } + + // Alloc new page + newp = (NSVGmemPage*)malloc(sizeof(NSVGmemPage)); + if (newp == NULL) return NULL; + memset(newp, 0, sizeof(NSVGmemPage)); + + // Add to linked list + if (cur != NULL) + cur->next = newp; + else + r->pages = newp; + + return newp; +} + +static void nsvg__resetPool(NSVGrasterizer* r) +{ + NSVGmemPage* p = r->pages; + while (p != NULL) { + p->size = 0; + p = p->next; + } + r->curpage = r->pages; +} + +static unsigned char* nsvg__alloc(NSVGrasterizer* r, int size) +{ + unsigned char* buf; + if (size > NSVG__MEMPAGE_SIZE) return NULL; + if (r->curpage == NULL || r->curpage->size+size > NSVG__MEMPAGE_SIZE) { + r->curpage = nsvg__nextPage(r, r->curpage); + } + buf = &r->curpage->mem[r->curpage->size]; + r->curpage->size += size; + return buf; +} + +static int nsvg__ptEquals(float x1, float y1, float x2, float y2, float tol) +{ + float dx = x2 - x1; + float dy = y2 - y1; + return dx*dx + dy*dy < tol*tol; +} + +static void nsvg__addPathPoint(NSVGrasterizer* r, float x, float y, int flags) +{ + NSVGpoint* pt; + + if (r->npoints > 0) { + pt = &r->points[r->npoints-1]; + if (nsvg__ptEquals(pt->x,pt->y, x,y, r->distTol)) { + pt->flags = (unsigned char)(pt->flags | flags); + return; + } + } + + if (r->npoints+1 > r->cpoints) { + r->cpoints = r->cpoints > 0 ? r->cpoints * 2 : 64; + r->points = (NSVGpoint*)realloc(r->points, sizeof(NSVGpoint) * r->cpoints); + if (r->points == NULL) return; + } + + pt = &r->points[r->npoints]; + pt->x = x; + pt->y = y; + pt->flags = (unsigned char)flags; + r->npoints++; +} + +static void nsvg__appendPathPoint(NSVGrasterizer* r, NSVGpoint pt) +{ + if (r->npoints+1 > r->cpoints) { + r->cpoints = r->cpoints > 0 ? r->cpoints * 2 : 64; + r->points = (NSVGpoint*)realloc(r->points, sizeof(NSVGpoint) * r->cpoints); + if (r->points == NULL) return; + } + r->points[r->npoints] = pt; + r->npoints++; +} + +static void nsvg__duplicatePoints(NSVGrasterizer* r) +{ + if (r->npoints > r->cpoints2) { + r->cpoints2 = r->npoints; + r->points2 = (NSVGpoint*)realloc(r->points2, sizeof(NSVGpoint) * r->cpoints2); + if (r->points2 == NULL) return; + } + + memcpy(r->points2, r->points, sizeof(NSVGpoint) * r->npoints); + r->npoints2 = r->npoints; +} + +static void nsvg__addEdge(NSVGrasterizer* r, float x0, float y0, float x1, float y1) +{ + NSVGedge* e; + + // Skip horizontal edges + if (y0 == y1) + return; + + if (r->nedges+1 > r->cedges) { + r->cedges = r->cedges > 0 ? r->cedges * 2 : 64; + r->edges = (NSVGedge*)realloc(r->edges, sizeof(NSVGedge) * r->cedges); + if (r->edges == NULL) return; + } + + e = &r->edges[r->nedges]; + r->nedges++; + + if (y0 < y1) { + e->x0 = x0; + e->y0 = y0; + e->x1 = x1; + e->y1 = y1; + e->dir = 1; + } else { + e->x0 = x1; + e->y0 = y1; + e->x1 = x0; + e->y1 = y0; + e->dir = -1; + } +} + +static float nsvg__normalize(float *x, float* y) +{ + float d = sqrtf((*x)*(*x) + (*y)*(*y)); + if (d > 1e-6f) { + float id = 1.0f / d; + *x *= id; + *y *= id; + } + return d; +} + +static float nsvg__absf(float x) { return x < 0 ? -x : x; } + +static void nsvg__flattenCubicBez(NSVGrasterizer* r, + float x1, float y1, float x2, float y2, + float x3, float y3, float x4, float y4, + int level, int type) +{ + float x12,y12,x23,y23,x34,y34,x123,y123,x234,y234,x1234,y1234; + float dx,dy,d2,d3; + + if (level > 10) return; + + x12 = (x1+x2)*0.5f; + y12 = (y1+y2)*0.5f; + x23 = (x2+x3)*0.5f; + y23 = (y2+y3)*0.5f; + x34 = (x3+x4)*0.5f; + y34 = (y3+y4)*0.5f; + x123 = (x12+x23)*0.5f; + y123 = (y12+y23)*0.5f; + + dx = x4 - x1; + dy = y4 - y1; + d2 = nsvg__absf(((x2 - x4) * dy - (y2 - y4) * dx)); + d3 = nsvg__absf(((x3 - x4) * dy - (y3 - y4) * dx)); + + if ((d2 + d3)*(d2 + d3) < r->tessTol * (dx*dx + dy*dy)) { + nsvg__addPathPoint(r, x4, y4, type); + return; + } + + x234 = (x23+x34)*0.5f; + y234 = (y23+y34)*0.5f; + x1234 = (x123+x234)*0.5f; + y1234 = (y123+y234)*0.5f; + + nsvg__flattenCubicBez(r, x1,y1, x12,y12, x123,y123, x1234,y1234, level+1, 0); + nsvg__flattenCubicBez(r, x1234,y1234, x234,y234, x34,y34, x4,y4, level+1, type); +} + +static void nsvg__flattenShape(NSVGrasterizer* r, NSVGshape* shape, float scale) +{ + int i, j; + NSVGpath* path; + + for (path = shape->paths; path != NULL; path = path->next) { + r->npoints = 0; + // Flatten path + nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0); + for (i = 0; i < path->npts-1; i += 3) { + float* p = &path->pts[i*2]; + nsvg__flattenCubicBez(r, p[0]*scale,p[1]*scale, p[2]*scale,p[3]*scale, p[4]*scale,p[5]*scale, p[6]*scale,p[7]*scale, 0, 0); + } + // Close path + nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0); + // Build edges + for (i = 0, j = r->npoints-1; i < r->npoints; j = i++) + nsvg__addEdge(r, r->points[j].x, r->points[j].y, r->points[i].x, r->points[i].y); + } +} + +enum NSVGpointFlags +{ + NSVG_PT_CORNER = 0x01, + NSVG_PT_BEVEL = 0x02, + NSVG_PT_LEFT = 0x04 +}; + +static void nsvg__initClosed(NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth) +{ + float w = lineWidth * 0.5f; + float dx = p1->x - p0->x; + float dy = p1->y - p0->y; + float len = nsvg__normalize(&dx, &dy); + float px = p0->x + dx*len*0.5f, py = p0->y + dy*len*0.5f; + float dlx = dy, dly = -dx; + float lx = px - dlx*w, ly = py - dly*w; + float rx = px + dlx*w, ry = py + dly*w; + left->x = lx; left->y = ly; + right->x = rx; right->y = ry; +} + +static void nsvg__buttCap(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p, float dx, float dy, float lineWidth, int connect) +{ + float w = lineWidth * 0.5f; + float px = p->x, py = p->y; + float dlx = dy, dly = -dx; + float lx = px - dlx*w, ly = py - dly*w; + float rx = px + dlx*w, ry = py + dly*w; + + nsvg__addEdge(r, lx, ly, rx, ry); + + if (connect) { + nsvg__addEdge(r, left->x, left->y, lx, ly); + nsvg__addEdge(r, rx, ry, right->x, right->y); + } + left->x = lx; left->y = ly; + right->x = rx; right->y = ry; +} + +static void nsvg__squareCap(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p, float dx, float dy, float lineWidth, int connect) +{ + float w = lineWidth * 0.5f; + float px = p->x - dx*w, py = p->y - dy*w; + float dlx = dy, dly = -dx; + float lx = px - dlx*w, ly = py - dly*w; + float rx = px + dlx*w, ry = py + dly*w; + + nsvg__addEdge(r, lx, ly, rx, ry); + + if (connect) { + nsvg__addEdge(r, left->x, left->y, lx, ly); + nsvg__addEdge(r, rx, ry, right->x, right->y); + } + left->x = lx; left->y = ly; + right->x = rx; right->y = ry; +} + +#ifndef NSVG_PI +#define NSVG_PI (3.14159265358979323846264338327f) +#endif + +static void nsvg__roundCap(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p, float dx, float dy, float lineWidth, int ncap, int connect) +{ + int i; + float w = lineWidth * 0.5f; + float px = p->x, py = p->y; + float dlx = dy, dly = -dx; + float lx = 0, ly = 0, rx = 0, ry = 0, prevx = 0, prevy = 0; + + for (i = 0; i < ncap; i++) { + float a = (float)i/(float)(ncap-1)*NSVG_PI; + float ax = cosf(a) * w, ay = sinf(a) * w; + float x = px - dlx*ax - dx*ay; + float y = py - dly*ax - dy*ay; + + if (i > 0) + nsvg__addEdge(r, prevx, prevy, x, y); + + prevx = x; + prevy = y; + + if (i == 0) { + lx = x; ly = y; + } else if (i == ncap-1) { + rx = x; ry = y; + } + } + + if (connect) { + nsvg__addEdge(r, left->x, left->y, lx, ly); + nsvg__addEdge(r, rx, ry, right->x, right->y); + } + + left->x = lx; left->y = ly; + right->x = rx; right->y = ry; +} + +static void nsvg__bevelJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth) +{ + float w = lineWidth * 0.5f; + float dlx0 = p0->dy, dly0 = -p0->dx; + float dlx1 = p1->dy, dly1 = -p1->dx; + float lx0 = p1->x - (dlx0 * w), ly0 = p1->y - (dly0 * w); + float rx0 = p1->x + (dlx0 * w), ry0 = p1->y + (dly0 * w); + float lx1 = p1->x - (dlx1 * w), ly1 = p1->y - (dly1 * w); + float rx1 = p1->x + (dlx1 * w), ry1 = p1->y + (dly1 * w); + + nsvg__addEdge(r, lx0, ly0, left->x, left->y); + nsvg__addEdge(r, lx1, ly1, lx0, ly0); + + nsvg__addEdge(r, right->x, right->y, rx0, ry0); + nsvg__addEdge(r, rx0, ry0, rx1, ry1); + + left->x = lx1; left->y = ly1; + right->x = rx1; right->y = ry1; +} + +static void nsvg__miterJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth) +{ + float w = lineWidth * 0.5f; + float dlx0 = p0->dy, dly0 = -p0->dx; + float dlx1 = p1->dy, dly1 = -p1->dx; + float lx0, rx0, lx1, rx1; + float ly0, ry0, ly1, ry1; + + if (p1->flags & NSVG_PT_LEFT) { + lx0 = lx1 = p1->x - p1->dmx * w; + ly0 = ly1 = p1->y - p1->dmy * w; + nsvg__addEdge(r, lx1, ly1, left->x, left->y); + + rx0 = p1->x + (dlx0 * w); + ry0 = p1->y + (dly0 * w); + rx1 = p1->x + (dlx1 * w); + ry1 = p1->y + (dly1 * w); + nsvg__addEdge(r, right->x, right->y, rx0, ry0); + nsvg__addEdge(r, rx0, ry0, rx1, ry1); + } else { + lx0 = p1->x - (dlx0 * w); + ly0 = p1->y - (dly0 * w); + lx1 = p1->x - (dlx1 * w); + ly1 = p1->y - (dly1 * w); + nsvg__addEdge(r, lx0, ly0, left->x, left->y); + nsvg__addEdge(r, lx1, ly1, lx0, ly0); + + rx0 = rx1 = p1->x + p1->dmx * w; + ry0 = ry1 = p1->y + p1->dmy * w; + nsvg__addEdge(r, right->x, right->y, rx1, ry1); + } + + left->x = lx1; left->y = ly1; + right->x = rx1; right->y = ry1; +} + +static void nsvg__roundJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth, int ncap) +{ + int i, n; + float w = lineWidth * 0.5f; + float dlx0 = p0->dy, dly0 = -p0->dx; + float dlx1 = p1->dy, dly1 = -p1->dx; + float a0 = atan2f(dly0, dlx0); + float a1 = atan2f(dly1, dlx1); + float da = a1 - a0; + float lx, ly, rx, ry; + + if (da < NSVG_PI) da += NSVG_PI*2; + if (da > NSVG_PI) da -= NSVG_PI*2; + + n = (int)ceilf((nsvg__absf(da) / NSVG_PI) * (float)ncap); + if (n < 2) n = 2; + if (n > ncap) n = ncap; + + lx = left->x; + ly = left->y; + rx = right->x; + ry = right->y; + + for (i = 0; i < n; i++) { + float u = (float)i/(float)(n-1); + float a = a0 + u*da; + float ax = cosf(a) * w, ay = sinf(a) * w; + float lx1 = p1->x - ax, ly1 = p1->y - ay; + float rx1 = p1->x + ax, ry1 = p1->y + ay; + + nsvg__addEdge(r, lx1, ly1, lx, ly); + nsvg__addEdge(r, rx, ry, rx1, ry1); + + lx = lx1; ly = ly1; + rx = rx1; ry = ry1; + } + + left->x = lx; left->y = ly; + right->x = rx; right->y = ry; +} + +static void nsvg__straightJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p1, float lineWidth) +{ + float w = lineWidth * 0.5f; + float lx = p1->x - (p1->dmx * w), ly = p1->y - (p1->dmy * w); + float rx = p1->x + (p1->dmx * w), ry = p1->y + (p1->dmy * w); + + nsvg__addEdge(r, lx, ly, left->x, left->y); + nsvg__addEdge(r, right->x, right->y, rx, ry); + + left->x = lx; left->y = ly; + right->x = rx; right->y = ry; +} + +static int nsvg__curveDivs(float r, float arc, float tol) +{ + float da = acosf(r / (r + tol)) * 2.0f; + int divs = (int)ceilf(arc / da); + if (divs < 2) divs = 2; + return divs; +} + +static void nsvg__expandStroke(NSVGrasterizer* r, NSVGpoint* points, int npoints, int closed, int lineJoin, int lineCap, float lineWidth) +{ + int ncap = nsvg__curveDivs(lineWidth*0.5f, NSVG_PI, r->tessTol); // Calculate divisions per half circle. + NSVGpoint left = {0,0,0,0,0,0,0,0}, right = {0,0,0,0,0,0,0,0}, firstLeft = {0,0,0,0,0,0,0,0}, firstRight = {0,0,0,0,0,0,0,0}; + NSVGpoint* p0, *p1; + int j, s, e; + + // Build stroke edges + if (closed) { + // Looping + p0 = &points[npoints-1]; + p1 = &points[0]; + s = 0; + e = npoints; + } else { + // Add cap + p0 = &points[0]; + p1 = &points[1]; + s = 1; + e = npoints-1; + } + + if (closed) { + nsvg__initClosed(&left, &right, p0, p1, lineWidth); + firstLeft = left; + firstRight = right; + } else { + // Add cap + float dx = p1->x - p0->x; + float dy = p1->y - p0->y; + nsvg__normalize(&dx, &dy); + if (lineCap == NSVG_CAP_BUTT) + nsvg__buttCap(r, &left, &right, p0, dx, dy, lineWidth, 0); + else if (lineCap == NSVG_CAP_SQUARE) + nsvg__squareCap(r, &left, &right, p0, dx, dy, lineWidth, 0); + else if (lineCap == NSVG_CAP_ROUND) + nsvg__roundCap(r, &left, &right, p0, dx, dy, lineWidth, ncap, 0); + } + + for (j = s; j < e; ++j) { + if (p1->flags & NSVG_PT_CORNER) { + if (lineJoin == NSVG_JOIN_ROUND) + nsvg__roundJoin(r, &left, &right, p0, p1, lineWidth, ncap); + else if (lineJoin == NSVG_JOIN_BEVEL || (p1->flags & NSVG_PT_BEVEL)) + nsvg__bevelJoin(r, &left, &right, p0, p1, lineWidth); + else + nsvg__miterJoin(r, &left, &right, p0, p1, lineWidth); + } else { + nsvg__straightJoin(r, &left, &right, p1, lineWidth); + } + p0 = p1++; + } + + if (closed) { + // Loop it + nsvg__addEdge(r, firstLeft.x, firstLeft.y, left.x, left.y); + nsvg__addEdge(r, right.x, right.y, firstRight.x, firstRight.y); + } else { + // Add cap + float dx = p1->x - p0->x; + float dy = p1->y - p0->y; + nsvg__normalize(&dx, &dy); + if (lineCap == NSVG_CAP_BUTT) + nsvg__buttCap(r, &right, &left, p1, -dx, -dy, lineWidth, 1); + else if (lineCap == NSVG_CAP_SQUARE) + nsvg__squareCap(r, &right, &left, p1, -dx, -dy, lineWidth, 1); + else if (lineCap == NSVG_CAP_ROUND) + nsvg__roundCap(r, &right, &left, p1, -dx, -dy, lineWidth, ncap, 1); + } +} + +static void nsvg__prepareStroke(NSVGrasterizer* r, float miterLimit, int lineJoin) +{ + int i, j; + NSVGpoint* p0, *p1; + + p0 = &r->points[r->npoints-1]; + p1 = &r->points[0]; + for (i = 0; i < r->npoints; i++) { + // Calculate segment direction and length + p0->dx = p1->x - p0->x; + p0->dy = p1->y - p0->y; + p0->len = nsvg__normalize(&p0->dx, &p0->dy); + // Advance + p0 = p1++; + } + + // calculate joins + p0 = &r->points[r->npoints-1]; + p1 = &r->points[0]; + for (j = 0; j < r->npoints; j++) { + float dlx0, dly0, dlx1, dly1, dmr2, cross; + dlx0 = p0->dy; + dly0 = -p0->dx; + dlx1 = p1->dy; + dly1 = -p1->dx; + // Calculate extrusions + p1->dmx = (dlx0 + dlx1) * 0.5f; + p1->dmy = (dly0 + dly1) * 0.5f; + dmr2 = p1->dmx*p1->dmx + p1->dmy*p1->dmy; + if (dmr2 > 0.000001f) { + float s2 = 1.0f / dmr2; + if (s2 > 600.0f) { + s2 = 600.0f; + } + p1->dmx *= s2; + p1->dmy *= s2; + } + + // Clear flags, but keep the corner. + p1->flags = (p1->flags & NSVG_PT_CORNER) ? NSVG_PT_CORNER : 0; + + // Keep track of left turns. + cross = p1->dx * p0->dy - p0->dx * p1->dy; + if (cross > 0.0f) + p1->flags |= NSVG_PT_LEFT; + + // Check to see if the corner needs to be beveled. + if (p1->flags & NSVG_PT_CORNER) { + if ((dmr2 * miterLimit*miterLimit) < 1.0f || lineJoin == NSVG_JOIN_BEVEL || lineJoin == NSVG_JOIN_ROUND) { + p1->flags |= NSVG_PT_BEVEL; + } + } + + p0 = p1++; + } +} + +static void nsvg__flattenShapeStroke(NSVGrasterizer* r, NSVGshape* shape, float scale) +{ + int i, j, closed; + NSVGpath* path; + NSVGpoint* p0, *p1; + float miterLimit = shape->miterLimit; + int lineJoin = shape->strokeLineJoin; + int lineCap = shape->strokeLineCap; + float lineWidth = shape->strokeWidth * scale; + + for (path = shape->paths; path != NULL; path = path->next) { + // Flatten path + r->npoints = 0; + nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, NSVG_PT_CORNER); + for (i = 0; i < path->npts-1; i += 3) { + float* p = &path->pts[i*2]; + nsvg__flattenCubicBez(r, p[0]*scale,p[1]*scale, p[2]*scale,p[3]*scale, p[4]*scale,p[5]*scale, p[6]*scale,p[7]*scale, 0, NSVG_PT_CORNER); + } + if (r->npoints < 2) + continue; + + closed = path->closed; + + // If the first and last points are the same, remove the last, mark as closed path. + p0 = &r->points[r->npoints-1]; + p1 = &r->points[0]; + if (nsvg__ptEquals(p0->x,p0->y, p1->x,p1->y, r->distTol)) { + r->npoints--; + p0 = &r->points[r->npoints-1]; + closed = 1; + } + + if (shape->strokeDashCount > 0) { + int idash = 0, dashState = 1; + float totalDist = 0, dashLen, allDashLen, dashOffset; + NSVGpoint cur; + + if (closed) + nsvg__appendPathPoint(r, r->points[0]); + + // Duplicate points -> points2. + nsvg__duplicatePoints(r); + + r->npoints = 0; + cur = r->points2[0]; + nsvg__appendPathPoint(r, cur); + + // Figure out dash offset. + allDashLen = 0; + for (j = 0; j < shape->strokeDashCount; j++) + allDashLen += shape->strokeDashArray[j]; + if (shape->strokeDashCount & 1) + allDashLen *= 2.0f; + // Find location inside pattern + dashOffset = fmodf(shape->strokeDashOffset, allDashLen); + if (dashOffset < 0.0f) + dashOffset += allDashLen; + + while (dashOffset > shape->strokeDashArray[idash]) { + dashOffset -= shape->strokeDashArray[idash]; + idash = (idash + 1) % shape->strokeDashCount; + } + dashLen = (shape->strokeDashArray[idash] - dashOffset) * scale; + + for (j = 1; j < r->npoints2; ) { + float dx = r->points2[j].x - cur.x; + float dy = r->points2[j].y - cur.y; + float dist = sqrtf(dx*dx + dy*dy); + + if ((totalDist + dist) > dashLen) { + // Calculate intermediate point + float d = (dashLen - totalDist) / dist; + float x = cur.x + dx * d; + float y = cur.y + dy * d; + nsvg__addPathPoint(r, x, y, NSVG_PT_CORNER); + + // Stroke + if (r->npoints > 1 && dashState) { + nsvg__prepareStroke(r, miterLimit, lineJoin); + nsvg__expandStroke(r, r->points, r->npoints, 0, lineJoin, lineCap, lineWidth); + } + // Advance dash pattern + dashState = !dashState; + idash = (idash+1) % shape->strokeDashCount; + dashLen = shape->strokeDashArray[idash] * scale; + // Restart + cur.x = x; + cur.y = y; + cur.flags = NSVG_PT_CORNER; + totalDist = 0.0f; + r->npoints = 0; + nsvg__appendPathPoint(r, cur); + } else { + totalDist += dist; + cur = r->points2[j]; + nsvg__appendPathPoint(r, cur); + j++; + } + } + // Stroke any leftover path + if (r->npoints > 1 && dashState) + nsvg__expandStroke(r, r->points, r->npoints, 0, lineJoin, lineCap, lineWidth); + } else { + nsvg__prepareStroke(r, miterLimit, lineJoin); + nsvg__expandStroke(r, r->points, r->npoints, closed, lineJoin, lineCap, lineWidth); + } + } +} + +static int nsvg__cmpEdge(const void *p, const void *q) +{ + const NSVGedge* a = (const NSVGedge*)p; + const NSVGedge* b = (const NSVGedge*)q; + + if (a->y0 < b->y0) return -1; + if (a->y0 > b->y0) return 1; + return 0; +} + + +static NSVGactiveEdge* nsvg__addActive(NSVGrasterizer* r, NSVGedge* e, float startPoint) +{ + NSVGactiveEdge* z; + + if (r->freelist != NULL) { + // Restore from freelist. + z = r->freelist; + r->freelist = z->next; + } else { + // Alloc new edge. + z = (NSVGactiveEdge*)nsvg__alloc(r, sizeof(NSVGactiveEdge)); + if (z == NULL) return NULL; + } + + float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); +// STBTT_assert(e->y0 <= start_point); + // round dx down to avoid going too far + if (dxdy < 0) + z->dx = (int)(-floorf(NSVG__FIX * -dxdy)); + else + z->dx = (int)floorf(NSVG__FIX * dxdy); + z->x = (int)floorf(NSVG__FIX * (e->x0 + dxdy * (startPoint - e->y0))); +// z->x -= off_x * FIX; + z->ey = e->y1; + z->next = 0; + z->dir = e->dir; + + return z; +} + +static void nsvg__freeActive(NSVGrasterizer* r, NSVGactiveEdge* z) +{ + z->next = r->freelist; + r->freelist = z; +} + +static void nsvg__fillScanline(unsigned char* scanline, int len, int x0, int x1, int maxWeight, int* xmin, int* xmax) +{ + int i = x0 >> NSVG__FIXSHIFT; + int j = x1 >> NSVG__FIXSHIFT; + if (i < *xmin) *xmin = i; + if (j > *xmax) *xmax = j; + if (i < len && j >= 0) { + if (i == j) { + // x0,x1 are the same pixel, so compute combined coverage + scanline[i] = (unsigned char)(scanline[i] + ((x1 - x0) * maxWeight >> NSVG__FIXSHIFT)); + } else { + if (i >= 0) // add antialiasing for x0 + scanline[i] = (unsigned char)(scanline[i] + (((NSVG__FIX - (x0 & NSVG__FIXMASK)) * maxWeight) >> NSVG__FIXSHIFT)); + else + i = -1; // clip + + if (j < len) // add antialiasing for x1 + scanline[j] = (unsigned char)(scanline[j] + (((x1 & NSVG__FIXMASK) * maxWeight) >> NSVG__FIXSHIFT)); + else + j = len; // clip + + for (++i; i < j; ++i) // fill pixels between x0 and x1 + scanline[i] = (unsigned char)(scanline[i] + maxWeight); + } + } +} + +// note: this routine clips fills that extend off the edges... ideally this +// wouldn't happen, but it could happen if the truetype glyph bounding boxes +// are wrong, or if the user supplies a too-small bitmap +static void nsvg__fillActiveEdges(unsigned char* scanline, int len, NSVGactiveEdge* e, int maxWeight, int* xmin, int* xmax, char fillRule) +{ + // non-zero winding fill + int x0 = 0, w = 0; + + if (fillRule == NSVG_FILLRULE_NONZERO) { + // Non-zero + while (e != NULL) { + if (w == 0) { + // if we're currently at zero, we need to record the edge start point + x0 = e->x; w += e->dir; + } else { + int x1 = e->x; w += e->dir; + // if we went to zero, we need to draw + if (w == 0) + nsvg__fillScanline(scanline, len, x0, x1, maxWeight, xmin, xmax); + } + e = e->next; + } + } else if (fillRule == NSVG_FILLRULE_EVENODD) { + // Even-odd + while (e != NULL) { + if (w == 0) { + // if we're currently at zero, we need to record the edge start point + x0 = e->x; w = 1; + } else { + int x1 = e->x; w = 0; + nsvg__fillScanline(scanline, len, x0, x1, maxWeight, xmin, xmax); + } + e = e->next; + } + } +} + +static float nsvg__clampf(float a, float mn, float mx) { return a < mn ? mn : (a > mx ? mx : a); } + +static unsigned int nsvg__RGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a) +{ + return (r) | (g << 8) | (b << 16) | (a << 24); +} + +static unsigned int nsvg__lerpRGBA(unsigned int c0, unsigned int c1, float u) +{ + int iu = (int)(nsvg__clampf(u, 0.0f, 1.0f) * 256.0f); + int r = (((c0) & 0xff)*(256-iu) + (((c1) & 0xff)*iu)) >> 8; + int g = (((c0>>8) & 0xff)*(256-iu) + (((c1>>8) & 0xff)*iu)) >> 8; + int b = (((c0>>16) & 0xff)*(256-iu) + (((c1>>16) & 0xff)*iu)) >> 8; + int a = (((c0>>24) & 0xff)*(256-iu) + (((c1>>24) & 0xff)*iu)) >> 8; + return nsvg__RGBA((unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a); +} + +static unsigned int nsvg__applyOpacity(unsigned int c, float u) +{ + int iu = (int)(nsvg__clampf(u, 0.0f, 1.0f) * 256.0f); + int r = (c) & 0xff; + int g = (c>>8) & 0xff; + int b = (c>>16) & 0xff; + int a = (((c>>24) & 0xff)*iu) >> 8; + return nsvg__RGBA((unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a); +} + +static inline int nsvg__div255(int x) +{ + return ((x+1) * 257) >> 16; +} + +static void nsvg__scanlineSolid(unsigned char* dst, int count, unsigned char* cover, int x, int y, + float tx, float ty, float scale, NSVGcachedPaint* cache) +{ + + if (cache->type == NSVG_PAINT_COLOR) { + int i, cr, cg, cb, ca; + cr = cache->colors[0] & 0xff; + cg = (cache->colors[0] >> 8) & 0xff; + cb = (cache->colors[0] >> 16) & 0xff; + ca = (cache->colors[0] >> 24) & 0xff; + + for (i = 0; i < count; i++) { + int r,g,b; + int a = nsvg__div255((int)cover[0] * ca); + int ia = 255 - a; + // Premultiply + r = nsvg__div255(cr * a); + g = nsvg__div255(cg * a); + b = nsvg__div255(cb * a); + + // Blend over + r += nsvg__div255(ia * (int)dst[0]); + g += nsvg__div255(ia * (int)dst[1]); + b += nsvg__div255(ia * (int)dst[2]); + a += nsvg__div255(ia * (int)dst[3]); + + dst[0] = (unsigned char)r; + dst[1] = (unsigned char)g; + dst[2] = (unsigned char)b; + dst[3] = (unsigned char)a; + + cover++; + dst += 4; + } + } else if (cache->type == NSVG_PAINT_LINEAR_GRADIENT) { + // TODO: spread modes. + // TODO: plenty of opportunities to optimize. + float fx, fy, dx, gy; + float* t = cache->xform; + int i, cr, cg, cb, ca; + unsigned int c; + + fx = ((float)x - tx) / scale; + fy = ((float)y - ty) / scale; + dx = 1.0f / scale; + + for (i = 0; i < count; i++) { + int r,g,b,a,ia; + gy = fx*t[1] + fy*t[3] + t[5]; + c = cache->colors[(int)nsvg__clampf(gy*255.0f, 0, 255.0f)]; + cr = (c) & 0xff; + cg = (c >> 8) & 0xff; + cb = (c >> 16) & 0xff; + ca = (c >> 24) & 0xff; + + a = nsvg__div255((int)cover[0] * ca); + ia = 255 - a; + + // Premultiply + r = nsvg__div255(cr * a); + g = nsvg__div255(cg * a); + b = nsvg__div255(cb * a); + + // Blend over + r += nsvg__div255(ia * (int)dst[0]); + g += nsvg__div255(ia * (int)dst[1]); + b += nsvg__div255(ia * (int)dst[2]); + a += nsvg__div255(ia * (int)dst[3]); + + dst[0] = (unsigned char)r; + dst[1] = (unsigned char)g; + dst[2] = (unsigned char)b; + dst[3] = (unsigned char)a; + + cover++; + dst += 4; + fx += dx; + } + } else if (cache->type == NSVG_PAINT_RADIAL_GRADIENT) { + // TODO: spread modes. + // TODO: plenty of opportunities to optimize. + // TODO: focus (fx,fy) + float fx, fy, dx, gx, gy, gd; + float* t = cache->xform; + int i, cr, cg, cb, ca; + unsigned int c; + + fx = ((float)x - tx) / scale; + fy = ((float)y - ty) / scale; + dx = 1.0f / scale; + + for (i = 0; i < count; i++) { + int r,g,b,a,ia; + gx = fx*t[0] + fy*t[2] + t[4]; + gy = fx*t[1] + fy*t[3] + t[5]; + gd = sqrtf(gx*gx + gy*gy); + c = cache->colors[(int)nsvg__clampf(gd*255.0f, 0, 255.0f)]; + cr = (c) & 0xff; + cg = (c >> 8) & 0xff; + cb = (c >> 16) & 0xff; + ca = (c >> 24) & 0xff; + + a = nsvg__div255((int)cover[0] * ca); + ia = 255 - a; + + // Premultiply + r = nsvg__div255(cr * a); + g = nsvg__div255(cg * a); + b = nsvg__div255(cb * a); + + // Blend over + r += nsvg__div255(ia * (int)dst[0]); + g += nsvg__div255(ia * (int)dst[1]); + b += nsvg__div255(ia * (int)dst[2]); + a += nsvg__div255(ia * (int)dst[3]); + + dst[0] = (unsigned char)r; + dst[1] = (unsigned char)g; + dst[2] = (unsigned char)b; + dst[3] = (unsigned char)a; + + cover++; + dst += 4; + fx += dx; + } + } +} + +static void nsvg__rasterizeSortedEdges(NSVGrasterizer *r, float tx, float ty, float scale, NSVGcachedPaint* cache, char fillRule) +{ + NSVGactiveEdge *active = NULL; + int y, s; + int e = 0; + int maxWeight = (255 / NSVG__SUBSAMPLES); // weight per vertical scanline + int xmin, xmax; + + for (y = 0; y < r->height; y++) { + memset(r->scanline, 0, r->width); + xmin = r->width; + xmax = 0; + for (s = 0; s < NSVG__SUBSAMPLES; ++s) { + // find center of pixel for this scanline + float scany = (float)(y*NSVG__SUBSAMPLES + s) + 0.5f; + NSVGactiveEdge **step = &active; + + // update all active edges; + // remove all active edges that terminate before the center of this scanline + while (*step) { + NSVGactiveEdge *z = *step; + if (z->ey <= scany) { + *step = z->next; // delete from list +// NSVG__assert(z->valid); + nsvg__freeActive(r, z); + } else { + z->x += z->dx; // advance to position for current scanline + step = &((*step)->next); // advance through list + } + } + + // resort the list if needed + for (;;) { + int changed = 0; + step = &active; + while (*step && (*step)->next) { + if ((*step)->x > (*step)->next->x) { + NSVGactiveEdge* t = *step; + NSVGactiveEdge* q = t->next; + t->next = q->next; + q->next = t; + *step = q; + changed = 1; + } + step = &(*step)->next; + } + if (!changed) break; + } + + // insert all edges that start before the center of this scanline -- omit ones that also end on this scanline + while (e < r->nedges && r->edges[e].y0 <= scany) { + if (r->edges[e].y1 > scany) { + NSVGactiveEdge* z = nsvg__addActive(r, &r->edges[e], scany); + if (z == NULL) break; + // find insertion point + if (active == NULL) { + active = z; + } else if (z->x < active->x) { + // insert at front + z->next = active; + active = z; + } else { + // find thing to insert AFTER + NSVGactiveEdge* p = active; + while (p->next && p->next->x < z->x) + p = p->next; + // at this point, p->next->x is NOT < z->x + z->next = p->next; + p->next = z; + } + } + e++; + } + + // now process all active edges in non-zero fashion + if (active != NULL) + nsvg__fillActiveEdges(r->scanline, r->width, active, maxWeight, &xmin, &xmax, fillRule); + } + // Blit + if (xmin < 0) xmin = 0; + if (xmax > r->width-1) xmax = r->width-1; + if (xmin <= xmax) { + nsvg__scanlineSolid(&r->bitmap[y * r->stride] + xmin*4, xmax-xmin+1, &r->scanline[xmin], xmin, y, tx,ty, scale, cache); + } + } + +} + +static void nsvg__unpremultiplyAlpha(unsigned char* image, int w, int h, int stride) +{ + int x,y; + + // Unpremultiply + for (y = 0; y < h; y++) { + unsigned char *row = &image[y*stride]; + for (x = 0; x < w; x++) { + int r = row[0], g = row[1], b = row[2], a = row[3]; + if (a != 0) { + row[0] = (unsigned char)(r*255/a); + row[1] = (unsigned char)(g*255/a); + row[2] = (unsigned char)(b*255/a); + } + row += 4; + } + } + + // Defringe + for (y = 0; y < h; y++) { + unsigned char *row = &image[y*stride]; + for (x = 0; x < w; x++) { + int r = 0, g = 0, b = 0, a = row[3], n = 0; + if (a == 0) { + if (x-1 > 0 && row[-1] != 0) { + r += row[-4]; + g += row[-3]; + b += row[-2]; + n++; + } + if (x+1 < w && row[7] != 0) { + r += row[4]; + g += row[5]; + b += row[6]; + n++; + } + if (y-1 > 0 && row[-stride+3] != 0) { + r += row[-stride]; + g += row[-stride+1]; + b += row[-stride+2]; + n++; + } + if (y+1 < h && row[stride+3] != 0) { + r += row[stride]; + g += row[stride+1]; + b += row[stride+2]; + n++; + } + if (n > 0) { + row[0] = (unsigned char)(r/n); + row[1] = (unsigned char)(g/n); + row[2] = (unsigned char)(b/n); + } + } + row += 4; + } + } +} + + +static void nsvg__initPaint(NSVGcachedPaint* cache, NSVGpaint* paint, float opacity) +{ + int i, j; + NSVGgradient* grad; + + cache->type = paint->type; + + if (paint->type == NSVG_PAINT_COLOR) { + cache->colors[0] = nsvg__applyOpacity(paint->color, opacity); + return; + } + + grad = paint->gradient; + + cache->spread = grad->spread; + memcpy(cache->xform, grad->xform, sizeof(float)*6); + + if (grad->nstops == 0) { + for (i = 0; i < 256; i++) + cache->colors[i] = 0; + } if (grad->nstops == 1) { + for (i = 0; i < 256; i++) + cache->colors[i] = nsvg__applyOpacity(grad->stops[i].color, opacity); + } else { + unsigned int ca, cb = 0; + float ua, ub, du, u; + int ia, ib, count; + + ca = nsvg__applyOpacity(grad->stops[0].color, opacity); + ua = nsvg__clampf(grad->stops[0].offset, 0, 1); + ub = nsvg__clampf(grad->stops[grad->nstops-1].offset, ua, 1); + ia = (int)(ua * 255.0f); + ib = (int)(ub * 255.0f); + for (i = 0; i < ia; i++) { + cache->colors[i] = ca; + } + + for (i = 0; i < grad->nstops-1; i++) { + ca = nsvg__applyOpacity(grad->stops[i].color, opacity); + cb = nsvg__applyOpacity(grad->stops[i+1].color, opacity); + ua = nsvg__clampf(grad->stops[i].offset, 0, 1); + ub = nsvg__clampf(grad->stops[i+1].offset, 0, 1); + ia = (int)(ua * 255.0f); + ib = (int)(ub * 255.0f); + count = ib - ia; + if (count <= 0) continue; + u = 0; + du = 1.0f / (float)count; + for (j = 0; j < count; j++) { + cache->colors[ia+j] = nsvg__lerpRGBA(ca,cb,u); + u += du; + } + } + + for (i = ib; i < 256; i++) + cache->colors[i] = cb; + } + +} + +/* +static void dumpEdges(NSVGrasterizer* r, const char* name) +{ + float xmin = 0, xmax = 0, ymin = 0, ymax = 0; + NSVGedge *e = NULL; + int i; + if (r->nedges == 0) return; + FILE* fp = fopen(name, "w"); + if (fp == NULL) return; + + xmin = xmax = r->edges[0].x0; + ymin = ymax = r->edges[0].y0; + for (i = 0; i < r->nedges; i++) { + e = &r->edges[i]; + xmin = nsvg__minf(xmin, e->x0); + xmin = nsvg__minf(xmin, e->x1); + xmax = nsvg__maxf(xmax, e->x0); + xmax = nsvg__maxf(xmax, e->x1); + ymin = nsvg__minf(ymin, e->y0); + ymin = nsvg__minf(ymin, e->y1); + ymax = nsvg__maxf(ymax, e->y0); + ymax = nsvg__maxf(ymax, e->y1); + } + + fprintf(fp, "", xmin, ymin, (xmax - xmin), (ymax - ymin)); + + for (i = 0; i < r->nedges; i++) { + e = &r->edges[i]; + fprintf(fp ,"", e->x0,e->y0, e->x1,e->y1); + } + + for (i = 0; i < r->npoints; i++) { + if (i+1 < r->npoints) + fprintf(fp ,"", r->points[i].x, r->points[i].y, r->points[i+1].x, r->points[i+1].y); + fprintf(fp ,"", r->points[i].x, r->points[i].y, r->points[i].flags == 0 ? "#f00" : "#0f0"); + } + + fprintf(fp, ""); + fclose(fp); +} +*/ + +void nsvgRasterize(NSVGrasterizer* r, + NSVGimage* image, float tx, float ty, float scale, + unsigned char* dst, int w, int h, int stride) +{ + NSVGshape *shape = NULL; + NSVGedge *e = NULL; + NSVGcachedPaint cache; + int i; + + r->bitmap = dst; + r->width = w; + r->height = h; + r->stride = stride; + + if (w > r->cscanline) { + r->cscanline = w; + r->scanline = (unsigned char*)realloc(r->scanline, w); + if (r->scanline == NULL) return; + } + + for (i = 0; i < h; i++) + memset(&dst[i*stride], 0, w*4); + + for (shape = image->shapes; shape != NULL; shape = shape->next) { + if (!(shape->flags & NSVG_FLAGS_VISIBLE)) + continue; + + if (shape->fill.type != NSVG_PAINT_NONE) { + nsvg__resetPool(r); + r->freelist = NULL; + r->nedges = 0; + + nsvg__flattenShape(r, shape, scale); + + // Scale and translate edges + for (i = 0; i < r->nedges; i++) { + e = &r->edges[i]; + e->x0 = tx + e->x0; + e->y0 = (ty + e->y0) * NSVG__SUBSAMPLES; + e->x1 = tx + e->x1; + e->y1 = (ty + e->y1) * NSVG__SUBSAMPLES; + } + + // Rasterize edges + qsort(r->edges, r->nedges, sizeof(NSVGedge), nsvg__cmpEdge); + + // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule + nsvg__initPaint(&cache, &shape->fill, shape->opacity); + + nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache, shape->fillRule); + } + if (shape->stroke.type != NSVG_PAINT_NONE && (shape->strokeWidth * scale) > 0.01f) { + nsvg__resetPool(r); + r->freelist = NULL; + r->nedges = 0; + + nsvg__flattenShapeStroke(r, shape, scale); + +// dumpEdges(r, "edge.svg"); + + // Scale and translate edges + for (i = 0; i < r->nedges; i++) { + e = &r->edges[i]; + e->x0 = tx + e->x0; + e->y0 = (ty + e->y0) * NSVG__SUBSAMPLES; + e->x1 = tx + e->x1; + e->y1 = (ty + e->y1) * NSVG__SUBSAMPLES; + } + + // Rasterize edges + qsort(r->edges, r->nedges, sizeof(NSVGedge), nsvg__cmpEdge); + + // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule + nsvg__initPaint(&cache, &shape->stroke, shape->opacity); + + nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache, NSVG_FILLRULE_NONZERO); + } + } + + nsvg__unpremultiplyAlpha(dst, w, h, stride); + + r->bitmap = NULL; + r->width = 0; + r->height = 0; + r->stride = 0; +} + +#endif