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

Skip to content

Commit 1738309

Browse files
committed
impl hatch styles in PDF backend
1 parent 6c6ff72 commit 1738309

File tree

4 files changed

+45
-8
lines changed

4 files changed

+45
-8
lines changed

lib/matplotlib/backend_bases.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ class RendererBase:
149149
* `draw_path_collection`
150150
* `draw_quad_mesh`
151151
"""
152+
153+
hatchstyles_enabled = False
154+
152155
def __init__(self):
153156
super().__init__()
154157
self._texmanager = None

lib/matplotlib/backends/backend_agg.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,6 @@ class RendererAgg(RendererBase):
5959
The renderer handles all the drawing primitives using a graphics
6060
context instance that controls the colors/styles
6161
"""
62-
hatchstyles_enabled = False
63-
6462
def __init__(self, width, height, dpi):
6563
super().__init__()
6664

lib/matplotlib/backends/backend_pdf.py

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1541,6 +1541,17 @@ def hatchPattern(self, hatch_style):
15411541
face = tuple(face)
15421542
hatch_style = (edge, face, hatch, lw)
15431543

1544+
if isinstance(hatch, list):
1545+
hatch_tuple = tuple(tuple(h.items()) for h in hatch)
1546+
hatch_style = (edge, face, hatch_tuple, lw)
1547+
pattern = self._hatch_patterns.get(hatch_style, None)
1548+
if pattern is not None:
1549+
return pattern
1550+
1551+
name = next(self._hatch_pattern_seq)
1552+
self._hatch_patterns[hatch_style] = name
1553+
return name
1554+
15441555
pattern = self._hatch_patterns.get(hatch_style, None)
15451556
if pattern is not None:
15461557
return pattern
@@ -1557,6 +1568,18 @@ def writeHatches(self):
15571568
hatchDict = dict()
15581569
sidelen = 72.0
15591570
for hatch_style, name in self._hatch_patterns.items():
1571+
stroke_rgb, fill_rgb, hatch, lw = hatch_style
1572+
filled = True
1573+
if isinstance(hatch, tuple):
1574+
custom_hatch = [dict(h) for h in hatch]
1575+
hatch_buffer_scale = custom_hatch[0].get('hatch_buffer_scale', 1.0)
1576+
sidelen = 72.0 * hatch_buffer_scale
1577+
path = Path.hatchstyle(custom_hatch)
1578+
else:
1579+
sidelen = 72.0
1580+
path = Path.hatch(hatch)
1581+
filled = filled and all(h not in '|-/\\+xX' for h in hatch)
1582+
15601583
ob = self.reserveObject('hatch pattern')
15611584
hatchDict[name] = ob
15621585
res = {'Procsets':
@@ -1571,7 +1594,6 @@ def writeHatches(self):
15711594
# Change origin to match Agg at top-left.
15721595
'Matrix': [1, 0, 0, 1, 0, self.height * 72]})
15731596

1574-
stroke_rgb, fill_rgb, hatch, lw = hatch_style
15751597
self.output(stroke_rgb[0], stroke_rgb[1], stroke_rgb[2],
15761598
Op.setrgb_stroke)
15771599
if fill_rgb is not None:
@@ -1583,9 +1605,12 @@ def writeHatches(self):
15831605
self.output(lw, Op.setlinewidth)
15841606

15851607
self.output(*self.pathOperations(
1586-
Path.hatch(hatch),
1608+
path,
15871609
Affine2D().scale(sidelen),
15881610
simplify=False))
1611+
if filled:
1612+
self.output(stroke_rgb[0], stroke_rgb[1], stroke_rgb[2],
1613+
Op.setrgb_nonstroke)
15891614
self.output(Op.fill_stroke)
15901615

15911616
self.endStream()
@@ -1954,6 +1979,9 @@ def __init__(self, file, image_dpi, height, width):
19541979
self.file = file
19551980
self.gc = self.new_gc()
19561981
self.image_dpi = image_dpi
1982+
self.hatch_buffer_scale = (
1983+
(max(self.width, self.height)) if RendererPdf.hatchstyles_enabled else 1.0
1984+
)
19571985

19581986
def finalize(self):
19591987
self.file.output(*self.gc.finalize())
@@ -2020,6 +2048,7 @@ def draw_image(self, gc, x, y, im, transform=None):
20202048

20212049
def draw_path(self, gc, path, transform, rgbFace=None):
20222050
# docstring inherited
2051+
gc.set_hatch_buffer_scale(self.hatch_buffer_scale)
20232052
self.check_gc(gc, rgbFace)
20242053
self.file.writePath(
20252054
path, transform,
@@ -2511,13 +2540,20 @@ def alpha_cmd(self, alpha, forced, effective_alphas):
25112540
name = self.file.alphaState(effective_alphas)
25122541
return [name, Op.setgstate]
25132542

2514-
def hatch_cmd(self, hatch, hatch_color, hatch_linewidth):
2515-
if not hatch:
2543+
def hatch_cmd(self, hatch, hatch_color, hatch_linewidth, custom_hatch):
2544+
if not (hatch or len(custom_hatch)):
25162545
if self._fillcolor is not None:
25172546
return self.fillcolor_cmd(self._fillcolor)
25182547
else:
25192548
return [Name('DeviceRGB'), Op.setcolorspace_nonstroke]
25202549
else:
2550+
if len(custom_hatch):
2551+
hatch_style = (hatch_color, self._fillcolor,
2552+
custom_hatch, hatch_linewidth)
2553+
name = self.file.hatchPattern(hatch_style)
2554+
return [Name('Pattern'), Op.setcolorspace_nonstroke,
2555+
name, Op.setcolor_nonstroke]
2556+
25212557
hatch_style = (hatch_color, self._fillcolor, hatch, hatch_linewidth)
25222558
name = self.file.hatchPattern(hatch_style)
25232559
return [Name('Pattern'), Op.setcolorspace_nonstroke,
@@ -2583,7 +2619,7 @@ def clip_cmd(self, cliprect, clippath):
25832619
(('_dashes',), dash_cmd),
25842620
(('_rgb',), rgb_cmd),
25852621
# must come after fillcolor and rgb
2586-
(('_hatch', '_hatch_color', '_hatch_linewidth'), hatch_cmd),
2622+
(('_hatch', '_hatch_color', '_hatch_linewidth', '_hatchstyle'), hatch_cmd),
25872623
)
25882624

25892625
def delta(self, other):

lib/matplotlib/patches.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ def set_hatchstyle(self, hatchstyle):
610610
if hatchstyle is None:
611611
hatchstyle = []
612612
else:
613-
mpl.backends.backend_agg.RendererAgg.hatchstyles_enabled = True
613+
mpl.backend_bases.RendererBase.hatchstyles_enabled = True
614614
if not isinstance(hatchstyle, list):
615615
hatchstyle = [hatchstyle]
616616
self._hatchstyle = hatchstyle

0 commit comments

Comments
 (0)