ref: 1a00aedb656315d215df71d12442044d4e5b8a51
dir: /svg.c/
#include <u.h> #include <libc.h> #include <draw.h> #include <event.h> #include <keyboard.h> #include <stdio.h> #define NANOSVG_ALL_COLOR_KEYWORDS #define NANOSVG_IMPLEMENTATION #include "nanosvg.h" #define NANOSVGRAST_IMPLEMENTATION #include "nanosvgrast.h" char* filename; Image *svg; int nineflag, w, h, sz; uchar *data; void rasterize(int scale) { NSVGimage *image; NSVGrasterizer *rast; float s, sx, sy, tx, ty; Rectangle r; image = nsvgParseFromFile(filename, "px", 96); if(image==nil) sysfatal("svg parse: %r"); w = image->width; h = image->height; s = 1.0f; if(scale){ r = insetrect(screen->r, 10); w = Dx(r); h = Dy(r); sx = (float)w/(image->width+0.5); sy = (float)h/(image->height+0.5); s = (sx < sy) ? sx : sy; } rast = nsvgCreateRasterizer(); if(rast==nil) sysfatal("create rasterizer: %r"); sz = w*h*4; data = malloc(sz); if(data==nil) sysfatal("malloc: %r"); nsvgRasterize(rast, image, 0, 0, s, data, w, h, w*4); nsvgDelete(image); nsvgDeleteRasterizer(rast); if(nineflag) return; svg = allocimage(display, Rect(0, 0, w, h), ABGR32, 0, DNofill); if(svg==nil) sysfatal("allocimage: %r"); if(loadimage(svg, svg->r, data, sz)<sz) sysfatal("loadimage: %r"); } void eresized(int new) { Point p; if(new && getwindow(display, Refnone)<0) sysfatal("cannot reattach: %r"); freeimage(svg); rasterize(1); p.x = (Dx(screen->r) - Dx(svg->r))/2; p.y = (Dy(screen->r) - Dy(svg->r))/2; draw(screen, screen->r, display->white, nil, ZP); draw(screen, rectaddpt(screen->r, p), svg, nil, ZP); } void usage(void) { fprint(2, "usage: %s [-9] [file.svg]\n", argv0); } void main(int argc, char *argv[]) { Event e; int ev; char buf[12+1]; ARGBEGIN{ case 't': /* page compatibility */ break; case '9': nineflag++; break; default: fprint(2, "invalid flag '%c'\n", ARGC()); usage(); exits("usage"); }ARGEND if(*argv==nil) filename = "/fd/0"; else filename = *argv; if(nineflag){ rasterize(0); chantostr(buf, ABGR32); print("%11s %11d %11d %11d %11d ", buf, 0, 0, w, h); if(write(1, data, sz) != sz) sysfatal("write: %r\n"); exits(nil); } if(initdraw(nil, nil, "svg")<0) sysfatal("initdraw: %r"); einit(Emouse|Ekeyboard); eresized(0); for(;;){ ev = event(&e); switch(ev){ case Ekeyboard: if(e.kbdc=='q' || e.kbdc==Kdel) exits(nil); break; case Emouse: break; } } }