Skip to content

Commit 571d7ef

Browse files
authored
Merge pull request matplotlib#7421 from QuLogic/hatch-dpi-density
Several hatching improvements
2 parents 6ed32d3 + 74e13fe commit 571d7ef

File tree

15 files changed

+30
-19
lines changed

15 files changed

+30
-19
lines changed

doc/users/dflt_style_changes.rst

+5
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,11 @@ The behavior of the PS and Agg backends was DPI dependent, thus::
625625

626626
There is no API level control of the hatch color or linewidth.
627627

628+
Hatching patterns are now rendered at a consistent density, regardless of DPI.
629+
Formerly, high DPI figures would be more dense than the default, and low DPI
630+
figures would be less dense. This old behavior cannot be directly restored,
631+
but the density may be increased by repeating the hatch specifier.
632+
628633

629634
.. _default_changes_font:
630635

lib/matplotlib/backends/backend_pdf.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -1141,12 +1141,12 @@ def alphaState(self, alpha):
11411141
def hatchPattern(self, hatch_style):
11421142
# The colors may come in as numpy arrays, which aren't hashable
11431143
if hatch_style is not None:
1144-
face, edge, hatch = hatch_style
1145-
if face is not None:
1146-
face = tuple(face)
1144+
edge, face, hatch = hatch_style
11471145
if edge is not None:
11481146
edge = tuple(edge)
1149-
hatch_style = (face, edge, hatch)
1147+
if face is not None:
1148+
face = tuple(face)
1149+
hatch_style = (edge, face, hatch)
11501150

11511151
pattern = self.hatchPatterns.get(hatch_style, None)
11521152
if pattern is not None:
@@ -1171,7 +1171,9 @@ def writeHatches(self):
11711171
'PatternType': 1, 'PaintType': 1, 'TilingType': 1,
11721172
'BBox': [0, 0, sidelen, sidelen],
11731173
'XStep': sidelen, 'YStep': sidelen,
1174-
'Resources': res})
1174+
'Resources': res,
1175+
# Change origin to match Agg at top-left.
1176+
'Matrix': [1, 0, 0, 1, 0, self.height * 72]})
11751177

11761178
stroke_rgb, fill_rgb, path = hatch_style
11771179
self.output(stroke_rgb[0], stroke_rgb[1], stroke_rgb[2],
@@ -1184,13 +1186,11 @@ def writeHatches(self):
11841186

11851187
self.output(rcParams['hatch.linewidth'], Op.setlinewidth)
11861188

1187-
# TODO: We could make this dpi-dependent, but that would be
1188-
# an API change
11891189
self.output(*self.pathOperations(
11901190
Path.hatch(path),
11911191
Affine2D().scale(sidelen),
11921192
simplify=False))
1193-
self.output(Op.stroke)
1193+
self.output(Op.fill_stroke)
11941194

11951195
self.endStream()
11961196
self.writeObject(self.hatchObject, hatchDict)

lib/matplotlib/backends/backend_ps.py

+10-7
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ def create_hatch(self, hatch):
305305
return self._hatches[hatch]
306306
name = 'H%d' % len(self._hatches)
307307
linewidth = rcParams['hatch.linewidth']
308+
pageheight = self.height * 72
308309
self._pswriter.write("""\
309310
<< /PatternType 1
310311
/PaintType 2
@@ -318,13 +319,15 @@ def create_hatch(self, hatch):
318319
%(linewidth)f setlinewidth
319320
""" % locals())
320321
self._pswriter.write(
321-
self._convert_path(Path.hatch(hatch), Affine2D().scale(72.0),
322+
self._convert_path(Path.hatch(hatch), Affine2D().scale(sidelen),
322323
simplify=False))
323324
self._pswriter.write("""\
324-
stroke
325+
fill
326+
stroke
325327
} bind
326328
>>
327329
matrix
330+
0.0 %(pageheight)f translate
328331
makepattern
329332
/%(name)s exch def
330333
""" % locals())
@@ -861,6 +864,7 @@ def _draw_ps(self, ps, gc, rgbFace, fill=True, stroke=True, command=None):
861864
stroke = stroke and mightstroke
862865
fill = (fill and rgbFace is not None and
863866
(len(rgbFace) <= 3 or rgbFace[3] != 0.0))
867+
hatch = gc.get_hatch()
864868

865869
if mightstroke:
866870
self.set_linewidth(gc.get_linewidth())
@@ -886,19 +890,18 @@ def _draw_ps(self, ps, gc, rgbFace, fill=True, stroke=True, command=None):
886890
write("\n")
887891

888892
if fill:
889-
if stroke:
893+
if stroke or hatch:
890894
write("gsave\n")
891895
self.set_color(store=0, *rgbFace[:3])
892896
write("fill\n")
893-
if stroke:
897+
if stroke or hatch:
894898
write("grestore\n")
895899

896-
hatch = gc.get_hatch()
897900
if hatch:
898901
hatch_name = self.create_hatch(hatch)
899902
write("gsave\n")
900-
write("[/Pattern [/DeviceRGB]] setcolorspace %f %f %f " % gc.get_hatch_color()[:3])
901-
write("%s setcolor fill grestore\n" % hatch_name)
903+
write("%f %f %f " % gc.get_hatch_color()[:3])
904+
write("%s setpattern fill grestore\n" % hatch_name)
902905

903906
if stroke:
904907
write("stroke\n")
Loading
Binary file not shown.
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading

src/_backend_agg.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,14 @@ RendererAgg::RendererAgg(unsigned int width, unsigned int height, double dpi)
5858
rendererBase.clear(_fill_color);
5959
rendererAA.attach(rendererBase);
6060
rendererBin.attach(rendererBase);
61-
hatchRenderingBuffer.attach(hatchBuffer, HATCH_SIZE, HATCH_SIZE, HATCH_SIZE * 4);
61+
hatch_size = int(dpi);
62+
hatchBuffer = new agg::int8u[hatch_size * hatch_size * 4];
63+
hatchRenderingBuffer.attach(hatchBuffer, hatch_size, hatch_size, hatch_size * 4);
6264
}
6365

6466
RendererAgg::~RendererAgg()
6567
{
68+
delete[] hatchBuffer;
6669
delete[] alphaBuffer;
6770
delete[] pixBuffer;
6871
}

src/_backend_agg.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -239,8 +239,8 @@ class RendererAgg
239239
void *lastclippath;
240240
agg::trans_affine lastclippath_transform;
241241

242-
static const size_t HATCH_SIZE = 72;
243-
agg::int8u hatchBuffer[HATCH_SIZE * HATCH_SIZE * 4];
242+
size_t hatch_size;
243+
agg::int8u *hatchBuffer;
244244
agg::rendering_buffer hatchRenderingBuffer;
245245

246246
agg::rgba _fill_color;
@@ -359,7 +359,7 @@ RendererAgg::_draw_path(path_t &path, bool has_clippath, const facepair_t &face,
359359
agg::trans_affine hatch_trans;
360360
hatch_trans *= agg::trans_affine_scaling(1.0, -1.0);
361361
hatch_trans *= agg::trans_affine_translation(0.0, 1.0);
362-
hatch_trans *= agg::trans_affine_scaling(HATCH_SIZE, HATCH_SIZE);
362+
hatch_trans *= agg::trans_affine_scaling(hatch_size, hatch_size);
363363
hatch_path_trans_t hatch_path_trans(hatch_path, hatch_trans);
364364
hatch_path_curve_t hatch_path_curve(hatch_path_trans);
365365
hatch_path_stroke_t hatch_path_stroke(hatch_path_curve);

0 commit comments

Comments
 (0)