mirror of
				https://gitlab.com/freepascal.org/lazarus/lazarus.git
				synced 2025-10-31 21:09:28 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			274 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			274 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
| //
 | ||
| // AggPas 2.4 RM3 Demo application
 | ||
| // Note: Press F1 key on run to see more info about this demo
 | ||
| //
 | ||
| // Paths: src;src\ctrl;src\svg;src\util;src\platform\win;expat-wrap
 | ||
| //
 | ||
| program
 | ||
|  conv_contour_ ;
 | ||
| 
 | ||
| uses
 | ||
|  agg_basics ,
 | ||
|  agg_platform_support ,
 | ||
| 
 | ||
|  agg_color ,
 | ||
|  agg_pixfmt ,
 | ||
|  agg_pixfmt_rgb ,
 | ||
| 
 | ||
|  agg_ctrl ,
 | ||
|  agg_rbox_ctrl ,
 | ||
|  agg_cbox_ctrl ,
 | ||
|  agg_slider_ctrl ,
 | ||
| 
 | ||
|  agg_rendering_buffer ,
 | ||
|  agg_renderer_base ,
 | ||
|  agg_renderer_scanline ,
 | ||
|  agg_rasterizer_scanline_aa ,
 | ||
|  agg_scanline_p ,
 | ||
|  agg_render_scanlines ,
 | ||
| 
 | ||
|  agg_conv_stroke ,
 | ||
|  agg_conv_transform ,
 | ||
|  agg_conv_curve ,
 | ||
|  agg_conv_contour ,
 | ||
|  agg_path_storage ,
 | ||
|  agg_trans_affine ,
 | ||
|  agg_math_stroke ;
 | ||
| 
 | ||
| {$I agg_mode.inc }
 | ||
| 
 | ||
| const
 | ||
|  flip_y = true;
 | ||
| 
 | ||
| type
 | ||
|  the_application = object(platform_support )
 | ||
|    m_close       : rbox_ctrl;
 | ||
|    m_width       : slider_ctrl;
 | ||
|    m_auto_detect : cbox_ctrl;
 | ||
|    m_path        : path_storage;
 | ||
| 
 | ||
|    constructor Construct(format_ : pix_format_e; flip_y_ : boolean );
 | ||
|    destructor  Destruct;
 | ||
| 
 | ||
|    procedure compose_path;
 | ||
|    procedure on_draw; virtual;
 | ||
| 
 | ||
|    procedure on_key(x ,y : int; key ,flags : unsigned ); virtual;
 | ||
| 
 | ||
|   end;
 | ||
| 
 | ||
| { CONSTRUCT }
 | ||
| constructor the_application.Construct;
 | ||
| begin
 | ||
|  inherited Construct(format_ ,flip_y_ );
 | ||
| 
 | ||
|  m_close.Construct      (10.0 ,10.0 ,130.0 ,80.0 ,not flip_y_ );
 | ||
|  m_width.Construct      (130 + 10.0 ,10.0 + 4.0 ,130 + 300.0 ,10.0 + 8.0 + 4.0 ,not flip_y_ );
 | ||
|  m_auto_detect.Construct(130 + 10.0 ,10.0 + 4.0 + 16.0 ,'Autodetect orientation if not defined' ,not flip_y_ );
 | ||
|  m_path.Construct;
 | ||
| 
 | ||
|  add_ctrl(@m_close );
 | ||
| 
 | ||
|  m_close.add_item ('Close' );
 | ||
|  m_close.add_item ('Close CW' );
 | ||
|  m_close.add_item ('Close CCW' );
 | ||
|  m_close.cur_item_(0 );
 | ||
| 
 | ||
|  add_ctrl(@m_width );
 | ||
| 
 | ||
|  m_width.range_(-100.0 ,100.0 );
 | ||
|  m_width.value_(0.0 );
 | ||
|  m_width.label_('Width=%1.2f' );
 | ||
| 
 | ||
|  add_ctrl(@m_auto_detect );
 | ||
| 
 | ||
| end;
 | ||
| 
 | ||
| { DESTRUCT }
 | ||
| destructor the_application.Destruct;
 | ||
| begin
 | ||
|  inherited Destruct;
 | ||
| 
 | ||
|  m_close.Destruct;
 | ||
|  m_width.Destruct;
 | ||
|  m_auto_detect.Destruct;
 | ||
|  m_path.Destruct;
 | ||
| 
 | ||
| end;
 | ||
| 
 | ||
| { COMPOSE_PATH }
 | ||
| procedure the_application.compose_path;
 | ||
| var
 | ||
|  flag : unsigned;
 | ||
| 
 | ||
| begin
 | ||
|  flag:=0;
 | ||
| 
 | ||
|  if m_close._cur_item = 1 then
 | ||
|   flag:=path_flags_cw;
 | ||
| 
 | ||
|  if m_close._cur_item = 2 then
 | ||
|   flag:=path_flags_ccw;
 | ||
| 
 | ||
|  m_path.remove_all;
 | ||
| 
 | ||
|  m_path.move_to(28.47 ,6.45 );
 | ||
|  m_path.curve3 (21.58 ,1.12  ,19.82 ,0.29 );
 | ||
|  m_path.curve3 (17.19 ,-0.93 ,14.21 ,-0.93 );
 | ||
|  m_path.curve3 (9.57  ,-0.93 ,6.57  ,2.25 );
 | ||
|  m_path.curve3 (3.56  ,5.42  ,3.56  ,10.60 );
 | ||
|  m_path.curve3 (3.56  ,13.87 ,5.03  ,16.26 );
 | ||
|  m_path.curve3 (7.03  ,19.58 ,11.99 ,22.51 );
 | ||
|  m_path.curve3 (16.94 ,25.44 ,28.47 ,29.64 );
 | ||
|  m_path.line_to(28.47 ,31.40 );
 | ||
|  m_path.curve3 (28.47 ,38.09 ,26.34 ,40.58 );
 | ||
|  m_path.curve3 (24.22 ,43.07 ,20.17 ,43.07 );
 | ||
|  m_path.curve3 (17.09 ,43.07 ,15.28 ,41.41 );
 | ||
|  m_path.curve3 (13.43 ,39.75 ,13.43 ,37.60 );
 | ||
|  m_path.line_to(13.53 ,34.77 );
 | ||
|  m_path.curve3 (13.53 ,32.52 ,12.38 ,31.30 );
 | ||
|  m_path.curve3 (11.23 ,30.08 ,9.38  ,30.08 );
 | ||
|  m_path.curve3 (7.57  ,30.08 ,6.42  ,31.35 );
 | ||
|  m_path.curve3 (5.27  ,32.62 ,5.27  ,34.81 );
 | ||
|  m_path.curve3 (5.27  ,39.01 ,9.57  ,42.53 );
 | ||
|  m_path.curve3 (13.87 ,46.04 ,21.63 ,46.04 );
 | ||
|  m_path.curve3 (27.59 ,46.04 ,31.40 ,44.04 );
 | ||
|  m_path.curve3 (34.28 ,42.53 ,35.64 ,39.31 );
 | ||
|  m_path.curve3 (36.52 ,37.21 ,36.52 ,30.71 );
 | ||
|  m_path.line_to(36.52 ,15.53 );
 | ||
|  m_path.curve3 (36.52 ,9.13  ,36.77 ,7.69 );
 | ||
|  m_path.curve3 (37.01 ,6.25  ,37.57 ,5.76 );
 | ||
|  m_path.curve3 (38.13 ,5.27  ,38.87 ,5.27 );
 | ||
|  m_path.curve3 (39.65 ,5.27  ,40.23 ,5.62 );
 | ||
|  m_path.curve3 (41.26 ,6.25  ,44.19 ,9.18 );
 | ||
|  m_path.line_to(44.19 ,6.45  );
 | ||
|  m_path.curve3 (38.72 ,-0.88 ,33.74 ,-0.88 );
 | ||
|  m_path.curve3 (31.35 ,-0.88 ,29.93 ,0.78 );
 | ||
|  m_path.curve3 (28.52 ,2.44  ,28.47 ,6.45 );
 | ||
| 
 | ||
|  m_path.close_polygon(flag );
 | ||
| 
 | ||
|  m_path.move_to(28.47 ,9.62 );
 | ||
|  m_path.line_to(28.47 ,26.66 );
 | ||
|  m_path.curve3 (21.09 ,23.73 ,18.95 ,22.51 );
 | ||
|  m_path.curve3 (15.09 ,20.36 ,13.43 ,18.02 );
 | ||
|  m_path.curve3 (11.77 ,15.67 ,11.77 ,12.89 );
 | ||
|  m_path.curve3 (11.77 ,9.38  ,13.87 ,7.06 );
 | ||
|  m_path.curve3 (15.97 ,4.74  ,18.70 ,4.74 );
 | ||
|  m_path.curve3 (22.41 ,4.74  ,28.47 ,9.62 );
 | ||
| 
 | ||
|  m_path.close_polygon(flag );
 | ||
| 
 | ||
| end;
 | ||
| 
 | ||
| { ON_DRAW }
 | ||
| procedure the_application.on_draw;
 | ||
| var
 | ||
|  pixf : pixel_formats;
 | ||
|  renb : renderer_base;
 | ||
|  ren  : renderer_scanline_aa_solid;
 | ||
|  rgba : aggclr;
 | ||
| 
 | ||
|  ras : rasterizer_scanline_aa;
 | ||
|  sl  : scanline_p8;
 | ||
| 
 | ||
|  mtx : trans_affine;
 | ||
|  tas : trans_affine_scaling;
 | ||
|  tat : trans_affine_translation;
 | ||
| 
 | ||
|  trans : conv_transform;
 | ||
|  curve : conv_curve;
 | ||
| 
 | ||
|  contour : conv_contour;
 | ||
| 
 | ||
| begin
 | ||
| // Initialize structures
 | ||
|  pixfmt_bgr24(pixf ,rbuf_window );
 | ||
| 
 | ||
|  renb.Construct(@pixf );
 | ||
|  ren.Construct (@renb );
 | ||
|  rgba.ConstrDbl(1 ,1 ,1 );
 | ||
|  renb.clear    (@rgba );
 | ||
| 
 | ||
|  ras.Construct;
 | ||
|  sl.Construct;
 | ||
| 
 | ||
| // Render
 | ||
|  mtx.Construct;
 | ||
| 
 | ||
|  tas.Construct(4.0 );
 | ||
|  mtx.multiply (@tas );
 | ||
| 
 | ||
|  tat.Construct(150 ,100 );
 | ||
|  mtx.multiply (@tat );
 | ||
| 
 | ||
|  trans.Construct(@m_path ,@mtx );
 | ||
|  curve.Construct(@trans );
 | ||
| 
 | ||
|  contour.Construct(@curve );
 | ||
| 
 | ||
|  contour.width_                  (m_width._value );
 | ||
|  //contour.line_join_              (miter_join );
 | ||
|  //contour.inner_join_             (miter_join );
 | ||
|  //contour.inner_miter_limit_      (4.0 );
 | ||
|  contour.auto_detect_orientation_(m_auto_detect._status );
 | ||
| 
 | ||
|  compose_path;
 | ||
|  ras.add_path(@contour );
 | ||
| 
 | ||
|  rgba.ConstrDbl(0 ,0 ,0 );
 | ||
|  ren.color_    (@rgba );
 | ||
| 
 | ||
|  render_scanlines(@ras ,@sl ,@ren );
 | ||
| 
 | ||
| // Render the controls
 | ||
|  render_ctrl(@ras ,@sl ,@ren ,@m_close );
 | ||
|  render_ctrl(@ras ,@sl ,@ren ,@m_width );
 | ||
|  render_ctrl(@ras ,@sl ,@ren ,@m_auto_detect );
 | ||
| 
 | ||
| // Free AGG resources
 | ||
|  ras.Destruct;
 | ||
|  sl.Destruct;
 | ||
| 
 | ||
|  curve.Destruct;
 | ||
|  contour.Destruct;
 | ||
| 
 | ||
| end;
 | ||
| 
 | ||
| { ON_KEY }
 | ||
| procedure the_application.on_key;
 | ||
| begin
 | ||
|  if key = key_f1 then
 | ||
|   message_(
 | ||
|    'One of the converters in AGG is conv_contour. It allows you to extend or shrink '#13 +
 | ||
|    'polygons. Initially, it was implemented to eliminate the "problem of adjacent edges"'#13 +
 | ||
|    'in the SVG Viewer, but it can be very useful in many other applications, for example,'#13 +
 | ||
|    'to change the font weight on the fly. The trick here is that the sign (dilation or '#13 +
 | ||
|    'shrinking) depends on the vertex order - clockwise or counterclockwise. '#13 +
 | ||
|    'In the conv_contour you can control the behavior. Sometimes you need to preserve '#13 +
 | ||
|    'the dilation regardless of the initial orientation, sometimes it should depend '#13 +
 | ||
|    'on the orientation. The glyph <20>a<EFBFBD> has a "hole" whose orientation differs from '#13 +
 | ||
|    'the main contour. To change the "weight" correctly, you need to keep the orientation '#13 +
 | ||
|    'as it is originally defined. If you turn "Autodetect orientation<6F>" on, the glyph will '#13 +
 | ||
|    'be extended or shrinked incorrectly.'#13#13 +
 | ||
|    'How to play with:'#13#13 +
 | ||
|    'The radio buttons control the orientation flad assigned to all polygons.'#13 +
 | ||
|    '"Close" doesn''t add the flag.'#13 +
 | ||
|    '"Close CW" and "Close CCW" add "clockwise" or "counterclockwise" flag respectively.' +
 | ||
|    #13#13'Note: F2 key saves current "screenshot" file in this demo''s directory.  ' );
 | ||
| 
 | ||
| end;
 | ||
| 
 | ||
| VAR
 | ||
|  app : the_application;
 | ||
| 
 | ||
| BEGIN
 | ||
|  app.Construct(pix_format_bgr24 ,flip_y );
 | ||
|  app.caption_ ('AGG Example. Contour Tool & Polygon Orientation (F1-Help)' );
 | ||
| 
 | ||
|  if app.init(440 ,330 ,0 ) then
 | ||
|   app.run;
 | ||
| 
 | ||
|  app.Destruct;
 | ||
| 
 | ||
| END. | 
