Update symbolizer_helpers to support new placement finder.
This commit is contained in:
parent
dc9106d444
commit
f0937451a2
8 changed files with 101 additions and 60 deletions
|
@ -30,6 +30,7 @@
|
|||
#include <mapnik/marker.hpp>
|
||||
#include <mapnik/marker_cache.hpp>
|
||||
#include <mapnik/text_path.hpp>
|
||||
#include <mapnik/text/placement_finder_ng.hpp>
|
||||
|
||||
//boost
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
@ -40,8 +41,6 @@ namespace mapnik {
|
|||
typedef boost::ptr_vector<text_path> placements_type;
|
||||
template <typename DetectorT> class placement_finder;
|
||||
|
||||
class text_layout;
|
||||
typedef boost::shared_ptr<text_layout> text_layout_ptr;
|
||||
|
||||
/** Helper object that does all the TextSymbolizer placment finding
|
||||
* work except actually rendering the object. */
|
||||
|
@ -63,16 +62,15 @@ public:
|
|||
/** Return next placement.
|
||||
* If no more placements are found false is returned.
|
||||
*/
|
||||
bool next();
|
||||
glyph_positions_ptr next();
|
||||
|
||||
/** Get current placement. next() has to be called before! */
|
||||
placements_type & placements() const;
|
||||
protected:
|
||||
bool next_point_placement();
|
||||
bool next_line_placement();
|
||||
glyph_positions_ptr next_point_placement();
|
||||
glyph_positions_ptr next_line_placement();
|
||||
bool next_placement();
|
||||
void initialize_geometries();
|
||||
void initialize_points();
|
||||
void update_detector(glyph_positions_ptr glyphs);
|
||||
|
||||
//Input
|
||||
text_symbolizer const& sym_;
|
||||
|
@ -107,7 +105,7 @@ protected:
|
|||
bool points_on_line_;
|
||||
|
||||
text_placement_info_ptr placement_;
|
||||
boost::shared_ptr<placement_finder<DetectorT> > finder_;
|
||||
placement_finder_ng finder_;
|
||||
};
|
||||
|
||||
template <typename FaceManagerT, typename DetectorT>
|
||||
|
@ -175,6 +173,7 @@ protected:
|
|||
using text_symbolizer_helper<FaceManagerT, DetectorT>::point_placement_;
|
||||
using text_symbolizer_helper<FaceManagerT, DetectorT>::angle_;
|
||||
using text_symbolizer_helper<FaceManagerT, DetectorT>::finder_;
|
||||
using text_symbolizer_helper<FaceManagerT, DetectorT>::layout_;
|
||||
};
|
||||
} //namespace
|
||||
#endif // SYMBOLIZER_HELPERS_HPP
|
||||
|
|
|
@ -41,11 +41,18 @@ namespace mapnik
|
|||
/** This class stores all glyphs in a format run (i.e. conscutive glyphs with the same format). */
|
||||
class format_run
|
||||
{
|
||||
char_properties_ptr properties;
|
||||
public:
|
||||
format_run(char_properties_ptr properties, double text_height);
|
||||
std::vector<glyph_info> const& glyphs() const { return glyphs_; }
|
||||
void add_glyph(glyph_info const& info);
|
||||
double line_height() const { return line_height_; }
|
||||
double text_height() const { return text_height_; }
|
||||
private:
|
||||
char_properties_ptr properties_;
|
||||
std::vector<glyph_info> glyphs_;
|
||||
double width_;
|
||||
double text_height_;
|
||||
double line_height_;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<format_run> format_run_ptr;
|
||||
|
@ -61,13 +68,13 @@ typedef boost::shared_ptr<format_run> format_run_ptr;
|
|||
class text_line
|
||||
{
|
||||
public:
|
||||
double max_text_height; //Height of the largest format run in this run.
|
||||
double max_line_height; //Includes line spacing
|
||||
text_line();
|
||||
std::vector<format_run_ptr> const& runs() const { return runs_; }
|
||||
void add_run(format_run_ptr);
|
||||
|
||||
void add_run(format_run_ptr run);
|
||||
private:
|
||||
std::vector<format_run_ptr> runs_;
|
||||
double max_line_height; //Includes line spacing
|
||||
double max_text_height; //Height of the largest format run in this run.
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<text_line> text_line_ptr;
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
//mapnik
|
||||
#include <mapnik/box2d.hpp>
|
||||
|
||||
//stl
|
||||
#include <list>
|
||||
|
||||
//boost
|
||||
#include <boost/utility.hpp>
|
||||
|
@ -42,10 +44,10 @@ typedef feature_impl Feature;
|
|||
class text_layout;
|
||||
typedef boost::shared_ptr<text_layout> text_layout_ptr;
|
||||
|
||||
class placement_positions
|
||||
class glyph_positions
|
||||
{
|
||||
public:
|
||||
placement_positions(text_layout_ptr layout);
|
||||
glyph_positions(text_layout_ptr layout);
|
||||
void point_placement(double x, double y);
|
||||
private:
|
||||
double x_;
|
||||
|
@ -53,7 +55,9 @@ private:
|
|||
bool point_;
|
||||
text_layout_ptr layout_;
|
||||
};
|
||||
typedef boost::shared_ptr<placement_positions> placement_positions_ptr;
|
||||
typedef boost::shared_ptr<glyph_positions> glyph_positions_ptr;
|
||||
|
||||
//typedef std::list<placement_positions_ptr> placement_positions_list;
|
||||
|
||||
class placement_finder_ng : boost::noncopyable
|
||||
{
|
||||
|
@ -63,7 +67,7 @@ public:
|
|||
box2d<double> const& extent);
|
||||
|
||||
/** Try to place a single label at the given point. */
|
||||
placement_positions_ptr find_point_placement(text_layout_ptr layout, double pos_x, double pos_y, double angle=0.0);
|
||||
glyph_positions_ptr find_point_placement(text_layout_ptr layout, double pos_x, double pos_y, double angle=0.0);
|
||||
private:
|
||||
Feature const& feature_;
|
||||
DetectorType const& detector_;
|
||||
|
|
|
@ -41,13 +41,10 @@ void agg_renderer<T>::process(text_symbolizer const& sym,
|
|||
|
||||
text_renderer<T> ren(*current_buffer_, font_manager_, *(font_manager_.get_stroker()), sym.comp_op());
|
||||
|
||||
while (helper.next())
|
||||
glyph_positions_ptr glyphs;
|
||||
while ((glyphs = helper.next()))
|
||||
{
|
||||
placements_type &placements = helper.placements();
|
||||
for (unsigned int ii = 0; ii < placements.size(); ++ii)
|
||||
{
|
||||
ren.render(placements[ii].center);
|
||||
}
|
||||
ren.render(glyphs);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1203,6 +1203,7 @@ void cairo_renderer_base::start_map_processing(Map const& map)
|
|||
cairo_context context(context_);
|
||||
context.set_operator(sym.comp_op());
|
||||
|
||||
#if 0
|
||||
while (helper.next())
|
||||
{
|
||||
placements_type &placements = helper.placements();
|
||||
|
@ -1215,6 +1216,9 @@ void cairo_renderer_base::start_map_processing(Map const& map)
|
|||
context.add_text(placements[ii], face_manager_, font_manager_);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#warning CAIRO: Shield symbolizer rendering disabled!
|
||||
#endif
|
||||
}
|
||||
|
||||
void cairo_renderer_base::process(line_pattern_symbolizer const& sym,
|
||||
|
@ -1629,6 +1633,7 @@ void cairo_renderer_base::start_map_processing(Map const& map)
|
|||
cairo_context context(context_);
|
||||
context.set_operator(sym.comp_op());
|
||||
|
||||
#if 0
|
||||
while (helper.next()) {
|
||||
placements_type &placements = helper.placements();
|
||||
for (unsigned int ii = 0; ii < placements.size(); ++ii)
|
||||
|
@ -1636,8 +1641,12 @@ void cairo_renderer_base::start_map_processing(Map const& map)
|
|||
context.add_text(placements[ii], face_manager_, font_manager_);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#warning CAIRO: Text rendering disabled
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template class cairo_renderer<Cairo::Surface>;
|
||||
template class cairo_renderer<Cairo::Context>;
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ text_symbolizer_helper<FaceManagerT, DetectorT>::text_symbolizer_helper(const te
|
|||
angle_(0.0),
|
||||
placement_valid_(false),
|
||||
points_on_line_(false),
|
||||
finder_()
|
||||
finder_(feature, detector, dims_)
|
||||
{
|
||||
initialize_geometries();
|
||||
if (!geometries_to_process_.size()) return;
|
||||
|
@ -55,9 +55,9 @@ text_symbolizer_helper<FaceManagerT, DetectorT>::text_symbolizer_helper(const te
|
|||
}
|
||||
|
||||
template <typename FaceManagerT, typename DetectorT>
|
||||
bool text_symbolizer_helper<FaceManagerT, DetectorT>::next()
|
||||
glyph_positions_ptr text_symbolizer_helper<FaceManagerT, DetectorT>::next()
|
||||
{
|
||||
if (!placement_valid_) return false;
|
||||
if (!placement_valid_) return glyph_positions_ptr();
|
||||
if (point_placement_)
|
||||
return next_point_placement();
|
||||
else
|
||||
|
@ -65,14 +65,14 @@ bool text_symbolizer_helper<FaceManagerT, DetectorT>::next()
|
|||
}
|
||||
|
||||
template <typename FaceManagerT, typename DetectorT>
|
||||
bool text_symbolizer_helper<FaceManagerT, DetectorT>::next_line_placement()
|
||||
glyph_positions_ptr text_symbolizer_helper<FaceManagerT, DetectorT>::next_line_placement()
|
||||
{
|
||||
while (!geometries_to_process_.empty())
|
||||
{
|
||||
if (geo_itr_ == geometries_to_process_.end())
|
||||
{
|
||||
//Just processed the last geometry. Try next placement.
|
||||
if (!next_placement()) return false; //No more placements
|
||||
if (!next_placement()) return glyph_positions_ptr(); //No more placements
|
||||
//Start again from begin of list
|
||||
geo_itr_ = geometries_to_process_.begin();
|
||||
continue; //Reexecute size check
|
||||
|
@ -80,10 +80,11 @@ bool text_symbolizer_helper<FaceManagerT, DetectorT>::next_line_placement()
|
|||
|
||||
typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type;
|
||||
typedef coord_transform<CoordTransform,clipped_geometry_type> path_type;
|
||||
|
||||
clipped_geometry_type clipped(**geo_itr_);
|
||||
clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy());
|
||||
path_type path(t_, clipped, prj_trans_);
|
||||
finder_->clear_placements();
|
||||
#if 0
|
||||
if (points_on_line_) {
|
||||
finder_->find_point_placements(path);
|
||||
} else {
|
||||
|
@ -102,42 +103,44 @@ bool text_symbolizer_helper<FaceManagerT, DetectorT>::next_line_placement()
|
|||
feature_, t_, writer_.second);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
//No placement for this geometry. Keep it in geometries_to_process_ for next try.
|
||||
geo_itr_++;
|
||||
}
|
||||
return false;
|
||||
return glyph_positions_ptr();
|
||||
}
|
||||
|
||||
template <typename FaceManagerT, typename DetectorT>
|
||||
bool text_symbolizer_helper<FaceManagerT, DetectorT>::next_point_placement()
|
||||
glyph_positions_ptr text_symbolizer_helper<FaceManagerT, DetectorT>::next_point_placement()
|
||||
{
|
||||
while (!points_.empty())
|
||||
{
|
||||
if (point_itr_ == points_.end())
|
||||
{
|
||||
//Just processed the last point. Try next placement.
|
||||
if (!next_placement()) return false; //No more placements
|
||||
if (!next_placement()) return glyph_positions_ptr(); //No more placements
|
||||
//Start again from begin of list
|
||||
point_itr_ = points_.begin();
|
||||
continue; //Reexecute size check
|
||||
}
|
||||
return false; //TODO
|
||||
finder_->clear_placements();
|
||||
finder_->find_point_placement(point_itr_->first, point_itr_->second, angle_);
|
||||
if (!finder_->get_results().empty())
|
||||
glyph_positions_ptr glyphs = finder_.find_point_placement(
|
||||
layout_, point_itr_->first, point_itr_->second, angle_);
|
||||
if (glyphs)
|
||||
{
|
||||
//Found a placement
|
||||
point_itr_ = points_.erase(point_itr_);
|
||||
#if 0
|
||||
if (writer_.first) writer_.first->add_text(
|
||||
finder_->get_results(), finder_->get_extents(),
|
||||
feature_, t_, writer_.second);
|
||||
finder_->update_detector();
|
||||
return true;
|
||||
#endif
|
||||
update_detector(glyphs);
|
||||
return glyphs;
|
||||
}
|
||||
//No placement for this point. Keep it in points_ for next try.
|
||||
point_itr_++;
|
||||
}
|
||||
return false;
|
||||
return glyph_positions_ptr();
|
||||
}
|
||||
|
||||
struct largest_bbox_first
|
||||
|
@ -265,21 +268,14 @@ bool text_symbolizer_helper<FaceManagerT, DetectorT>::next_placement()
|
|||
angle_ = 0.0;
|
||||
}
|
||||
|
||||
|
||||
// finder_ = boost::shared_ptr<placement_finder<DetectorT> >(new placement_finder<DetectorT>(feature_, *placement_, *info_, detector_, dims_));
|
||||
|
||||
#if 0
|
||||
if (writer_.first) finder_->set_collect_extents(true);
|
||||
#endif
|
||||
|
||||
placement_valid_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename FaceManagerT, typename DetectorT>
|
||||
placements_type &text_symbolizer_helper<FaceManagerT, DetectorT>::placements() const
|
||||
{
|
||||
return finder_->get_results();
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
@ -323,26 +319,27 @@ bool shield_symbolizer_helper<FaceManagerT, DetectorT>::next_point_placement()
|
|||
double label_x = point_itr_->first + shield_pos.first;
|
||||
double label_y = point_itr_->second + shield_pos.second;
|
||||
|
||||
finder_->clear_placements();
|
||||
finder_->find_point_placement(label_x, label_y, angle_);
|
||||
if (finder_->get_results().empty())
|
||||
glyph_positions_ptr glyphs = finder_.find_point_placement(layout_, label_x, label_y, angle_);
|
||||
if (!glyphs)
|
||||
{
|
||||
//No placement for this point. Keep it in points_ for next try.
|
||||
point_itr_++;
|
||||
continue;
|
||||
}
|
||||
//Found a label placement but not necessarily also a marker placement
|
||||
// check to see if image overlaps anything too, there is only ever 1 placement found for points and verticies
|
||||
// check to see if image overlaps anything too
|
||||
if (!sym_.get_unlock_image())
|
||||
{
|
||||
// center image at text center position
|
||||
// remove displacement from image label
|
||||
placements_type const& p = finder_->get_results();
|
||||
//TODO
|
||||
#if 0
|
||||
double lx = p[0].center.x - text_disp.first;
|
||||
double ly = p[0].center.y - text_disp.second;
|
||||
marker_x_ = lx - 0.5 * marker_w_;
|
||||
marker_y_ = ly - 0.5 * marker_h_;
|
||||
marker_ext_.re_center(lx, ly);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{ // center image at reference location
|
||||
|
@ -354,12 +351,14 @@ bool shield_symbolizer_helper<FaceManagerT, DetectorT>::next_point_placement()
|
|||
if (placement_->properties.allow_overlap || detector_.has_placement(marker_ext_))
|
||||
{
|
||||
detector_.insert(marker_ext_);
|
||||
finder_->update_detector();
|
||||
this->update_detector(glyphs);
|
||||
#if 0
|
||||
if (writer_.first) {
|
||||
writer_.first->add_box(marker_ext_, feature_, t_, writer_.second);
|
||||
writer_.first->add_text(finder_->get_results(), finder_->get_extents(),
|
||||
feature_, t_, writer_.second);
|
||||
}
|
||||
#endif
|
||||
point_itr_ = points_.erase(point_itr_);
|
||||
return true;
|
||||
}
|
||||
|
@ -374,6 +373,7 @@ template <typename FaceManagerT, typename DetectorT>
|
|||
bool shield_symbolizer_helper<FaceManagerT, DetectorT>::next_line_placement()
|
||||
{
|
||||
position const& pos = placement_->properties.displacement;
|
||||
#if 0
|
||||
finder_->additional_boxes.clear();
|
||||
//Markers are automatically centered
|
||||
finder_->additional_boxes.push_back(
|
||||
|
@ -381,6 +381,7 @@ bool shield_symbolizer_helper<FaceManagerT, DetectorT>::next_line_placement()
|
|||
-0.5 * marker_ext_.height() - pos.second,
|
||||
0.5 * marker_ext_.width() - pos.first,
|
||||
0.5 * marker_ext_.height() - pos.second));
|
||||
#endif
|
||||
return text_symbolizer_helper<FaceManagerT, DetectorT>::next_line_placement();
|
||||
}
|
||||
|
||||
|
|
|
@ -103,4 +103,28 @@ void text_layout::clear()
|
|||
glyphs_.clear();
|
||||
}
|
||||
|
||||
format_run::format_run(char_properties_ptr properties, double text_height)
|
||||
: properties_(properties), glyphs_(), width_(0), text_height_(text_height), line_height_(0)
|
||||
{
|
||||
}
|
||||
|
||||
void format_run::add_glyph(const glyph_info &info)
|
||||
{
|
||||
glyphs_.push_back(info);
|
||||
width_ += info.width;
|
||||
line_height_ = info.line_height; //Same value for all characters with the same format
|
||||
}
|
||||
|
||||
text_line::text_line()
|
||||
: max_line_height(0), max_text_height(0)
|
||||
{
|
||||
}
|
||||
|
||||
void text_line::add_run(format_run_ptr run)
|
||||
{
|
||||
max_line_height = std::max(max_line_height, run->line_height());
|
||||
max_text_height = std::max(max_text_height, run->text_height());
|
||||
runs_.push_back(run);
|
||||
}
|
||||
|
||||
} //ns mapnik
|
||||
|
|
|
@ -33,22 +33,22 @@ placement_finder_ng::placement_finder_ng( Feature const& feature, DetectorType &
|
|||
{
|
||||
}
|
||||
|
||||
placement_positions_ptr placement_finder_ng::find_point_placement(text_layout_ptr layout, double pos_x, double pos_y, double angle)
|
||||
glyph_positions_ptr placement_finder_ng::find_point_placement(text_layout_ptr layout, double pos_x, double pos_y, double angle)
|
||||
{
|
||||
placement_positions_ptr ptr = boost::make_shared<placement_positions>(layout);
|
||||
ptr->point_placement(pos_x, pos_y);
|
||||
glyph_positions_ptr glyphs = boost::make_shared<glyph_positions>(layout);
|
||||
glyphs->point_placement(pos_x, pos_y);
|
||||
//TODO: angle
|
||||
//TODO: Check for placement
|
||||
return ptr;
|
||||
return glyphs;
|
||||
}
|
||||
|
||||
placement_positions::placement_positions(text_layout_ptr layout)
|
||||
glyph_positions::glyph_positions(text_layout_ptr layout)
|
||||
: x_(0), y_(0), point_(true), layout_(layout)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void placement_positions::point_placement(double x, double y)
|
||||
void glyph_positions::point_placement(double x, double y)
|
||||
{
|
||||
x_ = x;
|
||||
y_ = y;
|
||||
|
|
Loading…
Reference in a new issue