@@ -109,6 +109,23 @@ def set_width_height(self, width, height):
109
109
# font transform?
110
110
111
111
112
+ def _do_clip(self, ctx, cliprect, clippath):
113
+ if cliprect is not None:
114
+ x,y,w,h = cliprect.bounds
115
+ # pixel-aligned clip-regions are faster
116
+ x,y,w,h = round(x), round(y), round(w), round(h)
117
+ ctx.new_path()
118
+ ctx.rectangle (x, self.height - h - y, w, h)
119
+ ctx.clip ()
120
+
121
+ if clippath is not None:
122
+ tpath, affine = clippath.get_transformed_path_and_affine()
123
+ ctx.new_path()
124
+ affine = affine + Affine2D().scale(1.0, -1.0).translate(0.0, self.height)
125
+ tpath = affine.transform_path(tpath)
126
+ RendererCairo.convert_path(ctx, tpath)
127
+ ctx.clip()
128
+
112
129
def _fill_and_stroke (self, ctx, fill_c, alpha):
113
130
if fill_c is not None:
114
131
ctx.save()
@@ -120,7 +137,6 @@ def _fill_and_stroke (self, ctx, fill_c, alpha):
120
137
ctx.restore()
121
138
ctx.stroke()
122
139
123
-
124
140
#@staticmethod
125
141
def convert_path(ctx, tpath):
126
142
for points, code in tpath.iter_segments():
@@ -144,6 +160,9 @@ def draw_path(self, gc, path, transform, rgbFace=None):
144
160
raise ValueError("The Cairo backend can not draw paths longer than 18980 points.")
145
161
146
162
ctx = gc.ctx
163
+ ctx.save()
164
+ self._do_clip(ctx, gc._cliprect, gc._clippath)
165
+
147
166
transform = transform + \
148
167
Affine2D().scale(1.0, -1.0).translate(0, self.height)
149
168
tpath = transform.transform_path(path)
@@ -152,6 +171,7 @@ def draw_path(self, gc, path, transform, rgbFace=None):
152
171
self.convert_path(ctx, tpath)
153
172
154
173
self._fill_and_stroke(ctx, rgbFace, gc.get_alpha())
174
+ ctx.restore()
155
175
156
176
def draw_image(self, x, y, im, bbox, clippath=None, clippath_trans=None):
157
177
# bbox - not currently used
@@ -164,9 +184,16 @@ def draw_image(self, x, y, im, bbox, clippath=None, clippath_trans=None):
164
184
buf, cairo.FORMAT_ARGB32, cols, rows, cols*4)
165
185
# function does not pass a 'gc' so use renderer.ctx
166
186
ctx = self.ctx
187
+ ctx.save()
188
+ if clippath is not None:
189
+ tpath = clippath_trans.transform_path(clippath)
190
+ ctx.new_path()
191
+ RendererCairo.convert_path(ctx, tpath)
192
+ ctx.clip()
167
193
y = self.height - y - rows
168
194
ctx.set_source_surface (surface, x, y)
169
195
ctx.paint()
196
+ ctx.restore()
170
197
171
198
im.flipud_out()
172
199
@@ -324,30 +351,9 @@ def set_capstyle(self, cs):
324
351
325
352
def set_clip_rectangle(self, rectangle):
326
353
self._cliprect = rectangle
327
- if rectangle is None:
328
- return
329
-
330
- x,y,w,h = rectangle.bounds
331
- # pixel-aligned clip-regions are faster
332
- x,y,w,h = round(x), round(y), round(w), round(h)
333
- ctx = self.ctx
334
- ctx.new_path()
335
- ctx.rectangle (x, self.renderer.height - h - y, w, h)
336
- ctx.clip ()
337
- # Alternative: just set _cliprect here and actually set cairo clip rect
338
- # in fill_and_stroke() inside ctx.save() ... ctx.restore()
339
-
340
354
341
355
def set_clip_path(self, path):
342
- if path is not None:
343
- tpath, affine = path.get_transformed_path_and_affine()
344
- ctx = self.ctx
345
- ctx.new_path()
346
- affine = affine + Affine2D().scale(1.0, -1.0).translate(0.0, self.renderer.height)
347
- tpath = affine.transform_path(tpath)
348
- RendererCairo.convert_path(ctx, tpath)
349
- ctx.clip()
350
-
356
+ self._clippath = path
351
357
352
358
def set_dashes(self, offset, dashes):
353
359
self._dashes = offset, dashes
0 commit comments