def morph_path(path, axes): bounds = [ y for x in list(Path(paths.Path(path).to_superpath()).bounding_box()) for y in list(x) ] new_path = [] current = [0.0, 0.0] start = [0.0, 0.0] for cmd, params in path: segment_type = cmd points = params if segment_type == "M": start[0] = points[0] start[1] = points[1] segment_type = convert_segment_to_cubic(current, segment_type, points, start) percentages = [0.0] * len(points) morphed = [0.0] * len(points) num_points = get_num_points(segment_type) normalize_points(bounds, points, percentages, num_points) map_points_to_morph(axes, percentages, morphed, num_points) add_segment(new_path, segment_type, morphed) if len(points) >= 2: current[0] = points[len(points) - 2] current[1] = points[len(points) - 1] return new_path
def _process_bbox(self): bbox = [ paths.Path(node.get("d")).bounding_box() for node in self.node.iterdescendants(SVG_PATH_TAG) if not node.get(CONNECTION_END, None) ] left, right = min([box.left for box in bbox]), max([box.right for box in bbox]) self.width = right - left self.min_x = left
def _move_to_origin(self): translate_x = -self.min_x translate_y = -self.baseline transform = transforms.Transform("translate(%s, %s)" % (translate_x, translate_y)) for node in self.node.iter(SVG_PATH_TAG): path = paths.Path(node.get("d")) path = path.transform(transform) node.set('d', str(path)) node.attrib.pop('transform', None) # Move commands as well for node in self.node.iter(SVG_USE_TAG): oldx = units.convert_unit(node.get("x", 0), 'px', node.unit) oldy = units.convert_unit(node.get("y", 0), 'px', node.unit) x, y = transform.apply_to_point((oldx, oldy)) node.set('x', x) node.set('y', y)
def effect(self): seenSegments = set() coordsCache = FixedRadiusSearch() for element in self.svg.selected.values(): if element.tag == inkex.addNS('path','svg'): d = element.get('d') path = paths.CubicSuperPath(d).to_path().to_arrays() newPath = [] start = prev = None pathclosed = True for i in range(0, len(path)): command = path[i][0] coords = path[i][1] newCoords = [] for x, y in zip(*[iter(coords)]*2): newCoords.extend(list(coordsCache.get_or_add((x, y)))) coords = newCoords tcoords = tuple(coords) if command == 'M': #remove this M command and it's point, if the next dataset conaints an M command too. # Like "M 49.8584,109.276 M ..." which creates just a single point but not a valid path if i+1 != len(path) and path[i][0] == path[i+1][0]: continue newPath.append([command, coords]) start = prev = tcoords pathclosed = True elif command == 'L': if ('L', prev, tcoords) in seenSegments or \ ('L', tcoords, prev) in seenSegments: newPath.append(['M', coords]) pathclosed = False else: newPath.append([command, coords]) seenSegments.add(('L', prev, tcoords)) prev = tcoords elif command == 'Z': if ('L', prev, start) in seenSegments or \ ('L', start, prev) in seenSegments: newPath.append(['M', start]) else: if pathclosed: newPath.append([command, coords]) else: newPath.append(['L', start]) seenSegments.add(('L', prev, start)) prev = start elif command == 'C': if ('C', prev, tcoords) in seenSegments or \ ('C', tcoords[4:], (tcoords[2:4], tcoords[0:2], prev)) in seenSegments: newPath.append(['M', coords[4:]]) else: newPath.append(['C', coords]) seenSegments.add(('C', prev, tcoords)) prev = tcoords[4:] else: newPath.append([command, coords]) while len(newPath) and newPath[-1][0] == 'M': newPath = newPath[:-1] element.set('d',str(paths.Path(newPath)))
def formatPath(p): return str(paths.Path(unCubicSuperPath(p)))
def parsePath(d): return paths.CubicSuperPath(paths.Path(d))
def CubicSuperPath(simplepath): return paths.Path(simplepath).to_superpath()
def effect(self): # loop over all selected paths if self.options.selection == "Path_lengthselection": for id, node in self.svg.selected.items(): if node.tag == inkex.addNS('path', 'svg'): l1, l2, l3, l4, l5 = [], [], [], [], [] p = paths.CubicSuperPath(inkex.paths.Path(node.get('d'))) slengths = csplength(p) b = [slengths, p] # path length select for x in range(0, len(slengths)): if sum(b[0][x]) < self.options.len1: l1.append(b[1][x]) if self.options.len2 > sum( b[0][x]) >= self.options.len1: l2.append(b[1][x]) if self.options.len3 > sum( b[0][x]) >= self.options.len2: l3.append(b[1][x]) if self.options.len4 > sum( b[0][x]) >= self.options.len3: l4.append(b[1][x]) if sum(b[0][x]) >= self.options.len4: l5.append(b[1][x]) # make path lensel = [l1, l2, l3, l4, l5] strlen = [ '#FF0001', '#00FF02', '#AAFF03', '#87CEE4', '#000FF5' ] for i, x in zip(strlen, lensel): s = { 'stroke-linejoin': 'miter', 'stroke-width': '0.5px', 'stroke-opacity': '1.0', 'fill-opacity': '1.0', 'stroke': i, 'stroke-linecap': 'butt', 'fill': 'none' } attribs = { 'style': str(inkex.Style(s)), 'd': str( paths.Path( paths.CubicSuperPath(x).to_path().to_arrays())) } etree.SubElement(node.getparent(), inkex.addNS('path', 'svg'), attribs) if self.options.selection == "Path_slantselection": for id, node in self.svg.selected.items(): if node.tag == inkex.addNS('path', 'svg'): hor1, ver2, slan3 = [], [], [] p = paths.CubicSuperPath(inkex.paths.Path(node.get('d'))) # path slant select for i, x in enumerate(p): tn = roughBBox(x) if tn < self.options.hor: hor1.append(p[i]) elif tn > self.options.ver: ver2.append(p[i]) else: slan3.append(p[i]) # make path slnsel = [hor1, ver2, slan3] strsln = ['#FF0001', '#00FF02', '#000FF5'] for i, x in zip(strsln, slnsel): s = { 'stroke-linejoin': 'miter', 'stroke-width': '0.5px', 'stroke-opacity': '1.0', 'fill-opacity': '1.0', 'stroke': i, 'stroke-linecap': 'butt', 'fill': 'none' } attribs = { 'style': str(inkex.Style(s)), 'd': str( paths.Path( paths.CubicSuperPath(x).to_path().to_arrays())) } etree.SubElement(node.getparent(), inkex.addNS('path', 'svg'), attribs)