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