void agg_renderer<T0,T1>::process(dot_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { double width = 0.0; double height = 0.0; bool has_width = has_key(sym,keys::width); bool has_height = has_key(sym,keys::height); if (has_width && has_height) { width = get<double>(sym, keys::width, feature, common_.vars_, 0.0); height = get<double>(sym, keys::height, feature, common_.vars_, 0.0); } else if (has_width) { width = height = get<double>(sym, keys::width, feature, common_.vars_, 0.0); } else if (has_height) { width = height = get<double>(sym, keys::height, feature, common_.vars_, 0.0); } double rx = width/2.0; double ry = height/2.0; double opacity = get<double>(sym, keys::opacity, feature, common_.vars_, 1.0); color const& fill = get<mapnik::color>(sym, keys::fill, feature, common_.vars_, mapnik::color(128,128,128)); ras_ptr->reset(); agg::rendering_buffer buf(current_buffer_->raw_data(),current_buffer_->width(),current_buffer_->height(),current_buffer_->width() * 4); using blender_type = agg::comp_op_adaptor_rgba_pre<agg::rgba8, agg::order_rgba>; using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer>; using renderer_base = agg::renderer_base<pixfmt_comp_type>; using renderer_type = agg::renderer_scanline_aa_solid<renderer_base>; pixfmt_comp_type pixf(buf); pixf.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over))); renderer_base renb(pixf); renderer_type ren(renb); agg::scanline_u8 sl; ren.color(agg::rgba8_pre(fill.red(), fill.green(), fill.blue(), int(fill.alpha() * opacity))); agg::ellipse el(0,0,rx,ry); unsigned num_steps = el.num_steps(); for (geometry_type const& geom : feature.paths()) { double x,y,z = 0; unsigned cmd = 1; geom.rewind(0); while ((cmd = geom.vertex(&x, &y)) != mapnik::SEG_END) { if (cmd == SEG_CLOSE) continue; prj_trans.backward(x,y,z); common_.t_.forward(&x,&y); el.init(x,y,rx,ry,num_steps); ras_ptr->add_path(el); agg::render_scanlines(*ras_ptr, sl, ren); } } }
void grid_renderer<T>::process(building_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { using pixfmt_type = typename grid_renderer_base_type::pixfmt_type; using color_type = typename grid_renderer_base_type::pixfmt_type::color_type; using renderer_type = agg::renderer_scanline_bin_solid<grid_renderer_base_type>; using transform_path_type = transform_path_adapter<view_transform, vertex_adapter>; agg::scanline_bin sl; grid_rendering_buffer buf(pixmap_.raw_data(), common_.width_, common_.height_, common_.width_); pixfmt_type pixf(buf); grid_renderer_base_type renb(pixf); renderer_type ren(renb); ras_ptr->reset(); double height = get<value_double>(sym, keys::height, feature, common_.vars_, 0.0); render_building_symbolizer( feature, height, [&](path_type const& faces) { vertex_adapter va(faces); transform_path_type faces_path (common_.t_,va,prj_trans); ras_ptr->add_path(faces_path); ren.color(color_type(feature.id())); agg::render_scanlines(*ras_ptr, sl, ren); ras_ptr->reset(); }, [&](path_type const& frame) { vertex_adapter va(frame); transform_path_type path(common_.t_,va,prj_trans); agg::conv_stroke<transform_path_type> stroke(path); ras_ptr->add_path(stroke); ren.color(color_type(feature.id())); agg::render_scanlines(*ras_ptr, sl, ren); ras_ptr->reset(); }, [&](path_type const& roof) { vertex_adapter va(roof); transform_path_type roof_path (common_.t_,va,prj_trans); ras_ptr->add_path(roof_path); ren.color(color_type(feature.id())); agg::render_scanlines(*ras_ptr, sl, ren); }); pixmap_.add_feature(feature); }
virtual void operator()(raster_marker_render_thunk const& thunk) { using buf_type = grid_rendering_buffer; using pixfmt_type = typename grid_renderer_base_type::pixfmt_type; using renderer_type = agg::renderer_scanline_bin_solid<grid_renderer_base_type>; buf_type render_buf(pixmap_.raw_data(), common_.width_, common_.height_, common_.width_); ras_.reset(); pixfmt_type pixf(render_buf); grid_renderer_base_type renb(pixf); renderer_type ren(renb); agg::trans_affine offset_tr = thunk.tr_; offset_tr.translate(offset_.x, offset_.y); render_raster_marker(ren, ras_, thunk.src_, feature_, offset_tr, thunk.opacity_); pixmap_.add_feature(feature_); }
void grid_renderer<T>::process(polygon_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { typedef agg::renderer_scanline_bin_solid<grid_renderer_base_type> renderer_type; typedef typename grid_renderer_base_type::pixfmt_type pixfmt_type; typedef typename grid_renderer_base_type::pixfmt_type::color_type color_type; ras_ptr->reset(); agg::trans_affine tr; evaluate_transform(tr, feature, sym.get_transform(), scale_factor_); typedef boost::mpl::vector<clip_poly_tag,transform_tag,affine_transform_tag,simplify_tag,smooth_tag> conv_types; vertex_converter<box2d<double>, grid_rasterizer, polygon_symbolizer, CoordTransform, proj_transform, agg::trans_affine, conv_types> converter(query_extent_,*ras_ptr,sym,t_,prj_trans,tr,scale_factor_); if (prj_trans.equal() && sym.clip()) converter.set<clip_poly_tag>(); //optional clip (default: true) converter.set<transform_tag>(); //always transform converter.set<affine_transform_tag>(); 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() > 2) { converter.apply(geom); } } grid_rendering_buffer buf(pixmap_.raw_data(), width_, height_, width_); pixfmt_type pixf(buf); grid_renderer_base_type renb(pixf); renderer_type ren(renb); // render id ren.color(color_type(feature.id())); agg::scanline_bin sl; ras_ptr->filling_rule(agg::fill_even_odd); agg::render_scanlines(*ras_ptr, sl, ren); // add feature properties to grid cache pixmap_.add_feature(feature); }
void agg_renderer<T0,T1>::process(polygon_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { using conv_types = boost::mpl::vector<clip_poly_tag,transform_tag,affine_transform_tag,simplify_tag,smooth_tag>; using vertex_converter_type = vertex_converter<box2d<double>, rasterizer, polygon_symbolizer, CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl>; ras_ptr->reset(); double gamma = get<value_double>(sym, keys::gamma, feature, common_.vars_, 1.0); gamma_method_enum gamma_method = get<gamma_method_enum>(sym, keys::gamma_method, feature, common_.vars_, GAMMA_POWER); if (gamma != gamma_ || gamma_method != gamma_method_) { set_gamma_method(ras_ptr, gamma, gamma_method); gamma_method_ = gamma_method; gamma_ = gamma; } box2d<double> clip_box = clipping_extent(); agg::rendering_buffer buf(current_buffer_->raw_data(),current_buffer_->width(),current_buffer_->height(), current_buffer_->width() * 4); render_polygon_symbolizer<vertex_converter_type>( sym, feature, prj_trans, common_, clip_box, *ras_ptr, [&](color const &fill, double opacity) { unsigned r=fill.red(); unsigned g=fill.green(); unsigned b=fill.blue(); unsigned a=fill.alpha(); 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>; using renderer_type = agg::renderer_scanline_aa_solid<renderer_base>; pixfmt_comp_type pixf(buf); auto comp_op = get<agg::comp_op_e>(sym, keys::comp_op, feature, common_.vars_, agg::comp_op_src_over); pixf.comp_op(comp_op); renderer_base renb(pixf); 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_even_odd); agg::render_scanlines(*ras_ptr, sl, ren); }); }
virtual void operator()(raster_marker_render_thunk const& thunk) { using blender_type = agg::comp_op_adaptor_rgba_pre<agg::rgba8, agg::order_rgba>; // comp blender using buf_type = agg::rendering_buffer; using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba<blender_type, buf_type>; using renderer_base = agg::renderer_base<pixfmt_comp_type>; ras_ptr_->reset(); buf_type render_buffer(buf_->bytes(), buf_->width(), buf_->height(), buf_->row_size()); pixfmt_comp_type pixf(render_buffer); pixf.comp_op(static_cast<agg::comp_op_e>(thunk.comp_op_)); renderer_base renb(pixf); agg::trans_affine offset_tr = thunk.tr_; offset_tr.translate(offset_.x, offset_.y); render_raster_marker(renb, *ras_ptr_, thunk.src_, offset_tr, thunk.opacity_, common_.scale_factor_, thunk.snap_to_pixels_); }
void THLine::draw(THRenderTarget* pCanvas, int iX, int iY) { // Strangely drawing at 0,0 would draw outside of the screen // so we start at 1,0. This makes SDL behave like DirectX. SDL_Rect rcDest; rcDest.x = iX + 1; rcDest.y = iY; // Try to get a cached line surface if (m_pBitmap) { SDL_BlitSurface(m_pBitmap, NULL, pCanvas->getRawSurface(), &rcDest); return; } // No cache, let's build a new one SDL_FreeSurface(m_pBitmap); Uint32 amask; #if SDL_BYTEORDER == SDL_BIG_ENDIAN amask = 0x000000ff; #else amask = 0xff000000; #endif const SDL_PixelFormat& fmt = *(pCanvas->getRawSurface()->format); m_pBitmap = SDL_CreateRGBSurface(SDL_HWSURFACE | SDL_SRCALPHA, (int)ceil(m_fMaxX), (int)ceil(m_fMaxY), fmt.BitsPerPixel, fmt.Rmask, fmt.Gmask, fmt.Bmask, amask); agg::rendering_buffer rbuf(reinterpret_cast<agg::int8u*>(m_pBitmap->pixels), m_pBitmap->w, m_pBitmap->h, m_pBitmap->pitch); agg::pixfmt_rgba32 pixf(rbuf); agg::renderer_base<agg::pixfmt_rgba32> renb(pixf); agg::conv_stroke<agg::path_storage> stroke(*m_oPath); stroke.width(m_fWidth); agg::rasterizer_scanline_aa<> ras; ras.add_path(stroke); agg::scanline_p8 sl; agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba8(m_iB, m_iG, m_iR, m_iA)); SDL_BlitSurface(m_pBitmap, NULL, pCanvas->getRawSurface(), &rcDest); }
void grid_renderer<T>::process(line_pattern_symbolizer const& sym, mapnik::feature_ptr const& feature, proj_transform const& prj_trans) { typedef coord_transform2<CoordTransform,geometry_type> path_type; typedef agg::renderer_base<mapnik::pixfmt_gray16> ren_base; typedef agg::renderer_scanline_bin_solid<ren_base> renderer; agg::scanline_bin sl; grid_rendering_buffer buf(pixmap_.raw_data(), width_, height_, width_); mapnik::pixfmt_gray16 pixf(buf); ren_base renb(pixf); renderer ren(renb); ras_ptr->reset(); // TODO - actually handle image dimensions int stroke_width = 2; for (unsigned i=0;i<feature->num_geometries();++i) { geometry_type const& geom = feature->get_geometry(i); if (geom.num_points() > 1) { path_type path(t_,geom,prj_trans); agg::conv_stroke<path_type> stroke(path); stroke.generator().miter_limit(4.0); stroke.generator().width(stroke_width * scale_factor_); ras_ptr->add_path(stroke); } } // render id ren.color(mapnik::gray16(feature->id())); agg::render_scanlines(*ras_ptr, sl, ren); // add feature properties to grid cache pixmap_.add_feature(feature); }
void agg_renderer<T0,T1>::process(dot_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { double width = 0.0; double height = 0.0; bool has_width = has_key(sym,keys::width); bool has_height = has_key(sym,keys::height); if (has_width && has_height) { width = get<double>(sym, keys::width, feature, common_.vars_, 0.0); height = get<double>(sym, keys::height, feature, common_.vars_, 0.0); } else if (has_width) { width = height = get<double>(sym, keys::width, feature, common_.vars_, 0.0); } else if (has_height) { width = height = get<double>(sym, keys::height, feature, common_.vars_, 0.0); } double rx = width/2.0; double ry = height/2.0; double opacity = get<double>(sym, keys::opacity, feature, common_.vars_, 1.0); color const& fill = get<mapnik::color>(sym, keys::fill, feature, common_.vars_, mapnik::color(128,128,128)); ras_ptr->reset(); agg::rendering_buffer buf(current_buffer_->bytes(),current_buffer_->width(),current_buffer_->height(),current_buffer_->row_size()); using blender_type = agg::comp_op_adaptor_rgba_pre<agg::rgba8, agg::order_rgba>; using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer>; using renderer_base = agg::renderer_base<pixfmt_comp_type>; using renderer_type = agg::renderer_scanline_aa_solid<renderer_base>; pixfmt_comp_type pixf(buf); pixf.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over))); renderer_base renb(pixf); renderer_type ren(renb); ren.color(agg::rgba8_pre(fill.red(), fill.green(), fill.blue(), int(fill.alpha() * opacity))); using render_dot_symbolizer_type = detail::render_dot_symbolizer<rasterizer, renderer_type, renderer_common, proj_transform>; render_dot_symbolizer_type apply(rx, ry, *ras_ptr, ren, common_, prj_trans); mapnik::util::apply_visitor(geometry::vertex_processor<render_dot_symbolizer_type>(apply), feature.get_geometry()); }
bool render(const Tile& tile,const std::vector<RoadSegment>& segments,agg::rendering_buffer& rbuf) { typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base; typedef agg::renderer_outline_aa<ren_base> renderer_oaa; typedef agg::rasterizer_outline_aa<renderer_oaa> rasterizer_outline_aa; typedef agg::renderer_scanline_aa_solid<ren_base> renderer; agg::pixfmt_rgba32 pixf(rbuf); ren_base renb(pixf); renderer ren(renb); agg::rasterizer_scanline_aa<> ras; agg::scanline_p8 sl; unsigned i = 0; for (i=0; i < segments.size(); i++) { RoadSegment rseg = segments[i]; Segment seg = rseg.convertToSegment(tile); ren.color(seg.getColor()); agg::path_storage path; path.move_to(seg.getFromPoint().getX(), seg.getFromPoint().getY()); path.line_to(seg.getToPoint().getX(), seg.getToPoint().getY()); agg::conv_stroke<agg::path_storage> stroke(path); stroke.width(seg.getStrokeWidth()); agg::line_cap_e cap = agg::round_cap; agg::line_join_e join = agg::round_join; stroke.line_join(join); stroke.line_cap(cap); ras.reset(); ras.add_path(stroke); agg::render_scanlines(ras,sl,ren); } return true; }
void render(mapnik::image_rgba8 const& image) const { agg::rendering_buffer buf(current_buffer_.bytes(), current_buffer_.width(), current_buffer_.height(), current_buffer_.row_size()); ras_ptr_->reset(); value_double gamma = get<value_double, keys::gamma>(sym_, feature_, common_.vars_); gamma_method_enum gamma_method = get<gamma_method_enum, keys::gamma_method>(sym_, feature_, common_.vars_); if (gamma != gamma_ || gamma_method != gamma_method_) { set_gamma_method(ras_ptr_, gamma, gamma_method); gamma_method_ = gamma_method; gamma_ = gamma; } using vertex_converter_type = vertex_converter<clip_poly_tag, transform_tag, affine_transform_tag, simplify_tag, smooth_tag>; using pattern_type = agg_polygon_pattern<vertex_converter_type>; pattern_type pattern(image, common_, sym_, feature_, prj_trans_); pattern_type::pixfmt_type pixf(buf); pixf.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e, keys::comp_op>(sym_, feature_, common_.vars_))); pattern_type::renderer_base renb(pixf); unsigned w = image.width(); unsigned h = image.height(); agg::rendering_buffer pattern_rbuf((agg::int8u*)image.bytes(),w,h,w*4); agg::pixfmt_rgba32_pre pixf_pattern(pattern_rbuf); pattern_type::img_source_type img_src(pixf_pattern); if (prj_trans_.equal() && pattern.clip_) pattern.converter_.set<clip_poly_tag>(); ras_ptr_->filling_rule(agg::fill_even_odd); pattern.render(renb, *ras_ptr_); }
virtual void on_draw() { typedef agg::renderer_base<agg::pixfmt_bgr24> ren_base; agg::pixfmt_bgr24 pixf(rbuf_window()); ren_base renb(pixf); renb.clear(agg::rgba(1, 1, 1)); agg::rasterizer_scanline_aa<> ras; agg::scanline_p8 sl; agg::trans_affine mtx; mtx *= agg::trans_affine_scaling(4.0); mtx *= agg::trans_affine_translation(150, 100); agg::conv_transform<agg::path_storage> trans(m_path, mtx); agg::conv_curve<agg::conv_transform<agg::path_storage> > curve(trans); agg::conv_contour <agg::conv_curve <agg::conv_transform <agg::path_storage> > > contour(curve); contour.width(m_width.value()); //contour.inner_join(agg::inner_bevel); //contour.line_join(agg::miter_join); //contour.inner_line_join(agg::miter_join); //contour.inner_miter_limit(4.0); contour.auto_detect_orientation(m_auto_detect.status()); compose_path(); ras.add_path(contour); agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba(0,0,0)); agg::render_ctrl(ras, sl, renb, m_close); agg::render_ctrl(ras, sl, renb, m_width); agg::render_ctrl(ras, sl, renb, m_auto_detect); }
virtual void operator()(vector_marker_render_thunk const& thunk) { using buf_type = grid_rendering_buffer; using pixfmt_type = typename grid_renderer_base_type::pixfmt_type; using renderer_type = agg::renderer_scanline_bin_solid<grid_renderer_base_type>; using svg_renderer_type = svg::renderer_agg<svg_path_adapter, svg_attribute_type, renderer_type, pixfmt_type>; buf_type render_buf(pixmap_.raw_data(), common_.width_, common_.height_, common_.width_); ras_.reset(); pixfmt_type pixf(render_buf); grid_renderer_base_type renb(pixf); renderer_type ren(renb); svg::vertex_stl_adapter<svg::svg_path_storage> stl_storage(thunk.src_->source()); svg_path_adapter svg_path(stl_storage); svg_renderer_type svg_renderer(svg_path, thunk.attrs_); agg::trans_affine offset_tr = thunk.tr_; offset_tr.translate(offset_.x, offset_.y); agg::scanline_bin sl; svg_renderer.render_id(ras_, sl, renb, feature_.id(), offset_tr, thunk.opacity_, thunk.src_->bounding_box()); pixmap_.add_feature(feature_); }
void grid_renderer<T>::process(polygon_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { using renderer_type = agg::renderer_scanline_bin_solid<grid_renderer_base_type>; using pixfmt_type = typename grid_renderer_base_type::pixfmt_type; using color_type = typename grid_renderer_base_type::pixfmt_type::color_type; using vertex_converter_type = vertex_converter<transform2_tag, clip_poly_tag, transform_tag, affine_transform_tag, simplify_tag, smooth_tag, contour_tag>; ras_ptr->reset(); grid_rendering_buffer buf(pixmap_.raw_data(), common_.width_, common_.height_, common_.width_); render_polygon_symbolizer<vertex_converter_type>( sym, feature, prj_trans, common_, common_.query_extent_, *ras_ptr, [&](color const &, double) { pixfmt_type pixf(buf); grid_renderer_base_type renb(pixf); renderer_type ren(renb); // render id ren.color(color_type(feature.id())); agg::scanline_bin sl; ras_ptr->filling_rule(agg::fill_non_zero); agg::render_scanlines(*ras_ptr, sl, ren); // add feature properties to grid cache pixmap_.add_feature(feature); }); }
void agg_renderer<T>::process(polygon_pattern_symbolizer const& sym, mapnik::feature_ptr const& feature, proj_transform const& prj_trans) { typedef agg::conv_clip_polygon<geometry_type> clipped_geometry_type; typedef coord_transform2<CoordTransform,clipped_geometry_type> path_type; typedef agg::renderer_base<agg::pixfmt_rgba32_plain> ren_base; typedef agg::wrap_mode_repeat wrap_x_type; typedef agg::wrap_mode_repeat wrap_y_type; typedef agg::pixfmt_alpha_blend_rgba<agg::blender_rgba32_plain, agg::row_accessor<agg::int8u>, agg::pixel32_type> rendering_buffer; typedef agg::image_accessor_wrap<rendering_buffer, wrap_x_type, wrap_y_type> img_source_type; typedef agg::span_pattern_rgba<img_source_type> span_gen_type; typedef agg::renderer_scanline_aa<ren_base, agg::span_allocator<agg::rgba8>, span_gen_type> renderer_type; agg::rendering_buffer buf(pixmap_.raw_data(),width_,height_, width_ * 4); agg::pixfmt_rgba32_plain pixf(buf); ren_base renb(pixf); agg::scanline_u8 sl; ras_ptr->reset(); set_gamma_method(sym,ras_ptr); std::string filename = path_processor_type::evaluate( *sym.get_filename(), *feature); boost::optional<mapnik::marker_ptr> marker; if ( !filename.empty() ) { marker = marker_cache::instance()->find(filename, true); } else { std::clog << "### Warning: file not found: " << filename << "\n"; } if (!marker) return; if (!(*marker)->is_bitmap()) { std::clog << "### Warning only images (not '" << filename << "') are supported in the polygon_pattern_symbolizer\n"; return; } boost::optional<image_ptr> pat = (*marker)->get_bitmap_data(); if (!pat) return; unsigned w=(*pat)->width(); unsigned h=(*pat)->height(); agg::row_accessor<agg::int8u> pattern_rbuf((agg::int8u*)(*pat)->getBytes(),w,h,w*4); agg::span_allocator<agg::rgba8> sa; agg::pixfmt_alpha_blend_rgba<agg::blender_rgba32_plain, agg::row_accessor<agg::int8u>, agg::pixel32_type> pixf_pattern(pattern_rbuf); img_source_type img_src(pixf_pattern); unsigned num_geometries = feature->num_geometries(); pattern_alignment_e align = sym.get_alignment(); unsigned offset_x=0; unsigned offset_y=0; if (align == LOCAL_ALIGNMENT) { double x0=0,y0=0; if (num_geometries>0) // FIXME: hmm...? { clipped_geometry_type clipped(feature->get_geometry(0)); clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy()); path_type path(t_,clipped,prj_trans); path.vertex(&x0,&y0); } offset_x = unsigned(width_-x0); offset_y = unsigned(height_-y0); } span_gen_type sg(img_src, offset_x, offset_y); renderer_type rp(renb,sa, sg); //metawriter_with_properties writer = sym.get_metawriter(); for (unsigned i=0;i<num_geometries;++i) { geometry_type & geom = feature->get_geometry(i); if (geom.num_points() > 2) { clipped_geometry_type clipped(geom); clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy()); path_type path(t_,clipped,prj_trans); ras_ptr->add_path(path); //if (writer.first) writer.first->add_polygon(path, *feature, t_, writer.second); } } agg::render_scanlines(*ras_ptr, sl, rp); }
void agg_renderer<T0,T1>::process(polygon_pattern_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { std::string filename = get<std::string, keys::file>(sym, feature, common_.vars_); if (filename.empty()) return; std::shared_ptr<mapnik::marker const> marker = marker_cache::instance().find(filename, true); buffer_type & current_buffer = buffers_.top().get(); agg::rendering_buffer buf(current_buffer.bytes(), current_buffer.width(), current_buffer.height(), current_buffer.row_size()); ras_ptr->reset(); value_double gamma = get<value_double, keys::gamma>(sym, feature, common_.vars_); gamma_method_enum gamma_method = get<gamma_method_enum, keys::gamma_method>(sym, feature, common_.vars_); if (gamma != gamma_ || gamma_method != gamma_method_) { set_gamma_method(ras_ptr, gamma, gamma_method); gamma_method_ = gamma_method; gamma_ = gamma; } value_bool clip = get<value_bool, keys::clip>(sym, feature, common_.vars_); value_double opacity = get<double, keys::opacity>(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_); using color = agg::rgba8; using order = agg::order_rgba; using blender_type = agg::comp_op_adaptor_rgba_pre<color, order>; using pixfmt_type = agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer>; using wrap_x_type = agg::wrap_mode_repeat; using wrap_y_type = agg::wrap_mode_repeat; using img_source_type = agg::image_accessor_wrap<agg::pixfmt_rgba32_pre, wrap_x_type, wrap_y_type>; using span_gen_type = agg::span_pattern_rgba<img_source_type>; using ren_base = agg::renderer_base<pixfmt_type>; using renderer_type = agg::renderer_scanline_aa_alpha<ren_base, agg::span_allocator<agg::rgba8>, span_gen_type>; pixfmt_type pixf(buf); pixf.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e, keys::comp_op>(sym, feature, common_.vars_))); ren_base renb(pixf); common_pattern_process_visitor<polygon_pattern_symbolizer, rasterizer> visitor(*ras_ptr, common_, sym, feature); image_rgba8 image(util::apply_visitor(visitor, *marker)); unsigned w = image.width(); unsigned h = image.height(); agg::rendering_buffer pattern_rbuf((agg::int8u*)image.bytes(),w,h,w*4); agg::pixfmt_rgba32_pre pixf_pattern(pattern_rbuf); img_source_type img_src(pixf_pattern); box2d<double> clip_box = clipping_extent(common_); coord<unsigned, 2> offset(detail::offset(sym, feature, prj_trans, common_, clip_box)); span_gen_type sg(img_src, offset.x, offset.y); agg::span_allocator<agg::rgba8> sa; renderer_type rp(renb,sa, sg, unsigned(opacity * 255)); 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_); using vertex_converter_type = vertex_converter<clip_poly_tag, transform_tag, affine_transform_tag, simplify_tag, smooth_tag>; vertex_converter_type converter(clip_box, sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_); if (prj_trans.equal() && clip) converter.set<clip_poly_tag>(); converter.set<transform_tag>(); //always transform 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 using apply_vertex_converter_type = detail::apply_vertex_converter<vertex_converter_type, rasterizer>; using vertex_processor_type = geometry::vertex_processor<apply_vertex_converter_type>; apply_vertex_converter_type apply(converter, *ras_ptr); mapnik::util::apply_visitor(vertex_processor_type(apply),feature.get_geometry()); agg::scanline_u8 sl; ras_ptr->filling_rule(agg::fill_even_odd); agg::render_scanlines(*ras_ptr, sl, rp); }
int main (int argc,char** argv) { namespace po = boost::program_options; bool verbose = false; bool auto_open = false; int return_value = 0; std::vector<std::string> svg_files; mapnik::logger::instance().set_severity(mapnik::logger::error); try { po::options_description desc("svg2png utility"); desc.add_options() ("help,h", "produce usage message") ("version,V","print version string") ("verbose,v","verbose output") ("open","automatically open the file after rendering (os x only)") ("svg",po::value<std::vector<std::string> >(),"svg file to read") ; po::positional_options_description p; p.add("svg",-1); po::variables_map vm; po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm); po::notify(vm); if (vm.count("version")) { std::clog <<"version " << MAPNIK_VERSION_STRING << std::endl; return 1; } if (vm.count("help")) { std::clog << desc << std::endl; return 1; } if (vm.count("verbose")) { verbose = true; } if (vm.count("open")) { auto_open = true; } if (vm.count("svg")) { svg_files=vm["svg"].as< std::vector<std::string> >(); } else { std::clog << "please provide an svg file!" << std::endl; return -1; } std::vector<std::string>::const_iterator itr = svg_files.begin(); if (itr == svg_files.end()) { std::clog << "no svg files to render" << std::endl; return 0; } xmlInitParser(); while (itr != svg_files.end()) { std::string svg_name (*itr++); if (verbose) { std::clog << "found: " << svg_name << "\n"; } boost::optional<mapnik::marker_ptr> marker_ptr = mapnik::marker_cache::instance().find(svg_name, false); if (!marker_ptr) { std::clog << "svg2png error: could not open: '" << svg_name << "'\n"; return_value = -1; continue; } mapnik::marker marker = **marker_ptr; if (!marker.is_vector()) { std::clog << "svg2png error: '" << svg_name << "' is not a valid vector!\n"; return_value = -1; continue; } using pixfmt = agg::pixfmt_rgba32_pre; using renderer_base = agg::renderer_base<pixfmt>; using renderer_solid = agg::renderer_scanline_aa_solid<renderer_base>; agg::rasterizer_scanline_aa<> ras_ptr; agg::scanline_u8 sl; double opacity = 1; int w = marker.width(); int h = marker.height(); if (verbose) { std::clog << "found width of '" << w << "' and height of '" << h << "'\n"; } // 10 pixel buffer to avoid edge clipping of 100% svg's mapnik::image_32 im(w+0,h+0); agg::rendering_buffer buf(im.raw_data(), im.width(), im.height(), im.width() * 4); pixfmt pixf(buf); renderer_base renb(pixf); mapnik::box2d<double> const& bbox = (*marker.get_vector_data())->bounding_box(); mapnik::coord<double,2> c = bbox.center(); // center the svg marker on '0,0' agg::trans_affine mtx = agg::trans_affine_translation(-c.x,-c.y); // render the marker at the center of the marker box mtx.translate(0.5 * im.width(), 0.5 * im.height()); mapnik::svg::vertex_stl_adapter<mapnik::svg::svg_path_storage> stl_storage((*marker.get_vector_data())->source()); mapnik::svg::svg_path_adapter svg_path(stl_storage); mapnik::svg::svg_renderer_agg<mapnik::svg::svg_path_adapter, agg::pod_bvector<mapnik::svg::path_attributes>, renderer_solid, agg::pixfmt_rgba32_pre > svg_renderer_this(svg_path, (*marker.get_vector_data())->attributes()); svg_renderer_this.render(ras_ptr, sl, renb, mtx, opacity, bbox); boost::algorithm::ireplace_last(svg_name,".svg",".png"); im.demultiply(); mapnik::save_to_file<mapnik::image_data_rgba8>(im.data(),svg_name,"png"); if (auto_open) { std::ostringstream s; #ifdef DARWIN s << "open " << svg_name; #else s << "xdg-open " << svg_name; #endif int ret = system(s.str().c_str()); if (ret != 0) return_value = ret; } std::clog << "rendered to: " << svg_name << "\n"; } } catch (...) { std::clog << "Exception of unknown type!" << std::endl; xmlCleanupParser(); return -1; } // only call this once, on exit // to make sure valgrind output is clean // http://xmlsoft.org/xmlmem.html xmlCleanupParser(); return return_value; }
void grid_renderer<T>::process(line_pattern_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { std::string filename = get<std::string>(sym, keys::file, feature, common_.vars_); if (filename.empty()) return; boost::optional<mapnik::marker_ptr> mark = marker_cache::instance().find(filename, true); if (!mark) return; if (!(*mark)->is_bitmap()) { MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: Only images (not '" << filename << "') are supported in the line_pattern_symbolizer"; return; } boost::optional<image_ptr> pat = (*mark)->get_bitmap_data(); if (!pat) return; bool clip = get<value_bool>(sym, keys::clip, feature, common_.vars_, true); double offset = get<value_double>(sym, keys::offset, feature, common_.vars_, 0.0); double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, common_.vars_, 0.0); double smooth = get<value_double>(sym, keys::smooth, feature, common_.vars_, false); typedef typename grid_renderer_base_type::pixfmt_type pixfmt_type; typedef typename grid_renderer_base_type::pixfmt_type::color_type color_type; typedef agg::renderer_scanline_bin_solid<grid_renderer_base_type> renderer_type; typedef boost::mpl::vector<clip_line_tag, transform_tag, offset_transform_tag, affine_transform_tag, simplify_tag, smooth_tag, stroke_tag> conv_types; agg::scanline_bin sl; grid_rendering_buffer buf(pixmap_.raw_data(), common_.width_, common_.height_, common_.width_); pixfmt_type pixf(buf); grid_renderer_base_type renb(pixf); renderer_type ren(renb); ras_ptr->reset(); int stroke_width = (*pat)->width(); 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> clipping_extent = common_.query_extent_; if (clip) { double padding = (double)(common_.query_extent_.width()/pixmap_.width()); double half_stroke = stroke_width/2.0; if (half_stroke > 1) padding *= half_stroke; if (std::fabs(offset) > 0) padding *= std::fabs(offset) * 1.2; padding *= common_.scale_factor_; clipping_extent.pad(padding); } // to avoid the complexity of using an agg pattern filter instead // we create a line_symbolizer in order to fake the pattern line_symbolizer line; put<value_double>(line, keys::stroke_width, value_double(stroke_width)); // TODO: really should pass the offset to the fake line too, but // this wasn't present in the previous version and makes the test // fail - in this case, probably the test should be updated. //put<value_double>(line, keys::offset, value_double(offset)); put<value_double>(line, keys::simplify_tolerance, value_double(simplify_tolerance)); put<value_double>(line, keys::smooth, value_double(smooth)); vertex_converter<box2d<double>, grid_rasterizer, line_symbolizer, CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl> converter(clipping_extent,*ras_ptr,line,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 converter.set<stroke_tag>(); //always stroke for (geometry_type & geom : feature.paths()) { if (geom.size() > 1) { converter.apply(geom); } } // render id ren.color(color_type(feature.id())); agg::render_scanlines(*ras_ptr, sl, ren); // add feature properties to grid cache pixmap_.add_feature(feature); }
void drawCurve(unsigned char* _data, int _width, int _height, LinkInfo& _info) { //============================================================ // AGG agg::rendering_buffer rbuf; rbuf.attach(_data, _width, _height, _width*4); // Pixel format and basic primitives renderer agg::pixfmt_bgra32 pixf(rbuf); agg::renderer_base<agg::pixfmt_bgra32> renb(pixf); //renb.clear(agg::rgba8(152, 185, 254, 0)); // Scanline renderer for solid filling. agg::renderer_scanline_aa_solid<agg::renderer_base<agg::pixfmt_bgra32> > ren(renb); // Rasterizer & scanline agg::rasterizer_scanline_aa<> ras; agg::scanline_p8 sl; // хранилище всех путей agg::path_storage path; // кривая безье которая строится по 4 точкам agg::curve4 curve; curve.approximation_method(agg::curve_approximation_method_e(agg::curve_inc)); // метод апроксимации, curve_inc - быстрый но много точек curve.approximation_scale(0.7); //масштаб апроксимации curve.angle_tolerance(agg::deg2rad(0)); curve.cusp_limit(agg::deg2rad(0)); const int offset = 3; curve.init( _info.point_start.left, _info.point_start.top, _info.point_start.left, _info.point_start.top, _info.point_end.left, _info.point_end.top, _info.point_end.left, _info.point_end.top); // добавляем путь безье path.concat_path(curve); // сам путь который рисуется, растерезатор agg::conv_stroke<agg::path_storage> stroke(path); stroke.width(2); // ширина линии stroke.line_join(agg::line_join_e(agg::bevel_join)); // хз че такое stroke.line_cap(agg::line_cap_e(agg::round_cap)); //обрезка концов stroke.inner_join(agg::inner_join_e(agg::inner_miter)); // соединения внутри линии точек stroke.inner_miter_limit(0); ras.add_path(stroke); // Setting the attrribute (color) & Rendering ren.color(agg::rgba8(_info.colour.red * 255, _info.colour.green * 255, _info.colour.blue * 255, 255)); agg::render_scanlines(ras, sl, ren); //============================================================ // хранилище всех путей /*agg::path_storage path2; // кривая безье которая строится по 4 точкам agg::curve4 curve2; curve2.approximation_method(agg::curve_approximation_method_e(agg::curve_inc)); // метод апроксимации, curve_inc - быстрый но много точек curve2.approximation_scale(0.7); //масштаб апроксимации curve2.angle_tolerance(agg::deg2rad(0)); curve2.cusp_limit(agg::deg2rad(0)); curve2.init( _info.point_start.left, _info.point_start.top, _info.point_start.left + _info.start_offset, _info.point_start.top, _info.point_end.left + _info.end_offset, _info.point_end.top, _info.point_end.left, _info.point_end.top); // добавляем путь безье path2.concat_path(curve2); // сам путь который рисуется, растерезатор agg::conv_stroke<agg::path_storage> stroke2(path2); stroke2.width(2); // ширина линии stroke2.line_join(agg::line_join_e(agg::bevel_join)); // хз че такое stroke2.line_cap(agg::line_cap_e(agg::butt_cap)); //обрезка концов stroke2.inner_join(agg::inner_join_e(agg::inner_miter)); // соединения внутри линии точек stroke2.inner_miter_limit(1.01); ras.add_path(stroke2); // Setting the attrribute (color) & Rendering ren.color(agg::rgba8(_info.colour.red * 255, _info.colour.green * 255, _info.colour.blue * 255, 255)); agg::render_scanlines(ras, sl, ren);*/ //============================================================ }
void grid_renderer<T>::process(line_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { using pixfmt_type = typename grid_renderer_base_type::pixfmt_type; using color_type = typename grid_renderer_base_type::pixfmt_type::color_type; using renderer_type = agg::renderer_scanline_bin_solid<grid_renderer_base_type>; agg::scanline_bin sl; grid_rendering_buffer buf(pixmap_.raw_data(), common_.width_, common_.height_, common_.width_); pixfmt_type pixf(buf); grid_renderer_base_type renb(pixf); renderer_type ren(renb); ras_ptr->reset(); 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> clipping_extent = common_.query_extent_; bool clip = get<value_bool>(sym, keys::clip, feature, common_.vars_, false); double width = get<value_double>(sym, keys::stroke_width, feature, common_.vars_,1.0); double offset = get<value_double>(sym, keys::offset, feature, common_.vars_,0.0); double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, common_.vars_,0.0); double smooth = get<value_double>(sym, keys::smooth, feature, common_.vars_,false); bool has_dash = has_key(sym, keys::stroke_dasharray); if (clip) { double padding = (double)(common_.query_extent_.width()/pixmap_.width()); double half_stroke = width/2.0; if (half_stroke > 1) padding *= half_stroke; if (std::fabs(offset) > 0) padding *= std::fabs(offset) * 1.2; padding *= common_.scale_factor_; clipping_extent.pad(padding); } using vertex_converter_type = vertex_converter<clip_line_tag, clip_poly_tag, transform_tag, affine_transform_tag, simplify_tag, smooth_tag, offset_transform_tag, dash_tag, stroke_tag>; vertex_converter_type converter(clipping_extent,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_); if (clip) { geometry::geometry_types type = geometry::geometry_type(feature.get_geometry()); if (type == geometry::geometry_types::Polygon || type == geometry::geometry_types::MultiPolygon) converter.template set<clip_poly_tag>(); else if (type == geometry::geometry_types::LineString || type == geometry::geometry_types::MultiLineString) converter.template set<clip_line_tag>(); } 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_dash) converter.set<dash_tag>(); converter.set<stroke_tag>(); //always stroke using apply_vertex_converter_type = detail::apply_vertex_converter<vertex_converter_type, grid_rasterizer>; using vertex_processor_type = geometry::vertex_processor<apply_vertex_converter_type>; apply_vertex_converter_type apply(converter, *ras_ptr); mapnik::util::apply_visitor(vertex_processor_type(apply),feature.get_geometry()); // render id ren.color(color_type(feature.id())); ras_ptr->filling_rule(agg::fill_non_zero); agg::render_scanlines(*ras_ptr, sl, ren); // add feature properties to grid cache pixmap_.add_feature(feature); }
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 grid_renderer<T>::process(line_pattern_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { std::string filename = get<std::string, keys::file>(sym, feature, common_.vars_); if (filename.empty()) return; std::shared_ptr<mapnik::marker const> mark = marker_cache::instance().find(filename, true); if (mark->is<mapnik::marker_null>()) return; if (!mark->is<mapnik::marker_rgba8>()) { MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: Only images (not '" << filename << "') are supported in the line_pattern_symbolizer"; return; } value_bool clip = get<value_bool, keys::clip>(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_); using pixfmt_type = typename grid_renderer_base_type::pixfmt_type; using color_type = typename grid_renderer_base_type::pixfmt_type::color_type; using renderer_type = agg::renderer_scanline_bin_solid<grid_renderer_base_type>; agg::scanline_bin sl; grid_rendering_buffer buf(pixmap_.raw_data(), common_.width_, common_.height_, common_.width_); pixfmt_type pixf(buf); grid_renderer_base_type renb(pixf); renderer_type ren(renb); ras_ptr->reset(); line_pattern_enum pattern = get<line_pattern_enum, keys::line_pattern>(sym, feature, common_.vars_); std::size_t stroke_width = (pattern == LINE_PATTERN_WARP) ? mark->width() : get<value_double, keys::stroke_width>(sym, feature, common_.vars_); 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> clipping_extent = common_.query_extent_; if (clip) { double pad_per_pixel = static_cast<double>(common_.query_extent_.width()/common_.width_); double pixels = std::ceil(std::max(stroke_width / 2.0 + std::fabs(offset), (std::fabs(offset) * offset_converter_default_threshold))); double padding = pad_per_pixel * pixels * common_.scale_factor_; clipping_extent.pad(padding); } // to avoid the complexity of using an agg pattern filter instead // we create a line_symbolizer in order to fake the pattern line_symbolizer line; put<value_double>(line, keys::stroke_width, value_double(stroke_width)); // TODO: really should pass the offset to the fake line too, but // this wasn't present in the previous version and makes the test // fail - in this case, probably the test should be updated. //put<value_double>(line, keys::offset, value_double(offset)); put<value_double>(line, keys::simplify_tolerance, value_double(simplify_tolerance)); put<value_double>(line, keys::smooth, value_double(smooth)); using vertex_converter_type = vertex_converter<clip_line_tag, transform_tag, affine_transform_tag, simplify_tag,smooth_tag, offset_transform_tag,stroke_tag>; vertex_converter_type converter(clipping_extent,line,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_); if (clip) converter.set<clip_line_tag>(); 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 converter.set<stroke_tag>(); //always stroke using apply_vertex_converter_type = detail::apply_vertex_converter<vertex_converter_type,grid_rasterizer>; using vertex_processor_type = geometry::vertex_processor<apply_vertex_converter_type>; apply_vertex_converter_type apply(converter, *ras_ptr); mapnik::util::apply_visitor(vertex_processor_type(apply),feature.get_geometry()); // render id ren.color(color_type(feature.id())); agg::render_scanlines(*ras_ptr, sl, ren); // add feature properties to grid cache pixmap_.add_feature(feature); }
void agg_renderer<T>::process(building_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { typedef coord_transform<CoordTransform,geometry_type> path_type; typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base; typedef agg::renderer_scanline_aa_solid<ren_base> renderer; agg::rendering_buffer buf(current_buffer_->raw_data(),width_,height_, width_ * 4); agg::pixfmt_rgba32 pixf(buf); ren_base renb(pixf); color const& fill_ = sym.get_fill(); unsigned r=fill_.red(); unsigned g=fill_.green(); unsigned b=fill_.blue(); unsigned a=fill_.alpha(); renderer ren(renb); agg::scanline_u8 sl; ras_ptr->reset(); ras_ptr->gamma(agg::gamma_power()); double height = 0.0; expression_ptr height_expr = sym.height(); if (height_expr) { value_type result = boost::apply_visitor(evaluate<Feature,value_type>(feature), *height_expr); height = result.to_double() * scale_factor_; } for (unsigned i=0;i<feature.num_geometries();++i) { geometry_type const& geom = feature.get_geometry(i); if (geom.size() > 2) { boost::scoped_ptr<geometry_type> frame(new geometry_type(LineString)); boost::scoped_ptr<geometry_type> roof(new geometry_type(Polygon)); std::deque<segment_t> face_segments; double x0 = 0; double y0 = 0; double x,y; geom.rewind(0); for (unsigned cm = geom.vertex(&x, &y); cm != SEG_END; cm = geom.vertex(&x, &y)) { if (cm == SEG_MOVETO) { frame->move_to(x,y); } else if (cm == SEG_LINETO || cm == SEG_CLOSE) { frame->line_to(x,y); face_segments.push_back(segment_t(x0,y0,x,y)); } x0 = x; y0 = y; } std::sort(face_segments.begin(),face_segments.end(), y_order); std::deque<segment_t>::const_iterator itr=face_segments.begin(); std::deque<segment_t>::const_iterator end=face_segments.end(); for (; itr!=end; ++itr) { boost::scoped_ptr<geometry_type> faces(new geometry_type(Polygon)); faces->move_to(itr->get<0>(),itr->get<1>()); faces->line_to(itr->get<2>(),itr->get<3>()); faces->line_to(itr->get<2>(),itr->get<3>() + height); faces->line_to(itr->get<0>(),itr->get<1>() + height); path_type faces_path (t_,*faces,prj_trans); ras_ptr->add_path(faces_path); ren.color(agg::rgba8(int(r*0.8), int(g*0.8), int(b*0.8), int(a * sym.get_opacity()))); agg::render_scanlines(*ras_ptr, sl, ren); ras_ptr->reset(); // frame->move_to(itr->get<0>(),itr->get<1>()); frame->line_to(itr->get<0>(),itr->get<1>()+height); } geom.rewind(0); for (unsigned cm = geom.vertex(&x, &y); cm != SEG_END; cm = geom.vertex(&x, &y)) { if (cm == SEG_MOVETO) { frame->move_to(x,y+height); roof->move_to(x,y+height); } else if (cm == SEG_LINETO || cm == SEG_CLOSE) { frame->line_to(x,y+height); roof->line_to(x,y+height); } } path_type path(t_,*frame,prj_trans); agg::conv_stroke<path_type> stroke(path); stroke.width(scale_factor_); ras_ptr->add_path(stroke); ren.color(agg::rgba8(int(r*0.8), int(g*0.8), int(b*0.8), int(a * sym.get_opacity()))); agg::render_scanlines(*ras_ptr, sl, ren); ras_ptr->reset(); path_type roof_path (t_,*roof,prj_trans); ras_ptr->add_path(roof_path); ren.color(agg::rgba8(r, g, b, int(a * sym.get_opacity()))); agg::render_scanlines(*ras_ptr, sl, ren); } } }
virtual void on_draw() { typedef agg::renderer_base<pixfmt> ren_base; pixfmt pixf(rbuf_window()); ren_base renb(pixf); renb.clear(agg::rgba(1, 1, 1)); agg::rasterizer_scanline_aa<> ras; agg::scanline_p8 sl; agg::path_storage path; path.move_to(m_x[0], m_y[0]); path.line_to((m_x[0] + m_x[1]) / 2, (m_y[0] + m_y[1]) / 2); // This point is added only to check // for numerical stability path.line_to(m_x[1], m_y[1]); path.line_to(m_x[2], m_y[2]); path.line_to(m_x[2], m_y[2]); // This point is added only to check for // numerical stability path.move_to((m_x[0] + m_x[1]) / 2, (m_y[0] + m_y[1]) / 2); path.line_to((m_x[1] + m_x[2]) / 2, (m_y[1] + m_y[2]) / 2); path.line_to((m_x[2] + m_x[0]) / 2, (m_y[2] + m_y[0]) / 2); path.close_polygon(); agg::line_cap_e cap = agg::butt_cap; if (m_cap.cur_item() == 1) cap = agg::square_cap; if (m_cap.cur_item() == 2) cap = agg::round_cap; agg::line_join_e join = agg::miter_join; if (m_join.cur_item() == 1) join = agg::miter_join_revert; if (m_join.cur_item() == 2) join = agg::round_join; if (m_join.cur_item() == 3) join = agg::bevel_join; // (1) agg::conv_stroke<agg::path_storage> stroke(path); stroke.line_join(join); stroke.line_cap(cap); stroke.miter_limit(m_miter_limit.value()); stroke.width(m_width.value()); ras.add_path(stroke); agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba(0.8, 0.7, 0.6)); // (1) // (2) agg::conv_stroke<agg::path_storage> poly1(path); poly1.width(1.5); ras.add_path(poly1); agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba(0, 0, 0)); // (2) // (3) agg::conv_dash<agg::conv_stroke<agg::path_storage> > poly2_dash(stroke); agg::conv_stroke<agg::conv_dash<agg::conv_stroke<agg::path_storage> > > poly2(poly2_dash); poly2.miter_limit(4.0); poly2.width(m_width.value() / 5.0); poly2.line_cap(cap); poly2.line_join(join); poly2_dash.add_dash(20.0, m_width.value() / 2.5); ras.add_path(poly2); agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba(0, 0, 0.3)); // (3) // (4) ras.add_path(path); agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba(0.0, 0.0, 0.0, 0.2)); // (4) agg::render_ctrl(ras, sl, renb, m_join); agg::render_ctrl(ras, sl, renb, m_cap); agg::render_ctrl(ras, sl, renb, m_width); agg::render_ctrl(ras, sl, renb, m_miter_limit); }
virtual void on_draw() { typedef agg::renderer_base<pixfmt> ren_base; pixfmt pixf(rbuf_window()); ren_base renb(pixf); renb.clear(agg::rgba(1, 1, 1)); agg::rasterizer_scanline_aa<> ras; agg::scanline_u8 sl; agg::line_cap_e cap = agg::butt_cap; if(m_cap.cur_item() == 1) cap = agg::square_cap; if(m_cap.cur_item() == 2) cap = agg::round_cap; // Here we declare a very cheap-in-use path storage. // It allocates space for at most 20 vertices in stack and // never allocates memory. But be aware that adding more than // 20 vertices is fatal! //------------------------ typedef agg::path_base< agg::vertex_stl_storage< agg::pod_auto_vector< agg::vertex_d, 20> > > path_storage_type; path_storage_type path; path.move_to(m_x[0], m_y[0]); path.line_to(m_x[1], m_y[1]); path.line_to((m_x[0]+m_x[1]+m_x[2]) / 3.0, (m_y[0]+m_y[1]+m_y[2]) / 3.0); path.line_to(m_x[2], m_y[2]); if(m_close.status()) path.close_polygon(); path.move_to((m_x[0] + m_x[1]) / 2, (m_y[0] + m_y[1]) / 2); path.line_to((m_x[1] + m_x[2]) / 2, (m_y[1] + m_y[2]) / 2); path.line_to((m_x[2] + m_x[0]) / 2, (m_y[2] + m_y[0]) / 2); if(m_close.status()) path.close_polygon(); if(m_even_odd.status()) ras.filling_rule(agg::fill_even_odd); // (1) ras.add_path(path); agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba(0.7, 0.5, 0.1, 0.5)); // (1) // Start of (2, 3, 4) agg::conv_smooth_poly1<path_storage_type> smooth(path); smooth.smooth_value(m_smooth.value()); // (2) ras.add_path(smooth); agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba(0.1, 0.5, 0.7, 0.1)); // (2) // (3) agg::conv_stroke<agg::conv_smooth_poly1<path_storage_type> > smooth_outline(smooth); ras.add_path(smooth_outline); agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba(0.0, 0.6, 0.0, 0.8)); // (3) // (4) agg::conv_curve<agg::conv_smooth_poly1<path_storage_type> > curve(smooth); agg::conv_dash<agg::conv_curve<agg::conv_smooth_poly1<path_storage_type> >, agg::vcgen_markers_term> dash(curve); agg::conv_stroke<agg::conv_dash<agg::conv_curve<agg::conv_smooth_poly1<path_storage_type> >, agg::vcgen_markers_term> > stroke(dash); stroke.line_cap(cap); stroke.width(m_width.value()); double k = ::pow(m_width.value(), 0.7); agg::arrowhead ah; ah.head(4 * k, 4 * k, 3 * k, 2 * k); if(!m_close.status()) ah.tail(1 * k, 1.5 * k, 3 * k, 5 * k); agg::conv_marker<agg::vcgen_markers_term, agg::arrowhead> arrow(dash.markers(), ah); dash.add_dash(20.0, 5.0); dash.add_dash(5.0, 5.0); dash.add_dash(5.0, 5.0); dash.dash_start(10); ras.add_path(stroke); ras.add_path(arrow); agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba(0.0, 0.0, 0.0)); // (4) ras.filling_rule(agg::fill_non_zero); agg::render_ctrl(ras, sl, renb, m_cap); agg::render_ctrl(ras, sl, renb, m_width); agg::render_ctrl(ras, sl, renb, m_smooth); agg::render_ctrl(ras, sl, renb, m_close); agg::render_ctrl(ras, sl, renb, m_even_odd); }
void grid_renderer<T>::process(line_symbolizer const& sym, Feature const& feature, proj_transform const& prj_trans) { typedef coord_transform2<CoordTransform,geometry_type> path_type; typedef agg::renderer_base<mapnik::pixfmt_gray16> ren_base; typedef agg::renderer_scanline_bin_solid<ren_base> renderer; agg::scanline_bin sl; grid_rendering_buffer buf(pixmap_.raw_data(), width_, height_, width_); mapnik::pixfmt_gray16 pixf(buf); ren_base renb(pixf); renderer ren(renb); ras_ptr->reset(); stroke const& stroke_ = sym.get_stroke(); for (unsigned i=0;i<feature.num_geometries();++i) { geometry_type const& geom = feature.get_geometry(i); if (geom.num_points() > 1) { path_type path(t_,geom,prj_trans); if (stroke_.has_dash()) { agg::conv_dash<path_type> dash(path); dash_array const& d = stroke_.get_dash_array(); dash_array::const_iterator itr = d.begin(); dash_array::const_iterator end = d.end(); for (;itr != end;++itr) { dash.add_dash(itr->first * scale_factor_, itr->second * scale_factor_); } agg::conv_stroke<agg::conv_dash<path_type > > stroke(dash); line_join_e join=stroke_.get_line_join(); if ( join == MITER_JOIN) stroke.generator().line_join(agg::miter_join); else if( join == MITER_REVERT_JOIN) stroke.generator().line_join(agg::miter_join); else if( join == ROUND_JOIN) stroke.generator().line_join(agg::round_join); else stroke.generator().line_join(agg::bevel_join); line_cap_e cap=stroke_.get_line_cap(); if (cap == BUTT_CAP) stroke.generator().line_cap(agg::butt_cap); else if (cap == SQUARE_CAP) stroke.generator().line_cap(agg::square_cap); else stroke.generator().line_cap(agg::round_cap); stroke.generator().miter_limit(4.0); stroke.generator().width(stroke_.get_width() * scale_factor_); ras_ptr->add_path(stroke); } else { agg::conv_stroke<path_type> stroke(path); line_join_e join=stroke_.get_line_join(); if ( join == MITER_JOIN) stroke.generator().line_join(agg::miter_join); else if( join == MITER_REVERT_JOIN) stroke.generator().line_join(agg::miter_join); else if( join == ROUND_JOIN) stroke.generator().line_join(agg::round_join); else stroke.generator().line_join(agg::bevel_join); line_cap_e cap=stroke_.get_line_cap(); if (cap == BUTT_CAP) stroke.generator().line_cap(agg::butt_cap); else if (cap == SQUARE_CAP) stroke.generator().line_cap(agg::square_cap); else stroke.generator().line_cap(agg::round_cap); stroke.generator().miter_limit(4.0); stroke.generator().width(stroke_.get_width() * scale_factor_); ras_ptr->add_path(stroke); } } } // render id ren.color(mapnik::gray16(feature.id())); agg::render_scanlines(*ras_ptr, sl, ren); // add feature properties to grid cache pixmap_.add_feature(feature); }
void agg_renderer<T>::process(line_symbolizer const& sym, Feature const& feature, proj_transform const& prj_trans) { typedef agg::renderer_base<agg::pixfmt_rgba32_plain> ren_base; typedef coord_transform2<CoordTransform,geometry_type> path_type; 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(); agg::rendering_buffer buf(pixmap_.raw_data(),width_,height_, width_ * 4); agg::pixfmt_rgba32_plain pixf(buf); if (sym.get_rasterizer() == RASTERIZER_FAST) { typedef agg::renderer_outline_aa<ren_base> renderer_type; typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type; agg::line_profile_aa profile; //agg::line_profile_aa profile(stroke_.get_width() * scale_factor_, agg::gamma_none()); profile.width(stroke_.get_width() * scale_factor_); ren_base base_ren(pixf); renderer_type ren(base_ren, profile); ren.color(agg::rgba8(r, g, b, int(a*stroke_.get_opacity()))); //ren.clip_box(0,0,width_,height_); rasterizer_type ras(ren); ras.line_join(agg::outline_miter_accurate_join); ras.round_cap(true); for (unsigned i=0;i<feature.num_geometries();++i) { geometry_type const& geom = feature.get_geometry(i); if (geom.num_points() > 1) { path_type path(t_,geom,prj_trans); ras.add_path(path); } } } else { typedef agg::renderer_scanline_aa_solid<ren_base> renderer; agg::scanline_p8 sl; ren_base renb(pixf); renderer ren(renb); ras_ptr->reset(); switch (stroke_.get_gamma_method()) { case GAMMA_POWER: ras_ptr->gamma(agg::gamma_power(stroke_.get_gamma())); break; case GAMMA_LINEAR: ras_ptr->gamma(agg::gamma_linear(0.0, stroke_.get_gamma())); break; case GAMMA_NONE: ras_ptr->gamma(agg::gamma_none()); break; case GAMMA_THRESHOLD: ras_ptr->gamma(agg::gamma_threshold(stroke_.get_gamma())); break; case GAMMA_MULTIPLY: ras_ptr->gamma(agg::gamma_multiply(stroke_.get_gamma())); break; default: ras_ptr->gamma(agg::gamma_power(stroke_.get_gamma())); } metawriter_with_properties writer = sym.get_metawriter(); for (unsigned i=0;i<feature.num_geometries();++i) { geometry_type const& geom = feature.get_geometry(i); if (geom.num_points() > 1) { path_type path(t_,geom,prj_trans); if (stroke_.has_dash()) { agg::conv_dash<path_type> dash(path); dash_array const& d = stroke_.get_dash_array(); dash_array::const_iterator itr = d.begin(); dash_array::const_iterator end = d.end(); for (;itr != end;++itr) { dash.add_dash(itr->first * scale_factor_, itr->second * scale_factor_); } agg::conv_stroke<agg::conv_dash<path_type > > stroke(dash); line_join_e join=stroke_.get_line_join(); if ( join == MITER_JOIN) stroke.generator().line_join(agg::miter_join); else if( join == MITER_REVERT_JOIN) stroke.generator().line_join(agg::miter_join); else if( join == ROUND_JOIN) stroke.generator().line_join(agg::round_join); else stroke.generator().line_join(agg::bevel_join); line_cap_e cap=stroke_.get_line_cap(); if (cap == BUTT_CAP) stroke.generator().line_cap(agg::butt_cap); else if (cap == SQUARE_CAP) stroke.generator().line_cap(agg::square_cap); else stroke.generator().line_cap(agg::round_cap); stroke.generator().miter_limit(4.0); stroke.generator().width(stroke_.get_width() * scale_factor_); ras_ptr->add_path(stroke); } else { agg::conv_stroke<path_type> stroke(path); line_join_e join=stroke_.get_line_join(); if ( join == MITER_JOIN) stroke.generator().line_join(agg::miter_join); else if( join == MITER_REVERT_JOIN) stroke.generator().line_join(agg::miter_join); else if( join == ROUND_JOIN) stroke.generator().line_join(agg::round_join); else stroke.generator().line_join(agg::bevel_join); line_cap_e cap=stroke_.get_line_cap(); if (cap == BUTT_CAP) stroke.generator().line_cap(agg::butt_cap); else if (cap == SQUARE_CAP) stroke.generator().line_cap(agg::square_cap); else stroke.generator().line_cap(agg::round_cap); stroke.generator().miter_limit(4.0); stroke.generator().width(stroke_.get_width() * scale_factor_); ras_ptr->add_path(stroke); if (writer.first) writer.first->add_line(path, feature, t_, writer.second); } } } ren.color(agg::rgba8(r, g, b, int(a*stroke_.get_opacity()))); agg::render_scanlines(*ras_ptr, sl, ren); } }
int main(int argc, char* argv[]) { if(argc < 4) { printf("usage: bezier_test <width> <height> <number_of_curves>\n"); return 1; } unsigned w = atoi(argv[1]); unsigned h = atoi(argv[2]); unsigned n = atoi(argv[3]); if(w < 20 || h < 20) { printf("Width and hight must be at least 20\n"); return 1; } if(w > 4096 || h > 4096) { printf("Width and hight mustn't exceed 4096\n"); return 1; } unsigned stride = (w * 3 + 3) / 4 * 4; unsigned char* frame_buffer = new unsigned char[stride * h]; agg::rendering_buffer rbuf; rbuf.attach((unsigned char*)frame_buffer, w, h, stride); agg::pixfmt_bgr24 pixf(rbuf); agg::renderer_base<agg::pixfmt_bgr24> renb(pixf); agg::renderer_scanline_aa_solid<agg::renderer_base<agg::pixfmt_bgr24> > ren(renb); renb.clear(agg::rgba(1.0, 1.0, 1.0)); clock_t t1 = clock(); agg::curve4 curve; agg::conv_stroke<agg::curve4> poly(curve); agg::rasterizer_scanline_aa<> ras; agg::scanline_p8 sl; unsigned i; for(i = 0; i < n; i++) { poly.width(double(rand() % 3500 + 500) / 500.0); curve.init(rand() % w, rand() % h, rand() % w, rand() % h, rand() % w, rand() % h, rand() % w, rand() % h); ren.color(agg::rgba8(rand() & 0xFF, rand() & 0xFF, rand() & 0xFF, rand() & 0xFF)); ras.add_path(poly, 0); agg::render_scanlines(ras, sl, ren); } clock_t t2 = clock(); double sec = double(t2 - t1) / CLOCKS_PER_SEC; printf("%10.3f sec, %10.3f curves per sec\n", sec, double(n) / sec); write_bmp_24("output.bmp", (unsigned char*)frame_buffer, w, h, stride); delete [] frame_buffer; return 0; }
int main (int argc,char** argv) { namespace po = boost::program_options; bool verbose=false; std::vector<std::string> svg_files; try { po::options_description desc("svg2png utility"); desc.add_options() ("help,h", "produce usage message") ("version,V","print version string") ("verbose,v","verbose output") ("svg",po::value<std::vector<std::string> >(),"svg file to read") ; po::positional_options_description p; p.add("svg",-1); po::variables_map vm; po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm); po::notify(vm); if (vm.count("version")) { std::clog<<"version 0.3.0" << std::endl; return 1; } if (vm.count("help")) { std::clog << desc << std::endl; return 1; } if (vm.count("verbose")) { verbose = true; } if (vm.count("svg")) { svg_files=vm["svg"].as< std::vector<std::string> >(); } else { std::clog << "please provide an svg file!" << std::endl; return -1; } std::vector<std::string>::const_iterator itr = svg_files.begin(); if (itr == svg_files.end()) { std::clog << "no svg files to render" << std::endl; return 0; } while (itr != svg_files.end()) { std::string svg_name (*itr++); boost::optional<mapnik::marker_ptr> marker_ptr = mapnik::marker_cache::instance()->find(svg_name, false); if (marker_ptr) { mapnik::marker marker = **marker_ptr; if (marker.is_vector()) { typedef agg::pixfmt_rgba32_plain pixfmt; typedef agg::renderer_base<pixfmt> renderer_base; typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid; agg::rasterizer_scanline_aa<> ras_ptr; agg::scanline_u8 sl; double opacity = 1; double scale_factor_ = .95; int w = marker.width(); int h = marker.height(); mapnik::image_32 im(w,h); agg::rendering_buffer buf(im.raw_data(), w, h, w * 4); pixfmt pixf(buf); renderer_base renb(pixf); mapnik::box2d<double> const& bbox = (*marker.get_vector_data())->bounding_box(); mapnik::coord<double,2> c = bbox.center(); // center the svg marker on '0,0' agg::trans_affine mtx = agg::trans_affine_translation(-c.x,-c.y); // apply symbol transformation to get to map space mtx *= agg::trans_affine_scaling(scale_factor_); // render the marker at the center of the marker box mtx.translate(0.5 * w, 0.5 * h); mapnik::svg::vertex_stl_adapter<mapnik::svg::svg_path_storage> stl_storage((*marker.get_vector_data())->source()); mapnik::svg::svg_path_adapter svg_path(stl_storage); mapnik::svg::svg_renderer<mapnik::svg::svg_path_adapter, agg::pod_bvector<mapnik::svg::path_attributes>, renderer_solid, agg::pixfmt_rgba32_plain > svg_renderer_this(svg_path, (*marker.get_vector_data())->attributes()); svg_renderer_this.render(ras_ptr, sl, renb, mtx, opacity, bbox); boost::algorithm::ireplace_last(svg_name,".svg",".png"); mapnik::save_to_file<mapnik::image_data_32>(im.data(),svg_name,"png"); std::ostringstream s; s << "open " << svg_name; return system(s.str().c_str()); } } } } catch (...) { std::clog << "Exception of unknown type!" << std::endl; return -1; } return 0; }
virtual void on_draw() { typedef agg::renderer_base<agg::pixfmt_bgra32> ren_base; typedef agg::renderer_base<agg::pixfmt_bgra32_pre> ren_base_pre; agg::gamma_lut<agg::int8u, agg::int8u> lut(2.0); agg::pixfmt_bgra32 pixf(rbuf_window()); ren_base renb(pixf); agg::pixfmt_bgra32_pre pixf_pre(rbuf_window()); ren_base_pre renb_pre(pixf_pre); // Clear the window with a gradient agg::pod_vector<agg::rgba8> gr(pixf_pre.width()); unsigned i; for(i = 0; i < pixf.width(); i++) { gr.add(agg::rgba8(255, 255, 0).gradient(agg::rgba8(0, 255, 255), double(i) / pixf.width())); } for(i = 0; i < pixf.height(); i++) { renb.copy_color_hspan(0, i, pixf.width(), &gr[0]); } pixf.apply_gamma_dir(lut); agg::rasterizer_scanline_aa<> ras; agg::rasterizer_compound_aa<agg::rasterizer_sl_clip_dbl> rasc; agg::scanline_u8 sl; agg::span_allocator<agg::rgba8> alloc; // Draw two triangles ras.move_to_d(0, 0); ras.line_to_d(width(), 0); ras.line_to_d(width(), height()); agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba8(lut.dir(0), lut.dir(100), lut.dir(0))); ras.move_to_d(0, 0); ras.line_to_d(0, height()); ras.line_to_d(width(), 0); agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba8(lut.dir(0), lut.dir(100), lut.dir(100))); agg::trans_affine mtx; mtx *= agg::trans_affine_scaling(4.0); mtx *= agg::trans_affine_translation(150, 100); agg::conv_transform<agg::path_storage> trans(m_path, mtx); agg::conv_curve<agg::conv_transform<agg::path_storage> > curve(trans); agg::conv_stroke <agg::conv_curve <agg::conv_transform <agg::path_storage> > > stroke(curve); compose_path(); agg::rgba8 styles[4]; if(m_invert_order.status()) { rasc.layer_order(agg::layer_inverse); } else { rasc.layer_order(agg::layer_direct); } styles[3] = agg::rgba8(lut.dir(255), lut.dir(0), lut.dir(108), 200).premultiply(); styles[2] = agg::rgba8(lut.dir(51), lut.dir(0), lut.dir(151), 180).premultiply(); styles[1] = agg::rgba8(lut.dir(143), lut.dir(90), lut.dir(6), 200).premultiply(); styles[0] = agg::rgba8(lut.dir(0), lut.dir(0), lut.dir(255), 220).premultiply(); style_handler sh(styles, 4); stroke.width(m_width.value()); rasc.reset(); rasc.master_alpha(3, m_alpha1.value()); rasc.master_alpha(2, m_alpha2.value()); rasc.master_alpha(1, m_alpha3.value()); rasc.master_alpha(0, m_alpha4.value()); agg::ellipse ell(220.0, 180.0, 120.0, 10.0, 128, false); agg::conv_stroke<agg::ellipse> str_ell(ell); str_ell.width(m_width.value() / 2); rasc.styles(3, -1); rasc.add_path(str_ell); rasc.styles(2, -1); rasc.add_path(ell); rasc.styles(1, -1); rasc.add_path(stroke); rasc.styles(0, -1); rasc.add_path(curve); agg::render_scanlines_compound_layered(rasc, sl, renb_pre, alloc, sh); agg::render_ctrl(ras, sl, renb, m_width); agg::render_ctrl(ras, sl, renb, m_alpha1); agg::render_ctrl(ras, sl, renb, m_alpha2); agg::render_ctrl(ras, sl, renb, m_alpha3); agg::render_ctrl(ras, sl, renb, m_alpha4); agg::render_ctrl(ras, sl, renb, m_invert_order); pixf.apply_gamma_inv(lut); }