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.