| 34 | } |
| 35 | |
| 36 | void SVGParser::parse(const std::string& filename, bool keep_bbox) { |
| 37 | NSVGimage* image = nsvgParseFromFile(filename.c_str(), "px", 96); |
| 38 | if (!image) { |
| 39 | throw IOError("Error: " + filename + " does not exist."); |
| 40 | } |
| 41 | const auto width = image->width; |
| 42 | const auto height = image->height; |
| 43 | |
| 44 | if (keep_bbox) { add_bbox(width, height); } |
| 45 | |
| 46 | for (auto shape = image->shapes; shape != NULL; shape=shape->next) { |
| 47 | for (auto path = shape->paths; path != NULL; path=path->next) { |
| 48 | const int v_first = m_vertices.size(); |
| 49 | for (size_t i=0; i<path->npts-1; i+=3) { |
| 50 | float* p = &path->pts[i*2]; |
| 51 | // SVG's coordinate system is left handed. |
| 52 | const Vector2F p0{p[0], -p[1]}; |
| 53 | const Vector2F p1{p[2], -p[3]}; |
| 54 | const Vector2F p2{p[4], -p[5]}; |
| 55 | const Vector2F p3{p[6], -p[7]}; |
| 56 | assert(p0.array().isFinite().all()); |
| 57 | assert(p3.array().isFinite().all()); |
| 58 | if (!std::isfinite(p1[0]) || !std::isfinite(p1[1]) || |
| 59 | !std::isfinite(p2[0]) || !std::isfinite(p2[1])) { |
| 60 | add_line_segment(p0, p3, i!=0); |
| 61 | } else { |
| 62 | const auto tol = ( |
| 63 | (p1-p0).norm() + |
| 64 | (p2-p1).norm() + |
| 65 | (p3-p2).norm()) * 1e-3; |
| 66 | add_bezier_curve(p0, p1, p2, p3, tol, 0, i!=0); |
| 67 | } |
| 68 | } |
| 69 | const int v_last = m_vertices.size()-1; |
| 70 | if (path->closed) { |
| 71 | m_edges.emplace_back(v_last, v_first); |
| 72 | } |
| 73 | } |
| 74 | } |
| 75 | nsvgDelete(image); |
| 76 | } |
| 77 | |
| 78 | |
| 79 | void SVGParser::add_bbox(Float width, Float height) { |
no test coverage detected