Example #1
0
    def effect(self):
        if len(self.svg.selected) == 0:
            inkex.errormsg("Please select some paths first.")
            exit()

        path_attribute = self.options.path_attribute
        is_text_attribute = path_attribute in ['id', 'label']
        for id, node in self.svg.selection.filter(inkex.PathElement).items():
            to_show = self.extract_path_attribute(path_attribute, node)

            node.path.transform(node.composed_transform()).to_superpath()
            bbox = node.bounding_box()
            tx, ty = bbox.center

            if self.options.group:
                group_element = node.getparent().add(inkex.Group())
                group_element.add(node)
                group_element.set('id', node.get('id') + "_group")
                text_element = group_element.add(inkex.TextElement())
            else:
                text_element = node.getparent().add(inkex.TextElement())

            tspan_element = text_element.add(inkex.Tspan())
            tspan_element.set('sodipodi:role', 'line')
            styles = {
                '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)
            }
            tspan_element.set('style', str(inkex.Style(styles)))
            tspan_element.set('dy', '0')

            if is_text_attribute:
                if self.options.capitals:
                    to_show = to_show.upper()

                if self.options.matchre != '':
                    matches = re.findall(self.options.matchre, to_show)
                    if len(matches) > 0:
                        to_show = matches[0]

                if self.options.replaced != '':
                    to_show = to_show.replace(self.options.replaced,
                                              self.options.replacewith)

            tspan_element.text = to_show
            tspan_element.set('id', node.get('id') + "_tspan")
            text_element.set('id', node.get('id') + "_text")
            text_element.set('x', str(tx))
            text_element.set('y', str(ty))
            text_element.set(
                'transform',
                'rotate(%s, %s, %s)' % (-int(self.options.angle), tx, ty))
Example #2
0
    def insert_pointer(self, problem):
        correction_transform = get_correction_transform(self.troubleshoot_layer)

        if isinstance(problem, ValidationWarning):
            fill_color = "#ffdd00"
            layer = self.warning_group
        elif isinstance(problem, ValidationError):
            fill_color = "#ff0000"
            layer = self.error_group
        elif isinstance(problem, ObjectTypeWarning):
            fill_color = "#ff9900"
            layer = self.type_warning_group

        pointer_style = "stroke:#000000;stroke-width:0.2;fill:%s;" % (fill_color)
        text_style = "fill:%s;stroke:#000000;stroke-width:0.2;font-size:8px;text-align:center;text-anchor:middle" % (fill_color)

        path = inkex.PathElement(attrib={
            "id": self.uniqueId("inkstitch__invalid_pointer__"),
            "d": "m %s,%s 4,20 h -8 l 4,-20" % (problem.position.x, problem.position.y),
            "style": pointer_style,
            INKSCAPE_LABEL: _('Invalid Pointer'),
            "transform": correction_transform
        })
        layer.insert(0, path)

        text = inkex.TextElement(attrib={
            INKSCAPE_LABEL: _('Description'),
            "x": str(problem.position.x),
            "y": str(float(problem.position.y) + 30),
            "transform": correction_transform,
            "style": text_style
        })
        layer.append(text)

        tspan = inkex.Tspan()
        tspan.text = problem.name
        if problem.label:
            tspan.text += " (%s)" % problem.label
        text.append(tspan)
Example #3
0
def export_mtext(vals):
    # mandatory group codes : (1 or 3, 10, 20) (text, x, y)
    if (vals.has_text or vals.has_mtext) and vals.has_x1 and vals.has_y1:
        x = vals.x1
        y = vals.y1
        # optional group codes : (21, 40, 50) (direction, text height mm, text angle)
        size = 12  # default fontsize in px
        if vals.has_scale:
            size = scale * textscale * vals.scale
        attribs = {'x': '%f' % x, 'y': '%f' % y, 'style': 'font-size: %.3fpx; fill: %s; font-family: %s' % (size, color, options.font)}
        angle = 0  # default angle in degrees
        if vals.has_angle:
            angle = vals.angle
            attribs.update({'transform': 'rotate (%f %f %f)' % (-angle, x, y)})
        elif vals.has_y2:
            if vals.y2 == 1.0:
                attribs.update({'transform': 'rotate (%f %f %f)' % (-90, x, y)})
            elif vals.y2 == -1.0:
                attribs.update({'transform': 'rotate (%f %f %f)' % (90, x, y)})
        node = layer.add(inkex.TextElement(**attribs))
        node.set('sodipodi:linespacing', '125%')
        text = ''
        if vals.has_mtext:
            text = ''.join(vals.mtext_list)
        if vals.has_text:
            text = vals.text
        found = text.find(r'\P')  # new line
        while found > -1:
            tspan = node.add(inkex.Tspan())
            tspan.set('sodipodi:role', 'line')
            tspan.text = text[:found]
            text = text[(found + 2):]
            found = text.find(r'\P')
        tspan = node.add(inkex.Tspan())
        tspan.set('sodipodi:role', 'line')
        tspan.text = text
Example #4
0
    def draw_swatch(self):
        border = self.canvas.add(inkex.PathElement())
        # Curve radius
        cr = self.svg.unittouu('10mm')
        # Swatch padding
        sp = self.svg.unittouu('30mm')
        # Handle length
        hl = cr / 2
        path_command = ('m %f,%f l %f,%f c %f,%f %f,%f %f,%f'
                        'l %f,%f c %f,%f %f,%f %f,%f '
                        'l %f,%f c %f,%f %f,%f %f,%f '
                        'l %f,%f c %f,%f %f,%f %f,%f ') % (
                            cr, 0, self.width - 2 * cr, 0, hl, 0, cr, cr - hl,
                            cr, cr, 0, self.height - 2 * cr + 1.5 * sp, 0, cr /
                            2, 0 - cr + hl, cr, 0 - cr, cr, 0 - self.width +
                            2 * cr, 0, 0 - hl, 0, 0 - cr, 0 - cr + hl, 0 - cr,
                            0 - cr, 0, 0 - self.height - 1.5 * sp + 2 * cr, 0,
                            0 - hl, cr - hl, 0 - cr, cr, 0 - cr)

        style = {
            "stroke": cut_colour,
            "stroke-width": str(self.stroke_width),
            "fill": "none",
        }
        border.update(**{
            "style": style,
            "inkscape:label": "lattice_border",
            "d": path_command
        })

        c = self.canvas.add(
            inkex.Circle(style=str(inkex.Style(style)),
                         cx=str(cr),
                         cy=str(cr),
                         r=str(self.svg.unittouu('4mm'))))

        self.y += sp

        text_style = {
            'fill': engrave_colour,
            'font-size': '9px',
            'font-family': 'sans-serif',
            'text-anchor': 'middle',
            'text-align': 'center',
        }
        text = self.canvas.add(
            inkex.TextElement(style=str(inkex.Style(text_style)),
                              x=str(self.x + self.width / 2),
                              y=str(self.y - sp / 2)))
        text.text = "Style: %s" % self.name

        text_style['font-size'] = "3px"
        text = self.canvas.add(
            inkex.TextElement(style=str(inkex.Style(text_style)),
                              x=str(self.x + self.width / 2),
                              y=str(self.y - sp / 4)))
        text.text = self.parameter_text()

        text = self.canvas.add(
            inkex.TextElement(style=str(inkex.Style(text_style)),
                              x=str(self.x + self.width / 2),
                              y=str(self.y + self.height + sp / 4)))
        text.text = "https://github.com/buxtronix/living-hinge"
    def generate(self):

        size = self.svg.unittouu(str(self.options.size) + 'px')
        head = self.svg.unittouu(str(self.options.head) + 'px')
        width = self.svg.unittouu(str(self.options.width) + 'pt')
        medium = self.svg.unittouu('10pt') # font sizes, ...
        large = self.svg.unittouu('12pt') # ... could be options

        tsector, survey_title = analyse3d(self.options.file, self.options.nsector)

        tmax = max(tsector)
        thoriz = 0.5 * sum(tsector) # each leg is counted twice
        ns = len(tsector)
        tmean = 2 * thoriz / ns

        # Inner group to contain all the rose diagram elements

        rose_diagram = inkex.Group() 

        elements = [''] * (2*ns) # list of lines and arc elements

        for i, v in enumerate(tsector):
            alo = 2 * m.pi * (i - 0.5) / ns
            ahi = 2 * m.pi * (i + 0.5) / ns
            rad = size * tsector[i] / tmax
            xx0 = rad * m.sin(alo)
            yy0 = - rad * m.cos(alo)
            xx1 = rad * m.sin(ahi)
            yy1 = - rad * m.cos(ahi)
            elements[2*i] = ('L' if i else 'M') + '%7.2f, %7.2f ' % (xx0, yy0)
            elements[2*i+1] = 'A %6.2f, %6.2f 0 0,1 %7.2f, %7.2f' % (rad, rad, xx1, yy1)

        # Add the lines and arc elements - 'z' closes the path

        zigzag = inkex.PathElement(d=' '.join(elements) + ' z')
        zigzag.style = {'stroke': 'black', 'fill': 'none' if self.options.bw else 'yellow', 'stroke-width': width}
        rose_diagram.add(zigzag)

        # Adjust the scale circle radius, rounding down if necessary
        
        scale_rad = fancy_round(tmean)
        if scale_rad > tmax:
            scale_rad = fancy_round(tmean, offset=0.0)

        # Add the scale circle 

        circle = inkex.Circle(r=str(size * scale_rad / tmax))
        circle.style = {'stroke': 'black' if self.options.bw else 'blue', 'fill': 'none', 'stroke-width': width}
        if self.options.bw:
            circle.style['stroke-dasharray'] = '{step} {step}'.format(step=4*width)
        rose_diagram.add(circle)

        # Add N-S, E-W, NW-SE, NE-SW lines; the N has a half-arrow

        style = {'stroke': 'black', 'fill': 'none', 'stroke-width': width}
        style = str(inkex.Style(style))

        length = 1.05 * size
        rose_diagram.add(inkex.PathElement(d=f'M0,{-length+2*head} L{-head},{-length+2*head} L0,-{length} L0,{length}', style=style))
        rose_diagram.add(inkex.PathElement(d=f'M-{length},0 L{length},0', style=style))

        length = m.sqrt(0.5) * 1.05 * size
        rose_diagram.add(inkex.PathElement(d=f'M-{length},-{length} L{length},{length}', style=style))
        rose_diagram.add(inkex.PathElement(d=f'M{length},-{length} L-{length},{length}', style=style))

        # Add a 'N' to the north arrow
        
        north = inkex.TextElement(x=str(head), y=str(-1.05*size+head))
        north.style = {'font-family': 'Verdana', 'font-size': large, 'fill': 'black', 'text-anchor': 'middle', 'text-align': 'center'}        
        north.text = 'N'
        rose_diagram.add(north)

        yield rose_diagram

        # Add annotation for cave length and circle radius

        annotation = inkex.TextElement(x=str(0), y=str(1.3*size))
        annotation.style = {'font-family': 'Verdana', 'font-size': medium, 'fill': 'black', 'text-anchor': 'middle', 'text-align': 'center'}        
        cave_length = f'{round(thoriz/1000, 1)} km' if thoriz > 10000 else f'{round(thoriz)} m'
        circle_radius = f'{scale_rad/1000} km' if scale_rad > 1000 else f'{scale_rad} m'
        annotation.text = f'length {cave_length}, circle radius is {circle_radius}'
        
        yield annotation

        # Add a title
        
        title = inkex.TextElement(x=str(0), y=str(-1.3*size))
        title.style = {'font-family': 'Verdana', 'font-size': large, 'fill': 'black', 'text-anchor': 'middle', 'text-align': 'center'}        
        title.text = self.options.title or survey_title

        yield title
Example #6
0
    def add_descriptions(self, problem_types):
        svg = self.document.getroot()

        # We could use svg.viewport_width, but then we would need to do unit conversions,
        # so let's stay with parsing the viewbox by ourselves
        # viewbox values are either separated through white space or commas
        text_x = str(float(svg.get('viewBox', '0 0 800 0').replace(",", " ").split()[2]) + 5.0)

        text_container = inkex.TextElement(attrib={
            "x": text_x,
            "y": str(5),
            "style": "fill:#000000;font-size:5px;line-height:1;"
        })
        self.troubleshoot_layer.append(text_container)

        text = [
            [_("Troubleshoot"), "font-weight: bold; font-size: 8px;"],
            ["", ""]
        ]

        for problem_type, problems in list(problem_types.items()):
            if problem_type == "error":
                text_color = "#ff0000"
                problem_type_header = _("Errors")
                problem_type_description = _("Problems that will prevent the shape from being embroidered.")
            elif problem_type == "warning":
                text_color = "#ffdd00"
                problem_type_header = _("Warnings")
                problem_type_description = _("These are problems that won't prevent the shape from being embroidered. "
                                             "You should consider to fix the warning, but if you don't, "
                                             "Ink/Stitch will do its best to process the object.")
            elif problem_type == "type_warning":
                text_color = "#ff9900"
                problem_type_header = _("Object Type Warnings")
                problem_type_description = _("These objects may not work properly with Ink/Stitch. "
                                             "Follow the instructions to correct unwanted behaviour.")
            if problems:
                text.append([problem_type_header, "font-weight: bold; fill: %s; text-decoration: underline; font-size: 7px;" % text_color])
                text.append(["", ""])
                text.append([problem_type_description, "fill:%s;" % text_color])
                text.append(["", ""])

            for problem in problems:
                text.append([problem.name, "font-weight: bold; fill: %s;" % text_color])
                text.append([problem.description, "font-size: 3px;"])
                text.append(["", ""])
                for step in problem.steps_to_solve:
                    text.append([step, "font-size: 4px;"])
                text.append(["", ""])

        explain_layer = _('It is possible, that one object contains more than one error, ' +
                          'yet there will be only one pointer per object.  Run this function again, ' +
                          'when further errors occur.  Remove pointers by deleting the layer named '
                          '"Troubleshoot" through the objects panel (Object -> Objects...).')
        explain_layer_parts = textwrap.wrap(explain_layer, 60)
        for description in explain_layer_parts:
            text.append([description, "font-style: italic; font-size: 4px;"])

        text = self.split_text(text)

        for text_line in text:
            tspan = inkex.Tspan(attrib={
                SODIPODI_ROLE: "line",
                "style": text_line[1]
            })
            tspan.text = text_line[0]
            text_container.append(tspan)