Merge pull request #2522 from mapnik/ff_settings_by_value

Store and pass font_feature_settings by value
This commit is contained in:
Dane Springmeyer 2014-10-11 22:46:12 -07:00
commit 84b20ad9c9
13 changed files with 77 additions and 46 deletions

View file

@ -289,7 +289,6 @@ struct evaluate_expression_wrapper<mapnik::color>
mapnik::color operator() (T1 const& expr, T2 const& feature, T3 const& vars) const
{
mapnik::value_type val = util::apply_visitor(mapnik::evaluate<T2,mapnik::value_type,T3>(feature,vars), expr);
// FIXME - throw instead?
if (val.is_null()) return mapnik::color(255,192,203); // pink
return mapnik::color(val.to_string());
}
@ -314,7 +313,6 @@ struct evaluate_expression_wrapper<mapnik::dash_array>
mapnik::dash_array operator() (T1 const& expr, T2 const& feature, T3 const& vars) const
{
mapnik::value_type val = util::apply_visitor(mapnik::evaluate<T2,mapnik::value_type,T3>(feature,vars), expr);
// FIXME - throw?
if (val.is_null()) return dash_array();
dash_array dash;
std::vector<double> buf;
@ -327,17 +325,16 @@ struct evaluate_expression_wrapper<mapnik::dash_array>
}
};
// mapnik::font_feature_settings_ptr
// mapnik::font_feature_settings
template <>
struct evaluate_expression_wrapper<mapnik::font_feature_settings_ptr>
struct evaluate_expression_wrapper<mapnik::font_feature_settings>
{
template <typename T1, typename T2, typename T3>
mapnik::font_feature_settings_ptr operator() (T1 const& expr, T2 const& feature, T3 const& vars) const
mapnik::font_feature_settings operator() (T1 const& expr, T2 const& feature, T3 const& vars) const
{
mapnik::value_type val = util::apply_visitor(mapnik::evaluate<T2, mapnik::value_type, T3>(feature, vars), expr);
// FIXME - throw instead?
if (val.is_null()) return std::make_shared<mapnik::font_feature_settings>();
return std::make_shared<mapnik::font_feature_settings>(val.to_string());
if (val.is_null()) return mapnik::font_feature_settings();
return mapnik::font_feature_settings(val.to_string());
}
};

View file

@ -94,7 +94,7 @@ using value_base_type = util::variant<value_bool,
dash_array,
raster_colorizer_ptr,
group_symbolizer_properties_ptr,
font_feature_settings_ptr>;
font_feature_settings>;
struct strict_value : value_base_type
{

View file

@ -35,11 +35,16 @@ namespace mapnik {
struct property_value_hash_visitor : util::static_visitor<std::size_t>
{
std::size_t operator() (color val) const
std::size_t operator() (color const& val) const
{
return val.rgba();
}
std::size_t operator() (font_feature_settings const& val) const
{
return 0; //FIXME
}
std::size_t operator() (transform_type const& val) const
{
return 0; //FIXME

View file

@ -90,7 +90,7 @@ enum class keys : std::uint8_t
vertical_alignment,
upright,
avoid_edges,
font_feature_settings,
ff_settings,
MAX_SYMBOLIZER_KEY
};

View file

@ -27,6 +27,7 @@
#include <vector>
#include <memory>
#include <limits>
#include <sstream>
// harfbuzz
#include <harfbuzz/hb.h>
@ -52,12 +53,27 @@ public:
const font_feature* get_features() const { return features_.data(); }
feature_vector::size_type count() const { return features_.size(); }
feature_vector const& features() const { return features_; }
private:
feature_vector features_;
};
using font_feature_settings_ptr = std::shared_ptr<font_feature_settings>;
template <typename charT, typename traits>
std::basic_ostream<charT, traits> &
operator << ( std::basic_ostream<charT, traits> & s, mapnik::font_feature_settings const& f )
{
s << f.to_string();
return s;
}
inline bool operator==(font_feature_settings const& lhs, font_feature_settings const& rhs)
{
// FIXME not working
//(lhs.features() == rhs.features());
return true;
}
constexpr unsigned int font_feature_range_global_start = 0u;
static const unsigned int font_feature_range_global_end = std::numeric_limits<unsigned int>::max();

View file

@ -59,7 +59,7 @@ public:
boost::optional<symbolizer_base::value_type> fill;
boost::optional<symbolizer_base::value_type> halo_fill;
boost::optional<symbolizer_base::value_type> halo_radius;
boost::optional<symbolizer_base::value_type> font_feature_settings;
boost::optional<symbolizer_base::value_type> ff_settings;
private:
node_ptr child_;

View file

@ -76,7 +76,7 @@ static void shape_text(text_line & line,
hb_buffer_pre_allocate(buffer.get(), length);
mapnik::value_unicode_string const& text = itemizer.text();
font_feature_settings_ptr features = list.front().format_->font_feature_settings;
font_feature_settings const& ff_settings = list.front().format_->ff_settings;
for (auto const& text_item : list)
{
@ -93,7 +93,7 @@ static void shape_text(text_line & line,
hb_buffer_set_direction(buffer.get(), (text_item.dir == UBIDI_RTL)?HB_DIRECTION_RTL:HB_DIRECTION_LTR);
hb_buffer_set_script(buffer.get(), _icu_script_to_script(text_item.script));
hb_font_t *font(hb_ft_font_create(face->get_face(), nullptr));
hb_shape(font, buffer.get(), features->get_features(), features->count());
hb_shape(font, buffer.get(), ff_settings.get_features(), ff_settings.count());
hb_font_destroy(font);
unsigned num_glyphs = hb_buffer_get_length(buffer.get());

View file

@ -49,18 +49,30 @@ namespace detail {
struct evaluated_format_properties
{
std::string face_name = "";
evaluated_format_properties() :
face_name(),
text_size(0.0),
character_spacing(0.0),
line_spacing(0.0),
text_opacity(1.0),
halo_opacity(1.0),
text_transform(NONE),
fill(0,0,0),
halo_fill(0,0,0),
halo_radius(0.0),
ff_settings() {}
std::string face_name;
boost::optional<font_set> fontset;
double text_size = 0.0;
double character_spacing = 0.0;
double line_spacing = 0.0;
double text_opacity = 1.0;
double halo_opacity = 1.0;
text_transform_e text_transform = NONE;
color fill = color(0,0,0);
color halo_fill = color(255,255,255);
double halo_radius = 0.0;
font_feature_settings_ptr font_feature_settings = std::make_shared<mapnik::font_feature_settings>();
double text_size;
double character_spacing;
double line_spacing;
double text_opacity;
double halo_opacity;
text_transform_e text_transform;
color fill;
color halo_fill;
double halo_radius;
font_feature_settings ff_settings;
};
struct evaluated_text_properties : noncopyable
@ -78,6 +90,7 @@ struct evaluated_text_properties : noncopyable
bool allow_overlap = false;
bool largest_bbox_only = true; // Only consider geometry with largest bbox (polygons)
text_upright_e upright = UPRIGHT_AUTO;
};
}
@ -120,7 +133,7 @@ struct MAPNIK_DECL format_properties
symbolizer_base::value_type halo_fill;
symbolizer_base::value_type halo_radius;
symbolizer_base::value_type text_transform;
symbolizer_base::value_type font_feature_settings;
symbolizer_base::value_type ff_settings;
};

View file

@ -201,13 +201,13 @@ struct do_xml_attribute_cast<mapnik::expression_ptr>
}
};
// specialization for mapnik::font_feature_settings_ptr
// specialization for mapnik::font_feature_settings
template <>
struct do_xml_attribute_cast<mapnik::font_feature_settings_ptr>
struct do_xml_attribute_cast<mapnik::font_feature_settings>
{
static inline boost::optional<mapnik::font_feature_settings_ptr> xml_attribute_cast_impl(xml_tree const& tree, std::string const& source)
static inline boost::optional<mapnik::font_feature_settings> xml_attribute_cast_impl(xml_tree const& tree, std::string const& source)
{
return std::make_shared<font_feature_settings>(source);
return mapnik::font_feature_settings(source);
}
};

View file

@ -51,7 +51,7 @@ void format_node::to_xml(ptree & xml) const
if (halo_fill) serialize_property("halo-fill", *halo_fill, new_node);
if (halo_radius) serialize_property("halo-radius", *halo_radius, new_node);
if (text_transform) serialize_property("text-transform", *text_transform, new_node);
if (font_feature_settings) serialize_property("font-feature-settings", *font_feature_settings, new_node);
if (ff_settings) serialize_property("font-feature-settings", *ff_settings, new_node);
if (face_name) set_attr(new_node, "face-name", *face_name);
if (fontset) set_attr(new_node, "fontset-name", fontset->get_name());
@ -75,7 +75,7 @@ node_ptr format_node::from_xml(xml_node const& xml, fontset_map const& fontsets)
set_property_from_xml<color>(n->fill, "fill", xml);
set_property_from_xml<color>(n->halo_fill, "halo-fill", xml);
set_property_from_xml<text_transform_e>(n->text_transform, "text-transform", xml);
set_property_from_xml<font_feature_settings_ptr>(n->font_feature_settings, "font-feature-settings", xml);
set_property_from_xml<font_feature_settings>(n->ff_settings, "font-feature-settings", xml);
boost::optional<std::string> face_name = xml.get_opt_attr<std::string>("face-name");
if (face_name)
@ -115,7 +115,7 @@ void format_node::apply(evaluated_format_properties_ptr p, feature_impl const& f
if (fill) new_properties->fill = util::apply_visitor(extract_value<color>(feature,attrs), *fill);
if (halo_fill) new_properties->halo_fill = util::apply_visitor(extract_value<color>(feature,attrs), *halo_fill);
if (text_transform) new_properties->text_transform = util::apply_visitor(extract_value<text_transform_enum>(feature,attrs), *text_transform);
if (font_feature_settings) new_properties->font_feature_settings = util::apply_visitor(extract_value<font_feature_settings_ptr>(feature,attrs), *font_feature_settings);
if (ff_settings) new_properties->ff_settings = util::apply_visitor(extract_value<font_feature_settings>(feature,attrs), *ff_settings);
if (fontset)
{
@ -159,7 +159,7 @@ void format_node::add_expressions(expression_set & output) const
if (fill && is_expression(*fill)) output.insert(util::get<expression_ptr>(*fill));
if (halo_fill && is_expression(*halo_fill)) output.insert(util::get<expression_ptr>(*halo_fill));
if (text_transform && is_expression(*text_transform)) output.insert(util::get<expression_ptr>(*text_transform));
if (font_feature_settings && is_expression(*font_feature_settings)) output.insert(util::get<expression_ptr>(*font_feature_settings));
if (ff_settings && is_expression(*ff_settings)) output.insert(util::get<expression_ptr>(*ff_settings));
if (child_) child_->add_expressions(output);
}

View file

@ -70,9 +70,9 @@ struct property_serializer : public util::static_visitor<>
node_.put("<xmlattr>." + name_, str);
}
void operator() (font_feature_settings_ptr const& val) const
void operator() (font_feature_settings const& val) const
{
std::string str = val->to_string();
std::string str = val.to_string();
node_.put("<xmlattr>." + name_, str);
}

View file

@ -86,11 +86,11 @@ void text_symbolizer_properties::process(text_layout & output, feature_impl cons
format->face_name = format_defaults.face_name;
format->fontset = format_defaults.fontset;
format->font_feature_settings = util::apply_visitor(extract_value<font_feature_settings_ptr>(feature,attrs), format_defaults.font_feature_settings);
format->ff_settings = util::apply_visitor(extract_value<font_feature_settings>(feature,attrs), format_defaults.ff_settings);
// Turn off ligatures if character_spacing > 0.
if (format->character_spacing > .0 && format->font_feature_settings->count() == 0)
if (format->character_spacing > .0 && format->ff_settings.count() == 0)
{
format->font_feature_settings->append(font_feature_liga_off);
format->ff_settings.append(font_feature_liga_off);
}
tree_->apply(format, feature, attrs, output);
@ -295,7 +295,7 @@ format_properties::format_properties()
halo_fill(color(255,255,255)),
halo_radius(0.0),
text_transform(enumeration_wrapper(NONE)),
font_feature_settings(std::make_shared<mapnik::font_feature_settings>()) {}
ff_settings() {}
void format_properties::from_xml(xml_node const& node, fontset_map const& fontsets, bool is_shield)
{
@ -316,7 +316,7 @@ void format_properties::from_xml(xml_node const& node, fontset_map const& fontse
set_property_from_xml<color>(fill, "fill", node);
set_property_from_xml<color>(halo_fill, "halo-fill", node);
set_property_from_xml<text_transform_e>(text_transform,"text-transform", node);
set_property_from_xml<font_feature_settings_ptr>(font_feature_settings, "font-feature-settings", node);
set_property_from_xml<font_feature_settings>(ff_settings, "font-feature-settings", node);
optional<std::string> face_name_ = node.get_opt_attr<std::string>("face-name");
if (face_name_) face_name = *face_name_;
@ -371,7 +371,7 @@ void format_properties::to_xml(boost::property_tree::ptree & node, bool explicit
if (!(fill == dfl.fill) || explicit_defaults) serialize_property("fill", fill, node);
if (!(halo_fill == dfl.halo_fill) || explicit_defaults) serialize_property("halo-fill", halo_fill, node);
if (!(text_transform == dfl.text_transform) || explicit_defaults) serialize_property("text-transform", text_transform, node);
if (!(font_feature_settings == dfl.font_feature_settings) || explicit_defaults) serialize_property("font-feature-settings", font_feature_settings, node);
if (!(ff_settings == dfl.ff_settings) || explicit_defaults) serialize_property("font-feature-settings", ff_settings, node);
}
void format_properties::add_expressions(expression_set & output) const
@ -385,7 +385,7 @@ void format_properties::add_expressions(expression_set & output) const
if (is_expression(fill)) output.insert(util::get<expression_ptr>(fill));
if (is_expression(halo_fill)) output.insert(util::get<expression_ptr>(halo_fill));
if (is_expression(text_transform)) output.insert(util::get<expression_ptr>(text_transform));
if (is_expression(font_feature_settings)) output.insert(util::get<expression_ptr>(font_feature_settings));
if (is_expression(ff_settings)) output.insert(util::get<expression_ptr>(ff_settings));
}

View file

@ -77,7 +77,7 @@ DEFINE_NAME_TRAIT( mapnik::value_integer, "int" )
DEFINE_NAME_TRAIT( std::string, "string" )
DEFINE_NAME_TRAIT( color, "color" )
DEFINE_NAME_TRAIT( expression_ptr, "expression_ptr" )
DEFINE_NAME_TRAIT( font_feature_settings_ptr, "font-feature-settings" )
DEFINE_NAME_TRAIT( font_feature_settings, "font-feature-settings" )
template <typename ENUM, int MAX>
struct name_trait< mapnik::enumeration<ENUM, MAX> >
@ -429,7 +429,7 @@ compile_get_opt_attr(justify_alignment_e);
compile_get_opt_attr(text_upright_e);
compile_get_opt_attr(halo_rasterizer_e);
compile_get_opt_attr(expression_ptr);
compile_get_opt_attr(font_feature_settings_ptr);
compile_get_opt_attr(font_feature_settings);
compile_get_attr(std::string);
compile_get_attr(filter_mode_e);
compile_get_attr(point_placement_e);