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

Skip to content

Commit b08aa49

Browse files
committed
Process clip paths the same way as regular Paths.
Specifically, run NaN removal, clipping to figure boundary, snapping to pixel centers, and path simplification on it. This means if you plot a Path, and then clip some other artist with it, you will get properly aligned results.
1 parent 9d00ca8 commit b08aa49

File tree

4 files changed

+22
-11
lines changed

4 files changed

+22
-11
lines changed

src/_backend_agg.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,15 @@ RendererAgg::restore_region(BufferRegion &region, int xx1, int yy1, int xx2, int
129129
}
130130

131131
bool RendererAgg::render_clippath(py::PathIterator &clippath,
132-
const agg::trans_affine &clippath_trans)
132+
const agg::trans_affine &clippath_trans,
133+
e_snap_mode snap_mode)
133134
{
134135
typedef agg::conv_transform<py::PathIterator> transformed_path_t;
135-
typedef agg::conv_curve<transformed_path_t> curve_t;
136+
typedef PathNanRemover<transformed_path_t> nan_removed_t;
137+
typedef PathClipper<nan_removed_t> clipped_t;
138+
typedef PathSnapper<clipped_t> snapped_t;
139+
typedef PathSimplifier<snapped_t> simplify_t;
140+
typedef agg::conv_curve<simplify_t> curve_t;
136141

137142
bool has_clippath = (clippath.total_vertices() != 0);
138143

@@ -145,7 +150,13 @@ bool RendererAgg::render_clippath(py::PathIterator &clippath,
145150

146151
rendererBaseAlphaMask.clear(agg::gray8(0, 0));
147152
transformed_path_t transformed_clippath(clippath, trans);
148-
curve_t curved_clippath(transformed_clippath);
153+
nan_removed_t nan_removed_clippath(transformed_clippath, true, clippath.has_curves());
154+
clipped_t clipped_clippath(nan_removed_clippath, !clippath.has_curves(), width, height);
155+
snapped_t snapped_clippath(clipped_clippath, snap_mode, clippath.total_vertices(), 0.0);
156+
simplify_t simplified_clippath(snapped_clippath,
157+
clippath.should_simplify() && !clippath.has_curves(),
158+
clippath.simplify_threshold());
159+
curve_t curved_clippath(simplified_clippath);
149160
theRasterizer.add_path(curved_clippath);
150161
rendererAlphaMask.color(agg::gray8(255, 255));
151162
agg::render_scanlines(theRasterizer, scanlineAlphaMask, rendererAlphaMask);

src/_backend_agg.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ class RendererAgg
251251
template <class R>
252252
void set_clipbox(const agg::rect_d &cliprect, R &rasterizer);
253253

254-
bool render_clippath(py::PathIterator &clippath, const agg::trans_affine &clippath_trans);
254+
bool render_clippath(py::PathIterator &clippath, const agg::trans_affine &clippath_trans, e_snap_mode snap_mode);
255255

256256
template <class PathIteratorType>
257257
void _draw_path(PathIteratorType &path, bool has_clippath, const facepair_t &face, GCAgg &gc);
@@ -379,7 +379,7 @@ RendererAgg::_draw_path(path_t &path, bool has_clippath, const facepair_t &face,
379379
// function
380380
set_clipbox(gc.cliprect, theRasterizer);
381381
if (has_clippath) {
382-
render_clippath(gc.clippath.path, gc.clippath.trans);
382+
render_clippath(gc.clippath.path, gc.clippath.trans, gc.snap_mode);
383383
}
384384

385385
// Transfer the hatch to the main image buffer
@@ -468,7 +468,7 @@ RendererAgg::draw_path(GCAgg &gc, PathIterator &path, agg::trans_affine &trans,
468468
theRasterizer.reset_clipping();
469469
rendererBase.reset_clipping(true);
470470
set_clipbox(gc.cliprect, theRasterizer);
471-
bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans);
471+
bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans, gc.snap_mode);
472472

473473
trans *= agg::trans_affine_scaling(1.0, -1.0);
474474
trans *= agg::trans_affine_translation(0.0, (double)height);
@@ -586,7 +586,7 @@ inline void RendererAgg::draw_markers(GCAgg &gc,
586586
theRasterizer.reset_clipping();
587587
rendererBase.reset_clipping(true);
588588
set_clipbox(gc.cliprect, rendererBase);
589-
bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans);
589+
bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans, gc.snap_mode);
590590

591591
double x, y;
592592

@@ -832,7 +832,7 @@ inline void RendererAgg::draw_image(GCAgg &gc,
832832
theRasterizer.reset_clipping();
833833
rendererBase.reset_clipping(true);
834834
set_clipbox(gc.cliprect, theRasterizer);
835-
bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans);
835+
bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans, gc.snap_mode);
836836

837837
agg::rendering_buffer buffer;
838838
buffer.attach(
@@ -941,7 +941,7 @@ inline void RendererAgg::_draw_path_collection_generic(GCAgg &gc,
941941
theRasterizer.reset_clipping();
942942
rendererBase.reset_clipping(true);
943943
set_clipbox(cliprect, theRasterizer);
944-
bool has_clippath = render_clippath(clippath, clippath_trans);
944+
bool has_clippath = render_clippath(clippath, clippath_trans, gc.snap_mode);
945945

946946
// Set some defaults, assuming no face or edge
947947
gc.linewidth = 0.0;
@@ -1249,7 +1249,7 @@ inline void RendererAgg::draw_gouraud_triangle(GCAgg &gc,
12491249
theRasterizer.reset_clipping();
12501250
rendererBase.reset_clipping(true);
12511251
set_clipbox(gc.cliprect, theRasterizer);
1252-
bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans);
1252+
bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans, gc.snap_mode);
12531253

12541254
_draw_gouraud_triangle(points, colors, trans, has_clippath);
12551255
}
@@ -1263,7 +1263,7 @@ inline void RendererAgg::draw_gouraud_triangles(GCAgg &gc,
12631263
theRasterizer.reset_clipping();
12641264
rendererBase.reset_clipping(true);
12651265
set_clipbox(gc.cliprect, theRasterizer);
1266-
bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans);
1266+
bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans, gc.snap_mode);
12671267

12681268
for (int i = 0; i < points.dim(0); ++i) {
12691269
typename PointArray::sub_t point = points.subarray(i);

0 commit comments

Comments
 (0)