144 | | |
145 | | # Define a different base class depending on the platform. |
146 | | |
147 | | if sys.platform == 'darwin': |
148 | | from mac import get_macport, ABCGI |
149 | | from mac.ABCGI import CGBitmapContext, CGImage, CGImageFile, \ |
150 | | CGLayerContext, CGMutablePath |
151 | | |
152 | | # The Mac backend only supports numpy. |
153 | | import numpy as np |
154 | | |
155 | | if wx.VERSION[:2] == (2, 6): |
156 | | def gc_for_dc(dc): |
157 | | """ Return the CGContext corresponding to the given wx.DC. |
158 | | """ |
159 | | port = get_macport(dc) |
160 | | return ABCGI.CGContextForPort(port) |
161 | | |
162 | | elif wx.VERSION[:2] == (2, 8): |
163 | | class UnflippingCGContext(ABCGI.CGContextInABox): |
164 | | """ Vertically flip the context to undo wx's flipping. |
165 | | """ |
166 | | |
167 | | def __init__(self, *args, **kwds): |
168 | | ABCGI.CGContextInABox.__init__(self, *args, **kwds) |
169 | | self._begun = False |
170 | | |
171 | | def begin(self): |
172 | | if self._begun: |
173 | | return |
174 | | self.save_state() |
175 | | self.translate_ctm(0, self.height()) |
176 | | self.scale_ctm(1.0, -1.0) |
177 | | self._begun = True |
178 | | |
179 | | def end(self): |
180 | | if self._begun: |
181 | | self.restore_state() |
182 | | self._begun = False |
183 | | |
184 | | def gc_for_dc(dc): |
185 | | """ Return the CGContext corresponding to the given wx.DC. |
186 | | """ |
187 | | pointer = get_macport(dc) |
188 | | gc = UnflippingCGContext(pointer, dc.GetSizeTuple()) |
189 | | return gc |
190 | | |
191 | | |
192 | | CompiledPath = CGMutablePath |
193 | | Image = CGImageFile |
194 | | |
195 | | class GraphicsContext(CGLayerContext): |
196 | | def __init__(self, size_or_array, window_gc=None, *args, **kwds): |
197 | | gc = window_gc |
198 | | if not gc: |
199 | | # Create a tiny base context to spawn the CGLayerContext from. |
200 | | # We are better off making our Layer from the window gc since |
201 | | # the data formats will match and so it will be faster to draw the |
202 | | # layer. |
203 | | gc = CGBitmapContext((1,1)) |
204 | | if isinstance(size_or_array, np.ndarray): |
205 | | # Initialize the layer with an image. |
206 | | image = CGImage(size_or_array) |
207 | | width = image.width |
208 | | height = image.height |
209 | | else: |
210 | | # No initialization. |
211 | | image = None |
212 | | width, height = size_or_array |
213 | | CGLayerContext.__init__(self, gc, |
214 | | (width, height)) |
215 | | if image is not None: |
216 | | self.draw_image(image) |
217 | | |
218 | | @classmethod |
219 | | def create_from_gc(klass, gc, size_or_array, *args, **kwds): |
220 | | return klass(size_or_array, gc, *args, **kwds) |
221 | | |
222 | | class Canvas(BaseWxCanvas, WidgetClass): |
223 | | """ Mac wx Kiva canvas. |
224 | | """ |
225 | | def __init__(self, parent, id = 01, size = wx.DefaultSize): |
226 | | # need to init self.memDC before calling BaseWxCanvas.__init__ |
227 | | self.memDC = wx.MemoryDC() |
228 | | self._size = (size.GetWidth(), size.GetHeight()) |
229 | | WidgetClass.__init__(self, parent, id, wx.Point(0, 0), size, |
230 | | wx.SUNKEN_BORDER | wx.WANTS_CHARS | \ |
231 | | wx.FULL_REPAINT_ON_RESIZE ) |
232 | | BaseWxCanvas.__init__(self) |
233 | | return |
234 | | |
235 | | def _create_kiva_gc(self, size): |
236 | | self._size = size |
237 | | self.bitmap = wx.EmptyBitmap(size[0], size[1]) |
238 | | self.memDC.SelectObject(self.bitmap) |
239 | | gc = gc_for_dc(self.memDC) |
240 | | #gc.begin() |
241 | | #print " **** gc is:", gc |
242 | | return gc |
243 | | |
244 | | def blit(self, event): |
245 | | t1 = now() |
246 | | paintdc = wx.PaintDC(self) |
247 | | paintdc.Blit(0, 0, self._size[0], self._size[1], |
248 | | self.memDC, 0, 0) |
249 | | t2 = now() |
250 | | self.blit_time = t2 - t1 |
251 | | self.dirty = 0 |
252 | | return |
253 | | |
254 | | def draw(self): |
255 | | t1 = now() |
256 | | self.gc.begin() |
257 | | self.do_draw(self.gc) |
258 | | self.gc.end() |
259 | | t2 = now() |
260 | | self.draw_time = t2-t1 |
261 | | return |
262 | | |
263 | | |
264 | | else: |
265 | | # the GraphicsContextSystem stuff should eventually be moved out of the |
266 | | # image backend. |
267 | | from backend_image import GraphicsContextSystem as GraphicsContext |
268 | | from agg import CompiledPath |
269 | | |
270 | | class Canvas(BaseWxCanvas, WidgetClass): |
271 | | "The basic wx Kiva canvas." |
272 | | def __init__(self, parent, id = -1, size = wx.DefaultSize): |
273 | | WidgetClass.__init__(self, parent, id, wx.Point(0, 0), size, |
274 | | wx.SUNKEN_BORDER | wx.WANTS_CHARS | \ |
275 | | wx.FULL_REPAINT_ON_RESIZE ) |
276 | | BaseWxCanvas.__init__(self) |
277 | | return |
| 144 | # the GraphicsContextSystem stuff should eventually be moved out of the |
| 145 | # image backend. |
| 146 | from backend_image import GraphicsContextSystem as GraphicsContext |
| 147 | from agg import CompiledPath |
| 148 | |
| 149 | class Canvas(BaseWxCanvas, WidgetClass): |
| 150 | "The basic wx Kiva canvas." |
| 151 | def __init__(self, parent, id = -1, size = wx.DefaultSize): |
| 152 | WidgetClass.__init__(self, parent, id, wx.Point(0, 0), size, |
| 153 | wx.SUNKEN_BORDER | wx.WANTS_CHARS | |
| 154 | wx.FULL_REPAINT_ON_RESIZE ) |
| 155 | BaseWxCanvas.__init__(self) |
| 156 | return |