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,
largest_box_only,
minimum_path_length,
halo_comp_op,
MAX_SYMBOLIZER_KEY
};

View file

@ -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_;

View file

@ -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(

View file

@ -46,11 +46,13 @@ 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);
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_,
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<double>(sym,keys::opacity, feature, common_.vars_, 1.0);

View file

@ -46,11 +46,13 @@ 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);
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_,
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<transform_type>(sym, keys::halo_transform);

View file

@ -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<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
{
optional<std::string> file = sym.get_opt_attr<std::string>("file");
optional<std::string> base = sym.get_opt_attr<std::string>("base");
optional<std::string> image_transform_wkt = sym.get_opt_attr<std::string>("transform");
optional<std::string> file = node.get_opt_attr<std::string>("file");
optional<std::string> base = node.get_opt_attr<std::string>("base");
optional<std::string> image_transform_wkt = node.get_opt_attr<std::string>("transform");
point_symbolizer symbol;
set_symbolizer_property<point_symbolizer,boolean>(symbol, keys::allow_overlap, sym);
set_symbolizer_property<point_symbolizer,double>(symbol, keys::opacity, sym);
set_symbolizer_property<point_symbolizer,boolean>(symbol, keys::ignore_placement, sym);
set_symbolizer_property<point_symbolizer,boolean>(symbol, keys::allow_overlap, node);
set_symbolizer_property<point_symbolizer,double>(symbol, keys::opacity, node);
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 (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<std::string> file = sym.get_opt_attr<std::string>("file");
optional<std::string> base = sym.get_opt_attr<std::string>("base");
optional<std::string> file = node.get_opt_attr<std::string>("file");
optional<std::string> base = node.get_opt_attr<std::string>("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<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)
{
// 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<markers_symbolizer,double>(symbol, keys::opacity, sym);
set_symbolizer_property<markers_symbolizer,double>(symbol, keys::opacity, node);
// 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)
{
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);
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);
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 );
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);
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));
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));
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<std::string>("file");
std::string file = node.get_attr<std::string>("file");
if (file.empty())
{
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)
{
@ -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<double> offset = sym.get_opt_attr<double>("offset");
optional<double> offset = node.get_opt_attr<double>("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<std::string>("file");
std::string file = node.get_attr<std::string>("file");
if (file.empty())
{
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)
{
@ -1125,44 +1125,44 @@ void map_parser::parse_polygon_pattern_symbolizer(rule & rule,
put(symbol, keys::file, parse_path(file));
// 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));
// opacity
set_symbolizer_property<polygon_pattern_symbolizer,double>(symbol, keys::opacity, sym);
set_symbolizer_property<polygon_pattern_symbolizer,double>(symbol, keys::opacity, node);
// 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);
// 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));
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<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)
{
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<text_placements_dummy>();
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<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);
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_));
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)
{
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<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)
{
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<text_placements_dummy>();
}
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<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)
{
put(shield_symbol, keys::image_transform, mapnik::parse_transform(*image_transform_wkt));
}
// 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);
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);
// 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
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
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);
std::string file = sym.get_attr<std::string>("file");
std::string file = node.get_attr<std::string>("file");
if (file.empty())
{
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)
{
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
// 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)
{
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);
ensure_exists(file);
put(shield_symbol, keys::file , parse_path(file));
parse_symbolizer_base(shield_symbol, sym);
optional<halo_rasterizer_e> halo_rasterizer_ = sym.get_opt_attr<halo_rasterizer_e>("halo-rasterizer");
parse_symbolizer_base(shield_symbol, node);
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_));
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<symbolizer_base,color>(symbol, keys::stroke, sym);
set_symbolizer_property<symbolizer_base,color>(symbol, keys::stroke, node);
// 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
set_symbolizer_property<symbolizer_base,double>(symbol, keys::stroke_opacity, sym);
set_symbolizer_property<symbolizer_base,double>(symbol, keys::stroke_opacity, node);
// 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));
// 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));
// 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);
// 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));
// 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);
// 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)
{
std::vector<double> buf;
@ -1346,7 +1361,7 @@ void map_parser::parse_stroke(symbolizer_base & symbol, xml_node const & sym)
}
// 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);
}
@ -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_symbolizer,color>(building_sym, keys::fill, sym);
set_symbolizer_property<building_symbolizer,color>(building_sym, keys::fill, node);
// 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
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);
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<std::string> mode = sym.get_opt_attr<std::string>("mode");
optional<std::string> mode = node.get_opt_attr<std::string>("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<std::string> scaling = sym.get_opt_attr<std::string>("scaling");
optional<std::string> scaling = node.get_opt_attr<std::string>("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<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);
// 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);
// 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);
// 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);
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<raster_colorizer>();
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<group_symbolizer_properties>();
set_symbolizer_property<symbolizer_base, value_integer>(symbol, keys::num_columns, sym);
set_symbolizer_property<symbolizer_base, value_integer>(symbol, keys::start_column, sym);
set_symbolizer_property<symbolizer_base, expression_ptr>(symbol, keys::repeat_key, sym);
set_symbolizer_property<symbolizer_base, value_integer>(symbol, keys::num_columns, node);
set_symbolizer_property<symbolizer_base, value_integer>(symbol, keys::start_column, node);
set_symbolizer_property<symbolizer_base, expression_ptr>(symbol, keys::repeat_key, node);
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);
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<debug_symbolizer_mode_e> mode = sym.get_opt_attr<debug_symbolizer_mode_e>("mode");
parse_symbolizer_base(symbol, node);
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));
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{ "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)

View file

@ -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 <typename T>
agg_text_renderer<T>::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 <typename T>
@ -177,7 +179,7 @@ void agg_text_renderer<T>::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<T>::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<T>::render_halo_id(
template <typename T>
grid_text_renderer<T>::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<image_32>;
template class grid_text_renderer<grid>;
}
} // namespace mapnik