void draw_polyline(Rasterizer& ras, Renderer& ren, const double* polyline, int num_points) { agg::poly_plain_adaptor<double> vs(polyline, num_points, m_line1.close()); agg::conv_transform<agg::poly_plain_adaptor<double> > trans(vs, m_scale); ras.add_path(trans); }
void draw_curve(Pattern& patt, Rasterizer& ras, Renderer& ren, PatternSource& src, VertexSource& vs) { patt.create(src); ren.scale_x(m_scale_x.value()); ren.start_x(m_start_x.value()); ras.add_path(vs); }
unsigned render_sbool(Rasterizer& ras1, Rasterizer& ras2) { pixfmt pf(rbuf_window()); agg::renderer_base<pixfmt> rb(pf); agg::renderer_scanline_aa_solid<agg::renderer_base<pixfmt> > ren(rb); agg::scanline_p8 sl; ras1.filling_rule(m_fill_rule.cur_item() ? agg::fill_non_zero : agg::fill_even_odd); ras2.filling_rule(m_fill_rule.cur_item() ? agg::fill_non_zero : agg::fill_even_odd); switch(m_polygons.cur_item()) { case 0: { //------------------------------------ // Two simple paths // agg::path_storage ps1; agg::path_storage ps2; double x = m_x - initial_width()/2 + 100; double y = m_y - initial_height()/2 + 100; ps1.move_to(x+140, y+145); ps1.line_to(x+225, y+44); ps1.line_to(x+296, y+219); ps1.close_polygon(); ps1.line_to(x+226, y+289); ps1.line_to(x+82, y+292); ps1.move_to(x+220, y+222); ps1.line_to(x+363, y+249); ps1.line_to(x+265, y+331); ps1.move_to(x+242, y+243); ps1.line_to(x+325, y+261); ps1.line_to(x+268, y+309); ps1.move_to(x+259, y+259); ps1.line_to(x+273, y+288); ps1.line_to(x+298, y+266); ps2.move_to(100+32, 100+77); ps2.line_to(100+473, 100+263); ps2.line_to(100+351, 100+290); ps2.line_to(100+354, 100+374); ras1.reset(); ras1.add_path(ps1); ren.color(agg::rgba(0, 0, 0, 0.1)); agg::render_scanlines(ras1, sl, ren); ras2.reset(); ras2.add_path(ps2); ren.color(agg::rgba(0, 0.6, 0, 0.1)); agg::render_scanlines(ras2, sl, ren); render_scanline_boolean(ras1, ras2); } break; case 1: { //------------------------------------ // Closed stroke // agg::path_storage ps1; agg::path_storage ps2; agg::conv_stroke<agg::path_storage> stroke(ps2); stroke.width(15.0); double x = m_x - initial_width()/2 + 100; double y = m_y - initial_height()/2 + 100; ps1.move_to(x+140, y+145); ps1.line_to(x+225, y+44); ps1.line_to(x+296, y+219); ps1.close_polygon(); ps1.line_to(x+226, y+289); ps1.line_to(x+82, y+292); ps1.move_to(x+220-50, y+222); ps1.line_to(x+363-50, y+249); ps1.line_to(x+265-50, y+331); ps1.close_polygon(); ps2.move_to(100+32, 100+77); ps2.line_to(100+473, 100+263); ps2.line_to(100+351, 100+290); ps2.line_to(100+354, 100+374); ps2.close_polygon(); ras1.reset(); ras1.add_path(ps1); ren.color(agg::rgba(0, 0, 0, 0.1)); agg::render_scanlines(ras1, sl, ren); ras2.reset(); ras2.add_path(stroke); ren.color(agg::rgba(0, 0.6, 0, 0.1)); agg::render_scanlines(ras2, sl, ren); render_scanline_boolean(ras1, ras2); } break; case 2: { //------------------------------------ // Great Britain and Arrows // agg::path_storage gb_poly; agg::path_storage arrows; make_gb_poly(gb_poly); make_arrows(arrows); agg::trans_affine mtx1; agg::trans_affine mtx2; mtx1 *= agg::trans_affine_translation(-1150, -1150); mtx1 *= agg::trans_affine_scaling(2.0); mtx2 = mtx1; mtx2 *= agg::trans_affine_translation(m_x - initial_width()/2, m_y - initial_height()/2); agg::conv_transform<agg::path_storage> trans_gb_poly(gb_poly, mtx1); agg::conv_transform<agg::path_storage> trans_arrows(arrows, mtx2); ras2.add_path(trans_gb_poly); ren.color(agg::rgba(0.5, 0.5, 0, 0.1)); agg::render_scanlines(ras2, sl, ren); agg::conv_stroke<agg::conv_transform<agg::path_storage> > stroke_gb_poly(trans_gb_poly); stroke_gb_poly.width(0.1); ras1.add_path(stroke_gb_poly); ren.color(agg::rgba(0, 0, 0)); agg::render_scanlines(ras1, sl, ren); ras2.add_path(trans_arrows); ren.color(agg::rgba(0.0, 0.5, 0.5, 0.1)); agg::render_scanlines(ras2, sl, ren); ras1.reset(); ras1.add_path(trans_gb_poly); render_scanline_boolean(ras1, ras2); } break; case 3: { //------------------------------------ // Great Britain and a Spiral // spiral sp(m_x, m_y, 10, 150, 30, 0.0); agg::conv_stroke<spiral> stroke(sp); stroke.width(15.0); agg::path_storage gb_poly; make_gb_poly(gb_poly); agg::trans_affine mtx; mtx *= agg::trans_affine_translation(-1150, -1150); mtx *= agg::trans_affine_scaling(2.0); mtx *= trans_affine_resizing(); agg::conv_transform<agg::path_storage> trans_gb_poly(gb_poly, mtx); ras1.add_path(trans_gb_poly); ren.color(agg::rgba(0.5, 0.5, 0, 0.1)); agg::render_scanlines(ras1, sl, ren); agg::conv_stroke<agg::conv_transform<agg::path_storage> > stroke_gb_poly(trans_gb_poly); stroke_gb_poly.width(0.1); ras1.reset(); ras1.add_path(stroke_gb_poly); ren.color(agg::rgba(0, 0, 0)); agg::render_scanlines(ras1, sl, ren); ras2.reset(); ras2.add_path(stroke); ren.color(agg::rgba(0.0, 0.5, 0.5, 0.1)); agg::render_scanlines(ras2, sl, ren); ras1.reset(); ras1.add_path(trans_gb_poly); render_scanline_boolean(ras1, ras2); } break; case 4: { //------------------------------------ // Spiral and glyph // spiral sp(m_x, m_y, 10, 150, 30, 0.0); agg::conv_stroke<spiral> stroke(sp); stroke.width(15.0); agg::path_storage glyph; glyph.move_to(28.47, 6.45); glyph.curve3(21.58, 1.12, 19.82, 0.29); glyph.curve3(17.19, -0.93, 14.21, -0.93); glyph.curve3(9.57, -0.93, 6.57, 2.25); glyph.curve3(3.56, 5.42, 3.56, 10.60); glyph.curve3(3.56, 13.87, 5.03, 16.26); glyph.curve3(7.03, 19.58, 11.99, 22.51); glyph.curve3(16.94, 25.44, 28.47, 29.64); glyph.line_to(28.47, 31.40); glyph.curve3(28.47, 38.09, 26.34, 40.58); glyph.curve3(24.22, 43.07, 20.17, 43.07); glyph.curve3(17.09, 43.07, 15.28, 41.41); glyph.curve3(13.43, 39.75, 13.43, 37.60); glyph.line_to(13.53, 34.77); glyph.curve3(13.53, 32.52, 12.38, 31.30); glyph.curve3(11.23, 30.08, 9.38, 30.08); glyph.curve3(7.57, 30.08, 6.42, 31.35); glyph.curve3(5.27, 32.62, 5.27, 34.81); glyph.curve3(5.27, 39.01, 9.57, 42.53); glyph.curve3(13.87, 46.04, 21.63, 46.04); glyph.curve3(27.59, 46.04, 31.40, 44.04); glyph.curve3(34.28, 42.53, 35.64, 39.31); glyph.curve3(36.52, 37.21, 36.52, 30.71); glyph.line_to(36.52, 15.53); glyph.curve3(36.52, 9.13, 36.77, 7.69); glyph.curve3(37.01, 6.25, 37.57, 5.76); glyph.curve3(38.13, 5.27, 38.87, 5.27); glyph.curve3(39.65, 5.27, 40.23, 5.62); glyph.curve3(41.26, 6.25, 44.19, 9.18); glyph.line_to(44.19, 6.45); glyph.curve3(38.72, -0.88, 33.74, -0.88); glyph.curve3(31.35, -0.88, 29.93, 0.78); glyph.curve3(28.52, 2.44, 28.47, 6.45); glyph.close_polygon(); glyph.move_to(28.47, 9.62); glyph.line_to(28.47, 26.66); glyph.curve3(21.09, 23.73, 18.95, 22.51); glyph.curve3(15.09, 20.36, 13.43, 18.02); glyph.curve3(11.77, 15.67, 11.77, 12.89); glyph.curve3(11.77, 9.38, 13.87, 7.06); glyph.curve3(15.97, 4.74, 18.70, 4.74); glyph.curve3(22.41, 4.74, 28.47, 9.62); glyph.close_polygon(); agg::trans_affine mtx; mtx *= agg::trans_affine_scaling(4.0); mtx *= agg::trans_affine_translation(220, 200); agg::conv_transform<agg::path_storage> trans(glyph, mtx); agg::conv_curve<agg::conv_transform<agg::path_storage> > curve(trans); ras1.reset(); ras1.add_path(stroke); ren.color(agg::rgba(0, 0, 0, 0.1)); agg::render_scanlines(ras1, sl, ren); ras2.reset(); ras2.add_path(curve); ren.color(agg::rgba(0, 0.6, 0, 0.1)); agg::render_scanlines(ras2, sl, ren); render_scanline_boolean(ras1, ras2); } break; } return 0; }
void render_scanline_boolean(Rasterizer& ras1, Rasterizer& ras2) { if(m_operation.cur_item() > 0) { agg::sbool_op_e op; switch(m_operation.cur_item()) { case 1: op = agg::sbool_or; break; case 2: op = agg::sbool_and; break; case 3: op = agg::sbool_xor; break; case 4: op = agg::sbool_xor_saddle;break; case 5: op = agg::sbool_a_minus_b; break; case 6: op = agg::sbool_b_minus_a; break; } typedef agg::renderer_base<pixfmt> renderer_base; pixfmt pixf(rbuf_window()); renderer_base rb(pixf); double t1 = 0.0; double t2 = 0.0; unsigned num_spans = 0; switch(m_scanline_type.cur_item()) { case 0: { typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid; typedef agg::scanline_p8 scanline_type; renderer_solid ren(rb); scanline_type sl; scanline_type sl1; scanline_type sl2; // The intermediate storage is used only to test the perfoprmance, // the short variant can be as follows: // ------------------------ // ren.color(agg::rgba(0.5, 0.0, 0, 0.5)); // agg::sbool_combine_shapes_aa(op, ras1, ras2, sl1, sl2, sl, ren); agg::scanline_storage_aa8 storage; agg::scanline_storage_aa8 storage1; agg::scanline_storage_aa8 storage2; agg::render_scanlines(ras1, sl, storage1); agg::render_scanlines(ras2, sl, storage2); start_timer(); for(int i = 0; i < 10; i++) { agg::sbool_combine_shapes_aa(op, storage1, storage2, sl1, sl2, sl, storage); } t1 = elapsed_time() / 10.0; start_timer(); ren.color(agg::rgba(0.5, 0.0, 0, 0.5)); agg::render_scanlines(storage, sl, ren); t2 = elapsed_time(); num_spans = count_spans(storage, sl); } break; case 1: { typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid; typedef agg::scanline_u8 scanline_type; renderer_solid ren(rb); scanline_type sl; scanline_type sl1; scanline_type sl2; agg::scanline_storage_aa8 storage; agg::scanline_storage_aa8 storage1; agg::scanline_storage_aa8 storage2; agg::render_scanlines(ras1, sl, storage1); agg::render_scanlines(ras2, sl, storage2); start_timer(); for(int i = 0; i < 10; i++) { agg::sbool_combine_shapes_aa(op, storage1, storage2, sl1, sl2, sl, storage); } t1 = elapsed_time() / 10.0; start_timer(); ren.color(agg::rgba(0.5, 0.0, 0, 0.5)); agg::render_scanlines(storage, sl, ren); t2 = elapsed_time(); num_spans = count_spans(storage, sl); } break; case 2: { typedef agg::renderer_scanline_bin_solid<renderer_base> renderer_solid; typedef agg::scanline_bin scanline_type; renderer_solid ren(rb); scanline_type sl; scanline_type sl1; scanline_type sl2; agg::scanline_storage_bin storage; agg::scanline_storage_bin storage1; agg::scanline_storage_bin storage2; agg::render_scanlines(ras1, sl, storage1); agg::render_scanlines(ras2, sl, storage2); start_timer(); for(int i = 0; i < 10; i++) { agg::sbool_combine_shapes_bin(op, storage1, storage2, sl1, sl2, sl, storage); } t1 = elapsed_time() / 10.0; start_timer(); ren.color(agg::rgba(0.5, 0.0, 0, 0.5)); agg::render_scanlines(storage, sl, ren); t2 = elapsed_time(); num_spans = count_spans(storage, sl); } break; } char buf[100]; sprintf(buf, "Combine=%.3fms\n\nRender=%.3fms\n\nnum_spans=%d", t1, t2, num_spans); agg::renderer_scanline_aa_solid<renderer_base> ren(rb); agg::scanline_p8 sl; agg::gsv_text txt; agg::conv_stroke<agg::gsv_text> txt_stroke(txt); txt_stroke.width(1.0); txt_stroke.line_cap(agg::round_cap); txt.size(8.0); txt.start_point(420, 40); txt.text(buf); ras1.add_path(txt_stroke); ren.color(agg::rgba(0.0, 0.0, 0.0)); agg::render_scanlines(ras1, sl, ren); } }
void render_id(Rasterizer& ras, Scanline& sl, Renderer& ren, int feature_id, agg::trans_affine const& mtx, double opacity, const box2d<double> &symbol_bbox) { using namespace agg; trans_affine transform; curved_stroked_trans_type curved_stroked_trans(curved_stroked_,transform); curved_trans_type curved_trans(curved_,transform); curved_trans_contour_type curved_trans_contour(curved_trans); curved_trans_contour.auto_detect_orientation(true); for(unsigned i = 0; i < attributes_.size(); ++i) { mapnik::svg::path_attributes const& attr = attributes_[i]; if (!attr.visibility_flag) continue; transform = attr.transform; double bx1,by1,bx2,by2; bounding_rect_single(curved_trans, attr.index, &bx1, &by1, &bx2, &by2); box2d<double> path_bbox(bx1,by1,bx2,by2); transform *= mtx; double scl = transform.scale(); //curved_.approximation_method(curve_inc); curved_.approximation_scale(scl); curved_.angle_tolerance(0.0); mapnik::gray16 color(feature_id); if (attr.fill_flag || attr.fill_gradient.get_gradient_type() != NO_GRADIENT) { ras.reset(); if(fabs(curved_trans_contour.width()) <= 1) { ras.add_path(curved_trans, attr.index); } else { curved_trans_contour.miter_limit(attr.miter_limit); ras.add_path(curved_trans_contour, attr.index); } ras.filling_rule(attr.even_odd_flag ? fill_even_odd : fill_non_zero); ScanlineRenderer ren_s(ren); ren_s.color(color); render_scanlines(ras, sl, ren_s); } if (attr.stroke_flag || attr.stroke_gradient.get_gradient_type() != NO_GRADIENT) { curved_stroked_.width(attr.stroke_width); //m_curved_stroked.line_join((attr.line_join == miter_join) ? miter_join_round : attr.line_join); curved_stroked_.line_join(attr.line_join); curved_stroked_.line_cap(attr.line_cap); curved_stroked_.miter_limit(attr.miter_limit); curved_stroked_.inner_join(inner_round); curved_stroked_.approximation_scale(scl); // If the *visual* line width is considerable we // turn on processing of curve cusps. //--------------------- if(attr.stroke_width * scl > 1.0) { curved_.angle_tolerance(0.2); } ras.reset(); ras.add_path(curved_stroked_trans, attr.index); ras.filling_rule(fill_non_zero); ScanlineRenderer ren_s(ren); ren_s.color(color); render_scanlines(ras, sl, ren_s); } } }
void render(Rasterizer& ras, Scanline& sl, Renderer& ren, agg::trans_affine const& mtx, double opacity, box2d<double> const& symbol_bbox) { using namespace agg; trans_affine transform; curved_stroked_trans_type curved_stroked_trans(curved_stroked_,transform); curved_trans_type curved_trans(curved_,transform); curved_trans_contour_type curved_trans_contour(curved_trans); curved_trans_contour.auto_detect_orientation(true); for(unsigned i = 0; i < attributes_.size(); ++i) { mapnik::svg::path_attributes const& attr = attributes_[i]; if (!attr.visibility_flag) continue; transform = attr.transform; transform *= mtx; double scl = transform.scale(); //curved_.approximation_method(curve_inc); curved_.approximation_scale(scl); curved_.angle_tolerance(0.0); typename PixelFormat::color_type color; if (attr.fill_flag || attr.fill_gradient.get_gradient_type() != NO_GRADIENT) { ras.reset(); // https://github.com/mapnik/mapnik/issues/1129 if(std::fabs(curved_trans_contour.width()) <= 1) { ras.add_path(curved_trans, attr.index); } else { curved_trans_contour.miter_limit(attr.miter_limit); ras.add_path(curved_trans_contour, attr.index); } if(attr.fill_gradient.get_gradient_type() != NO_GRADIENT) { render_gradient(ras, sl, ren, attr.fill_gradient, transform, attr.fill_opacity * attr.opacity * opacity, symbol_bbox, curved_trans, attr.index); } else { ras.filling_rule(attr.even_odd_flag ? fill_even_odd : fill_non_zero); color = attr.fill_color; color.opacity(color.opacity() * attr.fill_opacity * attr.opacity * opacity); ScanlineRenderer ren_s(ren); color.premultiply(); ren_s.color(color); render_scanlines(ras, sl, ren_s); } } if (attr.stroke_flag || attr.stroke_gradient.get_gradient_type() != NO_GRADIENT) { curved_stroked_.width(attr.stroke_width); //m_curved_stroked.line_join((attr.line_join == miter_join) ? miter_join_round : attr.line_join); curved_stroked_.line_join(attr.line_join); curved_stroked_.line_cap(attr.line_cap); curved_stroked_.miter_limit(attr.miter_limit); curved_stroked_.inner_join(inner_round); curved_stroked_.approximation_scale(scl); // If the *visual* line width is considerable we // turn on processing of curve cusps. //--------------------- if(attr.stroke_width * scl > 1.0) { curved_.angle_tolerance(0.2); } ras.reset(); ras.add_path(curved_stroked_trans, attr.index); if(attr.stroke_gradient.get_gradient_type() != NO_GRADIENT) { render_gradient(ras, sl, ren, attr.stroke_gradient, transform, attr.stroke_opacity * attr.opacity * opacity, symbol_bbox, curved_trans, attr.index); } else { ras.filling_rule(fill_non_zero); color = attr.stroke_color; color.opacity(color.opacity() * attr.stroke_opacity * attr.opacity * opacity); ScanlineRenderer ren_s(ren); color.premultiply(); ren_s.color(color); render_scanlines(ras, sl, ren_s); } } } }