Example #1
0
    def test_get_elements(self):
        """ Tests that elements passed to the constructor are used
        """

        root = etree.Element("root")
        element1 = etree.SubElement(root, "path")
        element2 = etree.SubElement(root, "rect")

        extractor = PathsExtractor([element1, element2], to_mm, "wId")

        self.assertEqual(extractor.get_elements(), [element1, element2])
Example #2
0
    def test_remove_working_area(self):
        """ Tests that the working area is not considered among svg elements to use
        """

        root = etree.Element("root")
        working_area = etree.SubElement(root, "svg", {"id": "wId"})
        other_element = etree.SubElement(root, "path")

        extractor = PathsExtractor([working_area, other_element], to_mm, "wId")

        self.assertEqual(extractor.get_elements(), [other_element])
    def place(self, nodes):
        max_line_width = self.unittouu('450mm')

        x_gap = y_gap = self.unittouu('10mm')
        x_start = self.unittouu('3mm')
        y_start = self.unittouu('1600mm') - self.unittouu('3mm')

        total_width = 0
        total_height = 0

        line_nodes = []

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

        for id, node, bbox in nodes:
            x, _, y, _ = bbox

            node_width = x_gap + self.width(bbox)
            # reached end of line, reset, move higher, start new group
            if total_width + node_width > max_line_width:
                group = etree.SubElement(self.current_layer, addNS('g', 'svg'))
                total_width = 0
                total_height += self.height(
                    self.computeBBox(line_nodes)) + y_gap
                line_nodes = []

            group.append(node)

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

            if node.tag == addNS('path', 'svg'):
                x_delta = x_dest - x
                y_delta = y_dest - y

                path = parsePath(node.attrib['d'])
                translatePath(path, x_delta, y_delta)
                node.attrib['d'] = formatPath(path)
            elif node.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]]
                applyTransformToNode(translation_matrix, node)

            else:
                node.attrib['x'] = str(x_dest)
                node.attrib['y'] = str(y_dest)

            total_width += node_width
            line_nodes.append(node)
Example #4
0
    def test_closed_paths(self):
        """ Tests that closed paths are extracted correctly by repeating the first point at the end
        """

        root = etree.Element("root")
        group = etree.SubElement(root, "{http://www.w3.org/2000/svg}g")
        etree.SubElement(group, "{http://www.w3.org/2000/svg}path",
                         {'d': "M 70,800 l 125,-300 l 60,490 Z"})

        extractor = PathsExtractor([group], to_mm, "wId")
        extractor.extract()

        self.assertEqual(len(extractor.paths()), 1)
        self.assertEqual(extractor.paths()[0], [(70.0, 800.0), (195.0, 500.0),
                                                (255.0, 990.0), (70.0, 800.0)])
Example #5
0
    def test_extract_paths_inside_group_keeping_transform(self):  #pylint: disable=invalid-name
        """ Tests that extracted path from a group take the transformation into account
        """

        root = etree.Element("root")
        group = etree.SubElement(root, "{http://www.w3.org/2000/svg}g",
                                 {'transform': "matrix(1,2,3,4,5,6)"})
        etree.SubElement(group, "{http://www.w3.org/2000/svg}path",
                         {'d': "M 10,20 L 50,30 L 20,70"})

        extractor = PathsExtractor([group], to_mm, "wId")
        extractor.extract()

        self.assertEqual(extractor.paths()[0], [(75.0, 106.0), (145.0, 226.0),
                                                (235.0, 326.0)])
Example #6
0
    def test_extract_path_inside_groups(self):  #pylint: disable=invalid-name
        """ Tests that a path inside a group is correctly extracted
        """

        root = etree.Element("root")
        group = etree.SubElement(root, "{http://www.w3.org/2000/svg}g")
        etree.SubElement(group, "{http://www.w3.org/2000/svg}path",
                         {'d': "M 70,800 l 125,-300 l 60,490"})

        extractor = PathsExtractor([group], to_mm, "wId")
        extractor.extract()

        self.assertEqual(len(extractor.paths()), 1)
        self.assertEqual(extractor.paths()[0], [(70.0, 800.0), (195.0, 500.0),
                                                (255.0, 990.0)])
Example #7
0
    def test_extract_paths_inside_group_keeping_nested_transform(self):  #pylint: disable=invalid-name
        """ Tests that extracted path from elements with nested transformation works correctly
        """

        root = etree.Element("root")
        group = etree.SubElement(root, "{http://www.w3.org/2000/svg}g",
                                 {'transform': "translate(10,20)"})
        subgroup = etree.SubElement(group, "{http://www.w3.org/2000/svg}g",
                                    {'transform': "matrix(1,2,3,4,5,6)"})
        etree.SubElement(subgroup, "{http://www.w3.org/2000/svg}path",
                         {'d': "M 10,20 L 50,30 L 20,70"})

        extractor = PathsExtractor([group], to_mm, "wId")
        extractor.extract()

        self.assertEqual(extractor.paths()[0], [(85.0, 126.0), (155.0, 246.0),
                                                (245.0, 346.0)])
Example #8
0
    def add(self):
        if not self.options.deckname:
            raise inkcardsError(
                "You need to give the deck name you want to add a card to.")
        svg = self.document.getroot()
        nsmap = dict(svg.nsmap, inkcards=icNS)
        card = etree.SubElement(svg, addNS('card', 'inkcards'), nsmap=nsmap)

        card.attrib['id'] = self.uniqueId('card')
        card.attrib[addNS('deck', 'inkcards')] = self.options.deckname
        card.attrib[addNS('number',
                          'inkcards')] = self.nextCardNB(card.attrib[addNS(
                              'deck', 'inkcards')])

        for lname in self.activeLayers:
            l = etree.SubElement(card, addNS('using', 'inkcards'), nsmap=nsmap)
            l.attrib[addNS('layer', 'inkcards')] = lname
        self.list()
Example #9
0
    def test_use_parent_transform_for_single_path_with_multiple_parents(self):  #pylint: disable=invalid-name
        """ Tests that extracted path takes all the ancestors transformations into account
        """

        root = etree.Element("root", {'transform': "scale(10)"})
        parent = etree.SubElement(root, "{http://www.w3.org/2000/svg}g",
                                  {'transform': "translate(10,20)"})
        element = etree.SubElement(parent, "{http://www.w3.org/2000/svg}path",
                                   {
                                       'transform': "matrix(1,2,3,4,5,6)",
                                       'd': "M 10,20 L 50,30 L 20,70"
                                   })

        extractor = PathsExtractor([element], to_mm, "wId")
        extractor.extract()

        self.assertEqual(extractor.paths()[0], [(850.0, 1260.0),
                                                (1550.0, 2460.0),
                                                (2450.0, 3460.0)])
Example #10
0
    def __add_name(self, name, layer):
        if self.separate_sizes:
            parent = self.__get_layer(layer)
        else:
            parent = self.current_layer

        text_attribs = {
            'style': self.text_style,
            'transform': self.text_transform,
            'x': str(0),
            'y': str(0),
            addNS('linespacing', 'sodipodi'): str(self.line_spacing),
        }

        line_attribs = {
            'x': str(0),
            'y': str(0),
            addNS('role', 'sodipodi'): 'line',
        }

        # make all-caps and turn whitespace into linebreak
        lines = name.upper().split()

        # skip empty strings
        if len(lines) > 0:
            # add nodes to doucument tree
            text = etree.SubElement(parent,
                                    addNS('text', 'svg'),
                                    attrib=text_attribs)
            for line in lines:
                text_line = etree.SubElement(text,
                                             addNS('tspan', 'svg'),
                                             attrib=line_attribs)
                text_line.text = line

                # set coordinates for next line
                y = float(line_attribs['y'])
                line_attribs['y'] = str(y + self.delta_y)

            if self.separate_sizes:
                self.__sort_layers()
    def test_upsert_does_not_create_duplicated_working_area(self):  # pylint: disable=invalid-name
        """ Tests that upsert does not insert a new working area if it is already present
        """
        generator = WorkingAreaGenerator(self.to_uu, "wId")
        root = etree.Element("root")
        etree.SubElement(root, "svg", {"id": "wId"})

        generator.upsert(root)

        self.assertEqual(len(root), 1)
        self.assertEqual(root[0].tag, "svg")
        self.assertEqual(root[0].get("id"), "wId")
    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
Example #13
0
    def test_extract_paths_inside_groups_and_outside(self):  #pylint: disable=invalid-name
        """ Tests that a mix of paths inside groups and outside are correctly extracted
        """

        root = etree.Element("root")
        element = etree.SubElement(root, "{http://www.w3.org/2000/svg}path",
                                   {'d': "M 70,800 l 125,-300 l 60,390"})
        group = etree.SubElement(root, "{http://www.w3.org/2000/svg}g")
        etree.SubElement(group, "{http://www.w3.org/2000/svg}path",
                         {'d': "M 70,800 l 125,-300 l 60,490"})
        etree.SubElement(group, "{http://www.w3.org/2000/svg}path",
                         {'d': "M 60,700 l 127,-500 l 70,900"})

        extractor = PathsExtractor([element, group], to_mm, "wId")
        extractor.extract()

        self.assertEqual(len(extractor.paths()), 3)
        self.assertEqual(extractor.paths()[0], [(70.0, 800.0), (195.0, 500.0),
                                                (255.0, 890.0)])
        self.assertEqual(extractor.paths()[1], [(70.0, 800.0), (195.0, 500.0),
                                                (255.0, 990.0)])
        self.assertEqual(extractor.paths()[2], [(60.0, 700.0), (187.0, 200.0),
                                                (257.0, 1100.0)])
Example #14
0
    def test_extract_svg_path_with_only_straight_lines(self):  #pylint: disable=invalid-name
        """ Tests that svg paths are correctly extracted
        """

        root = etree.Element("root")
        element = etree.SubElement(root, "{http://www.w3.org/2000/svg}path",
                                   {'d': "M 70,800 l 125,-300 l 60,490"})

        extractor = PathsExtractor([element], to_mm, "wId")
        extractor.extract()

        self.assertEqual(len(extractor.paths()), 1)
        self.assertEqual(extractor.paths()[0], [(70.0, 800.0), (195.0, 500.0),
                                                (255.0, 990.0)])
Example #15
0
    def test_throw_exception_for_unrecognized_svg_element(self):  #pylint: disable=invalid-name
        """ Tests that an exception is thrown for unrecognized svg elements
        """

        root = etree.Element("root")
        element = etree.SubElement(root, "invalidElement")

        extractor = PathsExtractor([element], to_mm, "wId")

        with self.assertRaises(UnrecognizedSVGElement) as context_manager:
            extractor.extract()

        exception = context_manager.exception
        self.assertEqual(exception.element, "invalidElement")
Example #16
0
    def test_use_parent_transform_for_multiple_path(self):  #pylint: disable=invalid-name
        """ Tests that extracted path takes the parent transformation into account
        """

        root1 = etree.Element("root", {'transform': "translate(10,20)"})
        element1 = etree.SubElement(root1, "{http://www.w3.org/2000/svg}path",
                                    {
                                        'transform': "matrix(1,2,3,4,5,6)",
                                        'd': "M 10,20 L 50,30 L 20,70"
                                    })
        root2 = etree.Element("root", {'transform': "translate(5,10)"})
        element2 = etree.SubElement(root2, "{http://www.w3.org/2000/svg}path",
                                    {
                                        'transform': "matrix(1,2,3,4,5,6)",
                                        'd': "M 10,20 L 50,30 L 20,70"
                                    })

        extractor = PathsExtractor([element1, element2], to_mm, "wId")
        extractor.extract()

        self.assertEqual(extractor.paths()[0], [(85.0, 126.0), (155.0, 246.0),
                                                (245.0, 346.0)])
        self.assertEqual(extractor.paths()[1], [(80.0, 116.0), (150.0, 236.0),
                                                (240.0, 336.0)])
Example #17
0
    def test_extract_multiple_paths_when_lines_interrupted(self):  #pylint: disable=invalid-name
        """ Tests that multiple paths are generated when svg path is not continuos
        """

        root = etree.Element("root")
        element = etree.SubElement(
            root, "{http://www.w3.org/2000/svg}path",
            {'d': "M 70,800 l 125,-300 l 60,490 M 100,100 L 200,200"})

        extractor = PathsExtractor([element], to_mm, "wId")
        extractor.extract()

        self.assertEqual(len(extractor.paths()), 2)
        self.assertEqual(extractor.paths()[0], [(70.0, 800.0), (195.0, 500.0),
                                                (255.0, 990.0)])
        self.assertEqual(extractor.paths()[1], [(100.0, 100.0),
                                                (200.0, 200.0)])
Example #18
0
    def test_closed_paths_with_multiple_paths(self):  #pylint: disable=invalid-name
        """ Tests that closed paths are extracted correctly also when multiple subpaths are present
        """

        root = etree.Element("root")
        element = etree.SubElement(
            root, "{http://www.w3.org/2000/svg}path",
            {'d': "M 70,800 l 125,-300 l 60,490 Z M 100,100 L 200,200"})

        extractor = PathsExtractor([element], to_mm, "wId")
        extractor.extract()

        self.assertEqual(len(extractor.paths()), 2)
        self.assertEqual(extractor.paths()[0], [(70.0, 800.0), (195.0, 500.0),
                                                (255.0, 990.0), (70.0, 800.0)])
        self.assertEqual(extractor.paths()[1], [(100.0, 100.0),
                                                (200.0, 200.0)])
Example #19
0
    def fill_row(self, node):
        max_line_width = self.unittouu('450mm')

        x_gap = y_gap = self.unittouu('10mm')
        x_start = self.unittouu('3mm')
        y_start = self.unittouu('1600mm') - self.unittouu('3mm')

        total_width = 0
        total_height = self.total_height

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

        bbox = computeBBox([node])
        x, _, y, _ = bbox
        node_width = x_gap + self.width(bbox)

        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 + self.height(bbox))

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

                path = parsePath(node_copy.attrib['d'])
                translatePath(path, x_delta, y_delta)
                node_copy.attrib['d'] = formatPath(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]]
                applyTransformToNode(translation_matrix, node_copy)

            else:
                node_copy.attrib['x'] = str(x_dest)
                node_copy.attrib['y'] = str(y_dest)

            total_width += node_width

        self.total_height += self.height(computeBBox(group)) + y_gap
Example #20
0
    def draw_rect(self, x, y, width, height):
        layer = self.current_layer

        style = {
            'stroke': '#ff0000',
            'stroke-width': '1',
            'fill': 'none',
        }

        attribs = {
            'style': formatStyle(style),
            'x': str(x),
            'y': str(y),
            'width': str(width),
            'height': str(height),
        }

        rect = etree.SubElement(layer, addNS('rect', 'svg'), attribs)
Example #21
0
    def test_automatically_close_open_paths_does_nothing_if_paths_closed(self):  #pylint: disable=invalid-name
        """ Tests that nothing changes if closing paths is requested but paths are closed
        """

        root = etree.Element("root")
        element = etree.SubElement(
            root, "{http://www.w3.org/2000/svg}path", {
                'd': ("M 70,800 l 125,-300 l 60,490 Z "
                      "M 100,100 L 200,200 L 100,100")
            })

        extractor = PathsExtractor([element], to_mm, "wId")
        extractor.extract()

        self.assertEqual(len(extractor.paths()), 2)
        self.assertEqual(extractor.paths()[0], [(70.0, 800.0), (195.0, 500.0),
                                                (255.0, 990.0), (70.0, 800.0)])
        self.assertEqual(extractor.paths()[1], [(100.0, 100.0), (200.0, 200.0),
                                                (100.0, 100.0)])
Example #22
0
    def test_automatically_close_open_paths(self):  #pylint: disable=invalid-name
        """ Tests that open paths are automatically closed if requested
        """

        root = etree.Element("root")
        element = etree.SubElement(
            root, "{http://www.w3.org/2000/svg}path",
            {'d': "M 70,800 l 125,-300 l 60,490 M 100,100 L 200,200"})

        extractor = PathsExtractor([element],
                                   to_mm,
                                   "wId",
                                   auto_close_path=True)
        extractor.extract()

        self.assertEqual(len(extractor.paths()), 2)
        self.assertEqual(extractor.paths()[0], [(70.0, 800.0), (195.0, 500.0),
                                                (255.0, 990.0), (70.0, 800.0)])
        self.assertEqual(extractor.paths()[1], [(100.0, 100.0), (200.0, 200.0),
                                                (100.0, 100.0)])
Example #23
0
    def paint(self, working_area):
        """ Draws the border in the working area

        :param working_area: the working area where the path is to be drawn
        :type working_area: an instance of the WirkingAreaGenerator
        """

        self.working_area = working_area

        if self.border_is_to_be_drawn():
            border_x = self.working_area.get_factor() * self.border.left()
            border_y = self.working_area.get_factor() * self.border.bottom()
            border_width = self.working_area.get_factor() * self.border.width()
            border_height = self.working_area.get_factor() * self.border.height()
            line_width = self.working_area.get_factor() * 0.25
            etree.SubElement(self.working_area.get_element(), "rect", {
                'x': str(border_x),
                'y': str(border_y),
                'width': str(border_width),
                'height': str(border_height),
                'style': ("stroke-width:{0};stroke-miterlimit:4;stroke-dasharray:0.25,0.25;"
                          "stroke-dashoffset:0;fill:none").format(line_width)})
Example #24
0
    def __get_layer(self, label):
        root = self.document.getroot()
        # tidy up the label
        label = label.strip().upper()
        label = re.sub(' +', ' ', label)

        # no label, just return current layer
        if len(label) == 0:
            return self.current_layer

        # return layer if already exists
        for layer in root:
            if layer.get(addNS('label', 'inkscape'),
                         default=None) == str(label):
                return layer
        # otherwise create new one
        layer_attrib = {
            addNS('groupmode', 'inkscape'): 'layer',
            addNS('label', 'inkscape'): str(label),
        }

        layer = etree.SubElement(root, addNS('g', 'svg'), attrib=layer_attrib)
        return layer
Example #25
0
    def test_flatten_path_if_requested(self):
        """ Tests that path is flattened if the constructor flatten parameter is not None
        """

        root = etree.Element("root")
        element = etree.SubElement(root, "{http://www.w3.org/2000/svg}path",
                                   {'d': "dummy value to check"})

        class FlattenMock:  #pylint: disable=missing-docstring,too-few-public-methods
            def __init__(self, test):
                self.test = test

            def __call__(self, curve):  #pylint: disable=missing-docstring
                self.test.assertEqual(curve, "dummy value to check")

                return [('M', (70.0, 800.0)), ('L', (195.0, 500.0)),
                        ('L', (255.0, 990.0))]

        extractor = PathsExtractor([element], to_mm, "wId", FlattenMock(self))
        extractor.extract()

        self.assertEqual(len(extractor.paths()), 1)
        self.assertEqual(extractor.paths()[0], [(70.0, 800.0), (195.0, 500.0),
                                                (255.0, 990.0)])
Example #26
0
def split_fill_and_stroke(path_node):
    """Split a path into two paths, one filled and one stroked

    Returns a the list [fill, stroke], where each is the XML element of the
    fill or stroke, or None.
    """
    style = simplestyle.parseStyle(path_node.get("style", ""))

    # If there is only stroke or only fill, don't split anything
    if "fill" in style.keys() and style["fill"] == "none":
        if "stroke" not in style.keys() or style["stroke"] == "none":
            return [None, None]  # Path has neither stroke nor fill
        else:
            return [None, path_node]
    if "stroke" not in style.keys() or style["stroke"] == "none":
        return [path_node, None]

    group = path_node.makeelement(addNS("g", "svg"))
    fill = etree.SubElement(group, addNS("path", "svg"))
    stroke = etree.SubElement(group, addNS("path", "svg"))

    attribs = path_node.attrib

    if "d" in attribs.keys():
        d = attribs["d"]
        del attribs["d"]
    else:
        raise AssertionError, "Cannot split stroke and fill of non-path element"

    if addNS("nodetypes", "sodipodi") in attribs.keys():
        nodetypes = attribs[addNS("nodetypes", "sodipodi")]
        del attribs[addNS("nodetypes", "sodipodi")]
    else:
        nodetypes = None

    if "id" in attribs.keys():
        path_id = attribs["id"]
        del attribs["id"]
    else:
        path_id = str(id(path_node))

    if "style" in attribs.keys():
        del attribs["style"]

    if "transform" in attribs.keys():
        transform = attribs["transform"]
        del attribs["transform"]
    else:
        transform = None

    # Pass along all remaining attributes to the group
    for attrib_name in attribs.keys():
        group.set(attrib_name, attribs[attrib_name])

    group.set("id", path_id)

    # Next split apart the style attribute
    style_group = {}
    style_fill = {"stroke": "none", "fill": "#000000"}
    style_stroke = {"fill": "none", "stroke": "none"}

    for key in style.keys():
        if key.startswith("fill"):
            style_fill[key] = style[key]
        elif key.startswith("stroke"):
            style_stroke[key] = style[key]
        elif key.startswith("marker"):
            style_stroke[key] = style[key]
        elif key.startswith("filter"):
            style_group[key] = style[key]
        else:
            style_fill[key] = style[key]
            style_stroke[key] = style[key]

    if len(style_group) != 0:
        group.set("style", simplestyle.formatStyle(style_group))

    fill.set("style", simplestyle.formatStyle(style_fill))
    stroke.set("style", simplestyle.formatStyle(style_stroke))

    # Finalize the two paths
    fill.set("d", d)
    stroke.set("d", d)
    if nodetypes is not None:
        fill.set(addNS("nodetypes", "sodipodi"), nodetypes)
        stroke.set(addNS("nodetypes", "sodipodi"), nodetypes)
    fill.set("id", path_id + "-fill")
    stroke.set("id", path_id + "-stroke")
    if transform is not None:
        fill.set("transform", transform)
        stroke.set("transform", transform)

    # Replace the original node with the group
    path_node.getparent().replace(path_node, group)

    return [fill, stroke]