support expressions in stroke-linejoin and stroke-linecap properties

This commit is contained in:
artemp 2014-06-30 14:06:34 +01:00
parent 19b38c2ed9
commit 79fa672843
3 changed files with 169 additions and 107 deletions

View file

@ -57,6 +57,97 @@ namespace agg { struct trans_affine; }
namespace mapnik
{
enum line_cap_enum
{
BUTT_CAP,
SQUARE_CAP,
ROUND_CAP,
line_cap_enum_MAX
};
DEFINE_ENUM( line_cap_e, line_cap_enum );
enum line_join_enum
{
MITER_JOIN,
MITER_REVERT_JOIN,
ROUND_JOIN,
BEVEL_JOIN,
line_join_enum_MAX
};
DEFINE_ENUM( line_join_e, line_join_enum );
enum line_rasterizer_enum
{
RASTERIZER_FULL, // agg::renderer_scanline_aa_solid
RASTERIZER_FAST, // agg::rasterizer_outline_aa, twice as fast but only good for thin lines
line_rasterizer_enum_MAX
};
DEFINE_ENUM( line_rasterizer_e, line_rasterizer_enum );
enum halo_rasterizer_enum
{
HALO_RASTERIZER_FULL,
HALO_RASTERIZER_FAST,
halo_rasterizer_enum_MAX
};
DEFINE_ENUM(halo_rasterizer_e, halo_rasterizer_enum);
enum point_placement_enum
{
CENTROID_POINT_PLACEMENT,
INTERIOR_POINT_PLACEMENT,
point_placement_enum_MAX
};
DEFINE_ENUM( point_placement_e, point_placement_enum );
enum pattern_alignment_enum
{
LOCAL_ALIGNMENT,
GLOBAL_ALIGNMENT,
pattern_alignment_enum_MAX
};
DEFINE_ENUM( pattern_alignment_e, pattern_alignment_enum );
enum debug_symbolizer_mode_enum
{
DEBUG_SYM_MODE_COLLISION,
DEBUG_SYM_MODE_VERTEX,
debug_symbolizer_mode_enum_MAX
};
DEFINE_ENUM( debug_symbolizer_mode_e, debug_symbolizer_mode_enum );
// markers
// TODO - consider merging with text_symbolizer label_placement_e
enum marker_placement_enum
{
MARKER_POINT_PLACEMENT,
MARKER_INTERIOR_PLACEMENT,
MARKER_LINE_PLACEMENT,
marker_placement_enum_MAX
};
DEFINE_ENUM( marker_placement_e, marker_placement_enum );
enum marker_multi_policy_enum
{
MARKER_EACH_MULTI, // each component in a multi gets its marker
MARKER_WHOLE_MULTI, // consider all components of a multi as a whole
MARKER_LARGEST_MULTI, // only the largest component of a multi gets a marker
marker_multi_policy_enum_MAX
};
DEFINE_ENUM( marker_multi_policy_e, marker_multi_policy_enum );
// fwd declares
// TODO - move these transform declares to own header
namespace detail { struct transform_node; }
@ -166,6 +257,64 @@ struct evaluate_path_wrapper<std::string>
namespace detail {
template <typename T>
struct enum_traits
{
typedef boost::optional<T> result_type;
static result_type from_string(std::string const& str)
{
return result_type();
}
};
template <>
struct enum_traits<composite_mode_e>
{
typedef boost::optional<composite_mode_e> result_type;
static result_type from_string(std::string const& str)
{
return comp_op_from_string(str);
}
};
template <>
struct enum_traits<line_join_enum>
{
typedef boost::optional<line_join_enum> result_type;
static result_type from_string(std::string const& str)
{
enumeration<line_join_enum,line_join_enum_MAX> e;
try
{
e.from_string(str);
return result_type(line_join_enum(e));
}
catch (...)
{
return result_type();
}
}
};
template <>
struct enum_traits<line_cap_enum>
{
typedef boost::optional<line_cap_enum> result_type;
static result_type from_string(std::string const& str)
{
enumeration<line_cap_enum,line_cap_enum_MAX> e;
try
{
e.from_string(str);
return result_type(line_cap_enum(e));
}
catch (...)
{
return result_type();
}
}
};
// enum
template <typename T, bool is_enum = true>
struct expression_result
@ -173,7 +322,7 @@ struct expression_result
typedef T result_type;
static result_type convert(value_type const& val)
{
auto result = comp_op_from_string(val.to_string());
auto result = enum_traits<T>::from_string(val.to_string());
if (result) return static_cast<result_type>(*result);
return result_type(0);
}
@ -458,95 +607,6 @@ typedef boost::variant<point_symbolizer,
typedef std::vector<std::pair<double,double> > dash_array;
enum line_cap_enum
{
BUTT_CAP,
SQUARE_CAP,
ROUND_CAP,
line_cap_enum_MAX
};
DEFINE_ENUM( line_cap_e, line_cap_enum );
enum line_join_enum
{
MITER_JOIN,
MITER_REVERT_JOIN,
ROUND_JOIN,
BEVEL_JOIN,
line_join_enum_MAX
};
DEFINE_ENUM( line_join_e, line_join_enum );
enum line_rasterizer_enum
{
RASTERIZER_FULL, // agg::renderer_scanline_aa_solid
RASTERIZER_FAST, // agg::rasterizer_outline_aa, twice as fast but only good for thin lines
line_rasterizer_enum_MAX
};
DEFINE_ENUM( line_rasterizer_e, line_rasterizer_enum );
enum halo_rasterizer_enum
{
HALO_RASTERIZER_FULL,
HALO_RASTERIZER_FAST,
halo_rasterizer_enum_MAX
};
DEFINE_ENUM(halo_rasterizer_e, halo_rasterizer_enum);
enum point_placement_enum
{
CENTROID_POINT_PLACEMENT,
INTERIOR_POINT_PLACEMENT,
point_placement_enum_MAX
};
DEFINE_ENUM( point_placement_e, point_placement_enum );
enum pattern_alignment_enum
{
LOCAL_ALIGNMENT,
GLOBAL_ALIGNMENT,
pattern_alignment_enum_MAX
};
DEFINE_ENUM( pattern_alignment_e, pattern_alignment_enum );
enum debug_symbolizer_mode_enum
{
DEBUG_SYM_MODE_COLLISION,
DEBUG_SYM_MODE_VERTEX,
debug_symbolizer_mode_enum_MAX
};
DEFINE_ENUM( debug_symbolizer_mode_e, debug_symbolizer_mode_enum );
// markers
// TODO - consider merging with text_symbolizer label_placement_e
enum marker_placement_enum
{
MARKER_POINT_PLACEMENT,
MARKER_INTERIOR_PLACEMENT,
MARKER_LINE_PLACEMENT,
marker_placement_enum_MAX
};
DEFINE_ENUM( marker_placement_e, marker_placement_enum );
enum marker_multi_policy_enum
{
MARKER_EACH_MULTI, // each component in a multi gets its marker
MARKER_WHOLE_MULTI, // consider all components of a multi as a whole
MARKER_LARGEST_MULTI, // only the largest component of a multi gets a marker
marker_multi_policy_enum_MAX
};
DEFINE_ENUM( marker_multi_policy_e, marker_multi_policy_enum );
}

View file

@ -848,7 +848,7 @@ void map_parser::parse_symbolizers(rule & rule, xml_node const & node)
namespace detail {
// helpers
template <typename Symbolizer, typename T>
template <typename Symbolizer, typename T, bool is_enum = false>
struct set_symbolizer_property_impl
{
static void apply(Symbolizer & sym, keys key, xml_node const & node)
@ -869,23 +869,23 @@ struct set_symbolizer_property_impl
}
};
template <typename Symbolizer>
struct set_symbolizer_property_impl<Symbolizer, composite_mode_e>
template <typename Symbolizer, typename T>
struct set_symbolizer_property_impl<Symbolizer, T, true>
{
static void apply(Symbolizer & sym, keys key, xml_node const & node)
{
typedef composite_mode_e value_type;
typedef T value_type;
std::string const& name = std::get<0>(get_meta(key));
try
{
optional<std::string> comp_op_name = node.get_opt_attr<std::string>(name);
optional<std::string> enum_str = node.get_opt_attr<std::string>(name);
if (comp_op_name)
if (enum_str)
{
optional<composite_mode_e> comp_op = comp_op_from_string(*comp_op_name);
if (comp_op)
optional<T> enum_val = detail::enum_traits<T>::from_string(*enum_str);
if (enum_val)
{
put(sym, key, *comp_op);
put(sym, key, *enum_val);
}
else
{
@ -905,7 +905,7 @@ struct set_symbolizer_property_impl<Symbolizer, composite_mode_e>
template <typename Symbolizer, typename T>
void set_symbolizer_property(Symbolizer & sym, keys key, xml_node const & node)
{
detail::set_symbolizer_property_impl<Symbolizer,T>::apply(sym,key,node);
detail::set_symbolizer_property_impl<Symbolizer,T, std::is_enum<T>::value>::apply(sym,key,node);
}
void map_parser::parse_symbolizer_base(symbolizer_base &sym, xml_node const &pt)
@ -1321,12 +1321,14 @@ void map_parser::parse_stroke(symbolizer_base & symbol, xml_node const & node)
set_symbolizer_property<symbolizer_base,double>(symbol, keys::stroke_opacity, node);
// stroke-linejoin
optional<line_join_e> line_join = node.get_opt_attr<line_join_e>("stroke-linejoin");
if (line_join) put(symbol, keys::stroke_linejoin, line_join_enum(*line_join));
set_symbolizer_property<symbolizer_base,line_join_enum>(symbol, keys::stroke_linejoin, node);
//optional<line_join_e> line_join = node.get_opt_attr<line_join_e>("stroke-linejoin");
//if (line_join) put(symbol, keys::stroke_linejoin, line_join_enum(*line_join));
// stroke-linecap
optional<line_cap_e> line_cap = node.get_opt_attr<line_cap_e>("stroke-linecap");
if (line_cap) put(symbol, keys::stroke_linecap,line_cap_enum(*line_cap));
set_symbolizer_property<symbolizer_base,line_cap_enum>(symbol, keys::stroke_linecap, node);
//optional<line_cap_e> line_cap = node.get_opt_attr<line_cap_e>("stroke-linecap");
//if (line_cap) put(symbol, keys::stroke_linecap,line_cap_enum(*line_cap));
// stroke-gamma
optional<double> gamma = node.get_opt_attr<double>("stroke-gamma");

View file

@ -48,13 +48,13 @@ static const property_meta_type key_meta[to_integral(keys::MAX_SYMBOLIZER_KEY)]
property_meta_type{ "stroke-width", 1.0 , nullptr, property_types::target_double},
property_meta_type{ "stroke-opacity", 1.0, nullptr, property_types::target_double},
property_meta_type{ "stroke-linejoin", enumeration_wrapper(MITER_JOIN),
[](enumeration_wrapper e) { return enumeration<line_join_enum,line_join_enum_MAX>(line_join_enum(e.value)).as_string();}, property_types::target_double },
[](enumeration_wrapper e) { return enumeration<line_join_enum,line_join_enum_MAX>(line_join_enum(e.value)).as_string();}, property_types::target_line_join },
property_meta_type{ "stroke-linecap", enumeration_wrapper(BUTT_CAP),
[](enumeration_wrapper e) { return enumeration<line_cap_enum,line_cap_enum_MAX>(line_cap_enum(e.value)).as_string();}, property_types::target_double },
[](enumeration_wrapper e) { return enumeration<line_cap_enum,line_cap_enum_MAX>(line_cap_enum(e.value)).as_string();}, property_types::target_line_cap },
property_meta_type{ "stroke-gamma", 1.0, nullptr, property_types::target_double },
property_meta_type{ "stroke-gamma-method",static_cast<value_integer>(GAMMA_POWER), nullptr, property_types::target_double },
property_meta_type{ "stroke-dashoffset", static_cast<value_integer>(0), nullptr, property_types::target_double },
property_meta_type{ "stroke-dasharray", false, nullptr, property_types::target_double },
property_meta_type{ "stroke-dasharray", false, nullptr, property_types::target_dash_array },
property_meta_type{ "stroke-miterlimit", 4.0, nullptr, property_types::target_double },
property_meta_type{ "geometry-transform", false, nullptr, property_types::target_transform },
property_meta_type{ "line-rasterizer", enumeration_wrapper(RASTERIZER_FULL),