store displacement logic in std::function and delay calc until dx/dy are evaluated (layout)
This commit is contained in:
parent
562058aff6
commit
4166fcdd5d
5 changed files with 85 additions and 32 deletions
|
@ -36,7 +36,7 @@
|
||||||
#include <mapnik/symbolizer.hpp>
|
#include <mapnik/symbolizer.hpp>
|
||||||
// stl
|
// stl
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <functional>
|
||||||
// boost
|
// boost
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
#include <boost/property_tree/ptree_fwd.hpp>
|
#include <boost/property_tree/ptree_fwd.hpp>
|
||||||
|
@ -93,7 +93,7 @@ struct MAPNIK_DECL text_layout_properties
|
||||||
horizontal_alignment_e halign;
|
horizontal_alignment_e halign;
|
||||||
justify_alignment_e jalign;
|
justify_alignment_e jalign;
|
||||||
vertical_alignment_e valign;
|
vertical_alignment_e valign;
|
||||||
|
std::function<pixel_position(feature_impl const& feature, attributes const& attrs)> displacement_evaluator_;
|
||||||
};
|
};
|
||||||
|
|
||||||
using text_layout_properties_ptr = std::shared_ptr<text_layout_properties>;
|
using text_layout_properties_ptr = std::shared_ptr<text_layout_properties>;
|
||||||
|
|
|
@ -92,6 +92,7 @@ void text_layout::layout()
|
||||||
init_alignment();
|
init_alignment();
|
||||||
|
|
||||||
// Find text origin.
|
// Find text origin.
|
||||||
|
std::cerr << displacement_.x << "," << displacement_.y << " " << this << std::endl;
|
||||||
displacement_ = scale_factor_ * displacement_ + alignment_offset();
|
displacement_ = scale_factor_ * displacement_ + alignment_offset();
|
||||||
if (rotate_displacement_) displacement_ = displacement_.rotate(!orientation_);
|
if (rotate_displacement_) displacement_ = displacement_.rotate(!orientation_);
|
||||||
// Find layout bounds, expanded for rotation
|
// Find layout bounds, expanded for rotation
|
||||||
|
@ -230,17 +231,18 @@ void text_layout::shape_text(text_line & line)
|
||||||
shaper_type::shape_text(line, itemizer_, width_map_, font_manager_, scale_factor_);
|
shaper_type::shape_text(line, itemizer_, width_map_, font_manager_, scale_factor_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void text_layout::evaluate_properties(feature_impl const& feature, attributes const& attr)
|
void text_layout::evaluate_properties(feature_impl const& feature, attributes const& attrs)
|
||||||
{
|
{
|
||||||
double dx = boost::apply_visitor(extract_value<value_double>(feature,attr), properties_.dx);
|
// dx,dy
|
||||||
double dy = boost::apply_visitor(extract_value<value_double>(feature,attr), properties_.dy);
|
displacement_ = properties_.displacement_evaluator_(feature, attrs);
|
||||||
displacement_ = {dx, dy};
|
|
||||||
wrap_width_ = boost::apply_visitor(extract_value<value_double>(feature,attr), properties_.wrap_width);
|
|
||||||
double angle = boost::apply_visitor(extract_value<value_double>(feature,attr), properties_.orientation);
|
|
||||||
|
|
||||||
|
wrap_width_ = boost::apply_visitor(extract_value<value_double>(feature,attrs), properties_.wrap_width);
|
||||||
|
|
||||||
|
double angle = boost::apply_visitor(extract_value<value_double>(feature,attrs), properties_.orientation);
|
||||||
orientation_.init(angle * M_PI/ 180.0);
|
orientation_.init(angle * M_PI/ 180.0);
|
||||||
wrap_before_ = boost::apply_visitor(extract_value<value_bool>(feature,attr), properties_.wrap_before);
|
|
||||||
rotate_displacement_ = boost::apply_visitor(extract_value<value_bool>(feature,attr), properties_.rotate_displacement);
|
wrap_before_ = boost::apply_visitor(extract_value<value_bool>(feature,attrs), properties_.wrap_before);
|
||||||
|
rotate_displacement_ = boost::apply_visitor(extract_value<value_bool>(feature,attrs), properties_.rotate_displacement);
|
||||||
}
|
}
|
||||||
|
|
||||||
void text_layout::init_alignment()
|
void text_layout::init_alignment()
|
||||||
|
|
|
@ -35,17 +35,17 @@ bool text_placement_info_list::next()
|
||||||
if (state == 0) {
|
if (state == 0) {
|
||||||
properties = parent_->defaults;
|
properties = parent_->defaults;
|
||||||
} else {
|
} else {
|
||||||
if (state-1 >= parent_->list_.size()) return false;
|
if (state >= parent_->list_.size() + 1) return false;
|
||||||
properties = parent_->list_[state-1];
|
properties = parent_->list_[state-1];
|
||||||
}
|
}
|
||||||
state++;
|
++state;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
text_symbolizer_properties & text_placements_list::add()
|
text_symbolizer_properties & text_placements_list::add()
|
||||||
{
|
{
|
||||||
if (list_.size()) {
|
if (list_.size()) {
|
||||||
text_symbolizer_properties &last = list_.back();
|
text_symbolizer_properties & last = list_.back();
|
||||||
list_.push_back(last); //Preinitialize with old values
|
list_.push_back(last); //Preinitialize with old values
|
||||||
} else {
|
} else {
|
||||||
list_.push_back(defaults);
|
list_.push_back(defaults);
|
||||||
|
@ -65,7 +65,8 @@ text_placement_info_ptr text_placements_list::get_placement_info(double scale_fa
|
||||||
}
|
}
|
||||||
|
|
||||||
text_placements_list::text_placements_list()
|
text_placements_list::text_placements_list()
|
||||||
: text_placements(), list_(0) {}
|
: text_placements(),
|
||||||
|
list_(0) {}
|
||||||
|
|
||||||
void text_placements_list::add_expressions(expression_set & output) const
|
void text_placements_list::add_expressions(expression_set & output) const
|
||||||
{
|
{
|
||||||
|
@ -94,7 +95,7 @@ text_placements_ptr text_placements_list::from_xml(xml_node const& xml, fontset_
|
||||||
for( ;itr != end; ++itr)
|
for( ;itr != end; ++itr)
|
||||||
{
|
{
|
||||||
if (itr->is_text() || !itr->is("Placement")) continue;
|
if (itr->is_text() || !itr->is("Placement")) continue;
|
||||||
text_symbolizer_properties &p = list->add();
|
text_symbolizer_properties & p = list->add();
|
||||||
p.format = std::make_shared<char_properties>(*(p.format)); //Make a deep copy
|
p.format = std::make_shared<char_properties>(*(p.format)); //Make a deep copy
|
||||||
//p.layout_defaults = std::make_shared<text_layout_properties>(*(p.layout_defaults));
|
//p.layout_defaults = std::make_shared<text_layout_properties>(*(p.layout_defaults));
|
||||||
//TODO: This needs a real copy constructor for text_symbolizer_properties
|
//TODO: This needs a real copy constructor for text_symbolizer_properties
|
||||||
|
|
|
@ -63,37 +63,77 @@ bool text_placement_info_simple::next()
|
||||||
|
|
||||||
bool text_placement_info_simple::next_position_only()
|
bool text_placement_info_simple::next_position_only()
|
||||||
{
|
{
|
||||||
pixel_position const& pdisp = {0,0};// FIXME parent_->defaults.layout_defaults.displacement;
|
|
||||||
pixel_position displacement = {0,0};// FIXME properties.layout_defaults.displacement;
|
|
||||||
if (position_state >= parent_->direction_.size()) return false;
|
if (position_state >= parent_->direction_.size()) return false;
|
||||||
directions_e dir = parent_->direction_[position_state];
|
directions_e dir = parent_->direction_[position_state];
|
||||||
switch (dir) {
|
switch (dir)
|
||||||
|
{
|
||||||
case EXACT_POSITION:
|
case EXACT_POSITION:
|
||||||
displacement = pdisp;
|
properties.layout_defaults.displacement_evaluator_ = [this](feature_impl const& feature, attributes const& attrs)
|
||||||
|
{
|
||||||
|
double dx = boost::apply_visitor(extract_value<value_double>(feature,attrs), this->parent_->defaults.layout_defaults.dx);
|
||||||
|
double dy = boost::apply_visitor(extract_value<value_double>(feature,attrs), this->parent_->defaults.layout_defaults.dy);
|
||||||
|
return pixel_position(dx,dy);
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
case NORTH:
|
case NORTH:
|
||||||
displacement.set(0, -std::abs(pdisp.y));
|
properties.layout_defaults.displacement_evaluator_ = [this](feature_impl const& feature, attributes const& attrs)
|
||||||
|
{
|
||||||
|
double dy = boost::apply_visitor(extract_value<value_double>(feature,attrs), this->parent_->defaults.layout_defaults.dy);
|
||||||
|
return pixel_position(0,-std::abs(dy));
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
case EAST:
|
case EAST:
|
||||||
displacement.set(std::abs(pdisp.x), 0);
|
properties.layout_defaults.displacement_evaluator_ = [this](feature_impl const& feature, attributes const& attrs)
|
||||||
|
{
|
||||||
|
double dx = boost::apply_visitor(extract_value<value_double>(feature,attrs), this->parent_->defaults.layout_defaults.dx);
|
||||||
|
return pixel_position(std::abs(dx),0);
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
case SOUTH:
|
case SOUTH:
|
||||||
displacement.set(0, std::abs(pdisp.y));
|
properties.layout_defaults.displacement_evaluator_ = [this](feature_impl const& feature, attributes const& attrs)
|
||||||
|
{
|
||||||
|
double dy = boost::apply_visitor(extract_value<value_double>(feature,attrs), this->parent_->defaults.layout_defaults.dy);
|
||||||
|
return pixel_position(0,std::abs(dy));
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
case WEST:
|
case WEST:
|
||||||
displacement.set(-std::abs(pdisp.x), 0);
|
properties.layout_defaults.displacement_evaluator_ = [this](feature_impl const& feature, attributes const& attrs)
|
||||||
|
{
|
||||||
|
double dx = boost::apply_visitor(extract_value<value_double>(feature,attrs), this->parent_->defaults.layout_defaults.dx);
|
||||||
|
return pixel_position(-std::abs(dx),0);
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
case NORTHEAST:
|
case NORTHEAST:
|
||||||
displacement.set(std::abs(pdisp.x), -std::abs(pdisp.y));
|
properties.layout_defaults.displacement_evaluator_ = [this](feature_impl const& feature, attributes const& attrs)
|
||||||
|
{
|
||||||
|
double dx = boost::apply_visitor(extract_value<value_double>(feature,attrs), this->parent_->defaults.layout_defaults.dx);
|
||||||
|
double dy = boost::apply_visitor(extract_value<value_double>(feature,attrs), this->parent_->defaults.layout_defaults.dy);
|
||||||
|
return pixel_position(std::abs(dx),-std::abs(dy));
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
case SOUTHEAST:
|
case SOUTHEAST:
|
||||||
displacement.set(std::abs(pdisp.x), std::abs(pdisp.y));
|
properties.layout_defaults.displacement_evaluator_ = [this](feature_impl const& feature, attributes const& attrs)
|
||||||
|
{
|
||||||
|
double dx = boost::apply_visitor(extract_value<value_double>(feature,attrs), this->parent_->defaults.layout_defaults.dx);
|
||||||
|
double dy = boost::apply_visitor(extract_value<value_double>(feature,attrs), this->parent_->defaults.layout_defaults.dy);
|
||||||
|
return pixel_position(std::abs(dx),std::abs(dy));
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
case NORTHWEST:
|
case NORTHWEST:
|
||||||
displacement.set(-std::abs(pdisp.x), -std::abs(pdisp.y));
|
properties.layout_defaults.displacement_evaluator_ = [this](feature_impl const& feature, attributes const& attrs)
|
||||||
|
{
|
||||||
|
double dx = boost::apply_visitor(extract_value<value_double>(feature,attrs), this->parent_->defaults.layout_defaults.dx);
|
||||||
|
double dy = boost::apply_visitor(extract_value<value_double>(feature,attrs), this->parent_->defaults.layout_defaults.dy);
|
||||||
|
return pixel_position(-std::abs(dx),-std::abs(dy));
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
case SOUTHWEST:
|
case SOUTHWEST:
|
||||||
displacement.set(-std::abs(pdisp.x), std::abs(pdisp.y));
|
properties.layout_defaults.displacement_evaluator_ = [this](feature_impl const& feature, attributes const& attrs)
|
||||||
|
{
|
||||||
|
double dx = boost::apply_visitor(extract_value<value_double>(feature,attrs), this->parent_->defaults.layout_defaults.dx);
|
||||||
|
double dy = boost::apply_visitor(extract_value<value_double>(feature,attrs), this->parent_->defaults.layout_defaults.dy);
|
||||||
|
return pixel_position(-std::abs(dx),std::abs(dy));
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
MAPNIK_LOG_WARN(text_placements) << "Unknown placement";
|
MAPNIK_LOG_WARN(text_placements) << "Unknown placement";
|
||||||
|
@ -145,9 +185,9 @@ void text_placements_simple::set_positions(std::string const& positions)
|
||||||
|
|
||||||
std::string::const_iterator first = positions.begin(), last = positions.end();
|
std::string::const_iterator first = positions.begin(), last = positions.end();
|
||||||
qi::phrase_parse(first, last,
|
qi::phrase_parse(first, last,
|
||||||
(direction_name[push_back(phoenix::ref(direction_), _1)] % ',') >> *(',' >> float_[push_back(phoenix::ref(text_sizes_), _1)]),
|
(direction_name[push_back(phoenix::ref(direction_), _1)] % ',')
|
||||||
space
|
>> *(',' >> float_[push_back(phoenix::ref(text_sizes_), _1)]),
|
||||||
);
|
space);
|
||||||
if (first != last)
|
if (first != last)
|
||||||
{
|
{
|
||||||
MAPNIK_LOG_WARN(text_placements) << "Could not parse text_placement_simple placement string ('" << positions << "')";
|
MAPNIK_LOG_WARN(text_placements) << "Could not parse text_placement_simple placement string ('" << positions << "')";
|
||||||
|
|
|
@ -200,7 +200,7 @@ void set_property_from_xml(symbolizer_base::value_type & val, char const* name,
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
optional<target_type> val_ = node.get_opt_attr<target_type>(name);
|
optional<target_type> val_ = node.get_opt_attr<target_type>(name);
|
||||||
//if (val_) std::cerr << std::string(name) << " = " << *val_ << std::endl;
|
if (val_) std::cerr << std::string(name) << ":" << *val_ << std::endl;
|
||||||
if (val_) val = *val_;
|
if (val_) val = *val_;
|
||||||
}
|
}
|
||||||
catch (config_error const& ex)
|
catch (config_error const& ex)
|
||||||
|
@ -217,7 +217,15 @@ void set_property_from_xml(symbolizer_base::value_type & val, char const* name,
|
||||||
text_layout_properties::text_layout_properties()
|
text_layout_properties::text_layout_properties()
|
||||||
: halign(H_AUTO),
|
: halign(H_AUTO),
|
||||||
jalign(J_AUTO),
|
jalign(J_AUTO),
|
||||||
valign(V_AUTO) {}
|
valign(V_AUTO)
|
||||||
|
{
|
||||||
|
displacement_evaluator_ = [this](feature_impl const& feature, attributes const& attrs)
|
||||||
|
{ double dx_ = boost::apply_visitor(extract_value<value_double>(feature,attrs), this->dx);
|
||||||
|
double dy_ = boost::apply_visitor(extract_value<value_double>(feature,attrs), this->dy);
|
||||||
|
std::cerr << dx_ << "," << dy_ << std::endl;
|
||||||
|
return pixel_position(dx_,dy_);};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void text_layout_properties::from_xml(xml_node const &node)
|
void text_layout_properties::from_xml(xml_node const &node)
|
||||||
{
|
{
|
||||||
|
@ -289,6 +297,8 @@ void text_layout_properties::to_xml(boost::property_tree::ptree & node,
|
||||||
|
|
||||||
void text_layout_properties::add_expressions(expression_set& output) const
|
void text_layout_properties::add_expressions(expression_set& output) const
|
||||||
{
|
{
|
||||||
|
if (is_expression(dx)) output.insert(boost::get<expression_ptr>(dx));
|
||||||
|
if (is_expression(dy)) output.insert(boost::get<expression_ptr>(dy));
|
||||||
if (is_expression(orientation)) output.insert(boost::get<expression_ptr>(orientation));
|
if (is_expression(orientation)) output.insert(boost::get<expression_ptr>(orientation));
|
||||||
if (is_expression(wrap_width)) output.insert(boost::get<expression_ptr>(wrap_width));
|
if (is_expression(wrap_width)) output.insert(boost::get<expression_ptr>(wrap_width));
|
||||||
if (is_expression(wrap_before)) output.insert(boost::get<expression_ptr>(wrap_before));
|
if (is_expression(wrap_before)) output.insert(boost::get<expression_ptr>(wrap_before));
|
||||||
|
|
Loading…
Reference in a new issue