Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

line_patterns_clip.cpp

Go to the documentation of this file.
00001 #include <math.h>
00002 #include <stdio.h>
00003 #include <time.h>
00004 #include "agg_math.h"
00005 #include "agg_rendering_buffer.h"
00006 #include "agg_conv_transform.h"
00007 #include "agg_conv_stroke.h"
00008 #include "agg_conv_clip_polyline.h"
00009 #include "agg_scanline_p.h"
00010 #include "agg_renderer_scanline.h"
00011 #include "agg_rasterizer_outline_aa.h"
00012 #include "agg_rasterizer_scanline_aa.h"
00013 #include "agg_pattern_filters_rgba.h"
00014 #include "agg_renderer_outline_aa.h"
00015 #include "agg_renderer_outline_image.h"
00016 #include "agg_path_storage.h"
00017 #include "agg_pixfmt_rgb.h"
00018 #include "ctrl/agg_slider_ctrl.h"
00019 #include "ctrl/agg_bezier_ctrl.h"
00020 #include "platform/agg_platform_support.h"
00021 
00022 
00023 enum flip_y_e { flip_y = true };
00024 
00025 typedef agg::pixfmt_bgr24 pixfmt;
00026 
00027 
00028 static agg::int8u brightness_to_alpha[256 * 3] = 
00029 {
00030     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
00031     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
00032     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
00033     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
00034     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
00035     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
00036     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
00037     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
00038     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
00039     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 254, 254, 254, 
00040     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
00041     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
00042     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
00043     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
00044     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
00045     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
00046     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
00047     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
00048     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
00049     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
00050     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
00051     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
00052     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
00053     254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 253, 253, 
00054     253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 252, 
00055     252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 251, 251, 251, 251, 251, 
00056     251, 251, 251, 251, 250, 250, 250, 250, 250, 250, 250, 250, 249, 249, 249, 249, 
00057     249, 249, 249, 248, 248, 248, 248, 248, 248, 248, 247, 247, 247, 247, 247, 246, 
00058     246, 246, 246, 246, 246, 245, 245, 245, 245, 245, 244, 244, 244, 244, 243, 243, 
00059     243, 243, 243, 242, 242, 242, 242, 241, 241, 241, 241, 240, 240, 240, 239, 239, 
00060     239, 239, 238, 238, 238, 238, 237, 237, 237, 236, 236, 236, 235, 235, 235, 234, 
00061     234, 234, 233, 233, 233, 232, 232, 232, 231, 231, 230, 230, 230, 229, 229, 229, 
00062     228, 228, 227, 227, 227, 226, 226, 225, 225, 224, 224, 224, 223, 223, 222, 222, 
00063     221, 221, 220, 220, 219, 219, 219, 218, 218, 217, 217, 216, 216, 215, 214, 214, 
00064     213, 213, 212, 212, 211, 211, 210, 210, 209, 209, 208, 207, 207, 206, 206, 205, 
00065     204, 204, 203, 203, 202, 201, 201, 200, 200, 199, 198, 198, 197, 196, 196, 195, 
00066     194, 194, 193, 192, 192, 191, 190, 190, 189, 188, 188, 187, 186, 186, 185, 184, 
00067     183, 183, 182, 181, 180, 180, 179, 178, 177, 177, 176, 175, 174, 174, 173, 172, 
00068     171, 171, 170, 169, 168, 167, 166, 166, 165, 164, 163, 162, 162, 161, 160, 159, 
00069     158, 157, 156, 156, 155, 154, 153, 152, 151, 150, 149, 148, 148, 147, 146, 145, 
00070     144, 143, 142, 141, 140, 139, 138, 137, 136, 135, 134, 133, 132, 131, 130, 129, 
00071     128, 128, 127, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 
00072     112, 111, 110, 109, 108, 107, 106, 105, 104, 102, 101, 100,  99,  98,  97,  96,  
00073      95,  94,  93,  91,  90,  89,  88,  87,  86,  85,  84,  82,  81,  80,  79,  78, 
00074      77,  75,  74,  73,  72,  71,  70,  69,  67,  66,  65,  64,  63,  61,  60,  59, 
00075      58,  57,  56,  54,  53,  52,  51,  50,  48,  47,  46,  45,  44,  42,  41,  40, 
00076      39,  37,  36,  35,  34,  33,  31,  30,  29,  28,  27,  25,  24,  23,  22,  20, 
00077      19,  18,  17,  15,  14,  13,  12,  11,   9,   8,   7,   6,   4,   3,   2,   1
00078 };
00079 
00080 
00081 class pattern_src_brightness_to_alpha_rgba8
00082 {
00083 public:
00084     pattern_src_brightness_to_alpha_rgba8(agg::rendering_buffer& rb) : 
00085         m_rb(&rb), m_pf(*m_rb) {}
00086 
00087     unsigned width()  const { return m_pf.width();  }
00088     unsigned height() const { return m_pf.height(); }
00089     agg::rgba8 pixel(int x, int y) const
00090     {
00091         agg::rgba8 c = m_pf.pixel(x, y);
00092         c.a = brightness_to_alpha[c.r + c.g + c.b];
00093         return c;
00094     }
00095 
00096 private:
00097     agg::rendering_buffer* m_rb;
00098     pixfmt m_pf;
00099 };
00100 
00101 
00102 class the_application : public agg::platform_support
00103 {
00104     agg::rgba8 m_ctrl_color;
00105     agg::polygon_ctrl<agg::rgba8> m_line1;
00106     agg::slider_ctrl<agg::rgba8>  m_scale_x;
00107     agg::slider_ctrl<agg::rgba8>  m_start_x;
00108     agg::trans_affine             m_scale;
00109 
00110 public:
00111     typedef agg::renderer_base<pixfmt> renderer_base;
00112     typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_scanline;
00113     typedef agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_int_sat> rasterizer_scanline;
00114     typedef agg::scanline_p8 scanline;
00115 
00116 
00117     the_application(agg::pix_format_e format, bool flip_y) :
00118         agg::platform_support(format, flip_y),
00119         m_ctrl_color(agg::rgba(0, 0.3, 0.5, 0.3)),
00120         m_line1(5),
00121         m_scale_x(5.0,   5.0, 240.0, 12.0, !flip_y),
00122         m_start_x(250.0, 5.0, 495.0, 12.0, !flip_y)
00123     {
00124         m_line1.line_color(m_ctrl_color);
00125         m_line1.xn(0) = 20;
00126         m_line1.yn(0) = 20;
00127         m_line1.xn(1) = 500-20;
00128         m_line1.yn(1) = 500-20;
00129         m_line1.xn(2) = 500-60;
00130         m_line1.yn(2) = 20;
00131         m_line1.xn(3) = 40;
00132         m_line1.yn(3) = 500-40;
00133         m_line1.xn(4) = 100;
00134         m_line1.yn(4) = 300;
00135         m_line1.close(false);
00136 
00137         add_ctrl(m_line1);
00138         m_line1.transform(m_scale);
00139 
00140         m_scale_x.label("Scale X=%.2f");
00141         m_scale_x.range(0.2, 3.0);
00142         m_scale_x.value(1.0);
00143         add_ctrl(m_scale_x);
00144         m_scale_x.no_transform();
00145 
00146         m_start_x.label("Start X=%.2f");
00147         m_start_x.range(0.0, 10.0);
00148         m_start_x.value(0.0);
00149         add_ctrl(m_start_x);
00150         m_start_x.no_transform();
00151     }
00152 
00153 
00154     template<class Rasterizer, class Renderer>
00155     void draw_polyline(Rasterizer& ras, 
00156                        Renderer& ren, 
00157                        const double* polyline, 
00158                        int num_points)
00159     {
00160         agg::poly_plain_adaptor<double> vs(polyline, num_points, m_line1.close());
00161         agg::conv_transform<agg::poly_plain_adaptor<double> > trans(vs, m_scale);
00162         ras.add_path(trans);
00163     }
00164 
00165 
00166     virtual void on_draw()
00167     {
00168         pixfmt pf(rbuf_window());
00169         renderer_base ren_base(pf);
00170         ren_base.clear(agg::rgba(0.5, 0.75, 0.85));
00171         renderer_scanline ren(ren_base);
00172 
00173         rasterizer_scanline ras;
00174         scanline sl;
00175 
00176         ras.clip_box(0, 0, width(), height());
00177 
00178         // Pattern source. Must have an interface:
00179         // width() const
00180         // height() const
00181         // pixel(int x, int y) const
00182         // Any agg::renderer_base<> or derived
00183         // is good for the use as a source.
00184         //-----------------------------------
00185         pattern_src_brightness_to_alpha_rgba8 p1(rbuf_img(0));
00186 
00187         agg::pattern_filter_bilinear_rgba8 fltr;           // Filtering functor
00188 
00189         // agg::line_image_pattern is the main container for the patterns. It creates
00190         // a copy of the patterns extended according to the needs of the filter.
00191         // agg::line_image_pattern can operate with arbitrary image width, but if the 
00192         // width of the pattern is power of 2, it's better to use the modified
00193         // version agg::line_image_pattern_pow2 because it works about 15-25 percent
00194         // faster than agg::line_image_pattern (because of using simple masking instead 
00195         // of expensive '%' operation). 
00196         typedef agg::line_image_pattern<agg::pattern_filter_bilinear_rgba8> pattern_type;
00197         typedef agg::renderer_base<pixfmt> base_ren_type;
00198         typedef agg::renderer_outline_image<base_ren_type, pattern_type> renderer_img_type;
00199         typedef agg::rasterizer_outline_aa<renderer_img_type, agg::line_coord_sat> rasterizer_img_type;
00200 
00201         typedef agg::renderer_outline_aa<base_ren_type> renderer_line_type;
00202         typedef agg::rasterizer_outline_aa<renderer_line_type, agg::line_coord_sat> rasterizer_line_type;
00203 
00204 
00205         //-- Create with specifying the source
00206         //pattern_type patt(fltr, src);   
00207 
00208         //-- Create uninitialized and set the source
00209         pattern_type patt(fltr);        
00210         patt.create(p1);
00211         renderer_img_type ren_img(ren_base, patt);
00212         rasterizer_img_type ras_img(ren_img);
00213 
00214 
00215         //-- create uninitialized and set parameters
00216         agg::line_profile_aa profile;
00217         profile.smoother_width(10.0);                    //optional
00218         profile.width(8.0);                              //mandatory!
00219         renderer_line_type ren_line(ren_base, profile);
00220         ren_line.color(agg::rgba8(0,0,127));            //mandatory!
00221         rasterizer_line_type ras_line(ren_line);
00222         ras_line.round_cap(true);                       //optional
00223         //ras_line.line_join(agg::outline_no_join);     //optional
00224 
00225         // Calculate the dilation value so that, the line caps were
00226         // drawn correctly.
00227         //---------------
00228         double w2 = 9.0;//p1.height() / 2 + 2;
00229 
00230 
00231         // Set the clip box a bit bigger than you expect. You need it
00232         // to draw the clipped line caps correctly. The correct result
00233         // is achieved with raster clipping.
00234         //------------------------
00235         ren_img.scale_x(m_scale_x.value());
00236         ren_img.start_x(m_start_x.value());
00237         ren_img.clip_box (50-w2, 50-w2, width()-50+w2, height()-50+w2);
00238         ren_line.clip_box(50-w2, 50-w2, width()-50+w2, height()-50+w2);
00239 
00240         // First, draw polyline without raster clipping just to show the idea
00241         //------------------------
00242         draw_polyline(ras_line, ren_line, m_line1.polygon(), m_line1.num_points());
00243         draw_polyline(ras_img,  ren_img,  m_line1.polygon(), m_line1.num_points());
00244 
00245         // Clear the area, almost opaque, but not completely
00246         //------------------------
00247         ren_base.blend_bar(0, 0, (int)width(), (int)height(), agg::rgba(1,1,1), 200);
00248 
00249 
00250         // Set the raster clip box and then, draw again. 
00251         // In reality there shouldn't be two calls above. 
00252         // It's done only for demonstration
00253         //------------------------
00254         ren_base.clip_box((int)50, (int)50, (int)width()-50, (int)height()-50);
00255 
00256         // This "copy_bar" is also for demonstration only
00257         //------------------------
00258         ren_base.copy_bar(0, 0, (int)width(), (int)height(), agg::rgba(1,1,1));
00259 
00260         // Finally draw polyline correctly clipped: We use double clipping, 
00261         // first is vector clipping, with extended clip box, second is raster 
00262         // clipping with normal clip box.
00263         //------------------------
00264         ren_img.scale_x(m_scale_x.value());
00265         ren_img.start_x(m_start_x.value());
00266         draw_polyline(ras_line, ren_line, m_line1.polygon(), m_line1.num_points());
00267         draw_polyline(ras_img, ren_img,   m_line1.polygon(), m_line1.num_points());
00268 
00269 
00270         // Reset clipping and draw the controls and stuff
00271         ren_base.reset_clipping(true);
00272 
00273         m_line1.line_width(1/m_scale.scale());
00274         m_line1.point_radius(5/m_scale.scale());
00275 
00276         agg::render_ctrl(ras, sl, ren_base, m_line1);
00277         agg::render_ctrl(ras, sl, ren_base, m_scale_x);
00278         agg::render_ctrl(ras, sl, ren_base, m_start_x);
00279 
00280 
00281         char buf[256]; 
00282         agg::gsv_text t;
00283         t.size(10.0);
00284 
00285         agg::conv_stroke<agg::gsv_text> pt(t);
00286         pt.width(1.5);
00287         pt.line_cap(agg::round_cap);
00288 
00289         const double* p = m_line1.polygon();
00290         sprintf(buf, "Len=%.2f", agg::calc_distance(p[0], p[1], p[2], p[3]) * m_scale.scale());
00291 
00292         t.start_point(10.0, 30.0);
00293         t.text(buf);
00294 
00295         ras.add_path(pt);
00296         ren.color(agg::rgba(0,0,0));
00297         agg::render_scanlines(ras, sl, ren);
00298 
00299     }
00300 
00301 
00302     virtual void on_key(int x, int y, unsigned key, unsigned flags)
00303     {
00304         if(key == '+' || key == agg::key_kp_plus)
00305         {
00306             m_scale *= agg::trans_affine_translation(-x, -y);
00307             m_scale *= agg::trans_affine_scaling(1.1);
00308             m_scale *= agg::trans_affine_translation(x, y);
00309             force_redraw();
00310         }
00311 
00312         if(key == '-' || key == agg::key_kp_minus)
00313         {
00314             m_scale *= agg::trans_affine_translation(-x, -y);
00315             m_scale *= agg::trans_affine_scaling(1/1.1);
00316             m_scale *= agg::trans_affine_translation(x, y);
00317             force_redraw();
00318         }
00319     }
00320 
00321     virtual void on_ctrl_change()
00322     {
00323     }
00324 };
00325 
00326 
00327 int agg_main(int argc, char* argv[])
00328 {
00329     the_application app(agg::pix_format_bgr24, flip_y);
00330     app.caption("AGG Example. Clipping Lines with Image Patterns");
00331 
00332     if(!app.load_img(0, "1"))
00333     {
00334         char buf[256];
00335         sprintf(buf, "There must be file 1%s\n", app.img_ext(), app.img_ext());
00336         app.message(buf);
00337         return 1;
00338     }
00339 
00340     if(app.init(500, 500, agg::window_resize))
00341     {
00342         return app.run();
00343     }
00344 
00345     return 1;
00346 }
00347 
00348 

© sourcejam.com 2005-2008