| 2631 | } |
| 2632 | |
| 2633 | static void nsvg__parseUse(NSVGparser* p, const char** dict) |
| 2634 | { |
| 2635 | NSVGattrib* attr = nsvg__getAttr(p); |
| 2636 | NSVGshape* shape = NULL; |
| 2637 | NSVGshape* ref = NULL; |
| 2638 | NSVGsymbol* refSym = NULL; |
| 2639 | int i; |
| 2640 | |
| 2641 | float x = 0.0f; |
| 2642 | float y = 0.0f; |
| 2643 | float xform[6]; |
| 2644 | |
| 2645 | for (i = 0; dict[i]; i += 2) { |
| 2646 | if (strcmp(dict[i], "x") == 0) { |
| 2647 | x = nsvg__parseCoordinate(p, dict[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); |
| 2648 | } else if (strcmp(dict[i], "y") == 0) { |
| 2649 | y = nsvg__parseCoordinate(p, dict[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); |
| 2650 | } else if (strcmp(dict[i], "xlink:href") == 0) { |
| 2651 | const char *href = dict[i+1]; |
| 2652 | refSym = p->symbols; |
| 2653 | while (refSym) { |
| 2654 | if (strcmp(refSym->id, href+1) == 0) |
| 2655 | break; |
| 2656 | refSym = refSym->next; |
| 2657 | } |
| 2658 | if (!refSym) { |
| 2659 | ref = p->image->shapes; |
| 2660 | while (ref) { |
| 2661 | if (strcmp(ref->id, href+1) == 0) |
| 2662 | break; |
| 2663 | ref = ref->next; |
| 2664 | } |
| 2665 | } |
| 2666 | if (!ref && !refSym) { |
| 2667 | return; // use without ref |
| 2668 | } |
| 2669 | } else { |
| 2670 | nsvg__parseAttr(p, dict[i], dict[i + 1]); |
| 2671 | } |
| 2672 | } |
| 2673 | |
| 2674 | if (refSym) { |
| 2675 | x -= refSym->viewBox[0]; |
| 2676 | y -= refSym->viewBox[1]; |
| 2677 | } else if (ref) { |
| 2678 | x -= ref->bounds[0]; |
| 2679 | y -= ref->bounds[1]; |
| 2680 | } |
| 2681 | |
| 2682 | nsvg__xformSetTranslation(&xform[0], x, y); |
| 2683 | nsvg__xformMultiply(&xform[0], attr->xform); //translate before rotate |
| 2684 | // DumpFloat2("use xform", xform, 6); |
| 2685 | |
| 2686 | if (ref) { |
| 2687 | shape = (NSVGshape*)AllocateCopyPool(sizeof(NSVGshape), ref); |
| 2688 | if (!shape) return; |
| 2689 | memcpy(shape->xform, &xform[0], sizeof(float)*6); |
| 2690 | shape->isSymbol = FALSE; |
no test coverage detected