Change glyph_positions interface to be easier to use.
This commit is contained in:
parent
9408f2e169
commit
c0180d59ed
4 changed files with 59 additions and 66 deletions
|
@ -29,7 +29,7 @@
|
|||
#include <mapnik/text/char_properties_ptr.hpp>
|
||||
|
||||
//stl
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
//boost
|
||||
#include <boost/utility.hpp>
|
||||
|
@ -47,33 +47,42 @@ typedef feature_impl Feature;
|
|||
class text_layout;
|
||||
typedef boost::shared_ptr<text_layout> text_layout_ptr;
|
||||
|
||||
struct glyph_position
|
||||
{
|
||||
glyph_position(glyph_info const& glyph, pixel_position const& pos, double angle)
|
||||
: glyph(&glyph), pos(pos), angle(angle) { }
|
||||
glyph_info const* glyph;
|
||||
pixel_position pos;
|
||||
double angle;
|
||||
};
|
||||
|
||||
/** Stores positions of glphys.
|
||||
*
|
||||
* The actual glyphs and their format is stored in text_layout.
|
||||
* For point placements only the base point is stored, glyph positions
|
||||
* are defined by information in text_layout.
|
||||
*/
|
||||
class glyph_positions
|
||||
{
|
||||
public:
|
||||
glyph_positions(text_layout_ptr layout);
|
||||
void point_placement(pixel_position base_point);
|
||||
bool is_point_placement() const { return point_; }
|
||||
bool next();
|
||||
void rewind();
|
||||
glyph_info const& get_glyph() const;
|
||||
pixel_position get_position() const;
|
||||
double get_angle() const;
|
||||
typedef std::vector<glyph_position>::const_iterator const_iterator;
|
||||
glyph_positions();
|
||||
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
|
||||
void push_back(glyph_info const& glyph, pixel_position offset, double angle);
|
||||
|
||||
/** Is each character rotated by the same angle?
|
||||
* This function is used to avoid costly trigonometric function calls when not necessary. */
|
||||
bool is_constant_angle() const;
|
||||
double get_angle() const;
|
||||
|
||||
pixel_position const& get_base_point() const;
|
||||
void set_base_point(pixel_position base_point);
|
||||
private:
|
||||
std::vector<glyph_position> data_;
|
||||
pixel_position base_point_;
|
||||
bool point_;
|
||||
text_layout_ptr layout_;
|
||||
signed current_;
|
||||
pixel_position current_position_;
|
||||
double angle_;
|
||||
bool const_angle_;
|
||||
};
|
||||
typedef boost::shared_ptr<glyph_positions> glyph_positions_ptr;
|
||||
|
||||
|
@ -85,11 +94,14 @@ public:
|
|||
box2d<double> const& extent);
|
||||
|
||||
/** Try to place a single label at the given point. */
|
||||
glyph_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);
|
||||
|
||||
void set_angle(double angle);
|
||||
private:
|
||||
Feature const& feature_;
|
||||
DetectorType const& detector_;
|
||||
box2d<double> const& extent_;
|
||||
double angle_;
|
||||
};
|
||||
|
||||
}//ns mapnik
|
||||
|
|
|
@ -123,7 +123,7 @@ glyph_positions_ptr text_symbolizer_helper<FaceManagerT, DetectorT>::next_point_
|
|||
continue; //Reexecute size check
|
||||
}
|
||||
glyph_positions_ptr glyphs = finder_.find_point_placement(
|
||||
layout_, point_itr_->first, point_itr_->second, angle_);
|
||||
layout_, point_itr_->first, point_itr_->second);
|
||||
if (glyphs)
|
||||
{
|
||||
//Found a placement
|
||||
|
@ -272,6 +272,7 @@ bool text_symbolizer_helper<FaceManagerT, DetectorT>::next_placement()
|
|||
} else {
|
||||
angle_ = 0.0;
|
||||
}
|
||||
finder_.set_angle(angle_);
|
||||
|
||||
#if 0
|
||||
if (writer_.first) finder_->set_collect_extents(true);
|
||||
|
@ -324,7 +325,7 @@ 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;
|
||||
|
||||
glyph_positions_ptr glyphs = finder_.find_point_placement(layout_, label_x, label_y, angle_);
|
||||
glyph_positions_ptr glyphs = finder_.find_point_placement(layout_, label_x, label_y);
|
||||
if (!glyphs)
|
||||
{
|
||||
//No placement for this point. Keep it in points_ for next try.
|
||||
|
|
|
@ -35,71 +35,52 @@ placement_finder_ng::placement_finder_ng( Feature const& feature, DetectorType &
|
|||
{
|
||||
}
|
||||
|
||||
glyph_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)
|
||||
{
|
||||
glyph_positions_ptr glyphs = boost::make_shared<glyph_positions>(layout);
|
||||
glyphs->point_placement(pixel_position(pos_x, pos_y));
|
||||
glyph_positions_ptr glyphs = boost::make_shared<glyph_positions>();
|
||||
// glyphs->point_placement(pixel_position(pos_x, pos_y));
|
||||
//TODO: angle
|
||||
//TODO: Check for placement
|
||||
return glyphs;
|
||||
}
|
||||
|
||||
glyph_positions::glyph_positions(text_layout_ptr layout)
|
||||
: base_point_(), point_(true), layout_(layout), current_(0)
|
||||
glyph_positions::glyph_positions()
|
||||
: base_point_(), const_angle_(true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void glyph_positions::point_placement(pixel_position base_point)
|
||||
glyph_positions::const_iterator glyph_positions::begin() const
|
||||
{
|
||||
base_point_ = base_point;
|
||||
point_ = true;
|
||||
return data_.begin();
|
||||
}
|
||||
|
||||
bool glyph_positions::next()
|
||||
glyph_positions::const_iterator glyph_positions::end() const
|
||||
{
|
||||
return false;
|
||||
#if 0
|
||||
if (current_ == -1)
|
||||
return data_.end();
|
||||
}
|
||||
|
||||
void glyph_positions::push_back(const glyph_info &glyph, pixel_position offset, double angle)
|
||||
{
|
||||
if (data_.empty())
|
||||
{
|
||||
current_ = 0;
|
||||
return (bool)layout_->size();
|
||||
angle_ = angle;
|
||||
} else
|
||||
{
|
||||
if (angle != angle_) const_angle_ = false;
|
||||
}
|
||||
if (current_ >= layout_->size()) return false;
|
||||
glyph_info glyph = layout_->get_glyphs()[current_];
|
||||
current_position_.x += glyph.width + glyph.format->character_spacing;
|
||||
current_++;
|
||||
if (current_ >= layout_->size()) return false;
|
||||
return true;
|
||||
#endif
|
||||
data_.push_back(glyph_position(glyph, offset, angle));
|
||||
}
|
||||
|
||||
void glyph_positions::rewind()
|
||||
{
|
||||
current_ = -1;
|
||||
current_position_ = pixel_position(0, 0);
|
||||
}
|
||||
|
||||
glyph_info const& glyph_positions::get_glyph() const
|
||||
bool glyph_positions::is_constant_angle() const
|
||||
{
|
||||
// assert(layout_);
|
||||
// assert(current_ < layout_->size());
|
||||
// return layout_->get_glyphs()[current_];
|
||||
}
|
||||
|
||||
pixel_position glyph_positions::get_position() const
|
||||
{
|
||||
return current_position_;
|
||||
return const_angle_;
|
||||
}
|
||||
|
||||
double glyph_positions::get_angle() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool glyph_positions::is_constant_angle() const
|
||||
{
|
||||
return point_;
|
||||
return angle_;
|
||||
}
|
||||
|
||||
const pixel_position &glyph_positions::get_base_point() const
|
||||
|
|
|
@ -26,7 +26,6 @@ void text_renderer<T>::prepare_glyphs(glyph_positions_ptr pos)
|
|||
FT_Vector pen;
|
||||
FT_Error error;
|
||||
|
||||
pos->rewind();
|
||||
bool constant_angle = pos->is_constant_angle();
|
||||
if (constant_angle)
|
||||
{
|
||||
|
@ -38,18 +37,18 @@ void text_renderer<T>::prepare_glyphs(glyph_positions_ptr pos)
|
|||
matrix.yx = (FT_Fixed)( sina * 0x10000L);
|
||||
matrix.yy = (FT_Fixed)( cosa * 0x10000L);
|
||||
}
|
||||
while (pos->next())
|
||||
glyph_positions::const_iterator itr = pos->begin(), end = pos->end();
|
||||
for (; itr != end; itr++)
|
||||
{
|
||||
glyph_info const& glyph = pos->get_glyph();
|
||||
glyph_info const& glyph = *(itr->glyph);
|
||||
glyph.face->set_character_sizes(glyph.format->text_size * scale_factor_); //TODO: Optimize this?
|
||||
|
||||
pixel_position p = pos->get_position();
|
||||
pen.x = int((p.x +glyph.offset_x) * 64);
|
||||
pen.y = int((p.y + glyph.offset_y) * 64);
|
||||
pen.x = int((itr->pos.x + glyph.offset_x) * 64);
|
||||
pen.y = int((itr->pos.y + glyph.offset_y) * 64);
|
||||
|
||||
if (!constant_angle)
|
||||
{
|
||||
double angle = pos->get_angle();
|
||||
double angle = itr->angle;
|
||||
double cosa = cos(angle);
|
||||
double sina = sin(angle);
|
||||
matrix.xx = (FT_Fixed)( cosa * 0x10000L);
|
||||
|
|
Loading…
Add table
Reference in a new issue