mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-27 20:53:57 +02:00
451 lines
9.1 KiB
ObjectPascal
451 lines
9.1 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
|
|
trans_curve1_ft ;
|
|
|
|
{DEFINE AGG_GRAY8 }
|
|
{$DEFINE AGG_BGR24 }
|
|
{DEFINE AGG_RGB24 }
|
|
{DEFINE AGG_BGRA32 }
|
|
{DEFINE AGG_RGBA32 }
|
|
{DEFINE AGG_ARGB32 }
|
|
{DEFINE AGG_ABGR32 }
|
|
{DEFINE AGG_RGB565 }
|
|
{DEFINE AGG_RGB555 }
|
|
|
|
uses
|
|
agg_basics ,
|
|
agg_platform_support ,
|
|
|
|
agg_ctrl ,
|
|
agg_cbox_ctrl ,
|
|
agg_slider_ctrl ,
|
|
|
|
agg_rasterizer_scanline_aa ,
|
|
agg_scanline ,
|
|
agg_scanline_p ,
|
|
|
|
agg_rendering_buffer ,
|
|
agg_renderer_base ,
|
|
agg_renderer_scanline ,
|
|
agg_render_scanlines ,
|
|
|
|
agg_conv_curve ,
|
|
agg_conv_transform ,
|
|
agg_conv_bspline ,
|
|
agg_conv_segmentator ,
|
|
agg_conv_stroke ,
|
|
agg_font_freetype ,
|
|
agg_font_cache_manager ,
|
|
agg_trans_single_path ,
|
|
interactive_polygon_
|
|
|
|
{$I pixel_formats.inc }
|
|
{$I agg_mode.inc }
|
|
|
|
const
|
|
flip_y = true;
|
|
|
|
text_ : PChar =
|
|
'Anti-Grain Geometry is designed as a set of loosely coupled ' +
|
|
'algorithms and class templates united with a common idea, ' +
|
|
'so that all the components can be easily combined. Also, ' +
|
|
'the template based design allows you to replace any part of ' +
|
|
'the library without the necessity to modify a single byte in ' +
|
|
'the existing code. ';
|
|
|
|
type
|
|
the_application = object(platform_support )
|
|
m_feng : font_engine_freetype_int16;
|
|
m_fman : font_cache_manager;
|
|
m_poly : interactive_polygon;
|
|
|
|
m_num_points : slider_ctrl;
|
|
m_close ,
|
|
m_preserve_x_scale ,
|
|
m_fixed_len ,
|
|
m_animate : cbox_ctrl;
|
|
|
|
m_dx ,
|
|
m_dy : array[0..5 ] of double;
|
|
|
|
m_prev_animate : boolean;
|
|
|
|
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;
|
|
procedure on_ctrl_change; virtual;
|
|
|
|
procedure move_point(x ,y ,dx ,dy : double_ptr );
|
|
|
|
procedure on_idle; virtual;
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor the_application.Construct;
|
|
begin
|
|
inherited Construct(format_ ,flip_y_ );
|
|
|
|
m_feng.Construct;
|
|
m_fman.Construct(@m_feng );
|
|
m_poly.Construct(6 ,5.0 );
|
|
|
|
m_num_points.Construct (5.0 ,5.0 ,340.0 ,12.0 ,not flip_y_ );
|
|
m_close.Construct (350 ,5.0 ,'Close' ,not flip_y_ );
|
|
m_preserve_x_scale.Construct(460 ,5.0 ,'Preserve X scale' ,not flip_y_ );
|
|
m_fixed_len.Construct (350 ,25.0 ,'Fixed Length' ,not flip_y_ );
|
|
m_animate.Construct (460 ,25.0 ,'Animate' ,not flip_y_ );
|
|
|
|
m_prev_animate:=false;
|
|
|
|
add_ctrl(@m_close );
|
|
add_ctrl(@m_preserve_x_scale );
|
|
add_ctrl(@m_fixed_len );
|
|
add_ctrl(@m_animate );
|
|
|
|
m_preserve_x_scale.status_(true );
|
|
m_fixed_len.status_ (true );
|
|
|
|
m_num_points.range_(10.0 ,400.0 );
|
|
m_num_points.value_(200.0 );
|
|
m_num_points.label_('Number of intermediate Points = %.3f' );
|
|
|
|
add_ctrl(@m_num_points );
|
|
|
|
end;
|
|
|
|
{ DESTRUCT }
|
|
destructor the_application.Destruct;
|
|
begin
|
|
inherited Destruct;
|
|
|
|
m_poly.Destruct;
|
|
|
|
m_num_points.Destruct;
|
|
m_close.Destruct;
|
|
m_preserve_x_scale.Destruct;
|
|
m_fixed_len.Destruct;
|
|
m_animate.Destruct;
|
|
|
|
m_feng.Destruct;
|
|
m_fman.Destruct;
|
|
|
|
end;
|
|
|
|
{ ON_INIT }
|
|
procedure the_application.on_init;
|
|
begin
|
|
m_poly.xn_ptr(0 )^:=50;
|
|
m_poly.yn_ptr(0 )^:=50;
|
|
m_poly.xn_ptr(1 )^:=150 + 20;
|
|
m_poly.yn_ptr(1 )^:=150 - 20;
|
|
m_poly.xn_ptr(2 )^:=250 - 20;
|
|
m_poly.yn_ptr(2 )^:=250 + 20;
|
|
m_poly.xn_ptr(3 )^:=350 + 20;
|
|
m_poly.yn_ptr(3 )^:=350 - 20;
|
|
m_poly.xn_ptr(4 )^:=450 - 20;
|
|
m_poly.yn_ptr(4 )^:=450 + 20;
|
|
m_poly.xn_ptr(5 )^:=550;
|
|
m_poly.yn_ptr(5 )^:=550;
|
|
|
|
end;
|
|
|
|
{ ON_DRAW }
|
|
procedure the_application.on_draw;
|
|
var
|
|
pixf : pixel_formats;
|
|
rgba : aggclr;
|
|
|
|
rb : renderer_base;
|
|
r : renderer_scanline_aa_solid;
|
|
sl : scanline_p8;
|
|
|
|
ras : rasterizer_scanline_aa;
|
|
|
|
path : simple_polygon_vertex_source;
|
|
bspline : conv_bspline;
|
|
tcurve : trans_single_path;
|
|
fcurves : conv_curve;
|
|
fsegm : conv_segmentator;
|
|
ftrans : conv_transform;
|
|
|
|
x ,y : double;
|
|
|
|
p : int8u_ptr;
|
|
|
|
glyph : glyph_cache_ptr;
|
|
|
|
stroke : conv_stroke;
|
|
|
|
begin
|
|
// Initialize structures
|
|
pixfmt(pixf ,rbuf_window );
|
|
|
|
rb.Construct(@pixf );
|
|
r.Construct (@rb );
|
|
|
|
rgba.ConstrDbl(1 ,1 ,1 );
|
|
rb.clear (@rgba );
|
|
|
|
sl.Construct;
|
|
ras.Construct;
|
|
|
|
m_poly.close_(m_close._status );
|
|
|
|
// Render the text
|
|
path.Construct (m_poly.polygon ,m_poly.num_points ,false ,m_close._status );
|
|
bspline.Construct(@path );
|
|
|
|
bspline.interpolation_step_(1.0 / m_num_points._value );
|
|
|
|
tcurve.Construct;
|
|
tcurve.add_path (@bspline );
|
|
tcurve.preserve_x_scale_(m_preserve_x_scale._status );
|
|
|
|
if m_fixed_len._status then
|
|
tcurve.base_length_(1120 );
|
|
|
|
fcurves.Construct(m_fman.path_adaptor );
|
|
fsegm.Construct (@fcurves );
|
|
ftrans.Construct (@fsegm ,@tcurve );
|
|
|
|
fsegm.approximation_scale_ (3.0 );
|
|
fcurves.approximation_scale_(2.0 );
|
|
|
|
if m_feng.load_font('timesi.ttf' ,0 ,glyph_ren_outline ) then
|
|
begin
|
|
x:=0.0;
|
|
y:=3.0;
|
|
p:=@text_[0 ];
|
|
|
|
m_feng.hinting_(false );
|
|
m_feng.height_ (40.0 );
|
|
|
|
while p^ <> 0 do
|
|
begin
|
|
glyph:=m_fman.glyph(p^ );
|
|
|
|
if glyph <> NIL then
|
|
begin
|
|
if x > tcurve.total_length then
|
|
break;
|
|
|
|
m_fman.add_kerning (@x ,@y );
|
|
m_fman.init_embedded_adaptors(glyph ,x ,y );
|
|
|
|
if glyph.data_type = glyph_data_outline then
|
|
begin
|
|
ras.reset;
|
|
ras.add_path(@ftrans );
|
|
|
|
rgba.ConstrInt(0 ,0 ,0 );
|
|
r.color_ (@rgba );
|
|
|
|
render_scanlines(@ras ,@sl ,@r );
|
|
|
|
end;
|
|
|
|
// increment pen position
|
|
x:=x + glyph.advance_x;
|
|
y:=y + glyph.advance_y;
|
|
|
|
end;
|
|
|
|
inc(ptrcomp(p ) ,sizeof(int8u ) );
|
|
|
|
end;
|
|
|
|
end
|
|
else
|
|
message_(
|
|
'Please copy file timesi.ttf to the current directory'#13 +
|
|
'or download it from http://www.antigrain.com/timesi.zip' );
|
|
|
|
// Render the path curve
|
|
stroke.Construct(@bspline );
|
|
stroke.width_ (2.0 );
|
|
|
|
rgba.ConstrInt(170 ,50 ,20 ,100 );
|
|
r.color_ (@rgba );
|
|
|
|
ras.add_path (@stroke );
|
|
render_scanlines(@ras ,@sl ,@r );
|
|
|
|
// Render the "poly" tool
|
|
rgba.ConstrDbl(0 ,0.3 ,0.5 ,0.3 );
|
|
r.color_ (@rgba );
|
|
|
|
ras.add_path (@m_poly );
|
|
render_scanlines(@ras ,@sl ,@r );
|
|
|
|
// Render the controls
|
|
render_ctrl(@ras ,@sl ,@r ,@m_close );
|
|
render_ctrl(@ras ,@sl ,@r ,@m_preserve_x_scale );
|
|
render_ctrl(@ras ,@sl ,@r ,@m_fixed_len );
|
|
render_ctrl(@ras ,@sl ,@r ,@m_animate );
|
|
render_ctrl(@ras ,@sl ,@r ,@m_num_points );
|
|
|
|
// Free AGG resources
|
|
sl.Destruct;
|
|
ras.Destruct;
|
|
|
|
bspline.Destruct;
|
|
tcurve.Destruct;
|
|
fcurves.Destruct;
|
|
fsegm.Destruct;
|
|
|
|
stroke.Destruct;
|
|
|
|
end;
|
|
|
|
{ ON_MOUSE_MOVE }
|
|
procedure the_application.on_mouse_move;
|
|
begin
|
|
if flags and mouse_left <> 0 then
|
|
if m_poly.on_mouse_move(x ,y ) then
|
|
force_redraw;
|
|
|
|
if flags and mouse_left = 0 then
|
|
on_mouse_button_up(x ,y ,flags );
|
|
|
|
end;
|
|
|
|
{ ON_MOUSE_BUTTON_DOWN }
|
|
procedure the_application.on_mouse_button_down;
|
|
begin
|
|
if flags and mouse_left <> 0 then
|
|
if m_poly.on_mouse_button_down(x ,y ) then
|
|
force_redraw;
|
|
|
|
end;
|
|
|
|
{ ON_MOUSE_BUTTON_UP }
|
|
procedure the_application.on_mouse_button_up;
|
|
begin
|
|
if m_poly.on_mouse_button_up(x ,y ) then
|
|
force_redraw;
|
|
|
|
end;
|
|
|
|
{ ON_KEY }
|
|
procedure the_application.on_key;
|
|
begin
|
|
if key = key_f1 then
|
|
message_(
|
|
'This is a "kinda-cool-stuff" demo that performs non-linear transformations and '#13 +
|
|
'draws vector text along a curve. Note that it''s not just calculating of the glyph '#13 +
|
|
'angles and positions, they are transformed as if they were elastic. The curve is '#13 +
|
|
'calculated as a bicubic spline. The option "Preserve X scale" makes the converter '#13 +
|
|
'distribute all the points uniformly along the curve. If it''s unchechked, the scale '#13 +
|
|
'will be proportional to the distance between the control points.' +
|
|
#13#13'Note: F2 key saves current "screenshot" file in this demo''s directory. ' );
|
|
|
|
end;
|
|
|
|
{ ON_CTRL_CHANGE }
|
|
procedure the_application.on_ctrl_change;
|
|
var
|
|
i : int;
|
|
|
|
begin
|
|
if m_animate._status <> m_prev_animate then
|
|
begin
|
|
if m_animate._status then
|
|
begin
|
|
on_init;
|
|
|
|
for i:=0 to 5 do
|
|
begin
|
|
m_dx[i ]:=((Random($7fff ) mod 1000 ) - 500 ) * 0.01;
|
|
m_dy[i ]:=((Random($7fff ) mod 1000 ) - 500 ) * 0.01;
|
|
|
|
end;
|
|
|
|
wait_mode_(false );
|
|
|
|
end
|
|
else
|
|
wait_mode_(true );
|
|
|
|
m_prev_animate:=m_animate._status;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{ MOVE_POINT }
|
|
procedure the_application.move_point;
|
|
begin
|
|
if x^ < 0.0 then
|
|
begin
|
|
x^ :=0.0;
|
|
dx^:=-dx^;
|
|
|
|
end;
|
|
|
|
if x^ > _width then
|
|
begin
|
|
x^ :=_width;
|
|
dx^:=-dx^;
|
|
|
|
end;
|
|
|
|
if y^ < 0.0 then
|
|
begin
|
|
y^ :=0.0;
|
|
dy^:=-dy^;
|
|
|
|
end;
|
|
|
|
if y^ > _height then
|
|
begin
|
|
y^ :=_height;
|
|
dy^:=-dy^;
|
|
|
|
end;
|
|
|
|
x^:=x^ + dx^;
|
|
y^:=y^ + dy^;
|
|
|
|
end;
|
|
|
|
{ ON_IDLE }
|
|
procedure the_application.on_idle;
|
|
var
|
|
i : int;
|
|
|
|
begin
|
|
for i:=0 to 5 do
|
|
move_point(m_poly.xn_ptr(i ) ,m_poly.yn_ptr(i ) ,@m_dx[i ] ,@m_dy[i ] );
|
|
|
|
force_redraw;
|
|
|
|
end;
|
|
|
|
VAR
|
|
app : the_application;
|
|
|
|
BEGIN
|
|
app.Construct(pix_format ,flip_y );
|
|
app.caption_ ('AGG Example. Non-linear "Along-A-Curve" Transformer - FreeType (F1-Help)' );
|
|
|
|
if app.init(600 ,600 ,window_resize ) then
|
|
app.run;
|
|
|
|
app.Destruct;
|
|
|
|
END.
|