00001 #include "agg_basics.h"
00002 #include "agg_rendering_buffer.h"
00003 #include "agg_rasterizer_scanline_aa.h"
00004 #include "agg_scanline_p.h"
00005 #include "agg_renderer_scanline.h"
00006 #include "agg_trans_affine.h"
00007 #include "agg_conv_stroke.h"
00008 #include "agg_conv_transform.h"
00009 #include "ctrl/agg_cbox_ctrl.h"
00010 #include "ctrl/agg_slider_ctrl.h"
00011 #include "platform/agg_platform_support.h"
00012
00013 #define AGG_BGR24
00014
00015
00016
00017
00018
00019
00020
00021 #include "pixel_formats.h"
00022
00023 enum flip_y_e { flip_y = false };
00024
00025
00026 struct path_attributes
00027 {
00028 unsigned index;
00029 agg::rgba8 fill_color;
00030 agg::rgba8 stroke_color;
00031 double stroke_width;
00032
00033 path_attributes() {}
00034 path_attributes(unsigned idx,
00035 const agg::rgba8& fill,
00036 const agg::rgba8& stroke,
00037 double width) :
00038 index(idx),
00039 fill_color(fill),
00040 stroke_color(stroke),
00041 stroke_width(width)
00042 {
00043 }
00044 };
00045
00046
00047
00048 static double g_poly_bulb[] =
00049 {
00050 -6,-67, -6,-71, -7,-74, -8,-76, -10,-79,
00051 -10,-82, -9,-84, -6,-86, -4,-87, -2,-86,
00052 -1,-86, 1,-84, 2,-82, 2,-79, 0,-77,
00053 -2,-73, -2,-71, -2,-69, -3,-67, -4,-65
00054 };
00055
00056 static double g_poly_beam1[] =
00057 {
00058 -14,-84,-22,-85,-23,-87,-22,-88,-21,-88
00059 };
00060
00061 static double g_poly_beam2[] =
00062 {
00063 -10,-92, -14,-96, -14,-98, -12,-99, -11,-97
00064 };
00065
00066 static double g_poly_beam3[] =
00067 {
00068 -1,-92, -2,-98, 0,-100, 2,-100, 1,-98
00069 };
00070
00071 static double g_poly_beam4[] =
00072 {
00073 5,-89, 11,-94, 13,-93, 13,-92, 12,-91
00074 };
00075
00076
00077 static double g_poly_fig1[] =
00078 {
00079 1,-48,-3,-54,-7,-58,-12,-58,-17,-55,-20,-52,-21,-47,
00080 -20,-40,-17,-33,-11,-28,-6,-26,-2,-25,2,-26,4,-28,5,
00081 -33,5,-39,3,-44,12,-48,12,-50,12,-51,3,-46
00082 };
00083
00084
00085 static double g_poly_fig2[] =
00086 {
00087 11,-27,6,-23,4,-22,3,-19,5,
00088 -16,6,-15,11,-17,19,-23,25,-30,32,-38,32,-41,32,-50,30,-64,32,-72,
00089 32,-75,31,-77,28,-78,26,-80,28,-87,27,-89,25,-88,24,-79,24,-76,23,
00090 -75,20,-76,17,-76,17,-74,19,-73,22,-73,24,-71,26,-69,27,-64,28,-55,
00091 28,-47,28,-40,26,-38,20,-33,14,-30
00092 };
00093
00094
00095 static double g_poly_fig3[] =
00096 {
00097 -6,-20,-9,-21,-15,-21,-20,-17,
00098 -28,-8,-32,-1,-32,1,-30,6,-26,8,-20,10,-16,12,-14,14,-15,16,-18,20,
00099 -22,20,-25,19,-27,20,-26,22,-23,23,-18,23,-14,22,-11,20,-10,17,-9,14,
00100 -11,11,-16,9,-22,8,-26,5,-28,2,-27,-2,-23,-8,-19,-11,-12,-14,-6,-15,
00101 -6,-18
00102 };
00103
00104
00105 static double g_poly_fig4[] =
00106 {
00107 11,-6,8,-16,5,-21,-1,-23,-7,
00108 -22,-10,-17,-9,-10,-8,0,-8,10,-10,18,-11,22,-10,26,-7,28,-3,30,0,31,
00109 5,31,10,27,14,18,14,11,11,2
00110 };
00111
00112
00113 static double g_poly_fig5[] =
00114 {
00115 0,22,-5,21,-8,22,-9,26,-8,49,
00116 -8,54,-10,64,-10,75,-9,81,-10,84,-16,89,-18,95,-18,97,-13,100,-12,99,
00117 -12,95,-10,90,-8,87,-6,86,-4,83,-3,82,-5,80,-6,79,-7,74,-6,63,-3,52,
00118 0,42,1,31
00119 };
00120
00121
00122 static double g_poly_fig6[] =
00123 {
00124 12,31,12,24,8,21,3,21,2,24,3,
00125 30,5,40,8,47,10,56,11,64,11,71,10,76,8,77,8,79,10,81,13,82,17,82,26,
00126 84,28,87,32,86,33,81,32,80,25,79,17,79,14,79,13,76,14,72,14,64,13,55,
00127 12,44,12,34
00128 };
00129
00130
00131
00132 static path_attributes g_attr[3];
00133 static agg::path_storage g_path;
00134 static unsigned g_npaths = 0;
00135 static agg::filling_rule_e g_pflag = agg::fill_non_zero;
00136 static agg::rasterizer_scanline_aa<> g_rasterizer;
00137 static agg::scanline_p8 g_scanline;
00138 static double g_angle = 0.0;
00139
00140 #define AGG_POLY_SIZE(p) (sizeof(p) / (sizeof(*p) * 2))
00141
00142
00143
00144 struct trans_roundoff
00145 {
00146 static void transform(double* x, double* y)
00147 {
00148 *x = floor(*x + 0.5);
00149 *y = floor(*y + 0.5);
00150 }
00151 };
00152
00153
00154 class the_application : public agg::platform_support
00155 {
00156 double m_dx;
00157 double m_dy;
00158 agg::cbox_ctrl<agg::rgba8> m_rotate;
00159 agg::cbox_ctrl<agg::rgba8> m_even_odd;
00160 agg::cbox_ctrl<agg::rgba8> m_draft;
00161 agg::cbox_ctrl<agg::rgba8> m_roundoff;
00162 agg::slider_ctrl<agg::rgba8> m_angle_delta;
00163 bool m_redraw_flag;
00164
00165 public:
00166 the_application(agg::pix_format_e format, bool flip_y) :
00167 agg::platform_support(format, flip_y),
00168 m_rotate(10, 3, "Rotate", !flip_y),
00169 m_even_odd(60, 3, "Even-Odd", !flip_y),
00170 m_draft(130, 3, "Draft", !flip_y),
00171 m_roundoff(175, 3, "Roundoff", !flip_y),
00172 m_angle_delta(10, 21, 250-10, 27, !flip_y),
00173 m_redraw_flag(true)
00174 {
00175 m_angle_delta.label("Step=%4.3f degree");
00176
00177 g_attr[g_npaths++] = path_attributes(g_path.start_new_path(),
00178 agg::rgba8(255, 255, 0),
00179 agg::rgba8(0, 0, 0),
00180 1.0);
00181
00182 g_path.concat_poly(g_poly_bulb, AGG_POLY_SIZE(g_poly_bulb), true);
00183
00184 g_attr[g_npaths++] = path_attributes(g_path.start_new_path(),
00185 agg::rgba8(255, 255, 200),
00186 agg::rgba8(90, 0, 0),
00187 0.7);
00188
00189 g_path.concat_poly(g_poly_beam1, AGG_POLY_SIZE(g_poly_beam1), true);
00190 g_path.concat_poly(g_poly_beam2, AGG_POLY_SIZE(g_poly_beam2), true);
00191 g_path.concat_poly(g_poly_beam3, AGG_POLY_SIZE(g_poly_beam3), true);
00192 g_path.concat_poly(g_poly_beam4, AGG_POLY_SIZE(g_poly_beam4), true);
00193
00194 g_attr[g_npaths++] = path_attributes(g_path.start_new_path(),
00195 agg::rgba8(0, 0, 0),
00196 agg::rgba8(0, 0, 0),
00197 0.0);
00198
00199 g_path.concat_poly(g_poly_fig1, AGG_POLY_SIZE(g_poly_fig1), true);
00200 g_path.concat_poly(g_poly_fig2, AGG_POLY_SIZE(g_poly_fig2), true);
00201 g_path.concat_poly(g_poly_fig3, AGG_POLY_SIZE(g_poly_fig3), true);
00202 g_path.concat_poly(g_poly_fig4, AGG_POLY_SIZE(g_poly_fig4), true);
00203 g_path.concat_poly(g_poly_fig5, AGG_POLY_SIZE(g_poly_fig5), true);
00204 g_path.concat_poly(g_poly_fig6, AGG_POLY_SIZE(g_poly_fig6), true);
00205
00206 m_rotate.text_size(7);
00207 m_even_odd.text_size(7);
00208 m_draft.text_size(7);
00209 m_roundoff.text_size(7);
00210 add_ctrl(m_rotate);
00211 add_ctrl(m_even_odd);
00212 add_ctrl(m_draft);
00213 add_ctrl(m_roundoff);
00214 add_ctrl(m_angle_delta);
00215 m_angle_delta.value(0.01);
00216 }
00217
00218
00219 virtual void on_init()
00220 {
00221 m_dx = rbuf_window().width();
00222 m_dy = rbuf_window().height();
00223 }
00224
00225 virtual void on_resize(int, int)
00226 {
00227 m_redraw_flag = true;
00228 }
00229
00230 virtual void on_draw()
00231 {
00232 typedef agg::renderer_base<pixfmt> ren_base;
00233
00234 pixfmt pixf(rbuf_window());
00235 ren_base rbase(pixf);
00236 trans_roundoff roundoff;
00237
00238 if(m_redraw_flag)
00239 {
00240 g_rasterizer.gamma(agg::gamma_none());
00241 rbase.clear(agg::rgba8(255,255,255));
00242 g_rasterizer.filling_rule(agg::fill_non_zero);
00243 agg::render_ctrl(g_rasterizer, g_scanline, rbase, m_rotate);
00244 agg::render_ctrl(g_rasterizer, g_scanline, rbase, m_even_odd);
00245 agg::render_ctrl(g_rasterizer, g_scanline, rbase, m_draft);
00246 agg::render_ctrl(g_rasterizer, g_scanline, rbase, m_roundoff);
00247 agg::render_ctrl(g_rasterizer, g_scanline, rbase, m_angle_delta);
00248 m_redraw_flag = false;
00249 }
00250 else
00251 {
00252 rbase.copy_bar(0,
00253 int(32.0 * rbuf_window().height() / m_dy),
00254 rbuf_window().width(),
00255 rbuf_window().height(),
00256 agg::rgba8(255,255,255));
00257 }
00258
00259
00260 if(m_draft.status())
00261 {
00262 g_rasterizer.gamma(agg::gamma_threshold(0.4));
00263 }
00264
00265 agg::trans_affine mtx;
00266 mtx.reset();
00267 mtx *= agg::trans_affine_rotation(g_angle * agg::pi / 180.0);
00268 mtx *= agg::trans_affine_translation(m_dx / 2, m_dy / 2 + 10);
00269 mtx *= agg::trans_affine_scaling(rbuf_window().width() / m_dx,
00270 rbuf_window().height() / m_dy);
00271
00272 agg::conv_transform<agg::path_storage> fill(g_path, mtx);
00273 agg::conv_transform
00274 <
00275 agg::conv_transform<agg::path_storage>,
00276 trans_roundoff
00277 >
00278 fill_roundoff(fill, roundoff);
00279
00280 agg::conv_stroke
00281 <
00282 agg::conv_transform<agg::path_storage>
00283 >
00284 stroke(fill);
00285
00286 agg::conv_stroke
00287 <
00288 agg::conv_transform
00289 <
00290 agg::conv_transform<agg::path_storage>,
00291 trans_roundoff
00292 >
00293 >
00294 stroke_roundoff(fill_roundoff);
00295
00296 g_pflag = m_even_odd.status() ? agg::fill_even_odd : agg::fill_non_zero;
00297
00298 unsigned i;
00299 for(i = 0; i < g_npaths; i++)
00300 {
00301 g_rasterizer.filling_rule(g_pflag);
00302 if(m_roundoff.status()) g_rasterizer.add_path(fill_roundoff, g_attr[i].index);
00303 else g_rasterizer.add_path(fill, g_attr[i].index);
00304
00305 if(m_draft.status())
00306 {
00307 agg::render_scanlines_bin_solid(g_rasterizer, g_scanline, rbase, g_attr[i].fill_color);
00308 }
00309 else
00310 {
00311 agg::render_scanlines_aa_solid(g_rasterizer, g_scanline, rbase, g_attr[i].fill_color);
00312 }
00313
00314 if(g_attr[i].stroke_width > 0.001)
00315 {
00316 stroke.width(g_attr[i].stroke_width * mtx.scale());
00317 stroke_roundoff.width(g_attr[i].stroke_width * mtx.scale());
00318 if(m_roundoff.status()) g_rasterizer.add_path(stroke_roundoff, g_attr[i].index);
00319 else g_rasterizer.add_path(stroke, g_attr[i].index);
00320 if(m_draft.status())
00321 {
00322 agg::render_scanlines_bin_solid(g_rasterizer, g_scanline, rbase, g_attr[i].stroke_color);
00323 }
00324 else
00325 {
00326 agg::render_scanlines_aa_solid(g_rasterizer, g_scanline, rbase, g_attr[i].stroke_color);
00327 }
00328 }
00329 }
00330 }
00331
00332 virtual void on_idle()
00333 {
00334 g_angle += m_angle_delta.value();
00335 if(g_angle > 360.0) g_angle -= 360.0;
00336 force_redraw();
00337 }
00338
00339 virtual void on_ctrl_change()
00340 {
00341 wait_mode(!m_rotate.status());
00342 m_redraw_flag = true;
00343 }
00344
00345 };
00346
00347
00348
00349
00350 int agg_main(int argc, char* argv[])
00351 {
00352 the_application app(pix_format, flip_y);
00353 app.caption("AGG Example. Idea");
00354
00355 if(app.init(250, 280, agg::window_resize))
00356 {
00357 return app.run();
00358 }
00359 return 1;
00360 }
00361
00362