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