#include <stdlib.h> #include <ctype.h> #include <stdio.h> #include "agg_basics.h" #include "agg_rendering_buffer.h" #include "agg_rasterizer_scanline_aa.h" #include "agg_rasterizer_outline.h" #include "agg_path_storage.h" #include "agg_conv_stroke.h" #include "agg_conv_transform.h" #include "agg_bounding_rect.h" #include "agg_scanline_u.h" #include "agg_scanline_p.h" #include "agg_pixfmt_rgb.h" #include "agg_renderer_base.h" #include "agg_renderer_outline_aa.h" #include "agg_rasterizer_outline_aa.h" #include "agg_renderer_scanline.h" #include "agg_span_allocator.h" #include "agg_ellipse.h" #include "platform/agg_platform_support.h" enum flip_y_e { flip_y = true }; agg::path_storage g_path; agg::rgba8 g_colors[100]; unsigned g_path_idx[100]; unsigned g_npaths = 0; double g_x1 = 0; double g_y1 = 0; double g_x2 = 0; double g_y2 = 0; double g_base_dx = 0; double g_base_dy = 0; double g_angle = 0; double g_scale = 1.0; double g_skew_x = 0; double g_skew_y = 0; int g_nclick = 0; unsigned parse_lion(agg::path_storage& ps, agg::rgba8* colors, unsigned* path_idx); void parse_lion() { g_npaths = parse_lion(g_path, g_colors, g_path_idx); agg::pod_array_adaptor<unsigned> path_idx(g_path_idx, 100); agg::bounding_rect(g_path, path_idx, 0, g_npaths, &g_x1, &g_y1, &g_x2, &g_y2); g_base_dx = (g_x2 - g_x1) / 2.0; g_base_dy = (g_y2 - g_y1) / 2.0; } namespace agg { template<class Order> class span_simple_blur_rgb24 { public: //-------------------------------------------------------------------- typedef rgba8 color_type; //-------------------------------------------------------------------- span_simple_blur_rgb24() : m_source_image(0) {} //-------------------------------------------------------------------- span_simple_blur_rgb24(const rendering_buffer& src) : m_source_image(&src) {} //-------------------------------------------------------------------- void source_image(const rendering_buffer& src) { m_source_image = &src; } const rendering_buffer& source_image() const { return *m_source_image; } //-------------------------------------------------------------------- void prepare() {} //-------------------------------------------------------------------- void generate(color_type* span, int x, int y, int len) { if(y < 1 || y >= int(m_source_image->height() - 1)) { do { *span++ = rgba8(0,0,0,0); } while(--len); return; } do { int color[4]; color[0] = color[1] = color[2] = color[3] = 0; if(x > 0 && x < int(m_source_image->width()-1)) { int i = 3; do { const int8u* ptr = m_source_image->row_ptr(y - i + 2) + (x - 1) * 3; color[0] += *ptr++; color[1] += *ptr++; color[2] += *ptr++; color[3] += 255; color[0] += *ptr++; color[1] += *ptr++; color[2] += *ptr++; color[3] += 255; color[0] += *ptr++; color[1] += *ptr++; color[2] += *ptr++; color[3] += 255; } while(--i); color[0] /= 9; color[1] /= 9; color[2] /= 9; color[3] /= 9; } *span++ = rgba8(color[Order::R], color[Order::G], color[Order::B], color[3]); ++x; } while(--len); } private: const rendering_buffer* m_source_image; }; } class the_application : public agg::platform_support { double m_cx; double m_cy; public: virtual ~the_application() { } the_application(agg::pix_format_e format, bool flip_y) : agg::platform_support(format, flip_y), m_cx(100), m_cy(102) { parse_lion(); } virtual void on_resize(int cx, int cy) { } virtual void on_draw() { typedef agg::pixfmt_bgr24 pixfmt; typedef agg::renderer_base<pixfmt> renderer_base; typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid; pixfmt pixf(rbuf_window()); renderer_base rb(pixf); renderer_solid rs(rb); rb.clear(agg::rgba(1, 1, 1)); agg::trans_affine mtx; agg::conv_transform<agg::path_storage, agg::trans_affine> trans(g_path, mtx); mtx *= agg::trans_affine_translation(-g_base_dx, -g_base_dy); mtx *= agg::trans_affine_scaling(g_scale, g_scale); mtx *= agg::trans_affine_rotation(g_angle + agg::pi); mtx *= agg::trans_affine_skewing(g_skew_x/1000.0, g_skew_y/1000.0); mtx *= agg::trans_affine_translation(initial_width()/4, initial_height()/2); mtx *= trans_affine_resizing(); agg::rasterizer_scanline_aa<> ras2; agg::scanline_p8 sl; agg::scanline_u8 sl2; agg::render_all_paths(ras2, sl, rs, trans, g_colors, g_path_idx, g_npaths); mtx *= ~trans_affine_resizing(); mtx *= agg::trans_affine_translation(initial_width()/2, 0); mtx *= trans_affine_resizing(); agg::line_profile_aa profile; profile.width(1.0); agg::renderer_outline_aa<renderer_base> rp(rb, profile); agg::rasterizer_outline_aa<agg::renderer_outline_aa<renderer_base> > ras(rp); ras.round_cap(true); ras.render_all_paths(trans, g_colors, g_path_idx, g_npaths); agg::ellipse ell(m_cx, m_cy, 100.0, 100.0, 100); agg::conv_stroke<agg::ellipse> ell_stroke1(ell); ell_stroke1.width(6.0); agg::conv_stroke<agg::conv_stroke<agg::ellipse> > ell_stroke2(ell_stroke1); ell_stroke2.width(2.0); rs.color(agg::rgba(0,0.2,0)); ras2.add_path(ell_stroke2); agg::render_scanlines(ras2, sl, rs); typedef agg::span_simple_blur_rgb24<agg::order_bgr> span_blur_gen; typedef agg::span_allocator<span_blur_gen::color_type> span_blur_alloc; span_blur_alloc sa; span_blur_gen sg; sg.source_image(rbuf_img(0)); ras2.add_path(ell); copy_window_to_img(0); agg::render_scanlines_aa(ras2, sl2, rb, sa, sg); // More blur if desired :-) //copy_window_to_img(0); //agg::render_scanlines(ras2, sl2, rblur); //copy_window_to_img(0); //agg::render_scanlines(ras2, sl2, rblur); //copy_window_to_img(0); //agg::render_scanlines(ras2, sl2, rblur); } virtual void on_mouse_button_down(int x, int y, unsigned flags) { if(flags & agg::mouse_left) { m_cx = x; m_cy = y; force_redraw(); } } virtual void on_mouse_move(int x, int y, unsigned flags) { on_mouse_button_down(x, y, flags); } }; int agg_main(int argc, char* argv[]) { the_application app(agg::pix_format_bgr24, flip_y); app.caption("AGG Example. Lion with Alpha-Masking"); if(app.init(512, 400, agg::window_resize)) { return app.run(); } return 1; } |