Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c551a41

Browse files
committed
Fix bug in Cairo backend related to clipping -- thanks Nathaniel Smith
svn path=/branches/v0_98_5_maint/; revision=6997
1 parent a69d5b9 commit c551a41

File tree

1 file changed

+29
-23
lines changed

1 file changed

+29
-23
lines changed

lib/matplotlib/backends/backend_cairo.py

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,23 @@ def set_width_height(self, width, height):
109109
# font transform?
110110

111111

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+
112129
def _fill_and_stroke (self, ctx, fill_c, alpha):
113130
if fill_c is not None:
114131
ctx.save()
@@ -120,7 +137,6 @@ def _fill_and_stroke (self, ctx, fill_c, alpha):
120137
ctx.restore()
121138
ctx.stroke()
122139

123-
124140
#@staticmethod
125141
def convert_path(ctx, tpath):
126142
for points, code in tpath.iter_segments():
@@ -144,6 +160,9 @@ def draw_path(self, gc, path, transform, rgbFace=None):
144160
raise ValueError("The Cairo backend can not draw paths longer than 18980 points.")
145161

146162
ctx = gc.ctx
163+
ctx.save()
164+
self._do_clip(ctx, gc._cliprect, gc._clippath)
165+
147166
transform = transform + \
148167
Affine2D().scale(1.0, -1.0).translate(0, self.height)
149168
tpath = transform.transform_path(path)
@@ -152,6 +171,7 @@ def draw_path(self, gc, path, transform, rgbFace=None):
152171
self.convert_path(ctx, tpath)
153172

154173
self._fill_and_stroke(ctx, rgbFace, gc.get_alpha())
174+
ctx.restore()
155175

156176
def draw_image(self, x, y, im, bbox, clippath=None, clippath_trans=None):
157177
# bbox - not currently used
@@ -164,9 +184,16 @@ def draw_image(self, x, y, im, bbox, clippath=None, clippath_trans=None):
164184
buf, cairo.FORMAT_ARGB32, cols, rows, cols*4)
165185
# function does not pass a 'gc' so use renderer.ctx
166186
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()
167193
y = self.height - y - rows
168194
ctx.set_source_surface (surface, x, y)
169195
ctx.paint()
196+
ctx.restore()
170197

171198
im.flipud_out()
172199

@@ -324,30 +351,9 @@ def set_capstyle(self, cs):
324351

325352
def set_clip_rectangle(self, rectangle):
326353
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-
340354

341355
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
351357

352358
def set_dashes(self, offset, dashes):
353359
self._dashes = offset, dashes

0 commit comments

Comments
 (0)