| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent f0c0647 commit bd77bf2
9 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -412,7 +412,7 @@ def get_snap(self): | |||
| 412 | 412 | * None: (auto) If the path contains only rectilinear line | |
| 413 | 413 | segments, round to the nearest pixel center | |
| 414 | 414 | ||
| 415 | - Only supported by the Agg backends. | ||
| 415 | + Only supported by the Agg and MacOSX backends. | ||
| 416 | 416 | """ | |
| 417 | 417 | return self._snap | |
| 418 | 418 | ||
@@ -427,7 +427,7 @@ def set_snap(self, snap): | |||
| 427 | 427 | * None: (auto) If the path contains only rectilinear line | |
| 428 | 428 | segments, round to the nearest pixel center | |
| 429 | 429 | ||
| 430 | - Only supported by the Agg backends. | ||
| 430 | + Only supported by the Agg and MacOSX backends. | ||
| 431 | 431 | """ | |
| 432 | 432 | self._snap = snap | |
| 433 | 433 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -188,7 +188,8 @@ def __len__(self): | |||
| 188 | 188 | return len(self.vertices) | |
| 189 | 189 | ||
| 190 | 190 | def iter_segments(self, transform=None, remove_nans=True, clip=None, | |
| 191 | - quantize=False, simplify=None, curves=True): | ||
| 191 | + quantize=False, stroke_width=1.0, simplify=None, | ||
| 192 | + curves=True): | ||
| 192 | 193 | """ | |
| 193 | 194 | Iterates over all of the curve segments in the path. Each | |
| 194 | 195 | iteration returns a 2-tuple (*vertices*, *code*), where | |
@@ -210,6 +211,9 @@ def iter_segments(self, transform=None, remove_nans=True, clip=None, | |||
| 210 | 211 | *quantize*: if None, auto-quantize. If True, force quantize, | |
| 211 | 212 | and if False, don't quantize. | |
| 212 | 213 | ||
| 214 | + *stroke_width*: the width of the stroke being drawn. Needed | ||
| 215 | + as a hint for the quantizer. | ||
| 216 | + | ||
| 213 | 217 | *simplify*: if True, perform simplification, to remove | |
| 214 | 218 | vertices that do not affect the appearance of the path. If | |
| 215 | 219 | False, perform no simplification. If None, use the | |
@@ -232,7 +236,7 @@ def iter_segments(self, transform=None, remove_nans=True, clip=None, | |||
| 232 | 236 | STOP = self.STOP | |
| 233 | 237 | ||
| 234 | 238 | vertices, codes = cleanup_path(self, transform, remove_nans, clip, | |
| 235 | - quantize, simplify, curves) | ||
| 239 | + quantize, stroke_width, simplify, curves) | ||
| 236 | 240 | len_vertices = len(vertices) | |
| 237 | 241 | ||
| 238 | 242 | i = 0 | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -535,14 +535,16 @@ RendererAgg::draw_markers(const Py::Tuple& args) { | |||
| 535 | 535 | transformed_path_t marker_path_transformed(marker_path, marker_trans); | |
| 536 | 536 | quantize_t marker_path_quantized(marker_path_transformed, | |
| 537 | 537 | gc.quantize_mode, | |
| 538 | - marker_path.total_vertices()); | ||
| 538 | + marker_path.total_vertices(), | ||
| 539 | + gc.linewidth); | ||
| 539 | 540 | curve_t marker_path_curve(marker_path_quantized); | |
| 540 | 541 | ||
| 541 | 542 | PathIterator path(path_obj); | |
| 542 | 543 | transformed_path_t path_transformed(path, trans); | |
| 543 | 544 | quantize_t path_quantized(path_transformed, | |
| 544 | 545 | gc.quantize_mode, | |
| 545 | - path.total_vertices()); | ||
| 546 | + path.total_vertices(), | ||
| 547 | + 1.0); | ||
| 546 | 548 | curve_t path_curve(path_quantized); | |
| 547 | 549 | path_curve.rewind(0); | |
| 548 | 550 | ||
@@ -1106,7 +1108,7 @@ RendererAgg::draw_path(const Py::Tuple& args) { | |||
| 1106 | 1108 | transformed_path_t tpath(path, trans); | |
| 1107 | 1109 | nan_removed_t nan_removed(tpath, true, path.has_curves()); | |
| 1108 | 1110 | clipped_t clipped(nan_removed, clip, width, height); | |
| 1109 | - quantized_t quantized(clipped, gc.quantize_mode, path.total_vertices()); | ||
| 1111 | + quantized_t quantized(clipped, gc.quantize_mode, path.total_vertices(), gc.linewidth); | ||
| 1110 | 1112 | simplify_t simplified(quantized, simplify, path.simplify_threshold()); | |
| 1111 | 1113 | curve_t curve(simplified); | |
| 1112 | 1114 | ||
@@ -1273,7 +1275,8 @@ RendererAgg::_draw_path_collection_generic | |||
| 1273 | 1275 | transformed_path_t tpath(path, trans); | |
| 1274 | 1276 | nan_removed_t nan_removed(tpath, true, has_curves); | |
| 1275 | 1277 | clipped_t clipped(nan_removed, do_clip, width, height); | |
| 1276 | - quantized_t quantized(clipped, gc.quantize_mode, path.total_vertices()); | ||
| 1278 | + quantized_t quantized(clipped, gc.quantize_mode, | ||
| 1279 | + path.total_vertices(), gc.linewidth); | ||
| 1277 | 1280 | if (has_curves) { | |
| 1278 | 1281 | quantized_curve_t curve(quantized); | |
| 1279 | 1282 | _draw_path(curve, has_clippath, face, gc); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -289,6 +289,7 @@ static void _draw_hatch(void *info, CGContextRef cr) | |||
| 289 | 289 | 0, | |
| 290 | 290 | rect, | |
| 291 | 291 | QUANTIZE_FALSE, | |
| 292 | + 1.0, | ||
| 292 | 293 | 0); | |
| 293 | 294 | Py_DECREF(transform); | |
| 294 | 295 | if (!iterator) | |
@@ -662,6 +663,7 @@ static int _get_snap(GraphicsContext* self, enum e_quantize_mode* mode) | |||
| 662 | 663 | 0, | |
| 663 | 664 | rect, | |
| 664 | 665 | QUANTIZE_AUTO, | |
| 666 | + 1.0, | ||
| 665 | 667 | 0); | |
| 666 | 668 | Py_DECREF(transform); | |
| 667 | 669 | if (!iterator) | |
@@ -889,6 +891,7 @@ static int _get_snap(GraphicsContext* self, enum e_quantize_mode* mode) | |||
| 889 | 891 | 0, | |
| 890 | 892 | rect, | |
| 891 | 893 | QUANTIZE_AUTO, | |
| 894 | + CGContextGetLineWidth(self), | ||
| 892 | 895 | rgbFace == NULL); | |
| 893 | 896 | if (!iterator) | |
| 894 | 897 | { | |
@@ -966,6 +969,7 @@ static int _get_snap(GraphicsContext* self, enum e_quantize_mode* mode) | |||
| 966 | 969 | 0, | |
| 967 | 970 | rect, | |
| 968 | 971 | QUANTIZE_AUTO, | |
| 972 | + CGContextGetLineWidth(self), | ||
| 969 | 973 | 0); | |
| 970 | 974 | if (!iterator) | |
| 971 | 975 | { | |
@@ -1042,6 +1046,7 @@ static int _get_snap(GraphicsContext* self, enum e_quantize_mode* mode) | |||
| 1042 | 1046 | 0, | |
| 1043 | 1047 | rect, | |
| 1044 | 1048 | mode, | |
| 1049 | + CGContextGetLineWidth(self), | ||
| 1045 | 1050 | 0); | |
| 1046 | 1051 | if (!iterator) | |
| 1047 | 1052 | { | |
@@ -1063,6 +1068,7 @@ static int _get_snap(GraphicsContext* self, enum e_quantize_mode* mode) | |||
| 1063 | 1068 | 1, | |
| 1064 | 1069 | rect, | |
| 1065 | 1070 | QUANTIZE_TRUE, | |
| 1071 | + 1.0, | ||
| 1066 | 1072 | 0); | |
| 1067 | 1073 | if (!iterator) | |
| 1068 | 1074 | { | |
@@ -1326,6 +1332,17 @@ static BOOL _clip(CGContextRef cr, PyObject* object) | |||
| 1326 | 1332 | 0, | |
| 1327 | 1333 | rect, | |
| 1328 | 1334 | mode, | |
| 1335 | + 1.0, | ||
| 1336 | + /* Hardcoding stroke width to 1.0 | ||
| 1337 | + here, but for true | ||
| 1338 | + correctness, the paths would | ||
| 1339 | + need to be set up for each | ||
| 1340 | + different linewidth that may | ||
| 1341 | + be applied below. This | ||
| 1342 | + difference is very minute in | ||
| 1343 | + practice, so this hardcoding | ||
| 1344 | + is probably ok for now. -- | ||
| 1345 | + MGD */ | ||
| 1329 | 1346 | 0); | |
| 1330 | 1347 | Py_DECREF(transform); | |
| 1331 | 1348 | Py_DECREF(path); | |
@@ -1362,6 +1379,7 @@ static BOOL _clip(CGContextRef cr, PyObject* object) | |||
| 1362 | 1379 | 0, | |
| 1363 | 1380 | rect, | |
| 1364 | 1381 | QUANTIZE_AUTO, | |
| 1382 | + 1.0, | ||
| 1365 | 1383 | 0); | |
| 1366 | 1384 | if (!iterator) | |
| 1367 | 1385 | { | |
@@ -1669,6 +1687,7 @@ static BOOL _clip(CGContextRef cr, PyObject* object) | |||
| 1669 | 1687 | 0, | |
| 1670 | 1688 | rect, | |
| 1671 | 1689 | QUANTIZE_AUTO, | |
| 1690 | + 1.0, | ||
| 1672 | 1691 | 0); | |
| 1673 | 1692 | if (iterator) | |
| 1674 | 1693 | { | |
@@ -2654,6 +2673,7 @@ static void _data_provider_release(void* info, const void* data, size_t size) | |||
| 2654 | 2673 | 0, | |
| 2655 | 2674 | rect, | |
| 2656 | 2675 | QUANTIZE_AUTO, | |
| 2676 | + 1.0, | ||
| 2657 | 2677 | 0); | |
| 2658 | 2678 | if (iterator) | |
| 2659 | 2679 | { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1228,8 +1228,9 @@ void __cleanup_path(VertexSource& source, | |||
| 1228 | 1228 | void _cleanup_path(PathIterator& path, const agg::trans_affine& trans, | |
| 1229 | 1229 | bool remove_nans, bool do_clip, | |
| 1230 | 1230 | const agg::rect_base<double>& rect, | |
| 1231 | - e_quantize_mode quantize_mode, bool do_simplify, | ||
| 1232 | - bool return_curves, std::vector<double>& vertices, | ||
| 1231 | + e_quantize_mode quantize_mode, double stroke_width, | ||
| 1232 | + bool do_simplify, bool return_curves, | ||
| 1233 | + std::vector<double>& vertices, | ||
| 1233 | 1234 | std::vector<npy_uint8>& codes) { | |
| 1234 | 1235 | typedef agg::conv_transform<PathIterator> transformed_path_t; | |
| 1235 | 1236 | typedef PathNanRemover<transformed_path_t> nan_removal_t; | |
@@ -1241,7 +1242,7 @@ void _cleanup_path(PathIterator& path, const agg::trans_affine& trans, | |||
| 1241 | 1242 | transformed_path_t tpath(path, trans); | |
| 1242 | 1243 | nan_removal_t nan_removed(tpath, remove_nans, path.has_curves()); | |
| 1243 | 1244 | clipped_t clipped(nan_removed, do_clip, rect); | |
| 1244 | - quantized_t quantized(clipped, quantize_mode, path.total_vertices()); | ||
| 1245 | + quantized_t quantized(clipped, quantize_mode, path.total_vertices(), stroke_width); | ||
| 1245 | 1246 | simplify_t simplified(quantized, do_simplify, path.simplify_threshold()); | |
| 1246 | 1247 | ||
| 1247 | 1248 | vertices.reserve(path.total_vertices() * 2); | |
@@ -1260,7 +1261,7 @@ void _cleanup_path(PathIterator& path, const agg::trans_affine& trans, | |||
| 1260 | 1261 | ||
| 1261 | 1262 | Py::Object _path_module::cleanup_path(const Py::Tuple& args) | |
| 1262 | 1263 | { | |
| 1263 | - args.verify_length(7); | ||
| 1264 | + args.verify_length(8); | ||
| 1264 | 1265 | ||
| 1265 | 1266 | PathIterator path(args[0]); | |
| 1266 | 1267 | agg::trans_affine trans = py_to_agg_transformation_matrix(args[1].ptr(), false); | |
@@ -1300,8 +1301,10 @@ Py::Object _path_module::cleanup_path(const Py::Tuple& args) | |||
| 1300 | 1301 | quantize_mode = QUANTIZE_FALSE; | |
| 1301 | 1302 | } | |
| 1302 | 1303 | ||
| 1304 | + double stroke_width = Py::Float(args[5]); | ||
| 1305 | + | ||
| 1303 | 1306 | bool simplify; | |
| 1304 | - Py::Object simplify_obj = args[5]; | ||
| 1307 | + Py::Object simplify_obj = args[6]; | ||
| 1305 | 1308 | if (simplify_obj.isNone()) | |
| 1306 | 1309 | { | |
| 1307 | 1310 | simplify = path.should_simplify(); | |
@@ -1311,13 +1314,13 @@ Py::Object _path_module::cleanup_path(const Py::Tuple& args) | |||
| 1311 | 1314 | simplify = simplify_obj.isTrue(); | |
| 1312 | 1315 | } | |
| 1313 | 1316 | ||
| 1314 | - bool return_curves = args[6].isTrue(); | ||
| 1317 | + bool return_curves = args[7].isTrue(); | ||
| 1315 | 1318 | ||
| 1316 | 1319 | std::vector<double> vertices; | |
| 1317 | 1320 | std::vector<npy_uint8> codes; | |
| 1318 | 1321 | ||
| 1319 | 1322 | _cleanup_path(path, trans, remove_nans, do_clip, clip_rect, quantize_mode, | |
| 1320 | - simplify, return_curves, vertices, codes); | ||
| 1323 | + stroke_width, simplify, return_curves, vertices, codes); | ||
| 1321 | 1324 | ||
| 1322 | 1325 | npy_intp length = codes.size(); | |
| 1323 | 1326 | npy_intp dims[] = { length, 2, 0 }; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -28,14 +28,16 @@ class PathCleanupIterator | |||
| 28 | 28 | PathCleanupIterator(PyObject* path, agg::trans_affine trans, | |
| 29 | 29 | bool remove_nans, bool do_clip, | |
| 30 | 30 | const agg::rect_base<double>& rect, | |
| 31 | - e_quantize_mode quantize_mode, bool do_simplify) : | ||
| 31 | + e_quantize_mode quantize_mode, double stroke_width, | ||
| 32 | + bool do_simplify) : | ||
| 32 | 33 | m_path_obj(path, true), | |
| 33 | 34 | m_path_iter(m_path_obj), | |
| 34 | 35 | m_transform(trans), | |
| 35 | 36 | m_transformed(m_path_iter, m_transform), | |
| 36 | 37 | m_nan_removed(m_transformed, remove_nans, m_path_iter.has_curves()), | |
| 37 | 38 | m_clipped(m_nan_removed, do_clip, rect), | |
| 38 | - m_quantized(m_clipped, quantize_mode, m_path_iter.total_vertices()), | ||
| 39 | + m_quantized(m_clipped, quantize_mode, m_path_iter.total_vertices(), | ||
| 40 | + stroke_width), | ||
| 39 | 41 | m_simplify(m_quantized, do_simplify && m_path_iter.should_simplify(), | |
| 40 | 42 | m_path_iter.simplify_threshold()) | |
| 41 | 43 | { | |
@@ -53,14 +55,15 @@ extern "C" { | |||
| 53 | 55 | void* | |
| 54 | 56 | get_path_iterator( | |
| 55 | 57 | PyObject* path, PyObject* trans, int remove_nans, int do_clip, | |
| 56 | - double rect[4], e_quantize_mode quantize_mode, int do_simplify) | ||
| 58 | + double rect[4], e_quantize_mode quantize_mode, double stroke_width, | ||
| 59 | + int do_simplify) | ||
| 57 | 60 | { | |
| 58 | 61 | agg::trans_affine agg_trans = py_to_agg_transformation_matrix(trans, false); | |
| 59 | 62 | agg::rect_base<double> clip_rect(rect[0], rect[1], rect[2], rect[3]); | |
| 60 | 63 | ||
| 61 | 64 | PathCleanupIterator* pipeline = new PathCleanupIterator( | |
| 62 | 65 | path, agg_trans, remove_nans != 0, do_clip != 0, | |
| 63 | - clip_rect, quantize_mode, do_simplify != 0); | ||
| 66 | + clip_rect, quantize_mode, stroke_width, do_simplify != 0); | ||
| 64 | 67 | ||
| 65 | 68 | return (void*)pipeline; | |
| 66 | 69 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -378,6 +378,7 @@ class PathQuantizer | |||
| 378 | 378 | private: | |
| 379 | 379 | VertexSource* m_source; | |
| 380 | 380 | bool m_quantize; | |
| 381 | + double m_quantize_value; | ||
| 381 | 382 | ||
| 382 | 383 | static bool should_quantize(VertexSource& path, | |
| 383 | 384 | e_quantize_mode quantize_mode, | |
@@ -436,10 +437,17 @@ class PathQuantizer | |||
| 436 | 437 | - QUANTIZE_FALSE: No quantization | |
| 437 | 438 | */ | |
| 438 | 439 | PathQuantizer(VertexSource& source, e_quantize_mode quantize_mode, | |
| 439 | - unsigned total_vertices=15) : | ||
| 440 | + unsigned total_vertices=15, double stroke_width=0.0) : | ||
| 440 | 441 | m_source(&source) | |
| 441 | 442 | { | |
| 442 | 443 | m_quantize = should_quantize(source, quantize_mode, total_vertices); | |
| 444 | + | ||
| 445 | + if (m_quantize) | ||
| 446 | + { | ||
| 447 | + int odd_even = (int)mpl_round(stroke_width) % 2; | ||
| 448 | + m_quantize_value = (odd_even) ? 0.5 : 0.0; | ||
| 449 | + } | ||
| 450 | + | ||
| 443 | 451 | source.rewind(0); | |
| 444 | 452 | } | |
| 445 | 453 | ||
@@ -454,8 +462,8 @@ class PathQuantizer | |||
| 454 | 462 | code = m_source->vertex(x, y); | |
| 455 | 463 | if (m_quantize && agg::is_vertex(code)) | |
| 456 | 464 | { | |
| 457 | - *x = mpl_round(*x) + 0.5; | ||
| 458 | - *y = mpl_round(*y) + 0.5; | ||
| 465 | + *x = mpl_round(*x) + m_quantize_value; | ||
| 466 | + *y = mpl_round(*y) + m_quantize_value; | ||
| 459 | 467 | } | |
| 460 | 468 | return code; | |
| 461 | 469 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments