def effect(self): zoom = self.unittouu(str(self.options.zoom) + 'px') if self.options.randomize: imagelist = generate_random_string(self.options.text, zoom) else: tokens = tokenize(self.options.text) imagelist = randomize_input_string(tokens, zoom) image = layoutstring(imagelist, zoom) if image: s = {'stroke': 'none', 'fill': '#000000'} new = inkex.etree.Element(inkex.addNS('path', 'svg')) new.set('style', simplestyle.formatStyle(s)) new.set('d', simplepath.formatPath(image)) self.current_layer.append(new) # compensate preserved transforms of parent layer if self.current_layer.getparent() is not None: mat = simpletransform.composeParents( self.current_layer, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]) simpletransform.applyTransformToNode( simpletransform.invertTransform(mat), new)
def get_correction_transform(svg): transform = get_viewbox_transform(svg) # we need to correct for the viewbox transform = simpletransform.invertTransform(transform) transform = simpletransform.formatTransform(transform) return transform
def get_origin(svg): # The user can specify the embroidery origin by defining two guides # named "embroidery origin" that intersect. namedview = svg.find(inkex.addNS('namedview', 'sodipodi')) all_guides = namedview.findall(inkex.addNS('guide', 'sodipodi')) label_attribute = inkex.addNS('label', 'inkscape') guides = [ guide for guide in all_guides if guide.get(label_attribute, "").startswith("embroidery origin") ] # document size used below doc_size = list(get_doc_size(svg)) # convert the size from viewbox-relative to real-world pixels viewbox_transform = get_viewbox_transform(svg) simpletransform.applyTransformToPoint( simpletransform.invertTransform(viewbox_transform), doc_size) default = [doc_size[0] / 2.0, doc_size[1] / 2.0] simpletransform.applyTransformToPoint(viewbox_transform, default) default = Point(*default) if len(guides) < 2: return default # Find out where the guides intersect. Only pay attention to the first two. guides = guides[:2] lines = [] for guide in guides: # inkscape's Y axis is reversed from SVG's, and the guide is in inkscape coordinates position = Point(*_string_to_floats(guide.get('position'))) position.y = doc_size[1] - position.y # This one baffles me. I think inkscape might have gotten the order of # their vector wrong? parts = _string_to_floats(guide.get('orientation')) direction = Point(parts[1], parts[0]) # We have a theoretically infinite line defined by a point on the line # and a vector direction. Shapely can only deal in concrete line # segments, so we'll pick points really far in either direction on the # line and call it good enough. lines.append( shgeo.LineString((position + 100000 * direction, position - 100000 * direction))) intersection = lines[0].intersection(lines[1]) if isinstance(intersection, shgeo.Point): origin = [intersection.x, intersection.y] simpletransform.applyTransformToPoint(viewbox_transform, origin) return Point(*origin) else: # Either the two guides are the same line, or they're parallel. return default
def process_path(self, ipath, mat_x, mat_y, term1): mat = simpletransform.composeParents( ipath, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]) path_string = ipath.get('d') svg_path = simplepath.parsePath(path_string) paths = [] # for path in svg_path: # inkex.debug("svg_path: " + str(svg_path)) for path in svg_path: if path[0] == 'M' or path[0] == 'L': paths.append([path[0], [path[1]]]) elif path[0] == 'C' or path[0] == 'Q': pts = [] if path[0] == 'C': num = 3 else: num = 2 for i in range(0, num): pt = [path[1][2 * i], path[1][2 * i + 1]] pts.append(pt) paths.append([path[0], pts]) elif path[0] == 'Z': paths.append(['Z', []]) # inkex.debug("paths: " + str(paths) + "\n\n") mat = simpletransform.invertTransform(mat) # simpletransform.applyTransformToPath(mat, p) for path in paths: for pt in path[1]: simpletransform.applyTransformToPoint(mat, pt) # do transformation for path in paths: for pt in path[1]: self.project_point(pt, mat_x, mat_y, term1) # back to original form res_paths = [] for path in paths: if path[0] == 'C' or path[0] == 'Q': flat_pts = [] for pt in path[1]: flat_pts.append(pt[0]) flat_pts.append(pt[1]) res_paths.append([path[0], flat_pts]) elif path[0] == 'M' or path[0] == 'L': res_paths.append([path[0], path[1][0]]) elif path[0] == 'Z': res_paths.append(path) # inkex.debug("res_paths: " + str(res_paths)) res_svg_paths = simplepath.formatPath(res_paths) # inkex.debug("res_svg_paths: " + str(res_svg_paths)) ipath.set('d', res_svg_paths)
def process_path(self,path): mat = simpletransform.composeParents(path, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]) d = path.get('d') p = cubicsuperpath.parsePath(d) simpletransform.applyTransformToPath(mat, p) for subs in p: for csp in subs: csp[0] = self.trafopoint(csp[0]) csp[1] = self.trafopoint(csp[1]) csp[2] = self.trafopoint(csp[2]) mat = simpletransform.invertTransform(mat) simpletransform.applyTransformToPath(mat, p) path.set('d',cubicsuperpath.formatPath(p))
def draw(self, transform): """ Draws the working area :param transform: the transform to apply to points :type transform: a 2x3 matrix """ # Using a viewBox so that we can express all measures relative to it. We compute the # view box height when the width is 100 to keep the aspect ratio. We also compute the stroke # width so that it is 0.5 millimiters self.factor = 100.0 / self.dim_x self.view_box_height = self.factor * self.dim_y line_width = self.factor * 0.5 # inverting transformation, we know absolute coordinates inv_transform = simpletransform.invertTransform(transform) # tranforming the position of the box box_origin = [0, self.page_height - self.dim_y] simpletransform.applyTransformToPoint(inv_transform, box_origin) # transforming lengths (ignoring translation) box_dims = [self.dim_x, self.dim_y] length_inv_transform = [[ inv_transform[0][0], inv_transform[0][1], 0.0 ], [inv_transform[1][0], inv_transform[1][1], 0.0]] simpletransform.applyTransformToPoint(length_inv_transform, box_dims) self.area = inkex.etree.Element( "svg", { 'id': self.working_area_id, 'x': str(self.to_uu(box_origin[0])), 'y': str(self.to_uu(box_origin[1])), 'width': str(self.to_uu(box_dims[0])), 'height': str(self.to_uu(box_dims[1])), 'viewBox': "0 0 100 " + str(self.view_box_height), 'preserveAspectRatio': "none", 'style': "fill:none;stroke-width:{};stroke:rgb(0,0,0)".format( line_width) }) self.draw_rectangle() self.draw_cross() self.draw_text()
def get_correction_transform(self, node): # if we want to place our new nodes in the same group as this node, # then we'll need to factor in the effects of any transforms set on # the parents of this node. # we can ignore the transform on the node itself since it won't apply # to the objects we add transform = get_node_transform(node.getparent()) # now invert it, so that we can position our objects in absolute # coordinates transform = simpletransform.invertTransform(transform) return simpletransform.formatTransform(transform)
def get_origin(svg): origin_command = global_command(svg, "origin") if origin_command: return origin_command.point else: # default: center of the canvas doc_size = list(get_doc_size(svg)) # convert the size from viewbox-relative to real-world pixels viewbox_transform = get_viewbox_transform(svg) simpletransform.applyTransformToPoint(simpletransform.invertTransform(viewbox_transform), doc_size) default = [doc_size[0] / 2.0, doc_size[1] / 2.0] simpletransform.applyTransformToPoint(viewbox_transform, default) default = Point(*default) return default
def get_correction_transform(node, child=False): """Get a transform to apply to new siblings or children of this SVG node""" # if we want to place our new nodes in the same group/layer as this node, # then we'll need to factor in the effects of any transforms set on # the parents of this node. if child: transform = get_node_transform(node) else: # we can ignore the transform on the node itself since it won't apply # to the objects we add transform = get_node_transform(node.getparent()) # now invert it, so that we can position our objects in absolute # coordinates transform = simpletransform.invertTransform(transform) return simpletransform.formatTransform(transform)
def _parse(self): self.label = self.node.get(INKSCAPE_LABEL, "") doc_size = list(get_doc_size(self.svg)) # convert the size from viewbox-relative to real-world pixels viewbox_transform = get_viewbox_transform(self.svg) simpletransform.applyTransformToPoint( simpletransform.invertTransform(viewbox_transform), doc_size) self.position = Point(*string_to_floats(self.node.get('position'))) # inkscape's Y axis is reversed from SVG's, and the guide is in inkscape coordinates self.position.y = doc_size[1] - self.position.y # This one baffles me. I think inkscape might have gotten the order of # their vector wrong? parts = string_to_floats(self.node.get('orientation')) self.direction = Point(parts[1], parts[0])
def test_simpletransform(self): """Test simpletransform API""" import simpletransform self.assertEqual(simpletransform.parseTransform('scale(10)'), [[10, 0, 0], [0, 10, 0]]) self.assertEqual(simpletransform.parseTransform('translate(2,3)'), [[1, 0, 2], [0, 1, 3]]) self.assertEqual( simpletransform.parseTransform('translate(2,3) rotate(90)'), [approx([0, -1, 2]), approx([1, 0, 3])]) m = simpletransform.formatTransform([[0, -1, 2], [1, 0, 3]]) self.assertEqual(re.sub(r',', ' ', re.sub(r'\.0*\b', '', m)), 'matrix(0 1 -1 0 2 3)') self.assertEqual( simpletransform.invertTransform([[1, 0, 2], [0, 1, 3]]), [[1, 0, -2], [0, 1, -3]]) self.assertEqual( simpletransform.composeTransform([[1, 0, 2], [0, 1, 3]], [[0, -1, 0], [1, 0, 0]]), [[0, -1, 2], [1, 0, 3]]) pt = [4, 5] self.assertEqual( simpletransform.applyTransformToPoint([[0, -1, 2], [1, 0, 3]], pt), None) self.assertEqual(pt, [-3, 7]) self.assertEqual(simpletransform.boxunion([3, 5, 2, 4], [4, 6, 1, 3]), (3, 6, 1, 4)) self.assertEqual(simpletransform.cubicExtrema(1, 2, 3, 4), (1, 4)) # TODO need cubic superpath self.assertTrue(simpletransform.applyTransformToPath) self.assertTrue(simpletransform.roughBBox) self.assertTrue(simpletransform.refinedBBox) # TODO need node self.assertTrue(simpletransform.fuseTransform) self.assertTrue(simpletransform.composeParents) self.assertTrue(simpletransform.applyTransformToNode) self.assertTrue(simpletransform.computeBBox) self.assertTrue(simpletransform.computePointInNode)
def emit_inkscape(parent, stitches): transform = get_viewbox_transform(parent.getroottree().getroot()) # we need to correct for the viewbox transform = simpletransform.invertTransform(transform) transform = simpletransform.formatTransform(transform) for color, polyline in stitches_to_polylines(stitches): # dbg.write('polyline: %s %s\n' % (color, repr(polyline))) inkex.etree.SubElement( parent, inkex.addNS('polyline', 'svg'), { 'style': simplestyle.formatStyle( { 'stroke': color if color is not None else '#000000', 'stroke-width': "0.4", 'fill': 'none' }), 'points': " ".join(",".join(str(coord) for coord in point) for point in polyline), 'transform': transform })
def effect(self): zoom = self.unittouu( str(self.options.zoom) + 'px') if self.options.randomize: imagelist = generate_random_string(self.options.text, zoom) else: tokens = tokenize(self.options.text) imagelist = randomize_input_string(tokens, zoom) image = layoutstring( imagelist, zoom ) if image: s = { 'stroke': 'none', 'fill': '#000000' } new = inkex.etree.Element(inkex.addNS('path','svg')) new.set('style', simplestyle.formatStyle(s)) new.set('d', simplepath.formatPath(image)) self.current_layer.append(new) # compensate preserved transforms of parent layer if self.current_layer.getparent() is not None: mat = simpletransform.composeParents(self.current_layer, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]) simpletransform.applyTransformToNode(simpletransform.invertTransform(mat), new)
def effect(self): docW = self.unittouu(self.document.getroot().get('width')) docH = self.unittouu(self.document.getroot().get('height')) boxW = self.unittouu(str(self.options.width) + self.options.unit) boxH = self.unittouu(str(self.options.height) + self.options.unit) boxD = self.unittouu(str(self.options.depth) + self.options.unit) tabProp = self.options.tabProportion tabH = boxD * tabProp box_id = self.uniqueId('box') self.box = g = inkex.etree.SubElement(self.current_layer, 'g', {'id': box_id}) line_style = simplestyle.formatStyle({ 'stroke': '#000000', 'fill': 'none', 'stroke-width': str(self.unittouu('1px')) }) #self.createGuide( 0, docH, 0 ); # Inner Close Tab line_path = [['M', [boxW - (tabH * 0.7), 0]], [ 'C', [ boxW - (tabH * 0.25), 0, boxW, tabH * 0.3, boxW, tabH * 0.9 ] ], ['L', [boxW, tabH]], ['L', [0, tabH]], ['L', [0, tabH * 0.9]], ['C', [0, tabH * 0.3, tabH * 0.25, 0, tabH * 0.7, 0]], ['Z', []]] line_atts = { 'style': line_style, 'id': box_id + '-inner-close-tab', 'd': formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts) lower_pos = boxD + tabH left_pos = 0 #self.createGuide( 0, docH-tabH, 0 ); # Upper Close Tab line_path = [['M', [left_pos, tabH]], ['L', [left_pos + boxW, tabH]], ['L', [left_pos + boxW, lower_pos]], ['L', [left_pos + 0, lower_pos]], ['Z', []]] line_atts = { 'style': line_style, 'id': box_id + '-upper-close-tab', 'd': formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts) left_pos += boxW # Upper Right Tab sideTabH = lower_pos - (boxW / 2) if sideTabH < tabH: sideTabH = tabH line_path = [['M', [left_pos, sideTabH]], ['L', [left_pos + (boxD * 0.8), sideTabH]], [ 'L', [left_pos + boxD, ((lower_pos * 3) - sideTabH) / 3] ], ['L', [left_pos + boxD, lower_pos]], ['L', [left_pos + 0, lower_pos]], ['Z', []]] line_atts = { 'style': line_style, 'id': box_id + '-upper-right-tab', 'd': formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts) left_pos += boxW + boxD # Upper Left Tab line_path = [['M', [left_pos + boxD, sideTabH]], ['L', [left_pos + (boxD * 0.2), sideTabH]], ['L', [left_pos, ((lower_pos * 3) - sideTabH) / 3]], ['L', [left_pos, lower_pos]], ['L', [left_pos + boxD, lower_pos]], ['Z', []]] line_atts = { 'style': line_style, 'id': box_id + '-upper-left-tab', 'd': formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts) left_pos = 0 #self.createGuide( 0, docH-tabH-boxD, 0 ); # Right Tab line_path = [ ['M', [left_pos, lower_pos]], ['L', [left_pos - (boxD / 2), lower_pos + (boxD / 4)]], ['L', [left_pos - (boxD / 2), lower_pos + boxH - (boxD / 4)]], ['L', [left_pos, lower_pos + boxH]], ['Z', []] ] line_atts = { 'style': line_style, 'id': box_id + '-left-tab', 'd': formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts) # Front line_path = [['M', [left_pos, lower_pos]], ['L', [left_pos + boxW, lower_pos]], ['L', [left_pos + boxW, lower_pos + boxH]], ['L', [left_pos, lower_pos + boxH]], ['Z', []]] line_atts = { 'style': line_style, 'id': box_id + '-front', 'd': formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts) left_pos += boxW # Right line_path = [['M', [left_pos, lower_pos]], ['L', [left_pos + boxD, lower_pos]], ['L', [left_pos + boxD, lower_pos + boxH]], ['L', [left_pos, lower_pos + boxH]], ['Z', []]] line_atts = { 'style': line_style, 'id': box_id + '-right', 'd': formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts) left_pos += boxD # Back line_path = [['M', [left_pos, lower_pos]], ['L', [left_pos + boxW, lower_pos]], ['L', [left_pos + boxW, lower_pos + boxH]], ['L', [left_pos, lower_pos + boxH]], ['Z', []]] line_atts = { 'style': line_style, 'id': box_id + '-back', 'd': formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts) left_pos += boxW # Left line_path = [['M', [left_pos, lower_pos]], ['L', [left_pos + boxD, lower_pos]], ['L', [left_pos + boxD, lower_pos + boxH]], ['L', [left_pos, lower_pos + boxH]], ['Z', []]] line_atts = { 'style': line_style, 'id': box_id + '-left', 'd': formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts) lower_pos += boxH left_pos = 0 bTab = lower_pos + boxD if bTab > boxW / 2.5: bTab = boxW / 2.5 # Bottom Front Tab line_path = [['M', [left_pos, lower_pos]], ['L', [left_pos, lower_pos + (boxD / 2)]], ['L', [left_pos + boxW, lower_pos + (boxD / 2)]], ['L', [left_pos + boxW, lower_pos]], ['Z', []]] line_atts = { 'style': line_style, 'id': box_id + '-bottom-front-tab', 'd': formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts) left_pos += boxW # Bottom Right Tab line_path = [['M', [left_pos, lower_pos]], ['L', [left_pos, lower_pos + bTab]], ['L', [left_pos + boxD, lower_pos + bTab]], ['L', [left_pos + boxD, lower_pos]], ['Z', []]] line_atts = { 'style': line_style, 'id': box_id + '-bottom-right-tab', 'd': formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts) left_pos += boxD # Bottom Back Tab line_path = [['M', [left_pos, lower_pos]], ['L', [left_pos, lower_pos + (boxD / 2)]], ['L', [left_pos + boxW, lower_pos + (boxD / 2)]], ['L', [left_pos + boxW, lower_pos]], ['Z', []]] line_atts = { 'style': line_style, 'id': box_id + '-bottom-back-tab', 'd': formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts) left_pos += boxW # Bottom Left Tab line_path = [['M', [left_pos, lower_pos]], ['L', [left_pos, lower_pos + bTab]], ['L', [left_pos + boxD, lower_pos + bTab]], ['L', [left_pos + boxD, lower_pos]], ['Z', []]] line_atts = { 'style': line_style, 'id': box_id + '-bottom-left-tab', 'd': formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts) left_pos += boxD lower_pos += bTab g.set( 'transform', 'translate(%f,%f)' % ((docW - left_pos) / 2, (docH - lower_pos) / 2)) # compensate preserved transforms of parent layer if self.current_layer.getparent() is not None: mat = simpletransform.composeParents( self.current_layer, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]) simpletransform.applyTransformToNode( simpletransform.invertTransform(mat), g)
def effect(self): #{{{ Check that elements have been selected if len(self.options.ids) == 0: inkex.errormsg(_("Please select objects!")) return #}}} #{{{ Drawing styles linestyle = { 'stroke' : '#000000', 'stroke-width' : str(self.unittouu('1px')), 'fill' : 'none' } facestyle = { 'stroke' : '#ff0000', 'stroke-width' : str(self.unittouu('1px')), 'fill' : 'none' } #}}} #{{{ Handle the transformation of the current group parentGroup = self.getParentNode(self.selected[self.options.ids[0]]) trans = self.getGlobalTransform(parentGroup) invtrans = None if trans: invtrans = simpletransform.invertTransform(trans) #}}} #{{{ Recovery of the selected objects pts = [] nodes = [] seeds = [] for id in self.options.ids: node = self.selected[id] nodes.append(node) bbox = simpletransform.computeBBox([node]) if bbox: cx = 0.5*(bbox[0]+bbox[1]) cy = 0.5*(bbox[2]+bbox[3]) pt = [cx,cy] if trans: simpletransform.applyTransformToPoint(trans,pt) pts.append(Point(pt[0],pt[1])) seeds.append(Point(cx,cy)) #}}} #{{{ Creation of groups to store the result if self.options.diagramType != 'Delaunay': # Voronoi groupVoronoi = inkex.etree.SubElement(parentGroup,inkex.addNS('g','svg')) groupVoronoi.set(inkex.addNS('label', 'inkscape'), 'Voronoi') if invtrans: simpletransform.applyTransformToNode(invtrans,groupVoronoi) if self.options.diagramType != 'Voronoi': # Delaunay groupDelaunay = inkex.etree.SubElement(parentGroup,inkex.addNS('g','svg')) groupDelaunay.set(inkex.addNS('label', 'inkscape'), 'Delaunay') #}}} #{{{ Clipping box handling if self.options.diagramType != 'Delaunay': #Clipping bounding box creation gBbox = simpletransform.computeBBox(nodes) #Clipbox is the box to which the Voronoi diagram is restricted clipBox = () if self.options.clipBox == 'Page': svg = self.document.getroot() w = self.unittouu(svg.get('width')) h = self.unittouu(svg.get('height')) clipBox = (0,w,0,h) else: clipBox = (2*gBbox[0]-gBbox[1], 2*gBbox[1]-gBbox[0], 2*gBbox[2]-gBbox[3], 2*gBbox[3]-gBbox[2]) #Safebox adds points so that no Voronoi edge in clipBox is infinite safeBox = (2*clipBox[0]-clipBox[1], 2*clipBox[1]-clipBox[0], 2*clipBox[2]-clipBox[3], 2*clipBox[3]-clipBox[2]) pts.append(Point(safeBox[0],safeBox[2])) pts.append(Point(safeBox[1],safeBox[2])) pts.append(Point(safeBox[1],safeBox[3])) pts.append(Point(safeBox[0],safeBox[3])) if self.options.showClipBox: #Add the clip box to the drawing rect = inkex.etree.SubElement(groupVoronoi,inkex.addNS('rect','svg')) rect.set('x',str(clipBox[0])) rect.set('y',str(clipBox[2])) rect.set('width',str(clipBox[1]-clipBox[0])) rect.set('height',str(clipBox[3]-clipBox[2])) rect.set('style',simplestyle.formatStyle(linestyle)) #}}} #{{{ Voronoi diagram generation if self.options.diagramType != 'Delaunay': vertices,lines,edges = voronoi.computeVoronoiDiagram(pts) for edge in edges: line = edge[0] vindex1 = edge[1] vindex2 = edge[2] if (vindex1 <0) or (vindex2 <0): continue # infinite lines have no need to be handled in the clipped box else: segment = self.clipEdge(vertices,lines,edge,clipBox) #segment = [vertices[vindex1],vertices[vindex2]] # deactivate clipping if len(segment)>1: v1 = segment[0] v2 = segment[1] cmds = [['M',[v1[0],v1[1]]],['L',[v2[0],v2[1]]]] path = inkex.etree.Element(inkex.addNS('path','svg')) path.set('d',simplepath.formatPath(cmds)) path.set('style',simplestyle.formatStyle(linestyle)) groupVoronoi.append(path) if self.options.diagramType != 'Voronoi': triangles = voronoi.computeDelaunayTriangulation(seeds) for triangle in triangles: p1 = seeds[triangle[0]] p2 = seeds[triangle[1]] p3 = seeds[triangle[2]] cmds = [['M',[p1.x,p1.y]], ['L',[p2.x,p2.y]], ['L',[p3.x,p3.y]], ['Z',[]]] path = inkex.etree.Element(inkex.addNS('path','svg')) path.set('d',simplepath.formatPath(cmds)) path.set('style',simplestyle.formatStyle(facestyle)) groupDelaunay.append(path)
def effect(self): docW = self.unittouu(self.document.getroot().get('width')) docH = self.unittouu(self.document.getroot().get('height')) boxW = self.unittouu( str(self.options.width) + self.options.unit ) boxH = self.unittouu( str(self.options.height) + self.options.unit ) boxD = self.unittouu( str(self.options.depth) + self.options.unit ) tabProp = self.options.tabProportion tabH = boxD * tabProp box_id = self.uniqueId('box') self.box = g = inkex.etree.SubElement(self.current_layer, 'g', {'id':box_id}) line_style = simplestyle.formatStyle({ 'stroke': '#000000', 'fill': 'none', 'stroke-width': str(self.unittouu('1px')) }) #self.createGuide( 0, docH, 0 ); # Inner Close Tab line_path = [ [ 'M', [ boxW-(tabH*0.7), 0 ] ], [ 'C', [ boxW-(tabH*0.25), 0, boxW, tabH*0.3, boxW, tabH*0.9 ] ], [ 'L', [ boxW, tabH ] ], [ 'L', [ 0, tabH ] ], [ 'L', [ 0, tabH*0.9 ] ], [ 'C', [ 0, tabH*0.3, tabH*0.25, 0, tabH*0.7, 0 ] ], [ 'Z', [] ] ] line_atts = { 'style':line_style, 'id':box_id+'-inner-close-tab', 'd':formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts ) lower_pos = boxD+tabH left_pos = 0 #self.createGuide( 0, docH-tabH, 0 ); # Upper Close Tab line_path = [ [ 'M', [ left_pos, tabH ] ], [ 'L', [ left_pos + boxW, tabH ] ], [ 'L', [ left_pos + boxW, lower_pos ] ], [ 'L', [ left_pos + 0, lower_pos ] ], [ 'Z', [] ] ] line_atts = { 'style':line_style, 'id':box_id+'-upper-close-tab', 'd':formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts ) left_pos += boxW # Upper Right Tab sideTabH = lower_pos - (boxW/2) if sideTabH < tabH: sideTabH = tabH line_path = [ [ 'M', [ left_pos, sideTabH ] ], [ 'L', [ left_pos + (boxD*0.8), sideTabH ] ], [ 'L', [ left_pos + boxD, ((lower_pos*3)-sideTabH)/3 ] ], [ 'L', [ left_pos + boxD, lower_pos ] ], [ 'L', [ left_pos + 0, lower_pos ] ], [ 'Z', [] ] ] line_atts = { 'style':line_style, 'id':box_id+'-upper-right-tab', 'd':formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts ) left_pos += boxW + boxD # Upper Left Tab line_path = [ [ 'M', [ left_pos + boxD, sideTabH ] ], [ 'L', [ left_pos + (boxD*0.2), sideTabH ] ], [ 'L', [ left_pos, ((lower_pos*3)-sideTabH)/3 ] ], [ 'L', [ left_pos, lower_pos ] ], [ 'L', [ left_pos + boxD, lower_pos ] ], [ 'Z', [] ] ] line_atts = { 'style':line_style, 'id':box_id+'-upper-left-tab', 'd':formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts ) left_pos = 0 #self.createGuide( 0, docH-tabH-boxD, 0 ); # Right Tab line_path = [ [ 'M', [ left_pos, lower_pos ] ], [ 'L', [ left_pos - (boxD/2), lower_pos + (boxD/4) ] ], [ 'L', [ left_pos - (boxD/2), lower_pos + boxH - (boxD/4) ] ], [ 'L', [ left_pos, lower_pos + boxH ] ], [ 'Z', [] ] ] line_atts = { 'style':line_style, 'id':box_id+'-left-tab', 'd':formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts ) # Front line_path = [ [ 'M', [ left_pos, lower_pos ] ], [ 'L', [ left_pos + boxW, lower_pos ] ], [ 'L', [ left_pos + boxW, lower_pos + boxH ] ], [ 'L', [ left_pos, lower_pos + boxH ] ], [ 'Z', [] ] ] line_atts = { 'style':line_style, 'id':box_id+'-front', 'd':formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts ) left_pos += boxW # Right line_path = [ [ 'M', [ left_pos, lower_pos ] ], [ 'L', [ left_pos + boxD, lower_pos ] ], [ 'L', [ left_pos + boxD, lower_pos + boxH ] ], [ 'L', [ left_pos, lower_pos + boxH ] ], [ 'Z', [] ] ] line_atts = { 'style':line_style, 'id':box_id+'-right', 'd':formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts ) left_pos += boxD # Back line_path = [ [ 'M', [ left_pos, lower_pos ] ], [ 'L', [ left_pos + boxW, lower_pos ] ], [ 'L', [ left_pos + boxW, lower_pos + boxH ] ], [ 'L', [ left_pos, lower_pos + boxH ] ], [ 'Z', [] ] ] line_atts = { 'style':line_style, 'id':box_id+'-back', 'd':formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts ) left_pos += boxW # Left line_path = [ [ 'M', [ left_pos, lower_pos ] ], [ 'L', [ left_pos + boxD, lower_pos ] ], [ 'L', [ left_pos + boxD, lower_pos + boxH ] ], [ 'L', [ left_pos, lower_pos + boxH ] ], [ 'Z', [] ] ] line_atts = { 'style':line_style, 'id':box_id+'-left', 'd':formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts ) lower_pos += boxH left_pos = 0 bTab = lower_pos + boxD if bTab > boxW / 2.5: bTab = boxW / 2.5 # Bottom Front Tab line_path = [ [ 'M', [ left_pos, lower_pos ] ], [ 'L', [ left_pos, lower_pos + (boxD/2) ] ], [ 'L', [ left_pos + boxW, lower_pos + (boxD/2) ] ], [ 'L', [ left_pos + boxW, lower_pos ] ], [ 'Z', [] ] ] line_atts = { 'style':line_style, 'id':box_id+'-bottom-front-tab', 'd':formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts ) left_pos += boxW # Bottom Right Tab line_path = [ [ 'M', [ left_pos, lower_pos ] ], [ 'L', [ left_pos, lower_pos + bTab ] ], [ 'L', [ left_pos + boxD, lower_pos + bTab ] ], [ 'L', [ left_pos + boxD, lower_pos ] ], [ 'Z', [] ] ] line_atts = { 'style':line_style, 'id':box_id+'-bottom-right-tab', 'd':formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts ) left_pos += boxD # Bottom Back Tab line_path = [ [ 'M', [ left_pos, lower_pos ] ], [ 'L', [ left_pos, lower_pos + (boxD/2) ] ], [ 'L', [ left_pos + boxW, lower_pos + (boxD/2) ] ], [ 'L', [ left_pos + boxW, lower_pos ] ], [ 'Z', [] ] ] line_atts = { 'style':line_style, 'id':box_id+'-bottom-back-tab', 'd':formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts ) left_pos += boxW # Bottom Left Tab line_path = [ [ 'M', [ left_pos, lower_pos ] ], [ 'L', [ left_pos, lower_pos + bTab ] ], [ 'L', [ left_pos + boxD, lower_pos + bTab ] ], [ 'L', [ left_pos + boxD, lower_pos ] ], [ 'Z', [] ] ] line_atts = { 'style':line_style, 'id':box_id+'-bottom-left-tab', 'd':formatPath(line_path) } inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts ) left_pos += boxD lower_pos += bTab g.set( 'transform', 'translate(%f,%f)' % ( (docW-left_pos)/2, (docH-lower_pos)/2 ) ) # compensate preserved transforms of parent layer if self.current_layer.getparent() is not None: mat = simpletransform.composeParents(self.current_layer, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]) simpletransform.applyTransformToNode(simpletransform.invertTransform(mat), g)