1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
"""
Simple ASCII output of the rendered image.
Think of it as a low resolution black and white image.
(C) 2006 Chris Liechti <cliechti@gmx.net>
"""
import sys
class AsciiOutputVisitor:
"""Render a list of shapes as ASCII art.
Scaled, think of it as a low resolution black and white image
"""
def __init__(self, scale=3):
self.image = {}
self.scale = scale
def visit(self, aa_image):
for shape in aa_image.shapes:
shape_name = shape.__class__.__name__.lower()
visitor_name = 'visit_%s' % shape_name
if hasattr(self, visitor_name):
getattr(self, visitor_name)(shape)
else:
print "don't know how to handle shape %r" % shape
def visit_point(self, point):
self.image[point.x*self.scale, point.y*self.scale] = '#'
def visit_line(self, line):
x1, x2 = line.start.x*self.scale, line.end.x*self.scale
y1, y2 = line.start.y*self.scale, line.end.y*self.scale
if x1 > x2: x1, x2 = x2, x1
if y1 > y2: y1, y2 = y2, y1
dx = x2 - x1
dy = y2 - y1
if dx > dy:
y = y1
if dx:
m = float(dy)/dx
else:
m = 0
for x in range(x1, x2+1):
self.image[x,int(y)] = '#'
y += m
else:
x = x1
if dy:
m = float(dx)/dy
else:
m = 0
for y in range(y1, y2+1):
self.image[int(x),y] = '#'
x += m
if line.start_style:
self.image[line.start.x*self.scale,line.start.y*self.scale] = 'O'
if line.end_style:
self.image[line.end.x*self.scale,line.end.y*self.scale] = 'O'
def visit_rectangle(self, rectangle):
x1, x2 = rectangle.p1.x*self.scale, rectangle.p2.x*self.scale
y1, y2 = rectangle.p1.y*self.scale, rectangle.p2.y*self.scale
if x1 > x2: x1, x2 = x2, x1
if y1 > y2: y1, y2 = y2, y1
for y in range(y1, y2):
for x in range(x1, x2):
self.image[x,y] = '#'
def visit_label(self, label):
x, y = label.position.x*self.scale, label.position.y*self.scale
for character in label.text:
self.image[x, y] = character
x += 1
def __str__(self):
"""return a cropped image"""
#find out size
min_x = min_y = sys.maxint
max_x = max_y = -sys.maxint
for x,y in self.image:
min_x = min(min_x, x)
max_x = max(max_x, x)
min_y = min(min_y, y)
max_y = max(max_y, y)
#render image to lines of text, fill unused fields with a dot
result = []
for y in range(min_y, max_y+1):
line = []
for x in range(min_x, max_x+1):
line.append(self.image.get((x,y), '.'))
result.append(''.join(line))
return '\n'.join(result)
|