Example #1
0
    def split_letters(self, node):
        """Returns a list of letters"""

        letters = []

        words = self.split_words(node)
        if not words:
            return letters

        for word in words:

            x = float(word.get("x"))
            y = word.get("y")

            # gets the font size. If element doesn't have a style attribute, it assumes font-size = 12px
            fontsize = word.style.get("font-size", "12px")
            fs = self.svg.unittouu(fontsize)

            # for each letter in element string
            for letter in word[0].text:
                tspan = Tspan()
                tspan.text = letter

                text = TextElement(**node.attrib)
                text.set("x", str(x))
                text.set("y", str(y))
                x += fs

                text.append(tspan)
                letters.append(text)
        return letters
Example #2
0
    def split_lines(self, node):
        """Returns a list of lines"""
        lines = []
        count = 1

        for elem in node:
            if isinstance(elem, TextPath):
                inkex.errormsg(
                    "Text on path isn't supported. First remove text from path."
                )
                break
            elif not isinstance(elem, (FlowPara, Tspan)):
                continue

            text = TextElement(**node.attrib)

            # handling flowed text nodes
            if isinstance(node, FlowRoot):
                fontsize = node.style.get("font-size", "12px")
                fs = self.svg.unittouu(fontsize)

                # selects the flowRegion's child (svg:rect) to get @X and @Y
                flowref = node.findone('svg:flowRegion')[0]

                if isinstance(flowref, Rectangle):
                    text.set("x", flowref.get("x"))
                    text.set("y", str(float(flowref.get("y")) + fs * count))
                    count += 1
                else:
                    inkex.debug(
                        "This type of text element isn't supported. First unflow text."
                    )
                    break

                # now let's convert flowPara into tspan
                tspan = Tspan()
                tspan.set("sodipodi:role", "line")
                tspan.text = elem.text
                text.append(tspan)

            else:
                from copy import copy
                x = elem.get("x") or node.get("x")
                y = elem.get("y") or node.get("y")

                text.set("x", x)
                text.set("y", y)
                text.append(copy(elem))

            lines.append(text)

        return lines
Example #3
0
    def generateText(self, text, x, y, size):
        tspan = Tspan()
        tspan.text = text

        textElement = TextElement()
        textElement.set("x", str(x))
        textElement.set("y", str(y))
        # textElement.style = "font-size:50px; font-family:Metal Lord"
        textElement.style = "font-size:{}px;".format(size)

        textElement.append(tspan)

        return textElement
Example #4
0
    def split_words(self, node):
        """Returns a list of words"""
        words = []

        # Function to recursively extract text
        def plain_str(elem):
            words = []
            if elem.text:
                words.append(elem.text)
            for n in elem:
                words.extend(plain_str(n))
                if n.tail:
                    words.append(n.tail)
            return words

        # if text has more than one line, iterates through elements
        lines = self.split_lines(node)
        if not lines:
            return words

        for line in lines:
            # gets the position of text node
            x = float(line.get("x"))
            y = line.get("y")

            # gets the font size. if element doesn't have a style attribute, it assumes font-size = 12px
            fontsize = line.style.get("font-size", "12px")
            fs = self.svg.unittouu(fontsize)

            # extract and returns a list of words
            words_list = "".join(plain_str(line)).split()
            prev_len = 0

            # creates new text nodes for each string in words_list
            for word in words_list:
                tspan = Tspan()
                tspan.text = word

                text = TextElement(**line.attrib)
                tspan.set('sodipodi:role', "line")

                # positioning new text elements
                x = x + prev_len * fs
                prev_len = len(word)
                text.set("x", str(x))
                text.set("y", str(y))

                text.append(tspan)
                words.append(text)

        return words
Example #5
0
 def add_fixedtext(self, node, x, y, text, anchor, angle, dy=0):
     new = node.add(Tspan())
     new.set('sodipodi:role', 'line')
     s = {'text-align': 'center', 'vertical-align': 'bottom',
          'text-anchor': anchor, 'font-size': str(self.options.fontsize),
          'fill-opacity': '1.0', 'stroke': 'none',
          'font-weight': 'normal', 'font-style': 'normal', 'fill': '#000000'}
     new.style = s
     new.set('dy', str(dy))
     if text[-2:] == "^2":
         new.append(Tspan.superscript("2"))
         new.text = str(text)[:-2]
     else:
         new.text = str(text)
     node.set('x', str(x))
     node.set('y', str(y))
     node.set('transform', 'rotate(%s, %s, %s)' % (angle, x, y))
Example #6
0
 def test_path(self):
     """Test getting paths"""
     self.assertFalse(TextPath().get_path())
     self.assertFalse(TextElement().get_path())
     self.assertFalse(FlowRegion().get_path())
     self.assertFalse(FlowRoot().get_path())
     self.assertFalse(FlowPara().get_path())
     self.assertFalse(FlowSpan().get_path())
     self.assertFalse(Tspan().get_path())
Example #7
0
 def add_textonpath(self, node, x, y, text, _node, anchor, startOffset, dy=0):
     new = node.add(TextPath())
     s = {'text-align': 'center', 'vertical-align': 'bottom',
          'text-anchor': anchor, 'font-size': str(self.options.fontsize),
          'fill-opacity': '1.0', 'stroke': 'none',
          'font-weight': 'normal', 'font-style': 'normal', 'fill': '#000000'}
     new.style = s
     new.href = _node
     new.set('startOffset', startOffset)
     new.set('dy', str(dy))  # dubious merit
     # new.append(tp)
     if text[-2:] == "^2":
         new.append(Tspan.superscript("2"))
         new.text = str(text)[:-2]
     else:
         new.text = str(text)
     # node.set('transform','rotate(180,'+str(-x)+','+str(-y)+')')
     node.set('x', str(x))
     node.set('y', str(y))
Example #8
0
    def effect(self):
        if len(self.svg.selected) == 0:
            inkex.errormsg("Please select some paths first.")
            exit()

        for id, node in self.svg.selected.items():
            id = node.get('id')
            self.group = node.getparent().add(TextElement())
            csp = node.path.transform(node.composed_transform()).to_superpath()
            bbox = node.bounding_box()
            tx, ty = bbox.center
            anchor = 'middle'

            node = self.group
            new = node.add(Tspan())
            new.set('sodipodi:role', 'line')
            s = {
                'text-align': 'center',
                'vertical-align': 'bottom',
                'text-anchor': 'middle',
                'font-size': str(self.options.fontsize) + 'px',
                'font-weight': self.options.fontweight,
                'font-style': 'normal',
                'font-family': self.options.font,
                'fill': str(self.options.color)
            }
            new.set('style', str(inkex.Style(s)))
            new.set('dy', '0')

            if self.options.capitals:
                id = id.upper()

            new.text = id.replace(self.options.replaced,
                                  self.options.replacewith)
            node.set('x', str(tx))
            node.set('y', str(ty))
            node.set('transform',
                     'rotate(%s, %s, %s)' % (-int(self.options.angle), tx, ty))
Example #9
0
 def test_append_superscript(self):
     """Test adding superscript"""
     tap = TextPath()
     tap.append(Tspan.superscript('th'))
     self.assertEqual(len(tap), 1)
Example #10
0
def writeSVG(self, unfolding, size, printNumbers):
    mesh = unfolding[0]
    isFoldingEdge = unfolding[1]
    glueNumber = unfolding[3]
    foldingDirection = unfolding[4]

    # Calculate the bounding box
    [xmin, ymin, boxSize] = findBoundingBox(unfolding[0])

    if size > 0:
        boxSize = size

    strokewidth = 0.002 * boxSize
    dashLength = 0.008 * boxSize
    spaceLength = 0.02 * boxSize
    textDistance = 0.02 * boxSize
    textStrokewidth = 0.05 * strokewidth
    textLength = 0.001 * boxSize
    fontsize = 0.015 * boxSize

    # Generate a main group
    paperfoldPageGroup = self.document.getroot().add(
        inkex.Group(id=self.svg.get_unique_id("paperfold-page-")))

    # Go over all edges of the grid
    for edge in mesh.edges():
        # The two endpoints
        he = mesh.halfedge_handle(edge, 0)
        vertex0 = mesh.point(mesh.from_vertex_handle(he))
        vertex1 = mesh.point(mesh.to_vertex_handle(he))

        # Write a straight line between the two corners
        line = paperfoldPageGroup.add(inkex.PathElement())
        #line.path = [
        #       ["M", [vertex0[0], vertex0[1]]],
        #       ["L", [vertex1[0], vertex1[1]]]
        #    ]
        line.set(
            'd', "M " + str(vertex0[0]) + "," + str(vertex0[1]) + " " +
            str(vertex1[0]) + "," + str(vertex1[1]))
        # Colour depending on folding direction
        lineStyle = {"fill": "none"}
        if foldingDirection[edge.idx()] > 0:
            lineStyle.update({"stroke": self.options.color_mountain_cut})
            line.set("id", self.svg.get_unique_id("mountain-cut-"))
        elif foldingDirection[edge.idx()] < 0:
            lineStyle.update({"stroke": self.options.color_valley_cut})
            line.set("id", self.svg.get_unique_id("valley-cut-"))

        lineStyle.update({"stroke-width": str(strokewidth)})
        lineStyle.update({"stroke-linecap": "butt"})
        lineStyle.update({"stroke-linejoin": "miter"})
        lineStyle.update({"stroke-miterlimit": "4"})

        # Dotted lines for folding edges
        if isFoldingEdge[edge.idx()]:
            lineStyle.update({
                "stroke-dasharray": (str(dashLength) + ", " + str(spaceLength))
            })
            if foldingDirection[edge.idx()] > 0:
                lineStyle.update(
                    {"stroke": self.options.color_mountain_perforate})
                line.set("id", self.svg.get_unique_id("mountain-perforate-"))
            if foldingDirection[edge.idx()] < 0:
                lineStyle.update(
                    {"stroke": self.options.color_valley_perforate})
                line.set("id", self.svg.get_unique_id("valley-perforate-"))
        else:
            lineStyle.update({"stroke-dasharray": "none"})

        lineStyle.update({"stroke-dashoffset": "0"})
        lineStyle.update({"stroke-opacity": "1"})
        line.style = lineStyle

        # The number of the edge to be glued
        if not isFoldingEdge[edge.idx()]:
            # Find halfedge in the face
            halfEdge = mesh.halfedge_handle(edge, 0)
            if mesh.face_handle(halfEdge).idx() == -1:
                halfEdge = mesh.opposite_halfedge_handle(halfEdge)
            vector = mesh.calc_edge_vector(halfEdge)
            # normalize
            vector = vector / np.linalg.norm(vector)
            midPoint = 0.5 * (mesh.point(mesh.from_vertex_handle(halfEdge)) +
                              mesh.point(mesh.to_vertex_handle(halfEdge)))
            rotatedVector = np.array([-vector[1], vector[0], 0])
            angle = np.arctan2(vector[1], vector[0])
            position = midPoint + textDistance * rotatedVector
            rotation = 180 / np.pi * angle

            if (printNumbers):
                text = paperfoldPageGroup.add(
                    TextElement(id=self.svg.get_unique_id("number-")))
                text.set("x", str(position[0]))
                text.set("y", str(position[1]))
                text.set("font-size", str(fontsize))
                text.set("style", "stroke-width:" + str(textStrokewidth))
                text.set(
                    "transform", "rotate(" + str(rotation) + "," +
                    str(position[0]) + "," + str(position[1]) + ")")

                tspan = text.add(Tspan())
                tspan.set("x", str(position[0]))
                tspan.set("y", str(position[1]))
                tspan.set("style", "stroke-width:" + str(textStrokewidth))
                tspan.text = str(glueNumber[edge.idx()])
    return paperfoldPageGroup