void agg_renderer<T0,T1>::process(line_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { color const& col = get<color, keys::stroke>(sym, feature, common_.vars_); unsigned r=col.red(); unsigned g=col.green(); unsigned b=col.blue(); unsigned a=col.alpha(); double gamma = get<value_double, keys::stroke_gamma>(sym, feature, common_.vars_); gamma_method_enum gamma_method = get<gamma_method_enum, keys::stroke_gamma_method>(sym, feature, common_.vars_); ras_ptr->reset(); if (gamma != gamma_ || gamma_method != gamma_method_) { set_gamma_method(ras_ptr, gamma, gamma_method); gamma_method_ = gamma_method; gamma_ = gamma; } agg::rendering_buffer buf(current_buffer_->getBytes(),current_buffer_->width(),current_buffer_->height(), current_buffer_->getRowSize()); using color_type = agg::rgba8; using order_type = agg::order_rgba; using blender_type = agg::comp_op_adaptor_rgba_pre<color_type, order_type>; // comp blender using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer>; using renderer_base = agg::renderer_base<pixfmt_comp_type>; pixfmt_comp_type pixf(buf); pixf.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e, keys::comp_op>(sym, feature, common_.vars_))); renderer_base renb(pixf); agg::trans_affine tr; auto transform = get_optional<transform_type>(sym, keys::geometry_transform); if (transform) evaluate_transform(tr, feature, common_.vars_, *transform, common_.scale_factor_); box2d<double> clip_box = clipping_extent(common_); value_bool clip = get<value_bool, keys::clip>(sym, feature, common_.vars_); value_double width = get<value_double, keys::stroke_width>(sym, feature, common_.vars_); value_double opacity = get<value_double,keys::stroke_opacity>(sym,feature, common_.vars_); value_double offset = get<value_double, keys::offset>(sym, feature, common_.vars_); value_double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym, feature, common_.vars_); value_double smooth = get<value_double, keys::smooth>(sym, feature, common_.vars_); line_rasterizer_enum rasterizer_e = get<line_rasterizer_enum, keys::line_rasterizer>(sym, feature, common_.vars_); if (clip) { double padding = static_cast<double>(common_.query_extent_.width()/pixmap_.width()); double half_stroke = 0.5 * width; if (half_stroke > 1) { padding *= half_stroke; } if (std::fabs(offset) > 0) { padding *= std::fabs(offset) * 1.2; } padding *= common_.scale_factor_; clip_box.pad(padding); // debugging //box2d<double> inverse = query_extent_; //inverse.pad(-padding); //draw_geo_extent(inverse,mapnik::color("red")); } if (rasterizer_e == RASTERIZER_FAST) { using renderer_type = agg::renderer_outline_aa<renderer_base>; using rasterizer_type = agg::rasterizer_outline_aa<renderer_type>; agg::line_profile_aa profile(width * common_.scale_factor_, agg::gamma_power(gamma)); renderer_type ren(renb, profile); ren.color(agg::rgba8_pre(r, g, b, int(a * opacity))); rasterizer_type ras(ren); set_join_caps_aa(sym, ras, feature, common_.vars_); vertex_converter<rasterizer_type,clip_line_tag, transform_tag, affine_transform_tag, simplify_tag, smooth_tag, offset_transform_tag, dash_tag, stroke_tag> converter(clip_box,ras,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_); if (clip) converter.set<clip_line_tag>(); // optional clip (default: true) converter.set<transform_tag>(); // always transform if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset converter.set<affine_transform_tag>(); // optional affine transform if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter for (geometry_type const& geom : feature.paths()) { if (geom.size() > 1) { vertex_adapter va(geom); converter.apply(va); } } } else { vertex_converter<rasterizer,clip_line_tag, transform_tag, affine_transform_tag, simplify_tag, smooth_tag, offset_transform_tag, dash_tag, stroke_tag> converter(clip_box,*ras_ptr,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_); if (clip) converter.set<clip_line_tag>(); // optional clip (default: true) converter.set<transform_tag>(); // always transform if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset converter.set<affine_transform_tag>(); // optional affine transform if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter if (has_key(sym, keys::stroke_dasharray)) converter.set<dash_tag>(); converter.set<stroke_tag>(); //always stroke for (geometry_type const& geom : feature.paths()) { if (geom.size() > 1) { vertex_adapter va(geom); converter.apply(va); } } using renderer_type = agg::renderer_scanline_aa_solid<renderer_base>; renderer_type ren(renb); ren.color(agg::rgba8_pre(r, g, b, int(a * opacity))); agg::scanline_u8 sl; ras_ptr->filling_rule(agg::fill_non_zero); agg::render_scanlines(*ras_ptr, sl, ren); } }
void agg_renderer<T>::process(line_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { stroke const& stroke_ = sym.get_stroke(); color const& col = stroke_.get_color(); unsigned r=col.red(); unsigned g=col.green(); unsigned b=col.blue(); unsigned a=col.alpha(); ras_ptr->reset(); if (stroke_.get_gamma() != gamma_ || stroke_.get_gamma_method() != gamma_method_) { set_gamma_method(stroke_, ras_ptr); gamma_method_ = stroke_.get_gamma_method(); gamma_ = stroke_.get_gamma(); } agg::rendering_buffer buf(current_buffer_->raw_data(),current_buffer_->width(),current_buffer_->height(), current_buffer_->width() * 4); typedef agg::rgba8 color_type; typedef agg::order_rgba order_type; typedef agg::comp_op_adaptor_rgba_pre<color_type, order_type> blender_type; // comp blender typedef agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer> pixfmt_comp_type; typedef agg::renderer_base<pixfmt_comp_type> renderer_base; typedef boost::mpl::vector<clip_line_tag, transform_tag, offset_transform_tag, affine_transform_tag, simplify_tag, smooth_tag, dash_tag, stroke_tag> conv_types; pixfmt_comp_type pixf(buf); pixf.comp_op(static_cast<agg::comp_op_e>(sym.comp_op())); renderer_base renb(pixf); agg::trans_affine tr; evaluate_transform(tr, feature, sym.get_transform(), scale_factor_); box2d<double> clip_box = clipping_extent(); if (sym.clip()) { double padding = (double)(query_extent_.width()/pixmap_.width()); double half_stroke = stroke_.get_width()/2.0; if (half_stroke > 1) padding *= half_stroke; if (std::fabs(sym.offset()) > 0) padding *= std::fabs(sym.offset()) * 1.2; padding *= scale_factor_; clip_box.pad(padding); // debugging //box2d<double> inverse = query_extent_; //inverse.pad(-padding); //draw_geo_extent(inverse,mapnik::color("red")); } if (sym.get_rasterizer() == RASTERIZER_FAST) { typedef agg::renderer_outline_aa<renderer_base> renderer_type; typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type; agg::line_profile_aa profile(stroke_.get_width() * scale_factor_, agg::gamma_power(stroke_.get_gamma())); renderer_type ren(renb, profile); ren.color(agg::rgba8_pre(r, g, b, int(a*stroke_.get_opacity()))); rasterizer_type ras(ren); set_join_caps_aa(stroke_,ras); vertex_converter<box2d<double>, rasterizer_type, line_symbolizer, CoordTransform, proj_transform, agg::trans_affine, conv_types> converter(clip_box,ras,sym,t_,prj_trans,tr,scale_factor_); if (sym.clip()) converter.set<clip_line_tag>(); // optional clip (default: true) converter.set<transform_tag>(); // always transform if (std::fabs(sym.offset()) > 0.0) converter.set<offset_transform_tag>(); // parallel offset converter.set<affine_transform_tag>(); // optional affine transform if (sym.simplify_tolerance() > 0.0) converter.set<simplify_tag>(); // optional simplify converter if (sym.smooth() > 0.0) converter.set<smooth_tag>(); // optional smooth converter for (geometry_type & geom : feature.paths()) { if (geom.size() > 1) { converter.apply(geom); } } } else { vertex_converter<box2d<double>, rasterizer, line_symbolizer, CoordTransform, proj_transform, agg::trans_affine, conv_types> converter(clip_box,*ras_ptr,sym,t_,prj_trans,tr,scale_factor_); if (sym.clip()) converter.set<clip_line_tag>(); // optional clip (default: true) converter.set<transform_tag>(); // always transform if (std::fabs(sym.offset()) > 0.0) converter.set<offset_transform_tag>(); // parallel offset converter.set<affine_transform_tag>(); // optional affine transform if (sym.simplify_tolerance() > 0.0) converter.set<simplify_tag>(); // optional simplify converter if (sym.smooth() > 0.0) converter.set<smooth_tag>(); // optional smooth converter if (stroke_.has_dash()) converter.set<dash_tag>(); converter.set<stroke_tag>(); //always stroke for (geometry_type & geom : feature.paths()) { if (geom.size() > 1) { converter.apply(geom); } } typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_type; renderer_type ren(renb); ren.color(agg::rgba8_pre(r, g, b, int(a * stroke_.get_opacity()))); agg::scanline_u8 sl; ras_ptr->filling_rule(agg::fill_non_zero); agg::render_scanlines(*ras_ptr, sl, ren); } }