def effect(self): # get number of digits prec = int(self.options.precision) # loop over all selected paths for id, node in self.selected.iteritems(): if node.tag == inkex.addNS('path','svg'): self.group = inkex.etree.SubElement(node.getparent(),inkex.addNS('text','svg')) t = node.get('transform') # Removed to fix LP #308183 # (Measure Path text shifted when used with a copied object) #if t: # self.group.set('transform', t) a =[] p = cubicsuperpath.parsePath(node.get('d')) num = 1 factor = 1.0/inkex.unittouu('1'+self.options.unit) if self.options.type == "length": slengths, stotal = csplength(p) else: stotal,x0,y0 = csparea(p) stotal *= factor*self.options.scale # Format the length as string lenstr = locale.format("%(len)25."+str(prec)+"f",{'len':round(stotal*factor*self.options.scale,prec)}).strip() if self.options.type == "length": self.addTextOnPath(self.group,0, 0,lenstr+' '+self.options.unit, id, self.options.offset) else: self.addTextWithTspan(self.group,x0,y0,lenstr+' '+self.options.unit+'^2', id, self.options.offset)
def effect(self): args = [ "./qqwing", "--one-line", "--generate", str(self.options.rows * self.options.cols) ] if self.options.difficulty != 'mixed': args.extend(["--difficulty", self.options.difficulty]) data = subprocess.Popen( args, stdout=subprocess.PIPE).communicate()[0].splitlines() parent = self.document.getroot() self.doc_w = inkex.unittouu(parent.get('width')) self.doc_h = inkex.unittouu(parent.get('height')) self.size = inkex.unittouu(self.options.puzzle_size) self.gap = inkex.unittouu(self.options.puzzle_gap) self.shift = self.size + self.gap self.left = (self.doc_w - (self.options.cols * self.shift - self.gap)) / 2 self.top = (self.doc_h - (self.options.rows * self.shift - self.gap)) / 2 self.sudoku_g = inkex.etree.SubElement(parent, 'g', {'id': 'sudoku'}) for row in range(0, self.options.rows): for col in range(0, self.options.cols): g = inkex.etree.SubElement( self.sudoku_g, 'g', {'id': 'puzzle_' + str(col) + str(row)}) self.draw_grid(g, col * self.shift, row * self.shift) self.fill_puzzle(g, col * self.shift, row * self.shift, data[col + row * self.options.cols])
def createPiano(self, parent): firstKeyNumber = keyNumberFromNote(self.options.firstNote) lastKeyNumber = keyNumberFromNote(self.options.lastNote) self.createKeyInRange(parent, firstKeyNumber, lastKeyNumber) rectBump = (self.white_key_width - self.black_key_width / 2) rectBump = inkex.unittouu('1 mm') rect_x1 = self.white_key_width * ( whiteKeyCountInRange(0, firstKeyNumber) - 1) - rectBump rect_y1 = inkex.unittouu('-3 mm') rect_width = self.white_key_width * (whiteKeyCountInRange( firstKeyNumber, lastKeyNumber)) + rectBump * 2 rect_height = inkex.unittouu('4 mm') rect_atts = { 'x': str(rect_x1), 'y': str(rect_y1), 'width': str(rect_width), 'height': str(rect_height), 'ry': str(0), 'style': 'fill:#ffffff;stroke:none;fill-opacity:1' } rect = inkex.etree.SubElement(parent, 'rect', rect_atts) path_atts = { 'style': 'fill:#ffffff;stroke:#000000;stroke-width:' + str(inkex.unittouu('0.25 mm')) + ';stroke-opacity:1', 'd': 'm ' + str(rect_x1) + ", " + str(rect_y1) + " l " + str(0) + ", " + str(rect_height) + " " + str(rect_width) + ", " + str(0) + " " + str(0) + ", " + str(-rect_height) } path = inkex.etree.SubElement(parent, 'path', path_atts)
def addDot(self, node): self.group = inkex.etree.SubElement(node.getparent(), inkex.addNS("g", "svg")) self.dotGroup = inkex.etree.SubElement(self.group, inkex.addNS("g", "svg")) self.numGroup = inkex.etree.SubElement(self.group, inkex.addNS("g", "svg")) try: t = node.get("transform") self.group.set("transform", t) except: pass style = simplestyle.formatStyle({"stroke": "none", "fill": "#000"}) a = [] p = simplepath.parsePath(node.get("d")) self.separateLastAndFirst(p) num = self.options.start for cmd, params in p: if cmd != "Z" and cmd != "z": dot_att = { "style": style, "r": str(inkex.unittouu(self.options.dotsize) / 2), "cx": str(params[-2]), "cy": str(params[-1]), } inkex.etree.SubElement(self.dotGroup, inkex.addNS("circle", "svg"), dot_att) self.addText( self.numGroup, params[-2] + (inkex.unittouu(self.options.dotsize) / 2), params[-1] - (inkex.unittouu(self.options.dotsize) / 2), num, ) num += self.options.step node.getparent().remove(node)
def svg_open(self, filename): doc_width = inkex.unittouu( self.document.documentElement.getAttribute('width')) doc_height = inkex.unittouu( self.document.documentElement.getAttribute('height')) doc_sizeH = min(doc_width, doc_height) doc_sizeW = max(doc_width, doc_height) def clone_and_rewrite(self, node_in): if node_in.localName != 'svg': node_out = self.document.createElement('svg:' + node_in.localName) for i in range(0, node_in.attributes.length): name = node_in.attributes.item(i).name value = node_in.attributes.item(i).value node_out.setAttribute(name, value) else: node_out = self.document.createElement('svg:g') for c in node_in.childNodes: if c.localName in ('g', 'path', 'polyline', 'polygon'): child = clone_and_rewrite(self, c) if c.localName == 'g': child.setAttribute( 'transform', 'matrix(' + str(doc_sizeH / 700.) + ',0,0,' + str(-doc_sizeH / 700.) + ',' + str(-doc_sizeH * 0.25) + ',' + str(doc_sizeW * 0.75) + ')') node_out.appendChild(child) return node_out doc = xml.dom.minidom.parse(filename) svg = doc.getElementsByTagName('svg')[0] group = clone_and_rewrite(self, svg) self.current_layer.appendChild(group)
def svg_open(self,filename): doc_width = inkex.unittouu(self.document.getroot().get('width')) doc_height = inkex.unittouu(self.document.getroot().get('height')) doc_sizeH = min(doc_width,doc_height) doc_sizeW = max(doc_width,doc_height) def clone_and_rewrite(self, node_in): in_tag = node_in.tag.rsplit('}',1)[-1] if in_tag != 'svg': node_out = inkex.etree.Element(inkex.addNS(in_tag,'svg')) for name in node_in.attrib: node_out.set(name, node_in.attrib[name]) else: node_out = inkex.etree.Element(inkex.addNS('g','svg')) for c in node_in.iterchildren(): c_tag = c.tag.rsplit('}',1)[-1] if c_tag in ('g', 'path', 'polyline', 'polygon'): child = clone_and_rewrite(self, c) if c_tag == 'g': child.set('transform','matrix('+str(doc_sizeH/700.)+',0,0,'+str(-doc_sizeH/700.)+','+str(-doc_sizeH*0.25)+','+str(doc_sizeW*0.75)+')') node_out.append(child) return node_out doc = inkex.etree.parse(filename) svg = doc.getroot() group = clone_and_rewrite(self, svg) self.current_layer.append(group)
def createHelpSheetScaleFromTitleAndIntervals(self, parent, title, intervals): textstyle = { 'font-size': '64px', 'font-family': 'arial', 'text-anchor': 'middle', 'text-align': 'center', 'fill': '#000000' } text_atts = { 'style': simplestyle.formatStyle(textstyle), 'x': str(self.doc_width / 2), 'y': str(inkex.unittouu('18 mm')) } text = inkex.etree.SubElement(parent, 'text', text_atts) text.text = title for i in range(0, 12): self.options.keynote = notes[i] if keys_color[i] == "W": t = 'translate(' + str( self.doc_width/2 ) + ','\ + str( self.doc_height-self.white_key_height*1.5-(self.white_key_height+inkex.unittouu('7 mm')) * int(keys_numbers[self.options.keynote]) ) + ')' else: t = 'translate(' + str( inkex.unittouu('7 mm') ) + ',' \ + str( self.doc_height-self.white_key_height*1.5-(self.white_key_height+inkex.unittouu('7 mm')) * int(keys_numbers[self.options.keynote])-self.white_key_height*0.5 ) + ')' group = inkex.etree.SubElement(parent, 'g', {'transform': t}) self.createPiano(group) self.createMarkersFromIntervals(group, intervals)
def svg_open(self,filename): doc_width = inkex.unittouu(self.document.documentElement.getAttribute('width')) doc_height = inkex.unittouu(self.document.documentElement.getAttribute('height')) doc_sizeH = min(doc_width,doc_height) doc_sizeW = max(doc_width,doc_height) def clone_and_rewrite(self, node_in): if node_in.localName != 'svg': node_out = self.document.createElement('svg:' + node_in.localName) for i in range(0, node_in.attributes.length): name = node_in.attributes.item(i).name value = node_in.attributes.item(i).value node_out.setAttribute(name, value) else: node_out = self.document.createElement('svg:g') for c in node_in.childNodes: if c.localName in ('g', 'path', 'polyline', 'polygon'): child = clone_and_rewrite(self, c) if c.localName == 'g': child.setAttribute('transform','matrix('+str(doc_sizeH/700.)+',0,0,'+str(-doc_sizeH/700.)+','+str(-doc_sizeH*0.25)+','+str(doc_sizeW*0.75)+')') node_out.appendChild(child) return node_out doc = xml.dom.minidom.parse(filename) svg = doc.getElementsByTagName('svg')[0] group = clone_and_rewrite(self, svg) self.current_layer.appendChild(group)
def effect(self): """Applies the effect""" svg_root = self.document.getroot() width = inkex.unittouu(svg_root.get("width")) height = inkex.unittouu(svg_root.get("height")) self.canvas = Canvas(width, height) self.walk_tree(svg_root)
def effect(self): # Get script's options values. Input. include_hor = self.options.include_hor_guide include_vert = self.options.include_vert_guide # getting parent tag of the guides namedview = self.document.xpath('/svg:svg/sodipodi:namedview', namespaces=inkex.NSS)[0] # getting the main SVG document element (canvas) svg = self.document.getroot() # getting the width and height attributes of the canvas canvas_width = inkex.unittouu(svg.get('width')) canvas_height = inkex.unittouu(svg.attrib['height']) # calculate center of document center_pos_x = canvas_width / 2 center_pos_y = canvas_height / 2 # call the function. Output. drawCenteredGuides(center_pos_x, center_pos_y, include_hor, include_vert, namedview)
def validate_options(self): #inkex.errormsg( self.options.input_encode ) # Convert string names lists in real lists m = re.match('\s*(.*[^\s])\s*', self.options.month_names) self.options.month_names = re.split('\s+', m.group(1)) m = re.match('\s*(.*[^\s])\s*', self.options.day_names) self.options.day_names = re.split('\s+', m.group(1)) # Validate names lists if len(self.options.month_names) != 12: inkex.errormsg('The month name list "' + \ str(self.options.month_names) + \ '" is invalid. Using default.') self.options.month_names = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ] if len(self.options.day_names) != 7: inkex.errormsg('The day name list "' + str(self.options.day_names) + '" is invalid. Using default.') self.options.day_names = [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ] # Convert year 0 to current year if self.options.year == 0: self.options.year = datetime.today().year # Year 1 starts it's week at monday, obligatorily if self.options.year == 1: self.options.start_day = 'mon' # Set the calendar start day if self.options.start_day == 'sun': calendar.setfirstweekday(6) else: calendar.setfirstweekday(0) # Convert string numbers with unit to user space float numbers self.options.month_width = inkex.unittouu(self.options.month_width) self.options.month_margin = inkex.unittouu(self.options.month_margin)
def snap_rect(self, elem, parent_transform=None): transform = self.transform(elem, parent_transform=parent_transform) if transform[0][1] or transform[1][0]: # if we've got any skew/rotation, get outta here raise TransformError("Selection contains transformations with skew/rotation") offset = self.elem_offset(elem, parent_transform) % 1 width = unittouu(elem.attrib['width']) height = unittouu(elem.attrib['height']) x = unittouu(elem.attrib['x']) y = unittouu(elem.attrib['y']) width, height = transform_dimensions(transform, width, height) x, y = transform_point(transform, [x, y]) # Snap to the nearest pixel height = round(height) width = round(width) x = round(x - offset) + offset # If there's a stroke of non-even width, it's shifted by half a pixel y = round(y - offset) + offset width, height = transform_dimensions(transform, width, height, inverse=True) x, y = transform_point(transform, [x, y], inverse=True) y += self.document_offset/transform[1][1] # Position the elem at the newly calculate values elem.attrib['width'] = str(width) elem.attrib['height'] = str(height) elem.attrib['x'] = str(x) elem.attrib['y'] = str(y)
def calculate_size_and_positions(self): # month_margin month_width months_per_line auto_organize self.doc_w = inkex.unittouu(self.document.getroot().get("width")) self.doc_h = inkex.unittouu(self.document.getroot().get("height")) if self.options.show_weeknr: self.cols_before = 1 else: self.cols_before = 0 if self.options.auto_organize: if self.doc_h > self.doc_w: self.months_per_line = 3 else: self.months_per_line = 4 else: self.months_per_line = self.options.months_per_line # self.month_w = self.doc_w / self.months_per_line if self.options.auto_organize: self.month_w = (self.doc_w * 0.8) / self.months_per_line self.month_margin = self.month_w / 10 else: self.month_w = self.options.month_width self.month_margin = self.options.month_margin self.day_w = self.month_w / (7 + self.cols_before) self.day_h = self.month_w / 9 self.month_h = self.day_w * 7 if self.options.month == 0: self.year_margin = ( self.doc_w + self.day_w - (self.month_w * self.months_per_line) - (self.month_margin * (self.months_per_line - 1)) ) / 2 # - self.month_margin else: self.year_margin = (self.doc_w - self.month_w) / 2 self.style_day = { "font-size": str(self.day_w / 2), "font-family": "arial", "text-anchor": "middle", "text-align": "center", "fill": self.options.color_day, } self.style_weekend = self.style_day.copy() self.style_weekend["fill"] = self.options.color_weekend self.style_nmd = self.style_day.copy() self.style_nmd["fill"] = self.options.color_nmd self.style_month = self.style_day.copy() self.style_month["fill"] = self.options.color_month self.style_month["font-size"] = str(self.day_w / 1.5) self.style_month["font-weight"] = "bold" self.style_day_name = self.style_day.copy() self.style_day_name["fill"] = self.options.color_day_name self.style_day_name["font-size"] = str(self.day_w / 3) self.style_year = self.style_day.copy() self.style_year["fill"] = self.options.color_year self.style_year["font-size"] = str(self.day_w * 2) self.style_year["font-weight"] = "bold" self.style_weeknr = self.style_day.copy() self.style_weeknr["fill"] = self.options.color_weeknr self.style_weeknr["font-size"] = str(self.day_w / 3)
def decode_raster(self, img): img_uri = img.attrib[inkex.addNS('href', 'xlink')] pil_img = Image.open(decode_uri(img_uri)) self.data = pil_img.getdata() self.transform = img.transform self.pos = (inkex.unittouu(img.attrib['x']), inkex.unittouu(img.attrib['y']))
def validate_polygon(self, polygon): svg = self.document.getroot() canw = inkex.unittouu(svg.get('width')) canh = inkex.unittouu(svg.attrib['height']) if pdbg > 2: dbg("Canvas (%dx, %dy)" % (canw, canh)) for (x, y) in polygon: dbg(' (%dx, %dy)' % (x, y))
def get_document_size(self): """Return width and height of document in SVG units as a tuple (W, H). """ if not self.doc_size: x = inkex.unittouu(self.document.getroot().get('width')) y = inkex.unittouu(self.document.getroot().get('height')) self.doc_size = (x, y) return self.doc_size
def calculate_size_and_positions(self): #month_margin month_width months_per_line auto_organize self.doc_w = inkex.unittouu(self.document.getroot().get('width')) self.doc_h = inkex.unittouu(self.document.getroot().get('height')) if self.options.show_weeknr: self.cols_before = 1 else: self.cols_before = 0 if self.options.auto_organize: if self.doc_h > self.doc_w: self.months_per_line = 3 else: self.months_per_line = 4 else: self.months_per_line = self.options.months_per_line #self.month_w = self.doc_w / self.months_per_line if self.options.auto_organize: self.month_w = (self.doc_w * 0.8) / self.months_per_line self.month_margin = self.month_w / 10 else: self.month_w = self.options.month_width self.month_margin = self.options.month_margin self.day_w = self.month_w / (7 + self.cols_before) self.day_h = self.month_w / 9 self.month_h = self.day_w * 7 if self.options.month == 0: self.year_margin = ((self.doc_w + self.day_w - \ (self.month_w * self.months_per_line) - \ (self.month_margin * \ (self.months_per_line - 1))) / 2) #- self.month_margin else: self.year_margin = (self.doc_w - self.month_w) / 2 self.style_day = { 'font-size': str(self.day_w / 2), 'font-family': 'arial', 'text-anchor': 'middle', 'text-align': 'center', 'fill': self.options.color_day } self.style_weekend = self.style_day.copy() self.style_weekend['fill'] = self.options.color_weekend self.style_nmd = self.style_day.copy() self.style_nmd['fill'] = self.options.color_nmd self.style_month = self.style_day.copy() self.style_month['fill'] = self.options.color_month self.style_month['font-size'] = str(self.day_w / 1.5) self.style_month['font-weight'] = 'bold' self.style_day_name = self.style_day.copy() self.style_day_name['fill'] = self.options.color_day_name self.style_day_name['font-size'] = str(self.day_w / 3) self.style_year = self.style_day.copy() self.style_year['fill'] = self.options.color_year self.style_year['font-size'] = str(self.day_w * 2) self.style_year['font-weight'] = 'bold' self.style_weeknr = self.style_day.copy() self.style_weeknr['fill'] = self.options.color_weeknr self.style_weeknr['font-size'] = str(self.day_w / 3)
def getNumberValues(self): sv = self.options.start_val ev = self.options.end_val if self.inte_att_type and self.inte_att_type != 'none': sv = inkex.unittouu( sv + self.inte_att_type ) ev = inkex.unittouu( ev + self.inte_att_type ) self.val_cur = self.val_ini = sv self.val_end = ev self.val_inc = ( ev - sv ) / float( self.tot_el - 1 )
def effect(self): """ This method is called first, and sets up the self.commands list for later output. """ svg = self.document.getroot() # find document width and height, used to scale down self.doc_width = inkex.unittouu(svg.get('width')) self.doc_height = inkex.unittouu(svg.get('height')) # add header self.commands.append("^DF;") self.commands.append("! 1;") self.commands.append("H;") self.commands.append("@ %d %d;" % (self.options.z_down, self.options.z_up)) self.commands.append("V {0};F {0};\n".format(self.options.feed_rate_moving)) self.commands.append("Z 0 0 %d;" % self.options.z_up) # mostly borrowed from hgpl_output.py lastX = 0 lastY = 0 # find paths in layers i = 0 layerPath = '//svg:g[@inkscape:groupmode="layer"]' for layer in svg.xpath(layerPath, namespaces=inkex.NSS): i += 1 nodePath = ('//svg:g[@inkscape:groupmode="layer"][%d]/descendant::svg:path') % i for node in svg.xpath(nodePath, namespaces=inkex.NSS): # these next lines added from this patch to fix the transformation issues - http://launchpadlibrarian.net/36269154/hpgl_output.py.patch # possibly also want to try this code: https://bugs.launchpad.net/inkscape/+bug/600472/+attachment/1475310/+files/hpgl_output.py transforms = node.xpath("./ancestor-or-self::svg:*[@transform]",namespaces=inkex.NSS) matrix = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]] for parenttransform in transforms: newmatrix = simpletransform.parseTransform(parenttransform.get("transform")) matrix = simpletransform.composeTransform(matrix, newmatrix) d = node.get('d') if len(simplepath.parsePath(d)): p = cubicsuperpath.parsePath(d) simpletransform.applyTransformToPath(matrix, p) # this line is also from the transform-fixing patch mentioned above cspsubdiv.cspsubdiv(p, self.options.flat) for sp in p: first = True for csp in sp: if first: x, y = self.conv_coords(csp[1][0], self.doc_height - csp[1][1]) self.commands.append("Z %d %d %d;" % (x, y, self.options.z_up)) self.commands.append("V {0};F {0};".format(self.options.feed_rate_cutting)) first = False x, y = self.conv_coords(csp[1][0], self.doc_height - csp[1][1]) self.commands.append("Z %d %d %d;" % (x, y, self.options.z_down)) lastX = x lastY = y self.commands.append("V {0};F {0};".format(self.options.feed_rate_moving)) self.commands.append("Z %d %d %d;" % (lastX, lastY, self.options.z_up)) self.commands.append("Z 0 0 %d;" % self.options.z_up) self.commands.append("H;")
def effect(self): """Applies the effect""" svg = self.document.getroot() width = inkex.unittouu(svg.get("width")) height = inkex.unittouu(svg.get("height")) ctx = Canvas(width, height) #starts parsing groups passing root element self.drawG(ctx, svg) self.content = ctx.output()
def effect(self): """ Effect behaviour. Overrides base class' method and inserts "Hello World" text into SVG document. """ self.parse() # Get script's "--what" option value. data_file = self.options.data_file try: handler = csv.reader(open(data_file, 'r')) i = 1 for line in handler: id = line[0] txt = line[1] try: styles = line[2] try: styles = eval(line[2]) except: inkex.errormsg("Styles syntax in line " + i + ". Ignoring styles.") except: styles = None # Create text element text = inkex.etree.Element(inkex.addNS('text', 'svg')) text.text = txt node = self.getElementById(id) # Again, there are two ways to get the attibutes: width = inkex.unittouu(node.get('width')) height = inkex.unittouu(node.get('height')) xpos = inkex.unittouu(node.get('x')) ypos = inkex.unittouu(node.get('y')) # Set text position to center of document. text.set('x', str(xpos + (width / 2))) text.set('y', str(ypos + (height / 2))) # Center text horizontally with CSS style. style = {'text-align': 'center', 'text-anchor': 'middle'} if styles is not None: style.update(styles) text.set('style', formatStyle(style)) # Connect elements together. self.document.getroot().append(text) i = i + 1 except: inkex.errormsg("Unkown error")
def register_all_els_geometry(self): ink_cmm = 'inkscape --query-all '+self.tmp_svg (status, output) = self.get_cmd_output( ink_cmm ) self.el_geo = { } if status == 0: for el in output.split('\n'): el = el.split(',') if len(el) == 5: self.el_geo[el[0]] = { 'x':float(el[1]), 'y':float(el[2]), 'w':float(el[3]), 'h':float(el[4]) } doc_w = inkex.unittouu( self.document.getroot().get('width') ) doc_h = inkex.unittouu( self.document.getroot().get('height') ) self.el_geo['webslicer-layer'] = { 'x':0, 'y':0, 'w':doc_w, 'h':doc_h }
def vectorize_tile(self, tile): tile_size = self.tile_size tile_x = inkex.unittouu(tile.attrib['x']) tile_y = inkex.unittouu(tile.attrib['y']) tile_img = Image.open(self.decode_uri(tile.attrib[inkex.addNS('href', 'xlink')])) tile_data = tile_img.getdata() any_img = tti_tools.AnyImage(tile_size, (tile_x, tile_y), tile_data) if self.options.group: return any_img.vectorize_with_paths() return any_img.vectorize()
def effect(self): self.tile_size = tile_size = self.options.tile_size clear_first = self.options.clear_first vectorize = self.options.vectorize root = self.document.xpath('//svg:svg',namespaces=inkex.NSS)[0] width = inkex.unittouu(root.attrib['width']) height = inkex.unittouu(root.attrib['height']) columns = width // tile_size if clear_first: set_layer_path = '//svg:g[@inkscape:label="Tileset Layer"]' set_layer = root.xpath(set_layer_path, namespaces=inkex.NSS) for layer in set_layer: root.remove(layer) set_layer = inkex.etree.SubElement(root, 'g') set_layer.set(inkex.addNS('label', 'inkscape'), 'Tileset Layer') set_layer.set(inkex.addNS('groupmode', 'inkscape'), 'layer') tiles = set() for uri in self.gather_source_uris(): tiles |= get_unique_tiles(Image.open(decode_uri(uri)), tile_size) if vectorize: for i, tile in enumerate(tiles): pos = tti_tools.index2pos(columns, i, scale=tile_size) any_img = tti_tools.AnyImage(tile_size, pos, tile) if self.options.group: vector_tile = any_img.vectorize_with_paths() else: vector_tile = any_img.vectorize() set_layer.append(vector_tile) else: tiles = [self.rebuild_tile(tile) for tile in tiles] for i, tile in enumerate(tiles): uri = make_data_uri(tile) img = self.build_svg_img( uri, x = str((i % columns) * tile_size), y = str((i // columns) * tile_size), width = str(tile_size), height = str(tile_size) ) set_layer.append(img)
def validate_options(self): #inkex.errormsg( self.options.input_encode ) # Convert string names lists in real lists: m = re.match( '\s*(.*[^\s])\s*', self.options.month_names ) self.options.month_names = re.split( '\s+', m.group(1) ) m = re.match( '\s*(.*[^\s])\s*', self.options.day_names ) self.options.day_names = re.split( '\s+', m.group(1) ) # Validate names lists: if len(self.options.month_names) != 12: inkex.errormsg('The month name list "'+ str(self.options.month_names)+ '" is invalid. Using default.') self.options.month_names = ['January','February','March', 'April', 'May', 'June', 'July', 'August', 'September', 'October','November','December'] if len(self.options.day_names) != 7: inkex.errormsg('The day name list "'+ str(self.options.day_names)+ '" is invalid. Using default.') self.options.day_names = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'] # Convert year 0 to current year: if self.options.year == 0: self.options.year = datetime.today().year # Set the calendar start day: if self.options.start_day=='sun': calendar.setfirstweekday(6) else: calendar.setfirstweekday(0) # Convert string numbers with unit to user space float numbers: self.options.month_width = inkex.unittouu( self.options.month_width ) self.options.month_margin = inkex.unittouu( self.options.month_margin ) def replace_year(dt): return date( int(self.options.year), dt.month, dt.day ) self.other_holidays = [] try: for d in re.split("[;,]+", self.options.other_holidays): d = d.strip() parts = re.split("[ \t]+", d) if parts and (parts[0]): part = { 'date': replace_year(parser.parse(parts[0]).date()), 'description': '' } if len(parts)>1: part['description'] = " ".join(parts[1:]) self.other_holidays.append(part) except Exception as e: inkex.errormsg("Error in parsing holidays string. Dates should be delimited by ';'. Optional date description should be appended after date followed by <space> character. \n%s" % e) exit(1) self.other_holidays_dates = [o['date'] for o in self.other_holidays]
def effect(self): # Get script's options values. Input. # Factor to multiply in order to get user units (pixels) factor = inkex.unittouu('1' + self.options.unit) # boolean same_margins = self.options.same_margins # convert string to integer, in user units (pixels) top_margin = float(self.options.top_margin) * factor right_margin = float(self.options.right_margin) * factor bottom_margin = float(self.options.bottom_margin) * factor left_margin = float(self.options.left_margin) * factor # getting parent tag of the guides namedview = self.document.xpath('/svg:svg/sodipodi:namedview', namespaces=inkex.NSS)[0] # getting the main SVG document element (canvas) svg = self.document.getroot() # getting the width and height attributes of the canvas canvas_width = inkex.unittouu(svg.get('width')) canvas_height = inkex.unittouu(svg.get('height')) # Get selection bounding box - TODO # now let's use the input: # draw margin guides (if not zero) if same_margins: right_margin = top_margin bottom_margin = top_margin left_margin = top_margin # start position of guides top_pos = canvas_height - top_margin right_pos = canvas_width - right_margin bottom_pos = bottom_margin left_pos = left_margin # Draw the four margin guides (if margin exists) if top_pos != canvas_height: drawGuide(top_pos, "horizontal", namedview) if right_pos != canvas_width: drawGuide(right_pos, "vertical", namedview) if bottom_pos != 0: drawGuide(bottom_pos, "horizontal", namedview) if left_pos != 0: drawGuide(left_pos, "vertical", namedview)
def effect(self): # メインのルート要素であるSVGを取得 svg = self.document.getroot() inkex.errormsg(str(svg)) image=svg.find(ALL+XMLNS+"image") width=inkex.unittouu(image.attrib["width"]) height=inkex.unittouu(image.attrib["height"]) #width = inkex.unittouu(svg.get('width')) #height = inkex.unittouu(svg.attrib['height']) #初期化の点 points=[[0,0],[width,0],[width,height],[0,height]] inkex.errormsg(u"画像属性" + str(image.attrib)) url=image.attrib[XLINK+"href"] inkex.errormsg((u"画像" + str(url))) #file.//の部分を取り除く im = Image.open(url[7:]) color=im.getpixel((0,0)) inkex.errormsg((u"色:" + str(color))) path=svg.find(ALL+XMLNS+"path") if path == None: inkex.errormsg(u"パスを書いてください!!") #パスの頂点座標を取得 vals=simplepath.parsePath(path.get('d')) for cmd,vert in vals: #たまに空のが入ってるため、それ対策 if len(vert) != 0: inkex.errormsg((u"頂点:" + str(vert))) points.append(vert) trignales,nodes = triangulate(points) inkex.errormsg(u"三角形分割の結果"+str(trignales)) i=0 for t in trignales: onedarray=t.parseSVG() attributes={"points":str(onedarray), "style":"fill:"+simplestyle.formatColor3i(color[0],color[1],color[2])+";stroke:white;stroke-width:3", "fill-opacity":"0.5"} polygon =inkex.etree.Element("polygon",attributes) svg.append(polygon) #for n in nodes: # circle=n.circle # inkex.errormsg(u"円:"+str(circle)) # attributes={"cx":str(circle.center.x),"cy":str(circle.center.y),"r":str(circle.radius), # "stroke":"yellow","stroke-width":"3","fill-opacity":"0.0"} # circle =inkex.etree.Element("circle",attributes) # svg.append(circle) inkex.errormsg(str(polygon))
def effect(self): self.hpgl = ['IN;SP%d;' % self.options.pen] x0 = self.options.xOrigin y0 = self.options.yOrigin scale = float(self.options.resolution)/90 self.options.flat *= scale mirror = 1.0 if self.options.mirror: mirror = -1.0 if inkex.unittouu(self.document.getroot().xpath('@height', namespaces=inkex.NSS)[0]): y0 -= float(inkex.unittouu(self.document.getroot().xpath('@height', namespaces=inkex.NSS)[0])) self.groupmat = [[[scale, 0.0, -x0*scale], [0.0, mirror*scale, -y0*scale]]] doc = self.document.getroot() self.process_group(doc) self.hpgl.append('PU;')
def startRendering(self): self.cursorY = 310 self.svg = self.document.getroot() self.width= inkex.unittouu(self.svg.get('width')) self.height= inkex.unittouu(self.svg.get('height')) #draw the UI and create layers, if it's not been done yet self.renderArmatureUI() if not self.options.newLayerSet is None: #find out what the state of the layers are layerInfo=self.getLayerInfo() self.updateArmatureData(self.options.newLayerSet,layerInfo) else: inkex.errormsg("Enter a title to update an existing set, or create a new one.")
def effect( self ): markup = processMarkup( self.options.text, self.options.fontfamily ) g,w = renderText( self.current_layer, markup ) # Now to wrap the text N times around the egg, we need to scale it to have # length 3200 * N. It's current width is w so the scale factor is (3200 * N) / w. scale_x = float( 3200 * self.options.wrap ) / float( w ) scale_y = scale_x if self.options.stretch: scale_y = scale_y * 2.0 / 3.0 # In planning the scaling, we'd like to know the height of our line of text. # Rather than computing its bounding box, we'll just use the height of the # parens from the Simplex Roman font. And, we could compute that but we'll # just use our prior knowledge of it being 32. h = float( 32.0 ) # And the angular tilt will be arcsine( height / (3200 * fWrap) ) svg = self.document.getroot() height = float( inkex.unittouu( svg.attrib['height'] ) ) - h * scale_y angle = ( float( 180 ) / math.pi ) * \ math.asin( height / float( 3200 * self.options.wrap ) ) if self.options.flip: angle += float( 180.0 ) t = 'translate(%f,%f) rotate(%f,%f,0) scale(%f,%f)' % ( -w*scale_x, h*scale_y, angle, w*scale_x, scale_x, scale_y ) else: t = 'translate(0,%f) rotate(%f,0,0) scale(%f,%f)' % ( h, angle, scale_x, scale_y ) g.set( 'transform', t)
def effect(self): #References: Minimum Requirements for Creating a DXF File of a 3D Model By Paul Bourke # NURB Curves: A Guide for the Uninitiated By Philip J. Schneider # The NURBS Book By Les Piegl and Wayne Tiller (Springer, 1995) # self.dxf_add("999\nDXF created by Inkscape\n") # Some programs do not take comments in DXF files (KLayout 0.21.12 for example) self.dxf_add(dxf_templates.r14_header) for node in self.document.getroot().xpath('//svg:g', namespaces=inkex.NSS): if node.get(inkex.addNS('groupmode', 'inkscape')) == 'layer': layer = node.get(inkex.addNS('label', 'inkscape')) layer = layer.replace(' ', '_') if layer and not layer in self.layers: self.layers.append(layer) self.dxf_add(" 2\nLAYER\n 5\n2\n100\nAcDbSymbolTable\n 70\n%s\n" % len(self.layers)) for i in range(len(self.layers)): self.dxf_add( " 0\nLAYER\n 5\n%x\n100\nAcDbSymbolTableRecord\n100\nAcDbLayerTableRecord\n 2\n%s\n 70\n0\n 6\nCONTINUOUS\n" % (i + 80, self.layers[i])) self.dxf_add(dxf_templates.r14_style) scale = eval(self.options.units) if not scale: scale = 25.4 / 90 # if no scale is specified, assume inch as baseunit h = inkex.unittouu(self.document.getroot().xpath( '@height', namespaces=inkex.NSS)[0]) self.groupmat = [[[scale, 0.0, 0.0], [0.0, -scale, h * scale]]] doc = self.document.getroot() self.process_group(doc) if self.options.ROBO == 'true': self.ROBO_output() if self.options.POLY == 'true': self.LWPOLY_output() self.dxf_add(dxf_templates.r14_footer)
def effect(self): markup = processMarkup(self.options.text, self.options.fontfamily) g, w = renderText(self.current_layer, markup) # Now to wrap the text N times around the egg, we need to scale it to have # length 3200 * N. It's current width is w so the scale factor is (3200 * N) / w. scale_x = float(3200 * self.options.wrap) / float(w) scale_y = scale_x if self.options.stretch: scale_y = scale_y * 2.0 / 3.0 # In planning the scaling, we'd like to know the height of our line of text. # Rather than computing its bounding box, we'll just use the height of the # parens from the Simplex Roman font. And, we could compute that but we'll # just use our prior knowledge of it being 32. h = float(32.0) # And the angular tilt will be arcsine( height / (3200 * fWrap) ) svg = self.document.getroot() height = float(inkex.unittouu(svg.attrib['height'])) - h * scale_y angle = ( float( 180 ) / math.pi ) * \ math.asin( height / float( 3200 * self.options.wrap ) ) if self.options.flip: angle += float(180.0) t = 'translate(%f,%f) rotate(%f,%f,0) scale(%f,%f)' % ( -w * scale_x, h * scale_y, angle, w * scale_x, scale_x, scale_y) else: t = 'translate(0,%f) rotate(%f,0,0) scale(%f,%f)' % ( h, angle, scale_x, scale_y) g.set('transform', t)
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 try: import simplestyle fontsize = simplestyle.parseStyle(word.get("style"))["font-size"] except: fontsize = "12px" fs = inkex.unittouu(fontsize) #for each letter in element string for letter in word[0].text: tspan = inkex.etree.Element(inkex.addNS("tspan", "svg")) tspan.text = letter text = inkex.etree.Element(inkex.addNS("text", "svg"), node.attrib) text.set("x", str(x)) text.set("y", str(y)) x += fs text.append(tspan) letters.append(text) return letters
def effect(self): #References: Minimum Requirements for Creating a DXF File of a 3D Model By Paul Bourke # NURB Curves: A Guide for the Uninitiated By Philip J. Schneider # The NURBS Book By Les Piegl and Wayne Tiller (Springer, 1995) # self.dxf_add("999\nDXF created by Inkscape\n") # Some programs do not take comments in DXF files (KLayout 0.21.12 for example) self.dxf_add(dxf_templates.r14_header) for node in self.document.getroot().xpath('//svg:g', namespaces=inkex.NSS): if node.get(inkex.addNS('groupmode', 'inkscape')) == 'layer': layer = node.get(inkex.addNS('label', 'inkscape')) layer = layer.replace(' ', '_') if layer and not layer in self.layers: self.layers.append(layer) self.dxf_add(" 2\nLAYER\n 5\n2\n100\nAcDbSymbolTable\n 70\n%s\n" % len(self.layers)) for i in range(len(self.layers)): self.dxf_add(" 0\nLAYER\n 5\n%x\n100\nAcDbSymbolTableRecord\n100\nAcDbLayerTableRecord\n 2\n%s\n 70\n0\n 6\nCONTINUOUS\n" % (i + 80, self.layers[i])) self.dxf_add(dxf_templates.r14_style) scale = eval(self.options.units) if not scale: scale = 25.4/90 # if no scale is specified, assume inch as baseunit h = inkex.unittouu(self.document.getroot().xpath('@height', namespaces=inkex.NSS)[0]) self.groupmat = [[[scale, 0.0, 0.0], [0.0, -scale, h*scale]]] doc = self.document.getroot() self.process_group(doc) if self.options.ROBO == 'true': self.ROBO_output() if self.options.POLY == 'true': self.LWPOLY_output() self.dxf_add(dxf_templates.r14_footer)
def createMarkerAt(self, parent, x, y, radius, markerText): markerGroup = inkex.etree.SubElement(parent, 'g') ellipce_atts = { inkex.addNS('cx','sodipodi'):str(x), inkex.addNS('cy','sodipodi'):str(y), inkex.addNS('rx','sodipodi'):str(radius), inkex.addNS('ry','sodipodi'):str(radius), inkex.addNS('type','sodipodi'):'arc', 'd':'m '+str(x+radius)+','+str(y)+' a '+ str(x)+','+str(y)+' 0 1 1 ' + str(-radius*2)+',0 '+ str(x)+','+str(y)+' 0 1 1 ' + str(radius*2)+',0 z', 'style':'fill:#b3b3b3;stroke:#000000;stroke-width:'+str(inkex.unittouu('0.125 mm'))+';stroke-opacity:1;fill-opacity:1' } ellipse = inkex.etree.SubElement(markerGroup, 'path', ellipce_atts) textstyle = { 'font-size': '11 px', 'font-family': 'arial', 'text-anchor': 'middle', 'text-align': 'center', 'fill': '#000000' } text_atts = { 'style':simplestyle.formatStyle(textstyle), 'x': str( x ), 'y': str( y + radius*0.5) } text = inkex.etree.SubElement(markerGroup, 'text', text_atts) text.text = str(markerText)
def effect(self): #References: Minimum Requirements for Creating a DXF File of a 3D Model By Paul Bourke # NURB Curves: A Guide for the Uninitiated By Philip J. Schneider # The NURBS Book By Les Piegl and Wayne Tiller (Springer, 1995) self.dxf_add("999\nDXF created by Inkscape\n") self.dxf_add(dxf_templates.r14_header) scale = 25.4/90.0 h = inkex.unittouu(self.document.getroot().xpath('@height', namespaces=inkex.NSS)[0]) path = '//svg:path' for node in self.document.getroot().xpath(path, namespaces=inkex.NSS): d = node.get('d') sim = simplepath.parsePath(d) if len(sim): simplepath.scalePath(sim,scale,-scale) simplepath.translatePath(sim,0,h*scale) p = cubicsuperpath.CubicSuperPath(sim) for sub in p: for i in range(len(sub)-1): s = sub[i] e = sub[i+1] if s[1] == s[2] and e[0] == e[1]: self.dxf_line([s[1],e[1]]) elif (self.options.ROBO == 'true'): self.ROBO_spline([s[1],s[2],e[0],e[1]]) else: self.dxf_spline([s[1],s[2],e[0],e[1]]) if self.options.ROBO == 'true': self.ROBO_output() self.LWPOLY_output() self.dxf_add(dxf_templates.r14_footer)
def effect(self): # Get script's options values. Input. # Factor to multiply in order to get user units (pixels) factor = inkex.unittouu('1' + self.options.unit) # boolean same_margins = self.options.same_margins # convert string to integer, in user units (pixels) top_margin = float(self.options.top_margin) * factor right_margin = float(self.options.right_margin) * factor bottom_margin = float(self.options.bottom_margin) * factor left_margin = float(self.options.left_margin) * factor # getting parent tag of the guides namedview = self.document.xpath('/svg:svg/sodipodi:namedview',namespaces=inkex.NSS)[0] # getting the main SVG document element (canvas) svg = self.document.getroot() # getting the width and height attributes of the canvas canvas_width = inkex.unittouu(svg.get('width')) canvas_height = inkex.unittouu(svg.get('height')) # Get selection bounding box - TODO # now let's use the input: # draw margin guides (if not zero) if same_margins: right_margin = top_margin bottom_margin = top_margin left_margin = top_margin # start position of guides top_pos = canvas_height - top_margin right_pos = canvas_width - right_margin bottom_pos = bottom_margin left_pos = left_margin # Draw the four margin guides (if margin exists) if top_pos != canvas_height: drawGuide(top_pos, "horizontal", namedview) if right_pos != canvas_width: drawGuide(right_pos, "vertical", namedview) if bottom_pos != 0: drawGuide(bottom_pos, "horizontal", namedview) if left_pos != 0: drawGuide(left_pos, "vertical", namedview)
def find_reasonable_center_xy(self, element): x = element.get('x') if x: return ((float(inkex.unittouu(x)) + float(inkex.unittou(element.get('width'))) / 2), (float(inkex.unittouu(element.get('y'))) + float(inkex.unittou(element.get('height'))) / 2)) else: return (float(element.get(inkex.addNS('cx', 'sodipodi'))), float(element.get(inkex.addNS('cy', 'sodipodi')))) y = element.get('y') if y: y = float(inkex.unittouu(y)) else: y = float(element.get(inkex.addNS('cy', 'sodipodi'))) return (x, y)
def createWhiteKey(self, parent, number): key_atts = { 'x': str(self.white_key_width * number), 'y': '0.0', 'width': str(self.white_key_width), 'height': str(self.white_key_height), 'ry': str(inkex.unittouu('0.7 mm')), 'style': 'fill:#ffffff;stroke:#000000;stroke-width:' + str(inkex.unittouu('0.25 mm')) + ';stroke-opacity:1;fill-opacity:1' } white_key = inkex.etree.SubElement(parent, 'rect', key_atts)
def unit_to_uu(self, unit): """ Wrapper for unittouu() accounting for different implementation in Inkscape versions""" try: # Inkscape > 0.48 return self.unittouu(unit) except AttributeError: # Inkscape <= 0.48 return inkex.unittouu(unit)
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 try: from simplestyle import parseStyle fontsize = parseStyle(line.get("style"))["font-size"] except: fontsize = "12px" fs = inkex.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 = inkex.etree.Element(inkex.addNS("tspan", "svg")) tspan.text = word text = inkex.etree.Element(inkex.addNS("text", "svg"), line.attrib) tspan.set(inkex.addNS("role", "sodipodi"), "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
def split_lines(self, node): """Returns a list of lines""" lines = [] count = 1 for n in node: if not (n.tag == inkex.addNS("flowPara", "svg") or n.tag == inkex.addNS("tspan", "svg")): if n.tag == inkex.addNS("textPath", "svg"): inkex.debug("This type of text element isn't supported. First remove text from path.") break else: continue text = inkex.etree.Element(inkex.addNS("text", "svg"), node.attrib) # handling flowed text nodes if node.tag == inkex.addNS("flowRoot", "svg"): try: from simplestyle import parseStyle fontsize = parseStyle(node.get("style"))["font-size"] except: fontsize = "12px" fs = inkex.unittouu(fontsize) # selects the flowRegion's child (svg:rect) to get @X and @Y id = node.get("id") flowref = self.xpathSingle('/svg:svg//*[@id="%s"]/svg:flowRegion[1]' % id)[0] if flowref.tag == inkex.addNS("rect", "svg"): 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 = inkex.etree.Element(inkex.addNS("tspan", "svg")) tspan.set(inkex.addNS("role", "sodipodi"), "line") tspan.text = n.text text.append(tspan) else: from copy import copy x = n.get("x") or node.get("x") y = n.get("y") or node.get("y") text.set("x", x) text.set("y", y) text.append(copy(n)) lines.append(text) return lines
def process_shape(self, node, mat): rgb = (0, 0, 0) # stroke color fillcolor = None # fill color stroke = 1 # pen width in printer pixels # Very NB : If the pen width is greater than 1 then the output will Not be a vector output ! style = node.get('style') if style: style = simplestyle.parseStyle(style) if style.has_key('stroke'): if style['stroke'] and style['stroke'] != 'none' and style[ 'stroke'][0:3] != 'url': rgb = simplestyle.parseColor(style['stroke']) if style.has_key('stroke-width'): stroke = inkex.unittouu(style['stroke-width']) stroke = int(stroke * self.scale) if style.has_key('fill'): if style['fill'] and style['fill'] != 'none' and style['fill'][ 0:3] != 'url': fill = simplestyle.parseColor(style['fill']) fillcolor = fill[0] + 256 * fill[1] + 256 * 256 * fill[2] color = rgb[0] + 256 * rgb[1] + 256 * 256 * rgb[2] if node.tag == inkex.addNS('path', 'svg'): d = node.get('d') if not d: return p = cubicsuperpath.parsePath(d) elif node.tag == inkex.addNS('rect', 'svg'): x = float(node.get('x')) y = float(node.get('y')) width = float(node.get('width')) height = float(node.get('height')) p = [[[x, y], [x, y], [x, y]]] p.append([[x + width, y], [x + width, y], [x + width, y]]) p.append([[x + width, y + height], [x + width, y + height], [x + width, y + height]]) p.append([[x, y + height], [x, y + height], [x, y + height]]) p.append([[x, y], [x, y], [x, y]]) p = [p] else: return trans = node.get('transform') if trans: mat = simpletransform.composeTransform( mat, simpletransform.parseTransform(trans)) simpletransform.applyTransformToPath(mat, p) hPen = mygdi.CreatePen(0, stroke, color) mygdi.SelectObject(self.hDC, hPen) self.emit_path(p) if fillcolor is not None: brush = LOGBRUSH(0, fillcolor, 0) hBrush = mygdi.CreateBrushIndirect(addressof(brush)) mygdi.SelectObject(self.hDC, hBrush) mygdi.BeginPath(self.hDC) self.emit_path(p) mygdi.EndPath(self.hDC) mygdi.FillPath(self.hDC) return
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 try: from simplestyle import parseStyle fontsize = parseStyle(line.get("style"))["font-size"] except: fontsize = "12px" fs = inkex.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 = inkex.etree.Element(inkex.addNS("tspan", "svg")) tspan.text = word text = inkex.etree.Element(inkex.addNS("text", "svg"), line.attrib) tspan.set(inkex.addNS("role", "sodipodi"), "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
def _handle_shape(self, node): """Extract shape data from node""" options = [] if node.tag == _ns('rect'): inset = node.get('rx', '0') or node.get('ry', '0') # TODO: ry <> rx is not supported by TikZ. Convert to path? x = inkex.unittouu(node.get('x', '0')) y = inkex.unittouu(node.get('y', '0')) # map from svg to tikz width = inkex.unittouu(node.get('width', '0')) height = inkex.unittouu(node.get('height', '0')) if width == 0.0 or height == 0.0: return None, [] if inset: # TODO: corner radius is not scaled by PGF. Find a better way to fix this. options = ["rounded corners=%s" % self.transform([inkex.unittouu(inset) * 0.8])] return ('rect', (x, y, width + x, height + y)), options elif node.tag in [_ns('polyline'), _ns('polygon'), ]: points = node.get('points', '').replace(',', ' ') points = map(inkex.unittouu, points.split()) if node.tag == _ns('polyline'): cmd = 'polyline' else: cmd = 'polygon' return (cmd, points), options elif node.tag in _ns('line'): points = [node.get('x1'), node.get('y1'), node.get('x2'), node.get('y2')] points = map(inkex.unittouu, points) # check for zero lenght line if not ((points[0] == points[2]) and (points[1] == points[3])): return ('polyline', points), options if node.tag == _ns('circle'): # ugly code... center = map(inkex.unittouu, [node.get('cx', '0'), node.get('cy', '0')]) r = inkex.unittouu(node.get('r', '0')) if r > 0.0: return ('circle', self.transform(center) + self.transform([r])), options elif node.tag == _ns('ellipse'): center = map(inkex.unittouu, [node.get('cx', '0'), node.get('cy', '0')]) rx = inkex.unittouu(node.get('rx', '0')) ry = inkex.unittouu(node.get('ry', '0')) if rx > 0.0 and ry > 0.0: return ('ellipse', self.transform(center) + self.transform([rx]) + self.transform([ry])), options else: return None, options return None, options
def effect(self): for id, node in self.selected.iteritems(): if node.tag == inkex.addNS('path', 'svg'): self.group = inkex.etree.SubElement(node.getparent(), inkex.addNS('g', 'svg')) self.dotGroup = inkex.etree.SubElement(self.group, inkex.addNS('g', 'svg')) self.numGroup = inkex.etree.SubElement(self.group, inkex.addNS('g', 'svg')) try: t = node.get('transform') self.group.set('transform', t) except: pass style = simplestyle.formatStyle({ 'stroke': 'none', 'fill': '#000' }) a = [] p = simplepath.parsePath(node.get('d')) self.separateLastAndFirst(p) num = 1 for cmd, params in p: if cmd != 'Z' and cmd != 'z': dot_att = { 'style': style, 'r': str(inkex.unittouu(self.options.dotsize) / 2), 'cx': str(params[-2]), 'cy': str(params[-1]) } inkex.etree.SubElement(self.dotGroup, inkex.addNS('circle', 'svg'), dot_att) self.addText( self.numGroup, params[-2] + (inkex.unittouu(self.options.dotsize) / 2), params[-1] - (inkex.unittouu(self.options.dotsize) / 2), num) num += 1 node.getparent().remove(node)
def separateLastAndFirst(self, p): # Separate the last and first dot if they are togheter lastDot = -1 if p[lastDot][1] == []: lastDot = -2 if round(p[lastDot][1][-2]) == round(p[0][1][-2]) and \ round(p[lastDot][1][-1]) == round(p[0][1][-1]): x1 = p[lastDot][1][-2] y1 = p[lastDot][1][-1] x2 = p[lastDot-1][1][-2] y2 = p[lastDot-1][1][-1] dx = abs( max(x1,x2) - min(x1,x2) ) dy = abs( max(y1,y2) - min(y1,y2) ) dist = math.sqrt( dx**2 + dy**2 ) x = dx/dist y = dy/dist if x1 > x2: x *= -1 if y1 > y2: y *= -1 p[lastDot][1][-2] += x * inkex.unittouu(self.options.dotsize) p[lastDot][1][-1] += y * inkex.unittouu(self.options.dotsize)
def __unittouu(self, param): """Wrap inkex.unittouu for compatibility. Required arguments: param -- string, to parse """ try: return inkex.unittouu(param) except AttributeError: return self.unittouu(param)
def effect(self): args = ["./qqwing", "--one-line", "--generate", str(self.options.rows * self.options.cols)] if self.options.difficulty != 'mixed': args.extend(["--difficulty", self.options.difficulty]) data = subprocess.Popen(args, stdout=subprocess.PIPE).communicate()[0].splitlines() parent = self.document.getroot() self.doc_w = inkex.unittouu(parent.get('width')) self.doc_h = inkex.unittouu(parent.get('height')) self.size = inkex.unittouu(self.options.puzzle_size) self.gap = inkex.unittouu(self.options.puzzle_gap) self.shift = self.size + self.gap self.left = (self.doc_w - (self.options.cols * self.shift - self.gap))/2 self.top = (self.doc_h - (self.options.rows * self.shift - self.gap))/2 self.sudoku_g = inkex.etree.SubElement(parent, 'g', {'id':'sudoku'}) for row in range(0, self.options.rows): for col in range(0, self.options.cols): g = inkex.etree.SubElement(self.sudoku_g, 'g', {'id':'puzzle_'+str(col)+str(row)}) self.draw_grid(g, col*self.shift, row*self.shift) self.fill_puzzle(g, col*self.shift, row*self.shift, data[col+row*self.options.cols])
def separateLastAndFirst(self, p): # Separate the last and first dot if they are togheter lastDot = -1 if p[lastDot][1] == []: lastDot = -2 if round(p[lastDot][1][-2]) == round(p[0][1][-2]) and \ round(p[lastDot][1][-1]) == round(p[0][1][-1]): x1 = p[lastDot][1][-2] y1 = p[lastDot][1][-1] x2 = p[lastDot - 1][1][-2] y2 = p[lastDot - 1][1][-1] dx = abs(max(x1, x2) - min(x1, x2)) dy = abs(max(y1, y2) - min(y1, y2)) dist = math.sqrt(dx**2 + dy**2) x = dx / dist y = dy / dist if x1 > x2: x *= -1 if y1 > y2: y *= -1 p[lastDot][1][-2] += x * inkex.unittouu(self.options.dotsize) p[lastDot][1][-1] += y * inkex.unittouu(self.options.dotsize)
def effect(self): svgRoot = self.document.getroot() tmpWidth = svgRoot.get("width") if tmpWidth == None: width = inkex.unittouu("800") else: width = inkex.unittouu(tmpWidth) tmpHeight = svgRoot.get("height") if tmpHeight == None: height = inkex.unittouu("600") else: height = inkex.unittouu(tmpHeight) self.core.canvas = Canvas(width, height) self.core.createTree(svgRoot) for drawable in self.core.root.getDrawable(): drawable.runDraw()
def effect(self): self.hpgl = ['IN;SP%d;' % self.options.pen] x0 = self.options.xOrigin y0 = self.options.yOrigin scale = float(self.options.resolution) / 90 self.options.flat *= scale mirror = 1.0 if self.options.mirror: mirror = -1.0 if inkex.unittouu(self.document.getroot().xpath( '@height', namespaces=inkex.NSS)[0]): y0 -= float( inkex.unittouu(self.document.getroot().xpath( '@height', namespaces=inkex.NSS)[0])) self.groupmat = [[[scale, 0.0, -x0 * scale], [0.0, mirror * scale, -y0 * scale]]] doc = self.document.getroot() self.process_group(doc) self.hpgl.append('PU;')
def mm2u(self, arr): ''' Translate a value or an array of values form 'mm' to document unit ''' if type(arr) is list: return [self.mm2u(coord) for coord in arr] else: try: # for 0.48 and 0.91 compatibility return inkex.unittouu("%smm" % arr) except AttributeError: return self.unittouu("%smm" % arr)
def effect(self): svg = self.document.getroot() self.document_offset = unittouu( svg.attrib['height'] ) % 1 # although SVG units are absolute, the elements are positioned relative to the top of the page, rather than zero for id, elem in self.selected.iteritems(): try: self.pixel_snap(elem) except TransformError, e: print >> sys.stderr, e
def calculate_size_and_positions(self): self.doc_width = inkex.unittouu(self.document.getroot().get('width')) self.doc_height = inkex.unittouu(self.document.getroot().get('height')) self.black_key_width = inkex.unittouu('3.6 mm') self.white_key_width = inkex.unittouu('6 mm') self.black_key_height = inkex.unittouu('18 mm') self.white_key_height = inkex.unittouu('30 mm')
def snap_rect(self, elem, parent_transform=None): transform = self.transform(elem, parent_transform=parent_transform) if transform[0][1] or transform[1][ 0]: # if we've got any skew/rotation, get outta here raise TransformError( "Selection contains transformations with skew/rotation") offset = self.elem_offset(elem, parent_transform) % 1 width = unittouu(elem.attrib['width']) height = unittouu(elem.attrib['height']) x = unittouu(elem.attrib['x']) y = unittouu(elem.attrib['y']) width, height = transform_dimensions(transform, width, height) x, y = transform_point(transform, [x, y]) # Snap to the nearest pixel height = round(height) width = round(width) x = round( x - offset ) + offset # If there's a stroke of non-even width, it's shifted by half a pixel y = round(y - offset) + offset width, height = transform_dimensions(transform, width, height, inverse=True) x, y = transform_point(transform, [x, y], inverse=True) y += self.document_offset / transform[1][1] # Position the elem at the newly calculate values elem.attrib['width'] = str(width) elem.attrib['height'] = str(height) elem.attrib['x'] = str(x) elem.attrib['y'] = str(y)