1{mac_copy:1.bmp}
2{mac_copy:2.bmp}
3{mac_copy:3.bmp}
4{mac_copy:4.bmp}
5{mac_copy:5.bmp}
6{mac_copy:6.bmp}
7{mac_copy:7.bmp}
8{mac_copy:8.bmp}
9{mac_copy:9.bmp}
10//
11// AggPas 2.4 RM3 Demo application
12// Note: Press F1 key on run to see more info about this demo
13//
14// Paths: src;src\ctrl;src\svg;src\util;src\platform\win;expat-wrap
15//
16program
17 line_patterns ;
18
19uses
20 SysUtils ,
21
22 agg_basics ,
23 agg_platform_support ,
24
25 agg_color ,
26 agg_pixfmt ,
27 agg_pixfmt_rgb ,
28
29 agg_ctrl ,
30 agg_slider_ctrl ,
31 agg_bezier_ctrl ,
32
33 agg_rendering_buffer ,
34 agg_renderer_base ,
35 agg_renderer_scanline ,
36 agg_renderer_outline_aa ,
37 agg_renderer_outline_image ,
38 agg_rasterizer_scanline_aa ,
39 agg_rasterizer_outline_aa ,
40 agg_scanline ,
41 agg_scanline_p ,
42 agg_render_scanlines ,
43
44 agg_pattern_filters_rgba ,
45 agg_conv_stroke ,
46 agg_conv_transform ,
47 agg_conv_clip_polyline ,
48 agg_vertex_source ;
49
50{$I agg_mode.inc }
51{$I- }
52const
53 flip_y = true;
54
55 brightness_to_alpha : array[0..256 * 3 - 1 ] of int8u = (
56
57  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
58  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
59  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
60  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
61  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
62  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
63  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
64  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
65  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
66  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 254, 254, 254,
67  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
68  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
69  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
70  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
71  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
72  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
73  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
74  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
75  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
76  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
77  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
78  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
79  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
80  254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 253, 253,
81  253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 252,
82  252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 251, 251, 251, 251, 251,
83  251, 251, 251, 251, 250, 250, 250, 250, 250, 250, 250, 250, 249, 249, 249, 249,
84  249, 249, 249, 248, 248, 248, 248, 248, 248, 248, 247, 247, 247, 247, 247, 246,
85  246, 246, 246, 246, 246, 245, 245, 245, 245, 245, 244, 244, 244, 244, 243, 243,
86  243, 243, 243, 242, 242, 242, 242, 241, 241, 241, 241, 240, 240, 240, 239, 239,
87  239, 239, 238, 238, 238, 238, 237, 237, 237, 236, 236, 236, 235, 235, 235, 234,
88  234, 234, 233, 233, 233, 232, 232, 232, 231, 231, 230, 230, 230, 229, 229, 229,
89  228, 228, 227, 227, 227, 226, 226, 225, 225, 224, 224, 224, 223, 223, 222, 222,
90  221, 221, 220, 220, 219, 219, 219, 218, 218, 217, 217, 216, 216, 215, 214, 214,
91  213, 213, 212, 212, 211, 211, 210, 210, 209, 209, 208, 207, 207, 206, 206, 205,
92  204, 204, 203, 203, 202, 201, 201, 200, 200, 199, 198, 198, 197, 196, 196, 195,
93  194, 194, 193, 192, 192, 191, 190, 190, 189, 188, 188, 187, 186, 186, 185, 184,
94  183, 183, 182, 181, 180, 180, 179, 178, 177, 177, 176, 175, 174, 174, 173, 172,
95  171, 171, 170, 169, 168, 167, 166, 166, 165, 164, 163, 162, 162, 161, 160, 159,
96  158, 157, 156, 156, 155, 154, 153, 152, 151, 150, 149, 148, 148, 147, 146, 145,
97  144, 143, 142, 141, 140, 139, 138, 137, 136, 135, 134, 133, 132, 131, 130, 129,
98  128, 128, 127, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113,
99  112, 111, 110, 109, 108, 107, 106, 105, 104, 102, 101, 100,  99,  98,  97,  96,
100   95,  94,  93,  91,  90,  89,  88,  87,  86,  85,  84,  82,  81,  80,  79,  78,
101   77,  75,  74,  73,  72,  71,  70,  69,  67,  66,  65,  64,  63,  61,  60,  59,
102   58,  57,  56,  54,  53,  52,  51,  50,  48,  47,  46,  45,  44,  42,  41,  40,
103   39,  37,  36,  35,  34,  33,  31,  30,  29,  28,  27,  25,  24,  23,  22,  20,
104   19,  18,  17,  15,  14,  13,  12,  11,   9,   8,   7,   6,   4,   3,   2,   1 );
105
106type
107 pattern_src_brightness_to_alpha_rgba8 = object(pixel_source )
108   m_rb : rendering_buffer_ptr;
109   m_pf : pixel_formats;
110
111   constructor Construct(rb : rendering_buffer_ptr );
112
113   function  _width : unsigned; virtual;
114   function  _height : unsigned; virtual;
115
116   function  pixel(x ,y : int ) : rgba8; virtual;
117
118  end;
119
120 the_application = object(platform_support )
121   m_ctrl_color : aggclr;
122
123   m_curve1  ,
124   m_curve2  ,
125   m_curve3  ,
126   m_curve4  ,
127   m_curve5  ,
128   m_curve6  ,
129   m_curve7  ,
130   m_curve8  ,
131   m_curve9  : bezier_ctrl;
132   m_scale_x ,
133   m_start_x : slider_ctrl;
134
135   constructor Construct(format_ : pix_format_e; flip_y_ : boolean );
136   destructor  Destruct;
137
138   procedure draw_curve(
139              patt : line_image_pattern_ptr;
140              ras  : rasterizer_outline_aa_ptr;
141              ren  : renderer_outline_image_ptr;
142              src  : pixel_source_ptr;
143              vs   : vertex_source_ptr );
144
145   procedure on_draw; virtual;
146
147   procedure on_key(x ,y : int; key ,flags : unsigned ); virtual;
148   procedure on_ctrl_change; virtual;
149
150  end;
151
152{ CONSTRUCT }
153constructor pattern_src_brightness_to_alpha_rgba8.Construct;
154begin
155 m_rb:=rb;
156
157 pixfmt_bgr24(m_pf ,m_rb );
158
159end;
160
161{ _WIDTH }
162function pattern_src_brightness_to_alpha_rgba8._width;
163begin
164 result:=m_pf._width;
165
166end;
167
168{ _HEIGHT }
169function pattern_src_brightness_to_alpha_rgba8._height;
170begin
171 result:=m_pf._height;
172
173end;
174
175{ PIXEL }
176function pattern_src_brightness_to_alpha_rgba8.pixel;
177var
178 c : aggclr;
179
180begin
181 c  :=m_pf.pixel(@m_pf ,x ,y );
182 c.a:=brightness_to_alpha[c.r + c.g + c.b ];
183
184 result.r:=c.r;
185 result.g:=c.g;
186 result.b:=c.b;
187 result.a:=c.a;
188
189end;
190
191{ CONSTRUCT }
192constructor the_application.Construct;
193begin
194 inherited Construct(format_ ,flip_y_ );
195
196 m_ctrl_color.ConstrDbl(0 ,0.3 ,0.5 ,0.3 );
197
198 m_scale_x.Construct(5.0 ,5.0 ,240.0 ,12.0 ,not flip_y_ );
199 m_start_x.Construct(250.0 ,5.0 ,495.0 ,12.0 ,not flip_y_ );
200
201 m_curve1.Construct;
202 m_curve2.Construct;
203 m_curve3.Construct;
204 m_curve4.Construct;
205 m_curve5.Construct;
206 m_curve6.Construct;
207 m_curve7.Construct;
208 m_curve8.Construct;
209 m_curve9.Construct;
210
211 m_curve1.line_color_(@m_ctrl_color );
212 m_curve2.line_color_(@m_ctrl_color );
213 m_curve3.line_color_(@m_ctrl_color );
214 m_curve4.line_color_(@m_ctrl_color );
215 m_curve5.line_color_(@m_ctrl_color );
216 m_curve6.line_color_(@m_ctrl_color );
217 m_curve7.line_color_(@m_ctrl_color );
218 m_curve8.line_color_(@m_ctrl_color );
219 m_curve9.line_color_(@m_ctrl_color );
220
221 m_curve1.curve_(64  ,19  ,14  ,126 ,118 ,266 ,19  ,265 );
222 m_curve2.curve_(112 ,113 ,178 ,32  ,200 ,132 ,125 ,438 );
223 m_curve3.curve_(401 ,24  ,326 ,149 ,285 ,11  ,177 ,77 );
224 m_curve4.curve_(188 ,427 ,129 ,295 ,19  ,283 ,25  ,410 );
225 m_curve5.curve_(451 ,346 ,302 ,218 ,265 ,441 ,459 ,400 );
226 m_curve6.curve_(454 ,198 ,14  ,13  ,220 ,291 ,483 ,283 );
227 m_curve7.curve_(301 ,398 ,355 ,231 ,209 ,211 ,170 ,353 );
228 m_curve8.curve_(484 ,101 ,222 ,33  ,486 ,435 ,487 ,138 );
229 m_curve9.curve_(143 ,147 ,11  ,45  ,83  ,427 ,132 ,197 );
230
231 add_ctrl(@m_curve1 );
232 add_ctrl(@m_curve2 );
233 add_ctrl(@m_curve3 );
234 add_ctrl(@m_curve4 );
235 add_ctrl(@m_curve5 );
236 add_ctrl(@m_curve6 );
237 add_ctrl(@m_curve7 );
238 add_ctrl(@m_curve8 );
239 add_ctrl(@m_curve9 );
240
241 m_curve1.no_transform;
242 m_curve2.no_transform;
243 m_curve3.no_transform;
244 m_curve4.no_transform;
245 m_curve5.no_transform;
246 m_curve6.no_transform;
247 m_curve7.no_transform;
248 m_curve8.no_transform;
249 m_curve9.no_transform;
250
251 m_scale_x.label_('Scale X=%.2f' );
252 m_scale_x.range_(0.2 ,3.0 );
253 m_scale_x.value_(1.0 );
254 m_scale_x.no_transform;
255
256 add_ctrl(@m_scale_x );
257
258 m_start_x.label_('Start X=%.2f' );
259 m_start_x.range_(0.0 ,10.0 );
260 m_start_x.value_(0.0 );
261 m_start_x.no_transform;
262
263 add_ctrl(@m_start_x );
264
265end;
266
267{ DESTRUCT }
268destructor the_application.Destruct;
269begin
270 inherited Destruct;
271
272 m_scale_x.Destruct;
273 m_start_x.Destruct;
274
275 m_curve1.Destruct;
276 m_curve2.Destruct;
277 m_curve3.Destruct;
278 m_curve4.Destruct;
279 m_curve5.Destruct;
280 m_curve6.Destruct;
281 m_curve7.Destruct;
282 m_curve8.Destruct;
283 m_curve9.Destruct;
284
285end;
286
287{ DRAW_CURVE }
288procedure the_application.draw_curve;
289begin
290 patt.create (src );
291 ren.scale_x_(m_scale_x._value );
292 ren.start_x_(m_start_x._value );
293 ras.add_path(vs );
294
295end;
296
297{ ON_DRAW }
298procedure the_application.on_draw;
299var
300 pf  : pixel_formats;
301 ren : renderer_scanline_aa_solid;
302 ras : rasterizer_scanline_aa;
303 sl  : scanline_p8;
304
305 rgba : aggclr;
306
307 ren_base : renderer_base;
308
309 p1 ,p2 ,p3 ,p4 ,p5 ,p6 ,p7 ,p8 ,p9 : pattern_src_brightness_to_alpha_rgba8;
310
311 fltr : pattern_filter_bilinear_rgba{};
312 patt : line_image_pattern;
313
314 ren_img : renderer_outline_image;
315 ras_img : rasterizer_outline_aa;
316
317begin
318// Initialize structures
319 pixfmt_bgr24(pf ,rbuf_window );
320
321 ren_base.Construct(@pf );
322 ren.Construct     (@ren_base );
323
324 rgba.ConstrDbl(1.0 ,1.0 ,0.95 );
325 ren_base.clear(@rgba );
326
327 ras.Construct;
328 sl.Construct;
329
330// Pattern source. Must have an interface:
331// width() const
332// height() const
333// pixel(int x, int y) const
334// Any agg::renderer_base<> or derived
335// is good for the use as a source.
336 p1.Construct(rbuf_img(0 ) );
337 p2.Construct(rbuf_img(1 ) );
338 p3.Construct(rbuf_img(2 ) );
339 p4.Construct(rbuf_img(3 ) );
340 p5.Construct(rbuf_img(4 ) );
341 p6.Construct(rbuf_img(5 ) );
342 p7.Construct(rbuf_img(6 ) );
343 p8.Construct(rbuf_img(7 ) );
344 p9.Construct(rbuf_img(8 ) );
345
346 fltr.Construct; // Filtering functor
347
348// agg::line_image_pattern is the main container for the patterns. It creates
349// a copy of the patterns extended according to the needs of the filter.
350// agg::line_image_pattern can operate with arbitrary image width, but if the
351// width of the pattern is power of 2, it's better to use the modified
352// version agg::line_image_pattern_pow2 because it works about 15-25 percent
353// faster than agg::line_image_pattern (because of using simple masking instead
354// of expensive '%' operation).
355
356//-- Create with specifying the source
357// patt.Construct(@fltr ,@src );
358
359//-- Create uninitialized and set the source
360 patt.Construct   (@fltr );
361 ren_img.Construct(@ren_base ,@patt );
362 ras_img.Construct(@ren_img );
363
364 draw_curve(@patt ,@ras_img ,@ren_img ,@p1 ,m_curve1._curve );
365 draw_curve(@patt ,@ras_img ,@ren_img ,@p2 ,m_curve2._curve );
366 draw_curve(@patt ,@ras_img ,@ren_img ,@p3 ,m_curve3._curve );
367 draw_curve(@patt ,@ras_img ,@ren_img ,@p4 ,m_curve4._curve );
368 draw_curve(@patt ,@ras_img ,@ren_img ,@p5 ,m_curve5._curve );
369 draw_curve(@patt ,@ras_img ,@ren_img ,@p6 ,m_curve6._curve );
370 draw_curve(@patt ,@ras_img ,@ren_img ,@p7 ,m_curve7._curve );
371 draw_curve(@patt ,@ras_img ,@ren_img ,@p8 ,m_curve8._curve );
372 draw_curve(@patt ,@ras_img ,@ren_img ,@p9 ,m_curve9._curve );
373
374// Render the controls
375 render_ctrl(@ras ,@sl ,@ren ,@m_curve1 );
376 render_ctrl(@ras ,@sl ,@ren ,@m_curve2 );
377 render_ctrl(@ras ,@sl ,@ren ,@m_curve3 );
378 render_ctrl(@ras ,@sl ,@ren ,@m_curve4 );
379 render_ctrl(@ras ,@sl ,@ren ,@m_curve5 );
380 render_ctrl(@ras ,@sl ,@ren ,@m_curve6 );
381 render_ctrl(@ras ,@sl ,@ren ,@m_curve7 );
382 render_ctrl(@ras ,@sl ,@ren ,@m_curve8 );
383 render_ctrl(@ras ,@sl ,@ren ,@m_curve9 );
384
385 render_ctrl(@ras ,@sl ,@ren ,@m_scale_x );
386 render_ctrl(@ras ,@sl ,@ren ,@m_start_x );
387
388// Free AGG resources
389 ras.Destruct;
390 sl.Destruct;
391
392 patt.Destruct;
393 ras_img.Destruct;
394
395end;
396
397{ ON_KEY }
398procedure the_application.on_key;
399var
400 fd  : text;
401 buf : array[0..255 ] of char;
402
403begin
404 if key = byte(' ' ) then
405  begin
406   AssignFile(fd ,'coord' );
407   rewrite   (fd );
408
409   sprintf(@buf[0 ]             ,'%.0f, ' ,m_curve1._x1 );
410   sprintf(@buf[StrLen(@buf ) ] ,'%.0f, ' ,m_curve1._y1 );
411   sprintf(@buf[StrLen(@buf ) ] ,'%.0f, ' ,m_curve1._x2 );
412   sprintf(@buf[StrLen(@buf ) ] ,'%.0f, ' ,m_curve1._y2 );
413   sprintf(@buf[StrLen(@buf ) ] ,'%.0f, ' ,m_curve1._x3 );
414   sprintf(@buf[StrLen(@buf ) ] ,'%.0f, ' ,m_curve1._y3 );
415   sprintf(@buf[StrLen(@buf ) ] ,'%.0f, ' ,m_curve1._x4 );
416   sprintf(@buf[StrLen(@buf ) ] ,'%.0f'   ,m_curve1._y4 );
417
418   write(fd ,PChar(@buf[0 ] ) );
419   close(fd );
420
421  end;
422
423 if key = key_f1 then
424  message_(
425   'The demo shows a very powerful mechanism of using arbitrary images as line patterns. '#13 +
426   'The main point of it is that the images are drawn along the path. It allows you to '#13 +
427   'draw very fancy looking lines quite easily and very useful in GIS/cartography applications. '#13 +
428   'There the bilinear filtering is used, but it''s also possible to add any other filtering '#13 +
429   'methods, or just use the nearest neighbour one for the sake of speed. '#13 +
430   'Actually, the algorithm uses 32bit images with alpha channel, but in this demo alpha is '#13 +
431   'simulated in such a way that wite is transparent, black is opaque. The intermediate colors '#13 +
432   'have intermediate opacity that is defined by the brightness_to_alpha array.'#13#13 +
433   'How to play with:'#13#13 +
434   'In the demo you can drag the control points of the curves and observe that the images '#13 +
435   'are transformed quite consistently and smoothly. You can also try to replace the image '#13 +
436   'files (1�9) with your own. The BMP files must have 24bit colors (TrueColor), the PPM '#13 +
437   'ones must be of type "P6". Also, the heigh should not exceed 64 pixels, and the background '#13 +
438   'should be white or very close to white.'#13 +
439   'Press the spacebar to write down the "coord" file of the curve 1 (of 1.bmp).' +
440   #13#13'Note: F2 key saves current "screenshot" file in this demo''s directory.  ' );
441
442end;
443
444{ ON_CTRL_CHANGE }
445procedure the_application.on_ctrl_change;
446begin
447end;
448
449VAR
450 app : the_application;
451 buf : array [0..255 ] of char;
452 ext : string[10 ];
453
454BEGIN
455 app.Construct(pix_format_bgr24 ,flip_y );
456 app.caption_ ('AGG Example. Drawing Lines with Image Patterns (F1-Help)' );
457
458 if not app.load_img(0 ,'1' ) or
459    not app.load_img(1 ,'2' ) or
460    not app.load_img(2 ,'3' ) or
461    not app.load_img(3 ,'4' ) or
462    not app.load_img(4 ,'5' ) or
463    not app.load_img(5 ,'6' ) or
464    not app.load_img(6 ,'7' ) or
465    not app.load_img(7 ,'8' ) or
466    not app.load_img(8 ,'9' ) then
467  begin
468   ext:=app._img_ext;
469
470   sprintf(@buf[0 ] ,'There must be files 1%s' ,ptrcomp(@ext[1 ] ) );
471   sprintf(
472    @buf[StrLen(@buf ) ] ,
473    '...9%s'#13 +
474    'Download and unzip:'#13 +
475    'http://www.antigrain.com/line_patterns.bmp.zip'#13 +
476    'or'#13 +
477    'http://www.antigrain.com/line_patterns.ppm.tar.gz'#13 ,
478    ptrcomp(@ext[1 ] ) );
479
480   app.message_(@buf[0 ] );
481
482  end
483 else
484  if app.init(500 ,450 ,window_resize ) then
485   app.run;
486
487 app.Destruct;
488
489END.