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 conv_contour_ ;
9
10uses
11 agg_basics ,
12 agg_platform_support ,
13
14 agg_color ,
15 agg_pixfmt ,
16 agg_pixfmt_rgb ,
17
18 agg_ctrl ,
19 agg_rbox_ctrl ,
20 agg_cbox_ctrl ,
21 agg_slider_ctrl ,
22
23 agg_rendering_buffer ,
24 agg_renderer_base ,
25 agg_renderer_scanline ,
26 agg_rasterizer_scanline_aa ,
27 agg_scanline_p ,
28 agg_render_scanlines ,
29
30 agg_conv_stroke ,
31 agg_conv_transform ,
32 agg_conv_curve ,
33 agg_conv_contour ,
34 agg_path_storage ,
35 agg_trans_affine ,
36 agg_math_stroke ;
37
38{$I agg_mode.inc }
39
40const
41 flip_y = true;
42
43type
44 the_application = object(platform_support )
45   m_close       : rbox_ctrl;
46   m_width       : slider_ctrl;
47   m_auto_detect : cbox_ctrl;
48   m_path        : path_storage;
49
50   constructor Construct(format_ : pix_format_e; flip_y_ : boolean );
51   destructor  Destruct;
52
53   procedure compose_path;
54   procedure on_draw; virtual;
55
56   procedure on_key(x ,y : int; key ,flags : unsigned ); virtual;
57
58  end;
59
60{ CONSTRUCT }
61constructor the_application.Construct;
62begin
63 inherited Construct(format_ ,flip_y_ );
64
65 m_close.Construct      (10.0 ,10.0 ,130.0 ,80.0 ,not flip_y_ );
66 m_width.Construct      (130 + 10.0 ,10.0 + 4.0 ,130 + 300.0 ,10.0 + 8.0 + 4.0 ,not flip_y_ );
67 m_auto_detect.Construct(130 + 10.0 ,10.0 + 4.0 + 16.0 ,'Autodetect orientation if not defined' ,not flip_y_ );
68 m_path.Construct;
69
70 add_ctrl(@m_close );
71
72 m_close.add_item ('Close' );
73 m_close.add_item ('Close CW' );
74 m_close.add_item ('Close CCW' );
75 m_close.cur_item_(0 );
76
77 add_ctrl(@m_width );
78
79 m_width.range_(-100.0 ,100.0 );
80 m_width.value_(0.0 );
81 m_width.label_('Width=%1.2f' );
82
83 add_ctrl(@m_auto_detect );
84
85end;
86
87{ DESTRUCT }
88destructor the_application.Destruct;
89begin
90 inherited Destruct;
91
92 m_close.Destruct;
93 m_width.Destruct;
94 m_auto_detect.Destruct;
95 m_path.Destruct;
96
97end;
98
99{ COMPOSE_PATH }
100procedure the_application.compose_path;
101var
102 flag : unsigned;
103
104begin
105 flag:=0;
106
107 if m_close._cur_item = 1 then
108  flag:=path_flags_cw;
109
110 if m_close._cur_item = 2 then
111  flag:=path_flags_ccw;
112
113 m_path.remove_all;
114
115 m_path.move_to(28.47 ,6.45 );
116 m_path.curve3 (21.58 ,1.12  ,19.82 ,0.29 );
117 m_path.curve3 (17.19 ,-0.93 ,14.21 ,-0.93 );
118 m_path.curve3 (9.57  ,-0.93 ,6.57  ,2.25 );
119 m_path.curve3 (3.56  ,5.42  ,3.56  ,10.60 );
120 m_path.curve3 (3.56  ,13.87 ,5.03  ,16.26 );
121 m_path.curve3 (7.03  ,19.58 ,11.99 ,22.51 );
122 m_path.curve3 (16.94 ,25.44 ,28.47 ,29.64 );
123 m_path.line_to(28.47 ,31.40 );
124 m_path.curve3 (28.47 ,38.09 ,26.34 ,40.58 );
125 m_path.curve3 (24.22 ,43.07 ,20.17 ,43.07 );
126 m_path.curve3 (17.09 ,43.07 ,15.28 ,41.41 );
127 m_path.curve3 (13.43 ,39.75 ,13.43 ,37.60 );
128 m_path.line_to(13.53 ,34.77 );
129 m_path.curve3 (13.53 ,32.52 ,12.38 ,31.30 );
130 m_path.curve3 (11.23 ,30.08 ,9.38  ,30.08 );
131 m_path.curve3 (7.57  ,30.08 ,6.42  ,31.35 );
132 m_path.curve3 (5.27  ,32.62 ,5.27  ,34.81 );
133 m_path.curve3 (5.27  ,39.01 ,9.57  ,42.53 );
134 m_path.curve3 (13.87 ,46.04 ,21.63 ,46.04 );
135 m_path.curve3 (27.59 ,46.04 ,31.40 ,44.04 );
136 m_path.curve3 (34.28 ,42.53 ,35.64 ,39.31 );
137 m_path.curve3 (36.52 ,37.21 ,36.52 ,30.71 );
138 m_path.line_to(36.52 ,15.53 );
139 m_path.curve3 (36.52 ,9.13  ,36.77 ,7.69 );
140 m_path.curve3 (37.01 ,6.25  ,37.57 ,5.76 );
141 m_path.curve3 (38.13 ,5.27  ,38.87 ,5.27 );
142 m_path.curve3 (39.65 ,5.27  ,40.23 ,5.62 );
143 m_path.curve3 (41.26 ,6.25  ,44.19 ,9.18 );
144 m_path.line_to(44.19 ,6.45  );
145 m_path.curve3 (38.72 ,-0.88 ,33.74 ,-0.88 );
146 m_path.curve3 (31.35 ,-0.88 ,29.93 ,0.78 );
147 m_path.curve3 (28.52 ,2.44  ,28.47 ,6.45 );
148
149 m_path.close_polygon(flag );
150
151 m_path.move_to(28.47 ,9.62 );
152 m_path.line_to(28.47 ,26.66 );
153 m_path.curve3 (21.09 ,23.73 ,18.95 ,22.51 );
154 m_path.curve3 (15.09 ,20.36 ,13.43 ,18.02 );
155 m_path.curve3 (11.77 ,15.67 ,11.77 ,12.89 );
156 m_path.curve3 (11.77 ,9.38  ,13.87 ,7.06 );
157 m_path.curve3 (15.97 ,4.74  ,18.70 ,4.74 );
158 m_path.curve3 (22.41 ,4.74  ,28.47 ,9.62 );
159
160 m_path.close_polygon(flag );
161
162end;
163
164{ ON_DRAW }
165procedure the_application.on_draw;
166var
167 pixf : pixel_formats;
168 renb : renderer_base;
169 ren  : renderer_scanline_aa_solid;
170 rgba : aggclr;
171
172 ras : rasterizer_scanline_aa;
173 sl  : scanline_p8;
174
175 mtx : trans_affine;
176 tas : trans_affine_scaling;
177 tat : trans_affine_translation;
178
179 trans : conv_transform;
180 curve : conv_curve;
181
182 contour : conv_contour;
183
184begin
185// Initialize structures
186 pixfmt_bgr24(pixf ,rbuf_window );
187
188 renb.Construct(@pixf );
189 ren.Construct (@renb );
190 rgba.ConstrDbl(1 ,1 ,1 );
191 renb.clear    (@rgba );
192
193 ras.Construct;
194 sl.Construct;
195
196// Render
197 mtx.Construct;
198
199 tas.Construct(4.0 );
200 mtx.multiply (@tas );
201
202 tat.Construct(150 ,100 );
203 mtx.multiply (@tat );
204
205 trans.Construct(@m_path ,@mtx );
206 curve.Construct(@trans );
207
208 contour.Construct(@curve );
209
210 contour.width_                  (m_width._value );
211 //contour.line_join_              (miter_join );
212 //contour.inner_join_             (miter_join );
213 //contour.inner_miter_limit_      (4.0 );
214 contour.auto_detect_orientation_(m_auto_detect._status );
215
216 compose_path;
217 ras.add_path(@contour );
218
219 rgba.ConstrDbl(0 ,0 ,0 );
220 ren.color_    (@rgba );
221
222 render_scanlines(@ras ,@sl ,@ren );
223
224// Render the controls
225 render_ctrl(@ras ,@sl ,@ren ,@m_close );
226 render_ctrl(@ras ,@sl ,@ren ,@m_width );
227 render_ctrl(@ras ,@sl ,@ren ,@m_auto_detect );
228
229// Free AGG resources
230 ras.Destruct;
231 sl.Destruct;
232
233 curve.Destruct;
234 contour.Destruct;
235
236end;
237
238{ ON_KEY }
239procedure the_application.on_key;
240begin
241 if key = key_f1 then
242  message_(
243   'One of the converters in AGG is conv_contour. It allows you to extend or shrink '#13 +
244   'polygons. Initially, it was implemented to eliminate the "problem of adjacent edges"'#13 +
245   'in the SVG Viewer, but it can be very useful in many other applications, for example,'#13 +
246   'to change the font weight on the fly. The trick here is that the sign (dilation or '#13 +
247   'shrinking) depends on the vertex order - clockwise or counterclockwise. '#13 +
248   'In the conv_contour you can control the behavior. Sometimes you need to preserve '#13 +
249   'the dilation regardless of the initial orientation, sometimes it should depend '#13 +
250   'on the orientation. The glyph �a� has a "hole" whose orientation differs from '#13 +
251   'the main contour. To change the "weight" correctly, you need to keep the orientation '#13 +
252   'as it is originally defined. If you turn "Autodetect orientation�" on, the glyph will '#13 +
253   'be extended or shrinked incorrectly.'#13#13 +
254   'How to play with:'#13#13 +
255   'The radio buttons control the orientation flad assigned to all polygons.'#13 +
256   '"Close" doesn''t add the flag.'#13 +
257   '"Close CW" and "Close CCW" add "clockwise" or "counterclockwise" flag respectively.' +
258   #13#13'Note: F2 key saves current "screenshot" file in this demo''s directory.  ' );
259
260end;
261
262VAR
263 app : the_application;
264
265BEGIN
266 app.Construct(pix_format_bgr24 ,flip_y );
267 app.caption_ ('AGG Example. Contour Tool & Polygon Orientation (F1-Help)' );
268
269 if app.init(440 ,330 ,0 ) then
270  app.run;
271
272 app.Destruct;
273
274END.