1
2
3
4
5
6
7
8
9
10
11 from aggdraw import Brush, Pen
12 from aggdraw import Font
13 import math
14 from rdkit import RDConfig
15 import os,re
16
17 from aggdraw import Draw
18 from canvasbase import CanvasBase
19
20 faceMap={'sans':os.path.join(RDConfig.RDCodeDir,'Chem','Draw','FreeSans.ttf')}
21
23 color = (int(color[0]*255),int(color[1]*255),int(color[2]*255))
24 return color
25
27
28
29 fontScale=1.2
30 - def __init__(self, img=None,
31 imageType=None,
32 fileName=None,
33 size=None,
34 ):
35 if img is None:
36 import Image
37 if size is None:
38 raise ValueError,'please provide either an image or a size'
39 img = Image.new('RGBA',size,"white")
40 self.image = img
41 self.draw = Draw(img)
42 self.draw.setantialias(True)
43 if size is None:
44 self.size = self.draw.size
45 else:
46 self.size = size
47 if imageType and imageType not in ('png','jpg'):
48 raise ValueError,'unsupported image type for agg canvas'
49 self.drawType=imageType
50 self.fileName=fileName
51
52 - def _doLine(self, p1, p2, pen, **kwargs):
53 if kwargs.get('dash',(0,0)) == (0,0):
54 self.draw.line((p1[0],p1[1],p2[0],p2[1]),pen)
55 else:
56 dash = kwargs['dash']
57 pts = self._getLinePoints(p1,p2,dash)
58
59 currDash = 0
60 dashOn = True
61 while currDash<(len(pts)-1):
62 if dashOn:
63 p1 = pts[currDash]
64 p2 = pts[currDash+1]
65 self.draw.line((p1[0],p1[1],p2[0],p2[1]),pen)
66 currDash+=1
67 dashOn = not dashOn
68
69 - def addCanvasLine(self, p1, p2, color=(0,0,0), color2=None, **kwargs):
70 if color2 and color2!=color:
71 mp = (p1[0]+p2[0])/2.,(p1[1]+p2[1])/2.
72 color = convertColor(color)
73 self._doLine(p1,mp,Pen(color,kwargs.get('linewidth',1)),**kwargs)
74 color2 = convertColor(color2)
75 self._doLine(mp,p2,Pen(color2,kwargs.get('linewidth',1)),**kwargs)
76 else:
77 color = convertColor(color)
78 self._doLine(p1,p2,Pen(color,kwargs.get('linewidth',1)),**kwargs)
79
80 - def addCanvasText(self,text,pos,font,color=(0,0,0),**kwargs):
81 orientation=kwargs.get('orientation','E')
82 color = convertColor(color)
83 font = Font(color,faceMap[font.face],size=font.size*self.fontScale)
84
85 blocks = list(re.finditer(r'\<(.+?)\>(.+?)\</\1\>',text))
86 w,h = 0,0
87 supH=0
88 subH=0
89 if not len(blocks):
90 w,h=self.draw.textsize(text,font)
91 bw,bh=w*1.1,h*1.1
92 dPos = pos[0]-bw/2.,pos[1]-bh/2.
93 bgColor=kwargs.get('bgColor',(1,1,1))
94 bgColor = convertColor(bgColor)
95 self.draw.rectangle((dPos[0],dPos[1],dPos[0]+bw,dPos[1]+bh),
96 None,Brush(bgColor))
97 dPos = pos[0]-w/2.,pos[1]-h/2.
98 self.draw.text(dPos,text,font)
99 else:
100 dblocks=[]
101 idx=0
102 for block in blocks:
103 blockStart,blockEnd=block.span(0)
104 if blockStart != idx:
105
106 tblock = text[idx:blockStart]
107 tw,th=self.draw.textsize(tblock,font)
108 w+=tw
109 h = max(h,th)
110 dblocks.append((tblock,'',tw,th))
111 fmt = block.groups()[0]
112 tblock = block.groups()[1]
113 tw,th=self.draw.textsize(tblock,font)
114 w+=tw
115 if fmt == 'sub':
116 subH = max(subH,th)
117 elif fmt=='sup':
118 supH = max(supH,th)
119 else:
120 h = max(h,th)
121 dblocks.append((tblock,fmt,tw,th))
122 idx = blockEnd
123 if idx!=len(text):
124
125 tblock = text[idx:]
126 tw,th=self.draw.textsize(tblock,font)
127 w+=tw
128 h = max(h,th)
129 dblocks.append((tblock,'',tw,th))
130
131 supH *= 0.25
132 subH *= 0.25
133 h += supH + subH
134 bw,bh=w*1.1,h
135
136 dPos = [pos[0]-w/2.,pos[1]-h/2.]
137 if orientation=='W':
138 dPos = [pos[0]-w,pos[1]-h/2.]
139 elif orientation=='E':
140 dPos = [pos[0],pos[1]-h/2.]
141 else:
142 dPos = [pos[0]-w/2,pos[1]-h/2.]
143
144 bgColor=kwargs.get('bgColor',(1,1,1))
145 bgColor = convertColor(bgColor)
146 self.draw.rectangle((dPos[0],dPos[1],dPos[0]+bw,dPos[1]+bh),
147 None,Brush(bgColor))
148 if supH: dPos[1]+=supH
149 for txt,fmt,tw,th in dblocks:
150 tPos = dPos[:]
151 if fmt=='sub':
152 tPos[1]+=subH
153 elif fmt=='sup':
154 tPos[1]-=supH
155 self.draw.text(tPos,txt,font)
156 dPos[0]+=tw
157
158
160 if not fill and not stroke: return
161 dps = []
162 for p in ps:
163 dps.extend(p)
164 color = convertColor(color)
165 brush=None
166 pen=None
167 if fill:
168 brush = Brush(color)
169 if stroke:
170 pen = Pen(color)
171 self.draw.polygon(dps,pen,brush)
172
173 - def addCanvasDashedWedge(self,p1,p2,p3,dash=(2,2),color=(0,0,0),
174 color2=None,**kwargs):
175 pen = Pen(color,kwargs.get('linewidth',1))
176 dash = (3,3)
177 pts1 = self._getLinePoints(p1,p2,dash)
178 pts2 = self._getLinePoints(p1,p3,dash)
179
180 if len(pts2)<len(pts1): pts2,pts1=pts1,pts2
181
182 for i in range(len(pts1)):
183 self.draw.line((pts1[i][0],pts1[i][1],pts2[i][0],pts2[i][1]),pen)
184
186 self.draw.flush()
187 if self.fileName:
188 self.image.save(self.fileName)
189