def test_mirror_lines(): def stroke(p): p.fill_mode() p.move_to((0, 0)) p.turn_to(180) p.move_forward(6) p.turn_to(0) p.line_forward(6) p.turn_right(60) p.line_forward(6) p = Pen() stroke(p) assert_path_data(p, 2, 'M-6.00,0.00 L0.00,0.00 L3.00,5.20') p = Pen() stroke(p) p.paper.mirror_x(0) assert_path_data(p, 2, 'M6.00,0.00 L0.00,0.00 L-3.00,5.20') p = Pen() stroke(p) p.paper.mirror_x(1) assert_path_data(p, 2, 'M8.00,0.00 L2.00,0.00 L-1.00,5.20') p = Pen() stroke(p) p.paper.mirror_y(0) assert_path_data(p, 2, 'M-6.00,0.00 L0.00,0.00 L3.00,-5.20')
def test_join_paths_loop(): # Already looped paths should not be affected by join_paths. p = Pen() p.fill_mode() p.move_to((0, 0)) p.square(2) target = 'M-1,1 L1,1 L1,-1 L-1,-1 L-1,1 z' assert_path_data(p, 0, target) p.paper.join_paths() assert_path_data(p, 0, target) # Loops can also be created by joining paths. p = Pen() p.fill_mode() p.move_to((0, 0)) p.line_to((1, 0)) p.line_to((1, 1)) p.break_stroke() p.line_to((0, 1)) p.line_to((0, 0)) p.paper.join_paths() assert_path_data(p, 0, 'M1,-1 L1,0 L0,0 L0,-1 L1,-1 z') # The joins can get complicated. p = Pen() p.fill_mode() p.move_to((3, 0)) p.line_to((2, 0)) p.break_stroke() p.move_to((1, 0)) p.line_to((2, 2)) p.break_stroke() p.move_to((4, 0)) p.line_to((3, 0)) p.break_stroke() p.move_to((1, 0)) p.line_to((2, 0)) p.break_stroke() p.move_to((4, 0)) p.line_to((2, 2)) p.paper.join_paths() assert_path_data( p, 0, 'M1,0 L2,-2 L4,0 L3,0 L2,0 L1,0 z', )
def test_two_pens_one_paper(): paper = Paper() p1 = Pen(paper) p2 = Pen(paper) p1.fill_mode() p2.fill_mode() p1.move_to((0, 0)) p2.move_to((0, 0)) p1.line_to((0, 1)) p2.line_to((2, 0)) assert_path_data(paper, 0, ['M0,0 L0,-1', 'M0,0 L2,0'])
def draw(): p = Pen() p.fill_mode() p.move_to((0, 0)) p.circle(2) paper1 = p.paper p = Pen() p.fill_mode() p.move_to((3, 0)) p.circle(1) paper2 = p.paper return paper1, paper2
def test_fuse_with_joint(): p = Pen() p.stroke_mode(2.0) p.move_to((0, 0)) p.turn_to(180) p.line_forward(5) p.turn_left(90) p.line_forward(5) p.break_stroke() p.move_to((0, 0)) p.turn_to(0) p.line_forward(5) assert_path_data(p, 0, [ 'M0,1 L0,-1 L-6,-1 L-6,5 L-4,5 L-4,1 L0,1 z', 'M0,-1 L0,1 L5,1 L5,-1 L0,-1 z', ]) p.paper.join_paths() p.paper.fuse_paths() assert_path_data(p, 0, 'M-6,5 L-4,5 L-4,1 L5,1 L5,-1 L-6,-1 L-6,5 z')
def handle_letter(letter, mode): letter_paper = draw_letter( letter, mode, fixed_width=30.0, show_template=True, fuse=False, ) letter_paper.translate((5, 0), bounds=False) p = Pen() p.move_to((-8, 3)) p.text( letter.case, 6.0, font, gray, centered=True, ) p.move_to((-8, -3)) p.text( ', '.join(lookup(letter.case)), 6.0, font, gray, centered=True, ) letter_paper.merge(p.paper) return letter_paper
def test_copy_loop(): p = Pen() p.stroke_mode(0.2) def square(): p.turn_to(180) p.line_forward(1) p.turn_left(90) p.line_forward(1) p.turn_left(90) p.line_forward(1) p.turn_left(90) p.line_forward(1) p.move_to((0, 0)) square() p = p.copy(paper=True) p.move_to((2, 0)) square() assert_path_data(p, 1, ('M0.1,-0.1 L-1.1,-0.1 L-1.1,1.1 L0.1,1.1 L0.1,-0.1 z ' 'M-0.1,0.1 L-0.1,0.9 L-0.9,0.9 L-0.9,0.1 L-0.1,0.1 z ' 'M2.1,-0.1 L0.9,-0.1 L0.9,1.1 L2.1,1.1 L2.1,-0.1 z ' 'M1.9,0.1 L1.9,0.9 L1.1,0.9 L1.1,0.1 L1.9,0.1 z'))
def test_override_bounds_copy(): # Get the bounds of a Paper, modify them, then set them back changed. paper = Paper() paper.override_bounds(0, 0, 1, 1) bounds = paper.bounds() bounds.right = 5 assert_equal(paper.bounds(), Bounds(0, 0, 1, 1)) paper.override_bounds(bounds) assert_equal(paper.bounds(), Bounds(0, 0, 5, 1)) # This works on non-overridden Papers as well. paper = Paper() p = Pen() p.fill_mode() p.move_to((0.5, 0.5)) p.circle(0.5) bounds = p.paper.bounds() bounds.right = 5 assert_equal(p.paper.bounds(), Bounds(0, 0, 1, 1)) p.paper.override_bounds(bounds) assert_equal(p.paper.bounds(), Bounds(0, 0, 5, 1))
def draw_character(self, mode, **kwargs): side_ending = self.side_ending_class( self, self.side_flipped, ) paper = Paper() pen = Pen() pen.set_mode(mode) pen.move_to((0, TOP - mode.width / 2)) pen.turn_to(0) pen.line_forward(2.0) pen.last_segment().start_cap = stub_cap side_ending.draw(pen) paper.merge(pen.paper) bounds = paper.bounds() bounds.top = OVER bounds.bottom = MIDDLE bounds.left = 0 paper.override_bounds(bounds) return paper
def test_translate(): p = Pen() p.stroke_mode(1.0) p.move_to((0, 0)) p.turn_to(0) p.line_forward(3) p.arc_left(90, 3) p.turn_left(90) p.move_forward(3) p.fill_mode() p.circle(0.5) p.move_forward(3) p.square(1) p.paper.translate((1, 1)) assert_equal(p.paper.svg_elements(1), [ ('<path d="M1.0,-1.5 L1.0,-0.5 L4.0,-0.5 A 3.5,3.5 0 0 0 ' '7.5,-4.0 L6.5,-4.0 A 2.5,2.5 0 0 1 4.0,-1.5 L1.0,-1.5 z" ' 'fill="#000000" />'), ('<path d="M4.5,-4.0 A 0.5,0.5 0 0 0 3.5,-4.0 ' 'A 0.5,0.5 0 0 0 4.5,-4.0 z" fill="#000000" />'), ('<path d="M0.5,-3.5 L1.5,-3.5 L1.5,-4.5 L0.5,-4.5 L0.5,-3.5 z" ' 'fill="#000000" />'), ])
def test_text_centered(): p = Pen() p.move_to((0, 0)) p.text('abcd', 1, 'sans-serif', centered=True) svg_data = p.paper.format_svg(0) assert ('<text x="0" y="0" font-family="sans-serif" font-size="1" ' 'fill="#000000" text-anchor="middle">abcd</text>') in svg_data
def test_text(): p = Pen() p.move_to((0, 0)) p.text('abcd', 1, 'sans-serif') svg_data = p.paper.format_svg(0) assert ('<text x="0" y="0" font-family="sans-serif" font-size="1" ' 'fill="#000000">abcd</text>') in svg_data
def test_center_on_xy(): p = Pen() p.stroke_mode(2.0) p.move_to((0, 0)) p.turn_to(0) p.line_forward(4) p.move_to((2, 1)) p.circle(1) p.paper.center_on_x(0) assert_equal(p.paper.svg_elements(0), [ '<path d="M-2,-1 L-2,1 L2,1 L2,-1 L-2,-1 z" fill="#000000" />', '<path d="M2,-1 A 2,2 0 0 0 -2,-1 A 2,2 0 0 0 2,-1 z" fill="#000000" />', ]) p.paper.center_on_y(0) assert_equal(p.paper.svg_elements(1), [ ('<path d="M-2.0,0.0 L-2.0,2.0 L2.0,2.0 L2.0,0.0 L-2.0,0.0 z" ' 'fill="#000000" />'), ('<path d="M2.0,0.0 A 2.0,2.0 0 0 0 -2.0,0.0 ' 'A 2.0,2.0 0 0 0 2.0,0.0 z" fill="#000000" />'), ])
def test_copy_arc_to(): p = Pen() p.fill_mode() p.move_to((0, 0)) p.turn_to(0) p.arc_to((5, 5)) p = p.copy(paper=True) assert_path_data(p, 0, 'M0,0 A 5,5 0 0 0 5,-5')
def test_draw_bounds(): p = Pen() p.fill_mode() Bounds(-2, -3, 1, 2).draw(p) assert_path_data( p, 0, 'M-2,3 L1,3 L1,-2 L-2,-2 L-2,3 z' )
def test_square_bounds(): p = Pen() p.fill_mode() p.move_to((1, 1)) p.square(4) assert_equal( p.paper.bounds(), Bounds(-1, -1, 3, 3) )
def test_text_translate(): p = Pen() p.move_to((0, 0)) p.text('abcd', 1) paper = p.paper paper.translate((2, 3)) svg_data = paper.format_svg(0) assert ('<text x="2" y="-3" font-family="sans-serif" font-size="1" ' 'fill="#000000">abcd</text>') in svg_data
def test_circle_bounds(): p = Pen() p.fill_mode() p.move_to((1, 1)) p.circle(1.5) assert_equal( p.paper.bounds(), Bounds(-0.5, -0.5, 2.5, 2.5) )
def test_copy_no_paper(): p1 = Pen() p1.fill_mode() p1.move_to((0, 0)) p1.turn_to(0) p1.line_forward(5) p2 = p1.copy() p2.line_forward(5) assert_path_data(p1, 0, 'M0,0 L5,0') assert_path_data(p2, 0, 'M5,0 L10,0')
def test_join_paths_thick(): # Segments join together if possible when join_paths is called. p = Pen() p.stroke_mode(2.0) p.move_to((0, 0)) p.turn_to(0) p.line_forward(5) p.break_stroke() p.turn_left(90) p.line_forward(5) p.paper.join_paths() assert_path_data(p, 0, 'M0,-1 L0,1 L6,1 L6,-5 L4,-5 L4,-1 L0,-1 z')
def test_copy_arc(): p1 = Pen() p1.fill_mode() p1.move_to((0, 0)) p1.turn_to(0) p1.arc_left(90, radius=5) p2 = p1.copy(paper=True) p2.arc_left(90, radius=5) assert_path_data(p1, 0, 'M0,0 A 5,5 0 0 0 5,-5') assert_path_data(p2, 0, 'M0,0 A 5,5 0 0 0 5,-5 A 5,5 0 0 0 0,-10')
def test_paper_merge(): # Merge two drawings together. paper = Paper() p = Pen() p.fill_mode() p.turn_to(0) p.arc_left(180, 5) p.paper.center_on_x(0) paper.merge(p.paper) p = Pen() p.fill_mode() p.turn_to(180) p.arc_left(180, 5) p.paper.center_on_x(0) paper.merge(p.paper) assert_path_data(paper, 1, [ 'M-2.5,0.0 A 5.0,5.0 0 0 0 -2.5,-10.0', 'M2.5,0.0 A 5.0,5.0 0 0 0 2.5,10.0', ])
def test_mirror_lines_thick(): def stroke(p): p.stroke_mode(sqrt2) p.move_to((0, 0)) p.turn_to(45) p.line_forward(3 * sqrt2) p = Pen() stroke(p) assert_path_data(p, 1, ['M-0.5,-0.5 L0.5,0.5 L3.5,-2.5 L2.5,-3.5 L-0.5,-0.5 z']) p = Pen() stroke(p) p.paper.mirror_x(0) assert_path_data(p, 1, ['M-0.5,0.5 L0.5,-0.5 L-2.5,-3.5 L-3.5,-2.5 L-0.5,0.5 z']) p = Pen() stroke(p) p.paper.mirror_y(0) assert_path_data(p, 1, ['M0.5,-0.5 L-0.5,0.5 L2.5,3.5 L3.5,2.5 L0.5,-0.5 z'])
def test_text_merge(): p = Pen() p.move_to((0, 0)) p.text('abcd', 1) paper1 = p.paper assert '<text' in paper1.format_svg(0) paper2 = Paper() paper2.merge(paper1) assert '<text' in paper2.format_svg(0) paper3 = Paper() paper3.merge_under(paper1) assert '<text' in paper3.format_svg(0)
def test_mirror_arcs_thick(): def stroke(p): p.stroke_mode(2.0) p.move_to((0, 0)) p.turn_to(0) p.arc_left(90, 5) p = Pen() stroke(p) assert_path_data(p, 1, ('M0.0,-1.0 L0.0,1.0 A 6.0,6.0 0 0 0 6.0,-5.0 ' 'L4.0,-5.0 A 4.0,4.0 0 0 1 0.0,-1.0 z')) p = Pen() stroke(p) p.paper.mirror_x(0) assert_path_data(p, 1, ('M0.0,1.0 L0.0,-1.0 A 4.0,4.0 0 0 1 -4.0,-5.0 ' 'L-6.0,-5.0 A 6.0,6.0 0 0 0 0.0,1.0 z')) p = Pen() stroke(p) p.paper.mirror_y(0) assert_path_data(p, 1, ('M0.0,-1.0 L0.0,1.0 A 4.0,4.0 0 0 1 4.0,5.0 ' 'L6.0,5.0 A 6.0,6.0 0 0 0 0.0,-1.0 z'))
def test_fuse_paths(): # Create two halves of a stroke in the same direction. p = Pen() p.stroke_mode(sqrt2) p.move_to((-3, 3)) p.turn_to(-45) p.line_forward(3 * sqrt2, start_slant=0) p.line_forward(3 * sqrt2, end_slant=0) p.paper.fuse_paths() assert_path_data(p, 1, ['M-2.0,-3.0 L-4.0,-3.0 L2.0,3.0 L4.0,3.0 L-2.0,-3.0 z'])
def test_mirror_end_slant(): paper = Paper() p = Pen() p.stroke_mode(sqrt2) p.move_to((0, 0)) p.turn_to(-45) p.line_forward(5 * sqrt2, end_slant=45) p.paper.mirror_x(0) paper.merge(p.paper) p = Pen() p.stroke_mode(sqrt2) p.move_to((0, 0)) p.turn_to(45) p.line_forward(5 * sqrt2) paper.merge(p.paper) paper.join_paths() paper.fuse_paths() assert_path_data(paper, 1, 'M-5.5,4.5 L-4.5,5.5 L5.5,-4.5 L4.5,-5.5 L-5.5,4.5 z')
def test_line_segment_bounds(): # Fill mode segment. p = Pen() p.fill_mode() p.move_to((1, 0)) p.line_to((2, 3)) line = p.last_segment() assert_equal( line.bounds(), Bounds(1, 0, 2, 3) ) # Stroke mode segment. p = Pen() p.stroke_mode(sqrt2) p.move_to((0, 0)) p.line_to((5, 5)) line = p.last_segment() assert_equal( line.bounds(), Bounds(-0.5, -0.5, 5.5, 5.5) )
def test_mirror_arcs(): def stroke(p): p.fill_mode() p.move_to((0, 0)) p.turn_to(0) p.arc_left(90, 3) p.arc_right(90, 3) p = Pen() stroke(p) assert_path_data(p, 1, ('M0.0,0.0 A 3.0,3.0 0 0 0 3.0,-3.0 ' 'A 3.0,3.0 0 0 1 6.0,-6.0')) p = Pen() stroke(p) p.paper.mirror_x(0) assert_path_data(p, 1, ('M0.0,0.0 A 3.0,3.0 0 0 1 -3.0,-3.0 ' 'A 3.0,3.0 0 0 0 -6.0,-6.0')) p = Pen() stroke(p) p.paper.mirror_y(0) assert_path_data(p, 1, ('M0.0,0.0 A 3.0,3.0 0 0 1 3.0,3.0 ' 'A 3.0,3.0 0 0 0 6.0,6.0'))
def draw_character(self, mode, fuse=True): bottom_ending = bottom_ending_class( self, self.bottom_straight, self.bottom_flipped, ) pen = Pen() pen.set_mode(mode) pen.move_to((0, TOP)) pen.turn_to(-90) pen.line_to_y(MIDDLE, start_slant=45) bottom_ending.draw(pen) if fuse: pen.paper.fuse_paths() pen.paper.center_on_x(0) return pen.paper