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

Skip to content

Commit bcee01f

Browse files
authored
Merge pull request #27856 from anntzer/ch
Support hatching in cairo backends.
2 parents 72731a5 + 8fc0ba4 commit bcee01f

File tree

1 file changed

+42
-13
lines changed

1 file changed

+42
-13
lines changed

lib/matplotlib/backends/backend_cairo.py

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@
3434
from matplotlib.transforms import Affine2D
3535

3636

37+
def _set_rgba(ctx, color, alpha, forced_alpha):
38+
if len(color) == 3 or forced_alpha:
39+
ctx.set_source_rgba(*color[:3], alpha)
40+
else:
41+
ctx.set_source_rgba(*color)
42+
43+
3744
def _append_path(ctx, path, transform, clip=None):
3845
for points, code in path.iter_segments(
3946
transform, remove_nans=True, clip=clip):
@@ -100,13 +107,11 @@ def set_context(self, ctx):
100107
self.gc.ctx = ctx
101108
self.width, self.height = size
102109

103-
def _fill_and_stroke(self, ctx, fill_c, alpha, alpha_overrides):
110+
@staticmethod
111+
def _fill_and_stroke(ctx, fill_c, alpha, alpha_overrides):
104112
if fill_c is not None:
105113
ctx.save()
106-
if len(fill_c) == 3 or alpha_overrides:
107-
ctx.set_source_rgba(fill_c[0], fill_c[1], fill_c[2], alpha)
108-
else:
109-
ctx.set_source_rgba(fill_c[0], fill_c[1], fill_c[2], fill_c[3])
114+
_set_rgba(ctx, fill_c, alpha, alpha_overrides)
110115
ctx.fill_preserve()
111116
ctx.restore()
112117
ctx.stroke()
@@ -122,8 +127,31 @@ def draw_path(self, gc, path, transform, rgbFace=None):
122127
+ Affine2D().scale(1, -1).translate(0, self.height))
123128
ctx.new_path()
124129
_append_path(ctx, path, transform, clip)
125-
self._fill_and_stroke(
126-
ctx, rgbFace, gc.get_alpha(), gc.get_forced_alpha())
130+
if rgbFace is not None:
131+
ctx.save()
132+
_set_rgba(ctx, rgbFace, gc.get_alpha(), gc.get_forced_alpha())
133+
ctx.fill_preserve()
134+
ctx.restore()
135+
hatch_path = gc.get_hatch_path()
136+
if hatch_path:
137+
dpi = int(self.dpi)
138+
hatch_surface = ctx.get_target().create_similar(
139+
cairo.Content.COLOR_ALPHA, dpi, dpi)
140+
hatch_ctx = cairo.Context(hatch_surface)
141+
_append_path(hatch_ctx, hatch_path,
142+
Affine2D().scale(dpi, -dpi).translate(0, dpi),
143+
None)
144+
hatch_ctx.set_line_width(self.points_to_pixels(gc.get_hatch_linewidth()))
145+
hatch_ctx.set_source_rgba(*gc.get_hatch_color())
146+
hatch_ctx.fill_preserve()
147+
hatch_ctx.stroke()
148+
hatch_pattern = cairo.SurfacePattern(hatch_surface)
149+
hatch_pattern.set_extend(cairo.Extend.REPEAT)
150+
ctx.save()
151+
ctx.set_source(hatch_pattern)
152+
ctx.fill_preserve()
153+
ctx.restore()
154+
ctx.stroke()
127155

128156
def draw_markers(self, gc, marker_path, marker_trans, path, transform,
129157
rgbFace=None):
@@ -267,8 +295,13 @@ def get_text_width_height_descent(self, s, prop, ismath):
267295
def new_gc(self):
268296
# docstring inherited
269297
self.gc.ctx.save()
298+
# FIXME: The following doesn't properly implement a stack-like behavior
299+
# and relies instead on the (non-guaranteed) fact that artists never
300+
# rely on nesting gc states, so directly resetting the attributes (IOW
301+
# a single-level stack) is enough.
270302
self.gc._alpha = 1
271303
self.gc._forced_alpha = False # if True, _alpha overrides A from RGBA
304+
self.gc._hatch = None
272305
return self.gc
273306

274307
def points_to_pixels(self, points):
@@ -298,12 +331,8 @@ def restore(self):
298331

299332
def set_alpha(self, alpha):
300333
super().set_alpha(alpha)
301-
_alpha = self.get_alpha()
302-
rgb = self._rgb
303-
if self.get_forced_alpha():
304-
self.ctx.set_source_rgba(rgb[0], rgb[1], rgb[2], _alpha)
305-
else:
306-
self.ctx.set_source_rgba(rgb[0], rgb[1], rgb[2], rgb[3])
334+
_set_rgba(
335+
self.ctx, self._rgb, self.get_alpha(), self.get_forced_alpha())
307336

308337
def set_antialiased(self, b):
309338
self.ctx.set_antialias(

0 commit comments

Comments
 (0)