def test_draw_border(self): """ Tests that the border is drawn if requested """ generator = WorkingAreaGenerator(self.to_uu, "wId") generator.set_size(400, 300) root = etree.Element("root") generator.upsert(root) border_index = len(root[0]) # border is added at the end of the list of children border = Border([[(40, 20), (160, 200)]], 0) painter = BorderPainter(border) painter.paint(generator) self.assertEqual(root[0][border_index].tag, "rect") self.assertEqual(root[0][border_index].get("x"), "10.0") self.assertEqual(root[0][border_index].get("y"), "5.0") self.assertEqual(root[0][border_index].get("width"), "30.0") self.assertEqual(root[0][border_index].get("height"), "45.0") self.assertEqual(root[0][border_index].get("style"), ("stroke-width:0.0625;" "stroke-miterlimit:4;" "stroke-dasharray:0.25,0.25;" "stroke-dashoffset:0;" "fill:none"))
def add_layer(self, name="Debug"): layer = etree.Element( "g", { INKSCAPE_GROUPMODE: "layer", INKSCAPE_LABEL: name, "style": "display: none" }) self.svg.append(layer) self.current_layer = layer
def test_upsert_adds_working_area_group(self): # pylint: disable=invalid-name """ Tests that the upsert function inserts the working area with the correct id """ generator = WorkingAreaGenerator(self.to_uu, "wId") root = etree.Element("root") generator.upsert(root) self.assertEqual(root[0].tag, "svg") self.assertEqual(root[0].get("id"), "wId")
def test_remove_working_area(self): """ Tests that the working area is not considered among svg elements to use """ root = etree.Element("root") working_area = etree.SubElement(root, "svg", {"id": "wId"}) other_element = etree.SubElement(root, "path") extractor = PathsExtractor([working_area, other_element], to_mm, "wId") self.assertEqual(extractor.get_elements(), [other_element])
def test_add_working_area_style(self): """ Test that the added working area has the correct style """ generator = WorkingAreaGenerator(self.to_uu, "wId") root = etree.Element("root") generator.upsert(root) self.assertEqual(root[0].get("style"), "fill:none;stroke-width:0.25;stroke:rgb(0,0,0)")
def test_path_is_not_added_when_empty(self): # pylint: disable=invalid-name """ Tests that the path is not added when empty """ path = [] painter = ToolPathPainter(path) root_element = etree.Element("root") factor = 100.0 / 300.0 painter.paint(root_element, factor, "255,0,0") self.assertEqual(len(root_element), 0)
def test_path_element_is_added(self): """ Tests that the path element is added """ path = [(10, 10)] painter = ToolPathPainter(path) root_element = etree.Element("root") factor = 100.0 / 300.0 painter.paint(root_element, factor, "255,0,0") self.assertEqual(root_element[0].tag, "path")
def test_get_elements(self): """ Tests that elements passed to the constructor are used """ root = etree.Element("root") element1 = etree.SubElement(root, "path") element2 = etree.SubElement(root, "rect") extractor = PathsExtractor([element1, element2], to_mm, "wId") self.assertEqual(extractor.get_elements(), [element1, element2])
def test_add_working_area_view_box_rectangular_area(self): # pylint: disable=invalid-name """ Tests that the added working area has the correct viewBox in case of rectangular areas """ generator = WorkingAreaGenerator(self.to_uu, "wId") generator.set_size(500, 400) root = etree.Element("root") generator.upsert(root) self.assertEqual(root[0].get("viewBox"), "0 0 100 80.0")
def test_add_working_area_view_box_and_scaling_policy(self): # pylint: disable=invalid-name """ Tests that the added working area has the correct viewBox and scaling policy """ generator = WorkingAreaGenerator(self.to_uu, "wId") generator.set_size(500, 500) root = etree.Element("root") generator.upsert(root) self.assertEqual(root[0].get("viewBox"), "0 0 100 100.0") self.assertEqual(root[0].get("preserveAspectRatio"), "none")
def test_add_working_area_position(self): """ Tests that the added working area has the correct position """ generator = WorkingAreaGenerator(self.to_uu, "wId") generator.set_size(1323, 876) root = etree.Element("root") generator.upsert(root) self.assertEqual(root[0].get("x"), "0.0") self.assertEqual(root[0].get("y"), "0.0")
def test_add_working_area_size(self): """ Tests that the added working area has the correct size """ generator = WorkingAreaGenerator(self.to_uu, "wId") generator.set_size(1323, 876) root = etree.Element("root") generator.upsert(root) self.assertEqual(root[0].get("width"), "2646.0") self.assertEqual(root[0].get("height"), "1752.0")
def test_upsert_does_not_create_duplicated_working_area(self): # pylint: disable=invalid-name """ Tests that upsert does not insert a new working area if it is already present """ generator = WorkingAreaGenerator(self.to_uu, "wId") root = etree.Element("root") etree.SubElement(root, "svg", {"id": "wId"}) generator.upsert(root) self.assertEqual(len(root), 1) self.assertEqual(root[0].tag, "svg") self.assertEqual(root[0].get("id"), "wId")
def test_use_translate_transform(self): """ Tests that the transformation of the element is taken into account when a translation """ generator = WorkingAreaGenerator(self.to_uu, "wId") generator.set_size(400, 200) root = etree.Element("root", {'transform': "translate(10,-30)"}) generator.upsert(root) self.assertEqual(root[0].get("x"), "-20.0") self.assertEqual(root[0].get("y"), "60.0")
def test_path_coordinates(self): """ Tests that the coordinates of the path have the correct value """ path = [(150, 75), (300, 0), (0, 150)] painter = ToolPathPainter(path) root_element = etree.Element("root") factor = 100.0 / 300.0 painter.paint(root_element, factor, "255,0,0") self.assertEqual(root_element[0].get("d"), "M 0.0,0.0 L 50.0,25.0 100.0,0.0 0.0,50.0")
def test_path_color(self): """ Tests that the correct color and width are added to the path """ path = [(10, 10)] painter = ToolPathPainter(path) root_element = etree.Element("root") factor = 100.0 / 300.0 painter.paint(root_element, factor, "255,0,0") self.assertEqual(root_element[0].get("style"), "stroke:rgb(255,0,0);fill:none")
def affect(self, args): embroidery_file = args[0] pattern = pyembroidery.read(embroidery_file) stitch_plan = StitchPlan() color_block = None for raw_stitches, thread in pattern.get_as_colorblocks(): color_block = stitch_plan.new_color_block(thread) for x, y, command in raw_stitches: if command == pyembroidery.STITCH: color_block.add_stitch(x * PIXELS_PER_MM / 10.0, y * PIXELS_PER_MM / 10.0) if len(color_block) > 0: if command == pyembroidery.TRIM: color_block.add_stitch(trim=True) elif command == pyembroidery.STOP: color_block.add_stitch(stop=True) color_block = stitch_plan.new_color_block(thread) stitch_plan.delete_empty_color_blocks() if stitch_plan.last_color_block: if stitch_plan.last_color_block.last_stitch: if stitch_plan.last_color_block.last_stitch.stop: # ending with a STOP command is redundant, so remove it del stitch_plan.last_color_block[-1] extents = stitch_plan.extents svg = etree.Element("svg", nsmap=inkex.NSS, attrib={ "width": str(extents[0] * 2), "height": str(extents[1] * 2), "viewBox": "0 0 %s %s" % (extents[0] * 2, extents[1] * 2), }) render_stitch_plan(svg, stitch_plan) # rename the Stitch Plan layer so that it doesn't get overwritten by Embroider layer = svg.find(".//*[@id='__inkstitch_stitch_plan__']") layer.set(INKSCAPE_LABEL, os.path.basename(embroidery_file.decode("UTF-8"))) layer.attrib.pop('id') # Shift the design so that its origin is at the center of the canvas # Note: this is NOT the same as centering the design in the canvas! layer.set('transform', 'translate(%s,%s)' % (extents[0], extents[1])) print etree.tostring(svg)
def test_add_cross(self): """ Tests that a cross is added """ generator = WorkingAreaGenerator(self.to_uu, "wId") generator.set_size(400, 200) root = etree.Element("root") generator.upsert(root) self.assertEqual(root[0][1].tag, "path") self.assertEqual(root[0][1].get("d"), "M -2.5,0 L 2.5,0 M 0,-2.5 L 0,2.5")
def affect(self, args): # libembroidery likes to dump a bunch of debugging stuff to stdout save_stdout() embroidery_file = args[0] pattern = embPattern_create() embPattern_read(pattern, embroidery_file) embPattern_flipVertical(pattern) stitch_plan = StitchPlan() color_block = None current_color = None for stitch in self.pattern_stitches(pattern): if stitch.color != current_color: thread = embThreadList_getAt(pattern.threadList, stitch.color) color = thread.color color_block = stitch_plan.new_color_block( (color.r, color.g, color.b)) current_color = stitch.color if not stitch.flags & END: color_block.add_stitch(stitch.xx * PIXELS_PER_MM, stitch.yy * PIXELS_PER_MM, jump=stitch.flags & JUMP, color_change=stitch.flags & STOP, trim=stitch.flags & TRIM) extents = stitch_plan.extents svg = etree.Element("svg", nsmap=inkex.NSS, attrib={ "width": str(extents[0] * 2), "height": str(extents[1] * 2), "viewBox": "0 0 %s %s" % (extents[0] * 2, extents[1] * 2), }) render_stitch_plan(svg, stitch_plan) # rename the Stitch Plan layer so that it doesn't get overwritten by Embroider layer = svg.find(".//*[@id='__inkstitch_stitch_plan__']") layer.set(INKSCAPE_LABEL, os.path.basename(embroidery_file)) layer.attrib.pop('id') # Shift the design so that its origin is at the center of the canvas # Note: this is NOT the same as centering the design in the canvas! layer.set('transform', 'translate(%s,%s)' % (extents[0], extents[1])) print >> sys.real_stdout, etree.tostring(svg)
def test_throw_exception_for_unrecognized_svg_element(self): #pylint: disable=invalid-name """ Tests that an exception is thrown for unrecognized svg elements """ root = etree.Element("root") element = etree.SubElement(root, "invalidElement") extractor = PathsExtractor([element], to_mm, "wId") with self.assertRaises(UnrecognizedSVGElement) as context_manager: extractor.extract() exception = context_manager.exception self.assertEqual(exception.element, "invalidElement")
def log_line(self, start, end, name="line", color=None): self.log_svg_element( etree.Element( "path", { "d": "M%s,%s %s,%s" % (start + end), "style": formatStyle({ "stroke": color or "#000000", "stroke-width": "0.3" }), INKSCAPE_LABEL: name }))
def test_extract_svg_path_with_only_straight_lines(self): #pylint: disable=invalid-name """ Tests that svg paths are correctly extracted """ root = etree.Element("root") element = etree.SubElement(root, "{http://www.w3.org/2000/svg}path", {'d': "M 70,800 l 125,-300 l 60,490"}) extractor = PathsExtractor([element], to_mm, "wId") extractor.extract() self.assertEqual(len(extractor.paths()), 1) self.assertEqual(extractor.paths()[0], [(70.0, 800.0), (195.0, 500.0), (255.0, 990.0)])
def test_closed_paths(self): """ Tests that closed paths are extracted correctly by repeating the first point at the end """ root = etree.Element("root") group = etree.SubElement(root, "{http://www.w3.org/2000/svg}g") etree.SubElement(group, "{http://www.w3.org/2000/svg}path", {'d': "M 70,800 l 125,-300 l 60,490 Z"}) extractor = PathsExtractor([group], to_mm, "wId") extractor.extract() self.assertEqual(len(extractor.paths()), 1) self.assertEqual(extractor.paths()[0], [(70.0, 800.0), (195.0, 500.0), (255.0, 990.0), (70.0, 800.0)])
def test_extract_path_inside_groups(self): #pylint: disable=invalid-name """ Tests that a path inside a group is correctly extracted """ root = etree.Element("root") group = etree.SubElement(root, "{http://www.w3.org/2000/svg}g") etree.SubElement(group, "{http://www.w3.org/2000/svg}path", {'d': "M 70,800 l 125,-300 l 60,490"}) extractor = PathsExtractor([group], to_mm, "wId") extractor.extract() self.assertEqual(len(extractor.paths()), 1) self.assertEqual(extractor.paths()[0], [(70.0, 800.0), (195.0, 500.0), (255.0, 990.0)])
def test_extract_paths_keeping_transform(self): #pylint: disable=invalid-name """ Tests that extracted path from a group take the transformation into account """ root = etree.Element("root") element = etree.SubElement(root, "{http://www.w3.org/2000/svg}path", { 'transform': "matrix(1,2,3,4,5,6)", 'd': "M 10,20 L 50,30 L 20,70" }) extractor = PathsExtractor([element], to_mm, "wId") extractor.extract() self.assertEqual(extractor.paths()[0], [(75.0, 106.0), (145.0, 226.0), (235.0, 326.0)])
def test_use_parent_transform_for_multiple_path(self): #pylint: disable=invalid-name """ Tests that extracted path takes the parent transformation into account """ root1 = etree.Element("root", {'transform': "translate(10,20)"}) element1 = etree.SubElement(root1, "{http://www.w3.org/2000/svg}path", { 'transform': "matrix(1,2,3,4,5,6)", 'd': "M 10,20 L 50,30 L 20,70" }) root2 = etree.Element("root", {'transform': "translate(5,10)"}) element2 = etree.SubElement(root2, "{http://www.w3.org/2000/svg}path", { 'transform': "matrix(1,2,3,4,5,6)", 'd': "M 10,20 L 50,30 L 20,70" }) extractor = PathsExtractor([element1, element2], to_mm, "wId") extractor.extract() self.assertEqual(extractor.paths()[0], [(85.0, 126.0), (155.0, 246.0), (245.0, 346.0)]) self.assertEqual(extractor.paths()[1], [(80.0, 116.0), (150.0, 236.0), (240.0, 336.0)])
def test_add_the_rectangle(self): """ Tests that a rectangle is added """ generator = WorkingAreaGenerator(self.to_uu, "wId") generator.set_size(400, 300) root = etree.Element("root") generator.upsert(root) self.assertEqual(root[0][0].tag, "rect") self.assertEqual(root[0][0].get("x"), "0") self.assertEqual(root[0][0].get("y"), "0") self.assertEqual(root[0][0].get("width"), "100") self.assertEqual(root[0][0].get("height"), "75.0")
def test_add_origin_coordinates_text(self): # pylint: disable=invalid-name """ Tests that coordinates at the orgin are added """ generator = WorkingAreaGenerator(self.to_uu, "wId") generator.set_size(400, 200) root = etree.Element("root") generator.upsert(root) self.assertEqual(root[0][2].tag, "text") self.assertEqual(root[0][2].get("x"), "-7.0") self.assertEqual(root[0][2].get("y"), "-2.5") self.assertEqual(root[0][2].get("font-family"), "Verdana") self.assertEqual(root[0][2].get("font-size"), "2.5") self.assertEqual(root[0][2].text, "(0, 0)")
def test_do_not_draw_border_if_equal_working_area(self): # pylint: disable=invalid-name """ Tests that no border is drawn if border is coincident with the working area """ generator = WorkingAreaGenerator(self.to_uu, "wId") generator.set_size(400, 300) root = etree.Element("root") generator.upsert(root) num_initial_root_children = len(root[0]) border = Border([[(0, 0), (400, 300)]], 0) painter = BorderPainter(border) painter.paint(generator) self.assertEqual(len(root[0]), num_initial_root_children)
def test_closed_paths_with_multiple_paths(self): #pylint: disable=invalid-name """ Tests that closed paths are extracted correctly also when multiple subpaths are present """ root = etree.Element("root") element = etree.SubElement( root, "{http://www.w3.org/2000/svg}path", {'d': "M 70,800 l 125,-300 l 60,490 Z M 100,100 L 200,200"}) extractor = PathsExtractor([element], to_mm, "wId") extractor.extract() self.assertEqual(len(extractor.paths()), 2) self.assertEqual(extractor.paths()[0], [(70.0, 800.0), (195.0, 500.0), (255.0, 990.0), (70.0, 800.0)]) self.assertEqual(extractor.paths()[1], [(100.0, 100.0), (200.0, 200.0)])