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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
from reportlab.pdfgen import canvas
from reportlab.lib.colors import black, gray, white, magenta, Color
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import cm, inch
from reportlab.platypus import SimpleDocTemplate, Spacer, Paragraph
from reportlab.platypus.flowables import Flowable
import re
class Alignment(Flowable):
def __init__(self, x_words, y_words, alignment, x_font, y_font, ptsize, unit, scale=True, colours=None):
self._x_words = x_words
self._y_words = y_words
self._alignment = alignment
self._unit = unit*cm
self._x_font = x_font
self._y_font = y_font
self._ptsize = ptsize
self._scale = 1
self._do_scale = scale
self._colours = colours
if not colours:
self._colours = {'S':black, 'P':gray, 'N':magenta}
def wrap(self, rw, rh):
xws = [self.canv.stringWidth(w, self._x_font, self._ptsize)
for w in self._x_words]
yws = [self.canv.stringWidth(w, self._y_font, self._ptsize)
for w in self._y_words]
width = (len(self._x_words) + 0.22)* self._unit + max(yws)
height = (len(self._y_words) + 0.22)* self._unit + max(xws)
if self._do_scale:
self._scale = min(rw / width, 1.5)
width *= self._scale
height *= self._scale
return (width, height)
def draw(self):
c = self.canv
print c.getAvailableFonts()
X=len(self._x_words)
Y=len(self._y_words)
c.saveState()
c.scale(self._scale, self._scale)
for (x, y), conf in self._alignment.items():
col = self._colours[conf]
if isinstance(col, Color):
c.setFillColor(col)
c.rect((0.02 + x)*self._unit, (0.02+Y-y-1)*self._unit,
self._unit, self._unit, 0, 1)
else:
bl = (x*self._unit, (Y-y-1)*self._unit)
tl = (x*self._unit, (Y-y)*self._unit)
tr = ((x+1)*self._unit, (Y-y)*self._unit)
br = ((x+1)*self._unit, (Y-y-1)*self._unit)
p = c.beginPath()
p.moveTo(*br)
p.lineTo(*tr)
p.lineTo(*tl)
c.setFillColor(col[0])
c.drawPath(p, fill=1)
p = c.beginPath()
p.moveTo(*br)
p.lineTo(*bl)
p.lineTo(*tl)
c.setFillColor(col[1])
c.drawPath(p, fill=1)
c.setStrokeColor(black)
c.grid(map(lambda x: (0.02+x)*self._unit, range(X+1)),
map(lambda y: (0.02+y)*self._unit, range(Y+1)))
c.setFont(self._x_font, self._ptsize)
c.setFillColor(black)
for x, word in enumerate(self._x_words):
c.saveState()
c.translate((x+0.52)*self._unit, (Y+0.22)*self._unit)
c.rotate(60)
c.drawString(0, 0, word)
c.restoreState()
c.setFont(self._y_font, self._ptsize)
for y, word in enumerate(self._y_words):
c.drawString((X+0.22)*self._unit, (Y-y+0.42-1)*self._unit, word)
c.restoreState()
class Document:
def __init__(self, filename):
self._styles = getSampleStyleSheet()
self._doc = SimpleDocTemplate(filename)
self._story = []
def append(self, flowable):
self._story.append(flowable)
self._story.append(Spacer(1, 1*cm))
def render(self):
self._doc.build(self._story[:-1])
class Canvas:
def __init__(self, filename):
self._filename = filename
self._canvas = canvas.Canvas('.' + filename, A4)
self._size = A4
self._body = None
def append(self, flowable):
if self._body:
print >>sys.stderr, 'WARNING: replacing existing flowable'
self._body = flowable
def render(self):
self._body.canv = self._canvas
width, height = self._body.wrap(*self._size)
width *= 1.02
height *= 1.02
self._canvas = canvas.Canvas(self._filename, (width, height))
self._body.canv = self._canvas
self._body.draw()
self._canvas.save()
|