Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

backend_pgf: clip paths within the backend (fixes #1857) #1858

Merged
merged 1 commit into from Apr 18, 2013
Jump to file or symbol
Failed to load files and symbols.
+31 −7
Split
@@ -421,7 +421,7 @@ def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None)
bl, tr = marker_path.get_extents(marker_trans).get_points()
coords = bl[0] * f, bl[1] * f, tr[0] * f, tr[1] * f
writeln(self.fh, r"\pgfsys@defobject{currentmarker}{\pgfqpoint{%fin}{%fin}}{\pgfqpoint{%fin}{%fin}}{" % coords)
- self._print_pgf_path(marker_path, marker_trans)
+ self._print_pgf_path(None, marker_path, marker_trans)
self._pgf_path_draw(stroke=gc.get_linewidth() != 0.0,
fill=rgbFace is not None)
writeln(self.fh, r"}")
@@ -441,7 +441,7 @@ def draw_path(self, gc, path, transform, rgbFace=None):
# draw the path
self._print_pgf_clip(gc)
self._print_pgf_path_styles(gc, rgbFace)
- self._print_pgf_path(path, transform)
+ self._print_pgf_path(gc, path, transform)
self._pgf_path_draw(stroke=gc.get_linewidth() != 0.0,
fill=rgbFace is not None)
writeln(self.fh, r"\end{pgfscope}")
@@ -452,7 +452,7 @@ def draw_path(self, gc, path, transform, rgbFace=None):
# combine clip and path for clipping
self._print_pgf_clip(gc)
- self._print_pgf_path(path, transform)
+ self._print_pgf_path(gc, path, transform)
writeln(self.fh, r"\pgfusepath{clip}")
# build pattern definition
@@ -461,7 +461,7 @@ def draw_path(self, gc, path, transform, rgbFace=None):
writeln(self.fh, r"\pgfpathrectangle{\pgfqpoint{0in}{0in}}{\pgfqpoint{1in}{1in}}")
writeln(self.fh, r"\pgfusepath{clip}")
scale = mpl.transforms.Affine2D().scale(self.dpi)
- self._print_pgf_path(gc.get_hatch_path(), scale)
+ self._print_pgf_path(None, gc.get_hatch_path(), scale)
self._pgf_path_draw(stroke=True)
writeln(self.fh, r"\end{pgfscope}")
writeln(self.fh, r"}")
@@ -495,7 +495,7 @@ def _print_pgf_clip(self, gc):
# check for clip path
clippath, clippath_trans = gc.get_clip_path()
if clippath is not None:
- self._print_pgf_path(clippath, clippath_trans)
+ self._print_pgf_path(gc, clippath, clippath_trans)
writeln(self.fh, r"\pgfusepath{clip}")
def _print_pgf_path_styles(self, gc, rgbFace):
@@ -543,10 +543,17 @@ def _print_pgf_path_styles(self, gc, rgbFace):
dash_str += r"}{%fpt}" % dash_offset
writeln(self.fh, dash_str)
- def _print_pgf_path(self, path, transform):
+ def _print_pgf_path(self, gc, path, transform):
f = 1. / self.dpi
+ # check for clip box
+ bbox = gc.get_clip_rectangle() if gc else None
+ if bbox:
+ p1, p2 = bbox.get_points()
+ clip = (p1[0], p1[1], p2[0], p2[1])
+ else:
+ clip = None
# build path
- for points, code in path.iter_segments(transform):
+ for points, code in path.iter_segments(transform, clip=clip):
if code == Path.MOVETO:
x, y = tuple(points)
writeln(self.fh, r"\pgfpathmoveto{\pgfqpoint{%fin}{%fin}}" %
@@ -75,3 +75,5 @@ def _check_output(*popenargs, **kwargs):
check_output = subprocess.check_output
else:
check_output = _check_output
+
+CalledProcessError = subprocess.CalledProcessError
@@ -130,6 +130,21 @@ def test_rcupdate():
create_figure()
compare_figure('pgf_rcupdate%d.pdf' % (i+1))
+
+# test backend-side clipping, since large numbers are not supported by TeX
+@switch_backend('pgf')
+def test_pathclip():
+ if not check_for('xelatex'):
+ raise SkipTest('xelatex + pgf is required')
+
+ plt.figure()
+ plt.plot([0., 1e100], [0., 1e100])
+ plt.xlim(0, 1)
+ plt.ylim(0, 1)
+ # this test passes if compiling/saving to pdf works (no image comparison)
+ plt.savefig(os.path.join(result_dir, "pgf_pathclip.pdf"))
+
+
if __name__ == '__main__':
import nose
nose.runmodule(argv=['-s','--with-doctest'], exit=False)