add support for fractional text size

( use FT_Set_Char_Size )
NOTE: ensure it works as expected, currently
I see different results from different fonts.
This commit is contained in:
Artem Pavlenko 2011-10-27 13:24:50 +01:00
parent b6b14a9879
commit c1504f874e
14 changed files with 56 additions and 35 deletions

View file

@ -119,7 +119,13 @@ public:
{
if (! FT_Set_Pixel_Sizes( face_, 0, size ))
return true;
return false;
}
bool set_character_sizes(float size)
{
if ( !FT_Set_Char_Size(face_,0,(FT_F26Dot6)(size * (1<<6)),0,0))
return true;
return false;
}
@ -184,6 +190,14 @@ public:
(*face)->set_pixel_sizes(size);
}
}
void set_character_sizes(float size)
{
for (std::vector<face_ptr>::iterator face = faces_.begin(); face != faces_.end(); ++face)
{
(*face)->set_character_sizes(size);
}
}
private:
std::vector<face_ptr> faces_;
std::map<unsigned, dimension_t> dimension_cache_;
@ -198,7 +212,7 @@ public:
void init(double radius)
{
FT_Stroker_Set(s_, (FT_Fixed) radius * (1<<6),
FT_Stroker_Set(s_, (FT_Fixed) (radius * (1<<6)),
FT_STROKER_LINECAP_ROUND,
FT_STROKER_LINEJOIN_ROUND,
0);
@ -332,11 +346,17 @@ struct text_renderer : private boost::noncopyable
halo_radius_(0.0),
opacity_(1.0) {}
void set_pixel_size(unsigned size)
{
faces_->set_pixel_sizes(size);
}
void set_character_size(float size)
{
faces_->set_character_sizes(size);
}
void set_fill(mapnik::color const& fill)
{
fill_=fill;

View file

@ -38,11 +38,11 @@ struct MAPNIK_DECL shield_symbolizer : public text_symbolizer,
{
shield_symbolizer(expression_ptr name,
std::string const& face_name,
unsigned size,
float size,
color const& fill,
path_expression_ptr file);
shield_symbolizer(expression_ptr name,
unsigned size,
float size,
color const& fill,
path_expression_ptr file);

View file

@ -112,7 +112,7 @@ public:
/* NOTE: Values are public and non-virtual to avoid any performance problems. */
position displacement;
unsigned text_size;
float text_size;
horizontal_alignment_e halign;
justify_alignment_e jalign;
vertical_alignment_e valign;
@ -127,9 +127,9 @@ public:
text_size_(10), halign_(H_MIDDLE), jalign_(J_MIDDLE), valign_(V_MIDDLE) {}
virtual text_placement_info_ptr get_placement_info() const =0;
virtual void set_default_text_size(unsigned size) { text_size_ = size; }
unsigned get_default_text_size() const { return text_size_; }
virtual void set_default_text_size(float size) { text_size_ = size; }
float get_default_text_size() const { return text_size_; }
virtual void set_default_displacement(position const& displacement) { displacement_ = displacement;}
position const& get_default_displacement() { return displacement_; }
@ -144,7 +144,7 @@ public:
virtual ~text_placements() {}
protected:
unsigned text_size_;
float text_size_;
position displacement_;
horizontal_alignment_e halign_;
justify_alignment_e jalign_;

View file

@ -44,10 +44,10 @@ namespace mapnik
struct MAPNIK_DECL text_symbolizer : public symbolizer_base
{
text_symbolizer(expression_ptr name, std::string const& face_name,
unsigned size, color const& fill,
float size, color const& fill,
text_placements_ptr placements = boost::make_shared<text_placements_dummy>()
);
text_symbolizer(expression_ptr name, unsigned size, color const& fill,
text_symbolizer(expression_ptr name, float size, color const& fill,
text_placements_ptr placements = boost::make_shared<text_placements_dummy>()
);
text_symbolizer(text_symbolizer const& rhs);
@ -80,8 +80,8 @@ struct MAPNIK_DECL text_symbolizer : public symbolizer_base
void set_force_odd_labels(bool force);
double get_max_char_angle_delta() const; // maximum change in angle between adjacent characters
void set_max_char_angle_delta(double angle);
unsigned get_text_size() const;
void set_text_size(unsigned size);
float get_text_size() const;
void set_text_size(float size);
std::string const& get_face_name() const;
void set_face_name(std::string face_name);
font_set const& get_fontset() const;

View file

@ -59,9 +59,9 @@ void agg_renderer<T>::process(glyph_symbolizer const& sym,
}
// set font size
unsigned size = sym.eval_size(feature);
ren.set_pixel_size(size * scale_factor_);
faces->set_pixel_sizes(size * scale_factor_);
float size = sym.eval_size(feature);
ren.set_character_size(size * scale_factor_);
faces->set_character_sizes(size * scale_factor_);
// Get and render text path
//

View file

@ -129,7 +129,7 @@ void agg_renderer<T>::process(shield_symbolizer const& sym,
{
text_renderer<T> ren(pixmap_, faces, *strk);
ren.set_pixel_size(sym.get_text_size() * scale_factor_);
ren.set_character_size(sym.get_text_size() * scale_factor_);
ren.set_fill(sym.get_fill());
ren.set_halo_fill(sym.get_halo_fill());
ren.set_halo_radius(sym.get_halo_radius() * scale_factor_);

View file

@ -103,12 +103,13 @@ void agg_renderer<T>::process(text_symbolizer const& sym,
throw config_error("Unable to find specified font face '" + sym.get_face_name() + "'");
}
text_renderer<T> ren(pixmap_, faces, *strk);
ren.set_pixel_size(placement_options->text_size * scale_factor_);
ren.set_character_size(placement_options->text_size * scale_factor_);
ren.set_fill(fill);
ren.set_halo_fill(sym.get_halo_fill());
ren.set_halo_radius(sym.get_halo_radius() * scale_factor_);
ren.set_opacity(sym.get_text_opacity());
box2d<double> dims(0,0,width_,height_);
placement_finder<label_collision_detector4> finder(*detector_,dims);

View file

@ -1138,7 +1138,7 @@ void cairo_renderer_base::process(shield_symbolizer const& sym,
placement_finder<label_collision_detector4> finder(detector_);
faces->set_pixel_sizes(placement_options->text_size);
faces->set_character_sizes(placement_options->text_size);
faces->get_string_info(info);
int w = (*marker)->width();
@ -1466,7 +1466,7 @@ void cairo_renderer_base::process(glyph_symbolizer const& sym,
// set font size
unsigned size = sym.eval_size(feature);
faces->set_pixel_sizes(size);
faces->set_character_sizes(size);
// Get and render text path
//
@ -1563,7 +1563,7 @@ void cairo_renderer_base::process(text_symbolizer const& sym,
cairo_context context(context_);
string_info info(text);
faces->set_pixel_sizes(placement_options->text_size);
faces->set_character_sizes(placement_options->text_size);
faces->get_string_info(info);
placement_finder<label_collision_detector4> finder(detector_);

View file

@ -97,7 +97,7 @@ unsigned glyph_symbolizer::eval_size(Feature const& feature) const
#ifdef MAPNIK_DEBUG
std::clog << "size_result=" << result.to_string() << "\n";
#endif
unsigned size = static_cast<unsigned>(result.to_int());
float size = static_cast<float>(result.to_double());
#ifdef MAPNIK_DEBUG
std::clog << "size=" << size << "\n";
#endif

View file

@ -110,7 +110,7 @@ void grid_renderer<T>::process(shield_symbolizer const& sym,
{
text_renderer<T> ren(pixmap_, faces, *strk);
ren.set_pixel_size(sym.get_text_size() * scale_factor_ * (1.0/pixmap_.get_resolution()));
ren.set_character_size(sym.get_text_size() * scale_factor_ * (1.0/pixmap_.get_resolution()));
ren.set_fill(sym.get_fill());
ren.set_halo_fill(sym.get_halo_fill());
ren.set_halo_radius(sym.get_halo_radius() * scale_factor_);

View file

@ -77,7 +77,7 @@ void grid_renderer<T>::process(text_symbolizer const& sym,
throw config_error("Unable to find specified font face '" + sym.get_face_name() + "'");
}
text_renderer<T> ren(pixmap_, faces, *strk);
ren.set_pixel_size(placement_options->text_size * (scale_factor_ * (1.0/pixmap_.get_resolution())));
ren.set_character_size(placement_options->text_size * (scale_factor_ * (1.0/pixmap_.get_resolution())));
ren.set_fill(fill);
ren.set_halo_fill(sym.get_halo_fill());
ren.set_halo_radius(sym.get_halo_radius() * scale_factor_);

View file

@ -1244,10 +1244,10 @@ void map_parser::parse_text_symbolizer( rule & rule, ptree const & sym )
optional<std::string> fontset_name =
get_opt_attr<std::string>(sym, "fontset-name");
unsigned size = get_attr(sym, "size", 10U);
float size = get_attr(sym, "size", 10.0f);
color c = get_attr(sym, "fill", color(0,0,0));
text_symbolizer text_symbol = text_symbolizer(parse_expression(name, "utf8"), size, c, placement_finder);
optional<std::string> orientation = get_opt_attr<std::string>(sym, "orientation");
@ -1486,7 +1486,7 @@ void map_parser::parse_shield_symbolizer( rule & rule, ptree const & sym )
optional<std::string> fontset_name =
get_opt_attr<std::string>(sym, "fontset-name");
unsigned size = get_attr(sym, "size", 10U);
float size = get_attr(sym, "size", 10.0f);
color fill = get_attr(sym, "fill", color(0,0,0));
std::string image_file = get_attr<std::string>(sym, "file");

View file

@ -37,7 +37,7 @@ namespace mapnik
shield_symbolizer::shield_symbolizer(
expression_ptr name,
std::string const& face_name,
unsigned size,
float size,
color const& fill,
path_expression_ptr file)
: text_symbolizer(name, face_name, size, fill),
@ -50,7 +50,7 @@ shield_symbolizer::shield_symbolizer(
shield_symbolizer::shield_symbolizer(
expression_ptr name,
unsigned size,
float size,
color const& fill,
path_expression_ptr file)
: text_symbolizer(name, size, fill),

View file

@ -87,7 +87,7 @@ IMPLEMENT_ENUM( text_transform_e, text_transform_strings )
text_symbolizer::text_symbolizer(expression_ptr name, std::string const& face_name,
unsigned size, color const& fill,
float size, color const& fill,
text_placements_ptr placements)
: symbolizer_base(),
name_(name),
@ -120,7 +120,7 @@ text_symbolizer::text_symbolizer(expression_ptr name, std::string const& face_na
set_text_size(size);
}
text_symbolizer::text_symbolizer(expression_ptr name, unsigned size, color const& fill,
text_symbolizer::text_symbolizer(expression_ptr name, float size, color const& fill,
text_placements_ptr placements)
: symbolizer_base(),
name_(name),
@ -378,12 +378,12 @@ void text_symbolizer::set_max_char_angle_delta(double angle)
max_char_angle_delta_ = angle;
}
void text_symbolizer::set_text_size(unsigned size)
void text_symbolizer::set_text_size(float size)
{
placement_options_->set_default_text_size(size);
}
unsigned text_symbolizer::get_text_size() const
float text_symbolizer::get_text_size() const
{
return placement_options_->get_default_text_size();
}