def export_dimension(vals): # mandatory group codes : (10, 11, 13, 14, 20, 21, 23, 24) (x1..4, y1..4) if vals.has_x1 and vals.has_x2 and vals.has_x3 and vals.has_x4 and \ vals.has_y1 and vals.has_y2 and vals.has_y3 and vals.has_y4: dx = abs(vals.x1 - vals.x3) dy = abs(vals.y1 - vals.y3) if (vals.x1 == vals.x4) and dx > 0.00001: d = dx / scale dy = 0 path = 'M %f,%f %f,%f' % (vals.x1, vals.y1, vals.x3, vals.y1) elif (vals.y1 == vals.y4) and dy > 0.00001: d = dy / scale dx = 0 path = 'M %f,%f %f,%f' % (vals.x1, vals.y1, vals.x1, vals.y3) else: return attribs = {'d': path, 'style': style + '; marker-start: url(#DistanceX); marker-end: url(#DistanceX); stroke-width: 0.25px'} etree.SubElement(layer, 'path', attribs) x = vals.x2 y = vals.y2 size = 12 # default fontsize in px if vals.has_mtext: if vals.mtext in DIMTXT: size = scale * textscale * DIMTXT[vals.mtext] if size < 2: size = 2 attribs = {'x': '%f' % x, 'y': '%f' % y, 'style': 'font-size: %.3fpx; fill: %s; font-family: %s; text-anchor: middle; text-align: center' % (size, color, options.font)} if dx == 0: attribs.update({'transform': 'rotate (%f %f %f)' % (-90, x, y)}) node = etree.SubElement(layer, 'text', attribs) tspan = node.add(inkex.Tspan()) tspan.set('sodipodi:role', 'line') tspan.text = str(float('%.2f' % d))
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))
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
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)
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)