mirror of
https://github.com/mapnik/mapnik.git
synced 2026-02-01 17:36:36 +00:00
text displacement expr : more re-factoring and various fixes
This commit is contained in:
parent
1f17620e18
commit
6c03a617a5
@ -163,7 +163,7 @@ public:
|
||||
|
||||
inline text_layout_vector::const_iterator begin() const { return layouts_.begin(); }
|
||||
inline text_layout_vector::const_iterator end() const { return layouts_.end(); }
|
||||
|
||||
inline text_layout_ptr const& back() const { return layouts_.back(); }
|
||||
inline mapnik::value_unicode_string const& text() const { return text_; }
|
||||
|
||||
inline unsigned glyphs_count() const { return glyphs_count_; }
|
||||
|
||||
@ -66,7 +66,7 @@ public:
|
||||
private:
|
||||
bool single_line_placement(vertex_cache &pp, text_upright_e orientation);
|
||||
// Moves dx pixels but makes sure not to fall of the end.
|
||||
void path_move_dx(vertex_cache &pp);
|
||||
void path_move_dx(vertex_cache &pp, double dx);
|
||||
// Normalize angle in range [-pi, +pi].
|
||||
static double normalize_angle(double angle);
|
||||
// Adjusts user defined spacing to place an integer number of labels.
|
||||
|
||||
@ -62,23 +62,23 @@ protected:
|
||||
bool clipped_;
|
||||
|
||||
//Processing
|
||||
/* Using list instead of vector, because we delete random elements and need iterators to stay valid. */
|
||||
/** Remaining geometries to be processed. */
|
||||
// Using list instead of vector, because we delete random elements and need iterators to stay valid.
|
||||
// Remaining geometries to be processed.
|
||||
std::list<geometry_type*> geometries_to_process_;
|
||||
/** Remaining points to be processed. */
|
||||
// Remaining points to be processed.
|
||||
std::list<pixel_position> points_;
|
||||
/** Geometry currently being processed. */
|
||||
// Geometry currently being processed.
|
||||
std::list<geometry_type*>::iterator geo_itr_;
|
||||
/** Point currently being processed. */
|
||||
// Point currently being processed.
|
||||
std::list<pixel_position>::iterator point_itr_;
|
||||
/** Use point placement. Otherwise line placement is used. */
|
||||
// Use point placement. Otherwise line placement is used.
|
||||
bool point_placement_;
|
||||
|
||||
text_placement_info_ptr placement_;
|
||||
};
|
||||
|
||||
/** Helper object that does all the TextSymbolizer placement finding
|
||||
* work except actually rendering the object. */
|
||||
// Helper object that does all the TextSymbolizer placement finding
|
||||
// work except actually rendering the object.
|
||||
|
||||
class text_symbolizer_helper : public base_symbolizer_helper
|
||||
{
|
||||
@ -92,8 +92,8 @@ public:
|
||||
unsigned height,
|
||||
double scale_factor,
|
||||
CoordTransform const& t,
|
||||
FaceManagerT &font_manager,
|
||||
DetectorT &detector,
|
||||
FaceManagerT & font_manager,
|
||||
DetectorT & detector,
|
||||
box2d<double> const& query_extent);
|
||||
|
||||
template <typename FaceManagerT, typename DetectorT>
|
||||
@ -104,12 +104,12 @@ public:
|
||||
unsigned width,
|
||||
unsigned height,
|
||||
double scale_factor,
|
||||
CoordTransform const &t,
|
||||
FaceManagerT &font_manager,
|
||||
DetectorT &detector,
|
||||
CoordTransform const& t,
|
||||
FaceManagerT & font_manager,
|
||||
DetectorT & detector,
|
||||
box2d<double> const& query_extent);
|
||||
|
||||
/** Return all placements.*/
|
||||
// Return all placements.
|
||||
placements_list const& get();
|
||||
protected:
|
||||
bool next_point_placement();
|
||||
@ -117,7 +117,7 @@ protected:
|
||||
|
||||
placement_finder finder_;
|
||||
|
||||
/** Place text at points on a line instead of following the line (used for ShieldSymbolizer) .*/
|
||||
// Place text at points on a line instead of following the line (used for ShieldSymbolizer)
|
||||
bool points_on_line_;
|
||||
|
||||
//ShieldSymbolizer only
|
||||
|
||||
@ -76,7 +76,7 @@ struct MAPNIK_DECL text_layout_properties
|
||||
void from_xml(xml_node const &sym);
|
||||
// Save all values to XML ptree (but does not create a new parent node!).
|
||||
void to_xml(boost::property_tree::ptree & node, bool explicit_defaults,
|
||||
text_layout_properties const& dfl=text_layout_properties()) const;
|
||||
text_layout_properties const& dfl = text_layout_properties()) const;
|
||||
|
||||
// Get a list of all expressions used in any placement.
|
||||
// This function is used to collect attributes.
|
||||
@ -105,16 +105,15 @@ struct MAPNIK_DECL text_symbolizer_properties
|
||||
{
|
||||
text_symbolizer_properties();
|
||||
// Load only placement related values from XML ptree.
|
||||
void placement_properties_from_xml(xml_node const &sym);
|
||||
void placement_properties_from_xml(xml_node const& sym);
|
||||
// Load all values from XML ptree.
|
||||
void from_xml(xml_node const &sym, fontset_map const & fontsets);
|
||||
void from_xml(xml_node const &sym, fontset_map const& fontsets);
|
||||
// Save all values to XML ptree (but does not create a new parent node!).
|
||||
void to_xml(boost::property_tree::ptree &node, bool explicit_defaults,
|
||||
text_symbolizer_properties const &dfl=text_symbolizer_properties()) const;
|
||||
text_symbolizer_properties const& dfl = text_symbolizer_properties()) const;
|
||||
|
||||
// Takes a feature and produces formated text as output.
|
||||
// The output object has to be created by the caller and passed in for thread safety.
|
||||
|
||||
void process(text_layout &output, feature_impl const& feature, attributes const& vars) const;
|
||||
// Automatically create processing instructions for a single expression.
|
||||
void set_old_style_expression(expression_ptr expr);
|
||||
|
||||
@ -94,7 +94,6 @@ void text_layout::layout()
|
||||
// Find text origin.
|
||||
displacement_ = scale_factor_ * displacement_ + alignment_offset();
|
||||
if (rotate_displacement_) displacement_ = displacement_.rotate(!orientation_);
|
||||
|
||||
// Find layout bounds, expanded for rotation
|
||||
rotated_box2d(bounds_, orientation_, displacement_, width_, height_);
|
||||
}
|
||||
|
||||
@ -117,7 +117,7 @@ bool placement_finder::find_point_placement(pixel_position const& pos)
|
||||
text_layout const& layout = *layout_ptr;
|
||||
rotation const& orientation = layout.orientation();
|
||||
|
||||
/* Find text origin. */
|
||||
// Find text origin.
|
||||
pixel_position layout_center = pos + layout.displacement();
|
||||
|
||||
if (!base_point_set)
|
||||
@ -129,7 +129,7 @@ bool placement_finder::find_point_placement(pixel_position const& pos)
|
||||
box2d<double> bbox = layout.bounds();
|
||||
bbox.re_center(layout_center.x, layout_center.y);
|
||||
|
||||
/* For point placements it is faster to just check the bounding box. */
|
||||
// For point placements it is faster to just check the bounding box.
|
||||
if (collision(bbox)) return false;
|
||||
|
||||
if (layout.num_lines()) bboxes.push_back(std::move(bbox));
|
||||
@ -137,12 +137,12 @@ bool placement_finder::find_point_placement(pixel_position const& pos)
|
||||
pixel_position layout_offset = layout_center - glyphs->get_base_point();
|
||||
layout_offset.y = -layout_offset.y;
|
||||
|
||||
/* IMPORTANT NOTE:
|
||||
x and y are relative to the center of the text
|
||||
coordinate system:
|
||||
x: grows from left to right
|
||||
y: grows from bottom to top (opposite of normal computer graphics)
|
||||
*/
|
||||
// IMPORTANT NOTE:
|
||||
// x and y are relative to the center of the text
|
||||
// coordinate system:
|
||||
// x: grows from left to right
|
||||
// y: grows from bottom to top (opposite of normal computer graphics)
|
||||
|
||||
double x, y;
|
||||
|
||||
// set for upper left corner of text envelope for the first line, top left of first character
|
||||
@ -166,7 +166,7 @@ bool placement_finder::find_point_placement(pixel_position const& pos)
|
||||
}
|
||||
}
|
||||
|
||||
/* add_marker first checks for collision and then updates the detector.*/
|
||||
// add_marker first checks for collision and then updates the detector.
|
||||
if (has_marker_ && !add_marker(glyphs, pos)) return false;
|
||||
|
||||
for (box2d<double> const& bbox : bboxes)
|
||||
@ -199,7 +199,7 @@ bool placement_finder::find_line_placements(T & path, bool points)
|
||||
{
|
||||
if ((pp.length() < info_.properties.minimum_path_length * scale_factor_)
|
||||
||
|
||||
(pp.length() <= 0.001) /* Clipping removed whole geometry */
|
||||
(pp.length() <= 0.001) // Clipping removed whole geometry
|
||||
||
|
||||
(pp.length() < layouts_.width()))
|
||||
{
|
||||
@ -222,7 +222,8 @@ bool placement_finder::find_line_placements(T & path, bool points)
|
||||
{
|
||||
pp.forward(pp.length());
|
||||
}
|
||||
path_move_dx(pp);
|
||||
double dx = layouts_.back()->displacement().x;
|
||||
if (dx != 0.0) path_move_dx(pp, dx);
|
||||
do
|
||||
{
|
||||
tolerance_iterator tolerance_offset(info_.properties.label_position_tolerance * scale_factor_, spacing); //TODO: Handle halign
|
||||
@ -264,7 +265,8 @@ bool placement_finder::single_line_placement(vertex_cache &pp, text_upright_e or
|
||||
pixel_position align_offset = layout.alignment_offset();
|
||||
pixel_position const& layout_displacement = layout.displacement();
|
||||
double sign = (real_orientation == UPRIGHT_LEFT) ? -1 : 1;
|
||||
double offset = align_offset.y + layout_displacement.y * scale_factor_ + sign * layout.height()/2.;
|
||||
//double offset = align_offset.y + layout_displacement.y * scale_factor_ + sign * layout.height()/2.0;
|
||||
double offset = layout_displacement.y + 0.5 * sign * layout.height();
|
||||
|
||||
for (auto const& line : layout)
|
||||
{
|
||||
@ -350,14 +352,14 @@ bool placement_finder::single_line_placement(vertex_cache &pp, text_upright_e or
|
||||
return true;
|
||||
}
|
||||
|
||||
void placement_finder::path_move_dx(vertex_cache & pp)
|
||||
void placement_finder::path_move_dx(vertex_cache & pp, double dx)
|
||||
{
|
||||
double dx = 0.0;// FIXME info_.properties.layout_defaults.displacement.x * scale_factor_;
|
||||
if (dx != 0.0)
|
||||
{
|
||||
//double dx = 0.0;// FIXME info_.properties.layout_defaults.displacement.x * scale_factor_;
|
||||
// if (dx != 0.0)
|
||||
// {
|
||||
vertex_cache::state state = pp.save_state();
|
||||
if (!pp.move(dx)) pp.restore_state(state);
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
double placement_finder::normalize_angle(double angle)
|
||||
|
||||
@ -63,6 +63,7 @@ bool text_placement_info_simple::next()
|
||||
|
||||
bool text_placement_info_simple::next_position_only()
|
||||
{
|
||||
//std::cerr << "next_position_only()" << std::endl;
|
||||
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;
|
||||
@ -98,12 +99,11 @@ bool text_placement_info_simple::next_position_only()
|
||||
default:
|
||||
MAPNIK_LOG_WARN(text_placements) << "Unknown placement";
|
||||
}
|
||||
position_state++;
|
||||
++position_state;
|
||||
return true;
|
||||
}
|
||||
|
||||
text_placement_info_ptr text_placements_simple::get_placement_info(
|
||||
double scale_factor) const
|
||||
text_placement_info_ptr text_placements_simple::get_placement_info(double scale_factor) const
|
||||
{
|
||||
return std::make_unique<text_placement_info_simple>(this, scale_factor);
|
||||
}
|
||||
|
||||
@ -34,7 +34,6 @@
|
||||
#include <mapnik/text/placements/base.hpp>
|
||||
#include <mapnik/text/placements/dummy.hpp>
|
||||
|
||||
|
||||
//agg
|
||||
#include "agg_conv_clip_polyline.h"
|
||||
|
||||
@ -60,7 +59,7 @@ base_symbolizer_helper::base_symbolizer_helper(
|
||||
placement_(get<text_placements_ptr>(sym_, keys::text_placements_)->get_placement_info(scale_factor))
|
||||
{
|
||||
initialize_geometries();
|
||||
if (!geometries_to_process_.size()) return;
|
||||
if (!geometries_to_process_.size()) return; // FIXME - bad practise
|
||||
initialize_points();
|
||||
}
|
||||
|
||||
@ -180,7 +179,7 @@ text_symbolizer_helper::text_symbolizer_helper(
|
||||
proj_transform const& prj_trans,
|
||||
unsigned width, unsigned height, double scale_factor,
|
||||
CoordTransform const& t, FaceManagerT & font_manager,
|
||||
DetectorT &detector, const box2d<double> &query_extent)
|
||||
DetectorT &detector, box2d<double> const& query_extent)
|
||||
: base_symbolizer_helper(sym, feature, vars, prj_trans, width, height, scale_factor, t, query_extent),
|
||||
finder_(feature, vars, detector, dims_, *placement_, font_manager, scale_factor),
|
||||
points_on_line_(false)
|
||||
|
||||
@ -102,18 +102,18 @@ void text_symbolizer_properties::placement_properties_from_xml(xml_node const &s
|
||||
if (largest_bbox_only_) largest_bbox_only = *largest_bbox_only_;
|
||||
}
|
||||
|
||||
void text_symbolizer_properties::from_xml(xml_node const &sym, fontset_map const & fontsets)
|
||||
void text_symbolizer_properties::from_xml(xml_node const& node, fontset_map const& fontsets)
|
||||
{
|
||||
placement_properties_from_xml(sym);
|
||||
placement_properties_from_xml(node);
|
||||
|
||||
optional<double> max_char_angle_delta_ = sym.get_opt_attr<double>("max-char-angle-delta");
|
||||
optional<double> max_char_angle_delta_ = node.get_opt_attr<double>("max-char-angle-delta");
|
||||
if (max_char_angle_delta_) max_char_angle_delta=(*max_char_angle_delta_)*(M_PI/180);
|
||||
optional<text_upright_e> upright_ = sym.get_opt_attr<text_upright_e>("upright");
|
||||
optional<text_upright_e> upright_ = node.get_opt_attr<text_upright_e>("upright");
|
||||
if (upright_) upright = *upright_;
|
||||
|
||||
layout_defaults.from_xml(sym);
|
||||
layout_defaults.from_xml(node);
|
||||
|
||||
optional<expression_ptr> name_ = sym.get_opt_attr<expression_ptr>("name");
|
||||
optional<expression_ptr> name_ = node.get_opt_attr<expression_ptr>("name");
|
||||
if (name_)
|
||||
{
|
||||
MAPNIK_LOG_WARN(text_placements) << "Using 'name' in TextSymbolizer/ShieldSymbolizer is deprecated!";
|
||||
@ -121,8 +121,8 @@ void text_symbolizer_properties::from_xml(xml_node const &sym, fontset_map const
|
||||
set_old_style_expression(*name_);
|
||||
}
|
||||
|
||||
format->from_xml(sym, fontsets);
|
||||
formatting::node_ptr n(formatting::node::from_xml(sym));
|
||||
format->from_xml(node, fontsets);
|
||||
formatting::node_ptr n(formatting::node::from_xml(node));
|
||||
if (n) set_format_tree(n);
|
||||
}
|
||||
|
||||
@ -193,7 +193,6 @@ void text_symbolizer_properties::set_old_style_expression(expression_ptr expr)
|
||||
}
|
||||
|
||||
// text_layout_properties
|
||||
|
||||
template <typename T>
|
||||
void set_property_from_xml(symbolizer_base::value_type & val, char const* name, xml_node const& node)
|
||||
{
|
||||
@ -201,6 +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_) val = *val_;
|
||||
}
|
||||
catch (config_error const& ex)
|
||||
@ -223,7 +223,6 @@ void text_layout_properties::from_xml(xml_node const &node)
|
||||
{
|
||||
set_property_from_xml<double>(dx, "dx", node);
|
||||
set_property_from_xml<double>(dy, "dy", node);
|
||||
|
||||
optional<vertical_alignment_e> valign_ = node.get_opt_attr<vertical_alignment_e>("vertical-alignment");
|
||||
if (valign_) valign = *valign_;
|
||||
optional<horizontal_alignment_e> halign_ = node.get_opt_attr<horizontal_alignment_e>("horizontal-alignment");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user