diff --git a/include/mapnik/text_properties.hpp b/include/mapnik/text_properties.hpp index b5f4433f8..d5d5cbe20 100644 --- a/include/mapnik/text_properties.hpp +++ b/include/mapnik/text_properties.hpp @@ -168,6 +168,7 @@ struct text_symbolizer_properties bool largest_bbox_only; unsigned text_ratio; unsigned wrap_width; + bool rotate_displacement; /** Default values for char_properties. */ char_properties_ptr format; private: diff --git a/src/text/placement_finder_ng.cpp b/src/text/placement_finder_ng.cpp index adf82d2e7..d1aeccaf2 100644 --- a/src/text/placement_finder_ng.cpp +++ b/src/text/placement_finder_ng.cpp @@ -150,6 +150,14 @@ static void rotated_box2d(box2d &box, double sina, double cosa, double w box.init(-new_width/2., -new_height/2., new_width/2., new_height/2.); } +static pixel_position rotate(pixel_position pos, double sina, double cosa) +{ + double tmp_x = pos.x * cosa + pos.y * sina; + pos.y = - pos.x * sina + pos.y * cosa; + pos.x = tmp_x; + return pos; +} + glyph_positions_ptr placement_finder_ng::find_point_placement(pixel_position pos) { @@ -157,9 +165,10 @@ glyph_positions_ptr placement_finder_ng::find_point_placement(pixel_position pos if (!layout_.size()) return glyphs; /* No data. Don't return NULL pointer, which would mean that not enough space was available. */ - //TODO: Verify enough space is available. For point placement the bounding box is enough! + pixel_position displacement = scale_factor_ * info_->properties.displacement + alignment_offset(); + if (info_->properties.rotate_displacement) displacement = rotate(displacement, sina_, cosa_); - glyphs->set_base_point(pos + scale_factor_ * info_->properties.displacement + alignment_offset()); + glyphs->set_base_point(pos + displacement); box2d bbox; rotated_box2d(bbox, sina_, cosa_, layout_.width(), layout_.height()); bbox.re_center(glyphs->get_base_point().x, glyphs->get_base_point().y); @@ -196,8 +205,6 @@ glyph_positions_ptr placement_finder_ng::find_point_placement(pixel_position pos else x = -((*line_itr)->width() / 2.0); - //TODO: Rotate - text_line::const_iterator glyph_itr = (*line_itr)->begin(), glyph_end = (*line_itr)->end(); for (; glyph_itr != glyph_end; glyph_itr++) { diff --git a/src/text_properties.cpp b/src/text_properties.cpp index 194700048..062661168 100644 --- a/src/text_properties.cpp +++ b/src/text_properties.cpp @@ -54,6 +54,7 @@ text_symbolizer_properties::text_symbolizer_properties() : largest_bbox_only(true), text_ratio(0), wrap_width(0), + rotate_displacement(false), format(boost::make_shared()), tree_() { @@ -112,6 +113,8 @@ void text_symbolizer_properties::from_xml(xml_node const &sym, fontset_map const if (jalign_) jalign = *jalign_; optional orientation_ = sym.get_opt_attr("orientation"); if (orientation_) orientation = *orientation_; + optional rotate_displacement_ = sym.get_opt_attr("rotate-displacement"); + if (rotate_displacement_) rotate_displacement = *rotate_displacement_; optional dx = sym.get_opt_attr("dx"); if (dx) displacement.x = *dx; optional dy = sym.get_opt_attr("dy"); @@ -216,6 +219,10 @@ void text_symbolizer_properties::to_xml(boost::property_tree::ptree &node, { set_attr(node, "vertical-alignment", valign); } + if (rotate_displacement != dfl.rotate_displacement || explicit_defaults) + { + set_attr(node, "rotate-displacement", rotate_displacement); + } format->to_xml(node, explicit_defaults, *(dfl.format)); if (tree_) tree_->to_xml(node); } diff --git a/tests/visual_tests/styles/orientation.xml b/tests/visual_tests/styles/orientation.xml index 1ff3232e8..3bd9648c7 100644 --- a/tests/visual_tests/styles/orientation.xml +++ b/tests/visual_tests/styles/orientation.xml @@ -46,6 +46,21 @@ "XYZ" + + [nr] = '8' + "XYZ" + + + + [nr] = '9' + "XYZ" + + + + [nr] = '10' + "XYZ" + +