lazarus/components/aggpas/conv_stroke.dpr
mattias 36a2b1ea07 added aggpas
git-svn-id: trunk@21942 -
2009-10-01 12:24:32 +00:00

405 lines
7.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_stroke_ ;
uses
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_join ,
m_cap : rbox_ctrl;
m_width ,
m_miter_limit : slider_ctrl;
constructor Construct(format_ : pix_format_e; flip_y_ : boolean );
destructor Destruct;
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_join.Construct (10.0 ,10.0 ,133.0 ,80.0 ,not flip_y_ );
m_cap.Construct (10.0 ,80.0 + 10.0 ,133.0 ,80.0 + 80.0 ,not flip_y_ );
m_width.Construct (130 + 10.0 ,10.0 + 4.0 ,500.0 - 10.0 ,10.0 + 8.0 + 4.0 ,not flip_y_ );
m_miter_limit.Construct(130 + 10.0 ,20.0 + 10.0 + 4.0 ,500.0 - 10.0 ,20.0 + 10.0 + 8.0 + 4.0 ,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_join );
m_join.text_size_ (7.5 );
m_join.text_thickness_(1.0 );
m_join.add_item ('Miter Join' );
m_join.add_item ('Miter Join Revert' );
m_join.add_item ('Round Join' );
m_join.add_item ('Bevel Join' );
m_join.cur_item_(2 );
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_(2 );
add_ctrl(@m_width );
m_width.range_(3.0 ,40.0 );
m_width.value_(20.0 );
m_width.label_('Width=%1.2f' );
add_ctrl(@m_miter_limit );
m_miter_limit.range_(1.0 ,10.0 );
m_miter_limit.value_(4.0 );
m_miter_limit.label_('Miter Limit=%1.2f' );
m_join.no_transform;
m_cap.no_transform;
m_width.no_transform;
m_miter_limit.no_transform;
end;
{ DESTRUCT }
destructor the_application.Destruct;
begin
inherited Destruct;
m_join.Destruct;
m_cap.Destruct;
m_width.Destruct;
m_miter_limit.Destruct;
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 ,
join : unsigned;
path : path_storage;
stroke ,
poly1 ,
poly2 : conv_stroke;
poly2_dash : conv_dash;
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
path.Construct;
path.move_to(m_x[0 ] ,m_y[0 ] );
path.line_to((m_x[0 ] + m_x[1 ] ) / 2 ,(m_y[0 ] + m_y[1 ] ) / 2 ); // This point is added only to check for numerical stability
path.line_to(m_x[1 ] ,m_y[1 ] );
path.line_to(m_x[2 ] ,m_y[2 ] );
path.line_to(m_x[2 ] ,m_y[2 ] ); // This point is added only to check for numerical stability
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 );
path.close_polygon;
cap:=butt_cap;
if m_cap._cur_item = 1 then
cap:=square_cap;
if m_cap._cur_item = 2 then
cap:=round_cap;
join:=miter_join;
if m_join._cur_item = 1 then
join:=miter_join_revert;
if m_join._cur_item = 2 then
join:=round_join;
if m_join._cur_item = 3 then
join:=bevel_join;
// (1)
stroke.Construct (@path );
stroke.line_join_ (join );
stroke.line_cap_ (cap );
stroke.miter_limit_(m_miter_limit._value );
stroke.width_ (m_width._value );
ras.add_path (@stroke );
rgba.ConstrDbl (0.8 ,0.7 ,0.6 );
ren.color_ (@rgba );
render_scanlines(@ras ,@sl ,@ren );
// (2)
poly1.Construct (@path );
poly1.width_ (1.5 );
ras.add_path (@poly1 );
rgba.ConstrDbl (0 ,0 ,0 );
ren.color_ (@rgba );
render_scanlines(@ras ,@sl ,@ren );
// (3)
poly2_dash.Construct(@stroke );
poly2.Construct (@poly2_dash );
poly2.miter_limit_ (4.0 );
poly2.width_ (m_width._value / 5.0 );
poly2.line_cap_ (cap );
poly2.line_join_ (join );
poly2_dash.add_dash (20.0 ,m_width._value / 2.5 );
ras.add_path (@poly2 );
rgba.ConstrDbl (0 ,0 ,0.3 );
ren.color_ (@rgba );
render_scanlines(@ras ,@sl ,@ren );
// (4)
ras.add_path (@path );
rgba.ConstrDbl (0.0 ,0.0 ,0.0 ,0.2 );
ren.color_ (@rgba );
render_scanlines(@ras ,@sl ,@ren );
// Render the controls
render_ctrl(@ras ,@sl ,@ren ,@m_join );
render_ctrl(@ras ,@sl ,@ren ,@m_cap );
render_ctrl(@ras ,@sl ,@ren ,@m_width );
render_ctrl(@ras ,@sl ,@ren ,@m_miter_limit );
// Free AGG resources
ras.Destruct;
sl.Destruct;
path.Destruct;
stroke.Destruct;
poly1.Destruct;
poly2_dash.Destruct;
poly2.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_(
'Another example that demonstrates the power of the custom pipeline concept. '#13 +
'First, we calculate a thick outline (stroke), then generate dashes, and then, '#13 +
'calculate the outlines (strokes) of the dashes again.'#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.