1// 2// AggPas 2.4 RM3 Demo application 3// Note: Press F1 key on run to see more info about this demo 4// 5// Paths: src;src\ctrl;src\svg;src\util;src\platform\win;expat-wrap 6// 7program 8 conv_contour_ ; 9 10uses 11 agg_basics , 12 agg_platform_support , 13 14 agg_color , 15 agg_pixfmt , 16 agg_pixfmt_rgb , 17 18 agg_ctrl , 19 agg_rbox_ctrl , 20 agg_cbox_ctrl , 21 agg_slider_ctrl , 22 23 agg_rendering_buffer , 24 agg_renderer_base , 25 agg_renderer_scanline , 26 agg_rasterizer_scanline_aa , 27 agg_scanline_p , 28 agg_render_scanlines , 29 30 agg_conv_stroke , 31 agg_conv_transform , 32 agg_conv_curve , 33 agg_conv_contour , 34 agg_path_storage , 35 agg_trans_affine , 36 agg_math_stroke ; 37 38{$I agg_mode.inc } 39 40const 41 flip_y = true; 42 43type 44 the_application = object(platform_support ) 45 m_close : rbox_ctrl; 46 m_width : slider_ctrl; 47 m_auto_detect : cbox_ctrl; 48 m_path : path_storage; 49 50 constructor Construct(format_ : pix_format_e; flip_y_ : boolean ); 51 destructor Destruct; 52 53 procedure compose_path; 54 procedure on_draw; virtual; 55 56 procedure on_key(x ,y : int; key ,flags : unsigned ); virtual; 57 58 end; 59 60{ CONSTRUCT } 61constructor the_application.Construct; 62begin 63 inherited Construct(format_ ,flip_y_ ); 64 65 m_close.Construct (10.0 ,10.0 ,130.0 ,80.0 ,not flip_y_ ); 66 m_width.Construct (130 + 10.0 ,10.0 + 4.0 ,130 + 300.0 ,10.0 + 8.0 + 4.0 ,not flip_y_ ); 67 m_auto_detect.Construct(130 + 10.0 ,10.0 + 4.0 + 16.0 ,'Autodetect orientation if not defined' ,not flip_y_ ); 68 m_path.Construct; 69 70 add_ctrl(@m_close ); 71 72 m_close.add_item ('Close' ); 73 m_close.add_item ('Close CW' ); 74 m_close.add_item ('Close CCW' ); 75 m_close.cur_item_(0 ); 76 77 add_ctrl(@m_width ); 78 79 m_width.range_(-100.0 ,100.0 ); 80 m_width.value_(0.0 ); 81 m_width.label_('Width=%1.2f' ); 82 83 add_ctrl(@m_auto_detect ); 84 85end; 86 87{ DESTRUCT } 88destructor the_application.Destruct; 89begin 90 inherited Destruct; 91 92 m_close.Destruct; 93 m_width.Destruct; 94 m_auto_detect.Destruct; 95 m_path.Destruct; 96 97end; 98 99{ COMPOSE_PATH } 100procedure the_application.compose_path; 101var 102 flag : unsigned; 103 104begin 105 flag:=0; 106 107 if m_close._cur_item = 1 then 108 flag:=path_flags_cw; 109 110 if m_close._cur_item = 2 then 111 flag:=path_flags_ccw; 112 113 m_path.remove_all; 114 115 m_path.move_to(28.47 ,6.45 ); 116 m_path.curve3 (21.58 ,1.12 ,19.82 ,0.29 ); 117 m_path.curve3 (17.19 ,-0.93 ,14.21 ,-0.93 ); 118 m_path.curve3 (9.57 ,-0.93 ,6.57 ,2.25 ); 119 m_path.curve3 (3.56 ,5.42 ,3.56 ,10.60 ); 120 m_path.curve3 (3.56 ,13.87 ,5.03 ,16.26 ); 121 m_path.curve3 (7.03 ,19.58 ,11.99 ,22.51 ); 122 m_path.curve3 (16.94 ,25.44 ,28.47 ,29.64 ); 123 m_path.line_to(28.47 ,31.40 ); 124 m_path.curve3 (28.47 ,38.09 ,26.34 ,40.58 ); 125 m_path.curve3 (24.22 ,43.07 ,20.17 ,43.07 ); 126 m_path.curve3 (17.09 ,43.07 ,15.28 ,41.41 ); 127 m_path.curve3 (13.43 ,39.75 ,13.43 ,37.60 ); 128 m_path.line_to(13.53 ,34.77 ); 129 m_path.curve3 (13.53 ,32.52 ,12.38 ,31.30 ); 130 m_path.curve3 (11.23 ,30.08 ,9.38 ,30.08 ); 131 m_path.curve3 (7.57 ,30.08 ,6.42 ,31.35 ); 132 m_path.curve3 (5.27 ,32.62 ,5.27 ,34.81 ); 133 m_path.curve3 (5.27 ,39.01 ,9.57 ,42.53 ); 134 m_path.curve3 (13.87 ,46.04 ,21.63 ,46.04 ); 135 m_path.curve3 (27.59 ,46.04 ,31.40 ,44.04 ); 136 m_path.curve3 (34.28 ,42.53 ,35.64 ,39.31 ); 137 m_path.curve3 (36.52 ,37.21 ,36.52 ,30.71 ); 138 m_path.line_to(36.52 ,15.53 ); 139 m_path.curve3 (36.52 ,9.13 ,36.77 ,7.69 ); 140 m_path.curve3 (37.01 ,6.25 ,37.57 ,5.76 ); 141 m_path.curve3 (38.13 ,5.27 ,38.87 ,5.27 ); 142 m_path.curve3 (39.65 ,5.27 ,40.23 ,5.62 ); 143 m_path.curve3 (41.26 ,6.25 ,44.19 ,9.18 ); 144 m_path.line_to(44.19 ,6.45 ); 145 m_path.curve3 (38.72 ,-0.88 ,33.74 ,-0.88 ); 146 m_path.curve3 (31.35 ,-0.88 ,29.93 ,0.78 ); 147 m_path.curve3 (28.52 ,2.44 ,28.47 ,6.45 ); 148 149 m_path.close_polygon(flag ); 150 151 m_path.move_to(28.47 ,9.62 ); 152 m_path.line_to(28.47 ,26.66 ); 153 m_path.curve3 (21.09 ,23.73 ,18.95 ,22.51 ); 154 m_path.curve3 (15.09 ,20.36 ,13.43 ,18.02 ); 155 m_path.curve3 (11.77 ,15.67 ,11.77 ,12.89 ); 156 m_path.curve3 (11.77 ,9.38 ,13.87 ,7.06 ); 157 m_path.curve3 (15.97 ,4.74 ,18.70 ,4.74 ); 158 m_path.curve3 (22.41 ,4.74 ,28.47 ,9.62 ); 159 160 m_path.close_polygon(flag ); 161 162end; 163 164{ ON_DRAW } 165procedure the_application.on_draw; 166var 167 pixf : pixel_formats; 168 renb : renderer_base; 169 ren : renderer_scanline_aa_solid; 170 rgba : aggclr; 171 172 ras : rasterizer_scanline_aa; 173 sl : scanline_p8; 174 175 mtx : trans_affine; 176 tas : trans_affine_scaling; 177 tat : trans_affine_translation; 178 179 trans : conv_transform; 180 curve : conv_curve; 181 182 contour : conv_contour; 183 184begin 185// Initialize structures 186 pixfmt_bgr24(pixf ,rbuf_window ); 187 188 renb.Construct(@pixf ); 189 ren.Construct (@renb ); 190 rgba.ConstrDbl(1 ,1 ,1 ); 191 renb.clear (@rgba ); 192 193 ras.Construct; 194 sl.Construct; 195 196// Render 197 mtx.Construct; 198 199 tas.Construct(4.0 ); 200 mtx.multiply (@tas ); 201 202 tat.Construct(150 ,100 ); 203 mtx.multiply (@tat ); 204 205 trans.Construct(@m_path ,@mtx ); 206 curve.Construct(@trans ); 207 208 contour.Construct(@curve ); 209 210 contour.width_ (m_width._value ); 211 //contour.line_join_ (miter_join ); 212 //contour.inner_join_ (miter_join ); 213 //contour.inner_miter_limit_ (4.0 ); 214 contour.auto_detect_orientation_(m_auto_detect._status ); 215 216 compose_path; 217 ras.add_path(@contour ); 218 219 rgba.ConstrDbl(0 ,0 ,0 ); 220 ren.color_ (@rgba ); 221 222 render_scanlines(@ras ,@sl ,@ren ); 223 224// Render the controls 225 render_ctrl(@ras ,@sl ,@ren ,@m_close ); 226 render_ctrl(@ras ,@sl ,@ren ,@m_width ); 227 render_ctrl(@ras ,@sl ,@ren ,@m_auto_detect ); 228 229// Free AGG resources 230 ras.Destruct; 231 sl.Destruct; 232 233 curve.Destruct; 234 contour.Destruct; 235 236end; 237 238{ ON_KEY } 239procedure the_application.on_key; 240begin 241 if key = key_f1 then 242 message_( 243 'One of the converters in AGG is conv_contour. It allows you to extend or shrink '#13 + 244 'polygons. Initially, it was implemented to eliminate the "problem of adjacent edges"'#13 + 245 'in the SVG Viewer, but it can be very useful in many other applications, for example,'#13 + 246 'to change the font weight on the fly. The trick here is that the sign (dilation or '#13 + 247 'shrinking) depends on the vertex order - clockwise or counterclockwise. '#13 + 248 'In the conv_contour you can control the behavior. Sometimes you need to preserve '#13 + 249 'the dilation regardless of the initial orientation, sometimes it should depend '#13 + 250 'on the orientation. The glyph �a� has a "hole" whose orientation differs from '#13 + 251 'the main contour. To change the "weight" correctly, you need to keep the orientation '#13 + 252 'as it is originally defined. If you turn "Autodetect orientation�" on, the glyph will '#13 + 253 'be extended or shrinked incorrectly.'#13#13 + 254 'How to play with:'#13#13 + 255 'The radio buttons control the orientation flad assigned to all polygons.'#13 + 256 '"Close" doesn''t add the flag.'#13 + 257 '"Close CW" and "Close CCW" add "clockwise" or "counterclockwise" flag respectively.' + 258 #13#13'Note: F2 key saves current "screenshot" file in this demo''s directory. ' ); 259 260end; 261 262VAR 263 app : the_application; 264 265BEGIN 266 app.Construct(pix_format_bgr24 ,flip_y ); 267 app.caption_ ('AGG Example. Contour Tool & Polygon Orientation (F1-Help)' ); 268 269 if app.init(440 ,330 ,0 ) then 270 app.run; 271 272 app.Destruct; 273 274END.