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_curve2 ;
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_math ,
41 agg_conv_curve ,
42 agg_conv_transform ,
43 agg_trans_double_path ,
44 agg_conv_bspline ,
45 agg_conv_segmentator ,
46 agg_conv_stroke ,
47 agg_font_win32_tt ,
48 agg_font_cache_manager ,
49 interactive_polygon_
50
51{$I pixel_formats.inc }
52{$I agg_mode.inc }
53
54const
55 flip_y = true;
56
57 text_ : PChar =
58  'Anti-Grain Geometry is designed as a set of loosely coupled ' +
59  'algorithms and class templates united with a common idea, ' +
60  'so that all the components can be easily combined. Also, ' +
61  'the template based design allows you to replace any part of ' +
62  'the library without the necessity to modify a single byte in ' +
63  'the existing code. ';
64
65type
66 the_application = object(platform_support )
67   m_feng  : font_engine_win32_tt_int16;
68   m_fman  : font_cache_manager;
69   m_poly1 ,
70   m_poly2 : interactive_polygon;
71
72   m_num_points       : slider_ctrl;
73   m_fixed_len        ,
74   m_preserve_x_scale ,
75   m_animate          : cbox_ctrl;
76
77   m_dx1 ,
78   m_dy1 ,
79   m_dx2 ,
80   m_dy2 : array[0..5 ] of double;
81
82   m_prev_animate : boolean;
83
84   constructor Construct(dc : HDC; format_ : pix_format_e; flip_y_ : boolean );
85   destructor  Destruct;
86
87   procedure on_init; virtual;
88   procedure on_draw; virtual;
89
90   procedure on_mouse_move       (x ,y : int; flags : unsigned ); virtual;
91   procedure on_mouse_button_down(x ,y : int; flags : unsigned ); virtual;
92   procedure on_mouse_button_up  (x ,y : int; flags : unsigned ); virtual;
93
94   procedure on_key(x ,y : int; key ,flags : unsigned ); virtual;
95   procedure on_ctrl_change; virtual;
96
97   procedure move_point     (x ,y ,dx ,dy : double_ptr );
98   procedure normalize_point(i : unsigned );
99
100   procedure on_idle; virtual;
101
102  end;
103
104{ CONSTRUCT }
105constructor the_application.Construct;
106begin
107 inherited Construct(format_ ,flip_y_ );
108
109 m_feng.Construct (dc );
110 m_fman.Construct (@m_feng );
111 m_poly1.Construct(6 ,5.0 );
112 m_poly2.Construct(6 ,5.0 );
113
114 m_num_points.Construct      (5.0 ,5.0  ,340.0 ,12.0 ,not flip_y_ );
115 m_fixed_len.Construct       (350 ,5.0  ,'Fixed Length' ,not flip_y_ );
116 m_preserve_x_scale.Construct(465 ,5.0  ,'Preserve X scale' ,not flip_y_ );
117 m_animate.Construct         (350 ,25.0 ,'Animate' ,not flip_y_ );
118
119 m_prev_animate:=false;
120
121 add_ctrl(@m_fixed_len );
122 add_ctrl(@m_preserve_x_scale );
123 add_ctrl(@m_animate );
124
125 m_fixed_len.status_       (true );
126 m_preserve_x_scale.status_(true );
127
128 m_num_points.range_(10.0 ,400.0 );
129 m_num_points.value_(200.0 );
130 m_num_points.label_('Number of intermediate Points = %.3f' );
131
132 add_ctrl(@m_num_points );
133
134 m_poly1.close_(false );
135 m_poly2.close_(false );
136
137end;
138
139{ DESTRUCT }
140destructor the_application.Destruct;
141begin
142 inherited Destruct;
143
144 m_num_points.Destruct;
145 m_fixed_len.Destruct;
146 m_preserve_x_scale.Destruct;
147 m_animate.Destruct;
148
149 m_poly1.Destruct;
150 m_poly2.Destruct;
151
152 m_feng.Destruct;
153 m_fman.Destruct;
154
155end;
156
157{ ON_INIT }
158procedure the_application.on_init;
159begin
160 m_poly1.xn_ptr(0 )^:= 10 + 50;
161 m_poly1.yn_ptr(0 )^:=-10 + 50;
162 m_poly1.xn_ptr(1 )^:= 10 + 150 + 20;
163 m_poly1.yn_ptr(1 )^:=-10 + 150 - 20;
164 m_poly1.xn_ptr(2 )^:= 10 + 250 - 20;
165 m_poly1.yn_ptr(2 )^:=-10 + 250 + 20;
166 m_poly1.xn_ptr(3 )^:= 10 + 350 + 20;
167 m_poly1.yn_ptr(3 )^:=-10 + 350 - 20;
168 m_poly1.xn_ptr(4 )^:= 10 + 450 - 20;
169 m_poly1.yn_ptr(4 )^:=-10 + 450 + 20;
170 m_poly1.xn_ptr(5 )^:= 10 + 550;
171 m_poly1.yn_ptr(5 )^:=-10 + 550;
172
173 m_poly2.xn_ptr(0 )^:=-10 + 50;
174 m_poly2.yn_ptr(0 )^:= 10 + 50;
175 m_poly2.xn_ptr(1 )^:=-10 + 150 + 20;
176 m_poly2.yn_ptr(1 )^:= 10 + 150 - 20;
177 m_poly2.xn_ptr(2 )^:=-10 + 250 - 20;
178 m_poly2.yn_ptr(2 )^:= 10 + 250 + 20;
179 m_poly2.xn_ptr(3 )^:=-10 + 350 + 20;
180 m_poly2.yn_ptr(3 )^:= 10 + 350 - 20;
181 m_poly2.xn_ptr(4 )^:=-10 + 450 - 20;
182 m_poly2.yn_ptr(4 )^:= 10 + 450 + 20;
183 m_poly2.xn_ptr(5 )^:=-10 + 550;
184 m_poly2.yn_ptr(5 )^:= 10 + 550;
185
186end;
187
188{ ON_DRAW }
189procedure the_application.on_draw;
190var
191 pixf : pixel_formats;
192 rgba : aggclr;
193
194 rb : renderer_base;
195 r  : renderer_scanline_aa_solid;
196 sl : scanline_p8;
197
198 ras : rasterizer_scanline_aa;
199
200 path1 ,
201 path2 : simple_polygon_vertex_source;
202
203 bspline1 ,
204 bspline2 : conv_bspline;
205
206 tcurve  : trans_double_path;
207 fcurves : conv_curve;
208 fsegm   : conv_segmentator;
209 ftrans  : conv_transform;
210
211 x ,y : double;
212
213 p : int8u_ptr;
214
215 glyph : glyph_cache_ptr;
216
217 stroke1 ,
218 stroke2 : conv_stroke;
219
220begin
221// Initialize structures
222 pixfmt(pixf ,rbuf_window );
223
224 rb.Construct(@pixf );
225 r.Construct (@rb );
226
227 rgba.ConstrDbl(1 ,1 ,1 );
228 rb.clear      (@rgba );
229
230 sl.Construct;
231 ras.Construct;
232
233// Render the text
234 path1.Construct(m_poly1.polygon ,m_poly1.num_points ,false ,false );
235 path2.Construct(m_poly2.polygon ,m_poly2.num_points ,false ,false );
236
237 bspline1.Construct(@path1 );
238 bspline2.Construct(@path2 );
239
240 bspline1.interpolation_step_(1.0 / m_num_points._value );
241 bspline2.interpolation_step_(1.0 / m_num_points._value );
242
243 tcurve.Construct;
244 fcurves.Construct(m_fman.path_adaptor );
245 fsegm.Construct  (@fcurves);
246 ftrans.Construct (@fsegm ,@tcurve );
247
248 tcurve.preserve_x_scale_(m_preserve_x_scale._status );
249
250 if m_fixed_len._status then
251  tcurve.base_length_(1140.0 );
252
253 tcurve.base_height_(30.0 );
254 tcurve.add_paths   (@bspline1 ,@bspline2 );
255
256 fsegm.approximation_scale_  (3.0 );
257 fcurves.approximation_scale_(5.0 );
258
259 m_feng.height_ (40.0 );
260 m_feng.hinting_(false );
261 m_feng.italic_ (true );
262
263 if m_feng.create_font('Times New Roman' ,glyph_ren_outline ) then
264  begin
265   x:=0.0;
266   y:=3.0;
267   p:=@text_[0 ];
268
269   while p^ <> 0 do
270    begin
271     glyph:=m_fman.glyph(p^ );
272
273     if glyph <> NIL then
274      begin
275       if x > tcurve.total_length1 then
276        break;
277
278       m_fman.add_kerning           (@x ,@y );
279       m_fman.init_embedded_adaptors(glyph ,x ,y );
280
281       if glyph.data_type = glyph_data_outline then
282        begin
283         ras.reset;
284         ras.add_path(@ftrans );
285
286         rgba.ConstrInt(0 ,0 ,0 );
287         r.color_      (@rgba );
288
289         render_scanlines(@ras ,@sl ,@r );
290
291        end;
292
293      // increment pen position
294       x:=x + glyph.advance_x;
295       y:=y + glyph.advance_y;
296
297      end;
298
299     inc(ptrcomp(p ) ,sizeof(int8u ) );
300
301    end;
302
303  end;
304
305// Render the path curve
306 stroke1.Construct(@bspline1 );
307 stroke2.Construct(@bspline2 );
308
309 stroke1.width_(2.0 );
310 stroke2.width_(2.0 );
311
312 rgba.ConstrInt(170 ,50 ,20 ,100 );
313 r.color_      (@rgba );
314
315 ras.add_path    (@stroke1 );
316 render_scanlines(@ras ,@sl ,@r );
317
318 ras.add_path    (@stroke2);
319 render_scanlines(@ras ,@sl ,@r );
320
321// Render the "poly" tool
322 rgba.ConstrDbl(0 ,0.3 ,0.5 ,0.2 );
323 r.color_      (@rgba );
324
325 ras.add_path    (@m_poly1 );
326 render_scanlines(@ras ,@sl ,@r );
327
328 ras.add_path    (@m_poly2 );
329 render_scanlines(@ras ,@sl ,@r );
330
331// Render the controls
332 render_ctrl(@ras ,@sl ,@r ,@m_fixed_len );
333 render_ctrl(@ras ,@sl ,@r ,@m_preserve_x_scale );
334 render_ctrl(@ras ,@sl ,@r ,@m_animate );
335 render_ctrl(@ras ,@sl ,@r ,@m_num_points );
336
337// Free AGG resources
338 sl.Destruct;
339 ras.Destruct;
340
341 bspline1.Destruct;
342 bspline2.Destruct;
343 tcurve.Destruct;
344 fcurves.Destruct;
345 fsegm.Destruct;
346
347 stroke1.Destruct;
348 stroke2.Destruct;
349
350end;
351
352{ ON_MOUSE_MOVE }
353procedure the_application.on_mouse_move;
354begin
355 if flags and mouse_left <> 0 then
356  begin
357   if m_poly1.on_mouse_move(x ,y ) then
358    force_redraw;
359
360   if m_poly2.on_mouse_move(x ,y ) then
361    force_redraw;
362
363  end;
364
365 if flags and mouse_left = 0 then
366  on_mouse_button_up(x ,y ,flags );
367
368end;
369
370{ ON_MOUSE_BUTTON_DOWN }
371procedure the_application.on_mouse_button_down;
372begin
373 if flags and mouse_left <> 0 then
374  begin
375   if m_poly1.on_mouse_button_down(x ,y ) then
376    force_redraw;
377
378   if m_poly2.on_mouse_button_down(x ,y ) then
379    force_redraw;
380
381  end;
382
383end;
384
385{ ON_MOUSE_BUTTON_UP }
386procedure the_application.on_mouse_button_up;
387begin
388 if m_poly1.on_mouse_button_up(x ,y ) then
389  force_redraw;
390
391 if m_poly2.on_mouse_button_up(x ,y ) then
392  force_redraw;
393
394end;
395
396{ ON_KEY }
397procedure the_application.on_key;
398begin
399 if key = key_f1 then
400  message_(
401   'Similar to the "trans_curve1" demo, but here the transformer operates with two '#13 +
402   'arbitrary curves. It requires more calculations, but gives you more freedom. '#13 +
403   'In other words you will see :-).' +
404   #13#13'Note: F2 key saves current "screenshot" file in this demo''s directory.  ' );
405
406end;
407
408{ ON_CTRL_CHANGE }
409procedure the_application.on_ctrl_change;
410var
411 i : int;
412
413begin
414 if m_animate._status <> m_prev_animate then
415  begin
416   if m_animate._status then
417    begin
418     on_init;
419
420     for i:=0 to 5 do
421      begin
422       m_dx1[i ]:=((Random($7fff ) mod 1000 ) - 500 ) * 0.01;
423       m_dy1[i ]:=((Random($7fff ) mod 1000 ) - 500 ) * 0.01;
424       m_dx2[i ]:=((Random($7fff ) mod 1000 ) - 500 ) * 0.01;
425       m_dy2[i ]:=((Random($7fff ) mod 1000 ) - 500 ) * 0.01;
426
427      end;
428
429     wait_mode_(false );
430
431    end
432   else
433    wait_mode_(true );
434
435   m_prev_animate:=m_animate._status;
436
437  end;
438
439end;
440
441{ MOVE_POINT }
442procedure the_application.move_point;
443begin
444 if x^ < 0.0 then
445  begin
446   x^ :=0.0;
447   dx^:=-dx^;
448
449  end;
450
451 if x^ > _width then
452  begin
453   x^ :=_width;
454   dx^:=-dx^;
455
456  end;
457
458 if y^ < 0.0 then
459  begin
460   y^ :=0.0;
461   dy^:=-dy^;
462
463  end;
464
465 if y^ > _height then
466  begin
467   y^ :=_height;
468   dy^:=-dy^;
469
470  end;
471
472 x^:=x^ + dx^;
473 y^:=y^ + dy^;
474
475end;
476
477{ NORMALIZE_POINT }
478procedure the_application.normalize_point;
479var
480 d : double;
481
482begin
483 d:=
484  calc_distance(
485   m_poly1.xn_ptr(i )^ ,m_poly1.yn_ptr(i )^ ,
486   m_poly2.xn_ptr(i )^ ,m_poly2.yn_ptr(i )^ );
487
488// 28.8 is 20 * sqrt(2)
489 if d > 28.28 then
490  begin
491   m_poly2.xn_ptr(i )^:=
492    m_poly1.xn_ptr(i )^ +
493    (m_poly2.xn_ptr(i )^ -
494     m_poly1.xn_ptr(i )^ ) * 28.28 / d;
495
496   m_poly2.yn_ptr(i )^:=
497    m_poly1.yn_ptr(i )^ +
498    (m_poly2.yn_ptr(i )^ -
499     m_poly1.yn_ptr(i )^ ) * 28.28 / d;
500
501  end;
502
503end;
504
505{ ON_IDLE }
506procedure the_application.on_idle;
507var
508 i : int;
509
510begin
511 for i:=0 to 5 do
512  begin
513   move_point(m_poly1.xn_ptr(i ) ,m_poly1.yn_ptr(i ) ,@m_dx1[i ] ,@m_dy1[i ] );
514   move_point(m_poly2.xn_ptr(i ) ,m_poly2.yn_ptr(i ) ,@m_dx2[i ] ,@m_dy2[i ] );
515
516   normalize_point(i);
517
518  end;
519
520 force_redraw;
521
522end;
523
524VAR
525 app : the_application;
526 dc  : HDC;
527
528BEGIN
529 dc:=GetDC(0 );
530
531 app.Construct(dc ,pix_format ,flip_y );
532 app.caption_ ('AGG Example. Non-linear "Along-A-Curve" Transformer - Win32 (F1-Help)' );
533
534 if app.init(600 ,600 ,window_resize ) then
535  app.run;
536
537 app.Destruct;
538
539 ReleaseDC(0 ,dc );
540
541END.