Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion lib/matplotlib/backends/backend_cairo.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,18 @@ def _fill_and_stroke(ctx, fill_c, alpha, alpha_overrides):

def draw_path(self, gc, path, transform, rgbFace=None):
# docstring inherited

# Use an isolated blend group if the path blend mode is other than "normal" and
# if more than one of fill/hatch/stroke is active to avoid internal blending
hatch_path = gc.get_hatch_path()
isolate = ((blend_mode := gc.get_blend_mode()) != "normal" and
sum([rgbFace is not None,
hatch_path is not None,
gc.get_linewidth() > 0]) > 1)
if isolate:
self.open_blend_group(blend_mode)
gc.set_blend_mode("normal")

ctx = gc.ctx
# Clip the path to the actual rendering extents if it isn't filled.
clip = (ctx.clip_extents()
Expand All @@ -149,7 +161,6 @@ def draw_path(self, gc, path, transform, rgbFace=None):
_set_rgba(ctx, rgbFace, gc.get_alpha(), gc.get_forced_alpha())
ctx.fill_preserve()
ctx.restore()
hatch_path = gc.get_hatch_path()
if hatch_path:
dpi = int(self.dpi)
hatch_surface = ctx.get_target().create_similar(
Expand All @@ -170,6 +181,9 @@ def draw_path(self, gc, path, transform, rgbFace=None):
ctx.restore()
ctx.stroke()

if isolate:
self.close_blend_group()

def draw_markers(self, gc, marker_path, marker_trans, path, transform,
rgbFace=None):
# docstring inherited
Expand Down
50 changes: 39 additions & 11 deletions lib/matplotlib/backends/backend_pgf.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,15 +437,27 @@ def draw_markers(self, gc, marker_path, marker_trans, path, trans,

def draw_path(self, gc, path, transform, rgbFace=None):
# docstring inherited
_writeln(self.fh, r"\begin{pgfscope}")
# draw the path
self._print_pgf_blend(gc)
self._print_pgf_clip(gc)
self._print_pgf_path_styles(gc, rgbFace)
self._print_pgf_path(gc, path, transform, rgbFace)
self._pgf_path_draw(stroke=gc.get_linewidth() != 0.0,
fill=rgbFace is not None)
_writeln(self.fh, r"\end{pgfscope}")

# Use an isolated blend group if the path blend mode is other than "normal" and
# if more than one of fill/hatch/stroke is active to avoid internal blending
isolate = ((blend_mode := gc.get_blend_mode()) != "normal" and
sum([rgbFace is not None,
gc.get_hatch() is not None,
gc.get_linewidth() > 0]) > 1)
if isolate:
self.open_blend_group(blend_mode)
gc.set_blend_mode("normal")

# draw any fill, and/or draw any stroke if no hatches
if rgbFace is not None or (gc.get_linewidth() != 0.0 and not gc.get_hatch()):
_writeln(self.fh, r"\begin{pgfscope}")
self._print_pgf_blend(gc)
self._print_pgf_clip(gc)
self._print_pgf_path_styles(gc, rgbFace)
self._print_pgf_path(gc, path, transform, rgbFace)
self._pgf_path_draw(stroke=gc.get_linewidth() != 0.0 and not gc.get_hatch(),
fill=rgbFace is not None)
_writeln(self.fh, r"\end{pgfscope}")

# if present, draw pattern on top
if gc.get_hatch():
Expand Down Expand Up @@ -473,14 +485,17 @@ def draw_path(self, gc, path, transform, rgbFace=None):
% hatch_rgba[:3])
_writeln(self.fh, r"\pgfsetstrokecolor{currenthatch}")
_writeln(self.fh, r"\pgfsetstrokeopacity{%f}" % hatch_rgba[3])
_writeln(self.fh, r"\pgfsetdash{}{0pt}")
_writeln(self.fh, r"\pgfsetfillcolor{currenthatch}")
_writeln(self.fh, r"\pgfsetfillopacity{%f}" % hatch_rgba[3])

_writeln(self.fh,
r"\pgfpathrectangle"
r"{\pgfqpoint{0in}{0in}}{\pgfqpoint{1in}{1in}}")
_writeln(self.fh, r"\pgfusepath{clip}")
scale = mpl.transforms.Affine2D().scale(self.dpi)
self._print_pgf_path(None, gc.get_hatch_path(), scale)
self._pgf_path_draw(stroke=True)
self._pgf_path_draw(stroke=True, fill=True)
_writeln(self.fh, r"\end{pgfscope}")
_writeln(self.fh, r"}")
# repeat pattern, filling the bounding rect of the path
Expand All @@ -501,6 +516,19 @@ def draw_path(self, gc, path, transform, rgbFace=None):

_writeln(self.fh, r"\end{pgfscope}")

# draw any stroke on top of hatches
if (gc.get_linewidth() != 0.0):
_writeln(self.fh, r"\begin{pgfscope}")
self._print_pgf_blend(gc)
self._print_pgf_clip(gc)
self._print_pgf_path_styles(gc, rgbFace)
self._print_pgf_path(gc, path, transform, rgbFace)
self._pgf_path_draw(stroke=True, fill=False)
_writeln(self.fh, r"\end{pgfscope}")

if isolate:
self.close_blend_group()

def _print_pgf_blend(self, gc):
if (blend_mode := gc.get_blend_mode()) not in _BlendModePDFSpec:
_log.warning(f"The '{blend_mode}' blend mode is not supported by the "
Expand Down Expand Up @@ -648,7 +676,7 @@ def _print_pgf_path(self, gc, path, transform, rgbFace=None):
_writeln(self.fh, f"\\pgfmathsetseed{{{int(randomness)}}}")
_writeln(self.fh, r"\pgfdecoratecurrentpath{random steps}")

def _pgf_path_draw(self, stroke=True, fill=False):
def _pgf_path_draw(self, *, stroke, fill):
actions = []
if stroke:
actions.append("stroke")
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading