예제 #1
0
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);
}
예제 #3
0
 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_);
    }
예제 #7
0
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);
}
예제 #8
0
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);

}
예제 #9
0
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());
}
예제 #10
0
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_);
    }
예제 #12
0
    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);
    }
예제 #13
0
 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_);
 }
예제 #14
0
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);
}
예제 #16
0
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);
}
예제 #17
0
파일: svg2png.cpp 프로젝트: orofarne/mapnik
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);

}
예제 #19
0
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);*/
    //============================================================
}
예제 #20
0
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);

}
예제 #21
0
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);

        }
    }
}
예제 #24
0
파일: conv_stroke.cpp 프로젝트: UIKit0/agg
  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);
  }
예제 #25
0
    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);

}
예제 #27
0
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);    
    }
}
예제 #28
0
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;
}
예제 #29
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;
}
예제 #30
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);
    }