diff --git a/include/mapnik/symbolizer_keys.hpp b/include/mapnik/symbolizer_keys.hpp index a1d86f9a6..f509ed701 100644 --- a/include/mapnik/symbolizer_keys.hpp +++ b/include/mapnik/symbolizer_keys.hpp @@ -84,6 +84,7 @@ enum class keys : std::uint8_t group_properties, largest_box_only, minimum_path_length, + halo_comp_op, MAX_SYMBOLIZER_KEY }; diff --git a/include/mapnik/text/renderer.hpp b/include/mapnik/text/renderer.hpp index 37ef4015e..f5b4ec591 100644 --- a/include/mapnik/text/renderer.hpp +++ b/include/mapnik/text/renderer.hpp @@ -69,6 +69,7 @@ class text_renderer : private mapnik::noncopyable public: text_renderer (halo_rasterizer_e rasterizer, composite_mode_e comp_op = src_over, + composite_mode_e halo_comp_op = src_over, double scale_factor=1.0, stroker_ptr stroker=stroker_ptr()); void set_transform(agg::trans_affine const& transform); @@ -78,6 +79,7 @@ protected: void prepare_glyphs(glyph_positions const& positions); halo_rasterizer_e rasterizer_; composite_mode_e comp_op_; + composite_mode_e halo_comp_op_; double scale_factor_; glyph_vector glyphs_; stroker_ptr stroker_; @@ -92,8 +94,9 @@ public: typedef T pixmap_type; agg_text_renderer (pixmap_type & pixmap, halo_rasterizer_e rasterizer, composite_mode_e comp_op = src_over, - double scale_factor=1.0, - stroker_ptr stroker=stroker_ptr()); + composite_mode_e halo_comp_op = src_over, + double scale_factor = 1.0, + stroker_ptr stroker = stroker_ptr()); void render(glyph_positions const& positions); private: pixmap_type & pixmap_; @@ -107,8 +110,9 @@ class grid_text_renderer : public text_renderer { public: typedef T pixmap_type; - grid_text_renderer (pixmap_type & pixmap, composite_mode_e comp_op = src_over, - double scale_factor=1.0); + grid_text_renderer (pixmap_type & pixmap, + composite_mode_e comp_op = src_over, + double scale_factor = 1.0); void render(glyph_positions const& positions, value_integer feature_id); private: pixmap_type & pixmap_; diff --git a/src/agg/process_group_symbolizer.cpp b/src/agg/process_group_symbolizer.cpp index f04580f12..1b453689c 100644 --- a/src/agg/process_group_symbolizer.cpp +++ b/src/agg/process_group_symbolizer.cpp @@ -41,7 +41,7 @@ namespace mapnik { /** - * Render a thunk which was frozen from a previous call to + * Render a thunk which was frozen from a previous call to * extract_bboxes. We should now have a new offset at which * to render it, and the boxes themselves should already be * in the detector from the placement_finder. @@ -68,7 +68,7 @@ struct thunk_renderer : public boost::static_visitor<> 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()); render_offset_placements( diff --git a/src/agg/process_shield_symbolizer.cpp b/src/agg/process_shield_symbolizer.cpp index 2f4035045..4d5f038e1 100644 --- a/src/agg/process_shield_symbolizer.cpp +++ b/src/agg/process_shield_symbolizer.cpp @@ -46,11 +46,13 @@ void agg_renderer::process(shield_symbolizer const& sym, halo_rasterizer_enum halo_rasterizer = get(sym, keys::halo_rasterizer, feature, common_.vars_, HALO_RASTERIZER_FULL); composite_mode_e comp_op = get(sym, keys::comp_op, feature, common_.vars_, src_over); + composite_mode_e halo_comp_op = get(sym, keys::halo_comp_op, feature, common_.vars_, src_over); agg_text_renderer ren(*current_buffer_, - halo_rasterizer, - comp_op, - common_.scale_factor_, - common_.font_manager_.get_stroker()); + halo_rasterizer, + comp_op, + halo_comp_op, + common_.scale_factor_, + common_.font_manager_.get_stroker()); double opacity = get(sym,keys::opacity, feature, common_.vars_, 1.0); diff --git a/src/agg/process_text_symbolizer.cpp b/src/agg/process_text_symbolizer.cpp index 440123ea1..0994e9708 100644 --- a/src/agg/process_text_symbolizer.cpp +++ b/src/agg/process_text_symbolizer.cpp @@ -46,11 +46,13 @@ void agg_renderer::process(text_symbolizer const& sym, halo_rasterizer_enum halo_rasterizer = get(sym, keys::halo_rasterizer,feature, common_.vars_, HALO_RASTERIZER_FULL); composite_mode_e comp_op = get(sym, keys::comp_op, feature, common_.vars_, src_over); + composite_mode_e halo_comp_op = get(sym, keys::halo_comp_op, feature, common_.vars_, src_over); agg_text_renderer ren(*current_buffer_, - halo_rasterizer, - comp_op, - common_.scale_factor_, - common_.font_manager_.get_stroker()); + halo_rasterizer, + comp_op, + halo_comp_op, + common_.scale_factor_, + common_.font_manager_.get_stroker()); agg::trans_affine halo_transform; auto transform = get_optional(sym, keys::halo_transform); diff --git a/src/load_map.cpp b/src/load_map.cpp index b5ee7c77f..d729cffd1 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -95,33 +95,33 @@ private: void parse_map_include(Map & map, xml_node const& include); void parse_style(Map & map, xml_node const& sty); 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); 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_point_symbolizer(rule & rule, xml_node const& sym); - void parse_line_pattern_symbolizer(rule & rule, xml_node const& sym); - void parse_polygon_pattern_symbolizer(rule & rule, xml_node const& sym); - void parse_text_symbolizer(rule & rule, xml_node const& sym); - void parse_shield_symbolizer(rule & rule, xml_node const& sym); - void parse_line_symbolizer(rule & rule, xml_node const& sym); - void parse_polygon_symbolizer(rule & rule, xml_node const& sym); - void parse_building_symbolizer(rule & rule, xml_node const& sym); - void parse_raster_symbolizer(rule & rule, xml_node const& sym); - void parse_markers_symbolizer(rule & rule, xml_node const& sym); - void parse_group_symbolizer(rule &rule, xml_node const& sym); - void parse_debug_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& node); + void parse_polygon_pattern_symbolizer(rule & rule, xml_node const& node); + void parse_text_symbolizer(rule & rule, xml_node const& node); + void parse_shield_symbolizer(rule & rule, xml_node const& node); + void parse_line_symbolizer(rule & rule, xml_node const& node); + void parse_polygon_symbolizer(rule & rule, xml_node const& node); + void parse_building_symbolizer(rule & rule, xml_node const& node); + void parse_raster_symbolizer(rule & rule, xml_node const& node); + void parse_markers_symbolizer(rule & rule, xml_node const& node); + void parse_group_symbolizer(rule &rule, xml_node const& node); + void parse_debug_symbolizer(rule & rule, xml_node const& node); - void parse_group_rule(group_symbolizer_properties &prop, xml_node const &r); - 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_group_rule(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& 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 find_unused_nodes(xml_node const& root); 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(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 { - optional file = sym.get_opt_attr("file"); - optional base = sym.get_opt_attr("base"); - optional image_transform_wkt = sym.get_opt_attr("transform"); + optional file = node.get_opt_attr("file"); + optional base = node.get_opt_attr("base"); + optional image_transform_wkt = node.get_opt_attr("transform"); point_symbolizer symbol; - set_symbolizer_property(symbol, keys::allow_overlap, sym); - set_symbolizer_property(symbol, keys::opacity, sym); - set_symbolizer_property(symbol, keys::ignore_placement, sym); + set_symbolizer_property(symbol, keys::allow_overlap, node); + set_symbolizer_property(symbol, keys::opacity, node); + set_symbolizer_property(symbol, keys::ignore_placement, node); - boost::optional placement = sym.get_opt_attr("placement"); + boost::optional placement = node.get_opt_attr("placement"); if (placement) put(symbol, keys::point_placement_type, point_placement_enum(*placement)); 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)); } } - parse_symbolizer_base(symbol, sym); + parse_symbolizer_base(symbol, node); rule.append(std::move(symbol)); } catch (config_error const& ex) { - ex.append_context(sym); + ex.append_context(node); 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 { std::string filename(""); - optional file = sym.get_opt_attr("file"); - optional base = sym.get_opt_attr("base"); + optional file = node.get_opt_attr("file"); + optional base = node.get_opt_attr("base"); 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); } - optional marker_type = sym.get_opt_attr("marker-type"); + optional marker_type = node.get_opt_attr("marker-type"); if (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 - set_symbolizer_property(symbol, keys::opacity, sym); + set_symbolizer_property(symbol, keys::opacity, node); // fill opacity - set_symbolizer_property(symbol, keys::fill_opacity, sym); + set_symbolizer_property(symbol, keys::fill_opacity, node); - optional image_transform_wkt = sym.get_opt_attr("transform"); + optional image_transform_wkt = node.get_opt_attr("transform"); if (image_transform_wkt) { put(symbol, keys::image_transform, mapnik::parse_transform(*image_transform_wkt)); } - set_symbolizer_property(symbol, keys::fill, sym); + set_symbolizer_property(symbol, keys::fill, node); - optional spacing = sym.get_opt_attr("spacing"); + optional spacing = node.get_opt_attr("spacing"); if (spacing) put(symbol,keys::spacing, *spacing); - optional max_error = sym.get_opt_attr("max-error"); + optional max_error = node.get_opt_attr("max-error"); if (max_error) put(symbol,keys::max_error, *max_error); - set_symbolizer_property(symbol, keys::allow_overlap, sym); + set_symbolizer_property(symbol, keys::allow_overlap, node); - set_symbolizer_property(symbol, keys::ignore_placement, sym); + set_symbolizer_property(symbol, keys::ignore_placement, node); - optional width = sym.get_opt_attr("width"); + optional width = node.get_opt_attr("width"); if (width) put(symbol, keys::width, *width ); - optional height = sym.get_opt_attr("height"); + optional height = node.get_opt_attr("height"); if (height) put(symbol, keys::height, *height); - parse_stroke(symbol,sym); + parse_stroke(symbol,node); - optional placement = sym.get_opt_attr("placement"); + optional placement = node.get_opt_attr("placement"); if (placement) put(symbol, keys::markers_placement_type, marker_placement_enum(*placement)); - optional mpolicy = sym.get_opt_attr("multi-policy"); + optional mpolicy = node.get_opt_attr("multi-policy"); 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)); } catch (config_error const& ex) { - ex.append_context(sym); + ex.append_context(node); 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 { - std::string file = sym.get_attr("file"); + std::string file = node.get_attr("file"); if (file.empty()) { throw config_error("empty file attribute"); } - optional base = sym.get_opt_attr("base"); + optional base = node.get_opt_attr("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)); // offset value - optional offset = sym.get_opt_attr("offset"); + optional offset = node.get_opt_attr("offset"); if (offset) put(symbol, keys::offset, *offset); - parse_symbolizer_base(symbol, sym); + parse_symbolizer_base(symbol, node); rule.append(std::move(symbol)); } catch (config_error const& ex) { - ex.append_context(sym); + ex.append_context(node); throw; } } void map_parser::parse_polygon_pattern_symbolizer(rule & rule, - xml_node const & sym) + xml_node const & node) { try { - std::string file = sym.get_attr("file"); + std::string file = node.get_attr("file"); if (file.empty()) { throw config_error("empty file attribute"); } - optional base = sym.get_opt_attr("base"); + optional base = node.get_opt_attr("base"); if(base) { @@ -1125,44 +1125,44 @@ void map_parser::parse_polygon_pattern_symbolizer(rule & rule, put(symbol, keys::file, parse_path(file)); // pattern alignment - optional p_alignment = sym.get_opt_attr("alignment"); + optional p_alignment = node.get_opt_attr("alignment"); if (p_alignment) put(symbol, keys::alignment, pattern_alignment_enum(*p_alignment)); // opacity - set_symbolizer_property(symbol, keys::opacity, sym); + set_symbolizer_property(symbol, keys::opacity, node); // gamma - optional gamma = sym.get_opt_attr("gamma"); + optional gamma = node.get_opt_attr("gamma"); if (gamma) put(symbol, keys::gamma, *gamma); // gamma method - optional gamma_method = sym.get_opt_attr("gamma-method"); + optional gamma_method = node.get_opt_attr("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)); } catch (config_error const& ex) { - ex.append_context(sym); + ex.append_context(node); 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 { text_placements_ptr placement_finder; - optional placement_type = sym.get_opt_attr("placement-type"); + optional placement_type = node.get_opt_attr("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 { placement_finder = std::make_shared(); - placement_finder->defaults.from_xml(sym, fontsets_); + placement_finder->defaults.from_xml(node, fontsets_); } 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); } text_symbolizer text_symbol; - parse_symbolizer_base(text_symbol, sym); + parse_symbolizer_base(text_symbol, node); + // halo-comp-op + optional comp_op_name = node.get_opt_attr("halo-comp-op"); + if (comp_op_name) + { + optional 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_symbol, keys::text_placements_, placement_finder); - optional halo_rasterizer_ = sym.get_opt_attr("halo-rasterizer"); + optional halo_rasterizer_ = node.get_opt_attr("halo-rasterizer"); if (halo_rasterizer_) put(text_symbol, keys::halo_rasterizer, halo_rasterizer_enum(*halo_rasterizer_)); - optional halo_transform_wkt = sym.get_opt_attr("halo-transform"); + optional halo_transform_wkt = node.get_opt_attr("halo-transform"); if (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) { - ex.append_context(sym); + ex.append_context(node); 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 { text_placements_ptr placement_finder; - optional placement_type = sym.get_opt_attr("placement-type"); + optional placement_type = node.get_opt_attr("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 { placement_finder = std::make_shared(); } - placement_finder->defaults.from_xml(sym, fontsets_); + placement_finder->defaults.from_xml(node, fontsets_); if (strict_ && !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; put(shield_symbol, keys::text_placements_, placement_finder); - optional image_transform_wkt = sym.get_opt_attr("transform"); + optional image_transform_wkt = node.get_opt_attr("transform"); if (image_transform_wkt) { put(shield_symbol, keys::image_transform, mapnik::parse_transform(*image_transform_wkt)); } // shield displacement - optional shield_dx = sym.get_opt_attr("shield-dx"); + optional shield_dx = node.get_opt_attr("shield-dx"); if (shield_dx) put(shield_symbol, keys::shield_dx, *shield_dx); - optional shield_dy = sym.get_opt_attr("shield-dy"); + optional shield_dy = node.get_opt_attr("shield-dy"); if (shield_dy) put(shield_symbol, keys::shield_dy, *shield_dy); // opacity - set_symbolizer_property(shield_symbol, keys::opacity, sym); + set_symbolizer_property(shield_symbol, keys::opacity, node); // text-opacity - set_symbolizer_property(shield_symbol, keys::text_opacity, sym); + set_symbolizer_property(shield_symbol, keys::text_opacity, node); // unlock_image - optional unlock_image = sym.get_opt_attr("unlock-image"); + optional unlock_image = node.get_opt_attr("unlock-image"); if (unlock_image) put(shield_symbol, keys::unlock_image, *unlock_image); - std::string file = sym.get_attr("file"); + std::string file = node.get_attr("file"); if (file.empty()) { throw config_error("empty file attribute"); } - optional base = sym.get_opt_attr("base"); + optional base = node.get_opt_attr("base"); if(base) { std::map::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 // before you could provide an expression with an empty string - optional no_text = sym.get_opt_attr("no-text"); + optional no_text = node.get_opt_attr("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: \"' '\""; @@ -1265,49 +1280,49 @@ void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& sym) file = ensure_relative_to_xml(file); ensure_exists(file); put(shield_symbol, keys::file , parse_path(file)); - parse_symbolizer_base(shield_symbol, sym); - optional halo_rasterizer_ = sym.get_opt_attr("halo-rasterizer"); + parse_symbolizer_base(shield_symbol, node); + optional halo_rasterizer_ = node.get_opt_attr("halo-rasterizer"); if (halo_rasterizer_) put(shield_symbol, keys::halo_rasterizer, halo_rasterizer_enum(*halo_rasterizer_)); rule.append(std::move(shield_symbol)); } catch (config_error const& ex) { - ex.append_context(sym); + ex.append_context(node); 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 - set_symbolizer_property(symbol, keys::stroke, sym); + set_symbolizer_property(symbol, keys::stroke, node); // stroke-width - set_symbolizer_property(symbol, keys::stroke_width, sym); + set_symbolizer_property(symbol, keys::stroke_width, node); // stroke-opacity - set_symbolizer_property(symbol, keys::stroke_opacity, sym); + set_symbolizer_property(symbol, keys::stroke_opacity, node); // stroke-linejoin - optional line_join = sym.get_opt_attr("stroke-linejoin"); + optional line_join = node.get_opt_attr("stroke-linejoin"); if (line_join) put(symbol, keys::stroke_linejoin, line_join_enum(*line_join)); // stroke-linecap - optional line_cap = sym.get_opt_attr("stroke-linecap"); + optional line_cap = node.get_opt_attr("stroke-linecap"); if (line_cap) put(symbol, keys::stroke_linecap,line_cap_enum(*line_cap)); // stroke-gamma - optional gamma = sym.get_opt_attr("stroke-gamma"); + optional gamma = node.get_opt_attr("stroke-gamma"); if (gamma) put(symbol, keys::stroke_gamma, *gamma); // stroke-gamma-method - optional gamma_method = sym.get_opt_attr("stroke-gamma-method"); + optional gamma_method = node.get_opt_attr("stroke-gamma-method"); if (gamma_method) put(symbol, keys::stroke_gamma_method, gamma_method_enum(*gamma_method)); // stroke-dashoffset - optional dash_offset = sym.get_opt_attr("stroke-dashoffset"); + optional dash_offset = node.get_opt_attr("stroke-dashoffset"); if (dash_offset) put(symbol,keys::stroke_dashoffset, *dash_offset); // stroke-dasharray - optional str = sym.get_opt_attr("stroke-dasharray"); + optional str = node.get_opt_attr("stroke-dasharray"); if (str) { std::vector buf; @@ -1346,7 +1361,7 @@ void map_parser::parse_stroke(symbolizer_base & symbol, xml_node const & sym) } // stroke-miterlimit - optional miterlimit = sym.get_opt_attr("stroke-miterlimit"); + optional miterlimit = node.get_opt_attr("stroke-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 { building_symbolizer building_sym; // fill - set_symbolizer_property(building_sym, keys::fill, sym); + set_symbolizer_property(building_sym, keys::fill, node); // fill-opacity - set_symbolizer_property(building_sym, keys::fill_opacity, sym); + set_symbolizer_property(building_sym, keys::fill_opacity, node); // height - optional height = sym.get_opt_attr("height"); + optional height = node.get_opt_attr("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)); } catch (config_error const& ex) { - ex.append_context(sym); + ex.append_context(node); 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 { raster_symbolizer raster_sym; // mode - optional mode = sym.get_opt_attr("mode"); + optional mode = node.get_opt_attr("mode"); if (mode) { std::string mode_string = *mode; @@ -1441,7 +1456,7 @@ void map_parser::parse_raster_symbolizer(rule & rule, xml_node const & sym) } // scaling - optional scaling = sym.get_opt_attr("scaling"); + optional scaling = node.get_opt_attr("scaling"); if (scaling) { std::string scaling_method = *scaling; @@ -1465,23 +1480,23 @@ void map_parser::parse_raster_symbolizer(rule & rule, xml_node const & sym) } // opacity - optional opacity = sym.get_opt_attr("opacity"); + optional opacity = node.get_opt_attr("opacity"); if (opacity) put(raster_sym, keys::opacity, *opacity); // filter factor - optional filter_factor = sym.get_opt_attr("filter-factor"); + optional filter_factor = node.get_opt_attr("filter-factor"); if (filter_factor) put(raster_sym, keys::filter_factor, *filter_factor); // mesh-size - optional mesh_size = sym.get_opt_attr("mesh-size"); + optional mesh_size = node.get_opt_attr("mesh-size"); if (mesh_size) put(raster_sym, keys::mesh_size, *mesh_size); // premultiplied status of image - optional premultiplied = sym.get_opt_attr("premultiplied"); + optional premultiplied = node.get_opt_attr("premultiplied"); if (premultiplied) put(raster_sym, keys::premultiplied, *premultiplied); bool found_colorizer = false; - for ( auto const& css : sym) + for ( auto const& css : node) { if (css.is("RasterColorizer")) { @@ -1496,52 +1511,52 @@ void map_parser::parse_raster_symbolizer(rule & rule, xml_node const & sym) if (!found_colorizer) { raster_colorizer_ptr colorizer = std::make_shared(); - if (parse_raster_colorizer(colorizer, sym)) + if (parse_raster_colorizer(colorizer, node)) put(raster_sym, keys::colorizer, colorizer); } - parse_symbolizer_base(raster_sym, sym); + parse_symbolizer_base(raster_sym, node); rule.append(std::move(raster_sym)); } catch (config_error const& ex) { - ex.append_context(sym); + ex.append_context(node); 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 { group_symbolizer symbol; group_symbolizer_properties_ptr prop = std::make_shared(); - set_symbolizer_property(symbol, keys::num_columns, sym); - set_symbolizer_property(symbol, keys::start_column, sym); - set_symbolizer_property(symbol, keys::repeat_key, sym); + set_symbolizer_property(symbol, keys::num_columns, node); + set_symbolizer_property(symbol, keys::start_column, node); + set_symbolizer_property(symbol, keys::repeat_key, node); text_placements_ptr placements = std::make_shared(); - placements->defaults.placement_properties_from_xml(sym); + placements->defaults.placement_properties_from_xml(node); put(symbol, keys::text_placements_, placements); 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); - node.set_processed(true); + parse_group_rule(*prop, child_node); + child_node.set_processed(true); } - else if (node.is("SimpleLayout")) + else if (child_node.is("SimpleLayout")) { - parse_simple_layout(*prop, node); - node.set_processed(true); + parse_simple_layout(*prop, child_node); + child_node.set_processed(true); ++layout_count; } - else if (node.is("PairLayout")) + else if (child_node.is("PairLayout")) { - parse_pair_layout(*prop, node); - node.set_processed(true); + parse_pair_layout(*prop, child_node); + child_node.set_processed(true); ++layout_count; } 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); - parse_symbolizer_base(symbol, sym); + parse_symbolizer_base(symbol, node); rule.append(symbol); } catch (const config_error & ex) { - ex.append_context(sym); + ex.append_context(node); 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; - parse_symbolizer_base(symbol, sym); - optional mode = sym.get_opt_attr("mode"); + parse_symbolizer_base(symbol, node); + optional mode = node.get_opt_attr("mode"); if (mode) put(symbol, keys::mode, debug_symbolizer_mode_enum(*mode)); rule.append(std::move(symbol)); } diff --git a/src/symbolizer_keys.cpp b/src/symbolizer_keys.cpp index 022a74f15..0eff55b62 100644 --- a/src/symbolizer_keys.cpp +++ b/src/symbolizer_keys.cpp @@ -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{ "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{ "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) diff --git a/src/text/renderer.cpp b/src/text/renderer.cpp index 996cbd3a6..8a1ef2365 100644 --- a/src/text/renderer.cpp +++ b/src/text/renderer.cpp @@ -31,9 +31,10 @@ 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), comp_op_(comp_op), + halo_comp_op_(halo_comp_op), scale_factor_(scale_factor), glyphs_(), stroker_(stroker), @@ -109,9 +110,10 @@ template agg_text_renderer::agg_text_renderer (pixmap_type & pixmap, halo_rasterizer_e rasterizer, composite_mode_e comp_op, + composite_mode_e halo_comp_op, double scale_factor, 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 @@ -177,7 +179,7 @@ void agg_text_renderer::render(glyph_positions const& pos) bit->left, height - bit->top, format->halo_opacity, - comp_op_); + halo_comp_op_); } } else @@ -192,7 +194,7 @@ void agg_text_renderer::render(glyph_positions const& pos) height - bit->top, halo_radius, format->halo_opacity, - comp_op_); + halo_comp_op_); } } } @@ -342,12 +344,11 @@ void grid_text_renderer::render_halo_id( template grid_text_renderer::grid_text_renderer(pixmap_type &pixmap, composite_mode_e comp_op, - double scale_factor) : - text_renderer(HALO_RASTERIZER_FAST, comp_op, scale_factor), pixmap_(pixmap) -{ -} - + double scale_factor) + : text_renderer(HALO_RASTERIZER_FAST, comp_op, src_over, scale_factor), + pixmap_(pixmap) {} template class agg_text_renderer; template class grid_text_renderer; -} + +} // namespace mapnik