| 2451 | } |
| 2452 | |
| 2453 | static void nsvg__parsePath(NSVGparser* p, const char** attr) |
| 2454 | { |
| 2455 | const char* s = NULL; |
| 2456 | char cmd = '\0'; |
| 2457 | float args[30]; |
| 2458 | int nargs; |
| 2459 | int rargs = 0; |
| 2460 | float cpx, cpy, cpx2, cpy2; |
| 2461 | // const char* tmp[4]; |
| 2462 | char closedFlag; |
| 2463 | int i; |
| 2464 | char item[kMaxIDLength]; |
| 2465 | |
| 2466 | for (i = 0; attr[i]; i += 2) { |
| 2467 | if (strcmp(attr[i], "d") == 0) { |
| 2468 | s = attr[i + 1]; |
| 2469 | } else { |
| 2470 | nsvg__parseAttr(p, attr[i], attr[i + 1]); |
| 2471 | } |
| 2472 | } |
| 2473 | |
| 2474 | if (s) { |
| 2475 | nsvg__resetPath(p); |
| 2476 | cpx = 0; cpy = 0; |
| 2477 | cpx2 = 0; cpy2 = 0; |
| 2478 | closedFlag = 0; |
| 2479 | nargs = 0; |
| 2480 | while (*s) { |
| 2481 | s = nsvg__getNextPathItem(s, item); |
| 2482 | if (!*item) break; |
| 2483 | if (nsvg__isnum(item[0])) { |
| 2484 | if (nargs < 30) { |
| 2485 | float x = (float)nsvg__atof(item); |
| 2486 | args[nargs++] = x; |
| 2487 | } |
| 2488 | if (nargs >= rargs) { |
| 2489 | switch (cmd) { |
| 2490 | case 'm': |
| 2491 | case 'M': |
| 2492 | nsvg__pathMoveTo(p, &cpx, &cpy, args, cmd == 'm' ? 1 : 0); |
| 2493 | // Moveto can be followed by multiple coordinate pairs, |
| 2494 | // which should be treated as linetos. |
| 2495 | cmd = (cmd == 'm') ? 'l' : 'L'; |
| 2496 | rargs = nsvg__getArgsPerElement(cmd); |
| 2497 | cpx2 = cpx; cpy2 = cpy; |
| 2498 | break; |
| 2499 | case 'l': |
| 2500 | case 'L': |
| 2501 | nsvg__pathLineTo(p, &cpx, &cpy, args, cmd == 'l' ? 1 : 0); |
| 2502 | cpx2 = cpx; cpy2 = cpy; |
| 2503 | break; |
| 2504 | case 'H': |
| 2505 | case 'h': |
| 2506 | nsvg__pathHLineTo(p, &cpx, &cpy, args, cmd == 'h' ? 1 : 0); |
| 2507 | cpx2 = cpx; cpy2 = cpy; |
| 2508 | break; |
| 2509 | case 'V': |
| 2510 | case 'v': |
no test coverage detected