@@ -148,6 +148,7 @@ GCAgg::GCAgg(const Py::Object &gc, double dpi) :
148148 _set_dashes (gc);
149149 _set_clip_rectangle (gc);
150150 _set_clip_path (gc);
151+ _set_snap (gc);
151152}
152153
153154GCAgg::GCAgg (double dpi) :
@@ -254,6 +255,24 @@ GCAgg::_set_clip_path( const Py::Object& gc) {
254255 }
255256}
256257
258+ void
259+ GCAgg::_set_snap ( const Py::Object& gc) {
260+ // set the snap setting
261+
262+ _VERBOSE (" GCAgg::_set_snap" );
263+
264+ Py::Object method_obj = gc.getAttr (" get_snap" );
265+ Py::Callable method (method_obj);
266+ Py::Object py_snap = method.apply (Py::Tuple ());
267+ if (py_snap.isNone ()) {
268+ snap = SNAP_AUTO;
269+ } else if (py_snap.isTrue ()) {
270+ snap = SNAP_TRUE;
271+ } else {
272+ snap = SNAP_FALSE;
273+ }
274+ }
275+
257276const size_t
258277RendererAgg::PIXELS_PER_INCH (96 );
259278
@@ -336,43 +355,51 @@ RendererAgg::_get_rgba_face(const Py::Object& rgbFace, double alpha) {
336355}
337356
338357template <class Path >
339- bool should_snap (Path& path, const agg::trans_affine& trans) {
358+ bool should_snap (const GCAgg& gc, Path& path, const agg::trans_affine& trans) {
340359 // If this contains only straight horizontal or vertical lines, it should be
341360 // quantized to the nearest pixels
342361 double x0, y0, x1, y1;
343362 unsigned code;
344363
345- if (path.total_vertices () > 15 )
346- return false ;
347-
348- code = path.vertex (&x0, &y0);
349- if (code == agg::path_cmd_stop) {
350- path.rewind (0 );
351- return false ;
352- }
353- trans.transform (&x0, &y0);
354-
355- while ((code = path.vertex (&x1, &y1)) != agg::path_cmd_stop) {
356- trans.transform (&x1, &y1);
364+ switch (gc.snap ) {
365+ case GCAgg::SNAP_AUTO:
366+ if (path.total_vertices () > 15 )
367+ return false ;
357368
358- switch (code) {
359- case agg::path_cmd_curve3:
360- case agg::path_cmd_curve4:
369+ code = path.vertex (&x0, &y0);
370+ if (code == agg::path_cmd_stop) {
361371 path.rewind (0 );
362372 return false ;
363- case agg::path_cmd_line_to:
364- if (!(fabs (x0 - x1) < 1e-4 || fabs (y0 - y1) < 1e-4 )) {
365- path.rewind (0 );
366- return false ;
373+ }
374+ trans.transform (&x0, &y0);
375+
376+ while ((code = path.vertex (&x1, &y1)) != agg::path_cmd_stop) {
377+ trans.transform (&x1, &y1);
378+
379+ switch (code) {
380+ case agg::path_cmd_curve3:
381+ case agg::path_cmd_curve4:
382+ path.rewind (0 );
383+ return false ;
384+ case agg::path_cmd_line_to:
385+ if (!(fabs (x0 - x1) < 1e-4 || fabs (y0 - y1) < 1e-4 )) {
386+ path.rewind (0 );
387+ return false ;
388+ }
367389 }
390+
391+ x0 = x1;
392+ y0 = y1;
368393 }
369394
370- x0 = x1;
371- y0 = y1;
395+ path.rewind (0 );
396+ return true ;
397+ case GCAgg::SNAP_FALSE:
398+ return false ;
399+ case GCAgg::SNAP_TRUE:
400+ return true ;
372401 }
373-
374- path.rewind (0 );
375- return true ;
402+ return false ;
376403}
377404
378405Py::Object
@@ -487,6 +514,8 @@ RendererAgg::draw_markers(const Py::Tuple& args) {
487514 if (args.size () == 6 )
488515 face_obj = args[5 ];
489516
517+ GCAgg gc = GCAgg (gc_obj, dpi);
518+
490519 // Deal with the difference in y-axis direction
491520 marker_trans *= agg::trans_affine_scaling (1.0 , -1.0 );
492521 trans *= agg::trans_affine_scaling (1.0 , -1.0 );
@@ -497,14 +526,13 @@ RendererAgg::draw_markers(const Py::Tuple& args) {
497526 // unfortunately, it can cause really small things to disappear.
498527 // Disabling for now to revisit at a later date.
499528 // const bool marker_snap = true;
500- bool marker_snap = should_snap (marker_path, marker_trans);
529+ bool marker_snap = should_snap (gc, marker_path, marker_trans);
501530 transformed_path_t marker_path_transformed (marker_path, marker_trans);
502531 simplify_t marker_path_simplified (marker_path_transformed, marker_snap, false , width, height);
503532 curve_t marker_path_curve (marker_path_simplified);
504533
505534 PathIterator path (path_obj);
506535 transformed_path_t path_transformed (path, trans);
507- GCAgg gc = GCAgg (gc_obj, dpi);
508536 path_transformed.rewind (0 );
509537
510538 facepair_t face = _get_rgba_face (face_obj, gc.alpha );
@@ -934,7 +962,7 @@ RendererAgg::draw_path(const Py::Tuple& args) {
934962
935963 trans *= agg::trans_affine_scaling (1.0 , -1.0 );
936964 trans *= agg::trans_affine_translation (0.0 , (double )height);
937- bool snap = should_snap (path, trans);
965+ bool snap = should_snap (gc, path, trans);
938966 bool simplify = path.should_simplify () && !face.first ;
939967
940968 transformed_path_t tpath (path, trans);
@@ -1098,7 +1126,7 @@ RendererAgg::_draw_path_collection_generic
10981126 }
10991127
11001128 if (check_snap) {
1101- snap = should_snap (path, trans);
1129+ snap = should_snap (gc, path, trans);
11021130 if (snap)
11031131 gc.isaa = false ;
11041132 else
0 commit comments