def _extract_paths(group: svgelements.Group, recursive) -> _PathListType: """Extract everything from the provided SVG group.""" if recursive: everything = group.select() else: everything = group paths = [] for elem in everything: if hasattr(elem, "values") and elem.values.get("visibility", "") in ( "hidden", "collapse", ): continue if isinstance(elem, svgelements.Path): if len(elem) != 0: paths.append(elem) elif isinstance(elem, (svgelements.Polyline, svgelements.Polygon)): # Here we add a "fake" path containing just the Polyline/Polygon, # to be treated specifically by _convert_flattened_paths. path = [svgelements.Move(elem.points[0]), elem] if isinstance(elem, svgelements.Polygon): path.append(svgelements.Close(elem.points[-1], elem.points[0])) paths.append(path) elif isinstance(elem, svgelements.Shape): e = svgelements.Path(elem) e.reify( ) # In some cases the shape could not have reified, the path must. if len(e) != 0: paths.append(e) return paths
def path_to_polylines(path_or_svgd, start=0j, tolerance=0.1): def subdivide_cubicBezier(cubic): for x, y in islice( aggsubdivision.bezier( (cubic.start.real, cubic.start.imag), (cubic.control1.real, cubic.control1.imag), (cubic.control2.real, cubic.control2.imag), (cubic.end.real, cubic.end.imag), distance_tolerance=tolerance), 1, None): yield complex(x, y) def subpath_to_polyline(subpath): for seg in subpath: if isinstance(seg, svgelements.Move): yield complex(*seg.end) elif isinstance(seg, svgelements.Line): yield complex(*seg.end) elif isinstance(seg, svgelements.CubicBezier): yield from subdivide_cubicBezier(seg) elif isinstance(seg, svgelements.QuadraticBezier): cubic = svgelements.CubicBezier( seg.start, 1 / 3 * seg.start + 2 / 3 * seg.control, 2 / 3 * seg.control + 1 / 3 * seg.end, seg.end) yield from subdivide_cubicBezier(cubic) elif isinstance(seg, svgelements.Arc): for cubic in seg.as_cubic_curves(): yield from subdivide_cubicBezier(cubic) elif isinstance(seg, svgelements.Close): yield complex(*seg.end) else: logging.warn('unimplemented segement type %s', type(seg)) if isinstance(path_or_svgd, svgelements.Path): path = path_or_svgd else: path = svgelements.Path() path.append(svgelements.Move(start)) path.parse(path_or_svgd) path.pop(0) for subpath in path.as_subpaths(): if subpath: yield list(subpath_to_polyline(subpath))