diff --git a/ext/import-svg.cpp b/ext/import-svg.cpp index 86f2ef4..d2fa7cc 100644 --- a/ext/import-svg.cpp +++ b/ext/import-svg.cpp @@ -5,6 +5,7 @@ #ifndef MSDFGEN_DISABLE_SVG +#include #include #include #include "../core/arithmetics.hpp" @@ -261,6 +262,40 @@ bool buildShapeFromSvgPath(Shape &shape, const char *pathDef, double endpointSna return true; } +static void getPathElements(tinyxml2::XMLElement *parent, std::vector *vectorPath) { + for (tinyxml2::XMLElement* child = parent->FirstChildElement("path"); child != NULL; child = child->NextSiblingElement("path")) + { + vectorPath->push_back(child); + } +} + +static void getGroupElements(tinyxml2::XMLElement *element, std::vector *vectorPath) { + std::vector groupPath; + for (tinyxml2::XMLElement* child = element->FirstChildElement("g"); child != NULL; child = child->NextSiblingElement("g")) + { + groupPath.push_back(child); + } + if(groupPath.size() != 0) + { + for (std::vector::iterator element = groupPath.begin(); element != groupPath.end(); ++element ) + { + getPathElements((*element),vectorPath); + getGroupElements((*element),vectorPath); + } + } +} + +static std::vector getRawPaths(std::vector *vectorPath) { + std::vector stringVector; + for (std::vector::iterator element = vectorPath->begin(); element != vectorPath->end(); ++element) + { + char *pd = strdup((*element)->Attribute("d")); + if (pd) + stringVector.push_back(pd); + } + return stringVector; +} + bool loadSvgShape(Shape &output, const char *filename, int pathIndex, Vector2 *dimensions) { tinyxml2::XMLDocument doc; if (doc.LoadFile(filename)) @@ -268,33 +303,16 @@ bool loadSvgShape(Shape &output, const char *filename, int pathIndex, Vector2 *d tinyxml2::XMLElement *root = doc.FirstChildElement("svg"); if (!root) return false; - + tinyxml2::XMLElement *path = NULL; + std::vector vectorPath; if (pathIndex > 0) { - path = root->FirstChildElement("path"); - if (!path) { - tinyxml2::XMLElement *g = root->FirstChildElement("g"); - if (g) - path = g->FirstChildElement("path"); - } - while (path && --pathIndex > 0) - path = path->NextSiblingElement("path"); + getPathElements(root,&vectorPath); + getGroupElements(root,&vectorPath); } else { - path = root->LastChildElement("path"); - if (!path) { - tinyxml2::XMLElement *g = root->LastChildElement("g"); - if (g) - path = g->LastChildElement("path"); - } - while (path && ++pathIndex < 0) - path = path->PreviousSiblingElement("path"); + getPathElements(root,&vectorPath); + getGroupElements(root,&vectorPath); } - if (!path) - return false; - const char *pd = path->Attribute("d"); - if (!pd) - return false; - output.contours.clear(); output.inverseYAxis = true; Vector2 dims(root->DoubleAttribute("width"), root->DoubleAttribute("height")); @@ -306,9 +324,21 @@ bool loadSvgShape(Shape &output, const char *filename, int pathIndex, Vector2 *d } if (dimensions) *dimensions = dims; - return buildShapeFromSvgPath(output, pd, ENDPOINT_SNAP_RANGE_PROPORTION*dims.length()); + + std::vector pathCollection = getRawPaths(&vectorPath); + if(pathCollection.size() == 0) + return false; + + for (std::vector::iterator path = pathCollection.begin(); path != pathCollection.end(); ++path) + { + if(buildShapeFromSvgPath(output, (*path), ENDPOINT_SNAP_RANGE_PROPORTION*dims.length()) == false) + { + return false; + } + } + return true; } } -#endif +#endif \ No newline at end of file