From fd2d9d7ff327b2c6ecaa6e699a81cf3d618b1851 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 2 Feb 2011 01:46:14 +0000 Subject: [PATCH] enable aliased lines using stroke-gamma for line_symbolizer - closes #689 --- bindings/python/mapnik_stroke.cpp | 17 +++++++++++++---- include/mapnik/stroke.hpp | 8 ++++++-- src/agg/process_line_symbolizer.cpp | 2 +- src/load_map.cpp | 3 +++ src/save_map.cpp | 12 ++++++++---- src/stroke.cpp | 17 ++++++++++++++++- tests/data/good_maps/line_symbolizer.xml | 22 ++++++++++++++++++++++ tests/python_tests/object_test.py | 3 +++ 8 files changed, 72 insertions(+), 12 deletions(-) create mode 100644 tests/data/good_maps/line_symbolizer.xml diff --git a/bindings/python/mapnik_stroke.cpp b/bindings/python/mapnik_stroke.cpp index 8a5a92b22..b045ec11a 100644 --- a/bindings/python/mapnik_stroke.cpp +++ b/bindings/python/mapnik_stroke.cpp @@ -64,17 +64,21 @@ struct stroke_pickle_suite : boost::python::pickle_suite getstate(const stroke& s) { boost::python::list dashes = get_dashes_list(s); - return boost::python::make_tuple(s.get_opacity(),dashes,s.get_line_cap(),s.get_line_join()); + return boost::python::make_tuple(s.get_opacity(), + dashes, + s.get_line_cap(), + s.get_line_join(), + s.get_gamma()); } static void setstate (stroke& s, boost::python::tuple state) { using namespace boost::python; - if (len(state) != 4) + if (len(state) != 5) { PyErr_SetObject(PyExc_ValueError, - ("expected 4-item tuple in call to __setstate__; got %s" + ("expected 5-item tuple in call to __setstate__; got %s" % state).ptr() ); throw_error_already_set(); @@ -93,8 +97,8 @@ struct stroke_pickle_suite : boost::python::pickle_suite } s.set_line_cap(extract(state[2])); - s.set_line_join(extract(state[3])); + s.set_gamma(extract(state[4])); } @@ -142,6 +146,11 @@ void export_stroke () &stroke::set_opacity, "Gets or sets the opacity of this stroke.\n" "The value is a float between 0 and 1.\n") + .add_property("gamma", + &stroke::get_gamma, + &stroke::set_gamma, + "Gets or sets the gamma of this stroke.\n" + "The value is a float between 0 and 1.\n") .add_property("line_cap", &stroke::get_line_cap, &stroke::set_line_cap, diff --git a/include/mapnik/stroke.hpp b/include/mapnik/stroke.hpp index 575267992..e1e27d36c 100644 --- a/include/mapnik/stroke.hpp +++ b/include/mapnik/stroke.hpp @@ -69,6 +69,7 @@ class MAPNIK_DECL stroke line_join_e line_join_; dash_array dash_; double dash_offset_; + double gamma_; public: explicit stroke(); stroke(color const& c, double width=1.0); @@ -76,13 +77,12 @@ public: stroke& operator=(const stroke& rhs); void set_color(const color& c); - color const& get_color() const; double get_width() const; void set_width(double w); - void set_opacity(double opacity); + void set_opacity(double opacity); double get_opacity() const; void set_line_cap(line_cap_e line_cap); @@ -90,9 +90,13 @@ public: void set_line_join(line_join_e line_join); line_join_e get_line_join() const; + + void set_gamma(double gamma); + double get_gamma() const; void add_dash(double dash,double gap); bool has_dash() const; + void set_dash_offset(double offset); double dash_offset() const; diff --git a/src/agg/process_line_symbolizer.cpp b/src/agg/process_line_symbolizer.cpp index 3205b1353..d5f856bd8 100644 --- a/src/agg/process_line_symbolizer.cpp +++ b/src/agg/process_line_symbolizer.cpp @@ -67,7 +67,7 @@ void agg_renderer::process(line_symbolizer const& sym, unsigned a=col.alpha(); renderer ren(renb); ras_ptr->reset(); - ras_ptr->gamma(agg::gamma_linear()); + ras_ptr->gamma(agg::gamma_linear(0.0, stroke_.get_gamma())); agg::scanline_p8 sl; metawriter_with_properties writer = sym.get_metawriter(); diff --git a/src/load_map.cpp b/src/load_map.cpp index f2200d990..de56ad92f 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -1557,6 +1557,9 @@ void map_parser::parse_stroke(stroke & strk, ptree const & sym) // stroke-linecap optional line_cap = get_opt_attr(sym, "stroke-linecap"); if (line_cap) strk.set_line_cap(*line_cap); + // stroke-gamma + optional gamma = get_opt_attr(sym, "stroke-gamma"); + if (gamma) strk.set_gamma(*gamma); // stroke-dashaffset optional offset = get_opt_attr(sym, "stroke-dashoffet"); if (offset) strk.set_dash_offset(*offset); diff --git a/src/save_map.cpp b/src/save_map.cpp index bec4c1ad1..76e9fc321 100644 --- a/src/save_map.cpp +++ b/src/save_map.cpp @@ -544,6 +544,14 @@ private: { set_attr( node, "stroke-linecap", strk.get_line_cap() ); } + if ( strk.get_gamma() != dfl.get_gamma() || explicit_defaults_ ) + { + set_attr( node, "stroke-gamma", strk.get_gamma()); + } + if ( strk.dash_offset() != dfl.dash_offset() || explicit_defaults_ ) + { + set_attr( node, "stroke-dashoffset", strk.dash_offset()); + } if ( ! strk.get_dash_array().empty() ) { std::ostringstream os; @@ -554,10 +562,6 @@ private: } set_attr( node, "stroke-dasharray", os.str() ); } - if ( strk.dash_offset() != dfl.dash_offset() || explicit_defaults_ ) - { - set_attr( node, "stroke-dashoffset", strk.dash_offset()); - } } void add_metawriter_attributes(ptree &node, symbolizer_base const& sym) diff --git a/src/stroke.cpp b/src/stroke.cpp index 05578dd05..12daedf9c 100644 --- a/src/stroke.cpp +++ b/src/stroke.cpp @@ -51,6 +51,7 @@ stroke::stroke() opacity_(1.0), line_cap_(BUTT_CAP), line_join_(MITER_JOIN), + gamma_(1.0), dash_(), dash_offset_(0) {} @@ -60,6 +61,7 @@ stroke::stroke(color const& c, double width) opacity_(1.0), line_cap_(BUTT_CAP), line_join_(MITER_JOIN), + gamma_(1.0), dash_(), dash_offset_(0.0) {} @@ -69,6 +71,7 @@ stroke::stroke(stroke const& other) opacity_(other.opacity_), line_cap_(other.line_cap_), line_join_(other.line_join_), + gamma_(other.gamma_), dash_(other.dash_), dash_offset_(other.dash_offset_) {} @@ -130,6 +133,16 @@ line_join_e stroke::get_line_join() const return line_join_; } +void stroke::set_gamma(double gamma) +{ + gamma_ = gamma; +} + +double stroke::get_gamma() const +{ + return gamma_; +} + void stroke::add_dash(double dash, double gap) { dash_.push_back(std::make_pair(dash,gap)); @@ -152,7 +165,7 @@ double stroke::dash_offset() const dash_array const& stroke::get_dash_array() const { - return dash_; + return dash_; } void stroke::swap(const stroke& other) throw() @@ -162,6 +175,8 @@ void stroke::swap(const stroke& other) throw() opacity_=other.opacity_; line_cap_=other.line_cap_; line_join_=other.line_join_; + gamma_=other.gamma_; dash_ = other.dash_; + dash_offset_ = other.dash_offset_; } } diff --git a/tests/data/good_maps/line_symbolizer.xml b/tests/data/good_maps/line_symbolizer.xml new file mode 100644 index 000000000..82e40397d --- /dev/null +++ b/tests/data/good_maps/line_symbolizer.xml @@ -0,0 +1,22 @@ + + + + + + test + + shape + ../../data/shp/poly.shp + + + + \ No newline at end of file diff --git a/tests/python_tests/object_test.py b/tests/python_tests/object_test.py index 1347a516f..8189adc49 100644 --- a/tests/python_tests/object_test.py +++ b/tests/python_tests/object_test.py @@ -153,12 +153,15 @@ def test_stroke_init(): eq_(s.color, mapnik2.Color('black')) eq_(s.line_cap, mapnik2.line_cap.BUTT_CAP) eq_(s.line_join, mapnik2.line_join.MITER_JOIN) + eq_(s.gamma,1.0) s = mapnik2.Stroke(mapnik2.Color('blue'), 5.0) + s.gamma = .5 eq_(s.width, 5) eq_(s.opacity, 1) eq_(s.color, mapnik2.Color('blue')) + eq_(s.gamma, .5) eq_(s.line_cap, mapnik2.line_cap.BUTT_CAP) eq_(s.line_join, mapnik2.line_join.MITER_JOIN)