void render_raster_marker(RendererType ren, RasterizerType & ras, image_data_rgba8 & src, mapnik::feature_impl const& feature, agg::trans_affine const& marker_tr, double opacity) { using color_type = typename RendererType::color_type; agg::scanline_bin sl; double width = src.width(); double height = src.height(); double p[8]; p[0] = 0; p[1] = 0; p[2] = width; p[3] = 0; p[4] = width; p[5] = height; p[6] = 0; p[7] = height; marker_tr.transform(&p[0], &p[1]); marker_tr.transform(&p[2], &p[3]); marker_tr.transform(&p[4], &p[5]); marker_tr.transform(&p[6], &p[7]); ras.move_to_d(p[0],p[1]); ras.line_to_d(p[2],p[3]); ras.line_to_d(p[4],p[5]); ras.line_to_d(p[6],p[7]); ren.color(color_type(feature.id())); agg::render_scanlines(ras, sl, ren); }
void CAggMemoryDC::Rect( const GraphTypes::PointF& tl, const GraphTypes::PointF& br, const GraphTypes::Color& clrfill, const GraphTypes::Color& clroutline, GraphTypes::REAL outline_width/*=1.0*/, bool bAA/*=false*/) { if (m_buf==0) return; if(bAA) { PointF points[4]; points[0].x=tl.x; points[0].y=tl.y; points[1].x=br.x; points[1].y=tl.y; points[2].x=br.x; points[2].y=br.y; points[3].x=tl.x; points[3].y=br.y; SolidPolygon(points, clrfill, 4, outline_width, clroutline); } else { pixel_format pixf(m_rbuf); ren_base renb(pixf); primitive_renderer pren(renb); pren.fill_color(agg::rgba8( clrfill.GetR(), clrfill.GetG(), clrfill.GetB(), clrfill.GetA())); pren.line_color(agg::rgba8( clroutline.GetR(), clroutline.GetG(), clroutline.GetB(), clroutline.GetA())); double topx(tl.x), topy(tl.y), bottomx(br.x), bottomy(br.y); m_mtx.transform(&topx,&topy); m_mtx.transform(&bottomx,&bottomy); int x1=round_int(topx); int y1=round_int(topy); int x2=round_int(bottomx); int y2=round_int(bottomy); pren.solid_rectangle(x1, y1, x2, y2); pren.rectangle(x1, y1, x2, y2); } }
void on_mouse_button_down(int x, int y, unsigned flags) { if(flags & 1) { double xd = x; double yd = y; double r = 4.0 / m_scale.scale(); m_scale.inverse_transform(&xd, &yd); m_point_idx = m_shape.hit_test(xd, yd, r); force_redraw(); } }
box2d<T>::box2d(const box2d_type &rhs, const agg::trans_affine& tr) { double x0 = rhs.minx_, y0 = rhs.miny_; double x1 = rhs.maxx_, y1 = rhs.miny_; double x2 = rhs.maxx_, y2 = rhs.maxy_; double x3 = rhs.minx_, y3 = rhs.maxy_; tr.transform(&x0, &y0); tr.transform(&x1, &y1); tr.transform(&x2, &y2); tr.transform(&x3, &y3); init(x0, y0, x2, y2); expand_to_include(x1, y1); expand_to_include(x3, y3); }
void CAggMemoryDC::Line( const PointF& p1, const PointF& p2, const Color& clr) { if (m_buf==0) return; CPoint _p1 = p1; CPoint _p2 = p2; pixel_format pixf(m_rbuf); ren_base renb(pixf); outline_renderer outline_rd(renb, s_lineprof); outline_rasterizer_aa outline_rt(outline_rd); outline_rd.profile(s_lineprof); outline_rd.color(agg::rgba8(clr.GetR(), clr.GetG(), clr.GetB(), clr.GetA())); outline_rd.clip_box(0, 0, m_rcUpdate.Width(), m_rcUpdate.Height()); double p1x(p1.x), p1y(p1.y), p2x(p2.x), p2y(p2.y); m_mtx.transform(&p1x,&p1y); m_mtx.transform(&p2x,&p2y); outline_rt.move_to_d(p1x, p1y); outline_rt.line_to_d(p2x, p2y); //outline_rt.round_cap( 1 ); outline_rt.render(false); }
bool only_translation(agg::trans_affine& mat, double epsilon) { double temp[6]; mat.store_to(temp); return (f_eq(temp[0], 1.0) && f_eq(temp[1], 0.0) && f_eq(temp[2], 0.0) && f_eq(temp[3], 1.0)); }
void get_translation(agg::trans_affine& m, double* tx, double* ty) { double temp[6]; m.store_to(temp); *tx = temp[4]; *ty = temp[5]; }
void cairo_context::add_image(agg::trans_affine const& tr, image_rgba8 const& data, double opacity) { cairo_pattern pattern(data); if (!tr.is_identity()) { double m[6]; tr.store_to(m); cairo_matrix_t cairo_matrix; cairo_matrix_init(&cairo_matrix,m[0],m[1],m[2],m[3],m[4],m[5]); cairo_matrix_invert(&cairo_matrix); pattern.set_matrix(cairo_matrix); } cairo_save(cairo_.get()); cairo_set_source(cairo_.get(), const_cast<cairo_pattern_t*>(pattern.pattern())); cairo_paint_with_alpha(cairo_.get(), opacity); cairo_restore(cairo_.get()); check_object_status_and_throw_exception(*this); }
void get_scale(agg::trans_affine& m, double* dx, double* dy) { { double temp[6]; m.store_to(temp); *dx = temp[0]; *dy = temp[3]; } }
void trans_affine_compose(agg::trans_affine& a, const agg::trans_affine& b) { double a_tx = a.tx, a_ty = a.ty; a.premultiply(b); a.tx = b.sx * a_tx + b.shx * a_ty + b.tx; a.ty = b.shy * a_tx + b.sy * a_ty + b.ty; }
bool is_identity(agg::trans_affine& mat, double epsilon) { double temp[6]; mat.store_to(temp); return (f_eq(temp[0], 1.0) && f_eq(temp[1], 0.0) && f_eq(temp[2], 0.0) && f_eq(temp[3], 1.0) && f_eq(temp[4], 0.0) && f_eq(temp[5], 0.0)); // return (temp[0] == 1.0 && temp[1] == 0.0 && // temp[2] == 0.0 && temp[3] == 1.0 && // temp[4] == 0.0 && temp[5] == 0.0); }
void render_raster_marker(agg::trans_affine const& marker_tr) { double width = src_.width(); double height = src_.height(); double p[8]; p[0] = 0; p[1] = 0; p[2] = width; p[3] = 0; p[4] = width; p[5] = height; p[6] = 0; p[7] = height; marker_tr.transform(&p[0], &p[1]); marker_tr.transform(&p[2], &p[3]); marker_tr.transform(&p[4], &p[5]); marker_tr.transform(&p[6], &p[7]); ras_.move_to_d(p[0],p[1]); ras_.line_to_d(p[2],p[3]); ras_.line_to_d(p[4],p[5]); ras_.line_to_d(p[6],p[7]); RendererType ren(renb_); ren.color(color_type(feature_.id())); agg::render_scanlines(ras_, sl_, ren); }
void render_raster_marker(agg::trans_affine const& marker_tr, double opacity) { double width = src_.width(); double height = src_.height(); double p[8]; p[0] = 0; p[1] = 0; p[2] = width; p[3] = 0; p[4] = width; p[5] = height; p[6] = 0; p[7] = height; marker_tr.transform(&p[0], &p[1]); marker_tr.transform(&p[2], &p[3]); marker_tr.transform(&p[4], &p[5]); marker_tr.transform(&p[6], &p[7]); ras_.move_to_d(p[0],p[1]); ras_.line_to_d(p[2],p[3]); ras_.line_to_d(p[4],p[5]); ras_.line_to_d(p[6],p[7]); agg::span_allocator<color_type> sa; agg::image_filter_bilinear filter_kernel; agg::image_filter_lut filter(filter_kernel, false); agg::rendering_buffer marker_buf((unsigned char *)src_.getBytes(), src_.width(), src_.height(), src_.width()*4); agg::pixfmt_rgba32_pre pixf(marker_buf); typedef agg::image_accessor_clone<agg::pixfmt_rgba32_pre> img_accessor_type; typedef agg::span_interpolator_linear<agg::trans_affine> interpolator_type; typedef agg::span_image_filter_rgba_2x2<img_accessor_type, interpolator_type> span_gen_type; typedef agg::renderer_scanline_aa_alpha<renderer_base, agg::span_allocator<color_type>, span_gen_type> renderer_type; img_accessor_type ia(pixf); interpolator_type interpolator(agg::trans_affine(p, 0, 0, width, height) ); span_gen_type sg(ia, interpolator, filter); renderer_type rp(renb_,sa, sg, unsigned(opacity*255)); agg::render_scanlines(ras_, sl_, rp); }
void pathAttr::apply(agg::path_storage* path, const agg::trans_affine& tr, double accuracy) { double scale = sqrt(fabs(tr.determinant())); if (mCommand == stroke) { if (mIsoWidthFlag) { trans.attach(*path); trans.transformer(tr); transCurvedStroked.width(mStrokeWidth * scale); transCurvedStroked.line_join(mLineJoin); transCurvedStroked.line_cap(mLineCap); transCurvedStroked.miter_limit(mMiterLimit); transCurvedStroked.inner_join(agg::inner_round); transCurvedStroked.approximation_scale(accuracy); transCurved.approximation_scale(accuracy); // If the *visual* line width is considerable we // turn on processing of curve cusps. //--------------------- if (mStrokeWidth * scale > 1.0) { transCurved.angle_tolerance(0.2); } else { transCurved.angle_tolerance(0.0); } } else { curved.attach(*path); curvedStrokedTrans.transformer(tr); curvedStroked.width(mStrokeWidth); curvedStroked.line_join(mLineJoin); curvedStroked.line_cap(mLineCap); curvedStroked.miter_limit(mMiterLimit); curvedStroked.inner_join(agg::inner_round); curvedStroked.approximation_scale(accuracy * scale); curved.approximation_scale(accuracy * scale); // If the *visual* line width is considerable we // turn on processing of curve cusps. //--------------------- if (mStrokeWidth * scale > 1.0) { curved.angle_tolerance(0.2); } else { curved.angle_tolerance(0.0); } } } else { trans.attach(*path); trans.transformer(tr); transCurved.approximation_scale(accuracy); } }
void on_mouse_move(int x, int y, unsigned flags) { if((flags & 1) == 0) { on_mouse_button_up(x, y, flags); } else { if(m_point_idx >= 0) { double xd = x; double yd = y; m_scale.inverse_transform(&xd, &yd); m_shape.modify_vertex(m_point_idx, xd, yd); force_redraw(); } } }
//----------------------------------------------------------------------------- int CAggMemoryDC::SetDIBitsToDevice( int x, int y, DWORD dwWidth, DWORD dwHeight, int xSrc, int ySrc, UINT uStartScan, UINT cScanLines, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse) { double dx = x; double dy = y; m_mtx.transform(&dx,&dy); return ::SetDIBitsToDevice(m_hDC, x, y, dwWidth, dwHeight, xSrc, ySrc, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse); }
Bounds::Bounds(const agg::trans_affine& trans, agg::path_storage* path, pathAttr* attr, double dilation, double scale) { double centx = attr->mCentroid.x; double centy = attr->mCentroid.y; trans.transform(¢x, ¢y); mValid = attr->boundingRect(path, trans, mMin_X, mMin_Y, mMax_X, mMax_Y, scale); if (mValid && mMin_X <= centx && mMax_X >= centx && mMin_Y <= centy && mMax_Y >= centy && dilation != 1.0) { mMin_X = dilation * (mMin_X - centx) + centx; mMax_X = dilation * (mMax_X - centx) + centx; mMin_Y = dilation * (mMin_Y - centy) + centy; mMax_Y = dilation * (mMax_Y - centy) + centy; } }
void SelectionScanlineSweeper::DrawImpl_rgb(agg::rect_d rect, RenderingData *data, unsigned int width, unsigned int height, int stride, agg::trans_affine const &mtx, agg::trans_affine const &viewport_mtx) { //ScanlineSource source(data); typedef agg::pixfmt_alpha_blend_rgb<agg::blender_rgb<agg::rgba8, agg::order_rgb>, agg::scanline_accessor> pixfmt_type; typedef pixfmt_type::color_type color_type; typedef color_type::value_type value_type; typedef agg::renderer_base<pixfmt_type> renderer_base; typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid; agg::rasterizer_scanline_aa<> l_rasterizer; agg::scanline_u8 l_scanline; //pixfmt_type pixfmt(agg::scanline_accessor(&source, ScanlineSource::get_scanline, width, height, stride)); pixfmt_type pixfmt((agg::scanline_accessor(data))); renderer_base rb(pixfmt); l_rasterizer.clip_box(0.0, 0.0, width, height); l_rasterizer.filling_rule(agg::fill_non_zero); if (flip_y) { mtx.transform(&rect.x1, &rect.y1); mtx.transform(&rect.x2, &rect.y2); } double vertexes[] = { rect.x1, rect.y2, rect.x1, rect.y1, rect.x2, rect.y1, rect.x2, rect.y2 }; agg::test_vertex_source vertex_source(vertexes, 4); agg::conv_transform<agg::test_vertex_source> vertex_source_converted(vertex_source, viewport_mtx); l_rasterizer.add_path(vertex_source_converted); renderer_solid r(rb); { r.color(color); agg::render_scanlines(l_rasterizer, l_scanline, r); } }
unsigned CAggMemoryDC::DrawScaledText( const TCHAR* text, const GraphTypes::RectF& rc, const GraphTypes::Color& clr, const char* font, int size, const PointF & descsubtract) { if (m_buf==0) return 0; unsigned len=0; pixel_format pixf(m_rbuf); ren_base renb(pixf); solid_renderer ren_solid(renb); ATLASSERT(m_buf); conv_font_curve_type fcurves(m_fonts->m_fman.path_adaptor()); conv_font_segm_type fsegm(fcurves); conv_font_trans_type ftrans(fsegm, m_mtx); // fsegm.approximation_scale(3.0); // fcurves.approximation_scale(2.0); m_fonts->m_feng.flip_y(true); m_fonts->m_feng.hinting(true); if(m_fonts->m_feng.create_font( font, agg::glyph_ren_outline, size, 0.0, FW_NORMAL, false, ANSI_CHARSET, DEFAULT_PITCH | FF_SWISS )) { double x = 0.0; double y = 0.0; const TCHAR* p = text; TEXTMETRIC tm; GetTextMetrics(&tm); //double descent=(tm.tmDescent>descsubtract.y)?(tm.tmDescent-descsubtract.y):(tm.tmDescent-1); //ATLASSERT(tm.tmDescent>descsubtract.y); //ATLASSERT(descent>0); //descent *= m_mtx.scale(); //m_mtx *= agg::trans_affine_translation(rc.x-m_rcUpdate.left, rc.y+rc.Height-descent-m_rcUpdate.top); double ascent=tm.tmAscent-descsubtract.y; ATLASSERT(ascent>0.0f); ascent *= m_mtx.scale(); m_mtx *= agg::trans_affine_translation(rc.x-m_rcUpdate.left, rc.y+ascent-m_rcUpdate.top); ren_solid.color(agg::rgba8(clr.GetR(), clr.GetG(), clr.GetB(), clr.GetA())); while(*p) { const agg::glyph_cache* glyph = m_fonts->m_fman.glyph(*p); if(glyph) { m_fonts->m_fman.add_kerning(&x, &y); m_fonts->m_fman.init_embedded_adaptors(glyph, x, y); if(glyph->data_type == agg::glyph_data_outline) { m_ras_aa.add_path(ftrans); } // increment pen position x += glyph->advance_x; y += glyph->advance_y; } ++p; ++len; } agg::render_scanlines(m_ras_aa, m_sl, ren_solid); ATLASSERT(m_buf); } return len; }
void render_raster_marker(agg::trans_affine const& marker_tr, double opacity) { using pixfmt_pre = agg::pixfmt_rgba32_pre; agg::scanline_u8 sl_; double width = src_.width(); double height = src_.height(); if (std::fabs(1.0 - scale_factor_) < 0.001 && (std::fabs(1.0 - marker_tr.sx) < agg::affine_epsilon) && (std::fabs(0.0 - marker_tr.shy) < agg::affine_epsilon) && (std::fabs(0.0 - marker_tr.shx) < agg::affine_epsilon) && (std::fabs(1.0 - marker_tr.sy) < agg::affine_epsilon)) { agg::rendering_buffer src_buffer((unsigned char *)src_.getBytes(),src_.width(),src_.height(),src_.width() * 4); pixfmt_pre pixf_mask(src_buffer); if (snap_to_pixels_) { renb_.blend_from(pixf_mask, 0, std::floor(marker_tr.tx + .5), std::floor(marker_tr.ty + .5), unsigned(255*opacity)); } else { renb_.blend_from(pixf_mask, 0, marker_tr.tx, marker_tr.ty, unsigned(255*opacity)); } } else { using img_accessor_type = agg::image_accessor_clone<pixfmt_pre>; using interpolator_type = agg::span_interpolator_linear<>; //using span_gen_type = agg::span_image_filter_rgba_2x2<img_accessor_type,interpolator_type>; using span_gen_type = agg::span_image_resample_rgba_affine<img_accessor_type>; using renderer_type = agg::renderer_scanline_aa_alpha<renderer_base, agg::span_allocator<color_type>, span_gen_type>; double p[8]; p[0] = 0; p[1] = 0; p[2] = width; p[3] = 0; p[4] = width; p[5] = height; p[6] = 0; p[7] = height; marker_tr.transform(&p[0], &p[1]); marker_tr.transform(&p[2], &p[3]); marker_tr.transform(&p[4], &p[5]); marker_tr.transform(&p[6], &p[7]); agg::span_allocator<color_type> sa; agg::image_filter_lut filter; filter.calculate(agg::image_filter_bilinear(), true); agg::rendering_buffer marker_buf((unsigned char *)src_.getBytes(), src_.width(), src_.height(), src_.width()*4); pixfmt_pre pixf(marker_buf); img_accessor_type ia(pixf); agg::trans_affine final_tr(p, 0, 0, width, height); if (snap_to_pixels_) { final_tr.tx = std::floor(final_tr.tx+.5); final_tr.ty = std::floor(final_tr.ty+.5); } interpolator_type interpolator(final_tr); span_gen_type sg(ia, interpolator, filter); renderer_type rp(renb_,sa, sg, unsigned(opacity*255)); ras_.move_to_d(p[0],p[1]); ras_.line_to_d(p[2],p[3]); ras_.line_to_d(p[4],p[5]); ras_.line_to_d(p[6],p[7]); agg::render_scanlines(ras_, sl_, rp); } }
bool CAggMemoryDC::DrawTransparent( HBITMAP hBitmap, int x, int y, int width, int height, int bmpWidth, int bmpHeight, COLORREF color) { ATLASSERT(width>0&&height>0); double dx = x; double dy = y; m_mtx.transform(&dx,&dy); CDC dcImage; bool bOk=dcImage.CreateCompatibleDC(m_hDC) != NULL; HBITMAP oldbmp=dcImage.SelectBitmap(hBitmap); // if OS supports non-leaky TransparentBlt use it (also on printer) if(s_bTransOk) { #ifndef _WIN32_WCE bOk=TransparentBlt(x, y, width, height, dcImage, 0, 0, bmpWidth, bmpHeight, color) != 0; if (!bOk) // just in case (e.g. printing), try emulation goto tryEmulate; #endif } else { tryEmulate: CBitmap bmpMono; bOk=bmpMono.CreateBitmap(width, height, 1, 1, NULL) != NULL; if (!bOk) return bOk; CDC dcMono; // Create dc for the mask bOk = dcMono.CreateCompatibleDC(m_hDC) != NULL; if (!bOk) return bOk; // Select the mask bitmap into its dc HBITMAP oldBitmapMono = (HBITMAP)::SelectObject(dcMono, bmpMono); if(bOk) { // Build mask based on transparent colour COLORREF crOldImg=dcImage.SetBkColor(color); bOk=dcMono.StretchBlt(0, 0, width, height, dcImage, 0, 0, bmpWidth, bmpHeight, SRCCOPY) != 0; dcImage.SetBkColor(crOldImg); // True Mask method - no flicker if destination is not actual display if(bOk) bOk=StretchBlt(x, y, width, height, dcImage, 0, 0, bmpWidth, bmpHeight, SRCINVERT) != 0; if(bOk) { // setup the destination for monochrome blit COLORREF crOldBack = SetBkColor(RGB(255,255,255)); COLORREF crOldText = SetTextColor(RGB(0,0,0)); bOk=BitBlt(x, y, width, height, dcMono, 0, 0, SRCAND) != 0; SetBkColor(crOldBack); SetTextColor(crOldText); } if(bOk) bOk=StretchBlt(x, y, width, height, dcImage, 0, 0, bmpWidth, bmpHeight, SRCINVERT) != 0; } dcMono.SelectBitmap(oldBitmapMono); } dcImage.SelectBitmap(oldbmp); return bOk; }
virtual void on_draw() { typedef agg::renderer_base<pixfmt_pre> renderer_base; typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_scanline; typedef agg::scanline_u8 scanline; pixfmt_pre pixf(rbuf_window()); renderer_base ren_base(pixf); ren_base.clear(agg::rgba(1.0, 1.0, 0.95)); renderer_scanline ren(ren_base); agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_dbl> ras; agg::scanline_u8 sl; agg::conv_transform<agg::compound_shape> shape(m_shape, m_scale); agg::conv_stroke<agg::conv_transform<agg::compound_shape> > stroke(shape); m_shape.approximation_scale(m_scale.scale()); unsigned i; agg::path_storage tmp_path; ras.clip_box(0, 0, width(), height()); // This is an alternative method of Flash rasterization. // We decompose the compound shape into separate paths // and select the ones that fit the given style (left or right). // So that, we form a sub-shape and draw it as a whole. // // Here the regular scanline rasterizer is used, but it doesn't // automatically close the polygons. So that, the rasterizer // actually works with a set of polylines instead of polygons. // Of course, the data integrity must be preserved, that is, // the polylines must eventually form a closed contour // (or a set of closed contours). So that, first we set // auto_close(false); // // The second important thing is that one path can be rasterized // twice, if it has both, left and right fill. Sometimes the // path has equal left and right fill, so that, the same path // will be added twice even for a single sub-shape. If the // rasterizer can tolerate these degenerates you can add them, // but it's also fine just to omit them. // // The third thing is that for one side (left or right) // you should invert the direction of the paths. // // The main disadvantage of this method is imperfect stitching // of the adjacent polygons. The problem can be solved if we use // compositing operation "plus" instead of alpha-blend. But // in this case we are forced to use an RGBA buffer, clean it with // zero, rasterize using "plus" operation, and then alpha-blend // the result over the final scene. It can be too expensive. //------------------------------------------------------------ ras.auto_close(false); //ras.filling_rule(agg::fill_even_odd); start_timer(); for(int s = m_shape.min_style(); s <= m_shape.max_style(); s++) { ras.reset(); for(i = 0; i < m_shape.paths(); i++) { const agg::path_style& style = m_shape.style(i); if(style.left_fill != style.right_fill) { if(style.left_fill == s) { ras.add_path(shape, style.path_id); } if(style.right_fill == s) { tmp_path.remove_all(); tmp_path.concat_path(shape, style.path_id); tmp_path.invert_polygon(0); ras.add_path(tmp_path); } } } agg::render_scanlines_aa_solid(ras, sl, ren_base, m_colors[s]); } double tfill = elapsed_time(); ras.auto_close(true); // Draw strokes //---------------------- start_timer(); stroke.width(sqrt(m_scale.scale())); stroke.line_join(agg::round_join); stroke.line_cap(agg::round_cap); for(i = 0; i < m_shape.paths(); i++) { ras.reset(); if(m_shape.style(i).line >= 0) { ras.add_path(stroke, m_shape.style(i).path_id); ren.color(agg::srgba8(0,0,0, 128)); agg::render_scanlines(ras, sl, ren); } } double tstroke = elapsed_time(); char buf[256]; agg::gsv_text t; t.size(8.0); t.flip(true); agg::conv_stroke<agg::gsv_text> ts(t); ts.width(1.6); ts.line_cap(agg::round_cap); sprintf(buf, "Fill=%.2fms (%dFPS) Stroke=%.2fms (%dFPS) Total=%.2fms (%dFPS)\n\n" "Space: Next Shape\n\n" "+/- : ZoomIn/ZoomOut (with respect to the mouse pointer)", tfill, int(1000.0 / tfill), tstroke, int(1000.0 / tstroke), tfill+tstroke, int(1000.0 / (tfill+tstroke))); t.start_point(10.0, 20.0); t.text(buf); ras.add_path(ts); ren.color(agg::rgba(0,0,0)); agg::render_scanlines(ras, sl, ren); }
void render_raster_marker(RendererType renb, RasterizerType & ras, image_rgba8 const& src, agg::trans_affine const& tr, double opacity, float scale_factor, bool snap_to_pixels) { using color_type = agg::rgba8; using const_rendering_buffer = util::rendering_buffer<image_rgba8>; using pixfmt_pre = agg::pixfmt_alpha_blend_rgba<agg::blender_rgba32_pre, const_rendering_buffer, agg::pixel32_type>; agg::scanline_u8 sl; double width = src.width(); double height = src.height(); if (std::fabs(1.0 - scale_factor) < 0.001 && (std::fabs(1.0 - tr.sx) < agg::affine_epsilon) && (std::fabs(0.0 - tr.shy) < agg::affine_epsilon) && (std::fabs(0.0 - tr.shx) < agg::affine_epsilon) && (std::fabs(1.0 - tr.sy) < agg::affine_epsilon)) { const_rendering_buffer src_buffer(src); pixfmt_pre pixf_mask(src_buffer); if (snap_to_pixels) { renb.blend_from(pixf_mask, 0, static_cast<int>(std::floor(tr.tx + .5)), static_cast<int>(std::floor(tr.ty + .5)), unsigned(255*opacity)); } else { renb.blend_from(pixf_mask, 0, static_cast<int>(tr.tx), static_cast<int>(tr.ty), unsigned(255*opacity)); } } else { using img_accessor_type = agg::image_accessor_clone<pixfmt_pre>; using interpolator_type = agg::span_interpolator_linear<>; //using span_gen_type = agg::span_image_filter_rgba_2x2<img_accessor_type,interpolator_type>; using span_gen_type = agg::span_image_resample_rgba_affine<img_accessor_type>; using renderer_type = agg::renderer_scanline_aa_alpha<RendererType, agg::span_allocator<color_type>, span_gen_type>; double p[8]; p[0] = 0; p[1] = 0; p[2] = width; p[3] = 0; p[4] = width; p[5] = height; p[6] = 0; p[7] = height; tr.transform(&p[0], &p[1]); tr.transform(&p[2], &p[3]); tr.transform(&p[4], &p[5]); tr.transform(&p[6], &p[7]); agg::span_allocator<color_type> sa; agg::image_filter_lut filter; filter.calculate(agg::image_filter_bilinear(), true); const_rendering_buffer src_buffer(src); pixfmt_pre pixf(src_buffer); img_accessor_type ia(pixf); agg::trans_affine final_tr(p, 0, 0, width, height); if (snap_to_pixels) { final_tr.tx = std::floor(final_tr.tx+.5); final_tr.ty = std::floor(final_tr.ty+.5); } interpolator_type interpolator(final_tr); span_gen_type sg(ia, interpolator, filter); renderer_type rp(renb, sa, sg, unsigned(opacity*255)); ras.move_to_d(p[0],p[1]); ras.line_to_d(p[2],p[3]); ras.line_to_d(p[4],p[5]); ras.line_to_d(p[6],p[7]); agg::render_scanlines(ras, sl, rp); } }
void TransformReset() { m_mtx.reset(); }
void agg_renderer<T0,T1>::render_marker(pixel_position const& pos, marker const& marker, agg::trans_affine const& tr, double opacity, composite_mode_e comp_op) { 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>; using svg_attribute_type = agg::pod_bvector<mapnik::svg::path_attributes>; ras_ptr->reset(); if (gamma_method_ != GAMMA_POWER || gamma_ != 1.0) { ras_ptr->gamma(agg::gamma_power()); gamma_method_ = GAMMA_POWER; gamma_ = 1.0; } agg::scanline_u8 sl; agg::rendering_buffer buf(current_buffer_->raw_data(), current_buffer_->width(), current_buffer_->height(), current_buffer_->width() * 4); pixfmt_comp_type pixf(buf); pixf.comp_op(static_cast<agg::comp_op_e>(comp_op)); renderer_base renb(pixf); if (marker.is_vector()) { box2d<double> const& bbox = (*marker.get_vector_data())->bounding_box(); 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 *= tr; mtx *= agg::trans_affine_scaling(common_.scale_factor_); // render the marker at the center of the marker box mtx.translate(pos.x, pos.y); using namespace mapnik::svg; vertex_stl_adapter<svg_path_storage> stl_storage((*marker.get_vector_data())->source()); svg_path_adapter svg_path(stl_storage); svg_renderer_agg<svg_path_adapter, svg_attribute_type, renderer_type, pixfmt_comp_type> svg_renderer(svg_path, (*marker.get_vector_data())->attributes()); svg_renderer.render(*ras_ptr, sl, renb, mtx, opacity, bbox); } else { double width = (*marker.get_bitmap_data())->width(); double height = (*marker.get_bitmap_data())->height(); if (std::fabs(1.0 - common_.scale_factor_) < 0.001 && tr.is_identity()) { double cx = 0.5 * width; double cy = 0.5 * height; composite(current_buffer_->data(), **marker.get_bitmap_data(), comp_op, opacity, boost::math::iround(pos.x - cx), boost::math::iround(pos.y - cy), false); } else { double p[8]; double x0 = pos.x - 0.5 * width; double y0 = pos.y - 0.5 * height; p[0] = x0; p[1] = y0; p[2] = x0 + width; p[3] = y0; p[4] = x0 + width; p[5] = y0 + height; p[6] = x0; p[7] = y0 + height; agg::trans_affine marker_tr; marker_tr *= agg::trans_affine_translation(-pos.x,-pos.y); marker_tr *= tr; marker_tr *= agg::trans_affine_scaling(common_.scale_factor_); marker_tr *= agg::trans_affine_translation(pos.x,pos.y); marker_tr.transform(&p[0], &p[1]); marker_tr.transform(&p[2], &p[3]); marker_tr.transform(&p[4], &p[5]); marker_tr.transform(&p[6], &p[7]); ras_ptr->move_to_d(p[0],p[1]); ras_ptr->line_to_d(p[2],p[3]); ras_ptr->line_to_d(p[4],p[5]); ras_ptr->line_to_d(p[6],p[7]); agg::span_allocator<color_type> sa; agg::image_filter_bilinear filter_kernel; agg::image_filter_lut filter(filter_kernel, false); image_data_32 const& src = **marker.get_bitmap_data(); agg::rendering_buffer marker_buf((unsigned char *)src.getBytes(), src.width(), src.height(), src.width()*4); agg::pixfmt_rgba32_pre marker_pixf(marker_buf); using img_accessor_type = agg::image_accessor_clone<agg::pixfmt_rgba32_pre>; using interpolator_type = agg::span_interpolator_linear<agg::trans_affine>; using span_gen_type = agg::span_image_filter_rgba_2x2<img_accessor_type, interpolator_type>; using renderer_type = agg::renderer_scanline_aa_alpha<renderer_base, agg::span_allocator<agg::rgba8>, span_gen_type>; img_accessor_type ia(marker_pixf); interpolator_type interpolator(agg::trans_affine(p, 0, 0, width, height) ); span_gen_type sg(ia, interpolator, filter); renderer_type rp(renb,sa, sg, unsigned(opacity*255)); agg::render_scanlines(*ras_ptr, sl, rp); } } }
virtual void on_draw() { typedef agg::renderer_base<pixfmt> renderer_base; typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_scanline; typedef agg::scanline_u8 scanline; pixfmt pixf(rbuf_window()); renderer_base ren_base(pixf); ren_base.clear(agg::rgba(1.0, 1.0, 0.95)); renderer_scanline ren(ren_base); unsigned i; unsigned w = unsigned(width()); m_gradient.resize(w); agg::rgba8 c1(255, 0, 0, 180); agg::rgba8 c2(0, 0, 255, 180); for(i = 0; i < w; i++) { m_gradient[i] = c1.gradient(c2, i / width()); m_gradient[i].premultiply(); } agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_dbl> ras; agg::rasterizer_compound_aa<agg::rasterizer_sl_clip_dbl> rasc; agg::scanline_u8 sl; agg::scanline_bin sl_bin; agg::conv_transform<agg::compound_shape> shape(m_shape, m_scale); agg::conv_stroke<agg::conv_transform<agg::compound_shape> > stroke(shape); agg::test_styles style_handler(m_colors, m_gradient.data()); agg::span_allocator<agg::rgba8> alloc; m_shape.approximation_scale(m_scale.scale()); // Fill shape //---------------------- rasc.clip_box(0, 0, width(), height()); rasc.reset(); //rasc.filling_rule(agg::fill_even_odd); start_timer(); for(i = 0; i < m_shape.paths(); i++) { if(m_shape.style(i).left_fill >= 0 || m_shape.style(i).right_fill >= 0) { rasc.styles(m_shape.style(i).left_fill, m_shape.style(i).right_fill); rasc.add_path(shape, m_shape.style(i).path_id); } } agg::render_scanlines_compound(rasc, sl, sl_bin, ren_base, alloc, style_handler); double tfill = elapsed_time(); // Hit-test test bool draw_strokes = true; if(m_hit_x >= 0 && m_hit_y >= 0) { if(rasc.hit_test(m_hit_x, m_hit_y)) { draw_strokes = false; } } // Draw strokes //---------------------- start_timer(); if(draw_strokes) { ras.clip_box(0, 0, width(), height()); stroke.width(sqrt(m_scale.scale())); stroke.line_join(agg::round_join); stroke.line_cap(agg::round_cap); for(i = 0; i < m_shape.paths(); i++) { ras.reset(); if(m_shape.style(i).line >= 0) { ras.add_path(stroke, m_shape.style(i).path_id); ren.color(agg::rgba8(0,0,0, 128)); agg::render_scanlines(ras, sl, ren); } } } double tstroke = elapsed_time(); char buf[256]; agg::gsv_text t; t.size(8.0); t.flip(true); agg::conv_stroke<agg::gsv_text> ts(t); ts.width(1.6); ts.line_cap(agg::round_cap); sprintf(buf, "Fill=%.2fms (%dFPS) Stroke=%.2fms (%dFPS) Total=%.2fms (%dFPS)\n\n" "Space: Next Shape\n\n" "+/- : ZoomIn/ZoomOut (with respect to the mouse pointer)", tfill, int(1000.0 / tfill), tstroke, int(1000.0 / tstroke), tfill+tstroke, int(1000.0 / (tfill+tstroke))); t.start_point(10.0, 20.0); t.text(buf); ras.add_path(ts); ren.color(agg::rgba(0,0,0)); agg::render_scanlines(ras, sl, ren); if(m_gamma.gamma() != 1.0) { pixf.apply_gamma_inv(m_gamma); } }
void grid_renderer<T>::render_marker(mapnik::feature_impl & feature, unsigned int step, pixel_position const& pos, marker const& marker, agg::trans_affine const& tr, double opacity, composite_mode_e comp_op) { if (marker.is_vector()) { typedef coord_transform<CoordTransform,geometry_type> path_type; typedef agg::renderer_base<mapnik::pixfmt_gray32> 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_gray32 pixf(buf); ren_base renb(pixf); renderer ren(renb); ras_ptr->reset(); box2d<double> const& bbox = (*marker.get_vector_data())->bounding_box(); 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 *= tr; mtx *= agg::trans_affine_scaling(scale_factor_*(1.0/step)); // render the marker at the center of the marker box mtx.translate(pos.x, pos.y); using namespace mapnik::svg; vertex_stl_adapter<svg_path_storage> stl_storage((*marker.get_vector_data())->source()); svg_path_adapter svg_path(stl_storage); svg_renderer_agg<svg_path_adapter, agg::pod_bvector<path_attributes>, renderer, mapnik::pixfmt_gray32> svg_renderer(svg_path, (*marker.get_vector_data())->attributes()); svg_renderer.render_id(*ras_ptr, sl, renb, feature.id(), mtx, opacity, bbox); } else { image_data_32 const& data = **marker.get_bitmap_data(); double width = data.width(); double height = data.height(); double cx = 0.5 * width; double cy = 0.5 * height; if (step == 1 && (std::fabs(1.0 - scale_factor_) < 0.001 && tr.is_identity())) { // TODO - support opacity pixmap_.set_rectangle(feature.id(), data, boost::math::iround(pos.x - cx), boost::math::iround(pos.y - cy)); } else { // TODO - remove support for step != or add support for agg scaling with opacity double ratio = (1.0/step); image_data_32 target(ratio * data.width(), ratio * data.height()); mapnik::scale_image_agg<image_data_32>(target,data, SCALING_NEAR, scale_factor_, 0.0, 0.0, 1.0, ratio); pixmap_.set_rectangle(feature.id(), target, boost::math::iround(pos.x - cx), boost::math::iround(pos.y - cy)); } } pixmap_.add_feature(feature); }
virtual void on_draw() { pixfmt pf(rbuf_window()); renderer_base ren_base(pf); ren_base.clear(agg::rgba(0.5, 0.75, 0.85)); renderer_scanline ren(ren_base); rasterizer_scanline ras; scanline sl; ras.clip_box(0, 0, width(), height()); // Pattern source. Must have an interface: // width() const // height() const // pixel(int x, int y) const // Any agg::renderer_base<> or derived // is good for the use as a source. //----------------------------------- pattern_src_brightness_to_alpha_rgba8 p1(rbuf_img(0)); agg::pattern_filter_bilinear_rgba8 fltr; // Filtering functor // agg::line_image_pattern is the main container for the patterns. It creates // a copy of the patterns extended according to the needs of the filter. // agg::line_image_pattern can operate with arbitrary image width, but if the // width of the pattern is power of 2, it's better to use the modified // version agg::line_image_pattern_pow2 because it works about 15-25 percent // faster than agg::line_image_pattern (because of using simple masking instead // of expensive '%' operation). typedef agg::line_image_pattern<agg::pattern_filter_bilinear_rgba8> pattern_type; typedef agg::renderer_base<pixfmt> base_ren_type; typedef agg::renderer_outline_image<base_ren_type, pattern_type> renderer_img_type; typedef agg::rasterizer_outline_aa<renderer_img_type, agg::line_coord_sat> rasterizer_img_type; typedef agg::renderer_outline_aa<base_ren_type> renderer_line_type; typedef agg::rasterizer_outline_aa<renderer_line_type, agg::line_coord_sat> rasterizer_line_type; //-- Create with specifying the source //pattern_type patt(fltr, src); //-- Create uninitialized and set the source pattern_type patt(fltr); patt.create(p1); renderer_img_type ren_img(ren_base, patt); rasterizer_img_type ras_img(ren_img); //-- create uninitialized and set parameters agg::line_profile_aa profile; profile.smoother_width(10.0); //optional profile.width(8.0); //mandatory! renderer_line_type ren_line(ren_base, profile); ren_line.color(agg::rgba8(0,0,127)); //mandatory! rasterizer_line_type ras_line(ren_line); ras_line.round_cap(true); //optional //ras_line.line_join(agg::outline_no_join); //optional // Calculate the dilation value so that, the line caps were // drawn correctly. //--------------- double w2 = 9.0;//p1.height() / 2 + 2; // Set the clip box a bit bigger than you expect. You need it // to draw the clipped line caps correctly. The correct result // is achieved with raster clipping. //------------------------ ren_img.scale_x(m_scale_x.value()); ren_img.start_x(m_start_x.value()); ren_img.clip_box (50-w2, 50-w2, width()-50+w2, height()-50+w2); ren_line.clip_box(50-w2, 50-w2, width()-50+w2, height()-50+w2); // First, draw polyline without raster clipping just to show the idea //------------------------ draw_polyline(ras_line, ren_line, m_line1.polygon(), m_line1.num_points()); draw_polyline(ras_img, ren_img, m_line1.polygon(), m_line1.num_points()); // Clear the area, almost opaque, but not completely //------------------------ ren_base.blend_bar(0, 0, (int)width(), (int)height(), agg::rgba(1,1,1), 200); // Set the raster clip box and then, draw again. // In reality there shouldn't be two calls above. // It's done only for demonstration //------------------------ ren_base.clip_box((int)50, (int)50, (int)width()-50, (int)height()-50); // This "copy_bar" is also for demonstration only //------------------------ ren_base.copy_bar(0, 0, (int)width(), (int)height(), agg::rgba(1,1,1)); // Finally draw polyline correctly clipped: We use double clipping, // first is vector clipping, with extended clip box, second is raster // clipping with normal clip box. //------------------------ ren_img.scale_x(m_scale_x.value()); ren_img.start_x(m_start_x.value()); draw_polyline(ras_line, ren_line, m_line1.polygon(), m_line1.num_points()); draw_polyline(ras_img, ren_img, m_line1.polygon(), m_line1.num_points()); // Reset clipping and draw the controls and stuff ren_base.reset_clipping(true); m_line1.line_width(1/m_scale.scale()); m_line1.point_radius(5/m_scale.scale()); agg::render_ctrl(ras, sl, ren_base, m_line1); agg::render_ctrl(ras, sl, ren_base, m_scale_x); agg::render_ctrl(ras, sl, ren_base, m_start_x); char buf[256]; agg::gsv_text t; t.size(10.0); agg::conv_stroke<agg::gsv_text> pt(t); pt.width(1.5); pt.line_cap(agg::round_cap); const double* p = m_line1.polygon(); sprintf(buf, "Len=%.2f", agg::calc_distance(p[0], p[1], p[2], p[3]) * m_scale.scale()); t.start_point(10.0, 30.0); t.text(buf); ras.add_path(pt); ren.color(agg::rgba(0,0,0)); agg::render_scanlines(ras, sl, ren); }