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>
|
||||
// stl
|
||||
#include <map>
|
||||
|
||||
#include <functional>
|
||||
// boost
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/property_tree/ptree_fwd.hpp>
|
||||
|
@ -93,7 +93,7 @@ struct MAPNIK_DECL text_layout_properties
|
|||
horizontal_alignment_e halign;
|
||||
justify_alignment_e jalign;
|
||||
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>;
|
||||
|
|
|
@ -92,6 +92,7 @@ void text_layout::layout()
|
|||
init_alignment();
|
||||
|
||||
// Find text origin.
|
||||
std::cerr << displacement_.x << "," << displacement_.y << " " << this << std::endl;
|
||||
displacement_ = scale_factor_ * displacement_ + alignment_offset();
|
||||
if (rotate_displacement_) displacement_ = displacement_.rotate(!orientation_);
|
||||
// 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_);
|
||||
}
|
||||
|
||||
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);
|
||||
double dy = boost::apply_visitor(extract_value<value_double>(feature,attr), properties_.dy);
|
||||
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);
|
||||
// dx,dy
|
||||
displacement_ = properties_.displacement_evaluator_(feature, attrs);
|
||||
|
||||
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);
|
||||
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()
|
||||
|
|
|
@ -35,17 +35,17 @@ bool text_placement_info_list::next()
|
|||
if (state == 0) {
|
||||
properties = parent_->defaults;
|
||||
} else {
|
||||
if (state-1 >= parent_->list_.size()) return false;
|
||||
if (state >= parent_->list_.size() + 1) return false;
|
||||
properties = parent_->list_[state-1];
|
||||
}
|
||||
state++;
|
||||
++state;
|
||||
return true;
|
||||
}
|
||||
|
||||
text_symbolizer_properties & text_placements_list::add()
|
||||
{
|
||||
if (list_.size()) {
|
||||
text_symbolizer_properties &last = list_.back();
|
||||
text_symbolizer_properties & last = list_.back();
|
||||
list_.push_back(last); //Preinitialize with old values
|
||||
} else {
|
||||
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_(0) {}
|
||||
: text_placements(),
|
||||
list_(0) {}
|
||||
|
||||
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)
|
||||
{
|
||||
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.layout_defaults = std::make_shared<text_layout_properties>(*(p.layout_defaults));
|
||||
//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()
|
||||
{
|
||||
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;
|
||||
directions_e dir = parent_->direction_[position_state];
|
||||
switch (dir) {
|
||||
switch (dir)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
default:
|
||||
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();
|
||||
qi::phrase_parse(first, last,
|
||||
(direction_name[push_back(phoenix::ref(direction_), _1)] % ',') >> *(',' >> float_[push_back(phoenix::ref(text_sizes_), _1)]),
|
||||
space
|
||||
);
|
||||
(direction_name[push_back(phoenix::ref(direction_), _1)] % ',')
|
||||
>> *(',' >> float_[push_back(phoenix::ref(text_sizes_), _1)]),
|
||||
space);
|
||||
if (first != last)
|
||||
{
|
||||
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
|
||||
{
|
||||
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_;
|
||||
}
|
||||
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()
|
||||
: halign(H_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)
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
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(wrap_width)) output.insert(boost::get<expression_ptr>(wrap_width));
|
||||
if (is_expression(wrap_before)) output.insert(boost::get<expression_ptr>(wrap_before));
|
||||
|
|
Loading…
Reference in a new issue