35 #ifndef NANOSVG_CPLUSPLUS
166 #ifndef NANOSVG_CPLUSPLUS
174 #ifdef NANOSVG_IMPLEMENTATION
180 #define NSVG_PI (3.14159265358979323846264338327f)
181 #define NSVG_KAPPA90 \
184 #define NSVG_ALIGN_MIN 0
185 #define NSVG_ALIGN_MID 1
186 #define NSVG_ALIGN_MAX 2
187 #define NSVG_ALIGN_NONE 0
188 #define NSVG_ALIGN_MEET 1
189 #define NSVG_ALIGN_SLICE 2
191 #define NSVG_NOTUSED(v) \
193 (void)(1 ? (void)0 : ((void)(v))); \
195 #define NSVG_RGB(r, g, b) (((unsigned int)r) | ((unsigned int)g << 8) | ((unsigned int)b << 16))
198 # pragma warning(disable : 4996)
199 # pragma warning(disable : 4100)
201 # define NSVG_INLINE inline
206 # define NSVG_INLINE inline
209 static int nsvg__isspace(
char c)
211 return strchr(
" \t\n\v\f\r",
c) != 0;
214 static int nsvg__isdigit(
char c)
216 return c >=
'0' &&
c <=
'9';
219 static NSVG_INLINE
float nsvg__minf(
float a,
float b)
221 return a < b ?
a : b;
223 static NSVG_INLINE
float nsvg__maxf(
float a,
float b)
225 return a > b ?
a : b;
230 #define NSVG_XML_TAG 1
231 #define NSVG_XML_CONTENT 2
232 #define NSVG_XML_MAX_ATTRIBS 256
234 static void nsvg__parseContent(
char *s,
void (*contentCb)(
void *ud,
const char *s),
void *ud)
237 while (*s && nsvg__isspace(*s))
246 static void nsvg__parseElement(
char *s,
247 void (*startelCb)(
void *ud,
const char *el,
const char **attr),
248 void (*endelCb)(
void *ud,
const char *el),
251 const char *attr[NSVG_XML_MAX_ATTRIBS];
259 while (*s && nsvg__isspace(*s))
272 if (!*s || *s ==
'?' || *s ==
'!')
277 while (*s && !nsvg__isspace(*s))
284 while (!end && *s && nattr < NSVG_XML_MAX_ATTRIBS - 3) {
289 while (*s && nsvg__isspace(*s))
299 while (*s && !nsvg__isspace(*s) && *s !=
'=')
305 while (*s && *s !=
'\"' && *s !=
'\'')
313 while (*s && *s != quote)
321 attr[nattr++] = name;
322 attr[nattr++] = value;
331 if (start && startelCb)
332 (*startelCb)(ud, name, attr);
334 (*endelCb)(ud, name);
337 static int nsvg__parseXML(
char *input,
338 void (*startelCb)(
void *ud,
const char *el,
const char **attr),
339 void (*endelCb)(
void *ud,
const char *el),
340 void (*contentCb)(
void *ud,
const char *s),
345 int state = NSVG_XML_CONTENT;
347 if (*s ==
'<' &&
state == NSVG_XML_CONTENT) {
350 nsvg__parseContent(mark, contentCb, ud);
352 state = NSVG_XML_TAG;
354 else if (*s ==
'>' &&
state == NSVG_XML_TAG) {
357 nsvg__parseElement(mark, startelCb, endelCb, ud);
359 state = NSVG_XML_CONTENT;
371 #define NSVG_MAX_ATTR 128
372 #define NSVG_MAX_BREADCRUMB 5
374 enum NSVGgradientUnits { NSVG_USER_SPACE = 0, NSVG_OBJECT_SPACE = 1 };
376 #define NSVG_MAX_DASHES 8
391 typedef struct NSVGcoordinate {
396 typedef struct NSVGlinearData {
397 NSVGcoordinate x1,
y1,
x2, y2;
400 typedef struct NSVGradialData {
401 NSVGcoordinate cx, cy,
r, fx, fy;
404 typedef struct NSVGgradientData {
409 NSVGlinearData linear;
410 NSVGradialData radial;
417 struct NSVGgradientData *
next;
420 typedef struct NSVGattrib {
423 unsigned int fillColor;
424 unsigned int strokeColor;
428 char fillGradient[64];
429 char strokeGradient[64];
431 float strokeDashOffset;
432 float strokeDashArray[NSVG_MAX_DASHES];
439 unsigned int stopColor;
447 typedef struct NSVGparser {
448 NSVGattrib attr[NSVG_MAX_ATTR];
455 NSVGgradientData *gradients;
457 float viewMinx, viewMiny, viewWidth, viewHeight;
458 int alignX, alignY, alignType;
463 char breadcrumb[NSVG_MAX_BREADCRUMB][64];
468 static void nsvg__xformIdentity(
float *
t)
478 static void nsvg__xformSetTranslation(
float *
t,
float tx,
float ty)
488 static void nsvg__xformSetScale(
float *
t,
float sx,
float sy)
498 static void nsvg__xformSetSkewX(
float *
t,
float a)
508 static void nsvg__xformSetSkewY(
float *
t,
float a)
518 static void nsvg__xformSetRotation(
float *
t,
float a)
529 static void nsvg__xformMultiply(
float *
t,
float *s)
531 float t0 =
t[0] * s[0] +
t[1] * s[2];
532 float t2 =
t[2] * s[0] +
t[3] * s[2];
533 float t4 =
t[4] * s[0] +
t[5] * s[2] + s[4];
534 t[1] =
t[0] * s[1] +
t[1] * s[3];
535 t[3] =
t[2] * s[1] +
t[3] * s[3];
536 t[5] =
t[4] * s[1] +
t[5] * s[3] + s[5];
542 static void nsvg__xformInverse(
float *inv,
float *
t)
544 double invdet, det = (
double)
t[0] *
t[3] - (
double)
t[2] *
t[1];
545 if (det > -1
e-6 && det < 1
e-6) {
546 nsvg__xformIdentity(
t);
550 inv[0] = (
float)(
t[3] * invdet);
551 inv[2] = (
float)(-
t[2] * invdet);
552 inv[4] = (
float)(((
double)
t[2] *
t[5] - (
double)
t[3] *
t[4]) * invdet);
553 inv[1] = (
float)(-
t[1] * invdet);
554 inv[3] = (
float)(
t[0] * invdet);
555 inv[5] = (
float)(((
double)
t[1] *
t[4] - (
double)
t[0] *
t[5]) * invdet);
558 static void nsvg__xformPremultiply(
float *
t,
float *s)
561 memcpy(s2, s,
sizeof(
float) * 6);
562 nsvg__xformMultiply(s2,
t);
563 memcpy(
t, s2,
sizeof(
float) * 6);
566 static void nsvg__xformPoint(
float *dx,
float *dy,
float x,
float y,
float *
t)
568 *dx =
x *
t[0] +
y *
t[2] +
t[4];
569 *dy =
x *
t[1] +
y *
t[3] +
t[5];
572 static void nsvg__xformVec(
float *dx,
float *dy,
float x,
float y,
float *
t)
574 *dx =
x *
t[0] +
y *
t[2];
575 *dy =
x *
t[1] +
y *
t[3];
578 #define NSVG_EPSILON (1e-12)
580 static int nsvg__ptInBounds(
float *pt,
float *
bounds)
585 static double nsvg__evalBezier(
double t,
double p0,
double p1,
double p2,
double p3)
588 return it * it * it * p0 + 3.0 * it * it *
t * p1 + 3.0 * it *
t *
t * p2 +
t *
t *
t * p3;
591 static void nsvg__curveBounds(
float *
bounds,
float *
curve)
594 double roots[2],
a, b,
c, b2ac,
t,
v;
595 float *v0 = &
curve[0];
598 float *v3 = &
curve[6];
601 bounds[0] = nsvg__minf(v0[0], v3[0]);
602 bounds[1] = nsvg__minf(v0[1], v3[1]);
603 bounds[2] = nsvg__maxf(v0[0], v3[0]);
604 bounds[3] = nsvg__maxf(v0[1], v3[1]);
612 for (i = 0; i < 2; i++) {
613 a = -3.0 * v0[i] + 9.0 *
v1[i] - 9.0 *
v2[i] + 3.0 * v3[i];
614 b = 6.0 * v0[i] - 12.0 *
v1[i] + 6.0 *
v2[i];
615 c = 3.0 *
v1[i] - 3.0 * v0[i];
617 if (
fabs(
a) < NSVG_EPSILON) {
618 if (
fabs(b) > NSVG_EPSILON) {
620 if (
t > NSVG_EPSILON &&
t < 1.0 - NSVG_EPSILON)
625 b2ac = b * b - 4.0 *
c *
a;
626 if (b2ac > NSVG_EPSILON) {
627 t = (-b +
sqrt(b2ac)) / (2.0 *
a);
628 if (
t > NSVG_EPSILON &&
t < 1.0 - NSVG_EPSILON)
630 t = (-b -
sqrt(b2ac)) / (2.0 *
a);
631 if (
t > NSVG_EPSILON &&
t < 1.0 - NSVG_EPSILON)
635 for (j = 0; j <
count; j++) {
636 v = nsvg__evalBezier(roots[j], v0[i],
v1[i],
v2[i], v3[i]);
643 static NSVGparser *nsvg__createParser()
646 p = (NSVGparser *)malloc(
sizeof(NSVGparser));
649 memset(p, 0,
sizeof(NSVGparser));
652 if (p->image ==
NULL)
657 nsvg__xformIdentity(p->attr[0].xform);
658 memset(p->attr[0].id, 0,
sizeof p->attr[0].id);
659 p->attr[0].fillColor = NSVG_RGB(0, 0, 0);
660 p->attr[0].strokeColor = NSVG_RGB(0, 0, 0);
661 p->attr[0].opacity = 1;
662 p->attr[0].fillOpacity = 1;
663 p->attr[0].strokeOpacity = 1;
664 p->attr[0].stopOpacity = 1;
665 p->attr[0].strokeWidth = 1;
668 p->attr[0].miterLimit = 4;
670 p->attr[0].hasFill = 1;
671 p->attr[0].visible = 1;
684 static void nsvg__deletePaths(
NSVGpath *path)
695 static void nsvg__deletePaint(
NSVGpaint *paint)
701 static void nsvg__deleteGradientData(NSVGgradientData *
grad)
703 NSVGgradientData *
next;
712 static void nsvg__deleteParser(NSVGparser *p)
715 nsvg__deletePaths(p->plist);
716 nsvg__deleteGradientData(p->gradients);
723 static void nsvg__resetPath(NSVGparser *p)
728 static void nsvg__addPoint(NSVGparser *p,
float x,
float y)
730 if (p->npts + 1 > p->cpts) {
731 p->cpts = p->cpts ? p->cpts * 2 : 8;
732 p->pts = (
float *)realloc(p->pts, p->cpts * 2 *
sizeof(
float));
736 p->pts[p->npts * 2 + 0] =
x;
737 p->pts[p->npts * 2 + 1] =
y;
741 static void nsvg__moveTo(NSVGparser *p,
float x,
float y)
744 p->pts[(p->npts - 1) * 2 + 0] =
x;
745 p->pts[(p->npts - 1) * 2 + 1] =
y;
748 nsvg__addPoint(p,
x,
y);
752 static void nsvg__lineTo(NSVGparser *p,
float x,
float y)
754 float px, py, dx, dy;
756 px = p->pts[(p->npts - 1) * 2 + 0];
757 py = p->pts[(p->npts - 1) * 2 + 1];
760 nsvg__addPoint(p, px + dx / 3.0f, py + dy / 3.0f);
761 nsvg__addPoint(p,
x - dx / 3.0f,
y - dy / 3.0f);
762 nsvg__addPoint(p,
x,
y);
766 static void nsvg__cubicBezTo(
767 NSVGparser *p,
float cpx1,
float cpy1,
float cpx2,
float cpy2,
float x,
float y)
770 nsvg__addPoint(p, cpx1, cpy1);
771 nsvg__addPoint(p, cpx2, cpy2);
772 nsvg__addPoint(p,
x,
y);
776 static NSVGattrib *nsvg__getAttr(NSVGparser *p)
778 return &p->attr[p->attrHead];
781 static void nsvg__pushAttr(NSVGparser *p)
783 if (p->attrHead < NSVG_MAX_ATTR - 1) {
785 memcpy(&p->attr[p->attrHead], &p->attr[p->attrHead - 1],
sizeof(NSVGattrib));
789 static void nsvg__popAttr(NSVGparser *p)
795 static float nsvg__actualOrigX(NSVGparser *p)
800 static float nsvg__actualOrigY(NSVGparser *p)
805 static float nsvg__actualWidth(NSVGparser *p)
810 static float nsvg__actualHeight(NSVGparser *p)
812 return p->viewHeight;
815 static float nsvg__actualLength(NSVGparser *p)
817 float w = nsvg__actualWidth(p), h = nsvg__actualHeight(p);
821 static float nsvg__convertToPixels(NSVGparser *p, NSVGcoordinate
c,
float orig,
float length)
823 NSVGattrib *attr = nsvg__getAttr(p);
825 case NSVG_UNITS_USER:
830 return c.value / 72.0f * p->dpi;
832 return c.value / 6.0f * p->dpi;
834 return c.value / 25.4f * p->dpi;
836 return c.value / 2.54f * p->dpi;
838 return c.value * p->dpi;
840 return c.value * attr->fontSize;
842 return c.value * attr->fontSize * 0.52f;
843 case NSVG_UNITS_PERCENT:
844 return orig +
c.value / 100.0f *
length;
851 static NSVGgradientData *nsvg__findGradientData(NSVGparser *p,
const char *
id)
853 NSVGgradientData *
grad = p->gradients;
854 if (
id ==
NULL || *
id ==
'\0')
857 if (strcmp(
grad->id,
id) == 0)
864 static NSVGgradient *nsvg__createGradient(NSVGparser *p,
866 const float *localBounds,
869 NSVGattrib *attr = nsvg__getAttr(p);
871 NSVGgradientData *ref =
NULL;
874 float ox, oy, sw, sh, sl;
878 data = nsvg__findGradientData(p,
id);
885 while (ref !=
NULL) {
886 NSVGgradientData *nextRef =
NULL;
887 if (stops ==
NULL && ref->stops !=
NULL) {
889 nstops = ref->nstops;
892 nextRef = nsvg__findGradientData(p, ref->ref);
908 if (
data->units == NSVG_OBJECT_SPACE) {
911 sw = localBounds[2] - localBounds[0];
912 sh = localBounds[3] - localBounds[1];
915 ox = nsvg__actualOrigX(p);
916 oy = nsvg__actualOrigY(p);
917 sw = nsvg__actualWidth(p);
918 sh = nsvg__actualHeight(p);
923 float x1,
y1,
x2, y2, dx, dy;
924 x1 = nsvg__convertToPixels(p,
data->linear.x1, ox, sw);
925 y1 = nsvg__convertToPixels(p,
data->linear.y1, oy, sh);
926 x2 = nsvg__convertToPixels(p,
data->linear.x2, ox, sw);
927 y2 = nsvg__convertToPixels(p,
data->linear.y2, oy, sh);
932 grad->xform[1] = -dx;
939 float cx, cy, fx, fy,
r;
940 cx = nsvg__convertToPixels(p,
data->radial.cx, ox, sw);
941 cy = nsvg__convertToPixels(p,
data->radial.cy, oy, sh);
942 fx = nsvg__convertToPixels(p,
data->radial.fx, ox, sw);
943 fy = nsvg__convertToPixels(p,
data->radial.fy, oy, sh);
944 r = nsvg__convertToPixels(p,
data->radial.r, 0, sl);
956 nsvg__xformMultiply(
grad->xform,
data->xform);
957 nsvg__xformMultiply(
grad->xform, attr->xform);
961 grad->nstops = nstops;
963 *paintType =
data->type;
968 static float nsvg__getAverageScale(
float *
t)
970 float sx =
sqrtf(
t[0] *
t[0] +
t[2] *
t[2]);
971 float sy =
sqrtf(
t[1] *
t[1] +
t[3] *
t[3]);
972 return (sx + sy) * 0.5f;
975 static void nsvg__getLocalBounds(
float *
bounds,
NSVGshape *shape,
float *xform)
978 float curve[4 * 2], curveBounds[4];
982 for (i = 0; i < path->
npts - 1; i += 3) {
984 &
curve[2], &
curve[3], path->
pts[(i + 1) * 2], path->
pts[(i + 1) * 2 + 1], xform);
986 &
curve[4], &
curve[5], path->
pts[(i + 2) * 2], path->
pts[(i + 2) * 2 + 1], xform);
988 &
curve[6], &
curve[7], path->
pts[(i + 3) * 2], path->
pts[(i + 3) * 2 + 1], xform);
989 nsvg__curveBounds(curveBounds,
curve);
991 bounds[0] = curveBounds[0];
992 bounds[1] = curveBounds[1];
993 bounds[2] = curveBounds[2];
994 bounds[3] = curveBounds[3];
1009 static void nsvg__addShape(NSVGparser *p)
1011 NSVGattrib *attr = nsvg__getAttr(p);
1017 if (p->plist ==
NULL)
1025 memcpy(shape->
id, attr->id,
sizeof shape->
id);
1027 if (p->breadcrumb_len > 0) {
1034 scale = nsvg__getAverageScale(attr->xform);
1038 for (i = 0; i < attr->strokeDashCount; i++)
1044 shape->
opacity = attr->opacity;
1046 shape->
paths = p->plist;
1062 if (attr->hasFill == 0) {
1065 else if (attr->hasFill == 1) {
1068 shape->
fill.
color |= (
unsigned int)(attr->fillOpacity * 255) << 24;
1070 else if (attr->hasFill == 2) {
1071 float inv[6], localBounds[4];
1072 nsvg__xformInverse(inv, attr->xform);
1073 nsvg__getLocalBounds(localBounds, shape, inv);
1075 p, attr->fillGradient, localBounds, &shape->
fill.
type);
1082 if (attr->hasStroke == 0) {
1085 else if (attr->hasStroke == 1) {
1088 shape->
stroke.
color |= (
unsigned int)(attr->strokeOpacity * 255) << 24;
1090 else if (attr->hasStroke == 2) {
1091 float inv[6], localBounds[4];
1092 nsvg__xformInverse(inv, attr->xform);
1093 nsvg__getLocalBounds(localBounds, shape, inv);
1095 p, attr->strokeGradient, localBounds, &shape->
stroke.
type);
1104 if (p->image->shapes ==
NULL)
1105 p->image->shapes = shape;
1107 p->shapesTail->
next = shape;
1108 p->shapesTail = shape;
1117 static void nsvg__addPath(NSVGparser *p,
char closed)
1119 NSVGattrib *attr = nsvg__getAttr(p);
1129 nsvg__lineTo(p, p->pts[0], p->pts[1]);
1132 if ((p->npts % 3) != 1)
1140 path->
pts = (
float *)malloc(p->npts * 2 *
sizeof(
float));
1144 path->
npts = p->npts;
1147 for (i = 0; i < p->npts; ++i)
1149 &path->
pts[i * 2], &path->
pts[i * 2 + 1], p->pts[i * 2], p->pts[i * 2 + 1], attr->xform);
1152 for (i = 0; i < path->
npts - 1; i += 3) {
1169 path->
next = p->plist;
1183 static double nsvg__atof(
const char *s)
1185 char *cur = (
char *)s;
1187 double res = 0.0,
sign = 1.0;
1188 long long intPart = 0, fracPart = 0;
1189 char hasIntPart = 0, hasFracPart = 0;
1195 else if (*cur ==
'-') {
1201 if (nsvg__isdigit(*cur)) {
1203 intPart = strtoll(cur, &end, 10);
1214 if (nsvg__isdigit(*cur)) {
1216 fracPart = strtoll(cur, &end, 10);
1218 res += (
double)fracPart /
pow(10.0, (
double)(end - cur));
1226 if (!hasIntPart && !hasFracPart)
1230 if (*cur ==
'e' || *cur ==
'E') {
1233 expPart = strtol(cur, &end, 10);
1235 res *=
pow(10.0, (
double)expPart);
1242 static const char *nsvg__parseNumber(
const char *s,
char *it,
const int size)
1244 const int last =
size - 1;
1248 if (*s ==
'-' || *s ==
'+') {
1254 while (*s && nsvg__isdigit(*s)) {
1265 while (*s && nsvg__isdigit(*s)) {
1272 if ((*s ==
'e' || *s ==
'E') && (s[1] !=
'm' && s[1] !=
'x')) {
1276 if (*s ==
'-' || *s ==
'+') {
1281 while (*s && nsvg__isdigit(*s)) {
1292 static const char *nsvg__getNextPathItem(
const char *s,
char *it)
1296 while (*s && (nsvg__isspace(*s) || *s ==
','))
1300 if (*s ==
'-' || *s ==
'+' || *s ==
'.' || nsvg__isdigit(*s)) {
1301 s = nsvg__parseNumber(s, it, 64);
1313 static unsigned int nsvg__parseColorHex(
const char *
str)
1315 unsigned int c = 0,
r = 0, g = 0, b = 0;
1319 while (
str[n] && !nsvg__isspace(
str[n]))
1322 sscanf(
str,
"%x", &
c);
1325 sscanf(
str,
"%x", &
c);
1326 c = (
c & 0xf) | ((
c & 0xf0) << 4) | ((
c & 0xf00) << 8);
1329 r = (
c >> 16) & 0xff;
1330 g = (
c >> 8) & 0xff;
1332 return NSVG_RGB(
r, g, b);
1335 static unsigned int nsvg__parseColorRGB(
const char *
str)
1337 int r = -1, g = -1, b = -1;
1338 char s1[32] =
"", s2[32] =
"";
1339 sscanf(
str + 4,
"%d%[%%, \t]%d%[%%, \t]%d", &
r, s1, &g, s2, &b);
1340 if (strchr(s1,
'%')) {
1341 return NSVG_RGB((
r * 255) / 100, (g * 255) / 100, (b * 255) / 100);
1344 return NSVG_RGB(
r, g, b);
1348 typedef struct NSVGNamedColor {
1353 NSVGNamedColor nsvg__colors[] = {
1355 {
"red", NSVG_RGB(255, 0, 0)},
1356 {
"green", NSVG_RGB(0, 128, 0)},
1357 {
"blue", NSVG_RGB(0, 0, 255)},
1358 {
"yellow", NSVG_RGB(255, 255, 0)},
1359 {
"cyan", NSVG_RGB(0, 255, 255)},
1360 {
"magenta", NSVG_RGB(255, 0, 255)},
1361 {
"black", NSVG_RGB(0, 0, 0)},
1362 {
"grey", NSVG_RGB(128, 128, 128)},
1363 {
"gray", NSVG_RGB(128, 128, 128)},
1364 {
"white", NSVG_RGB(255, 255, 255)},
1366 #ifdef NANOSVG_ALL_COLOR_KEYWORDS
1367 {
"aliceblue", NSVG_RGB(240, 248, 255)},
1368 {
"antiquewhite", NSVG_RGB(250, 235, 215)},
1369 {
"aqua", NSVG_RGB(0, 255, 255)},
1370 {
"aquamarine", NSVG_RGB(127, 255, 212)},
1371 {
"azure", NSVG_RGB(240, 255, 255)},
1372 {
"beige", NSVG_RGB(245, 245, 220)},
1373 {
"bisque", NSVG_RGB(255, 228, 196)},
1374 {
"blanchedalmond", NSVG_RGB(255, 235, 205)},
1375 {
"blueviolet", NSVG_RGB(138, 43, 226)},
1376 {
"brown", NSVG_RGB(165, 42, 42)},
1377 {
"burlywood", NSVG_RGB(222, 184, 135)},
1378 {
"cadetblue", NSVG_RGB(95, 158, 160)},
1379 {
"chartreuse", NSVG_RGB(127, 255, 0)},
1380 {
"chocolate", NSVG_RGB(210, 105, 30)},
1381 {
"coral", NSVG_RGB(255, 127, 80)},
1382 {
"cornflowerblue", NSVG_RGB(100, 149, 237)},
1383 {
"cornsilk", NSVG_RGB(255, 248, 220)},
1384 {
"crimson", NSVG_RGB(220, 20, 60)},
1385 {
"darkblue", NSVG_RGB(0, 0, 139)},
1386 {
"darkcyan", NSVG_RGB(0, 139, 139)},
1387 {
"darkgoldenrod", NSVG_RGB(184, 134, 11)},
1388 {
"darkgray", NSVG_RGB(169, 169, 169)},
1389 {
"darkgreen", NSVG_RGB(0, 100, 0)},
1390 {
"darkgrey", NSVG_RGB(169, 169, 169)},
1391 {
"darkkhaki", NSVG_RGB(189, 183, 107)},
1392 {
"darkmagenta", NSVG_RGB(139, 0, 139)},
1393 {
"darkolivegreen", NSVG_RGB(85, 107, 47)},
1394 {
"darkorange", NSVG_RGB(255, 140, 0)},
1395 {
"darkorchid", NSVG_RGB(153, 50, 204)},
1396 {
"darkred", NSVG_RGB(139, 0, 0)},
1397 {
"darksalmon", NSVG_RGB(233, 150, 122)},
1398 {
"darkseagreen", NSVG_RGB(143, 188, 143)},
1399 {
"darkslateblue", NSVG_RGB(72, 61, 139)},
1400 {
"darkslategray", NSVG_RGB(47, 79, 79)},
1401 {
"darkslategrey", NSVG_RGB(47, 79, 79)},
1402 {
"darkturquoise", NSVG_RGB(0, 206, 209)},
1403 {
"darkviolet", NSVG_RGB(148, 0, 211)},
1404 {
"deeppink", NSVG_RGB(255, 20, 147)},
1405 {
"deepskyblue", NSVG_RGB(0, 191, 255)},
1406 {
"dimgray", NSVG_RGB(105, 105, 105)},
1407 {
"dimgrey", NSVG_RGB(105, 105, 105)},
1408 {
"dodgerblue", NSVG_RGB(30, 144, 255)},
1409 {
"firebrick", NSVG_RGB(178, 34, 34)},
1410 {
"floralwhite", NSVG_RGB(255, 250, 240)},
1411 {
"forestgreen", NSVG_RGB(34, 139, 34)},
1412 {
"fuchsia", NSVG_RGB(255, 0, 255)},
1413 {
"gainsboro", NSVG_RGB(220, 220, 220)},
1414 {
"ghostwhite", NSVG_RGB(248, 248, 255)},
1415 {
"gold", NSVG_RGB(255, 215, 0)},
1416 {
"goldenrod", NSVG_RGB(218, 165, 32)},
1417 {
"greenyellow", NSVG_RGB(173, 255, 47)},
1418 {
"honeydew", NSVG_RGB(240, 255, 240)},
1419 {
"hotpink", NSVG_RGB(255, 105, 180)},
1420 {
"indianred", NSVG_RGB(205, 92, 92)},
1421 {
"indigo", NSVG_RGB(75, 0, 130)},
1422 {
"ivory", NSVG_RGB(255, 255, 240)},
1423 {
"khaki", NSVG_RGB(240, 230, 140)},
1424 {
"lavender", NSVG_RGB(230, 230, 250)},
1425 {
"lavenderblush", NSVG_RGB(255, 240, 245)},
1426 {
"lawngreen", NSVG_RGB(124, 252, 0)},
1427 {
"lemonchiffon", NSVG_RGB(255, 250, 205)},
1428 {
"lightblue", NSVG_RGB(173, 216, 230)},
1429 {
"lightcoral", NSVG_RGB(240, 128, 128)},
1430 {
"lightcyan", NSVG_RGB(224, 255, 255)},
1431 {
"lightgoldenrodyellow", NSVG_RGB(250, 250, 210)},
1432 {
"lightgray", NSVG_RGB(211, 211, 211)},
1433 {
"lightgreen", NSVG_RGB(144, 238, 144)},
1434 {
"lightgrey", NSVG_RGB(211, 211, 211)},
1435 {
"lightpink", NSVG_RGB(255, 182, 193)},
1436 {
"lightsalmon", NSVG_RGB(255, 160, 122)},
1437 {
"lightseagreen", NSVG_RGB(32, 178, 170)},
1438 {
"lightskyblue", NSVG_RGB(135, 206, 250)},
1439 {
"lightslategray", NSVG_RGB(119, 136, 153)},
1440 {
"lightslategrey", NSVG_RGB(119, 136, 153)},
1441 {
"lightsteelblue", NSVG_RGB(176, 196, 222)},
1442 {
"lightyellow", NSVG_RGB(255, 255, 224)},
1443 {
"lime", NSVG_RGB(0, 255, 0)},
1444 {
"limegreen", NSVG_RGB(50, 205, 50)},
1445 {
"linen", NSVG_RGB(250, 240, 230)},
1446 {
"maroon", NSVG_RGB(128, 0, 0)},
1447 {
"mediumaquamarine", NSVG_RGB(102, 205, 170)},
1448 {
"mediumblue", NSVG_RGB(0, 0, 205)},
1449 {
"mediumorchid", NSVG_RGB(186, 85, 211)},
1450 {
"mediumpurple", NSVG_RGB(147, 112, 219)},
1451 {
"mediumseagreen", NSVG_RGB(60, 179, 113)},
1452 {
"mediumslateblue", NSVG_RGB(123, 104, 238)},
1453 {
"mediumspringgreen", NSVG_RGB(0, 250, 154)},
1454 {
"mediumturquoise", NSVG_RGB(72, 209, 204)},
1455 {
"mediumvioletred", NSVG_RGB(199, 21, 133)},
1456 {
"midnightblue", NSVG_RGB(25, 25, 112)},
1457 {
"mintcream", NSVG_RGB(245, 255, 250)},
1458 {
"mistyrose", NSVG_RGB(255, 228, 225)},
1459 {
"moccasin", NSVG_RGB(255, 228, 181)},
1460 {
"navajowhite", NSVG_RGB(255, 222, 173)},
1461 {
"navy", NSVG_RGB(0, 0, 128)},
1462 {
"oldlace", NSVG_RGB(253, 245, 230)},
1463 {
"olive", NSVG_RGB(128, 128, 0)},
1464 {
"olivedrab", NSVG_RGB(107, 142, 35)},
1465 {
"orange", NSVG_RGB(255, 165, 0)},
1466 {
"orangered", NSVG_RGB(255, 69, 0)},
1467 {
"orchid", NSVG_RGB(218, 112, 214)},
1468 {
"palegoldenrod", NSVG_RGB(238, 232, 170)},
1469 {
"palegreen", NSVG_RGB(152, 251, 152)},
1470 {
"paleturquoise", NSVG_RGB(175, 238, 238)},
1471 {
"palevioletred", NSVG_RGB(219, 112, 147)},
1472 {
"papayawhip", NSVG_RGB(255, 239, 213)},
1473 {
"peachpuff", NSVG_RGB(255, 218, 185)},
1474 {
"peru", NSVG_RGB(205, 133, 63)},
1475 {
"pink", NSVG_RGB(255, 192, 203)},
1476 {
"plum", NSVG_RGB(221, 160, 221)},
1477 {
"powderblue", NSVG_RGB(176, 224, 230)},
1478 {
"purple", NSVG_RGB(128, 0, 128)},
1479 {
"rosybrown", NSVG_RGB(188, 143, 143)},
1480 {
"royalblue", NSVG_RGB(65, 105, 225)},
1481 {
"saddlebrown", NSVG_RGB(139, 69, 19)},
1482 {
"salmon", NSVG_RGB(250, 128, 114)},
1483 {
"sandybrown", NSVG_RGB(244, 164, 96)},
1484 {
"seagreen", NSVG_RGB(46, 139, 87)},
1485 {
"seashell", NSVG_RGB(255, 245, 238)},
1486 {
"sienna", NSVG_RGB(160, 82, 45)},
1487 {
"silver", NSVG_RGB(192, 192, 192)},
1488 {
"skyblue", NSVG_RGB(135, 206, 235)},
1489 {
"slateblue", NSVG_RGB(106, 90, 205)},
1490 {
"slategray", NSVG_RGB(112, 128, 144)},
1491 {
"slategrey", NSVG_RGB(112, 128, 144)},
1492 {
"snow", NSVG_RGB(255, 250, 250)},
1493 {
"springgreen", NSVG_RGB(0, 255, 127)},
1494 {
"steelblue", NSVG_RGB(70, 130, 180)},
1495 {
"tan", NSVG_RGB(210, 180, 140)},
1496 {
"teal", NSVG_RGB(0, 128, 128)},
1497 {
"thistle", NSVG_RGB(216, 191, 216)},
1498 {
"tomato", NSVG_RGB(255, 99, 71)},
1499 {
"turquoise", NSVG_RGB(64, 224, 208)},
1500 {
"violet", NSVG_RGB(238, 130, 238)},
1501 {
"wheat", NSVG_RGB(245, 222, 179)},
1502 {
"whitesmoke", NSVG_RGB(245, 245, 245)},
1503 {
"yellowgreen", NSVG_RGB(154, 205, 50)},
1507 static unsigned int nsvg__parseColorName(
const char *
str)
1509 int i, ncolors =
sizeof(nsvg__colors) /
sizeof(NSVGNamedColor);
1511 for (i = 0; i < ncolors; i++) {
1512 if (strcmp(nsvg__colors[i].name,
str) == 0) {
1513 return nsvg__colors[i].color;
1517 return NSVG_RGB(128, 128, 128);
1520 static unsigned int nsvg__parseColor(
const char *
str)
1526 if (
len >= 1 && *
str ==
'#')
1527 return nsvg__parseColorHex(
str);
1528 else if (
len >= 4 &&
str[0] ==
'r' &&
str[1] ==
'g' &&
str[2] ==
'b' &&
str[3] ==
'(')
1529 return nsvg__parseColorRGB(
str);
1530 return nsvg__parseColorName(
str);
1533 static float nsvg__parseOpacity(
const char *
str)
1535 float val = nsvg__atof(
str);
1543 static float nsvg__parseMiterLimit(
const char *
str)
1545 float val = nsvg__atof(
str);
1551 static int nsvg__parseUnits(
const char *units)
1553 if (units[0] ==
'p' && units[1] ==
'x')
1554 return NSVG_UNITS_PX;
1555 else if (units[0] ==
'p' && units[1] ==
't')
1556 return NSVG_UNITS_PT;
1557 else if (units[0] ==
'p' && units[1] ==
'c')
1558 return NSVG_UNITS_PC;
1559 else if (units[0] ==
'm' && units[1] ==
'm')
1560 return NSVG_UNITS_MM;
1561 else if (units[0] ==
'c' && units[1] ==
'm')
1562 return NSVG_UNITS_CM;
1563 else if (units[0] ==
'i' && units[1] ==
'n')
1564 return NSVG_UNITS_IN;
1565 else if (units[0] ==
'%')
1566 return NSVG_UNITS_PERCENT;
1567 else if (units[0] ==
'e' && units[1] ==
'm')
1568 return NSVG_UNITS_EM;
1569 else if (units[0] ==
'e' && units[1] ==
'x')
1570 return NSVG_UNITS_EX;
1571 return NSVG_UNITS_USER;
1574 static int nsvg__isCoordinate(
const char *s)
1577 if (*s ==
'-' || *s ==
'+')
1580 return nsvg__isdigit(*s);
1583 static NSVGcoordinate nsvg__parseCoordinateRaw(
const char *
str)
1585 NSVGcoordinate coord = {0, NSVG_UNITS_USER};
1587 coord.units = nsvg__parseUnits(nsvg__parseNumber(
str, buf, 64));
1588 coord.value = nsvg__atof(buf);
1592 static NSVGcoordinate nsvg__coord(
float v,
int units)
1594 NSVGcoordinate coord = {
v, units};
1598 static float nsvg__parseCoordinate(NSVGparser *p,
const char *
str,
float orig,
float length)
1600 NSVGcoordinate coord = nsvg__parseCoordinateRaw(
str);
1601 return nsvg__convertToPixels(p, coord, orig,
length);
1604 static int nsvg__parseTransformArgs(
const char *
str,
float *args,
int maxNa,
int *na)
1612 while (*
ptr && *
ptr !=
'(')
1617 while (*end && *end !=
')')
1623 if (*
ptr ==
'-' || *
ptr ==
'+' || *
ptr ==
'.' || nsvg__isdigit(*
ptr)) {
1626 ptr = nsvg__parseNumber(
ptr, it, 64);
1627 args[(*na)++] = (
float)nsvg__atof(it);
1633 return (
int)(end -
str);
1636 static int nsvg__parseMatrix(
float *xform,
const char *
str)
1640 int len = nsvg__parseTransformArgs(
str,
t, 6, &na);
1643 memcpy(xform,
t,
sizeof(
float) * 6);
1647 static int nsvg__parseTranslate(
float *xform,
const char *
str)
1652 int len = nsvg__parseTransformArgs(
str, args, 2, &na);
1656 nsvg__xformSetTranslation(
t, args[0], args[1]);
1657 memcpy(xform,
t,
sizeof(
float) * 6);
1661 static int nsvg__parseScale(
float *xform,
const char *
str)
1666 int len = nsvg__parseTransformArgs(
str, args, 2, &na);
1669 nsvg__xformSetScale(
t, args[0], args[1]);
1670 memcpy(xform,
t,
sizeof(
float) * 6);
1674 static int nsvg__parseSkewX(
float *xform,
const char *
str)
1679 int len = nsvg__parseTransformArgs(
str, args, 1, &na);
1680 nsvg__xformSetSkewX(
t, args[0] / 180.0f * NSVG_PI);
1681 memcpy(xform,
t,
sizeof(
float) * 6);
1685 static int nsvg__parseSkewY(
float *xform,
const char *
str)
1690 int len = nsvg__parseTransformArgs(
str, args, 1, &na);
1691 nsvg__xformSetSkewY(
t, args[0] / 180.0f * NSVG_PI);
1692 memcpy(xform,
t,
sizeof(
float) * 6);
1696 static int nsvg__parseRotate(
float *xform,
const char *
str)
1702 int len = nsvg__parseTransformArgs(
str, args, 3, &na);
1704 args[1] = args[2] = 0.0f;
1705 nsvg__xformIdentity(m);
1708 nsvg__xformSetTranslation(
t, -args[1], -args[2]);
1709 nsvg__xformMultiply(m,
t);
1712 nsvg__xformSetRotation(
t, args[0] / 180.0f * NSVG_PI);
1713 nsvg__xformMultiply(m,
t);
1716 nsvg__xformSetTranslation(
t, args[1], args[2]);
1717 nsvg__xformMultiply(m,
t);
1720 memcpy(xform, m,
sizeof(
float) * 6);
1725 static void nsvg__parseTransform(
float *xform,
const char *
str)
1729 nsvg__xformIdentity(xform);
1731 if (strncmp(
str,
"matrix", 6) == 0)
1732 len = nsvg__parseMatrix(
t,
str);
1733 else if (strncmp(
str,
"translate", 9) == 0)
1734 len = nsvg__parseTranslate(
t,
str);
1735 else if (strncmp(
str,
"scale", 5) == 0)
1736 len = nsvg__parseScale(
t,
str);
1737 else if (strncmp(
str,
"rotate", 6) == 0)
1738 len = nsvg__parseRotate(
t,
str);
1739 else if (strncmp(
str,
"skewX", 5) == 0)
1740 len = nsvg__parseSkewX(
t,
str);
1741 else if (strncmp(
str,
"skewY", 5) == 0)
1742 len = nsvg__parseSkewY(
t,
str);
1755 nsvg__xformPremultiply(xform,
t);
1759 static void nsvg__parseUrl(
char *
id,
const char *
str)
1765 while (i < 63 && *
str !=
')') {
1772 static char nsvg__parseLineCap(
const char *
str)
1774 if (strcmp(
str,
"butt") == 0)
1776 else if (strcmp(
str,
"round") == 0)
1778 else if (strcmp(
str,
"square") == 0)
1784 static char nsvg__parseLineJoin(
const char *
str)
1786 if (strcmp(
str,
"miter") == 0)
1788 else if (strcmp(
str,
"round") == 0)
1790 else if (strcmp(
str,
"bevel") == 0)
1796 static char nsvg__parseFillRule(
const char *
str)
1798 if (strcmp(
str,
"nonzero") == 0)
1800 else if (strcmp(
str,
"evenodd") == 0)
1806 static const char *nsvg__getNextDashItem(
const char *s,
char *it)
1811 while (*s && (nsvg__isspace(*s) || *s ==
','))
1814 while (*s && (!nsvg__isspace(*s) && *s !=
',')) {
1823 static int nsvg__parseStrokeDashArray(NSVGparser *p,
const char *
str,
float *strokeDashArray)
1835 str = nsvg__getNextDashItem(
str, item);
1838 if (
count < NSVG_MAX_DASHES)
1840 nsvg__parseCoordinate(p, item, 0.0f, nsvg__actualLength(p)));
1843 for (i = 0; i <
count; i++)
1844 sum += strokeDashArray[i];
1851 static void nsvg__parseStyle(NSVGparser *p,
const char *
str);
1853 static int nsvg__parseAttr(NSVGparser *p,
const char *name,
const char *value)
1856 NSVGattrib *attr = nsvg__getAttr(p);
1860 if (strcmp(name,
"style") == 0) {
1861 nsvg__parseStyle(p, value);
1863 else if (strcmp(name,
"display") == 0) {
1864 if (strcmp(value,
"none") == 0)
1868 else if (strcmp(name,
"fill") == 0) {
1869 if (strcmp(value,
"none") == 0) {
1872 else if (strncmp(value,
"url(", 4) == 0) {
1874 nsvg__parseUrl(attr->fillGradient, value);
1878 attr->fillColor = nsvg__parseColor(value);
1881 else if (strcmp(name,
"opacity") == 0) {
1882 attr->opacity = nsvg__parseOpacity(value);
1884 else if (strcmp(name,
"fill-opacity") == 0) {
1885 attr->fillOpacity = nsvg__parseOpacity(value);
1887 else if (strcmp(name,
"stroke") == 0) {
1888 if (strcmp(value,
"none") == 0) {
1889 attr->hasStroke = 0;
1891 else if (strncmp(value,
"url(", 4) == 0) {
1892 attr->hasStroke = 2;
1893 nsvg__parseUrl(attr->strokeGradient, value);
1896 attr->hasStroke = 1;
1897 attr->strokeColor = nsvg__parseColor(value);
1900 else if (strcmp(name,
"stroke-width") == 0) {
1901 attr->strokeWidth = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p));
1903 else if (strcmp(name,
"stroke-dasharray") == 0) {
1904 attr->strokeDashCount = nsvg__parseStrokeDashArray(p, value, attr->strokeDashArray);
1906 else if (strcmp(name,
"stroke-dashoffset") == 0) {
1907 attr->strokeDashOffset = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p));
1909 else if (strcmp(name,
"stroke-opacity") == 0) {
1910 attr->strokeOpacity = nsvg__parseOpacity(value);
1912 else if (strcmp(name,
"stroke-linecap") == 0) {
1913 attr->strokeLineCap = nsvg__parseLineCap(value);
1915 else if (strcmp(name,
"stroke-linejoin") == 0) {
1916 attr->strokeLineJoin = nsvg__parseLineJoin(value);
1918 else if (strcmp(name,
"stroke-miterlimit") == 0) {
1919 attr->miterLimit = nsvg__parseMiterLimit(value);
1921 else if (strcmp(name,
"fill-rule") == 0) {
1922 attr->fillRule = nsvg__parseFillRule(value);
1924 else if (strcmp(name,
"font-size") == 0) {
1925 attr->fontSize = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p));
1927 else if (strcmp(name,
"transform") == 0) {
1928 nsvg__parseTransform(xform, value);
1929 nsvg__xformPremultiply(attr->xform, xform);
1931 else if (strcmp(name,
"stop-color") == 0) {
1932 attr->stopColor = nsvg__parseColor(value);
1934 else if (strcmp(name,
"stop-opacity") == 0) {
1935 attr->stopOpacity = nsvg__parseOpacity(value);
1937 else if (strcmp(name,
"offset") == 0) {
1938 attr->stopOffset = nsvg__parseCoordinate(p, value, 0.0f, 1.0f);
1940 else if (strcmp(name,
"id") == 0) {
1941 strncpy(attr->id, value, 63);
1942 attr->id[63] =
'\0';
1950 static int nsvg__parseNameValue(NSVGparser *p,
const char *start,
const char *end)
1959 while (
str < end && *
str !=
':')
1965 while (
str > start && (*
str ==
':' || nsvg__isspace(*
str)))
1969 n = (int)(
str - start);
1973 memcpy(name, start, n);
1976 while (val < end && (*val ==
':' || nsvg__isspace(*val)))
1979 n = (int)(end - val);
1983 memcpy(value, val, n);
1986 return nsvg__parseAttr(p, name, value);
1989 static void nsvg__parseStyle(NSVGparser *p,
const char *
str)
1996 while (*
str && nsvg__isspace(*
str))
1999 while (*
str && *
str !=
';')
2004 while (end > start && (*end ==
';' || nsvg__isspace(*end)))
2008 nsvg__parseNameValue(p, start, end);
2014 static void nsvg__parseAttribs(NSVGparser *p,
const char **attr)
2017 for (i = 0; attr[i]; i += 2) {
2018 if (strcmp(attr[i],
"style") == 0)
2019 nsvg__parseStyle(p, attr[i + 1]);
2021 nsvg__parseAttr(p, attr[i], attr[i + 1]);
2025 static int nsvg__getArgsPerElement(
char cmd)
2058 static void nsvg__pathMoveTo(NSVGparser *p,
float *cpx,
float *cpy,
float *args,
int rel)
2068 nsvg__moveTo(p, *cpx, *cpy);
2071 static void nsvg__pathLineTo(NSVGparser *p,
float *cpx,
float *cpy,
float *args,
int rel)
2081 nsvg__lineTo(p, *cpx, *cpy);
2084 static void nsvg__pathHLineTo(NSVGparser *p,
float *cpx,
float *cpy,
float *args,
int rel)
2090 nsvg__lineTo(p, *cpx, *cpy);
2093 static void nsvg__pathVLineTo(NSVGparser *p,
float *cpx,
float *cpy,
float *args,
int rel)
2099 nsvg__lineTo(p, *cpx, *cpy);
2102 static void nsvg__pathCubicBezTo(
2103 NSVGparser *p,
float *cpx,
float *cpy,
float *cpx2,
float *cpy2,
float *args,
int rel)
2105 float x2, y2, cx1, cy1, cx2, cy2;
2108 cx1 = *cpx + args[0];
2109 cy1 = *cpy + args[1];
2110 cx2 = *cpx + args[2];
2111 cy2 = *cpy + args[3];
2112 x2 = *cpx + args[4];
2113 y2 = *cpy + args[5];
2124 nsvg__cubicBezTo(p, cx1, cy1, cx2, cy2,
x2, y2);
2132 static void nsvg__pathCubicBezShortTo(
2133 NSVGparser *p,
float *cpx,
float *cpy,
float *cpx2,
float *cpy2,
float *args,
int rel)
2135 float x1,
y1,
x2, y2, cx1, cy1, cx2, cy2;
2140 cx2 = *cpx + args[0];
2141 cy2 = *cpy + args[1];
2142 x2 = *cpx + args[2];
2143 y2 = *cpy + args[3];
2152 cx1 = 2 * x1 - *cpx2;
2153 cy1 = 2 *
y1 - *cpy2;
2155 nsvg__cubicBezTo(p, cx1, cy1, cx2, cy2,
x2, y2);
2163 static void nsvg__pathQuadBezTo(
2164 NSVGparser *p,
float *cpx,
float *cpy,
float *cpx2,
float *cpy2,
float *args,
int rel)
2166 float x1,
y1,
x2, y2, cx, cy;
2167 float cx1, cy1, cx2, cy2;
2172 cx = *cpx + args[0];
2173 cy = *cpy + args[1];
2174 x2 = *cpx + args[2];
2175 y2 = *cpy + args[3];
2185 cx1 = x1 + 2.0f / 3.0f * (cx - x1);
2186 cy1 =
y1 + 2.0f / 3.0f * (cy -
y1);
2187 cx2 =
x2 + 2.0f / 3.0f * (cx -
x2);
2188 cy2 = y2 + 2.0f / 3.0f * (cy - y2);
2190 nsvg__cubicBezTo(p, cx1, cy1, cx2, cy2,
x2, y2);
2198 static void nsvg__pathQuadBezShortTo(
2199 NSVGparser *p,
float *cpx,
float *cpy,
float *cpx2,
float *cpy2,
float *args,
int rel)
2201 float x1,
y1,
x2, y2, cx, cy;
2202 float cx1, cy1, cx2, cy2;
2207 x2 = *cpx + args[0];
2208 y2 = *cpy + args[1];
2215 cx = 2 * x1 - *cpx2;
2216 cy = 2 *
y1 - *cpy2;
2219 cx1 = x1 + 2.0f / 3.0f * (cx - x1);
2220 cy1 =
y1 + 2.0f / 3.0f * (cy -
y1);
2221 cx2 =
x2 + 2.0f / 3.0f * (cx -
x2);
2222 cy2 = y2 + 2.0f / 3.0f * (cy - y2);
2224 nsvg__cubicBezTo(p, cx1, cy1, cx2, cy2,
x2, y2);
2232 static float nsvg__sqr(
float x)
2236 static float nsvg__vmag(
float x,
float y)
2241 static float nsvg__vecrat(
float ux,
float uy,
float vx,
float vy)
2243 return (ux * vx + uy * vy) / (nsvg__vmag(ux, uy) * nsvg__vmag(vx, vy));
2246 static float nsvg__vecang(
float ux,
float uy,
float vx,
float vy)
2248 float r = nsvg__vecrat(ux, uy, vx, vy);
2253 return ((ux * vy < uy * vx) ? -1.0f : 1.0f) *
acosf(
r);
2256 static void nsvg__pathArcTo(NSVGparser *p,
float *cpx,
float *cpy,
float *args,
int rel)
2260 float x1,
y1,
x2, y2, cx, cy, dx, dy, d;
2261 float x1p, y1p, cxp, cyp, s, sa, sb;
2262 float ux, uy, vx, vy, a1, da;
2263 float x,
y, tanx, tany,
a, px = 0, py = 0, ptanx = 0, ptany = 0,
t[6];
2269 rx =
fabsf(args[0]);
2270 ry =
fabsf(args[1]);
2271 rotx = args[2] / 180.0f * NSVG_PI;
2272 fa =
fabsf(args[3]) > 1
e-6 ? 1 : 0;
2273 fs =
fabsf(args[4]) > 1
e-6 ? 1 : 0;
2277 x2 = *cpx + args[5];
2278 y2 = *cpy + args[6];
2287 d =
sqrtf(dx * dx + dy * dy);
2288 if (d < 1e-6f || rx < 1e-6f || ry < 1e-6f) {
2290 nsvg__lineTo(p,
x2, y2);
2302 x1p = cosrx * dx / 2.0f + sinrx * dy / 2.0f;
2303 y1p = -sinrx * dx / 2.0f + cosrx * dy / 2.0f;
2304 d = nsvg__sqr(x1p) / nsvg__sqr(rx) + nsvg__sqr(y1p) / nsvg__sqr(ry);
2312 sa = nsvg__sqr(rx) * nsvg__sqr(ry) - nsvg__sqr(rx) * nsvg__sqr(y1p) -
2313 nsvg__sqr(ry) * nsvg__sqr(x1p);
2314 sb = nsvg__sqr(rx) * nsvg__sqr(y1p) + nsvg__sqr(ry) * nsvg__sqr(x1p);
2321 cxp = s * rx * y1p / ry;
2322 cyp = s * -ry * x1p / rx;
2325 cx = (x1 +
x2) / 2.0f + cosrx * cxp - sinrx * cyp;
2326 cy = (
y1 + y2) / 2.0f + sinrx * cxp + cosrx * cyp;
2329 ux = (x1p - cxp) / rx;
2330 uy = (y1p - cyp) / ry;
2331 vx = (-x1p - cxp) / rx;
2332 vy = (-y1p - cyp) / ry;
2333 a1 = nsvg__vecang(1.0f, 0.0f, ux, uy);
2334 da = nsvg__vecang(ux, uy, vx, vy);
2339 if (fs == 0 && da > 0)
2341 else if (fs == 1 && da < 0)
2354 ndivs = (int)(
fabsf(da) / (NSVG_PI * 0.5f) + 1.0f);
2355 hda = (da / (
float)ndivs) / 2.0f;
2356 kappa =
fabsf(4.0f / 3.0f * (1.0f -
cosf(hda)) /
sinf(hda));
2360 for (i = 0; i <= ndivs; i++) {
2361 a = a1 + da * ((
float)i / (
float)ndivs);
2364 nsvg__xformPoint(&
x, &
y, dx * rx, dy * ry,
t);
2365 nsvg__xformVec(&tanx, &tany, -dy * rx * kappa, dx * ry * kappa,
t);
2367 nsvg__cubicBezTo(p, px + ptanx, py + ptany,
x - tanx,
y - tany,
x,
y);
2378 static void nsvg__parsePath(NSVGparser *p,
const char **attr)
2380 const char *s =
NULL;
2386 float cpx, cpy, cpx2, cpy2;
2392 for (i = 0; attr[i]; i += 2) {
2393 if (strcmp(attr[i],
"d") == 0) {
2398 tmp[1] = attr[i + 1];
2401 nsvg__parseAttribs(p, tmp);
2416 s = nsvg__getNextPathItem(s, item);
2419 if (cmd !=
'\0' && nsvg__isCoordinate(item)) {
2421 args[nargs++] = (
float)nsvg__atof(item);
2422 if (nargs >= rargs) {
2426 nsvg__pathMoveTo(p, &cpx, &cpy, args, cmd ==
'm' ? 1 : 0);
2429 cmd = (cmd ==
'm') ?
'l' :
'L';
2430 rargs = nsvg__getArgsPerElement(cmd);
2437 nsvg__pathLineTo(p, &cpx, &cpy, args, cmd ==
'l' ? 1 : 0);
2443 nsvg__pathHLineTo(p, &cpx, &cpy, args, cmd ==
'h' ? 1 : 0);
2449 nsvg__pathVLineTo(p, &cpx, &cpy, args, cmd ==
'v' ? 1 : 0);
2455 nsvg__pathCubicBezTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd ==
'c' ? 1 : 0);
2459 nsvg__pathCubicBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd ==
's' ? 1 : 0);
2463 nsvg__pathQuadBezTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd ==
'q' ? 1 : 0);
2467 nsvg__pathQuadBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd ==
't' ? 1 : 0);
2471 nsvg__pathArcTo(p, &cpx, &cpy, args, cmd ==
'a' ? 1 : 0);
2477 cpx = args[nargs - 2];
2478 cpy = args[nargs - 1];
2489 if (cmd ==
'M' || cmd ==
'm') {
2492 nsvg__addPath(p, closedFlag);
2498 else if (initPoint == 0) {
2502 if (cmd ==
'Z' || cmd ==
'z') {
2511 nsvg__addPath(p, closedFlag);
2515 nsvg__moveTo(p, cpx, cpy);
2519 rargs = nsvg__getArgsPerElement(cmd);
2529 nsvg__addPath(p, closedFlag);
2535 static void nsvg__parseRect(NSVGparser *p,
const char **attr)
2545 for (i = 0; attr[i]; i += 2) {
2546 if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
2547 if (strcmp(attr[i],
"x") == 0)
2548 x = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
2549 if (strcmp(attr[i],
"y") == 0)
2550 y = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
2551 if (strcmp(attr[i],
"width") == 0)
2552 w = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualWidth(p));
2553 if (strcmp(attr[i],
"height") == 0)
2554 h = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualHeight(p));
2555 if (strcmp(attr[i],
"rx") == 0)
2556 rx =
fabsf(nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualWidth(p)));
2557 if (strcmp(attr[i],
"ry") == 0)
2558 ry =
fabsf(nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualHeight(p)));
2562 if (rx < 0.0f && ry > 0.0f)
2564 if (ry < 0.0f && rx > 0.0f)
2575 if (
w != 0.0f && h != 0.0f) {
2578 if (rx < 0.00001f || ry < 0.0001f) {
2579 nsvg__moveTo(p,
x,
y);
2580 nsvg__lineTo(p,
x +
w,
y);
2581 nsvg__lineTo(p,
x +
w,
y + h);
2582 nsvg__lineTo(p,
x,
y + h);
2586 nsvg__moveTo(p,
x + rx,
y);
2587 nsvg__lineTo(p,
x +
w - rx,
y);
2589 x +
w - rx * (1 - NSVG_KAPPA90),
2592 y + ry * (1 - NSVG_KAPPA90),
2595 nsvg__lineTo(p,
x +
w,
y + h - ry);
2598 y + h - ry * (1 - NSVG_KAPPA90),
2599 x +
w - rx * (1 - NSVG_KAPPA90),
2603 nsvg__lineTo(p,
x + rx,
y + h);
2605 x + rx * (1 - NSVG_KAPPA90),
2608 y + h - ry * (1 - NSVG_KAPPA90),
2611 nsvg__lineTo(p,
x,
y + ry);
2613 p,
x,
y + ry * (1 - NSVG_KAPPA90),
x + rx * (1 - NSVG_KAPPA90),
y,
x + rx,
y);
2616 nsvg__addPath(p, 1);
2622 static void nsvg__parseCircle(NSVGparser *p,
const char **attr)
2629 for (i = 0; attr[i]; i += 2) {
2630 if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
2631 if (strcmp(attr[i],
"cx") == 0)
2632 cx = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
2633 if (strcmp(attr[i],
"cy") == 0)
2634 cy = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
2635 if (strcmp(attr[i],
"r") == 0)
2636 r =
fabsf(nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualLength(p)));
2643 nsvg__moveTo(p, cx +
r, cy);
2644 nsvg__cubicBezTo(p, cx +
r, cy +
r * NSVG_KAPPA90, cx +
r * NSVG_KAPPA90, cy +
r, cx, cy +
r);
2645 nsvg__cubicBezTo(p, cx -
r * NSVG_KAPPA90, cy +
r, cx -
r, cy +
r * NSVG_KAPPA90, cx -
r, cy);
2646 nsvg__cubicBezTo(p, cx -
r, cy -
r * NSVG_KAPPA90, cx -
r * NSVG_KAPPA90, cy -
r, cx, cy -
r);
2647 nsvg__cubicBezTo(p, cx +
r * NSVG_KAPPA90, cy -
r, cx +
r, cy -
r * NSVG_KAPPA90, cx +
r, cy);
2649 nsvg__addPath(p, 1);
2655 static void nsvg__parseEllipse(NSVGparser *p,
const char **attr)
2663 for (i = 0; attr[i]; i += 2) {
2664 if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
2665 if (strcmp(attr[i],
"cx") == 0)
2666 cx = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
2667 if (strcmp(attr[i],
"cy") == 0)
2668 cy = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
2669 if (strcmp(attr[i],
"rx") == 0)
2670 rx =
fabsf(nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualWidth(p)));
2671 if (strcmp(attr[i],
"ry") == 0)
2672 ry =
fabsf(nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualHeight(p)));
2676 if (rx > 0.0f && ry > 0.0f) {
2680 nsvg__moveTo(p, cx + rx, cy);
2682 p, cx + rx, cy + ry * NSVG_KAPPA90, cx + rx * NSVG_KAPPA90, cy + ry, cx, cy + ry);
2684 p, cx - rx * NSVG_KAPPA90, cy + ry, cx - rx, cy + ry * NSVG_KAPPA90, cx - rx, cy);
2686 p, cx - rx, cy - ry * NSVG_KAPPA90, cx - rx * NSVG_KAPPA90, cy - ry, cx, cy - ry);
2688 p, cx + rx * NSVG_KAPPA90, cy - ry, cx + rx, cy - ry * NSVG_KAPPA90, cx + rx, cy);
2690 nsvg__addPath(p, 1);
2696 static void nsvg__parseLine(NSVGparser *p,
const char **attr)
2704 for (i = 0; attr[i]; i += 2) {
2705 if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
2706 if (strcmp(attr[i],
"x1") == 0)
2707 x1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
2708 if (strcmp(attr[i],
"y1") == 0)
2709 y1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
2710 if (strcmp(attr[i],
"x2") == 0)
2711 x2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
2712 if (strcmp(attr[i],
"y2") == 0)
2713 y2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
2719 nsvg__moveTo(p, x1,
y1);
2720 nsvg__lineTo(p,
x2, y2);
2722 nsvg__addPath(p, 0);
2727 static void nsvg__parsePoly(NSVGparser *p,
const char **attr,
int closeFlag)
2732 int nargs, npts = 0;
2737 for (i = 0; attr[i]; i += 2) {
2738 if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
2739 if (strcmp(attr[i],
"points") == 0) {
2743 s = nsvg__getNextPathItem(s, item);
2744 args[nargs++] = (
float)nsvg__atof(item);
2747 nsvg__moveTo(p, args[0], args[1]);
2749 nsvg__lineTo(p, args[0], args[1]);
2758 nsvg__addPath(p, (
char)closeFlag);
2763 static void nsvg__parseSVG(NSVGparser *p,
const char **attr)
2766 for (i = 0; attr[i]; i += 2) {
2767 if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
2768 if (strcmp(attr[i],
"width") == 0) {
2769 p->image->width = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f);
2771 else if (strcmp(attr[i],
"height") == 0) {
2772 p->image->height = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f);
2774 else if (strcmp(attr[i],
"viewBox") == 0) {
2775 const char *s = attr[i + 1];
2777 s = nsvg__parseNumber(s, buf, 64);
2778 p->viewMinx = nsvg__atof(buf);
2779 while (*s && (nsvg__isspace(*s) || *s ==
'%' || *s ==
','))
2783 s = nsvg__parseNumber(s, buf, 64);
2784 p->viewMiny = nsvg__atof(buf);
2785 while (*s && (nsvg__isspace(*s) || *s ==
'%' || *s ==
','))
2789 s = nsvg__parseNumber(s, buf, 64);
2790 p->viewWidth = nsvg__atof(buf);
2791 while (*s && (nsvg__isspace(*s) || *s ==
'%' || *s ==
','))
2795 s = nsvg__parseNumber(s, buf, 64);
2796 p->viewHeight = nsvg__atof(buf);
2798 else if (strcmp(attr[i],
"preserveAspectRatio") == 0) {
2799 if (strstr(attr[i + 1],
"none") != 0) {
2801 p->alignType = NSVG_ALIGN_NONE;
2805 if (strstr(attr[i + 1],
"xMin") != 0)
2806 p->alignX = NSVG_ALIGN_MIN;
2807 else if (strstr(attr[i + 1],
"xMid") != 0)
2808 p->alignX = NSVG_ALIGN_MID;
2809 else if (strstr(attr[i + 1],
"xMax") != 0)
2810 p->alignX = NSVG_ALIGN_MAX;
2812 if (strstr(attr[i + 1],
"yMin") != 0)
2813 p->alignY = NSVG_ALIGN_MIN;
2814 else if (strstr(attr[i + 1],
"yMid") != 0)
2815 p->alignY = NSVG_ALIGN_MID;
2816 else if (strstr(attr[i + 1],
"yMax") != 0)
2817 p->alignY = NSVG_ALIGN_MAX;
2819 p->alignType = NSVG_ALIGN_MEET;
2820 if (strstr(attr[i + 1],
"slice") != 0)
2821 p->alignType = NSVG_ALIGN_SLICE;
2828 static void nsvg__parseGradient(NSVGparser *p,
const char **attr,
char type)
2831 NSVGgradientData *
grad = (NSVGgradientData *)malloc(
sizeof(NSVGgradientData));
2834 memset(
grad, 0,
sizeof(NSVGgradientData));
2835 grad->units = NSVG_OBJECT_SPACE;
2838 grad->linear.x1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT);
2839 grad->linear.y1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT);
2840 grad->linear.x2 = nsvg__coord(100.0f, NSVG_UNITS_PERCENT);
2841 grad->linear.y2 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT);
2844 grad->radial.cx = nsvg__coord(50.0f, NSVG_UNITS_PERCENT);
2845 grad->radial.cy = nsvg__coord(50.0f, NSVG_UNITS_PERCENT);
2846 grad->radial.r = nsvg__coord(50.0f, NSVG_UNITS_PERCENT);
2849 nsvg__xformIdentity(
grad->xform);
2851 for (i = 0; attr[i]; i += 2) {
2852 if (strcmp(attr[i],
"id") == 0) {
2853 strncpy(
grad->id, attr[i + 1], 63);
2854 grad->id[63] =
'\0';
2856 else if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
2857 if (strcmp(attr[i],
"gradientUnits") == 0) {
2858 if (strcmp(attr[i + 1],
"objectBoundingBox") == 0)
2859 grad->units = NSVG_OBJECT_SPACE;
2861 grad->units = NSVG_USER_SPACE;
2863 else if (strcmp(attr[i],
"gradientTransform") == 0) {
2864 nsvg__parseTransform(
grad->xform, attr[i + 1]);
2866 else if (strcmp(attr[i],
"cx") == 0) {
2867 grad->radial.cx = nsvg__parseCoordinateRaw(attr[i + 1]);
2869 else if (strcmp(attr[i],
"cy") == 0) {
2870 grad->radial.cy = nsvg__parseCoordinateRaw(attr[i + 1]);
2872 else if (strcmp(attr[i],
"r") == 0) {
2873 grad->radial.r = nsvg__parseCoordinateRaw(attr[i + 1]);
2875 else if (strcmp(attr[i],
"fx") == 0) {
2876 grad->radial.fx = nsvg__parseCoordinateRaw(attr[i + 1]);
2878 else if (strcmp(attr[i],
"fy") == 0) {
2879 grad->radial.fy = nsvg__parseCoordinateRaw(attr[i + 1]);
2881 else if (strcmp(attr[i],
"x1") == 0) {
2882 grad->linear.x1 = nsvg__parseCoordinateRaw(attr[i + 1]);
2884 else if (strcmp(attr[i],
"y1") == 0) {
2885 grad->linear.y1 = nsvg__parseCoordinateRaw(attr[i + 1]);
2887 else if (strcmp(attr[i],
"x2") == 0) {
2888 grad->linear.x2 = nsvg__parseCoordinateRaw(attr[i + 1]);
2890 else if (strcmp(attr[i],
"y2") == 0) {
2891 grad->linear.y2 = nsvg__parseCoordinateRaw(attr[i + 1]);
2893 else if (strcmp(attr[i],
"spreadMethod") == 0) {
2894 if (strcmp(attr[i + 1],
"pad") == 0)
2896 else if (strcmp(attr[i + 1],
"reflect") == 0)
2898 else if (strcmp(attr[i + 1],
"repeat") == 0)
2901 else if (strcmp(attr[i],
"xlink:href") == 0) {
2902 const char *href = attr[i + 1];
2903 strncpy(
grad->ref, href + 1, 62);
2904 grad->ref[62] =
'\0';
2909 grad->next = p->gradients;
2910 p->gradients =
grad;
2913 static void nsvg__parseGradientStop(NSVGparser *p,
const char **attr)
2915 NSVGattrib *curAttr = nsvg__getAttr(p);
2916 NSVGgradientData *
grad;
2920 curAttr->stopOffset = 0;
2921 curAttr->stopColor = 0;
2922 curAttr->stopOpacity = 1.0f;
2924 for (i = 0; attr[i]; i += 2) {
2925 nsvg__parseAttr(p, attr[i], attr[i + 1]);
2929 grad = p->gradients;
2939 idx =
grad->nstops - 1;
2940 for (i = 0; i <
grad->nstops - 1; i++) {
2941 if (curAttr->stopOffset <
grad->stops[i].offset) {
2946 if (idx !=
grad->nstops - 1) {
2947 for (i =
grad->nstops - 1; i > idx; i--)
2948 grad->stops[i] =
grad->stops[i - 1];
2951 stop = &
grad->stops[idx];
2952 stop->
color = curAttr->stopColor;
2953 stop->
color |= (
unsigned int)(curAttr->stopOpacity * 255) << 24;
2954 stop->
offset = curAttr->stopOffset;
2957 static void nsvg__startElement(
void *ud,
const char *el,
const char **attr)
2959 NSVGparser *p = (NSVGparser *)ud;
2963 if (strcmp(el,
"linearGradient") == 0) {
2966 else if (strcmp(el,
"radialGradient") == 0) {
2969 else if (strcmp(el,
"stop") == 0) {
2970 nsvg__parseGradientStop(p, attr);
2975 if (strcmp(el,
"g") == 0) {
2977 nsvg__parseAttribs(p, attr);
2980 if (p->breadcrumb_len < NSVG_MAX_BREADCRUMB) {
2981 NSVGattrib *
attr_id = nsvg__getAttr(p);
2983 p->breadcrumb[p->breadcrumb_len],
attr_id->id,
sizeof(p->breadcrumb[p->breadcrumb_len]));
2984 p->breadcrumb_len++;
2987 else if (strcmp(el,
"path") == 0) {
2991 nsvg__parsePath(p, attr);
2994 else if (strcmp(el,
"rect") == 0) {
2996 nsvg__parseRect(p, attr);
2999 else if (strcmp(el,
"circle") == 0) {
3001 nsvg__parseCircle(p, attr);
3004 else if (strcmp(el,
"ellipse") == 0) {
3006 nsvg__parseEllipse(p, attr);
3009 else if (strcmp(el,
"line") == 0) {
3011 nsvg__parseLine(p, attr);
3014 else if (strcmp(el,
"polyline") == 0) {
3016 nsvg__parsePoly(p, attr, 0);
3019 else if (strcmp(el,
"polygon") == 0) {
3021 nsvg__parsePoly(p, attr, 1);
3024 else if (strcmp(el,
"linearGradient") == 0) {
3027 else if (strcmp(el,
"radialGradient") == 0) {
3030 else if (strcmp(el,
"stop") == 0) {
3031 nsvg__parseGradientStop(p, attr);
3033 else if (strcmp(el,
"defs") == 0) {
3036 else if (strcmp(el,
"svg") == 0) {
3037 nsvg__parseSVG(p, attr);
3041 static void nsvg__endElement(
void *ud,
const char *el)
3043 NSVGparser *p = (NSVGparser *)ud;
3045 if (strcmp(el,
"g") == 0) {
3047 if (p->breadcrumb_len > 0) {
3048 p->breadcrumb[p->breadcrumb_len - 1][0] =
'\0';
3049 p->breadcrumb_len--;
3054 else if (strcmp(el,
"path") == 0) {
3057 else if (strcmp(el,
"defs") == 0) {
3062 static void nsvg__content(
void *ud,
const char *s)
3069 static void nsvg__imageBounds(NSVGparser *p,
float *
bounds)
3072 shape = p->image->shapes;
3073 if (shape ==
NULL) {
3081 for (shape = shape->
next; shape !=
NULL; shape = shape->
next) {
3089 static float nsvg__viewAlign(
float content,
float container,
int type)
3091 if (
type == NSVG_ALIGN_MIN)
3093 else if (
type == NSVG_ALIGN_MAX)
3094 return container - content;
3096 return (container - content) * 0.5f;
3099 static void nsvg__scaleGradient(
NSVGgradient *
grad,
float tx,
float ty,
float sx,
float sy)
3102 nsvg__xformSetTranslation(
t, tx, ty);
3103 nsvg__xformMultiply(
grad->xform,
t);
3105 nsvg__xformSetScale(
t, sx, sy);
3106 nsvg__xformMultiply(
grad->xform,
t);
3109 static void nsvg__scaleToViewbox(NSVGparser *p,
const char *units)
3113 float tx, ty, sx, sy, us,
bounds[4],
t[6], avgs;
3118 nsvg__imageBounds(p,
bounds);
3120 if (p->viewWidth == 0) {
3121 if (p->image->width > 0) {
3122 p->viewWidth = p->image->width;
3129 if (p->viewHeight == 0) {
3130 if (p->image->height > 0) {
3131 p->viewHeight = p->image->height;
3138 if (p->image->width == 0)
3139 p->image->width = p->viewWidth;
3140 if (p->image->height == 0)
3141 p->image->height = p->viewHeight;
3145 sx = p->viewWidth > 0 ? p->image->width / p->viewWidth : 0;
3146 sy = p->viewHeight > 0 ? p->image->height / p->viewHeight : 0;
3148 us = 1.0f / nsvg__convertToPixels(p, nsvg__coord(1.0f, nsvg__parseUnits(units)), 0.0f, 1.0f);
3151 if (p->alignType == NSVG_ALIGN_MEET) {
3153 sx = sy = nsvg__minf(sx, sy);
3154 tx += nsvg__viewAlign(p->viewWidth * sx, p->image->width, p->alignX) / sx;
3155 ty += nsvg__viewAlign(p->viewHeight * sy, p->image->height, p->alignY) / sy;
3157 else if (p->alignType == NSVG_ALIGN_SLICE) {
3159 sx = sy = nsvg__maxf(sx, sy);
3160 tx += nsvg__viewAlign(p->viewWidth * sx, p->image->width, p->alignX) / sx;
3161 ty += nsvg__viewAlign(p->viewHeight * sy, p->image->height, p->alignY) / sy;
3167 avgs = (sx + sy) / 2.0f;
3168 for (shape = p->image->shapes; shape !=
NULL; shape = shape->
next) {
3173 for (path = shape->
paths; path !=
NULL; path = path->
next) {
3178 for (i = 0; i < path->
npts; i++) {
3179 pt = &path->
pts[i * 2];
3180 pt[0] = (pt[0] + tx) * sx;
3181 pt[1] = (pt[1] + ty) * sy;
3187 nsvg__scaleGradient(shape->
fill.
gradient, tx, ty, sx, sy);
3210 p = nsvg__createParser();
3216 nsvg__parseXML(input, nsvg__startElement, nsvg__endElement, nsvg__content, p);
3219 nsvg__scaleToViewbox(p, units);
3224 nsvg__deleteParser(p);
3236 fp = fopen(filename,
"rb");
3239 fseek(fp, 0, SEEK_END);
3241 fseek(fp, 0, SEEK_SET);
3276 res->
pts = (
float *)malloc(p->
npts * 2 *
sizeof(
float));
3279 memcpy(res->
pts, p->
pts, p->
npts *
sizeof(
float) * 2);
3302 while (shape !=
NULL) {
3303 snext = shape->
next;
3304 nsvg__deletePaths(shape->
paths);
3305 nsvg__deletePaint(&shape->
fill);
3306 nsvg__deletePaint(&shape->
stroke);
typedef float(TangentPoint)[2]
void BLI_kdtree_nd_() free(KDTree *tree)
typedef double(DMatrix)[4][4]
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble y1
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble x2
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
SIMD_FORCE_INLINE btScalar length(const btQuaternion &q)
Return the length of a quaternion.
static T sum(const btAlignedObjectArray< T > &items)
struct @612::@615 attr_id
static void error(const char *str)
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
struct NSVGgradient NSVGgradient
NSVGimage * nsvgParse(char *input, const char *units, float dpi)
struct NSVGgradientStop NSVGgradientStop
@ NSVG_PAINT_RADIAL_GRADIENT
@ NSVG_PAINT_LINEAR_GRADIENT
struct NSVGshape NSVGshape
struct NSVGpaint NSVGpaint
NSVGimage * nsvgParseFromFile(const char *filename, const char *units, float dpi)
struct NSVGimage NSVGimage
void nsvgDelete(NSVGimage *image)
NSVGpath * nsvgDuplicatePath(NSVGpath *p)
BLI_INLINE float grad(int hash_val, float x, float y, float z)
NSVGgradientStop stops[1]
ccl_device_inline float2 fabs(const float2 &a)