1{target:win} 2// 3// AggPas 2.4 RM3 Demo application 4// Note: Press F1 key on run to see more info about this demo 5// 6// Paths: src;src\ctrl;src\svg;src\util;src\platform\win;expat-wrap 7// 8program 9 trans_curve1 ; 10 11{DEFINE AGG_GRAY8 } 12{$DEFINE AGG_BGR24 } 13{DEFINE AGG_RGB24 } 14{DEFINE AGG_BGRA32 } 15{DEFINE AGG_RGBA32 } 16{DEFINE AGG_ARGB32 } 17{DEFINE AGG_ABGR32 } 18{DEFINE AGG_RGB565 } 19{DEFINE AGG_RGB555 } 20 21uses 22 Windows , 23 24 agg_basics , 25 agg_platform_support , 26 27 agg_ctrl , 28 agg_cbox_ctrl , 29 agg_slider_ctrl , 30 31 agg_rasterizer_scanline_aa , 32 agg_scanline , 33 agg_scanline_p , 34 35 agg_rendering_buffer , 36 agg_renderer_base , 37 agg_renderer_scanline , 38 agg_render_scanlines , 39 40 agg_conv_curve , 41 agg_conv_transform , 42 agg_conv_bspline , 43 agg_conv_segmentator , 44 agg_conv_stroke , 45 agg_font_win32_tt , 46 agg_font_cache_manager , 47 agg_trans_single_path , 48 interactive_polygon_ 49 50{$I pixel_formats.inc } 51{$I agg_mode.inc } 52 53const 54 flip_y = true; 55 56 text_ : PChar = 57 'Anti-Grain Geometry is designed as a set of loosely coupled ' + 58 'algorithms and class templates united with a common idea, ' + 59 'so that all the components can be easily combined. Also, ' + 60 'the template based design allows you to replace any part of ' + 61 'the library without the necessity to modify a single byte in ' + 62 'the existing code. '; 63 64type 65 the_application = object(platform_support ) 66 m_feng : font_engine_win32_tt_int16; 67 m_fman : font_cache_manager; 68 m_poly : interactive_polygon; 69 70 m_num_points : slider_ctrl; 71 m_close , 72 m_preserve_x_scale , 73 m_fixed_len , 74 m_animate : cbox_ctrl; 75 76 m_dx , 77 m_dy : array[0..5 ] of double; 78 79 m_prev_animate : boolean; 80 81 constructor Construct(dc : HDC; format_ : pix_format_e; flip_y_ : boolean ); 82 destructor Destruct; 83 84 procedure on_init; virtual; 85 procedure on_draw; virtual; 86 87 procedure on_mouse_move (x ,y : int; flags : unsigned ); virtual; 88 procedure on_mouse_button_down(x ,y : int; flags : unsigned ); virtual; 89 procedure on_mouse_button_up (x ,y : int; flags : unsigned ); virtual; 90 91 procedure on_key(x ,y : int; key ,flags : unsigned ); virtual; 92 procedure on_ctrl_change; virtual; 93 94 procedure move_point(x ,y ,dx ,dy : double_ptr ); 95 96 procedure on_idle; virtual; 97 98 end; 99 100{ CONSTRUCT } 101constructor the_application.Construct; 102begin 103 inherited Construct(format_ ,flip_y_ ); 104 105 m_feng.Construct(dc ); 106 m_fman.Construct(@m_feng ); 107 m_poly.Construct(6 ,5.0 ); 108 109 m_num_points.Construct (5.0 ,5.0 ,340.0 ,12.0 ,not flip_y_ ); 110 m_close.Construct (350 ,5.0 ,'Close' ,not flip_y_ ); 111 m_preserve_x_scale.Construct(460 ,5.0 ,'Preserve X scale' ,not flip_y_ ); 112 m_fixed_len.Construct (350 ,25.0 ,'Fixed Length' ,not flip_y_ ); 113 m_animate.Construct (460 ,25.0 ,'Animate' ,not flip_y_ ); 114 115 m_prev_animate:=false; 116 117 add_ctrl(@m_close ); 118 add_ctrl(@m_preserve_x_scale ); 119 add_ctrl(@m_fixed_len ); 120 add_ctrl(@m_animate ); 121 122 m_preserve_x_scale.status_(true ); 123 m_fixed_len.status_ (true ); 124 125 m_num_points.range_(10.0 ,400.0 ); 126 m_num_points.value_(200.0 ); 127 m_num_points.label_('Number of intermediate Points = %.3f' ); 128 129 add_ctrl(@m_num_points ); 130 131end; 132 133{ DESTRUCT } 134destructor the_application.Destruct; 135begin 136 inherited Destruct; 137 138 m_poly.Destruct; 139 140 m_num_points.Destruct; 141 m_close.Destruct; 142 m_preserve_x_scale.Destruct; 143 m_fixed_len.Destruct; 144 m_animate.Destruct; 145 146 m_feng.Destruct; 147 m_fman.Destruct; 148 149end; 150 151{ ON_INIT } 152procedure the_application.on_init; 153begin 154 m_poly.xn_ptr(0 )^:=50; 155 m_poly.yn_ptr(0 )^:=50; 156 m_poly.xn_ptr(1 )^:=150 + 20; 157 m_poly.yn_ptr(1 )^:=150 - 20; 158 m_poly.xn_ptr(2 )^:=250 - 20; 159 m_poly.yn_ptr(2 )^:=250 + 20; 160 m_poly.xn_ptr(3 )^:=350 + 20; 161 m_poly.yn_ptr(3 )^:=350 - 20; 162 m_poly.xn_ptr(4 )^:=450 - 20; 163 m_poly.yn_ptr(4 )^:=450 + 20; 164 m_poly.xn_ptr(5 )^:=550; 165 m_poly.yn_ptr(5 )^:=550; 166 167end; 168 169{ ON_DRAW } 170procedure the_application.on_draw; 171var 172 pixf : pixel_formats; 173 rgba : aggclr; 174 175 rb : renderer_base; 176 r : renderer_scanline_aa_solid; 177 sl : scanline_p8; 178 179 ras : rasterizer_scanline_aa; 180 181 path : simple_polygon_vertex_source; 182 bspline : conv_bspline; 183 tcurve : trans_single_path; 184 fcurves : conv_curve; 185 fsegm : conv_segmentator; 186 ftrans : conv_transform; 187 188 x ,y : double; 189 190 p : int8u_ptr; 191 192 glyph : glyph_cache_ptr; 193 194 stroke : conv_stroke; 195 196begin 197// Initialize structures 198 pixfmt(pixf ,rbuf_window ); 199 200 rb.Construct(@pixf ); 201 r.Construct (@rb ); 202 203 rgba.ConstrDbl(1 ,1 ,1 ); 204 rb.clear (@rgba ); 205 206 sl.Construct; 207 ras.Construct; 208 209 m_poly.close_(m_close._status ); 210 211// Render the text 212 path.Construct (m_poly.polygon ,m_poly.num_points ,false ,m_close._status ); 213 bspline.Construct(@path ); 214 215 bspline.interpolation_step_(1.0 / m_num_points._value ); 216 217 tcurve.Construct; 218 tcurve.add_path (@bspline ); 219 tcurve.preserve_x_scale_(m_preserve_x_scale._status ); 220 221 if m_fixed_len._status then 222 tcurve.base_length_(1120 ); 223 224 fcurves.Construct(m_fman.path_adaptor ); 225 fsegm.Construct (@fcurves ); 226 ftrans.Construct (@fsegm ,@tcurve ); 227 228 fsegm.approximation_scale_ (3.0 ); 229 fcurves.approximation_scale_(2.0 ); 230 231 m_feng.height_(40.0 ); 232 //m_feng.italic_(true ); 233 234 if m_feng.create_font('Times New Roman' ,glyph_ren_outline ) then 235 begin 236 x:=0.0; 237 y:=3.0; 238 p:=@text_[0 ]; 239 240 while p^ <> 0 do 241 begin 242 glyph:=m_fman.glyph(p^ ); 243 244 if glyph <> NIL then 245 begin 246 if x > tcurve.total_length then 247 break; 248 249 m_fman.add_kerning (@x ,@y ); 250 m_fman.init_embedded_adaptors(glyph ,x ,y ); 251 252 if glyph.data_type = glyph_data_outline then 253 begin 254 ras.reset; 255 ras.add_path(@ftrans ); 256 257 rgba.ConstrInt(0 ,0 ,0 ); 258 r.color_ (@rgba ); 259 260 render_scanlines(@ras ,@sl ,@r ); 261 262 end; 263 264 // increment pen position 265 x:=x + glyph.advance_x; 266 y:=y + glyph.advance_y; 267 268 end; 269 270 inc(ptrcomp(p ) ,sizeof(int8u ) ); 271 272 end; 273 274 end; 275 276// Render the path curve 277 stroke.Construct(@bspline ); 278 stroke.width_ (2.0 ); 279 280 rgba.ConstrInt(170 ,50 ,20 ,100 ); 281 r.color_ (@rgba ); 282 283 ras.add_path (@stroke ); 284 render_scanlines(@ras ,@sl ,@r ); 285 286// Render the "poly" tool 287 rgba.ConstrDbl(0 ,0.3 ,0.5 ,0.3 ); 288 r.color_ (@rgba ); 289 290 ras.add_path (@m_poly ); 291 render_scanlines(@ras ,@sl ,@r ); 292 293// Render the controls 294 render_ctrl(@ras ,@sl ,@r ,@m_close ); 295 render_ctrl(@ras ,@sl ,@r ,@m_preserve_x_scale ); 296 render_ctrl(@ras ,@sl ,@r ,@m_fixed_len ); 297 render_ctrl(@ras ,@sl ,@r ,@m_animate ); 298 render_ctrl(@ras ,@sl ,@r ,@m_num_points ); 299 300// Free AGG resources 301 sl.Destruct; 302 ras.Destruct; 303 304 bspline.Destruct; 305 tcurve.Destruct; 306 fcurves.Destruct; 307 fsegm.Destruct; 308 309 stroke.Destruct; 310 311end; 312 313{ ON_MOUSE_MOVE } 314procedure the_application.on_mouse_move; 315begin 316 if flags and mouse_left <> 0 then 317 if m_poly.on_mouse_move(x ,y ) then 318 force_redraw; 319 320 if flags and mouse_left = 0 then 321 on_mouse_button_up(x ,y ,flags ); 322 323end; 324 325{ ON_MOUSE_BUTTON_DOWN } 326procedure the_application.on_mouse_button_down; 327begin 328 if flags and mouse_left <> 0 then 329 if m_poly.on_mouse_button_down(x ,y ) then 330 force_redraw; 331 332end; 333 334{ ON_MOUSE_BUTTON_UP } 335procedure the_application.on_mouse_button_up; 336begin 337 if m_poly.on_mouse_button_up(x ,y ) then 338 force_redraw; 339 340end; 341 342{ ON_KEY } 343procedure the_application.on_key; 344begin 345 if key = key_f1 then 346 message_( 347 'This is a "kinda-cool-stuff" demo that performs non-linear transformations and '#13 + 348 'draws vector text along a curve. Note that it''s not just calculating of the glyph '#13 + 349 'angles and positions, they are transformed as if they were elastic. The curve is '#13 + 350 'calculated as a bicubic spline. The option "Preserve X scale" makes the converter '#13 + 351 'distribute all the points uniformly along the curve. If it''s unchechked, the scale '#13 + 352 'will be proportional to the distance between the control points.' + 353 #13#13'Note: F2 key saves current "screenshot" file in this demo''s directory. ' ); 354 355end; 356 357{ ON_CTRL_CHANGE } 358procedure the_application.on_ctrl_change; 359var 360 i : int; 361 362begin 363 if m_animate._status <> m_prev_animate then 364 begin 365 if m_animate._status then 366 begin 367 on_init; 368 369 for i:=0 to 5 do 370 begin 371 m_dx[i ]:=((Random($7fff ) mod 1000 ) - 500 ) * 0.01; 372 m_dy[i ]:=((Random($7fff ) mod 1000 ) - 500 ) * 0.01; 373 374 end; 375 376 wait_mode_(false ); 377 378 end 379 else 380 wait_mode_(true ); 381 382 m_prev_animate:=m_animate._status; 383 384 end; 385 386end; 387 388{ MOVE_POINT } 389procedure the_application.move_point; 390begin 391 if x^ < 0.0 then 392 begin 393 x^ :=0.0; 394 dx^:=-dx^; 395 396 end; 397 398 if x^ > _width then 399 begin 400 x^ :=_width; 401 dx^:=-dx^; 402 403 end; 404 405 if y^ < 0.0 then 406 begin 407 y^ :=0.0; 408 dy^:=-dy^; 409 410 end; 411 412 if y^ > _height then 413 begin 414 y^ :=_height; 415 dy^:=-dy^; 416 417 end; 418 419 x^:=x^ + dx^; 420 y^:=y^ + dy^; 421 422end; 423 424{ ON_IDLE } 425procedure the_application.on_idle; 426var 427 i : int; 428 429begin 430 for i:=0 to 5 do 431 move_point(m_poly.xn_ptr(i ) ,m_poly.yn_ptr(i ) ,@m_dx[i ] ,@m_dy[i ] ); 432 433 force_redraw; 434 435end; 436 437VAR 438 app : the_application; 439 dc : HDC; 440 441BEGIN 442 dc:=GetDC(0 ); 443 444 app.Construct(dc ,pix_format ,flip_y ); 445 app.caption_ ('AGG Example. Non-linear "Along-A-Curve" Transformer - Win32 (F1-Help)' ); 446 447 if app.init(600 ,600 ,window_resize ) then 448 app.run; 449 450 app.Destruct; 451 452 ReleaseDC(0 ,dc ); 453 454END.