1 #include <math.h>
2 #include <stdio.h>
3 #include "agg_basics.h"
4 #include "agg_rendering_buffer.h"
5 #include "agg_rasterizer_scanline_aa.h"
6 #include "agg_conv_curve.h"
7 #include "agg_conv_contour.h"
8 #include "agg_conv_stroke.h"
9 #include "agg_scanline_p.h"
10 #include "agg_renderer_scanline.h"
11 #include "agg_pixfmt_rgb.h"
12 #include "agg_pixfmt_rgba.h"
13 #include "agg_pixfmt_gray.h"
14 #include "agg_bounding_rect.h"
15 #include "agg_trans_perspective.h"
16 #include "agg_blur.h"
17 #include "ctrl/agg_slider_ctrl.h"
18 #include "ctrl/agg_rbox_ctrl.h"
19 #include "ctrl/agg_cbox_ctrl.h"
20 #include "ctrl/agg_polygon_ctrl.h"
21 #include "platform/agg_platform_support.h"
22 
23 //#define AGG_GRAY8
24 #define AGG_BGR24
25 //#define AGG_BGR48
26 //#define AGG_RGB_AAA
27 //#define AGG_BGRA32
28 //#define AGG_RGBA32
29 //#define AGG_ARGB32
30 //#define AGG_ABGR32
31 //#define AGG_RGB565
32 //#define AGG_RGB555
33 #include "pixel_formats.h"
34 
35 
36 static agg::int8u g_gradient_colors[] =
37 {
38     255, 255, 255, 255,
39     255, 255, 254, 255,
40     255, 255, 254, 255,
41     255, 255, 254, 255,
42     255, 255, 253, 255,
43     255, 255, 253, 255,
44     255, 255, 252, 255,
45     255, 255, 251, 255,
46     255, 255, 250, 255,
47     255, 255, 248, 255,
48     255, 255, 246, 255,
49     255, 255, 244, 255,
50     255, 255, 241, 255,
51     255, 255, 238, 255,
52     255, 255, 235, 255,
53     255, 255, 231, 255,
54     255, 255, 227, 255,
55     255, 255, 222, 255,
56     255, 255, 217, 255,
57     255, 255, 211, 255,
58     255, 255, 206, 255,
59     255, 255, 200, 255,
60     255, 254, 194, 255,
61     255, 253, 188, 255,
62     255, 252, 182, 255,
63     255, 250, 176, 255,
64     255, 249, 170, 255,
65     255, 247, 164, 255,
66     255, 246, 158, 255,
67     255, 244, 152, 255,
68     254, 242, 146, 255,
69     254, 240, 141, 255,
70     254, 238, 136, 255,
71     254, 236, 131, 255,
72     253, 234, 126, 255,
73     253, 232, 121, 255,
74     253, 229, 116, 255,
75     252, 227, 112, 255,
76     252, 224, 108, 255,
77     251, 222, 104, 255,
78     251, 219, 100, 255,
79     251, 216,  96, 255,
80     250, 214,  93, 255,
81     250, 211,  89, 255,
82     249, 208,  86, 255,
83     249, 205,  83, 255,
84     248, 202,  80, 255,
85     247, 199,  77, 255,
86     247, 196,  74, 255,
87     246, 193,  72, 255,
88     246, 190,  69, 255,
89     245, 187,  67, 255,
90     244, 183,  64, 255,
91     244, 180,  62, 255,
92     243, 177,  60, 255,
93     242, 174,  58, 255,
94     242, 170,  56, 255,
95     241, 167,  54, 255,
96     240, 164,  52, 255,
97     239, 161,  51, 255,
98     239, 157,  49, 255,
99     238, 154,  47, 255,
100     237, 151,  46, 255,
101     236, 147,  44, 255,
102     235, 144,  43, 255,
103     235, 141,  41, 255,
104     234, 138,  40, 255,
105     233, 134,  39, 255,
106     232, 131,  37, 255,
107     231, 128,  36, 255,
108     230, 125,  35, 255,
109     229, 122,  34, 255,
110     228, 119,  33, 255,
111     227, 116,  31, 255,
112     226, 113,  30, 255,
113     225, 110,  29, 255,
114     224, 107,  28, 255,
115     223, 104,  27, 255,
116     222, 101,  26, 255,
117     221,  99,  25, 255,
118     220,  96,  24, 255,
119     219,  93,  23, 255,
120     218,  91,  22, 255,
121     217,  88,  21, 255,
122     216,  86,  20, 255,
123     215,  83,  19, 255,
124     214,  81,  18, 255,
125     213,  79,  17, 255,
126     212,  77,  17, 255,
127     211,  74,  16, 255,
128     210,  72,  15, 255,
129     209,  70,  14, 255,
130     207,  68,  13, 255,
131     206,  66,  13, 255,
132     205,  64,  12, 255,
133     204,  62,  11, 255,
134     203,  60,  10, 255,
135     202,  58,  10, 255,
136     201,  56,   9, 255,
137     199,  55,   9, 255,
138     198,  53,   8, 255,
139     197,  51,   7, 255,
140     196,  50,   7, 255,
141     195,  48,   6, 255,
142     193,  46,   6, 255,
143     192,  45,   5, 255,
144     191,  43,   5, 255,
145     190,  42,   4, 255,
146     188,  41,   4, 255,
147     187,  39,   3, 255,
148     186,  38,   3, 255,
149     185,  37,   2, 255,
150     183,  35,   2, 255,
151     182,  34,   1, 255,
152     181,  33,   1, 255,
153     179,  32,   1, 255,
154     178,  30,   0, 255,
155     177,  29,   0, 255,
156     175,  28,   0, 255,
157     174,  27,   0, 255,
158     173,  26,   0, 255,
159     171,  25,   0, 255,
160     170,  24,   0, 255,
161     168,  23,   0, 255,
162     167,  22,   0, 255,
163     165,  21,   0, 255,
164     164,  21,   0, 255,
165     163,  20,   0, 255,
166     161,  19,   0, 255,
167     160,  18,   0, 255,
168     158,  17,   0, 255,
169     156,  17,   0, 255,
170     155,  16,   0, 255,
171     153,  15,   0, 255,
172     152,  14,   0, 255,
173     150,  14,   0, 255,
174     149,  13,   0, 255,
175     147,  12,   0, 255,
176     145,  12,   0, 255,
177     144,  11,   0, 255,
178     142,  11,   0, 255,
179     140,  10,   0, 255,
180     139,  10,   0, 255,
181     137,   9,   0, 255,
182     135,   9,   0, 255,
183     134,   8,   0, 255,
184     132,   8,   0, 255,
185     130,   7,   0, 255,
186     128,   7,   0, 255,
187     126,   6,   0, 255,
188     125,   6,   0, 255,
189     123,   5,   0, 255,
190     121,   5,   0, 255,
191     119,   4,   0, 255,
192     117,   4,   0, 255,
193     115,   4,   0, 255,
194     113,   3,   0, 255,
195     111,   3,   0, 255,
196     109,   2,   0, 255,
197     107,   2,   0, 255,
198     105,   2,   0, 255,
199     103,   1,   0, 255,
200     101,   1,   0, 255,
201      99,   1,   0, 255,
202      97,   0,   0, 255,
203      95,   0,   0, 255,
204      93,   0,   0, 255,
205      91,   0,   0, 255,
206      90,   0,   0, 255,
207      88,   0,   0, 255,
208      86,   0,   0, 255,
209      84,   0,   0, 255,
210      82,   0,   0, 255,
211      80,   0,   0, 255,
212      78,   0,   0, 255,
213      77,   0,   0, 255,
214      75,   0,   0, 255,
215      73,   0,   0, 255,
216      72,   0,   0, 255,
217      70,   0,   0, 255,
218      68,   0,   0, 255,
219      67,   0,   0, 255,
220      65,   0,   0, 255,
221      64,   0,   0, 255,
222      63,   0,   0, 255,
223      61,   0,   0, 255,
224      60,   0,   0, 255,
225      59,   0,   0, 255,
226      58,   0,   0, 255,
227      57,   0,   0, 255,
228      56,   0,   0, 255,
229      55,   0,   0, 255,
230      54,   0,   0, 255,
231      53,   0,   0, 255,
232      53,   0,   0, 255,
233      52,   0,   0, 255,
234      52,   0,   0, 255,
235      51,   0,   0, 255,
236      51,   0,   0, 255,
237      51,   0,   0, 255,
238      50,   0,   0, 255,
239      50,   0,   0, 255,
240      51,   0,   0, 255,
241      51,   0,   0, 255,
242      51,   0,   0, 255,
243      51,   0,   0, 255,
244      52,   0,   0, 255,
245      52,   0,   0, 255,
246      53,   0,   0, 255,
247      54,   1,   0, 255,
248      55,   2,   0, 255,
249      56,   3,   0, 255,
250      57,   4,   0, 255,
251      58,   5,   0, 255,
252      59,   6,   0, 255,
253      60,   7,   0, 255,
254      62,   8,   0, 255,
255      63,   9,   0, 255,
256      64,  11,   0, 255,
257      66,  12,   0, 255,
258      68,  13,   0, 255,
259      69,  14,   0, 255,
260      71,  16,   0, 255,
261      73,  17,   0, 255,
262      75,  18,   0, 255,
263      77,  20,   0, 255,
264      79,  21,   0, 255,
265      81,  23,   0, 255,
266      83,  24,   0, 255,
267      85,  26,   0, 255,
268      87,  28,   0, 255,
269      90,  29,   0, 255,
270      92,  31,   0, 255,
271      94,  33,   0, 255,
272      97,  34,   0, 255,
273      99,  36,   0, 255,
274     102,  38,   0, 255,
275     104,  40,   0, 255,
276     107,  41,   0, 255,
277     109,  43,   0, 255,
278     112,  45,   0, 255,
279     115,  47,   0, 255,
280     117,  49,   0, 255,
281     120,  51,   0, 255,
282     123,  52,   0, 255,
283     126,  54,   0, 255,
284     128,  56,   0, 255,
285     131,  58,   0, 255,
286     134,  60,   0, 255,
287     137,  62,   0, 255,
288     140,  64,   0, 255,
289     143,  66,   0, 255,
290     145,  68,   0, 255,
291     148,  70,   0, 255,
292     151,  72,   0, 255,
293     154,  74,   0, 255
294 };
295 
296 
297 enum flip_y_e { flip_y = true };
298 
299 
300 class the_application : public agg::platform_support
301 {
302     agg::rbox_ctrl<agg::rgba8>    m_method;
303     agg::slider_ctrl<agg::rgba8>  m_radius;
304     agg::polygon_ctrl<agg::rgba8> m_shadow_ctrl;
305 
306     agg::path_storage             m_path;
307     typedef agg::conv_curve<agg::path_storage> shape_type;
308     shape_type                    m_shape;
309 
310     agg::rasterizer_scanline_aa<> m_ras;
311     agg::scanline_p8              m_sl;
312 
313     agg::rect_d m_shape_bounds;
314 
315     agg::pod_array<agg::int8u> m_gray8_buf;
316     agg::rendering_buffer      m_gray8_rbuf;
317     agg::rendering_buffer      m_gray8_rbuf2;
318 
319     agg::pod_array<color_type> m_color_lut;
320 public:
321 
the_application(agg::pix_format_e format,bool flip_y)322     the_application(agg::pix_format_e format, bool flip_y) :
323         agg::platform_support(format, flip_y),
324         m_method     (10.0, 10.0, 130.0, 55.0, !flip_y),
325         m_radius     (130 + 10.0, 10.0 + 4.0, 130 + 300.0, 10.0 + 8.0 + 4.0, !flip_y),
326         m_shadow_ctrl(4),
327         m_shape(m_path)
328     {
329         add_ctrl(m_method);
330         m_method.text_size(8);
331         m_method.add_item("Single Color");
332         m_method.add_item("Color LUT");
333         m_method.cur_item(1);
334 
335         add_ctrl(m_radius);
336         m_radius.range(0.0, 40.0);
337         m_radius.value(15.0);
338         m_radius.label("Blur Radius=%1.2f");
339 
340         add_ctrl(m_shadow_ctrl);
341 
342         m_path.remove_all();
343         m_path.move_to(28.47, 6.45);
344         m_path.curve3(21.58, 1.12, 19.82, 0.29);
345         m_path.curve3(17.19, -0.93, 14.21, -0.93);
346         m_path.curve3(9.57, -0.93, 6.57, 2.25);
347         m_path.curve3(3.56, 5.42, 3.56, 10.60);
348         m_path.curve3(3.56, 13.87, 5.03, 16.26);
349         m_path.curve3(7.03, 19.58, 11.99, 22.51);
350         m_path.curve3(16.94, 25.44, 28.47, 29.64);
351         m_path.line_to(28.47, 31.40);
352         m_path.curve3(28.47, 38.09, 26.34, 40.58);
353         m_path.curve3(24.22, 43.07, 20.17, 43.07);
354         m_path.curve3(17.09, 43.07, 15.28, 41.41);
355         m_path.curve3(13.43, 39.75, 13.43, 37.60);
356         m_path.line_to(13.53, 34.77);
357         m_path.curve3(13.53, 32.52, 12.38, 31.30);
358         m_path.curve3(11.23, 30.08, 9.38, 30.08);
359         m_path.curve3(7.57, 30.08, 6.42, 31.35);
360         m_path.curve3(5.27, 32.62, 5.27, 34.81);
361         m_path.curve3(5.27, 39.01, 9.57, 42.53);
362         m_path.curve3(13.87, 46.04, 21.63, 46.04);
363         m_path.curve3(27.59, 46.04, 31.40, 44.04);
364         m_path.curve3(34.28, 42.53, 35.64, 39.31);
365         m_path.curve3(36.52, 37.21, 36.52, 30.71);
366         m_path.line_to(36.52, 15.53);
367         m_path.curve3(36.52, 9.13, 36.77, 7.69);
368         m_path.curve3(37.01, 6.25, 37.57, 5.76);
369         m_path.curve3(38.13, 5.27, 38.87, 5.27);
370         m_path.curve3(39.65, 5.27, 40.23, 5.62);
371         m_path.curve3(41.26, 6.25, 44.19, 9.18);
372         m_path.line_to(44.19, 6.45);
373         m_path.curve3(38.72, -0.88, 33.74, -0.88);
374         m_path.curve3(31.35, -0.88, 29.93, 0.78);
375         m_path.curve3(28.52, 2.44, 28.47, 6.45);
376         m_path.close_polygon();
377 
378         m_path.move_to(28.47, 9.62);
379         m_path.line_to(28.47, 26.66);
380         m_path.curve3(21.09, 23.73, 18.95, 22.51);
381         m_path.curve3(15.09, 20.36, 13.43, 18.02);
382         m_path.curve3(11.77, 15.67, 11.77, 12.89);
383         m_path.curve3(11.77, 9.38, 13.87, 7.06);
384         m_path.curve3(15.97, 4.74, 18.70, 4.74);
385         m_path.curve3(22.41, 4.74, 28.47, 9.62);
386         m_path.close_polygon();
387 
388         agg::trans_affine shape_mtx;
389         shape_mtx *= agg::trans_affine_scaling(4.0);
390         shape_mtx *= agg::trans_affine_translation(150, 100);
391         m_path.transform(shape_mtx);
392 
393         agg::bounding_rect_single(m_shape, 0,
394                                   &m_shape_bounds.x1, &m_shape_bounds.y1,
395                                   &m_shape_bounds.x2, &m_shape_bounds.y2);
396 
397         m_shadow_ctrl.xn(0) = m_shape_bounds.x1;
398         m_shadow_ctrl.yn(0) = m_shape_bounds.y1;
399         m_shadow_ctrl.xn(1) = m_shape_bounds.x2;
400         m_shadow_ctrl.yn(1) = m_shape_bounds.y1;
401         m_shadow_ctrl.xn(2) = m_shape_bounds.x2;
402         m_shadow_ctrl.yn(2) = m_shape_bounds.y2;
403         m_shadow_ctrl.xn(3) = m_shape_bounds.x1;
404         m_shadow_ctrl.yn(3) = m_shape_bounds.y2;
405         m_shadow_ctrl.line_color(agg::rgba(0, 0.3, 0.5, 0.3));
406 
407 
408         m_color_lut.resize(256);
409         unsigned i;
410         const agg::int8u* p = g_gradient_colors;
411         for(i = 0; i < 256; i++)
412         {
413             m_color_lut[i] = agg::rgba8(p[0], p[1], p[2], (i > 63) ? 255 : i * 4);//p[3]);
414             //m_color_lut[i].premultiply();
415             p += 4;
416         }
417     }
418 
419 
on_resize(int sx,int sy)420     virtual void on_resize(int sx, int sy)
421     {
422         m_gray8_buf.resize(sx * sy);
423         m_gray8_rbuf.attach(m_gray8_buf.data(), sx, sy, sx);
424     }
425 
426 
on_draw()427     virtual void on_draw()
428     {
429         typedef agg::pixfmt_gray8 pixfmt_gray8;
430         typedef agg::renderer_base<pixfmt_gray8> ren_base_gray8;
431 
432         m_ras.clip_box(0,0, width(), height());
433 
434         pixfmt_gray8 pixf_gray8(m_gray8_rbuf);
435         ren_base_gray8 renb_gray8(pixf_gray8);
436         renb_gray8.clear(agg::gray8(0));
437 
438         // Testing enhanced compositing operations.
439         // Uncomment and replace renb.blend_from_* to renb_blend.blend_from_*
440         //----------------
441         //typedef agg::comp_op_rgba_minus<color_type, component_order> blender_type;
442         //typedef agg::comp_adaptor_rgba<blender_type> blend_adaptor_type;
443         //typedef agg::pixfmt_custom_blend_rgba<blend_adaptor_type, agg::rendering_buffer> pixfmt_type;
444         //typedef agg::renderer_base<pixfmt_type> ren_base;
445         //pixfmt_type pixf_blend(rbuf_window());
446         //agg::renderer_base<pixfmt_type> renb_blend(pixf_blend);
447 
448         pixfmt pixf(rbuf_window());
449         agg::renderer_base<pixfmt> renb(pixf);
450         renb.clear(agg::rgba(1, 0.95, 0.95));
451 
452         agg::trans_perspective shadow_persp(m_shape_bounds.x1, m_shape_bounds.y1,
453                                             m_shape_bounds.x2, m_shape_bounds.y2,
454                                             m_shadow_ctrl.polygon());
455 
456         agg::conv_transform<shape_type,
457                             agg::trans_perspective> shadow_trans(m_shape,
458                                                                  shadow_persp);
459 
460         start_timer();
461 
462         // Render shadow
463         m_ras.add_path(shadow_trans);
464         agg::render_scanlines_aa_solid(m_ras, m_sl, renb_gray8, agg::gray8(255));
465 
466         // Calculate the bounding box and extend it by the blur radius
467         agg::rect_d bbox;
468         agg::bounding_rect_single(shadow_trans, 0, &bbox.x1, &bbox.y1, &bbox.x2, &bbox.y2);
469 
470         bbox.x1 -= m_radius.value();
471         bbox.y1 -= m_radius.value();
472         bbox.x2 += m_radius.value();
473         bbox.y2 += m_radius.value();
474 
475         if(bbox.clip(agg::rect_d(0, 0, width(), height())))
476         {
477             // Create a new pixel renderer and attach it to the main one as a child image.
478             // It returns true if the attachment suceeded. It fails if the rectangle
479             // (bbox) is fully clipped.
480             //------------------
481             pixfmt_gray8 pixf2(m_gray8_rbuf2);
482             if(pixf2.attach(pixf_gray8, int(bbox.x1), int(bbox.y1), int(bbox.x2), int(bbox.y2)))
483             {
484                 // Blur it
485                 agg::stack_blur_gray8(pixf2, agg::uround(m_radius.value()),
486                                              agg::uround(m_radius.value()));
487             }
488             if(m_method.cur_item() == 0)
489             {
490                 renb.blend_from_color(pixf2,
491                                       agg::rgba8(0, 100, 0),
492                                       0,
493                                       int(bbox.x1),
494                                       int(bbox.y1));
495             }
496             else
497             {
498                 renb.blend_from_lut(pixf2,
499                                     m_color_lut.data(),
500                                     0,
501                                     int(bbox.x1),
502                                     int(bbox.y1));
503             }
504         }
505         double tm = elapsed_time();
506 
507         char buf[64];
508         agg::gsv_text t;
509         t.size(10.0);
510 
511         agg::conv_stroke<agg::gsv_text> st(t);
512         st.width(1.5);
513 
514         sprintf(buf, "%3.2f ms", tm);
515         t.start_point(140.0, 30.0);
516         t.text(buf);
517 
518         m_ras.add_path(st);
519         agg::render_scanlines_aa_solid(m_ras, m_sl, renb, agg::rgba(0,0,0));
520 
521         agg::render_ctrl(m_ras, m_sl, renb, m_method);
522         agg::render_ctrl(m_ras, m_sl, renb, m_radius);
523         agg::render_ctrl(m_ras, m_sl, renb, m_shadow_ctrl);
524     }
525 
526 };
527 
528 
529 
agg_main(int argc,char * argv[])530 int agg_main(int argc, char* argv[])
531 {
532     the_application app(pix_format, flip_y);
533     app.caption("AGG Example. Gaussian and Stack Blur");
534 
535     if(app.init(440, 330, 0))
536     {
537         return app.run();
538     }
539     return 1;
540 }
541 
542 
543