diff --git a/bindings/python/mapnik/__init__.py b/bindings/python/mapnik/__init__.py index b3cd28e2a..8b3241ccc 100644 --- a/bindings/python/mapnik/__init__.py +++ b/bindings/python/mapnik/__init__.py @@ -618,6 +618,8 @@ __all__ = [ 'FontSet', 'FormatingNode', 'FormatingTextNode', + 'FormatingFormatNode', + 'FormatingListNode', 'Geometry2d', 'Image', 'ImageView', diff --git a/bindings/python/mapnik_text_placement.cpp b/bindings/python/mapnik_text_placement.cpp index f2a51c9bb..b637f606d 100644 --- a/bindings/python/mapnik_text_placement.cpp +++ b/bindings/python/mapnik_text_placement.cpp @@ -20,6 +20,7 @@ * *****************************************************************************/ #include +#include #include #include "mapnik_enumeration.hpp" @@ -147,6 +148,43 @@ struct FormatNodeWrap: formating::format_node, wrapper } }; +struct ListNodeWrap: formating::list_node, wrapper +{ + //Default constructor + ListNodeWrap() : formating::list_node(), wrapper() + { + } + + //Special constructor: Takes a python sequence as its argument + ListNodeWrap(object l) : formating::list_node(), wrapper() + { + stl_input_iterator begin(l), end; + children_.insert(children_.end(), begin, end); + } + + /* TODO: Add constructor taking variable number of arguments. + http://wiki.python.org/moin/boost.python/HowTo#A.22Raw.22_function */ + + + virtual void apply(char_properties const& p, Feature const& feature, processed_text &output) const + { + if(override o = this->get_override("apply")) + { + python_block_auto_unblock b; + o(ptr(&p), ptr(&feature), ptr(&output)); + } + else + { + formating::list_node::apply(p, feature, output); + } + } + + void default_apply(char_properties const& p, Feature const& feature, processed_text &output) const + { + formating::list_node::apply(p, feature, output); + } +}; + struct TextPlacementsWrap: text_placements, wrapper { text_placement_info_ptr get_placement_info(double scale_factor_, dimension_type dim, @@ -402,4 +440,16 @@ void export_text_placement() &formating::format_node::set_child) ; register_ptr_to_python >(); + + class_, + bases, + boost::noncopyable> + ("FormatingListNode", init<>()) + .def(init()) + .def("append", &formating::list_node::push_back) + .def("apply", &formating::list_node::apply, &ListNodeWrap::default_apply) + ; + + register_ptr_to_python >(); } diff --git a/include/mapnik/text_processing.hpp b/include/mapnik/text_processing.hpp index 9807b835c..0e3e0c1a7 100644 --- a/include/mapnik/text_processing.hpp +++ b/include/mapnik/text_processing.hpp @@ -119,8 +119,9 @@ public: void push_back(node_ptr n); void set_children(std::vector const& children); std::vector const& get_children() const; + void clear(); -private: +protected: std::vector children_; }; diff --git a/tests/visual_tests/test_python.py b/tests/visual_tests/test_python.py index 06ff21189..d80a4ddc7 100755 --- a/tests/visual_tests/test_python.py +++ b/tests/visual_tests/test_python.py @@ -74,14 +74,21 @@ m.layers.append(layer) bbox = mapnik.Box2d(-0.05, -0.01, 0.95, 0.01) m.zoom_to_box(bbox) +formatnode = mapnik.FormatingFormatNode() +formatnode.child = mapnik.FormatingTextNode(mapnik.Expression("[name]")) +formatnode.fill = mapnik.Color("green") format_trees = [ ('TextNode', mapnik.FormatingTextNode(mapnik.Expression("[name]"))), ('MyText', MyText()), ('IfElse', IfElse("[nr] != '5'", mapnik.FormatingTextNode(mapnik.Expression("[name]")), - mapnik.FormatingTextNode(mapnik.Expression("'SPECIAL!'")))) - + mapnik.FormatingTextNode(mapnik.Expression("'SPECIAL!'")))), + ('Format', formatnode), + ('List', mapnik.FormatingListNode([ + mapnik.FormatingTextNode(mapnik.Expression("[name]+'\n'")), + MyText() + ])) ] for format_tree in format_trees: