mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-30 15:23:46 +02:00
293 lines
6.1 KiB
ObjectPascal
293 lines
6.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
|
||
rounded_rect ;
|
||
|
||
uses
|
||
agg_basics ,
|
||
agg_platform_support ,
|
||
agg_color ,
|
||
agg_pixfmt ,
|
||
agg_pixfmt_rgb ,
|
||
|
||
agg_ctrl ,
|
||
agg_slider_ctrl ,
|
||
agg_cbox_ctrl ,
|
||
|
||
agg_renderer_base ,
|
||
agg_renderer_scanline ,
|
||
agg_rasterizer_scanline_aa ,
|
||
agg_scanline_p ,
|
||
agg_render_scanlines ,
|
||
|
||
agg_gamma_functions ,
|
||
agg_gamma_lut ,
|
||
agg_ellipse ,
|
||
agg_rounded_rect ,
|
||
agg_conv_stroke ,
|
||
agg_vertex_source ;
|
||
|
||
{$I agg_mode.inc }
|
||
|
||
const
|
||
flip_y = true;
|
||
|
||
type
|
||
the_application = object(platform_support )
|
||
m_x ,
|
||
m_y : array[0..1 ] of double;
|
||
|
||
m_dx ,
|
||
m_dy : double;
|
||
|
||
m_idx : int;
|
||
|
||
m_radius ,
|
||
m_gamma ,
|
||
m_offset : slider_ctrl;
|
||
|
||
m_white_on_black : cbox_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;
|
||
var
|
||
rgba8 : aggclr;
|
||
|
||
begin
|
||
inherited Construct(format_ ,flip_y_ );
|
||
|
||
m_radius.Construct(10 ,10 ,600 - 10 ,19 ,not flip_y_ );
|
||
m_gamma.Construct (10 ,10 + 20 ,600 - 10 ,19 + 20 ,not flip_y_ );
|
||
m_offset.Construct(10 ,10 + 40 ,600 - 10 ,19 + 40 ,not flip_y_ );
|
||
|
||
m_white_on_black.Construct(10 ,10 + 60 ,'White on black' );
|
||
|
||
m_idx:=-1;
|
||
|
||
m_x[0 ]:=100; m_y[0 ]:=100;
|
||
m_x[1 ]:=500; m_y[1 ]:=350;
|
||
|
||
add_ctrl(@m_radius );
|
||
add_ctrl(@m_gamma );
|
||
add_ctrl(@m_offset );
|
||
add_ctrl(@m_white_on_black );
|
||
|
||
m_gamma.label_('gamma=%4.3f' );
|
||
m_gamma.range_(0.0 ,3.0 );
|
||
m_gamma.value_(1.8 );
|
||
|
||
m_radius.label_('radius=%4.3f' );
|
||
m_radius.range_(0.0 ,50.0 );
|
||
m_radius.value_(25.0 );
|
||
|
||
m_offset.label_('subpixel offset=%4.3f' );
|
||
m_offset.range_(-2.0 ,3.0 );
|
||
|
||
rgba8.ConstrInt(127 ,127 ,127 );
|
||
|
||
m_white_on_black.text_color_ (@rgba8 );
|
||
m_white_on_black.inactive_color_(@rgba8 );
|
||
|
||
end;
|
||
|
||
{ DESTRUCT }
|
||
destructor the_application.Destruct;
|
||
begin
|
||
inherited Destruct;
|
||
|
||
m_radius.Destruct;
|
||
m_gamma.Destruct;
|
||
m_offset.Destruct;
|
||
|
||
m_white_on_black.Destruct;
|
||
|
||
end;
|
||
|
||
{ ON_DRAW }
|
||
procedure the_application.on_draw;
|
||
var
|
||
pixf : pixel_formats;
|
||
|
||
rb : renderer_base;
|
||
ren : renderer_scanline_aa_solid;
|
||
ras : rasterizer_scanline_aa;
|
||
sl : scanline_p8;
|
||
|
||
rgba : aggclr;
|
||
gamma : gamma_lut;
|
||
gm_no : vertex_source;
|
||
|
||
e : ellipse;
|
||
r : agg_rounded_rect.rounded_rect;
|
||
p : conv_stroke;
|
||
d : double;
|
||
|
||
begin
|
||
// Initialize structures
|
||
gamma.Construct(m_gamma._value ,8 ,8 );
|
||
|
||
pixfmt_bgr24_gamma(pixf ,rbuf_window ,@gamma );
|
||
|
||
rb.Construct (@pixf );
|
||
ren.Construct(@rb );
|
||
|
||
if m_white_on_black._status then
|
||
rgba.ConstrDbl(0 ,0 ,0 )
|
||
else
|
||
rgba.ConstrDbl(1 ,1 ,1 );
|
||
|
||
rb.clear(@rgba );
|
||
|
||
ras.Construct;
|
||
sl.Construct;
|
||
|
||
// Render two "control" circles
|
||
e.Construct;
|
||
rgba.ConstrInt(127 ,127 ,127 );
|
||
ren.color_ (@rgba );
|
||
|
||
e.init (m_x[0 ] ,m_y[0 ] ,3 ,3 ,16 );
|
||
ras.add_path(@e );
|
||
|
||
render_scanlines(@ras ,@sl ,@ren );
|
||
|
||
e.init (m_x[1 ] ,m_y[1 ] ,3 ,3 ,16 );
|
||
ras.add_path(@e );
|
||
|
||
render_scanlines(@ras ,@sl ,@ren );
|
||
|
||
// Creating a rounded rectangle
|
||
d:=m_offset._value;
|
||
|
||
r.Construct(m_x[0 ] + d ,m_y[0 ] + d ,m_x[1 ] + d ,m_y[1 ] + d ,m_radius._value );
|
||
r.normalize_radius;
|
||
|
||
// Drawing as an outline
|
||
p.Construct(@r );
|
||
p.width_ (1.0 );
|
||
|
||
ras.add_path(@p );
|
||
|
||
if m_white_on_black._status then
|
||
rgba.ConstrDbl(1 ,1 ,1 )
|
||
else
|
||
rgba.ConstrDbl(0 ,0 ,0 );
|
||
|
||
ren.color_(@rgba );
|
||
|
||
render_scanlines(@ras ,@sl ,@ren );
|
||
|
||
gm_no.Construct;
|
||
ras.gamma(@gm_no );
|
||
|
||
// Render the controls
|
||
render_ctrl(@ras ,@sl ,@ren ,@m_radius );
|
||
render_ctrl(@ras ,@sl ,@ren ,@m_gamma );
|
||
render_ctrl(@ras ,@sl ,@ren ,@m_offset );
|
||
render_ctrl(@ras ,@sl ,@ren ,@m_white_on_black );
|
||
|
||
// Free AGG resources
|
||
ras.Destruct;
|
||
sl.Destruct;
|
||
|
||
gamma.Destruct;
|
||
p.Destruct;
|
||
|
||
end;
|
||
|
||
{ ON_MOUSE_MOVE }
|
||
procedure the_application.on_mouse_move;
|
||
begin
|
||
if flags and mouse_left <> 0 then
|
||
if m_idx >= 0 then
|
||
begin
|
||
m_x[m_idx ]:=x - m_dx;
|
||
m_y[m_idx ]:=y - m_dy;
|
||
|
||
force_redraw;
|
||
|
||
end
|
||
else
|
||
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
|
||
for i:=0 to 1 do
|
||
if Sqrt((x - m_x[i ] ) * (x - m_x[i ] ) + (y - m_y[i ] ) * (y - m_y[i ] ) ) < 5.0 then
|
||
begin
|
||
m_dx :=x - m_x[i ];
|
||
m_dy :=y - m_y[i ];
|
||
m_idx:=i;
|
||
|
||
break;
|
||
|
||
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;
|
||
begin
|
||
if key = key_f1 then
|
||
message_(
|
||
'Yet another example dedicated to Gamma Correction. If you have a CRT monitor: '#13 +
|
||
'The rectangle looks bad - the rounded corners are thicker than its side lines. '#13 +
|
||
'First try to drag the "subpixel offset" control <20> it simply adds some fractional '#13 +
|
||
'value to the coordinates. When dragging you will see that the rectangle is'#13 +
|
||
'"blinking". Then increase "Gamma" to about 1.5. The result will look almost '#13 +
|
||
'perfect <20> the visual thickness of the rectangle remains the same. That''s good, '#13 +
|
||
'but turn the checkbox "White on black" on <20> what do we see ? Our rounded '#13 +
|
||
'rectangle looks terrible. Drag the "subpixel offset" slider <20> it''s blinking as hell. '#13 +
|
||
'Now decrease "Gamma" to about 0.6. What do we see now ? Perfect result ! '#13 +
|
||
'If you use an LCD monitor, the good value of gamma will be closer to 1.0 in both '#13 +
|
||
'cases <20> black on white or white on black. There''s no perfection in this world, but '#13 +
|
||
'at least you can control Gamma in Anti-Grain Geometry :-)' +
|
||
#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. Rounded rectangle with gamma-correction & stuff (F1-Help)' );
|
||
|
||
if app.init(600 ,400 ,window_resize ) then
|
||
app.run;
|
||
|
||
app.Destruct;
|
||
|
||
END. |