コード例 #1
0
 def fixVHbehaviour(self, elem):
     raw = Path(elem.get("d")).to_arrays()
     subpaths, prev = [], 0
     for i in range(len(raw)): # Breaks compound paths into simple paths
         if raw[i][0] == 'M' and i != 0:
             subpaths.append(raw[prev:i])
             prev = i
     subpaths.append(raw[prev:])
     seg = []
     for simpath in subpaths:
         if simpath[-1][0] == 'Z':
             simpath[-1][0] = 'L'
             if simpath[-2][0] == 'L': simpath[-1][1] = simpath[0][1]
             else: simpath.pop()
         for i in range(len(simpath)):
             if simpath[i][0] == 'V': # vertical and horizontal lines only have one point in args, but 2 are required
                 #inkex.utils.debug(simpath[i][0])
                 simpath[i][0]='L' #overwrite V with regular L command
                 add=simpath[i-1][1][0] #read the X value from previous segment
                 simpath[i][1].append(simpath[i][1][0]) #add the second (missing) argument by taking argument from previous segment
                 simpath[i][1][0]=add #replace with recent X after Y was appended
             if simpath[i][0] == 'H': # vertical and horizontal lines only have one point in args, but 2 are required
                 #inkex.utils.debug(simpath[i][0])
                 simpath[i][0]='L' #overwrite H with regular L command
                 simpath[i][1].append(simpath[i-1][1][1]) #add the second (missing) argument by taking argument from previous segment				
             #inkex.utils.debug(simpath[i])
             seg.append(simpath[i])
     elem.set("d", Path(seg))
     return seg
コード例 #2
0
    def effect(self):
        path_strings = []
        net_strings = ["M"]
        my_path = etree.Element(inkex.addNS('path', 'svg'))
        s = {
            'stroke-width': self.options.s_width,
            'stroke': '#000000',
            'fill': 'none'
        }
        my_path.set('style', str(inkex.Style(s)))
        for id, node in self.svg.selected.items():
            if node.tag == inkex.addNS('path', 'svg'):
                d = node.get('d')
                p = CubicSuperPath(Path(d))
                for subpath in p:
                    for i, csp in enumerate(subpath):
                        path_strings.append("%f,%f" % (csp[1][0], csp[1][1]))
                node.set('d', str(Path(p)))

                while len(path_strings) > 0:
                    net_strings.append(path_strings.pop(0))
                    if len(path_strings) > 0:
                        net_strings.append(path_strings.pop())
                my_path.set('d', " ".join(net_strings))
                self.svg.get_current_layer().append(my_path)
コード例 #3
0
ファイル: vh_to_line.py プロジェクト: hasantahir/myinkspace
 def effect(self):
     if len(self.svg.selected) == 0: exit("Please select at least one path.")
     for obj in self.svg.selected: # The objects are the paths, which may be compound
         if obj.tag == inkex.addNS('path','svg'):
             curr = self.svg.selected[obj]
             raw = Path(curr.get("d")).to_arrays()
             subpaths, prev = [], 0
             for i in range(len(raw)): # Breaks compound paths into simple paths
                 if raw[i][0] == 'M' and i != 0:
                     subpaths.append(raw[prev:i])
                     prev = i
             subpaths.append(raw[prev:])
 			
             seg = []
             for simpath in subpaths:
                 if simpath[-1][0] == 'Z':
                     simpath[-1][0] = 'L'
                     if simpath[-2][0] == 'L': simpath[-1][1] = simpath[0][1]
                     else: simpath.pop()
                 for i in range(len(simpath)):
                     if simpath[i][0] == 'V': # vertical and horizontal lines only have one point in args, but 2 are required
                         #inkex.utils.debug(simpath[i][0])
                         simpath[i][0]='L' #overwrite V with regular L command
                         add=simpath[i-1][1][0] #read the X value from previous segment
                         simpath[i][1].append(simpath[i][1][0]) #add the second (missing) argument by taking argument from previous segment
                         simpath[i][1][0]=add #replace with recent X after Y was appended
                     if simpath[i][0] == 'H': # vertical and horizontal lines only have one point in args, but 2 are required
                        #inkex.utils.debug(simpath[i][0])
                         simpath[i][0]='L' #overwrite H with regular L command
                         simpath[i][1].append(simpath[i-1][1][1]) #add the second (missing) argument by taking argument from previous segment				
                     #inkex.utils.debug(simpath[i])
                     seg.append(simpath[i])
             curr.set("d", Path(seg))
         else:
             inkex.utils.debug("Object " + obj.get('id') + " is not a path. Please convert it to a path first.")
コード例 #4
0
 def effect(self):
     for id, node in self.svg.selected.items():
         if node.tag == inkex.addNS('path', 'svg'):
             d = node.get('d')
             d = str(Path((Path(d).to_arrays())))
             d = re.sub(r'(?i)(m[^mz]+)', r'\1 Z ', d)
             d = re.sub(r'(?i)\s*z\s*z\s*', r' Z ', d)
             node.set('d', d)
コード例 #5
0
ファイル: test_inkex_paths.py プロジェクト: wachin/inkscape
 def test_closing(self):
     """Closing paths create two arrays"""
     path = Path("M 0,0 C 1.505,0 2.727,-0.823 2.727,-1.841 V -4.348 C 2.727,-5.363"\
                 " 1.505,-6.189 0,-6.189 H -8.3 V 0 Z m -10.713,1.991 h -0.211 V -8.178"\
                 " H 0 c 2.954,0 5.345,1.716 5.345,3.83 v 2.507 C 5.345,0.271 2.954,1.991"
                 " 0,1.991 Z")
     csp = path.to_superpath()
     self.assertEqual(len(csp), 2)
コード例 #6
0
ファイル: test_inkex_paths.py プロジェクト: wachin/inkscape
 def test_closing_without_z(self):
     """Closing paths without z create two arrays"""
     path = Path("m 51.553104,253.58572 c -11.644086,-0.14509 -4.683516,-19.48876"\
                 " 2.096523,-8.48973 1.722993,2.92995 0.781608,6.73867 -2.096523,8.48973"\
                 " m -3.100522,-13.02176 c -18.971587,17.33811 15.454875,20.05577"\
                 " 6.51412,3.75474 -1.362416,-2.30812 -3.856221,-3.74395 -6.51412,-3.75474")
     csp = path.to_superpath()
     self.assertEqual(len(csp), 2)
コード例 #7
0
def getTranslatedPath(d, posX, posY):
    if(CommonDefs.inkVer == 1.0):
        path = Path(d)
        path.translate(posX, posY, inplace = True)
        return path.to_superpath().__str__()
    else:
        path = simplepath.parsePath(d)
        simplepath.translatePath(path, posX, posY)
        return simplepath.formatPath(path)
コード例 #8
0
ファイル: test_inkex_paths.py プロジェクト: wachin/inkscape
    def test_extending(self):
        """Paths can be extended using addition"""
        ret = Path('M 20 20') + Path('L 40 40 9 10')
        self.assertEqual(type(ret), Path)
        self._assertPath(ret, 'M 20 20 L 40 40 L 9 10')

        ret = Path('M 20 20') + 'C 40 40 9 10 10 10'
        self.assertEqual(type(ret), Path)
        self._assertPath(ret, 'M 20 20 C 40 40 9 10 10 10')
コード例 #9
0
ファイル: test_inkex_paths.py プロジェクト: wachin/inkscape
    def test_bounding_box_lines(self):
        """
        Test the bounding box calculations

        A diagonal line from 20,20 to 90,90 then to +10,+10  "\"

        """
        self.assertEqual((20, 100), (20, 100),
                         Path('M 20,20 L 90,90 l 10,10 Z').bounding_box())
        self.assertEqual((10, 90), (10, 90),
                         Path('M 20,20 L 90,90 L 10,10 Z').bounding_box())
コード例 #10
0
    def recursiveFuseTransform(self,
                               node,
                               transf=[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]):
        transf = Transform(transf) * Transform(node.get("transform", None))

        if 'transform' in node.attrib:
            del node.attrib['transform']

        node = ApplyTransform.objectToPath(node)

        if 'd' in node.attrib:
            d = node.get('d')
            p = CubicSuperPath(d)
            p = Path(p).to_absolute().transform(transf, True)
            node.set('d', Path(CubicSuperPath(p).to_path()))

            self.scaleStrokeWidth(node, transf)

        elif node.tag in [
                inkex.addNS('polygon', 'svg'),
                inkex.addNS('polyline', 'svg')
        ]:
            points = node.get('points')
            points = points.strip().split(' ')
            for k, p in enumerate(points):
                if ',' in p:
                    p = p.split(',')
                    p = [float(p[0]), float(p[1])]
                    applyTransformToPoint(transf, p)
                    p = [str(p[0]), str(p[1])]
                    p = ','.join(p)
                    points[k] = p
            points = ' '.join(points)
            node.set('points', points)

            self.scaleStrokeWidth(node, transf)

        elif node.tag in [
                inkex.addNS('rect', 'svg'),
                inkex.addNS('text', 'svg'),
                inkex.addNS('image', 'svg'),
                inkex.addNS('use', 'svg'),
                inkex.addNS('circle', 'svg')
        ]:
            # node.set('transform', str(Transform(transf)))
            inkex.utils.errormsg("Shape %s not yet supported" % node.tag)

        else:
            # e.g. <g style="...">
            self.scaleStrokeWidth(node, transf)

        for child in node.getchildren():
            self.recursiveFuseTransform(child, transf)
コード例 #11
0
ファイル: test_inkex_paths.py プロジェクト: wachin/inkscape
    def test_inline_transformations(self):
        path = Path()
        self.assertTrue(path is not path.translate(10, 20))
        self.assertTrue(path is not path.transform(Transform(scale=10)))
        self.assertTrue(path is not path.rotate(10))
        self.assertTrue(path is not path.scale(10, 20))

        self.assertTrue(path is path.translate(10, 20, inplace=True))
        self.assertTrue(
            path is path.transform(Transform(scale=10), inplace=True))
        self.assertTrue(path is path.rotate(10, inplace=True))
        self.assertTrue(path is path.scale(10, 20, inplace=True))
コード例 #12
0
    def effect(self):
        unit_factor = 1.0 / self.svg.uutounit(1.0, self.options.unit)
        for id, node in self.svg.selected.items():

            #get recent XY coordinates (top left corner of the bounding box)
            bbox = node.bounding_box()
            new_horiz_scale = self.options.expected_size * unit_factor / bbox.width
            new_vert_scale = self.options.expected_size * unit_factor / bbox.height

            if self.options.scale_type == "Horizontal":
                translation_matrix = [[new_horiz_scale, 0.0, 0.0],
                                      [0.0, 1.0, 0.0]]
            elif self.options.scale_type == "Vertical":
                translation_matrix = [[1.0, 0.0, 0.0],
                                      [0.0, new_vert_scale, 0.0]]
            else:  #Uniform
                translation_matrix = [[new_horiz_scale, 0.0, 0.0],
                                      [0.0, new_vert_scale, 0.0]]
            node.transform = Transform(translation_matrix) * node.transform

            # now that the node moved we need to get the nodes XY coordinates again to fix them
            bbox_new = node.bounding_box()

            #inkex.utils.debug(cx)
            #inkex.utils.debug(cy)
            #inkex.utils.debug(cx_new)
            #inkex.utils.debug(cy_new)

            # We remove the transformation attribute from SVG XML tree in case it's regular path. In case the node is an object like arc,circle, ellipse or star we have the attribute "sodipodi:type". Then we do not play with it's path because the size transformation will not apply (this code block is ugly)
            if node.get('sodipodi:type') is None and 'd' in node.attrib:
                #inkex.utils.debug("it's a path!")
                d = node.get('d')
                p = CubicSuperPath(d)
                transf = Transform(node.get("transform", None))
                if 'transform' in node.attrib:
                    del node.attrib['transform']
                p = Path(p).to_absolute().transform(transf, True)
                node.set('d', Path(CubicSuperPath(p).to_path()))
            #else:
            #inkex.utils.debug("it's an object!")

            #we perform second translation to reset the center of the path
            translation_matrix = [[
                1.0, 0.0,
                bbox.left - bbox_new.left + (bbox.width - bbox_new.width) / 2
            ],
                                  [
                                      0.0, 1.0, bbox.top - bbox_new.top +
                                      (bbox.height - bbox_new.height) / 2
                                  ]]
            node.transform = Transform(translation_matrix) * node.transform
コード例 #13
0
    def fill_row(self, node):
        #max_line_width = self.svg.unittouu('450mm')
        #x_start = self.svg.unittouu('3mm')
        #y_start = self.svg.unittouu('1600mm') - self.svg.unittouu('3mm')
        #gap_x = gap_y = self.svg.unittouu('10mm')

        svg = self.document.getroot()
        x_start = 0
        y_start = self.svg.unittouu(svg.attrib['height'])
        max_line_width = self.svg.unittouu(svg.get('width'))

        total_width = 0
        total_height = self.total_height

        group = etree.SubElement(self.svg.get_current_layer(),
                                 addNS('g', 'svg'))

        bbox = node.bounding_box()
        x = bbox.left
        y = bbox.top
        node_width = self.options.gap_x + bbox.width

        while total_width + node_width < max_line_width:
            node_copy = deepcopy(node)
            group.append(node_copy)

            x_dest = x_start + total_width
            y_dest = y_start - (total_height + bbox.height)

            # translation logic
            if node_copy.tag == addNS('path', 'svg'):
                x_delta = x_dest - x
                y_delta = y_dest - y

                path = Path(node_copy.attrib['d'])
                path.translate(x_delta, y_delta, True)
                node_copy.attrib['d'] = str(Path(path))
            elif node_copy.tag == addNS('g', 'svg'):
                x_delta = x_dest - x
                y_delta = y_dest - y

                translation_matrix = [[1.0, 0.0, x_delta], [0.0, 1.0, y_delta]]
                Transform(translation_matrix) * node_copy.transform
            else:
                node_copy.attrib['x'] = str(x_dest)
                node_copy.attrib['y'] = str(y_dest)

            total_width += node_width

        self.total_height += group.bounding_box().height + self.options.gap_y
コード例 #14
0
ファイル: test_inkex_paths.py プロジェクト: wachin/inkscape
 def test_is_line(self):
     """Test is super path segments can detect lines"""
     path = Path("m 49,88 70,-1 c 18,17 1,59 1.7,59 "\
                 "0,0 -48.7,18 -70.5,-1 18,-15 25,-32.4 -1.5,-57.2 z")
     csp = path.to_superpath()
     self.assertTrue(csp.is_line(csp[0][0], csp[0][1]), "Should be a line")
     self.assertFalse(csp.is_line(csp[0][3], csp[0][4]),
                      "Both controls not detected")
     self.assertFalse(csp.is_line(csp[0][1], csp[0][2]),
                      "Start control not detected")
     self.assertFalse(csp.is_line(csp[0][2], csp[0][3]),
                      "End control not detected")
     # Also tests if zone close is applied correctly.
     self.assertEqual(str(csp.to_path()), "M 49 88 L 119 87 C 137 104 120 146 120.7 146 "\
         "C 120.7 146 72 164 50.2 145 C 68.2 130 75.2 112.6 48.7 87.8 Z")
コード例 #15
0
ファイル: test_inkex_paths.py プロジェクト: wachin/inkscape
    def test_relative(self):
        """Paths can be converted to relative"""
        ret = Path("M 100 100 L 110 120 140 140 300 300")
        self._assertPath(ret.to_relative(),
                         "m 100 100 l 10 20 l 30 20 l 160 160")

        ret = Path("M 150,150 A 76,55 0 1 1 433,278")
        self._assertPath(ret.to_relative(), "m 150 150 a 76 55 0 1 1 283 128")

        ret = Path("M 1 2 H 3 V 3 Z M 5 2 H 7 V 3 Z M 5 4 H 7 V 5 Z")
        self._assertPath(ret.to_relative(),
                         "m 1 2 h 2 v 1 z m 4 0 h 2 v 1 z m 0 2 h 2 v 1 z")
コード例 #16
0
def morphPath(path, axes):
    bounds = [y for x in list(Path(path).bounding_box()) for y in list(x)]
    assert len(bounds) == 4
    new_path = []
    current = [0.0, 0.0]
    start = [0.0, 0.0]

    for cmd, params in path:
        segmentType = cmd
        points = params
        if segmentType == "M":
            start[0] = points[0]
            start[1] = points[1]
        segmentType = convertSegmentToCubic(current, segmentType, points,
                                            start)
        percentages = [0.0] * len(points)
        morphed = [0.0] * len(points)
        numPts = getNumPts(segmentType)
        normalizePoints(bounds, points, percentages, numPts)
        mapPointsToMorph(axes, percentages, morphed, numPts)
        addSegment(new_path, segmentType, morphed)
        if len(points) >= 2:
            current[0] = points[len(points) - 2]
            current[1] = points[len(points) - 1]
    return new_path
コード例 #17
0
 def path_round_it(self, node):
     if node.tag == inkex.addNS('path', 'svg'):
         d = node.get('d')
         p = CubicSuperPath(d)
         for subpath in p:
             for csp in subpath:
                 delta = self.roundit(csp[1])
                 if self.options.along:
                     csp[0][0] += delta[0]
                     csp[0][1] += delta[1]
                 csp[1][0] += delta[0]
                 csp[1][1] += delta[1]
                 if self.options.along:
                     csp[2][0] += delta[0]
                     csp[2][1] += delta[1]
                 if self.options.ctrl:
                     delta = self.roundit(csp[0])
                     csp[0][0] += delta[0]
                     csp[0][1] += delta[1]
                     delta = self.roundit(csp[2])
                     csp[2][0] += delta[0]
                     csp[2][1] += delta[1]
         node.set('d', str(Path(p)))
     elif node.tag == inkex.addNS('g', 'svg'):
         for e in node:
             self.path_round_it(e)
コード例 #18
0
ファイル: test_inkex_paths.py プロジェクト: wachin/inkscape
    def test_scale(self):
        """Paths can be scaled using the times operator"""
        ret = Path('M 10,10 L 30,30 C 20 20 10 10 10 10 l 10 10').scale(2.5, 3)
        self._assertPath(ret, 'M 25 30 L 75 90 C 50 60 25 30 25 30 l 25 30')

        ret = Path(
            "M 29.867708,101.68274 A 14.867708,14.867708 0 0 1 15,116.55045 14.867708,"
            "14.867708 0 0 1 0.13229179,101.68274 14.867708,14.867708 0 0 1 15,86.815031 "
            "14.867708,14.867708 0 0 1 29.867708,101.68274 Z")
        ret = ret.scale(1.2, 0.8)
        self._assertPath(
            ret, 'M 35.8412 81.3462 '
            'A 17.8412 11.8942 0 0 1 18 93.2404 '
            'A 17.8412 11.8942 0 0 1 0.15875 81.3462 '
            'A 17.8412 11.8942 0 0 1 18 69.452 '
            'A 17.8412 11.8942 0 0 1 35.8412 81.3462 Z')
コード例 #19
0
    def breakContours(self, node):  #this does the same as "CTRL + SHIFT + K"
        if node.tag == inkex.addNS('path', 'svg'):
            parent = node.getparent()
            idx = parent.index(node)
            idSuffix = 0
            raw = Path(node.get("d")).to_arrays()
            subPaths, prev = [], 0
            for i in range(
                    len(raw)):  # Breaks compound paths into simple paths
                if raw[i][0] == 'M' and i != 0:
                    subPaths.append(raw[prev:i])
                    prev = i
            subPaths.append(raw[prev:])
            for subpath in subPaths:
                replacedNode = copy.copy(node)
                oldId = replacedNode.get('id')

                replacedNode.set('d', CubicSuperPath(subpath))
                replacedNode.set('id', oldId + str(idSuffix).zfill(5))
                parent.insert(idx, replacedNode)
                idSuffix += 1
                self.replacedNodes.append(replacedNode)
            node.delete()
        for child in node:
            self.breakContours(child)
コード例 #20
0
    def effect(self):
        if len(self.options.ids) < 2:
            raise Exception(
                "Two paths must be selected. The 1st is the letter, the 2nd is the envelope and must have 4 sides."
            )
            exit()

        letterElement = self.svg.selected[self.options.ids[0]]
        envelopeElement = self.svg.selected[self.options.ids[1]]

        if letterElement.tag != inkex.addNS(
                'path', 'svg') or envelopeElement.tag != inkex.addNS(
                    'path', 'svg'):
            raise Exception("Both letter and envelope must be SVG paths.")
            exit()

        axes = extractMorphAxes(Path(envelopeElement.get('d')).to_arrays())
        if axes is None:
            raise Exception("No axes found on envelope.")
        axisCount = len(axes)
        if axisCount < 4:
            raise Exception("The envelope path has less than 4 segments.")
        for i in range(0, 4):
            if axes[i] is None:
                raise Exception("axes[%i] is None" % i)
        # morph the enveloped element according to the axes
        morph_element(letterElement, envelopeElement, axes)
コード例 #21
0
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
コード例 #22
0
def getCubicSuperPath(d = None):
    if(CommonDefs.inkVer == 1.0):
        if(d == None): return CubicSuperPath([])
        return CubicSuperPath(Path(d).to_superpath())
    else:
        if(d == None): return []
        return CubicSuperPath(simplepath.parsePath(d))
コード例 #23
0
ファイル: test_inkex_paths.py プロジェクト: wachin/inkscape
 def test_passthrough(self):
     """Create a path and test the re-rendering of the commands"""
     for path in (
             'M 50,50 L 10,10 m 10 10 l 2.1,2',
             'm 150 150 c 10 10 6 6 20 10 L 10 10',
     ):
         self._assertPath(Path(path), path.replace(',', ' '))
コード例 #24
0
    def scaleCubicSuper(self, cspath, scaleFactor, scaleFrom):
        bbox = Path(cspath).bounding_box()

        if (scaleFrom == 'topLeft'):
            oldOrigin = [bbox.left, bbox.bottom]
        elif (scaleFrom == 'topRight'):
            oldOrigin = [bbox.right, bbox.bottom]
        elif (scaleFrom == 'bottomLeft'):
            oldOrigin = [bbox.left, bbox.top]
        elif (scaleFrom == 'bottomRight'):
            oldOrigin = [bbox.right, bbox.top]
        else:  #if(scaleFrom == 'center'):
            oldOrigin = [
                bbox.left + (bbox.right - bbox.left) / 2.,
                bbox.bottom + (bbox.top - bbox.bottom) / 2.
            ]

        newOrigin = [oldOrigin[0] * scaleFactor, oldOrigin[1] * scaleFactor]

        for subpath in cspath:
            for bezierPt in subpath:
                for i in range(0, len(bezierPt)):

                    bezierPt[i] = [
                        bezierPt[i][0] * scaleFactor,
                        bezierPt[i][1] * scaleFactor
                    ]

                    bezierPt[i][0] += (oldOrigin[0] - newOrigin[0])
                    bezierPt[i][1] += (oldOrigin[1] - newOrigin[1])
コード例 #25
0
 def _prep(val):
     if val:
         if attr == 'd':
             from inkex.paths import Path
             return [attr] + Path(val).to_arrays()
         return (attr, val)
     return val
コード例 #26
0
ファイル: test_inkex_paths.py プロジェクト: wachin/inkscape
 def test_control_points(self):
     """Test how x,y points are extracted"""
     for path, ret in (
         ('M 100 100', ((100, 100), )),
         ('L 100 100', ((100, 100), )),
         ('H 133', ((133, 0), )),
         ('V 144', ((0, 144), )),
         ('Q 40 20 12 99 T 100 100', (
             (40, 20),
             (12, 99),
             (-16, 178),
             (100, 100),
         )),
         ('C 12 12 15 15 20 20', ((12, 12), (15, 15), (20, 20))),
         ('S 50 90 30 10', (
             (0, 0),
             (50, 90),
             (30, 10),
         )),
         ('Q 40 20 12 99', (
             (40, 20),
             (12, 99),
         )),
         ('A 1,2,3,0,0,10,20', ((10, 20), )),
         ('Z', ((0, 0), )),
     ):
         points = list(Path(path).control_points)
         self.assertEqual(len(points), len(ret), msg=path)
         self.assertTrue(all(p.is_close(r) for p, r in zip(points, ret)),
                         msg=path)
コード例 #27
0
 def convertPath(self, node):
     if node.tag == inkex.addNS('path', 'svg'):
         polypath = []
         i = 0
         for x, y in node.path.end_points:
             if i == 0:
                 polypath.append(['M', [x, y]])
             else:
                 polypath.append(['L', [x, y]])
                 if i == 1 and polypath[len(polypath) -
                                        2][1] == polypath[len(polypath) -
                                                          1][1]:
                     polypath.pop(
                         len(polypath) - 1
                     )  #special handling for the seconds point after M command
                 elif polypath[len(polypath) -
                               2] == polypath[len(polypath) -
                                              1]:  #get the previous point
                     polypath.pop(len(polypath) - 1)
             i += 1
             node.set('d', str(Path(polypath)))
     children = node.getchildren()
     if children is not None:
         for child in children:
             self.convertPath(child)
コード例 #28
0
    def effect(self):
        elements = self.document.xpath('//svg:path', namespaces=inkex.NSS)
        for el in elements:
            oldpathstring = el.attrib['d']
            nodes = Path(oldpathstring).to_arrays()
            currentSection = []
            sections = [currentSection]
            for node in nodes:
                command = node.pop(0)
                currentSection.append(
                    command + ' ' +
                    ' '.join(list(map(lambda c: ','.join(map(str, c)), node))))
                if command.lower() == 'z':
                    currentSection = []
                    sections.append(currentSection)

            sections = list(
                map(lambda n: ' '.join(n),
                    filter(lambda n: len(n) > 0, sections)))

            if (sections[-1][-2].lower() != 'z'):
                nonClosedSection = ' ' + sections.pop()
            else:
                nonClosedSection = ''

            sections = filter(lambda s: s[0].lower() != 'z', sections)
            sections = sorted(sections, key=getArea)
            newpathstring = "z ".join(sections) + nonClosedSection
            el.set('d', newpathstring)
コード例 #29
0
ファイル: test_inkex_paths.py プロジェクト: wachin/inkscape
 def test_to_arrays(self):
     """Return the full path as a bunch of arrays"""
     ret = Path("M 100 100 L 110 120 H 20 C 120 0 6 10 10 2 Z").to_arrays()
     self.assertEqual(len(ret), 5)
     self.assertEqual(ret[0][0], 'M')
     self.assertEqual(ret[1][0], 'L')
     self.assertEqual(ret[2][0], 'L')
     self.assertEqual(ret[3][0], 'C')
コード例 #30
0
ファイル: test_inkex_paths.py プロジェクト: wachin/inkscape
 def test_transform(self):
     """Transform by a whole matrix"""
     ret = Path("M 100 100 L 110 120 L 140 140 L 300 300")
     ret = ret.transform(Transform(translate=(10, 10)))
     self.assertEqual(str(ret), 'M 110 110 L 120 130 L 150 150 L 310 310')
     ret = ret.transform(Transform(translate=(-10, -10)))
     self.assertEqual(str(ret), 'M 100 100 L 110 120 L 140 140 L 300 300')
     ret = Path('M 5 5 H 10 V 15')
     ret = ret.transform(Transform(rotate=-10))
     self.assertEqual(
         'M 5.79228 4.0558 '
         'L 10.7163 3.18756 '
         'L 12.4528 13.0356', str(ret))
     ret = Path("M 10 10 A 50,50 0 0 1 85.355333,85.355341 L 100 0")
     ret = ret.transform(Transform(scale=10))
     self.assertEqual(str(ret),
                      'M 100 100 A 500 500 0 0 1 853.553 853.553 L 1000 0')
     self.assertRaises(ValueError, Horz([10]).transform, Transform())