mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-27 19:13:52 +02:00
434 lines
8.3 KiB
ObjectPascal
434 lines
8.3 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_dash_marker ;
|
|
|
|
uses
|
|
Math ,
|
|
|
|
agg_basics ,
|
|
agg_platform_support ,
|
|
|
|
agg_color ,
|
|
agg_pixfmt ,
|
|
agg_pixfmt_rgb ,
|
|
|
|
agg_ctrl ,
|
|
agg_slider_ctrl ,
|
|
agg_rbox_ctrl ,
|
|
agg_cbox_ctrl ,
|
|
|
|
agg_renderer_base ,
|
|
agg_renderer_scanline ,
|
|
agg_rasterizer_scanline_aa ,
|
|
agg_scanline ,
|
|
agg_scanline_u ,
|
|
agg_render_scanlines ,
|
|
|
|
agg_conv_stroke ,
|
|
agg_conv_dash ,
|
|
agg_conv_curve ,
|
|
agg_conv_contour ,
|
|
agg_conv_smooth_poly1 ,
|
|
agg_conv_marker ,
|
|
agg_arrowhead ,
|
|
agg_vcgen_markers_term ,
|
|
agg_math ,
|
|
agg_math_stroke ,
|
|
agg_path_storage ;
|
|
|
|
{$I agg_mode.inc }
|
|
|
|
const
|
|
flip_y = true;
|
|
|
|
type
|
|
the_application = object(platform_support )
|
|
m_x ,
|
|
m_y : array[0..2 ] of double;
|
|
m_dx ,
|
|
m_dy : double;
|
|
m_idx : int;
|
|
|
|
m_cap : rbox_ctrl;
|
|
m_width ,
|
|
m_smooth : slider_ctrl;
|
|
m_close ,
|
|
m_even_odd : cbox_ctrl;
|
|
|
|
constructor Construct(format_ : pix_format_e; flip_y_ : boolean );
|
|
destructor Destruct;
|
|
|
|
procedure on_init; virtual;
|
|
procedure on_draw; virtual;
|
|
|
|
procedure on_mouse_move (x ,y : int; flags : unsigned ); virtual;
|
|
procedure on_mouse_button_down(x ,y : int; flags : unsigned ); virtual;
|
|
procedure on_mouse_button_up (x ,y : int; flags : unsigned ); virtual;
|
|
|
|
procedure on_key(x ,y : int; key ,flags : unsigned ); virtual;
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor the_application.Construct;
|
|
begin
|
|
inherited Construct(format_ ,flip_y_ );
|
|
|
|
m_cap.Construct (10.0 ,10.0 ,130.0 ,80.0 ,not flip_y_ );
|
|
m_width.Construct (130 + 10.0 ,10.0 + 4.0 ,130 + 150.0 ,10.0 + 8.0 + 4.0 ,not flip_y_ );
|
|
m_smooth.Construct (130 + 150.0 + 10.0 ,10.0 + 4.0 ,500 - 10.0 ,10.0 + 8.0 + 4.0 ,not flip_y_ );
|
|
m_close.Construct (130 + 10.0 ,10.0 + 4.0 + 16.0 ,'Close Polygons' ,not flip_y_ );
|
|
m_even_odd.Construct(130 + 150.0 + 10.0 ,10.0 + 4.0 + 16.0 ,'Even-Odd Fill' ,not flip_y_ );
|
|
|
|
m_idx:=-1;
|
|
|
|
m_x[0 ]:=57 + 100;
|
|
m_y[0 ]:=60;
|
|
m_x[1 ]:=369 + 100;
|
|
m_y[1 ]:=170;
|
|
m_x[2 ]:=143 + 100;
|
|
m_y[2 ]:=310;
|
|
|
|
add_ctrl(@m_cap );
|
|
|
|
m_cap.add_item ('Butt Cap' );
|
|
m_cap.add_item ('Square Cap' );
|
|
m_cap.add_item ('Round Cap' );
|
|
m_cap.cur_item_(0 );
|
|
m_cap.no_transform;
|
|
|
|
add_ctrl(@m_width );
|
|
|
|
m_width.range_(0.0 ,10.0 );
|
|
m_width.value_(3.0 );
|
|
m_width.label_('Width=%1.2f' );
|
|
m_width.no_transform;
|
|
|
|
add_ctrl(@m_smooth );
|
|
|
|
m_smooth.range_(0.0 ,2.0 );
|
|
m_smooth.value_(1.0 );
|
|
m_smooth.label_('Smooth=%1.2f' );
|
|
m_smooth.no_transform;
|
|
|
|
add_ctrl(@m_close );
|
|
|
|
m_close.no_transform;
|
|
|
|
add_ctrl(@m_even_odd );
|
|
|
|
m_even_odd.no_transform;
|
|
|
|
end;
|
|
|
|
{ DESTRUCT }
|
|
destructor the_application.Destruct;
|
|
begin
|
|
inherited Destruct;
|
|
|
|
m_cap.Destruct;
|
|
m_width.Destruct;
|
|
m_smooth.Destruct;
|
|
m_close.Destruct;
|
|
m_even_odd.Destruct;
|
|
|
|
end;
|
|
|
|
{ ON_INIT }
|
|
procedure the_application.on_init;
|
|
begin
|
|
end;
|
|
|
|
{ ON_DRAW }
|
|
procedure the_application.on_draw;
|
|
var
|
|
pixf : pixel_formats;
|
|
rgba : aggclr;
|
|
renb : renderer_base;
|
|
ren : renderer_scanline_aa_solid;
|
|
ras : rasterizer_scanline_aa;
|
|
sl : scanline_u8;
|
|
|
|
cap : unsigned;
|
|
path : path_storage;
|
|
|
|
smooth : conv_smooth_poly1;
|
|
|
|
smooth_outline : conv_stroke;
|
|
|
|
curve : conv_curve;
|
|
dash : conv_dash;
|
|
stroke : conv_stroke;
|
|
arrow : conv_marker;
|
|
marker : vcgen_markers_term;
|
|
|
|
k : double;
|
|
ah : arrowhead;
|
|
|
|
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
|
|
cap:=butt_cap;
|
|
|
|
if m_cap._cur_item = 1 then
|
|
cap:=square_cap;
|
|
|
|
if m_cap._cur_item = 2 then
|
|
cap:=round_cap;
|
|
|
|
path.Construct;
|
|
|
|
path.move_to(m_x[0 ] ,m_y[0 ] );
|
|
path.line_to(m_x[1 ] ,m_y[1 ] );
|
|
path.line_to((m_x[0 ] + m_x[1 ] + m_x[2 ] ) / 3.0 ,(m_y[0 ] + m_y[1 ] + m_y[2 ] ) / 3.0 );
|
|
path.line_to(m_x[2 ] ,m_y[2 ] );
|
|
|
|
if m_close._status then
|
|
path.close_polygon;
|
|
|
|
path.move_to((m_x[0 ] + m_x[1 ] ) / 2 ,(m_y[0 ] + m_y[1 ] ) / 2 );
|
|
path.line_to((m_x[1 ] + m_x[2 ] ) / 2 ,(m_y[1 ] + m_y[2 ] ) / 2 );
|
|
path.line_to((m_x[2 ] + m_x[0 ] ) / 2 ,(m_y[2 ] + m_y[0 ] ) / 2 );
|
|
|
|
if m_close._status then
|
|
path.close_polygon;
|
|
|
|
if m_even_odd._status then
|
|
ras.filling_rule(fill_even_odd );
|
|
|
|
// (1)
|
|
ras.add_path (@path );
|
|
rgba.ConstrDbl (0.7 ,0.5 ,0.1 ,0.5 );
|
|
ren.color_ (@rgba );
|
|
render_scanlines(@ras ,@sl ,@ren );
|
|
|
|
// Start of (2, 3, 4)
|
|
smooth.Construct (@path );
|
|
smooth.smooth_value_(m_smooth._value );
|
|
|
|
// (2)
|
|
ras.add_path (@smooth );
|
|
rgba.ConstrDbl (0.1 ,0.5 ,0.7 ,0.1 );
|
|
ren.color_ (@rgba );
|
|
render_scanlines(@ras ,@sl ,@ren );
|
|
|
|
// (3)
|
|
smooth_outline.Construct(@smooth );
|
|
|
|
ras.add_path (@smooth_outline );
|
|
rgba.ConstrDbl (0.0 ,0.6 ,0.0 ,0.8 );
|
|
ren.color_ (@rgba );
|
|
render_scanlines(@ras ,@sl ,@ren );
|
|
|
|
// (4)
|
|
curve.Construct(@smooth );
|
|
dash.Construct (@curve );
|
|
|
|
marker.Construct;
|
|
dash.set_markers(@marker );
|
|
|
|
stroke.Construct(@dash );
|
|
stroke.line_cap_(cap);
|
|
stroke.width_ (m_width._value );
|
|
|
|
k:=Power(m_width._value ,0.7 );
|
|
|
|
ah.Construct;
|
|
ah.head_(4 * k ,4 * k ,3 * k ,2 * k );
|
|
|
|
if not m_close._status then
|
|
ah.tail_(1 * k ,1.5 * k ,3 * k ,5 * k );
|
|
|
|
arrow.Construct(dash.markers ,@ah );
|
|
|
|
dash.add_dash (20.0 ,5.0 );
|
|
dash.add_dash (5.0 ,5.0 );
|
|
dash.add_dash (5.0 ,5.0 );
|
|
dash.dash_start(10 );
|
|
|
|
ras.add_path (@stroke );
|
|
ras.add_path (@arrow );
|
|
rgba.ConstrDbl (0.0 ,0.0 ,0.0 );
|
|
ren.color_ (@rgba );
|
|
render_scanlines(@ras ,@sl ,@ren );
|
|
|
|
// Render the controls
|
|
ras.filling_rule(fill_non_zero );
|
|
|
|
render_ctrl(@ras ,@sl ,@ren ,@m_cap );
|
|
render_ctrl(@ras ,@sl ,@ren ,@m_width );
|
|
render_ctrl(@ras ,@sl ,@ren ,@m_smooth );
|
|
render_ctrl(@ras ,@sl ,@ren ,@m_close );
|
|
render_ctrl(@ras ,@sl ,@ren ,@m_even_odd );
|
|
|
|
// Free AGG resources
|
|
ras.Destruct;
|
|
sl.Destruct;
|
|
|
|
path.Destruct;
|
|
smooth.Destruct;
|
|
smooth_outline.Destruct;
|
|
curve.Destruct;
|
|
dash.Destruct;
|
|
marker.Destruct;
|
|
stroke.Destruct;
|
|
|
|
end;
|
|
|
|
{ ON_MOUSE_MOVE }
|
|
procedure the_application.on_mouse_move;
|
|
var
|
|
dx ,dy : double;
|
|
|
|
begin
|
|
if flags and mouse_left <> 0 then
|
|
begin
|
|
if m_idx = 3 then
|
|
begin
|
|
dx:=x - m_dx;
|
|
dy:=y - m_dy;
|
|
|
|
m_x[1 ]:=m_x[1 ] - (m_x[0 ] - dx );
|
|
m_y[1 ]:=m_y[1 ] - (m_y[0 ] - dy );
|
|
m_x[2 ]:=m_x[2 ] - (m_x[0 ] - dx );
|
|
m_y[2 ]:=m_y[2 ] - (m_y[0 ] - dy );
|
|
|
|
m_x[0 ]:=dx;
|
|
m_y[0 ]:=dy;
|
|
|
|
force_redraw;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
if m_idx >= 0 then
|
|
begin
|
|
m_x[m_idx ]:=x - m_dx;
|
|
m_y[m_idx ]:=y - m_dy;
|
|
|
|
force_redraw;
|
|
|
|
end;
|
|
|
|
end
|
|
else
|
|
on_mouse_button_up(x ,y ,flags );
|
|
|
|
end;
|
|
|
|
{ ON_MOUSE_BUTTON_DOWN }
|
|
procedure the_application.on_mouse_button_down;
|
|
var
|
|
i : unsigned;
|
|
|
|
begin
|
|
if flags and mouse_left <> 0 then
|
|
begin
|
|
i:=0;
|
|
|
|
while i < 3 do
|
|
begin
|
|
if Sqrt((x - m_x[i ] ) * (x - m_x[i ] ) + (y - m_y[i ] ) * (y - m_y[i ] ) ) < 20.0 then
|
|
begin
|
|
m_dx :=x - m_x[i ];
|
|
m_dy :=y - m_y[i ];
|
|
m_idx:=i;
|
|
|
|
break;
|
|
|
|
end;
|
|
|
|
inc(i );
|
|
|
|
end;
|
|
|
|
if i = 3 then
|
|
if point_in_triangle(
|
|
m_x[0 ] ,m_y[0 ] ,
|
|
m_x[1 ] ,m_y[1 ] ,
|
|
m_x[2 ] ,m_y[2 ] ,x ,y ) then
|
|
begin
|
|
m_dx :=x - m_x[0 ];
|
|
m_dy :=y - m_y[0 ];
|
|
m_idx:=3;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{ ON_MOUSE_BUTTON_UP }
|
|
procedure the_application.on_mouse_button_up;
|
|
begin
|
|
m_idx:=-1;
|
|
|
|
end;
|
|
|
|
{ ON_KEY }
|
|
procedure the_application.on_key;
|
|
var
|
|
dx ,dy : double;
|
|
|
|
begin
|
|
dx:=0;
|
|
dy:=0;
|
|
|
|
case key of
|
|
key_left : dx:=-0.1;
|
|
key_right : dx:= 0.1;
|
|
key_up : dy:= 0.1;
|
|
key_down : dy:=-0.1;
|
|
|
|
end;
|
|
|
|
m_x[0 ]:=m_x[0 ] + dx;
|
|
m_y[0 ]:=m_y[0 ] + dy;
|
|
m_x[1 ]:=m_x[1 ] + dx;
|
|
m_y[1 ]:=m_y[1 ] + dy;
|
|
|
|
force_redraw;
|
|
|
|
if key = key_f1 then
|
|
message_(
|
|
'The example demonstrates rather a complex pipeline that consists of diffrerent '#13 +
|
|
'converters, particularly, of the dash generator, marker generator, and of course, '#13 +
|
|
'the stroke converter. There is also a converter that allows you to draw smooth '#13 +
|
|
'curves based on polygons, see "Interpolation with Bezier Curves" on www.antigrain.com. '#13#13 +
|
|
'How to play with:'#13#13 +
|
|
'Use the left mouse in the corners of the triangle to move the particular vertices.'#13 +
|
|
'Drag and move the whole picture with mouse or arrow keys.' +
|
|
#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. Line Join (F1-Help)' );
|
|
|
|
if app.init(500 ,330 ,0 ) then
|
|
app.run;
|
|
|
|
app.Destruct;
|
|
|
|
END. |