diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index f1560bf6dcf0..2711b3228f1d 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -454,8 +454,7 @@ def _iter_collection(self, gc, master_transform, all_transforms, if Noffsets: toffsets = offsetTrans.transform(offsets) - gc0 = self.new_gc() - gc0.copy_properties(gc) + gc0 = self.new_gc_copy(gc) if Nfacecolors == 0: rgbFace = None @@ -715,6 +714,11 @@ def new_gc(self): """ return GraphicsContextBase() + def new_gc_copy(self, gc): + gc0 = self.new_gc() + gc0.copy_properties(gc) + return gc0 + def points_to_pixels(self, points): """ Convert points to display units diff --git a/lib/matplotlib/backends/backend_macosx.py b/lib/matplotlib/backends/backend_macosx.py index 3aa17977ee51..2b21b494fe87 100755 --- a/lib/matplotlib/backends/backend_macosx.py +++ b/lib/matplotlib/backends/backend_macosx.py @@ -55,7 +55,13 @@ def draw_path(self, gc, path, transform, rgbFace=None): if rgbFace is not None: rgbFace = tuple(rgbFace) linewidth = gc.get_linewidth() - gc.draw_path(path, transform, linewidth, rgbFace) + sketch_params = gc.get_sketch_params() + if sketch_params is not None: + args = sketch_params + else: + args = () + gc.draw_path(path, transform, linewidth, rgbFace, + *args) def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None): if rgbFace is not None: @@ -98,10 +104,27 @@ def draw_quad_mesh(self, gc, master_transform, meshWidth, meshHeight, def new_gc(self): self.gc.save() self.gc.set_hatch(None) + self.gc._sketch = None self.gc._alpha = 1.0 self.gc._forced_alpha = False # if True, _alpha overrides A from RGBA return self.gc + def new_gc_copy(self, gc): + # The Mac OSX backend has a stateful GraphicsContext stack, + # which is different from the other backends. Since the + # new_gc is always the same as the old one, we need to + # override this special function to make sure the old state is + # copied correctly when we want a copy of the previous state. + orig_sketch = gc.get_sketch_params() + orig_hatch = gc.get_hatch() + gc0 = self.new_gc() + gc0.copy_properties(gc) + if orig_sketch is not None: + gc0.set_sketch_params(*orig_sketch) + if orig_hatch is not None: + gc0.set_hatch(orig_hatch) + return gc0 + def draw_gouraud_triangle(self, gc, points, colors, transform): points = transform.transform(points) gc.draw_gouraud_triangle(points, colors) @@ -229,6 +252,7 @@ def set_clip_path(self, path): _macosx.GraphicsContext.set_clip_path(self, path) + ######################################################################## # # The following functions and classes are for pylab and implement diff --git a/lib/matplotlib/backends/backend_mixed.py b/lib/matplotlib/backends/backend_mixed.py index a783b9798177..b62c62907f18 100644 --- a/lib/matplotlib/backends/backend_mixed.py +++ b/lib/matplotlib/backends/backend_mixed.py @@ -62,12 +62,12 @@ def __init__(self, figure, width, height, dpi, vector_renderer, close_group draw_image draw_markers draw_path draw_path_collection draw_quad_mesh draw_tex draw_text finalize flipy get_canvas_width_height get_image_magnification - get_texmanager get_text_width_height_descent new_gc open_group - option_image_nocomposite points_to_pixels strip_math - start_filter stop_filter draw_gouraud_triangle - draw_gouraud_triangles option_scale_image - _text2path _get_text_path_transform height width - """.split() + get_texmanager get_text_width_height_descent new_gc + new_gc_copy open_group option_image_nocomposite + points_to_pixels strip_math start_filter stop_filter + draw_gouraud_triangle draw_gouraud_triangles + option_scale_image _text2path _get_text_path_transform height + width """.split() def _set_current_renderer(self, renderer): self._renderer = renderer diff --git a/lib/matplotlib/patheffects.py b/lib/matplotlib/patheffects.py index 5435bcc8bd00..6a2bf11804c2 100644 --- a/lib/matplotlib/patheffects.py +++ b/lib/matplotlib/patheffects.py @@ -192,9 +192,7 @@ def draw_path(self, renderer, gc, tpath, affine, rgbFace): """ # Do not modify the input! Use copy instead. - gc0 = renderer.new_gc() - gc0.copy_properties(gc) - + gc0 = renderer.new_gc_copy(gc) gc0 = self._update_gc(gc0, self._gc) trans = self._offset_transform(renderer, affine) renderer.draw_path(gc0, tpath, trans, rgbFace) @@ -264,8 +262,8 @@ def draw_path(self, renderer, gc, tpath, affine, rgbFace): """ # IMPORTANT: Do not modify the input - we copy everything instead. affine0 = self._offset_transform(renderer, affine) - gc0 = renderer.new_gc() - gc0.copy_properties(gc) + orig_sketch = gc.get_sketch_params() + gc0 = renderer.new_gc_copy(gc) if self._shadow_rgbFace is None: r,g,b = (rgbFace or (1., 1., 1.))[:3] @@ -341,8 +339,7 @@ def draw_path(self, renderer, gc, tpath, affine, rgbFace): """ # IMPORTANT: Do not modify the input - we copy everything instead. affine0 = self._offset_transform(renderer, affine) - gc0 = renderer.new_gc() - gc0.copy_properties(gc) + gc0 = renderer.new_gc_copy(gc) if self._shadow_color is None: r,g,b = (gc0.get_foreground() or (1., 1., 1.))[:3] diff --git a/src/_macosx.m b/src/_macosx.m index 10f6eb1e2550..70128683426e 100644 --- a/src/_macosx.m +++ b/src/_macosx.m @@ -351,6 +351,9 @@ static void _draw_hatch(void *info, CGContextRef cr) rect, SNAP_FALSE, 1.0, + 0, + 0, + 0, 0); Py_DECREF(transform); if (!iterator) @@ -743,6 +746,9 @@ static int _get_snap(GraphicsContext* self, enum e_snap_mode* mode) rect, SNAP_AUTO, 1.0, + 0, + 0, + 0, 0); Py_DECREF(transform); if (!iterator) @@ -971,8 +977,11 @@ static int _get_snap(GraphicsContext* self, enum e_snap_mode* mode) { PyObject* path; PyObject* transform; - PyObject* rgbFace; + PyObject* rgbFace = NULL; float linewidth; + double sketch_scale = 0; + double sketch_length = 0; + double sketch_randomness = 0; int n; @@ -987,11 +996,14 @@ static int _get_snap(GraphicsContext* self, enum e_snap_mode* mode) return NULL; } - if(!PyArg_ParseTuple(args, "OOf|O", + if(!PyArg_ParseTuple(args, "OOf|Oddd", &path, &transform, &linewidth, - &rgbFace)) return NULL; + &rgbFace, + &sketch_scale, + &sketch_length, + &sketch_randomness)) return NULL; if(rgbFace==Py_None) rgbFace = NULL; @@ -1002,7 +1014,10 @@ static int _get_snap(GraphicsContext* self, enum e_snap_mode* mode) rect, SNAP_AUTO, linewidth, - rgbFace == NULL); + rgbFace == NULL, + sketch_scale, + sketch_length, + sketch_randomness); if (!iterator) { PyErr_SetString(PyExc_RuntimeError, @@ -1094,6 +1109,9 @@ static int _get_snap(GraphicsContext* self, enum e_snap_mode* mode) rect, SNAP_AUTO, linewidth, + 0, + 0, + 0, 0); if (!iterator) { @@ -1175,6 +1193,9 @@ static int _get_snap(GraphicsContext* self, enum e_snap_mode* mode) rect, mode, linewidth, + 0, + 0, + 0, 0); if (!iterator) { @@ -1197,6 +1218,9 @@ static int _get_snap(GraphicsContext* self, enum e_snap_mode* mode) rect, SNAP_TRUE, 1.0, + 0, + 0, + 0, 0); if (!iterator) { @@ -1504,6 +1528,9 @@ static int _transformation_converter(PyObject* object, void* pointer) practice, so this hardcoding is probably ok for now. -- MGD */ + 0, + 0, + 0, 0); if (!iterator) { diff --git a/src/path_cleanup.cpp b/src/path_cleanup.cpp index 7951cfd9cef5..f54a93d93861 100644 --- a/src/path_cleanup.cpp +++ b/src/path_cleanup.cpp @@ -58,7 +58,7 @@ class PathCleanupIterator unsigned vertex(double *x, double *y) { - return m_simplify.vertex(x, y); + return m_sketch.vertex(x, y); } }; @@ -81,17 +81,18 @@ void *get_path_iterator(PyObject *path, } agg::rect_base clip_rect(rect[0], rect[1], rect[2], rect[3]); - PathCleanupIterator *pipeline = new PathCleanupIterator(path, - agg_trans, - remove_nans != 0, - do_clip != 0, - clip_rect, - snap_mode, - stroke_width, - do_simplify != 0, - sketch_scale, - sketch_length, - sketch_randomness); + PathCleanupIterator *pipeline = new PathCleanupIterator( + path, + agg_trans, + remove_nans != 0, + do_clip != 0, + clip_rect, + snap_mode, + stroke_width, + do_simplify != 0, + sketch_scale, + sketch_length, + sketch_randomness); return (void *)pipeline; } diff --git a/src/path_cleanup.h b/src/path_cleanup.h index b481395aa54e..446bb523f49c 100644 --- a/src/path_cleanup.h +++ b/src/path_cleanup.h @@ -18,7 +18,10 @@ void *get_path_iterator(PyObject *path, double rect[4], enum e_snap_mode snap_mode, double stroke_width, - int do_simplify); + int do_simplify, + double sketch_scale, + double sketch_lenth, + double sketch_randomness); unsigned get_vertex(void *pipeline, double *x, double *y);