1
2
3
4
5
6
7
8 import cairo
9 import math
10 import rdkit.RDConfig
11 import os
12 import array
13
14
15
16
17
19 - def __init__(self,
20 image=None,
21 size=None,
22 ctx=None,
23 imageType=None,
24 fileName=None,
25 ):
26 """
27 Canvas can be used in four modes:
28 1) using the supplied PIL image
29 2) using the supplied cairo context ctx
30 3) writing to a file fileName with image type imageType
31 4) creating a cairo surface and context within the constructor
32 """
33 self.image=None
34 self.imageType=imageType
35 if image is not None:
36 imgd = image.tostring()
37 a = array.array('B',imgd)
38 stride = cairo.ImageSurface.format_stride_for_width (cairo.FORMAT_ARGB32,
39 image.size[0])
40 if stride != image.size[0] * 4:
41 raise Exception ,"invalid stride"
42 surface = cairo.ImageSurface.create_for_data (
43 a, cairo.FORMAT_ARGB32,
44 image.size[0], image.size[1], stride)
45 ctx = cairo.Context(surface)
46 size=image.size[0], image.size[1]
47 self.image=image
48 elif size is not None:
49
50
51
52
53
54
55
56
57
58 if cairo.HAS_PDF_SURFACE and imageType == "pdf":
59 surface = cairo.PDFSurface (fileName, size[0], size[1])
60 elif cairo.HAS_SVG_SURFACE and imageType == "svg":
61 surface = cairo.SVGSurface (fileName, size[0], size[1])
62 elif cairo.HAS_PS_SURFACE and imageType == "ps":
63 surface = cairo.PSSurface (fileName, size[0], size[1])
64 elif cairo.HAS_IMAGE_SURFACE and imageType == "png":
65 surface = cairo.ImageSurface (cairo.FORMAT_ARGB32, size[0], size[1])
66 else:
67 raise Exception, "Wrong file type"
68 ctx = cairo.Context(surface)
69 ctx.set_source_rgb(255,255,255)
70 ctx.paint()
71 else:
72 surface=ctx.get_target()
73 try:
74 size=surface.get_width(),surface.get_height()
75 except AttributeError:
76 size=None
77 self.ctx=ctx
78 self.size=size
79 self.surface=surface
80 self.fileName=fileName
81
82
84 """temporary interface, must be splitted to different methods,
85 (elif self.imageType == "png":)"""
86 try:
87 if self.fileName:
88 self.surface.write_to_png(self.fileName)
89 except AttributeError:
90 pass
91 if self.image is not None:
92 self.image.fromstring(self.surface.get_data(),
93 "raw","RGBA",0,1)
94 self.surface.finish()
95 elif self.imageType == "png":
96 buffer=self.surface.get_data()
97 return buffer
98
99
101 color = (int(color[0]*255),int(color[1]*255),int(color[2]*255))
102 return color
103
105 x1,y1=p1
106 x2,y2=p2
107 dx = x2-x1
108 dy = y2-y1
109 lineLen = math.sqrt(dx*dx+dy*dy)
110 theta = math.atan2(dy,dx)
111 cosT = math.cos(theta)
112 sinT = math.sin(theta)
113
114 pos = (x1,y1)
115 pts = [pos]
116 dist = 0
117 currDash = 0
118 while dist < lineLen:
119 currL = dash[currDash%len(dash)]
120 if(dist+currL > lineLen): currL = lineLen-dist
121 endP = (pos[0] + currL*cosT, pos[1] + currL*sinT)
122 pts.append(endP)
123 pos = endP
124 dist += currL
125 currDash += 1
126 return pts
127
128 -def _doLine(canvas,p1,p2,**kwargs):
129 if kwargs.get('dashes',(0,0)) == (0,0):
130 canvas.ctx.move_to(p1[0],p1[1])
131 canvas.ctx.line_to(p2[0],p2[1])
132 else:
133
134 dash = [x*4 for x in kwargs['dashes']]
135 pts = _getLinePoints(p1,p2,dash)
136
137 currDash = 0
138 dashOn = True
139 while currDash<(len(pts)-1):
140 if dashOn:
141 p1 = pts[currDash]
142 p2 = pts[currDash+1]
143 canvas.ctx.move_to(p1[0],p1[1])
144 canvas.ctx.line_to(p2[0],p2[1])
145 currDash+=1
146 dashOn = not dashOn
147
148 -def addCanvasLine(canvas,p1,p2,color=(0,0,0),color2=None,**kwargs):
149 canvas.ctx.set_line_width(kwargs.get('linewidth',1))
150 if color2 and color2!=color:
151 mp = (p1[0]+p2[0])/2.,(p1[1]+p2[1])/2.
152 color = convertColor(color)
153 canvas.ctx.set_source_rgb(*color)
154 _doLine(canvas,p1,mp,**kwargs)
155 canvas.ctx.stroke()
156 color2 = convertColor(color2)
157 canvas.ctx.set_source_rgb(*color2)
158 _doLine(canvas,mp,p2,**kwargs)
159 canvas.ctx.stroke()
160 else:
161 color = convertColor(color)
162 canvas.ctx.set_source_rgb(*color)
163 _doLine(canvas,p1,p2,**kwargs)
164 canvas.ctx.stroke()
165
166 -def addCanvasText(canvas,text,pos,font,color=(0,0,0),**kwargs):
167 color = convertColor(color)
168 canvas.ctx.select_font_face("Georgia",
169 cairo.FONT_SLANT_NORMAL,
170 cairo.FONT_WEIGHT_BOLD)
171 canvas.ctx.set_font_size(font.size)
172 w,h=canvas.ctx.text_extents(text)[2:4]
173 bw,bh=w*1.8,h*1.4
174 dPos = pos[0]-bw/2.,pos[1]-bh/2.
175 bgColor=kwargs.get('bgColor',(1,1,1))
176 bgColor = convertColor(bgColor)
177 canvas.ctx.set_source_rgb(*bgColor)
178 canvas.ctx.rectangle(dPos[0],dPos[1],bw,bh)
179 canvas.ctx.fill()
180 dPos = pos[0]-w/2.,pos[1]+h/2.
181 canvas.ctx.set_source_rgb(*color)
182 canvas.ctx.move_to(*dPos)
183 canvas.ctx.show_text(text)
184
194
195 -def addCanvasDashedWedge(canvas,p1,p2,p3,dash=(2,2),color=(0,0,0),
196 color2=None,**kwargs):
197 canvas.ctx.set_line_width(kwargs.get('linewidth',1))
198 color = convertColor(color)
199 canvas.ctx.set_source_rgb(*color)
200 dash = (3,3)
201 pts1 = _getLinePoints(p1,p2,dash)
202 pts2 = _getLinePoints(p1,p3,dash)
203
204 if len(pts2)<len(pts1): pts2,pts1=pts1,pts2
205
206 for i in range(len(pts1)):
207 canvas.ctx.move_to(pts1[i][0],pts1[i][1])
208 canvas.ctx.line_to(pts2[i][0],pts2[i][1])
209 canvas.ctx.stroke()
210