bool THRawBitmap::_checkScaled(THRenderTarget* pCanvas, SDL_Rect& rcDest) { float fFactor; if(!pCanvas->shouldScaleBitmaps(&fFactor)) return false; int iScaledWidth = (int)((float)m_pBitmap->w * fFactor); if(!m_pCachedScaledBitmap || m_pCachedScaledBitmap->w != iScaledWidth) { SDL_FreeSurface(m_pCachedScaledBitmap); Uint32 iRMask, iGMask, iBMask; #if SDL_BYTEORDER == SDL_BIG_ENDIAN iRMask = 0xff000000; iGMask = 0x00ff0000; iBMask = 0x0000ff00; #else iRMask = 0x000000ff; iGMask = 0x0000ff00; iBMask = 0x00ff0000; #endif m_pCachedScaledBitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, iScaledWidth, (int)((float)m_pBitmap->h * fFactor), 24, iRMask, iGMask, iBMask, 0); SDL_LockSurface(m_pCachedScaledBitmap); SDL_LockSurface(m_pBitmap); typedef agg::pixfmt_rgb24_pre pixfmt_pre_t; typedef agg::renderer_base<pixfmt_pre_t> renbase_pre_t; typedef image_accessor_clip_rgb24_pal8<pixfmt_pre_t> imgsrc_t; typedef agg::span_interpolator_linear<> interpolator_t; typedef agg::span_image_filter_rgb_2x2<imgsrc_t, interpolator_t> span_gen_type; agg::scanline_p8 sl; agg::span_allocator<pixfmt_pre_t::color_type> sa; agg::image_filter<agg::image_filter_bilinear> filter; agg::trans_affine_scaling img_mtx(1.0 / fFactor); agg::rendering_buffer rbuf_src(m_pData, m_pBitmap->w, m_pBitmap->h, m_pBitmap->pitch); imgsrc_t img_src(rbuf_src, *m_pPalette, agg::rgba(0.0, 0.0, 0.0)); interpolator_t interpolator(img_mtx); span_gen_type sg(img_src, interpolator, filter); agg::rendering_buffer rbuf(reinterpret_cast<unsigned char*>(m_pCachedScaledBitmap->pixels), m_pCachedScaledBitmap->w, m_pCachedScaledBitmap->h, m_pCachedScaledBitmap->pitch); pixfmt_pre_t pixf_pre(rbuf); renbase_pre_t rbase_pre(pixf_pre); rasterizer_scanline_rect ras(0, 0, rbuf.width(), rbuf.height()); rbase_pre.clear(agg::rgba(1.0,0,0,0)); agg::render_scanlines_aa(ras, sl, rbase_pre, sa, sg); SDL_UnlockSurface(m_pBitmap); SDL_UnlockSurface(m_pCachedScaledBitmap); } rcDest.x = (Sint16)((float)rcDest.x * fFactor); rcDest.y = (Sint16)((float)rcDest.y * fFactor); return true; }
int agg2RenderPolygonTiled(imageObj *img, shapeObj *p, imageObj * tile) { assert(img->format->renderer == tile->format->renderer); AGG2Renderer *r = AGG_RENDERER(img); AGG2Renderer *tileRenderer = AGG_RENDERER(tile); polygon_adaptor polygons(p); typedef mapserver::wrap_mode_repeat wrap_type; typedef mapserver::image_accessor_wrap<pixel_format,wrap_type,wrap_type> img_source_type; typedef mapserver::span_pattern_rgba<img_source_type> span_gen_type; mapserver::span_allocator<mapserver::rgba8> sa; r->m_rasterizer_aa.reset(); r->m_rasterizer_aa.filling_rule(mapserver::fill_even_odd); img_source_type img_src(tileRenderer->m_pixel_format); span_gen_type sg(img_src, 0, 0); r->m_rasterizer_aa.add_path(polygons); mapserver::render_scanlines_aa(r->m_rasterizer_aa, r->sl_poly, r->m_renderer_base, sa , sg); return MS_SUCCESS; }
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_); }
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); }
virtual void on_draw() { typedef agg::renderer_base<pixfmt> renderer_base; typedef agg::renderer_base<pixfmt_pre> renderer_base_pre; pixfmt pixf(rbuf_window()); pixfmt_pre pixf_pre(rbuf_window()); renderer_base rb(pixf); renderer_base_pre rb_pre(pixf_pre); rb.clear(agg::rgba(1.0, 1.0, 1.0)); agg::trans_affine src_mtx; src_mtx *= agg::trans_affine_translation(-initial_width()/2 - 10, -initial_height()/2 - 20 - 10); src_mtx *= agg::trans_affine_rotation(m_angle.value() * agg::pi / 180.0); src_mtx *= agg::trans_affine_scaling(m_scale.value()); src_mtx *= agg::trans_affine_translation(initial_width()/2, initial_height()/2 + 20); src_mtx *= trans_affine_resizing(); agg::trans_affine img_mtx; img_mtx *= agg::trans_affine_translation(-initial_width()/2 + 10, -initial_height()/2 + 20 + 10); img_mtx *= agg::trans_affine_rotation(m_angle.value() * agg::pi / 180.0); img_mtx *= agg::trans_affine_scaling(m_scale.value()); img_mtx *= agg::trans_affine_translation(initial_width()/2, initial_height()/2 + 20); img_mtx *= trans_affine_resizing(); img_mtx.invert(); agg::span_allocator<color_type> sa; typedef agg::span_interpolator_linear<> interpolator_type; interpolator_type interpolator(img_mtx); typedef agg::image_accessor_clip<pixfmt> img_source_type; pixfmt img_pixf(rbuf_img(0)); img_source_type img_src(img_pixf, agg::rgba_pre(0, 0.4, 0, 0.5)); /* // Version without filtering (nearest neighbor) //------------------------------------------ typedef agg::span_image_filter_rgb_nn<img_source_type, interpolator_type> span_gen_type; span_gen_type sg(img_src, interpolator); //------------------------------------------ */ // Version with "hardcoded" bilinear filter and without // image_accessor (direct filter, the old variant) //------------------------------------------ typedef agg::span_image_filter_rgb_bilinear_clip<pixfmt, interpolator_type> span_gen_type; span_gen_type sg(img_pixf, agg::rgba_pre(0, 0.4, 0, 0.5), interpolator); //------------------------------------------ /* // Version with arbitrary 2x2 filter //------------------------------------------ typedef agg::span_image_filter_rgb_2x2<img_source_type, interpolator_type> span_gen_type; agg::image_filter<agg::image_filter_kaiser> filter; span_gen_type sg(img_src, interpolator, filter); //------------------------------------------ */ /* // Version with arbitrary filter //------------------------------------------ typedef agg::span_image_filter_rgb<img_source_type, interpolator_type> span_gen_type; agg::image_filter<agg::image_filter_spline36> filter; span_gen_type sg(img_src, interpolator, filter); //------------------------------------------ */ agg::rasterizer_scanline_aa<> ras; ras.clip_box(0, 0, width(), height()); agg::scanline_u8 sl; double r = initial_width(); if(initial_height() - 60 < r) r = initial_height() - 60; agg::ellipse ell(initial_width() / 2.0 + 10, initial_height() / 2.0 + 20 + 10, r / 2.0 + 16.0, r / 2.0 + 16.0, 200); agg::conv_transform<agg::ellipse> tr(ell, src_mtx); ras.add_path(tr); agg::render_scanlines_aa(ras, sl, rb_pre, sa, sg); agg::render_ctrl(ras, sl, rb, m_angle); agg::render_ctrl(ras, sl, rb, m_scale); }
void scale_image_agg(T & target, T const& source, scaling_method_e scaling_method, double image_ratio_x, double image_ratio_y, double x_off_f, double y_off_f, double filter_factor) { // "the image filters should work namely in the premultiplied color space" // http://old.nabble.com/Re:--AGG--Basic-image-transformations-p1110665.html // "Yes, you need to use premultiplied images only. Only in this case the simple weighted averaging works correctly in the image fitering." // http://permalink.gmane.org/gmane.comp.graphics.agg/3443 using image_type = T; using pixel_type = typename image_type::pixel_type; using pixfmt_pre = typename detail::agg_scaling_traits<image_type>::pixfmt_pre; using color_type = typename detail::agg_scaling_traits<image_type>::color_type; using img_src_type = typename detail::agg_scaling_traits<image_type>::img_src_type; using interpolator_type = typename detail::agg_scaling_traits<image_type>::interpolator_type; using renderer_base_pre = agg::renderer_base<pixfmt_pre>; constexpr std::size_t pixel_size = sizeof(pixel_type); // define some stuff we'll use soon agg::rasterizer_scanline_aa<> ras; agg::scanline_u8 sl; agg::span_allocator<color_type> sa; // initialize source AGG buffer agg::rendering_buffer rbuf_src(const_cast<unsigned char*>(source.bytes()), source.width(), source.height(), source.width() * pixel_size); pixfmt_pre pixf_src(rbuf_src); img_src_type img_src(pixf_src); // initialize destination AGG buffer (with transparency) agg::rendering_buffer rbuf_dst(target.bytes(), target.width(), target.height(), target.width() * pixel_size); pixfmt_pre pixf_dst(rbuf_dst); renderer_base_pre rb_dst_pre(pixf_dst); // create a scaling matrix agg::trans_affine img_mtx; img_mtx /= agg::trans_affine_scaling(image_ratio_x, image_ratio_y); // create a linear interpolator for our scaling matrix interpolator_type interpolator(img_mtx); // draw an anticlockwise polygon to render our image into double scaled_width = target.width(); double scaled_height = target.height(); ras.reset(); ras.move_to_d(x_off_f, y_off_f); ras.line_to_d(x_off_f + scaled_width, y_off_f); ras.line_to_d(x_off_f + scaled_width, y_off_f + scaled_height); ras.line_to_d(x_off_f, y_off_f + scaled_height); if (scaling_method == SCALING_NEAR) { using span_gen_type = typename detail::agg_scaling_traits<image_type>::span_image_filter; span_gen_type sg(img_src, interpolator); agg::render_scanlines_aa(ras, sl, rb_dst_pre, sa, sg); } else { using span_gen_type = typename detail::agg_scaling_traits<image_type>::span_image_resample_affine; agg::image_filter_lut filter; detail::set_scaling_method(filter, scaling_method, filter_factor); span_gen_type sg(img_src, interpolator, filter); agg::render_scanlines_aa(ras, sl, rb_dst_pre, sa, sg); } }
virtual void on_draw() { typedef agg::pixfmt_bgr24 pixfmt; typedef agg::renderer_base<pixfmt> renderer_base; pixfmt pixf(rbuf_window()); renderer_base rb(pixf); rb.clear(agg::rgba(1.0, 1.0, 1.0)); agg::trans_affine src_mtx; src_mtx *= agg::trans_affine_translation(-initial_width()/2, -initial_height()/2); src_mtx *= agg::trans_affine_rotation(10.0 * agg::pi / 180.0); src_mtx *= agg::trans_affine_translation(initial_width()/2, initial_height()/2); src_mtx *= trans_affine_resizing(); agg::trans_affine img_mtx = src_mtx; img_mtx.invert(); typedef agg::span_allocator<agg::rgba8> span_alloc; unsigned i; unsigned char brightness_alpha_array[agg::span_conv_brightness_alpha_rgb8::array_size]; for(i = 0; i < agg::span_conv_brightness_alpha_rgb8::array_size; i++) { brightness_alpha_array[i] = agg::int8u(m_alpha.value(double(i) / double(agg::span_conv_brightness_alpha_rgb8::array_size)) * 255.0); } agg::span_conv_brightness_alpha_rgb8 color_alpha(brightness_alpha_array); typedef agg::image_accessor_clip<pixfmt> img_source_type; typedef agg::span_interpolator_linear<> interpolator_type; typedef agg::span_image_filter_rgb_bilinear<img_source_type, interpolator_type> span_gen; typedef agg::span_converter<span_gen, agg::span_conv_brightness_alpha_rgb8> span_conv; span_alloc sa; interpolator_type interpolator(img_mtx); pixfmt img_pixf(rbuf_img(0)); img_source_type img_src(img_pixf, agg::rgba(0,0,0,0)); span_gen sg(img_src, interpolator); span_conv sc(sg, color_alpha); agg::ellipse ell; agg::rasterizer_scanline_aa<> ras; agg::scanline_u8 sl; for(i = 0; i < 50; i++) { ell.init(m_x[i], m_y[i], m_rx[i], m_ry[i], 50); ras.add_path(ell); agg::render_scanlines_aa_solid(ras, sl, rb, m_colors[i]); } ell.init(initial_width() / 2.0, initial_height() / 2.0, initial_width() / 1.9, initial_height() / 1.9, 200); agg::conv_transform<agg::ellipse> tr(ell, src_mtx); ras.add_path(tr); agg::render_scanlines_aa(ras, sl, rb, sa, sc); agg::render_ctrl(ras, sl, rb, m_alpha); }
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); }
//------------------------------------------------------------------------ virtual void on_draw() { double width = rbuf_window().width(); double height = rbuf_window().height(); typedef agg::renderer_base<pixfmt> renderer_base; typedef agg::renderer_base<pixfmt_pre> renderer_base_pre; pixfmt pixf(rbuf_window()); pixfmt_pre pixf_pre(rbuf_window()); renderer_base rb(pixf); renderer_base_pre rb_pre(pixf_pre); rb.clear(agg::rgba(1.0, 1.0, 1.0)); agg::trans_affine polygon_mtx; polygon_mtx *= agg::trans_affine_translation(-m_polygon_cx, -m_polygon_cy); polygon_mtx *= agg::trans_affine_rotation(m_polygon_angle.value() * agg::pi / 180.0); polygon_mtx *= agg::trans_affine_scaling(m_polygon_scale.value()); polygon_mtx *= agg::trans_affine_translation(m_polygon_cx, m_polygon_cy); double r = initial_width() / 3.0 - 8.0; create_star(m_polygon_cx, m_polygon_cy, r, r / 1.45, 14); agg::conv_transform<agg::path_storage> tr(m_ps, polygon_mtx); typedef agg::wrap_mode_reflect_auto_pow2 wrap_x_type; typedef agg::wrap_mode_reflect_auto_pow2 wrap_y_type; typedef agg::image_accessor_wrap<pixfmt, wrap_x_type, wrap_y_type> img_source_type; typedef agg::span_pattern_rgba<img_source_type> span_gen_type; unsigned offset_x = 0; unsigned offset_y = 0; if(m_tie_pattern.status()) { offset_x = unsigned(width-m_polygon_cx); offset_y = unsigned(height-m_polygon_cy); } agg::span_allocator<color_type> sa; pixfmt img_pixf(m_pattern_rbuf); img_source_type img_src(img_pixf); span_gen_type sg(img_src, offset_x, offset_y); // Alpha is meaningful for RGB only because RGBA has its own sg.alpha(span_gen_type::value_type(m_pattern_alpha.value() * 255.0)); m_ras.add_path(tr); agg::render_scanlines_aa(m_ras, m_sl, rb_pre, sa, sg); agg::render_ctrl(m_ras, m_sl, rb, m_polygon_angle); agg::render_ctrl(m_ras, m_sl, rb, m_polygon_scale); agg::render_ctrl(m_ras, m_sl, rb, m_pattern_angle); agg::render_ctrl(m_ras, m_sl, rb, m_pattern_size); agg::render_ctrl(m_ras, m_sl, rb, m_pattern_alpha); agg::render_ctrl(m_ras, m_sl, rb, m_rotate_polygon); agg::render_ctrl(m_ras, m_sl, rb, m_rotate_pattern); agg::render_ctrl(m_ras, m_sl, rb, m_tie_pattern); }
virtual void on_draw() { pixfmt pixf(rbuf_window()); pixfmt_pre pixf_pre(rbuf_window()); renderer_base rb(pixf); renderer_base_pre rb_pre(pixf_pre); if(!m_test_flag) { rb.clear(agg::rgba(1, 1, 1)); } if(m_trans_type.cur_item() == 0) { // For the affine parallelogram transformations we // calculate the 4-th (implicit) point of the parallelogram m_quad.xn(3) = m_quad.xn(0) + (m_quad.xn(2) - m_quad.xn(1)); m_quad.yn(3) = m_quad.yn(0) + (m_quad.yn(2) - m_quad.yn(1)); } if(!m_test_flag) { //-------------------------- // Render the "quad" tool and controls g_rasterizer.add_path(m_quad); agg::render_scanlines_aa_solid(g_rasterizer, g_scanline, rb, agg::rgba(0, 0.3, 0.5, 0.6)); //-------------------------- agg::render_ctrl(g_rasterizer, g_scanline, rb, m_trans_type); } // Prepare the polygon to rasterize. Here we need to fill // the destination (transformed) polygon. g_rasterizer.clip_box(0, 0, width(), height()); g_rasterizer.reset(); g_rasterizer.move_to_d(m_quad.xn(0), m_quad.yn(0)); g_rasterizer.line_to_d(m_quad.xn(1), m_quad.yn(1)); g_rasterizer.line_to_d(m_quad.xn(2), m_quad.yn(2)); g_rasterizer.line_to_d(m_quad.xn(3), m_quad.yn(3)); typedef agg::span_allocator<color_type> span_alloc_type; span_alloc_type sa; agg::image_filter<agg::image_filter_hanning> filter; typedef agg::wrap_mode_reflect_auto_pow2 remainder_type; typedef agg::image_accessor_wrap<pixfmt, remainder_type, remainder_type> img_source_type; pixfmt img_pixf(rbuf_img(0)); img_source_type img_src(img_pixf); enum subdiv_shift_e { subdiv_shift = 2 }; switch(m_trans_type.cur_item()) { case 0: { // Note that we consruct an affine matrix that transforms // a parallelogram to a rectangle, i.e., it's inverted. // It's actually the same as: // tr(g_x1, g_y1, g_x2, g_y2, m_triangle.polygon()); // tr.invert(); agg::trans_affine tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2); // Also note that we can use the linear interpolator instead of // arbitrary span_interpolator_trans. It works much faster, // but the transformations must be linear and parellel. typedef agg::span_interpolator_linear<agg::trans_affine> interpolator_type; interpolator_type interpolator(tr); typedef span_image_filter_2x2<img_source_type, interpolator_type> span_gen_type; span_gen_type sg(img_src, interpolator, filter); agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg); break; } case 1: { agg::trans_bilinear tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2); if(tr.is_valid()) { typedef agg::span_interpolator_linear<agg::trans_bilinear> interpolator_type; interpolator_type interpolator(tr); typedef span_image_filter_2x2<img_source_type, interpolator_type> span_gen_type; span_gen_type sg(img_src, interpolator, filter); agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg); } break; } case 2: { agg::trans_perspective tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2); if(tr.is_valid()) { typedef agg::span_interpolator_linear_subdiv<agg::trans_perspective, 8> interpolator_type; interpolator_type interpolator(tr); typedef span_image_filter_2x2<img_source_type, interpolator_type> span_gen_type; span_gen_type sg(img_src, interpolator, filter); agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg); } break; } } }
virtual void on_draw() { double img_width = rbuf_img(0).width(); double img_height = rbuf_img(0).height(); typedef agg::pixfmt_bgr24 pixfmt; typedef agg::renderer_base<pixfmt> renderer_base; pixfmt pixf(rbuf_window()); pixfmt img_pixf(rbuf_img(0)); renderer_base rb(pixf); rb.clear(agg::rgba(1.0, 1.0, 1.0)); agg::trans_affine src_mtx; src_mtx *= agg::trans_affine_translation(-img_width/2, -img_height/2); src_mtx *= agg::trans_affine_rotation(m_angle.value() * agg::pi / 180.0); src_mtx *= agg::trans_affine_translation(img_width/2 + 10, img_height/2 + 10 + 40); src_mtx *= trans_affine_resizing(); agg::trans_affine img_mtx; img_mtx *= agg::trans_affine_translation(-img_width/2, -img_height/2); img_mtx *= agg::trans_affine_rotation(m_angle.value() * agg::pi / 180.0); img_mtx *= agg::trans_affine_scaling(m_scale.value()); img_mtx *= agg::trans_affine_translation(img_width/2 + 10, img_height/2 + 10 + 40); img_mtx *= trans_affine_resizing(); img_mtx.invert(); typedef agg::span_allocator<agg::rgba8> span_alloc_type; span_alloc_type sa; typedef agg::span_interpolator_adaptor<agg::span_interpolator_linear<>, periodic_distortion> interpolator_type; periodic_distortion* dist = 0; distortion_wave dist_wave; distortion_swirl dist_swirl; distortion_wave_swirl dist_wave_swirl; distortion_swirl_wave dist_swirl_wave; switch(m_distortion.cur_item()) { case 0: dist = &dist_wave; break; case 1: dist = &dist_swirl; break; case 2: dist = &dist_wave_swirl; break; case 3: dist = &dist_swirl_wave; break; } dist->period(m_period.value()); dist->amplitude(m_amplitude.value()); dist->phase(m_phase); double cx = m_center_x; double cy = m_center_y; img_mtx.transform(&cx, &cy); dist->center(cx, cy); interpolator_type interpolator(img_mtx, *dist); typedef agg::image_accessor_clip<pixfmt> img_source_type; img_source_type img_src(img_pixf, agg::rgba(1,1,1)); /* // Version without filtering (nearest neighbor) //------------------------------------------ typedef agg::span_image_filter_rgb_nn<img_source_type, interpolator_type> span_gen_type; span_gen_type sg(img_src, interpolator); //------------------------------------------ */ // Version with "hardcoded" bilinear filter and without // image_accessor (direct filter, the old variant) //------------------------------------------ typedef agg::span_image_filter_rgb_bilinear_clip<pixfmt, interpolator_type> span_gen_type; span_gen_type sg(img_pixf, agg::rgba(1,1,1), interpolator); //------------------------------------------ /* // Version with arbitrary 2x2 filter //------------------------------------------ typedef agg::span_image_filter_rgb_2x2<img_source_type, interpolator_type> span_gen_type; agg::image_filter<agg::image_filter_kaiser> filter; span_gen_type sg(img_src, interpolator, filter); //------------------------------------------ */ /* // Version with arbitrary filter //------------------------------------------ typedef agg::span_image_filter_rgb<img_source_type, interpolator_type> span_gen_type; agg::image_filter<agg::image_filter_spline36> filter; span_gen_type sg(img_src, interpolator, filter); //------------------------------------------ */ agg::rasterizer_scanline_aa<> ras; agg::scanline_u8 sl; double r = img_width; if(img_height < r) r = img_height; agg::ellipse ell(img_width / 2.0, img_height / 2.0, r / 2.0 - 20.0, r / 2.0 - 20.0, 200); agg::conv_transform<agg::ellipse> tr(ell, src_mtx); ras.add_path(tr); agg::render_scanlines_aa(ras, sl, rb, sa, sg); src_mtx *= ~trans_affine_resizing(); src_mtx *= agg::trans_affine_translation(img_width - img_width/10, 0.0); src_mtx *= trans_affine_resizing(); ras.add_path(tr); agg::render_scanlines_aa_solid(ras, sl, rb, agg::rgba8(0,0,0)); typedef agg::span_gradient<agg::rgba8, interpolator_type, agg::gradient_circle, color_array_type> gradient_span_gen; agg::gradient_circle gradient_function; color_array_type gradient_colors(m_gradient_colors); gradient_span_gen span_gradient(interpolator, gradient_function, gradient_colors, 0, 180); agg::trans_affine gr1_mtx; gr1_mtx *= agg::trans_affine_translation(-img_width/2, -img_height/2); gr1_mtx *= agg::trans_affine_scaling(0.8); gr1_mtx *= agg::trans_affine_rotation(m_angle.value() * agg::pi / 180.0); gr1_mtx *= agg::trans_affine_translation(img_width - img_width/10 + img_width/2 + 10, img_height/2 + 10 + 40); gr1_mtx *= trans_affine_resizing(); agg::trans_affine gr2_mtx; gr2_mtx *= agg::trans_affine_rotation(m_angle.value() * agg::pi / 180.0); gr2_mtx *= agg::trans_affine_scaling(m_scale.value()); gr2_mtx *= agg::trans_affine_translation(img_width - img_width/10 + img_width/2 + 10 + 50, img_height/2 + 10 + 40 + 50); gr2_mtx *= trans_affine_resizing(); gr2_mtx.invert(); cx = m_center_x + img_width - img_width/10; cy = m_center_y; gr2_mtx.transform(&cx, &cy); dist->center(cx, cy); interpolator.transformer(gr2_mtx); agg::conv_transform<agg::ellipse> tr2(ell, gr1_mtx); ras.add_path(tr2); agg::render_scanlines_aa(ras, sl, rb, sa, span_gradient); agg::render_ctrl(ras, sl, rb, m_angle); agg::render_ctrl(ras, sl, rb, m_scale); agg::render_ctrl(ras, sl, rb, m_amplitude); agg::render_ctrl(ras, sl, rb, m_period); agg::render_ctrl(ras, sl, rb, m_distortion); }
void operator() (marker_svg const& marker) { agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_); auto image_transform = get_optional<transform_type>(sym_, keys::image_transform); if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform); mapnik::box2d<double> const& bbox_image = marker.get_data()->bounding_box() * image_tr; mapnik::image_rgba8 image(bbox_image.width(), bbox_image.height()); render_pattern<buffer_type>(*ras_ptr_, marker, image_tr, 1.0, image); 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_); box2d<double> clip_box = clipping_extent(common_); 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); 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); pattern_alignment_enum alignment = get<pattern_alignment_enum, keys::alignment>(sym_, feature_, common_.vars_); unsigned offset_x=0; unsigned offset_y=0; if (alignment == LOCAL_ALIGNMENT) { double x0 = 0; double y0 = 0; using apply_local_alignment = detail::apply_local_alignment; apply_local_alignment apply(common_.t_,prj_trans_, clip_box, x0, y0); util::apply_visitor(geometry::vertex_processor<apply_local_alignment>(apply), feature_.get_geometry()); offset_x = unsigned(current_buffer_->width() - x0); offset_y = unsigned(current_buffer_->height() - y0); } 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); }
void agg_renderer<T>::process(polygon_pattern_symbolizer const& sym, Feature const& feature, proj_transform const& prj_trans) { typedef coord_transform2<CoordTransform,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(); switch (sym.get_gamma_method()) { case GAMMA_POWER: ras_ptr->gamma(agg::gamma_power(sym.get_gamma())); break; case GAMMA_LINEAR: ras_ptr->gamma(agg::gamma_linear(0.0, sym.get_gamma())); break; case GAMMA_NONE: ras_ptr->gamma(agg::gamma_none()); break; case GAMMA_THRESHOLD: ras_ptr->gamma(agg::gamma_threshold(sym.get_gamma())); break; case GAMMA_MULTIPLY: ras_ptr->gamma(agg::gamma_multiply(sym.get_gamma())); break; default: ras_ptr->gamma(agg::gamma_power(sym.get_gamma())); } 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 || !(*marker)->is_bitmap()) 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) { path_type path(t_,feature.get_geometry(0),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 const& geom = feature.get_geometry(i); if (geom.num_points() > 2) { path_type path(t_,geom,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 scale_image_agg(Image & target, Image const& source, scaling_method_e scaling_method, double image_ratio, double x_off_f, double y_off_f, double filter_radius, double ratio) { // "the image filters should work namely in the premultiplied color space" // http://old.nabble.com/Re:--AGG--Basic-image-transformations-p1110665.html // "Yes, you need to use premultiplied images only. Only in this case the simple weighted averaging works correctly in the image fitering." // http://permalink.gmane.org/gmane.comp.graphics.agg/3443 typedef agg::pixfmt_rgba32_pre pixfmt_pre; typedef agg::renderer_base<pixfmt_pre> renderer_base_pre; // define some stuff we'll use soon agg::rasterizer_scanline_aa<> ras; agg::scanline_u8 sl; agg::span_allocator<agg::rgba8> sa; agg::image_filter_lut filter; // initialize source AGG buffer agg::rendering_buffer rbuf_src((unsigned char*)source.getBytes(), source.width(), source.height(), source.width() * 4); pixfmt_pre pixf_src(rbuf_src); typedef agg::image_accessor_clone<pixfmt_pre> img_src_type; img_src_type img_src(pixf_src); // initialize destination AGG buffer (with transparency) agg::rendering_buffer rbuf_dst((unsigned char*)target.getBytes(), target.width(), target.height(), target.width() * 4); pixfmt_pre pixf_dst(rbuf_dst); renderer_base_pre rb_dst_pre(pixf_dst); rb_dst_pre.clear(agg::rgba(0, 0, 0, 0)); // create a scaling matrix agg::trans_affine img_mtx; img_mtx /= agg::trans_affine_scaling(image_ratio * ratio, image_ratio * ratio); // create a linear interpolator for our scaling matrix typedef agg::span_interpolator_linear<> interpolator_type; interpolator_type interpolator(img_mtx); // draw an anticlockwise polygon to render our image into double scaled_width = target.width(); double scaled_height = target.height(); ras.reset(); ras.move_to_d(x_off_f, y_off_f); ras.line_to_d(x_off_f + scaled_width, y_off_f); ras.line_to_d(x_off_f + scaled_width, y_off_f + scaled_height); ras.line_to_d(x_off_f, y_off_f + scaled_height); switch(scaling_method) { case SCALING_NEAR: { typedef agg::span_image_filter_rgba_nn<img_src_type, interpolator_type> span_gen_type; span_gen_type sg(img_src, interpolator); agg::render_scanlines_aa(ras, sl, rb_dst_pre, sa, sg); return; } case SCALING_BILINEAR: case SCALING_BILINEAR8: filter.calculate(agg::image_filter_bilinear(), true); break; case SCALING_BICUBIC: filter.calculate(agg::image_filter_bicubic(), true); break; case SCALING_SPLINE16: filter.calculate(agg::image_filter_spline16(), true); break; case SCALING_SPLINE36: filter.calculate(agg::image_filter_spline36(), true); break; case SCALING_HANNING: filter.calculate(agg::image_filter_hanning(), true); break; case SCALING_HAMMING: filter.calculate(agg::image_filter_hamming(), true); break; case SCALING_HERMITE: filter.calculate(agg::image_filter_hermite(), true); break; case SCALING_KAISER: filter.calculate(agg::image_filter_kaiser(), true); break; case SCALING_QUADRIC: filter.calculate(agg::image_filter_quadric(), true); break; case SCALING_CATROM: filter.calculate(agg::image_filter_catrom(), true); break; case SCALING_GAUSSIAN: filter.calculate(agg::image_filter_gaussian(), true); break; case SCALING_BESSEL: filter.calculate(agg::image_filter_bessel(), true); break; case SCALING_MITCHELL: filter.calculate(agg::image_filter_mitchell(), true); break; case SCALING_SINC: filter.calculate(agg::image_filter_sinc(filter_radius), true); break; case SCALING_LANCZOS: filter.calculate(agg::image_filter_lanczos(filter_radius), true); break; case SCALING_BLACKMAN: filter.calculate(agg::image_filter_blackman(filter_radius), true); break; } // details on various resampling considerations // http://old.nabble.com/Re%3A-Newbie---texture-p5057255.html // high quality resampler //typedef agg::span_image_resample_rgba_affine<img_src_type> span_gen_type; // faster, lower quality //typedef agg::span_image_filter_rgba<img_src_type,interpolator_type> span_gen_type; // local, modified agg::span_image_resample_rgba_affine // not convinced we need this // https://github.com/mapnik/mapnik/issues/1489 typedef mapnik::span_image_resample_rgba_affine<img_src_type> span_gen_type; span_gen_type sg(img_src, interpolator, filter); agg::render_scanlines_aa(ras, sl, rb_dst_pre, sa, sg); }
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_); std::shared_ptr<mapnik::marker const> marker = marker_cache::instance().find(filename, true); if (marker->is<marker_null>()) { return; } 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; } using vertex_converter_type = vertex_converter<transform2_tag, clip_poly_tag, transform_tag, affine_transform_tag, simplify_tag, smooth_tag>; using pattern_type = agg_polygon_pattern<vertex_converter_type>; common_pattern_process_visitor visitor(common_, sym, feature); image_rgba8 image(util::apply_visitor(visitor, *marker)); 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 (pattern.clip_ && !pattern.prj_trans_.equal()) { pattern.converter_.template set<transform2_tag>(); } else { pattern.converter_.template set<transform_tag>(); } if (pattern.clip_) pattern.converter_.set<clip_poly_tag>(); ras_ptr->filling_rule(agg::fill_even_odd); pattern.render(renb, *ras_ptr); }