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.