support halo-comp-op property (#2267)

This commit is contained in:
artemp 2014-06-17 15:10:20 +01:00
parent d9597972d4
commit 2c3173c1aa
8 changed files with 186 additions and 159 deletions

View file

@ -84,6 +84,7 @@ enum class keys : std::uint8_t
group_properties, group_properties,
largest_box_only, largest_box_only,
minimum_path_length, minimum_path_length,
halo_comp_op,
MAX_SYMBOLIZER_KEY MAX_SYMBOLIZER_KEY
}; };

View file

@ -69,6 +69,7 @@ class text_renderer : private mapnik::noncopyable
public: public:
text_renderer (halo_rasterizer_e rasterizer, text_renderer (halo_rasterizer_e rasterizer,
composite_mode_e comp_op = src_over, composite_mode_e comp_op = src_over,
composite_mode_e halo_comp_op = src_over,
double scale_factor=1.0, double scale_factor=1.0,
stroker_ptr stroker=stroker_ptr()); stroker_ptr stroker=stroker_ptr());
void set_transform(agg::trans_affine const& transform); void set_transform(agg::trans_affine const& transform);
@ -78,6 +79,7 @@ protected:
void prepare_glyphs(glyph_positions const& positions); void prepare_glyphs(glyph_positions const& positions);
halo_rasterizer_e rasterizer_; halo_rasterizer_e rasterizer_;
composite_mode_e comp_op_; composite_mode_e comp_op_;
composite_mode_e halo_comp_op_;
double scale_factor_; double scale_factor_;
glyph_vector glyphs_; glyph_vector glyphs_;
stroker_ptr stroker_; stroker_ptr stroker_;
@ -92,6 +94,7 @@ public:
typedef T pixmap_type; typedef T pixmap_type;
agg_text_renderer (pixmap_type & pixmap, halo_rasterizer_e rasterizer, agg_text_renderer (pixmap_type & pixmap, halo_rasterizer_e rasterizer,
composite_mode_e comp_op = src_over, composite_mode_e comp_op = src_over,
composite_mode_e halo_comp_op = src_over,
double scale_factor = 1.0, double scale_factor = 1.0,
stroker_ptr stroker = stroker_ptr()); stroker_ptr stroker = stroker_ptr());
void render(glyph_positions const& positions); void render(glyph_positions const& positions);
@ -107,7 +110,8 @@ class grid_text_renderer : public text_renderer
{ {
public: public:
typedef T pixmap_type; typedef T pixmap_type;
grid_text_renderer (pixmap_type & pixmap, composite_mode_e comp_op = src_over, grid_text_renderer (pixmap_type & pixmap,
composite_mode_e comp_op = src_over,
double scale_factor = 1.0); double scale_factor = 1.0);
void render(glyph_positions const& positions, value_integer feature_id); void render(glyph_positions const& positions, value_integer feature_id);
private: private:

View file

@ -68,7 +68,7 @@ struct thunk_renderer : public boost::static_visitor<>
void operator()(text_render_thunk const &thunk) const void operator()(text_render_thunk const &thunk) const
{ {
text_renderer_type ren(*buf_, thunk.halo_rasterizer_, thunk.comp_op_, text_renderer_type ren(*buf_, thunk.halo_rasterizer_, thunk.comp_op_, thunk.comp_op_,
common_.scale_factor_, common_.font_manager_.get_stroker()); common_.scale_factor_, common_.font_manager_.get_stroker());
render_offset_placements( render_offset_placements(

View file

@ -46,9 +46,11 @@ void agg_renderer<T0,T1>::process(shield_symbolizer const& sym,
halo_rasterizer_enum halo_rasterizer = get<halo_rasterizer_enum>(sym, keys::halo_rasterizer, feature, common_.vars_, HALO_RASTERIZER_FULL); halo_rasterizer_enum halo_rasterizer = get<halo_rasterizer_enum>(sym, keys::halo_rasterizer, feature, common_.vars_, HALO_RASTERIZER_FULL);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over); composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over);
composite_mode_e halo_comp_op = get<composite_mode_e>(sym, keys::halo_comp_op, feature, common_.vars_, src_over);
agg_text_renderer<T0> ren(*current_buffer_, agg_text_renderer<T0> ren(*current_buffer_,
halo_rasterizer, halo_rasterizer,
comp_op, comp_op,
halo_comp_op,
common_.scale_factor_, common_.scale_factor_,
common_.font_manager_.get_stroker()); common_.font_manager_.get_stroker());

View file

@ -46,9 +46,11 @@ void agg_renderer<T0,T1>::process(text_symbolizer const& sym,
halo_rasterizer_enum halo_rasterizer = get<halo_rasterizer_enum>(sym, keys::halo_rasterizer,feature, common_.vars_, HALO_RASTERIZER_FULL); halo_rasterizer_enum halo_rasterizer = get<halo_rasterizer_enum>(sym, keys::halo_rasterizer,feature, common_.vars_, HALO_RASTERIZER_FULL);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over); composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over);
composite_mode_e halo_comp_op = get<composite_mode_e>(sym, keys::halo_comp_op, feature, common_.vars_, src_over);
agg_text_renderer<T0> ren(*current_buffer_, agg_text_renderer<T0> ren(*current_buffer_,
halo_rasterizer, halo_rasterizer,
comp_op, comp_op,
halo_comp_op,
common_.scale_factor_, common_.scale_factor_,
common_.font_manager_.get_stroker()); common_.font_manager_.get_stroker());

View file

@ -95,33 +95,33 @@ private:
void parse_map_include(Map & map, xml_node const& include); void parse_map_include(Map & map, xml_node const& include);
void parse_style(Map & map, xml_node const& sty); void parse_style(Map & map, xml_node const& sty);
void parse_layer(Map & map, xml_node const& lay); void parse_layer(Map & map, xml_node const& lay);
void parse_symbolizer_base(symbolizer_base &sym, xml_node const& pt); void parse_symbolizer_base(symbolizer_base &sym, xml_node const& node);
void parse_fontset(Map & map, xml_node const & fset); void parse_fontset(Map & map, xml_node const & fset);
bool parse_font(font_set & fset, xml_node const& f); bool parse_font(font_set & fset, xml_node const& f);
void parse_rule(feature_type_style & style, xml_node const & r); void parse_rule(feature_type_style & style, xml_node const & node);
void parse_symbolizers(rule & rule, xml_node const & node); void parse_symbolizers(rule & rule, xml_node const & node);
void parse_point_symbolizer(rule & rule, xml_node const& sym); void parse_point_symbolizer(rule & rule, xml_node const& node);
void parse_line_pattern_symbolizer(rule & rule, xml_node const& sym); void parse_line_pattern_symbolizer(rule & rule, xml_node const& node);
void parse_polygon_pattern_symbolizer(rule & rule, xml_node const& sym); void parse_polygon_pattern_symbolizer(rule & rule, xml_node const& node);
void parse_text_symbolizer(rule & rule, xml_node const& sym); void parse_text_symbolizer(rule & rule, xml_node const& node);
void parse_shield_symbolizer(rule & rule, xml_node const& sym); void parse_shield_symbolizer(rule & rule, xml_node const& node);
void parse_line_symbolizer(rule & rule, xml_node const& sym); void parse_line_symbolizer(rule & rule, xml_node const& node);
void parse_polygon_symbolizer(rule & rule, xml_node const& sym); void parse_polygon_symbolizer(rule & rule, xml_node const& node);
void parse_building_symbolizer(rule & rule, xml_node const& sym); void parse_building_symbolizer(rule & rule, xml_node const& node);
void parse_raster_symbolizer(rule & rule, xml_node const& sym); void parse_raster_symbolizer(rule & rule, xml_node const& node);
void parse_markers_symbolizer(rule & rule, xml_node const& sym); void parse_markers_symbolizer(rule & rule, xml_node const& node);
void parse_group_symbolizer(rule &rule, xml_node const& sym); void parse_group_symbolizer(rule &rule, xml_node const& node);
void parse_debug_symbolizer(rule & rule, xml_node const& sym); void parse_debug_symbolizer(rule & rule, xml_node const& node);
void parse_group_rule(group_symbolizer_properties &prop, xml_node const &r); void parse_group_rule(group_symbolizer_properties &prop, xml_node const& node);
void parse_simple_layout(group_symbolizer_properties &prop, xml_node const& node); void parse_simple_layout(group_symbolizer_properties &prop, xml_node const& node);
void parse_pair_layout(group_symbolizer_properties &prop, xml_node const &nd); void parse_pair_layout(group_symbolizer_properties &prop, xml_node const& node);
bool parse_raster_colorizer(raster_colorizer_ptr const& rc, xml_node const& node); bool parse_raster_colorizer(raster_colorizer_ptr const& rc, xml_node const& node);
void parse_stroke(symbolizer_base & symbol, xml_node const & sym); void parse_stroke(symbolizer_base & symbol, xml_node const& node);
void ensure_font_face(std::string const& face_name); void ensure_font_face(std::string const& face_name);
void find_unused_nodes(xml_node const& root); void find_unused_nodes(xml_node const& root);
void find_unused_nodes_recursive(xml_node const& node, std::string & error_text); void find_unused_nodes_recursive(xml_node const& node, std::string & error_text);
@ -911,20 +911,20 @@ void map_parser::parse_symbolizer_base(symbolizer_base &sym, xml_node const &pt)
set_symbolizer_property<symbolizer_base,double>(sym, keys::smooth, pt); set_symbolizer_property<symbolizer_base,double>(sym, keys::smooth, pt);
} }
void map_parser::parse_point_symbolizer(rule & rule, xml_node const & sym) void map_parser::parse_point_symbolizer(rule & rule, xml_node const & node)
{ {
try try
{ {
optional<std::string> file = sym.get_opt_attr<std::string>("file"); optional<std::string> file = node.get_opt_attr<std::string>("file");
optional<std::string> base = sym.get_opt_attr<std::string>("base"); optional<std::string> base = node.get_opt_attr<std::string>("base");
optional<std::string> image_transform_wkt = sym.get_opt_attr<std::string>("transform"); optional<std::string> image_transform_wkt = node.get_opt_attr<std::string>("transform");
point_symbolizer symbol; point_symbolizer symbol;
set_symbolizer_property<point_symbolizer,boolean>(symbol, keys::allow_overlap, sym); set_symbolizer_property<point_symbolizer,boolean>(symbol, keys::allow_overlap, node);
set_symbolizer_property<point_symbolizer,double>(symbol, keys::opacity, sym); set_symbolizer_property<point_symbolizer,double>(symbol, keys::opacity, node);
set_symbolizer_property<point_symbolizer,boolean>(symbol, keys::ignore_placement, sym); set_symbolizer_property<point_symbolizer,boolean>(symbol, keys::ignore_placement, node);
boost::optional<point_placement_e> placement = sym.get_opt_attr<point_placement_e>("placement"); boost::optional<point_placement_e> placement = node.get_opt_attr<point_placement_e>("placement");
if (placement) put(symbol, keys::point_placement_type, point_placement_enum(*placement)); if (placement) put(symbol, keys::point_placement_type, point_placement_enum(*placement));
if (file && !file->empty()) if (file && !file->empty())
@ -948,23 +948,23 @@ void map_parser::parse_point_symbolizer(rule & rule, xml_node const & sym)
put(symbol, keys::image_transform, mapnik::parse_transform(*image_transform_wkt)); put(symbol, keys::image_transform, mapnik::parse_transform(*image_transform_wkt));
} }
} }
parse_symbolizer_base(symbol, sym); parse_symbolizer_base(symbol, node);
rule.append(std::move(symbol)); rule.append(std::move(symbol));
} }
catch (config_error const& ex) catch (config_error const& ex)
{ {
ex.append_context(sym); ex.append_context(node);
throw; throw;
} }
} }
void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& sym) void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& node)
{ {
try try
{ {
std::string filename(""); std::string filename("");
optional<std::string> file = sym.get_opt_attr<std::string>("file"); optional<std::string> file = node.get_opt_attr<std::string>("file");
optional<std::string> base = sym.get_opt_attr<std::string>("base"); optional<std::string> base = node.get_opt_attr<std::string>("base");
if (file && !file->empty()) if (file && !file->empty())
{ {
@ -980,7 +980,7 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& sym)
filename = ensure_relative_to_xml(file); filename = ensure_relative_to_xml(file);
} }
optional<std::string> marker_type = sym.get_opt_attr<std::string>("marker-type"); optional<std::string> marker_type = node.get_opt_attr<std::string>("marker-type");
if (marker_type) if (marker_type)
{ {
// TODO - revisit whether to officially deprecate marker-type // TODO - revisit whether to officially deprecate marker-type
@ -1009,64 +1009,64 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& sym)
} }
// overall opacity to be applied to all paths // overall opacity to be applied to all paths
set_symbolizer_property<markers_symbolizer,double>(symbol, keys::opacity, sym); set_symbolizer_property<markers_symbolizer,double>(symbol, keys::opacity, node);
// fill opacity // fill opacity
set_symbolizer_property<markers_symbolizer,double>(symbol, keys::fill_opacity, sym); set_symbolizer_property<markers_symbolizer,double>(symbol, keys::fill_opacity, node);
optional<std::string> image_transform_wkt = sym.get_opt_attr<std::string>("transform"); optional<std::string> image_transform_wkt = node.get_opt_attr<std::string>("transform");
if (image_transform_wkt) if (image_transform_wkt)
{ {
put(symbol, keys::image_transform, mapnik::parse_transform(*image_transform_wkt)); put(symbol, keys::image_transform, mapnik::parse_transform(*image_transform_wkt));
} }
set_symbolizer_property<markers_symbolizer,color>(symbol, keys::fill, sym); set_symbolizer_property<markers_symbolizer,color>(symbol, keys::fill, node);
optional<double> spacing = sym.get_opt_attr<double>("spacing"); optional<double> spacing = node.get_opt_attr<double>("spacing");
if (spacing) put(symbol,keys::spacing, *spacing); if (spacing) put(symbol,keys::spacing, *spacing);
optional<double> max_error = sym.get_opt_attr<double>("max-error"); optional<double> max_error = node.get_opt_attr<double>("max-error");
if (max_error) put(symbol,keys::max_error, *max_error); if (max_error) put(symbol,keys::max_error, *max_error);
set_symbolizer_property<markers_symbolizer,boolean>(symbol, keys::allow_overlap, sym); set_symbolizer_property<markers_symbolizer,boolean>(symbol, keys::allow_overlap, node);
set_symbolizer_property<markers_symbolizer,boolean>(symbol, keys::ignore_placement, sym); set_symbolizer_property<markers_symbolizer,boolean>(symbol, keys::ignore_placement, node);
optional<expression_ptr> width = sym.get_opt_attr<expression_ptr>("width"); optional<expression_ptr> width = node.get_opt_attr<expression_ptr>("width");
if (width) put(symbol, keys::width, *width ); if (width) put(symbol, keys::width, *width );
optional<expression_ptr> height = sym.get_opt_attr<expression_ptr>("height"); optional<expression_ptr> height = node.get_opt_attr<expression_ptr>("height");
if (height) put(symbol, keys::height, *height); if (height) put(symbol, keys::height, *height);
parse_stroke(symbol,sym); parse_stroke(symbol,node);
optional<marker_placement_e> placement = sym.get_opt_attr<marker_placement_e>("placement"); optional<marker_placement_e> placement = node.get_opt_attr<marker_placement_e>("placement");
if (placement) put(symbol, keys::markers_placement_type, marker_placement_enum(*placement)); if (placement) put(symbol, keys::markers_placement_type, marker_placement_enum(*placement));
optional<marker_multi_policy_e> mpolicy = sym.get_opt_attr<marker_multi_policy_e>("multi-policy"); optional<marker_multi_policy_e> mpolicy = node.get_opt_attr<marker_multi_policy_e>("multi-policy");
if (mpolicy) put(symbol, keys::markers_multipolicy, marker_multi_policy_enum(*mpolicy)); if (mpolicy) put(symbol, keys::markers_multipolicy, marker_multi_policy_enum(*mpolicy));
parse_symbolizer_base(symbol, sym); parse_symbolizer_base(symbol, node);
rule.append(std::move(symbol)); rule.append(std::move(symbol));
} }
catch (config_error const& ex) catch (config_error const& ex)
{ {
ex.append_context(sym); ex.append_context(node);
throw; throw;
} }
} }
void map_parser::parse_line_pattern_symbolizer(rule & rule, xml_node const & sym) void map_parser::parse_line_pattern_symbolizer(rule & rule, xml_node const & node)
{ {
try try
{ {
std::string file = sym.get_attr<std::string>("file"); std::string file = node.get_attr<std::string>("file");
if (file.empty()) if (file.empty())
{ {
throw config_error("empty file attribute"); throw config_error("empty file attribute");
} }
optional<std::string> base = sym.get_opt_attr<std::string>("base"); optional<std::string> base = node.get_opt_attr<std::string>("base");
if(base) if(base)
{ {
@ -1083,32 +1083,32 @@ void map_parser::parse_line_pattern_symbolizer(rule & rule, xml_node const & sym
put(symbol, keys::file, parse_path(file)); put(symbol, keys::file, parse_path(file));
// offset value // offset value
optional<double> offset = sym.get_opt_attr<double>("offset"); optional<double> offset = node.get_opt_attr<double>("offset");
if (offset) put(symbol, keys::offset, *offset); if (offset) put(symbol, keys::offset, *offset);
parse_symbolizer_base(symbol, sym); parse_symbolizer_base(symbol, node);
rule.append(std::move(symbol)); rule.append(std::move(symbol));
} }
catch (config_error const& ex) catch (config_error const& ex)
{ {
ex.append_context(sym); ex.append_context(node);
throw; throw;
} }
} }
void map_parser::parse_polygon_pattern_symbolizer(rule & rule, void map_parser::parse_polygon_pattern_symbolizer(rule & rule,
xml_node const & sym) xml_node const & node)
{ {
try try
{ {
std::string file = sym.get_attr<std::string>("file"); std::string file = node.get_attr<std::string>("file");
if (file.empty()) if (file.empty())
{ {
throw config_error("empty file attribute"); throw config_error("empty file attribute");
} }
optional<std::string> base = sym.get_opt_attr<std::string>("base"); optional<std::string> base = node.get_opt_attr<std::string>("base");
if(base) if(base)
{ {
@ -1125,44 +1125,44 @@ void map_parser::parse_polygon_pattern_symbolizer(rule & rule,
put(symbol, keys::file, parse_path(file)); put(symbol, keys::file, parse_path(file));
// pattern alignment // pattern alignment
optional<pattern_alignment_e> p_alignment = sym.get_opt_attr<pattern_alignment_e>("alignment"); optional<pattern_alignment_e> p_alignment = node.get_opt_attr<pattern_alignment_e>("alignment");
if (p_alignment) put(symbol, keys::alignment, pattern_alignment_enum(*p_alignment)); if (p_alignment) put(symbol, keys::alignment, pattern_alignment_enum(*p_alignment));
// opacity // opacity
set_symbolizer_property<polygon_pattern_symbolizer,double>(symbol, keys::opacity, sym); set_symbolizer_property<polygon_pattern_symbolizer,double>(symbol, keys::opacity, node);
// gamma // gamma
optional<double> gamma = sym.get_opt_attr<double>("gamma"); optional<double> gamma = node.get_opt_attr<double>("gamma");
if (gamma) put(symbol, keys::gamma, *gamma); if (gamma) put(symbol, keys::gamma, *gamma);
// gamma method // gamma method
optional<gamma_method_e> gamma_method = sym.get_opt_attr<gamma_method_e>("gamma-method"); optional<gamma_method_e> gamma_method = node.get_opt_attr<gamma_method_e>("gamma-method");
if (gamma_method) put(symbol, keys::gamma_method, gamma_method_enum(*gamma_method)); if (gamma_method) put(symbol, keys::gamma_method, gamma_method_enum(*gamma_method));
parse_symbolizer_base(symbol, sym); parse_symbolizer_base(symbol, node);
rule.append(std::move(symbol)); rule.append(std::move(symbol));
} }
catch (config_error const& ex) catch (config_error const& ex)
{ {
ex.append_context(sym); ex.append_context(node);
throw; throw;
} }
} }
void map_parser::parse_text_symbolizer(rule & rule, xml_node const& sym) void map_parser::parse_text_symbolizer(rule & rule, xml_node const& node)
{ {
try try
{ {
text_placements_ptr placement_finder; text_placements_ptr placement_finder;
optional<std::string> placement_type = sym.get_opt_attr<std::string>("placement-type"); optional<std::string> placement_type = node.get_opt_attr<std::string>("placement-type");
if (placement_type) if (placement_type)
{ {
placement_finder = placements::registry::instance().from_xml(*placement_type, sym, fontsets_); placement_finder = placements::registry::instance().from_xml(*placement_type, node, fontsets_);
} }
else else
{ {
placement_finder = std::make_shared<text_placements_dummy>(); placement_finder = std::make_shared<text_placements_dummy>();
placement_finder->defaults.from_xml(sym, fontsets_); placement_finder->defaults.from_xml(node, fontsets_);
} }
if (strict_ && if (strict_ &&
@ -1171,12 +1171,27 @@ void map_parser::parse_text_symbolizer(rule & rule, xml_node const& sym)
ensure_font_face(placement_finder->defaults.format->face_name); ensure_font_face(placement_finder->defaults.format->face_name);
} }
text_symbolizer text_symbol; text_symbolizer text_symbol;
parse_symbolizer_base(text_symbol, sym); parse_symbolizer_base(text_symbol, node);
// halo-comp-op
optional<std::string> comp_op_name = node.get_opt_attr<std::string>("halo-comp-op");
if (comp_op_name)
{
optional<composite_mode_e> halo_comp_op = comp_op_from_string(*comp_op_name);
if (halo_comp_op)
{
put(text_symbol, keys::halo_comp_op, *halo_comp_op);
}
else
{
throw config_error("failed to parse halo-comp-op: '" + *comp_op_name + "'");
}
}
put<text_placements_ptr>(text_symbol, keys::text_placements_, placement_finder); put<text_placements_ptr>(text_symbol, keys::text_placements_, placement_finder);
optional<halo_rasterizer_e> halo_rasterizer_ = sym.get_opt_attr<halo_rasterizer_e>("halo-rasterizer"); optional<halo_rasterizer_e> halo_rasterizer_ = node.get_opt_attr<halo_rasterizer_e>("halo-rasterizer");
if (halo_rasterizer_) put(text_symbol, keys::halo_rasterizer, halo_rasterizer_enum(*halo_rasterizer_)); if (halo_rasterizer_) put(text_symbol, keys::halo_rasterizer, halo_rasterizer_enum(*halo_rasterizer_));
optional<std::string> halo_transform_wkt = sym.get_opt_attr<std::string>("halo-transform"); optional<std::string> halo_transform_wkt = node.get_opt_attr<std::string>("halo-transform");
if (halo_transform_wkt) if (halo_transform_wkt)
{ {
put(text_symbol, keys::halo_transform, mapnik::parse_transform(*halo_transform_wkt)); put(text_symbol, keys::halo_transform, mapnik::parse_transform(*halo_transform_wkt));
@ -1186,24 +1201,24 @@ void map_parser::parse_text_symbolizer(rule & rule, xml_node const& sym)
} }
catch (config_error const& ex) catch (config_error const& ex)
{ {
ex.append_context(sym); ex.append_context(node);
throw; throw;
} }
} }
void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& sym) void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& node)
{ {
try try
{ {
text_placements_ptr placement_finder; text_placements_ptr placement_finder;
optional<std::string> placement_type = sym.get_opt_attr<std::string>("placement-type"); optional<std::string> placement_type = node.get_opt_attr<std::string>("placement-type");
if (placement_type) if (placement_type)
{ {
placement_finder = placements::registry::instance().from_xml(*placement_type, sym, fontsets_); placement_finder = placements::registry::instance().from_xml(*placement_type, node, fontsets_);
} else { } else {
placement_finder = std::make_shared<text_placements_dummy>(); placement_finder = std::make_shared<text_placements_dummy>();
} }
placement_finder->defaults.from_xml(sym, fontsets_); placement_finder->defaults.from_xml(node, fontsets_);
if (strict_ && if (strict_ &&
!placement_finder->defaults.format->fontset) !placement_finder->defaults.format->fontset)
{ {
@ -1212,36 +1227,36 @@ void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& sym)
shield_symbolizer shield_symbol; shield_symbolizer shield_symbol;
put<text_placements_ptr>(shield_symbol, keys::text_placements_, placement_finder); put<text_placements_ptr>(shield_symbol, keys::text_placements_, placement_finder);
optional<std::string> image_transform_wkt = sym.get_opt_attr<std::string>("transform"); optional<std::string> image_transform_wkt = node.get_opt_attr<std::string>("transform");
if (image_transform_wkt) if (image_transform_wkt)
{ {
put(shield_symbol, keys::image_transform, mapnik::parse_transform(*image_transform_wkt)); put(shield_symbol, keys::image_transform, mapnik::parse_transform(*image_transform_wkt));
} }
// shield displacement // shield displacement
optional<double> shield_dx = sym.get_opt_attr<double>("shield-dx"); optional<double> shield_dx = node.get_opt_attr<double>("shield-dx");
if (shield_dx) put(shield_symbol, keys::shield_dx, *shield_dx); if (shield_dx) put(shield_symbol, keys::shield_dx, *shield_dx);
optional<double> shield_dy = sym.get_opt_attr<double>("shield-dy"); optional<double> shield_dy = node.get_opt_attr<double>("shield-dy");
if (shield_dy) put(shield_symbol, keys::shield_dy, *shield_dy); if (shield_dy) put(shield_symbol, keys::shield_dy, *shield_dy);
// opacity // opacity
set_symbolizer_property<shield_symbolizer,double>(shield_symbol, keys::opacity, sym); set_symbolizer_property<shield_symbolizer,double>(shield_symbol, keys::opacity, node);
// text-opacity // text-opacity
set_symbolizer_property<shield_symbolizer,double>(shield_symbol, keys::text_opacity, sym); set_symbolizer_property<shield_symbolizer,double>(shield_symbol, keys::text_opacity, node);
// unlock_image // unlock_image
optional<boolean> unlock_image = sym.get_opt_attr<boolean>("unlock-image"); optional<boolean> unlock_image = node.get_opt_attr<boolean>("unlock-image");
if (unlock_image) put(shield_symbol, keys::unlock_image, *unlock_image); if (unlock_image) put(shield_symbol, keys::unlock_image, *unlock_image);
std::string file = sym.get_attr<std::string>("file"); std::string file = node.get_attr<std::string>("file");
if (file.empty()) if (file.empty())
{ {
throw config_error("empty file attribute"); throw config_error("empty file attribute");
} }
optional<std::string> base = sym.get_opt_attr<std::string>("base"); optional<std::string> base = node.get_opt_attr<std::string>("base");
if(base) if(base)
{ {
std::map<std::string,std::string>::const_iterator itr = file_sources_.find(*base); std::map<std::string,std::string>::const_iterator itr = file_sources_.find(*base);
@ -1253,7 +1268,7 @@ void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& sym)
// no_text - removed property in 2.1.x that used to have a purpose // no_text - removed property in 2.1.x that used to have a purpose
// before you could provide an expression with an empty string // before you could provide an expression with an empty string
optional<boolean> no_text = sym.get_opt_attr<boolean>("no-text"); optional<boolean> no_text = node.get_opt_attr<boolean>("no-text");
if (no_text) if (no_text)
{ {
MAPNIK_LOG_ERROR(shield_symbolizer) << "'no-text' is deprecated and will be removed in Mapnik 3.x, to create a ShieldSymbolizer without text just provide an element like: \"<ShieldSymbolizer ... />' '</>\""; MAPNIK_LOG_ERROR(shield_symbolizer) << "'no-text' is deprecated and will be removed in Mapnik 3.x, to create a ShieldSymbolizer without text just provide an element like: \"<ShieldSymbolizer ... />' '</>\"";
@ -1265,49 +1280,49 @@ void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& sym)
file = ensure_relative_to_xml(file); file = ensure_relative_to_xml(file);
ensure_exists(file); ensure_exists(file);
put(shield_symbol, keys::file , parse_path(file)); put(shield_symbol, keys::file , parse_path(file));
parse_symbolizer_base(shield_symbol, sym); parse_symbolizer_base(shield_symbol, node);
optional<halo_rasterizer_e> halo_rasterizer_ = sym.get_opt_attr<halo_rasterizer_e>("halo-rasterizer"); optional<halo_rasterizer_e> halo_rasterizer_ = node.get_opt_attr<halo_rasterizer_e>("halo-rasterizer");
if (halo_rasterizer_) put(shield_symbol, keys::halo_rasterizer, halo_rasterizer_enum(*halo_rasterizer_)); if (halo_rasterizer_) put(shield_symbol, keys::halo_rasterizer, halo_rasterizer_enum(*halo_rasterizer_));
rule.append(std::move(shield_symbol)); rule.append(std::move(shield_symbol));
} }
catch (config_error const& ex) catch (config_error const& ex)
{ {
ex.append_context(sym); ex.append_context(node);
throw; throw;
} }
} }
void map_parser::parse_stroke(symbolizer_base & symbol, xml_node const & sym) void map_parser::parse_stroke(symbolizer_base & symbol, xml_node const & node)
{ {
// stroke // stroke
set_symbolizer_property<symbolizer_base,color>(symbol, keys::stroke, sym); set_symbolizer_property<symbolizer_base,color>(symbol, keys::stroke, node);
// stroke-width // stroke-width
set_symbolizer_property<symbolizer_base,double>(symbol, keys::stroke_width, sym); set_symbolizer_property<symbolizer_base,double>(symbol, keys::stroke_width, node);
// stroke-opacity // stroke-opacity
set_symbolizer_property<symbolizer_base,double>(symbol, keys::stroke_opacity, sym); set_symbolizer_property<symbolizer_base,double>(symbol, keys::stroke_opacity, node);
// stroke-linejoin // stroke-linejoin
optional<line_join_e> line_join = sym.get_opt_attr<line_join_e>("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)); if (line_join) put(symbol, keys::stroke_linejoin, line_join_enum(*line_join));
// stroke-linecap // stroke-linecap
optional<line_cap_e> line_cap = sym.get_opt_attr<line_cap_e>("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)); if (line_cap) put(symbol, keys::stroke_linecap,line_cap_enum(*line_cap));
// stroke-gamma // stroke-gamma
optional<double> gamma = sym.get_opt_attr<double>("stroke-gamma"); optional<double> gamma = node.get_opt_attr<double>("stroke-gamma");
if (gamma) put(symbol, keys::stroke_gamma, *gamma); if (gamma) put(symbol, keys::stroke_gamma, *gamma);
// stroke-gamma-method // stroke-gamma-method
optional<gamma_method_e> gamma_method = sym.get_opt_attr<gamma_method_e>("stroke-gamma-method"); optional<gamma_method_e> gamma_method = node.get_opt_attr<gamma_method_e>("stroke-gamma-method");
if (gamma_method) put(symbol, keys::stroke_gamma_method, gamma_method_enum(*gamma_method)); if (gamma_method) put(symbol, keys::stroke_gamma_method, gamma_method_enum(*gamma_method));
// stroke-dashoffset // stroke-dashoffset
optional<double> dash_offset = sym.get_opt_attr<double>("stroke-dashoffset"); optional<double> dash_offset = node.get_opt_attr<double>("stroke-dashoffset");
if (dash_offset) put(symbol,keys::stroke_dashoffset, *dash_offset); if (dash_offset) put(symbol,keys::stroke_dashoffset, *dash_offset);
// stroke-dasharray // stroke-dasharray
optional<std::string> str = sym.get_opt_attr<std::string>("stroke-dasharray"); optional<std::string> str = node.get_opt_attr<std::string>("stroke-dasharray");
if (str) if (str)
{ {
std::vector<double> buf; std::vector<double> buf;
@ -1346,7 +1361,7 @@ void map_parser::parse_stroke(symbolizer_base & symbol, xml_node const & sym)
} }
// stroke-miterlimit // stroke-miterlimit
optional<double> miterlimit = sym.get_opt_attr<double>("stroke-miterlimit"); optional<double> miterlimit = node.get_opt_attr<double>("stroke-miterlimit");
if (miterlimit) put(symbol, keys::stroke_miterlimit, *miterlimit); if (miterlimit) put(symbol, keys::stroke_miterlimit, *miterlimit);
} }
@ -1397,38 +1412,38 @@ void map_parser::parse_polygon_symbolizer(rule & rule, xml_node const & node)
} }
} }
void map_parser::parse_building_symbolizer(rule & rule, xml_node const & sym) void map_parser::parse_building_symbolizer(rule & rule, xml_node const & node)
{ {
try try
{ {
building_symbolizer building_sym; building_symbolizer building_sym;
// fill // fill
set_symbolizer_property<building_symbolizer,color>(building_sym, keys::fill, sym); set_symbolizer_property<building_symbolizer,color>(building_sym, keys::fill, node);
// fill-opacity // fill-opacity
set_symbolizer_property<building_symbolizer,double>(building_sym, keys::fill_opacity, sym); set_symbolizer_property<building_symbolizer,double>(building_sym, keys::fill_opacity, node);
// height // height
optional<expression_ptr> height = sym.get_opt_attr<expression_ptr>("height"); optional<expression_ptr> height = node.get_opt_attr<expression_ptr>("height");
if (height) put(building_sym, keys::height, *height); if (height) put(building_sym, keys::height, *height);
parse_symbolizer_base(building_sym, sym); parse_symbolizer_base(building_sym, node);
rule.append(std::move(building_sym)); rule.append(std::move(building_sym));
} }
catch (config_error const& ex) catch (config_error const& ex)
{ {
ex.append_context(sym); ex.append_context(node);
throw; throw;
} }
} }
void map_parser::parse_raster_symbolizer(rule & rule, xml_node const & sym) void map_parser::parse_raster_symbolizer(rule & rule, xml_node const & node)
{ {
try try
{ {
raster_symbolizer raster_sym; raster_symbolizer raster_sym;
// mode // mode
optional<std::string> mode = sym.get_opt_attr<std::string>("mode"); optional<std::string> mode = node.get_opt_attr<std::string>("mode");
if (mode) if (mode)
{ {
std::string mode_string = *mode; std::string mode_string = *mode;
@ -1441,7 +1456,7 @@ void map_parser::parse_raster_symbolizer(rule & rule, xml_node const & sym)
} }
// scaling // scaling
optional<std::string> scaling = sym.get_opt_attr<std::string>("scaling"); optional<std::string> scaling = node.get_opt_attr<std::string>("scaling");
if (scaling) if (scaling)
{ {
std::string scaling_method = *scaling; std::string scaling_method = *scaling;
@ -1465,23 +1480,23 @@ void map_parser::parse_raster_symbolizer(rule & rule, xml_node const & sym)
} }
// opacity // opacity
optional<double> opacity = sym.get_opt_attr<double>("opacity"); optional<double> opacity = node.get_opt_attr<double>("opacity");
if (opacity) put(raster_sym, keys::opacity, *opacity); if (opacity) put(raster_sym, keys::opacity, *opacity);
// filter factor // filter factor
optional<double> filter_factor = sym.get_opt_attr<double>("filter-factor"); optional<double> filter_factor = node.get_opt_attr<double>("filter-factor");
if (filter_factor) put(raster_sym, keys::filter_factor, *filter_factor); if (filter_factor) put(raster_sym, keys::filter_factor, *filter_factor);
// mesh-size // mesh-size
optional<unsigned> mesh_size = sym.get_opt_attr<unsigned>("mesh-size"); optional<unsigned> mesh_size = node.get_opt_attr<unsigned>("mesh-size");
if (mesh_size) put<value_integer>(raster_sym, keys::mesh_size, *mesh_size); if (mesh_size) put<value_integer>(raster_sym, keys::mesh_size, *mesh_size);
// premultiplied status of image // premultiplied status of image
optional<boolean> premultiplied = sym.get_opt_attr<boolean>("premultiplied"); optional<boolean> premultiplied = node.get_opt_attr<boolean>("premultiplied");
if (premultiplied) put(raster_sym, keys::premultiplied, *premultiplied); if (premultiplied) put(raster_sym, keys::premultiplied, *premultiplied);
bool found_colorizer = false; bool found_colorizer = false;
for ( auto const& css : sym) for ( auto const& css : node)
{ {
if (css.is("RasterColorizer")) if (css.is("RasterColorizer"))
{ {
@ -1496,52 +1511,52 @@ void map_parser::parse_raster_symbolizer(rule & rule, xml_node const & sym)
if (!found_colorizer) if (!found_colorizer)
{ {
raster_colorizer_ptr colorizer = std::make_shared<raster_colorizer>(); raster_colorizer_ptr colorizer = std::make_shared<raster_colorizer>();
if (parse_raster_colorizer(colorizer, sym)) if (parse_raster_colorizer(colorizer, node))
put(raster_sym, keys::colorizer, colorizer); put(raster_sym, keys::colorizer, colorizer);
} }
parse_symbolizer_base(raster_sym, sym); parse_symbolizer_base(raster_sym, node);
rule.append(std::move(raster_sym)); rule.append(std::move(raster_sym));
} }
catch (config_error const& ex) catch (config_error const& ex)
{ {
ex.append_context(sym); ex.append_context(node);
throw; throw;
} }
} }
void map_parser::parse_group_symbolizer(rule &rule, xml_node const & sym) void map_parser::parse_group_symbolizer(rule &rule, xml_node const & node)
{ {
try try
{ {
group_symbolizer symbol; group_symbolizer symbol;
group_symbolizer_properties_ptr prop = std::make_shared<group_symbolizer_properties>(); group_symbolizer_properties_ptr prop = std::make_shared<group_symbolizer_properties>();
set_symbolizer_property<symbolizer_base, value_integer>(symbol, keys::num_columns, sym); set_symbolizer_property<symbolizer_base, value_integer>(symbol, keys::num_columns, node);
set_symbolizer_property<symbolizer_base, value_integer>(symbol, keys::start_column, sym); set_symbolizer_property<symbolizer_base, value_integer>(symbol, keys::start_column, node);
set_symbolizer_property<symbolizer_base, expression_ptr>(symbol, keys::repeat_key, sym); set_symbolizer_property<symbolizer_base, expression_ptr>(symbol, keys::repeat_key, node);
text_placements_ptr placements = std::make_shared<text_placements_dummy>(); text_placements_ptr placements = std::make_shared<text_placements_dummy>();
placements->defaults.placement_properties_from_xml(sym); placements->defaults.placement_properties_from_xml(node);
put<text_placements_ptr>(symbol, keys::text_placements_, placements); put<text_placements_ptr>(symbol, keys::text_placements_, placements);
size_t layout_count = 0; size_t layout_count = 0;
for (auto const& node : sym) for (auto const& child_node : node)
{ {
if (node.is("GroupRule")) if (child_node.is("GroupRule"))
{ {
parse_group_rule(*prop, node); parse_group_rule(*prop, child_node);
node.set_processed(true); child_node.set_processed(true);
} }
else if (node.is("SimpleLayout")) else if (child_node.is("SimpleLayout"))
{ {
parse_simple_layout(*prop, node); parse_simple_layout(*prop, child_node);
node.set_processed(true); child_node.set_processed(true);
++layout_count; ++layout_count;
} }
else if (node.is("PairLayout")) else if (child_node.is("PairLayout"))
{ {
parse_pair_layout(*prop, node); parse_pair_layout(*prop, child_node);
node.set_processed(true); child_node.set_processed(true);
++layout_count; ++layout_count;
} }
if (layout_count > 1) if (layout_count > 1)
@ -1551,21 +1566,21 @@ void map_parser::parse_group_symbolizer(rule &rule, xml_node const & sym)
} }
put(symbol, keys::group_properties, prop); put(symbol, keys::group_properties, prop);
parse_symbolizer_base(symbol, sym); parse_symbolizer_base(symbol, node);
rule.append(symbol); rule.append(symbol);
} }
catch (const config_error & ex) catch (const config_error & ex)
{ {
ex.append_context(sym); ex.append_context(node);
throw; throw;
} }
} }
void map_parser::parse_debug_symbolizer(rule & rule, xml_node const & sym) void map_parser::parse_debug_symbolizer(rule & rule, xml_node const & node)
{ {
debug_symbolizer symbol; debug_symbolizer symbol;
parse_symbolizer_base(symbol, sym); parse_symbolizer_base(symbol, node);
optional<debug_symbolizer_mode_e> mode = sym.get_opt_attr<debug_symbolizer_mode_e>("mode"); optional<debug_symbolizer_mode_e> mode = node.get_opt_attr<debug_symbolizer_mode_e>("mode");
if (mode) put(symbol, keys::mode, debug_symbolizer_mode_enum(*mode)); if (mode) put(symbol, keys::mode, debug_symbolizer_mode_enum(*mode));
rule.append(std::move(symbol)); rule.append(std::move(symbol));
} }

View file

@ -96,7 +96,9 @@ static const property_meta_type key_meta[to_integral(keys::MAX_SYMBOLIZER_KEY)]
property_meta_type{ "repeat-key", nullptr, nullptr, property_types::target_repeat_key}, property_meta_type{ "repeat-key", nullptr, nullptr, property_types::target_repeat_key},
property_meta_type{ "symbolizer-properties", nullptr, nullptr, property_types::target_group_symbolizer_properties}, property_meta_type{ "symbolizer-properties", nullptr, nullptr, property_types::target_group_symbolizer_properties},
property_meta_type{ "largest-box-only", false, nullptr, property_types::target_bool }, property_meta_type{ "largest-box-only", false, nullptr, property_types::target_bool },
property_meta_type{ "minimum-path-length", false, nullptr, property_types::target_double } property_meta_type{ "minimum-path-length", false, nullptr, property_types::target_double },
property_meta_type{ "halo-comp-op", enumeration_wrapper(src_over),
[](enumeration_wrapper e) { return *comp_op_to_string(composite_mode_e(e.value)); }, property_types::target_comp_op},
}; };
property_meta_type const& get_meta(mapnik::keys key) property_meta_type const& get_meta(mapnik::keys key)

View file

@ -31,9 +31,10 @@
namespace mapnik namespace mapnik
{ {
text_renderer::text_renderer (halo_rasterizer_e rasterizer, composite_mode_e comp_op, double scale_factor, stroker_ptr stroker) text_renderer::text_renderer (halo_rasterizer_e rasterizer, composite_mode_e comp_op, composite_mode_e halo_comp_op, double scale_factor, stroker_ptr stroker)
: rasterizer_(rasterizer), : rasterizer_(rasterizer),
comp_op_(comp_op), comp_op_(comp_op),
halo_comp_op_(halo_comp_op),
scale_factor_(scale_factor), scale_factor_(scale_factor),
glyphs_(), glyphs_(),
stroker_(stroker), stroker_(stroker),
@ -109,9 +110,10 @@ template <typename T>
agg_text_renderer<T>::agg_text_renderer (pixmap_type & pixmap, agg_text_renderer<T>::agg_text_renderer (pixmap_type & pixmap,
halo_rasterizer_e rasterizer, halo_rasterizer_e rasterizer,
composite_mode_e comp_op, composite_mode_e comp_op,
composite_mode_e halo_comp_op,
double scale_factor, double scale_factor,
stroker_ptr stroker) stroker_ptr stroker)
: text_renderer(rasterizer, comp_op, scale_factor, stroker), pixmap_(pixmap) : text_renderer(rasterizer, comp_op, halo_comp_op, scale_factor, stroker), pixmap_(pixmap)
{} {}
template <typename T> template <typename T>
@ -177,7 +179,7 @@ void agg_text_renderer<T>::render(glyph_positions const& pos)
bit->left, bit->left,
height - bit->top, height - bit->top,
format->halo_opacity, format->halo_opacity,
comp_op_); halo_comp_op_);
} }
} }
else else
@ -192,7 +194,7 @@ void agg_text_renderer<T>::render(glyph_positions const& pos)
height - bit->top, height - bit->top,
halo_radius, halo_radius,
format->halo_opacity, format->halo_opacity,
comp_op_); halo_comp_op_);
} }
} }
} }
@ -342,12 +344,11 @@ void grid_text_renderer<T>::render_halo_id(
template <typename T> template <typename T>
grid_text_renderer<T>::grid_text_renderer(pixmap_type &pixmap, grid_text_renderer<T>::grid_text_renderer(pixmap_type &pixmap,
composite_mode_e comp_op, composite_mode_e comp_op,
double scale_factor) : double scale_factor)
text_renderer(HALO_RASTERIZER_FAST, comp_op, scale_factor), pixmap_(pixmap) : text_renderer(HALO_RASTERIZER_FAST, comp_op, src_over, scale_factor),
{ pixmap_(pixmap) {}
}
template class agg_text_renderer<image_32>; template class agg_text_renderer<image_32>;
template class grid_text_renderer<grid>; template class grid_text_renderer<grid>;
}
} // namespace mapnik