mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-30 17:23:44 +02:00
1591 lines
28 KiB
ObjectPascal
1591 lines
28 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
|
|
graph_test ;
|
|
|
|
uses
|
|
SysUtils ,
|
|
|
|
agg_basics ,
|
|
agg_platform_support ,
|
|
|
|
agg_color ,
|
|
agg_pixfmt ,
|
|
agg_pixfmt_rgb ,
|
|
|
|
agg_ctrl ,
|
|
agg_slider_ctrl ,
|
|
agg_cbox_ctrl ,
|
|
agg_rbox_ctrl ,
|
|
|
|
agg_renderer_base ,
|
|
agg_renderer_scanline ,
|
|
agg_renderer_primitives ,
|
|
agg_rasterizer_scanline_aa ,
|
|
agg_rasterizer_outline ,
|
|
agg_scanline ,
|
|
agg_scanline_p ,
|
|
agg_scanline_u ,
|
|
agg_render_scanlines ,
|
|
|
|
agg_array ,
|
|
agg_curves ,
|
|
agg_ellipse ,
|
|
agg_vertex_source ,
|
|
agg_conv_stroke ,
|
|
agg_conv_dash ,
|
|
agg_conv_curve ,
|
|
agg_conv_contour ,
|
|
agg_conv_marker ,
|
|
agg_conv_shorten_path ,
|
|
agg_conv_marker_adaptor ,
|
|
agg_conv_concat ,
|
|
agg_arrowhead ,
|
|
agg_vcgen_markers_term ,
|
|
agg_span_allocator ,
|
|
agg_span_gradient ,
|
|
agg_span_interpolator_linear ,
|
|
agg_gamma_functions ,
|
|
agg_trans_affine ;
|
|
|
|
{$I agg_mode.inc }
|
|
{$I- }
|
|
const
|
|
flip_y = true;
|
|
|
|
type
|
|
base_renderer = renderer_base;
|
|
primitives_renderer = renderer_primitives;
|
|
solid_renderer = renderer_scanline_aa_solid;
|
|
draft_renderer = renderer_scanline_bin_solid;
|
|
gradient_function = gradient_radial_d;
|
|
interpolator = span_interpolator_linear;
|
|
gradient_span_gen = span_gradient;
|
|
gradient_span_alloc = span_allocator;
|
|
gradient_renderer = renderer_scanline_aa;
|
|
scanline_rasterizer = rasterizer_scanline_aa;
|
|
outline_rasterizer = rasterizer_outline;
|
|
|
|
node_ptr = ^node;
|
|
node = object
|
|
x ,y : double;
|
|
|
|
constructor Construct; overload;
|
|
constructor Construct(x_ ,y_ : double ); overload;
|
|
|
|
end;
|
|
|
|
edge_ptr = ^edge;
|
|
edge = object
|
|
node1 ,node2 : int;
|
|
|
|
constructor Construct; overload;
|
|
constructor Construct(n1 ,n2 : int ); overload;
|
|
|
|
end;
|
|
|
|
graph = object
|
|
m_num_nodes ,
|
|
m_num_edges : int;
|
|
|
|
m_nodes : node_ptr;
|
|
m_edges : edge_ptr;
|
|
|
|
constructor Construct(num_nodes ,num_edges : int );
|
|
destructor Destruct;
|
|
|
|
function get_num_nodes : int;
|
|
function get_num_edges : int;
|
|
|
|
function get_node(idx : int; w ,h : double ) : node;
|
|
function get_edge(idx : int ) : edge;
|
|
|
|
end;
|
|
|
|
line = object(vertex_source )
|
|
x1 ,y1 ,x2 ,y2 : double;
|
|
|
|
f : int;
|
|
|
|
constructor Construct(x1_ ,y1_ ,x2_ ,y2_ : double );
|
|
|
|
procedure rewind(path_id : unsigned ); virtual;
|
|
function vertex(x ,y : double_ptr ) : unsigned; virtual;
|
|
|
|
end;
|
|
|
|
curve = object(vertex_source )
|
|
c : curve4;
|
|
|
|
constructor Construct(x1 ,y1 ,x2 ,y2 : double; k : double = 0.5 );
|
|
destructor Destruct; virtual;
|
|
|
|
procedure rewind(path_id : unsigned ); virtual;
|
|
function vertex(x ,y : double_ptr ) : unsigned; virtual;
|
|
|
|
end;
|
|
|
|
stroke_draft_simple = object(vertex_source )
|
|
s : vertex_source_ptr;
|
|
|
|
constructor Construct(src : vertex_source_ptr );
|
|
|
|
procedure rewind(path_id : unsigned ); virtual;
|
|
function vertex(x ,y : double_ptr ) : unsigned; virtual;
|
|
|
|
end;
|
|
|
|
stroke_draft_arrow = object(vertex_source )
|
|
s : conv_marker_adaptor;
|
|
ah : arrowhead;
|
|
m : conv_marker;
|
|
ma : vcgen_markers_term;
|
|
c : conv_concat;
|
|
|
|
constructor Construct(src : vertex_source_ptr; w : double );
|
|
destructor Destruct; virtual;
|
|
|
|
procedure rewind(path_id : unsigned ); virtual;
|
|
function vertex(x ,y : double_ptr ) : unsigned; virtual;
|
|
|
|
end;
|
|
|
|
stroke_fine_simple = object(vertex_source )
|
|
s : conv_stroke;
|
|
|
|
constructor Construct(src : vertex_source_ptr; w : double );
|
|
destructor Destruct; virtual;
|
|
|
|
procedure rewind(path_id : unsigned ); virtual;
|
|
function vertex(x ,y : double_ptr ) : unsigned; virtual;
|
|
|
|
end;
|
|
|
|
stroke_fine_arrow = object(vertex_source )
|
|
s : conv_stroke;
|
|
ah : arrowhead;
|
|
m : conv_marker;
|
|
ma : vcgen_markers_term;
|
|
c : conv_concat;
|
|
|
|
constructor Construct(src : vertex_source_ptr; w : double );
|
|
destructor Destruct; virtual;
|
|
|
|
procedure rewind(path_id : unsigned ); virtual;
|
|
function vertex(x ,y : double_ptr ) : unsigned; virtual;
|
|
|
|
end;
|
|
|
|
dash_stroke_draft_simple = object(vertex_source )
|
|
d : conv_dash;
|
|
|
|
constructor Construct(src : vertex_source_ptr; dash_len ,gap_len ,w : double );
|
|
destructor Destruct; virtual;
|
|
|
|
procedure rewind(path_id : unsigned ); virtual;
|
|
function vertex(x ,y : double_ptr ) : unsigned; virtual;
|
|
|
|
end;
|
|
|
|
dash_stroke_draft_arrow = object(vertex_source )
|
|
d : conv_dash;
|
|
ah : arrowhead;
|
|
m : conv_marker;
|
|
ma : vcgen_markers_term;
|
|
c : conv_concat;
|
|
|
|
constructor Construct(src : vertex_source_ptr; dash_len ,gap_len ,w : double );
|
|
destructor Destruct; virtual;
|
|
|
|
procedure rewind(path_id : unsigned ); virtual;
|
|
function vertex(x ,y : double_ptr ) : unsigned; virtual;
|
|
|
|
end;
|
|
|
|
dash_stroke_fine_simple = object(vertex_source )
|
|
d : conv_dash;
|
|
s : conv_stroke;
|
|
|
|
constructor Construct(src : vertex_source_ptr; dash_len ,gap_len ,w : double );
|
|
destructor Destruct; virtual;
|
|
|
|
procedure rewind(path_id : unsigned ); virtual;
|
|
function vertex(x ,y : double_ptr ) : unsigned; virtual;
|
|
|
|
end;
|
|
|
|
dash_stroke_fine_arrow = object(vertex_source )
|
|
d : conv_dash;
|
|
s : conv_stroke;
|
|
ah : arrowhead;
|
|
m : conv_marker;
|
|
ma : vcgen_markers_term;
|
|
c : conv_concat;
|
|
|
|
constructor Construct(src : vertex_source_ptr; dash_len ,gap_len ,w : double );
|
|
destructor Destruct; virtual;
|
|
|
|
procedure rewind(path_id : unsigned ); virtual;
|
|
function vertex(x ,y : double_ptr ) : unsigned; virtual;
|
|
|
|
end;
|
|
|
|
{ stroke_draft = stroke_draft_simple;
|
|
dash_stroke_draft = dash_stroke_draft_simple;
|
|
stroke_fine = stroke_fine_simple;
|
|
dash_stroke_fine = dash_stroke_fine_simple;{}
|
|
|
|
stroke_draft = stroke_draft_arrow;
|
|
dash_stroke_draft = dash_stroke_draft_arrow;
|
|
stroke_fine = stroke_fine_arrow;
|
|
dash_stroke_fine = dash_stroke_fine_arrow;{}
|
|
|
|
the_application = object(platform_support )
|
|
m_type : rbox_ctrl;
|
|
m_width : slider_ctrl;
|
|
|
|
m_benchmark ,
|
|
m_draw_nodes ,
|
|
m_draw_edges ,
|
|
m_draft ,
|
|
m_translucent : cbox_ctrl;
|
|
|
|
m_gradient_colors : pod_auto_array;
|
|
|
|
m_graph : graph;
|
|
m_draw : int;
|
|
m_sl : scanline_u8;
|
|
|
|
constructor Construct(format_ : pix_format_e; flip_y_ : boolean );
|
|
destructor Destruct;
|
|
|
|
procedure draw_nodes_draft;
|
|
procedure draw_nodes_fine(ras : rasterizer_scanline_ptr );
|
|
|
|
procedure render_edge_fine(
|
|
ras : rasterizer_scanline_ptr;
|
|
ren_fine ,
|
|
ren_draft : renderer_scanline_ptr;
|
|
src : vertex_source_ptr );
|
|
|
|
procedure draw_lines_draft;
|
|
procedure draw_curves_draft;
|
|
procedure draw_dashes_draft;
|
|
|
|
procedure draw_lines_fine(
|
|
ras : rasterizer_scanline_ptr;
|
|
solid ,
|
|
draft : renderer_scanline_ptr );
|
|
|
|
procedure draw_curves_fine(
|
|
ras : rasterizer_scanline_ptr;
|
|
solid ,
|
|
draft : renderer_scanline_ptr );
|
|
|
|
procedure draw_dashes_fine(
|
|
ras : rasterizer_scanline_ptr;
|
|
solid ,
|
|
draft : renderer_scanline_ptr );
|
|
|
|
procedure draw_polygons(
|
|
ras : rasterizer_scanline_ptr;
|
|
solid ,
|
|
draft : renderer_scanline_ptr );
|
|
|
|
procedure draw_scene(
|
|
ras : rasterizer_scanline_ptr;
|
|
solid ,
|
|
draft : renderer_scanline_ptr );
|
|
|
|
procedure on_draw; virtual;
|
|
procedure on_ctrl_change; virtual;
|
|
|
|
procedure on_key(x ,y : int; key ,flags : unsigned ); virtual;
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor node.Construct;
|
|
begin
|
|
x:=0;
|
|
y:=0;
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor node.Construct(x_ ,y_ : double );
|
|
begin
|
|
x:=x_;
|
|
y:=y_;
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor edge.Construct;
|
|
begin
|
|
node1:=0;
|
|
node2:=0;
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor edge.Construct(n1 ,n2 : int );
|
|
begin
|
|
node1:=n1;
|
|
node2:=n2;
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor graph.Construct;
|
|
var
|
|
i : int;
|
|
n : node_ptr;
|
|
e : edge_ptr;
|
|
|
|
begin
|
|
m_num_nodes:=num_nodes;
|
|
m_num_edges:=num_edges;
|
|
|
|
agg_getmem(pointer(m_nodes ) ,m_num_nodes * sizeof(node ) );
|
|
agg_getmem(pointer(m_edges ) ,m_num_edges * sizeof(edge ) );
|
|
|
|
RandSeed:=100;
|
|
|
|
for i:=0 to m_num_nodes - 1 do
|
|
begin
|
|
n:=node_ptr(ptrcomp(m_nodes ) + i * sizeof(node ) );
|
|
|
|
n.x:=(Random($7fff ) / $7fff ) * 0.75 + 0.2;
|
|
n.y:=(Random($7fff ) / $7fff ) * 0.85 + 0.1;
|
|
|
|
end;
|
|
|
|
i:=0;
|
|
|
|
while i < m_num_edges do
|
|
begin
|
|
e:=edge_ptr(ptrcomp(m_edges ) + i * sizeof(edge ) );
|
|
|
|
e.node1:=Random($7fff ) mod m_num_nodes;
|
|
e.node2:=Random($7fff ) mod m_num_nodes;
|
|
|
|
if e.node1 = e.node2 then
|
|
dec(i );
|
|
|
|
inc(i );
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{ DESTRUCT }
|
|
destructor graph.Destruct;
|
|
begin
|
|
agg_freemem(pointer(m_nodes ) ,m_num_nodes * sizeof(node ) );
|
|
agg_freemem(pointer(m_edges ) ,m_num_edges * sizeof(edge ) );
|
|
|
|
end;
|
|
|
|
{ GET_NUM_NODES }
|
|
function graph.get_num_nodes;
|
|
begin
|
|
result:=m_num_nodes;
|
|
|
|
end;
|
|
|
|
{ GET_NUM_EDGES }
|
|
function graph.get_num_edges;
|
|
begin
|
|
result:=m_num_edges;
|
|
|
|
end;
|
|
|
|
{ GET_NODE }
|
|
function graph.get_node;
|
|
var
|
|
p : node;
|
|
|
|
begin
|
|
p.Construct;
|
|
|
|
if idx < m_num_nodes then
|
|
begin
|
|
p:=node_ptr(ptrcomp(m_nodes ) + idx * sizeof(node ) )^;
|
|
|
|
p.x:=p.x * w;
|
|
p.y:=p.y * h;
|
|
|
|
end;
|
|
|
|
result:=p;
|
|
|
|
end;
|
|
|
|
{ GET_EDGE }
|
|
function graph.get_edge;
|
|
var
|
|
b : edge;
|
|
|
|
begin
|
|
b.Construct;
|
|
|
|
if idx < m_num_edges then
|
|
b:=edge_ptr(ptrcomp(m_edges ) + idx * sizeof(edge ) )^;
|
|
|
|
result:=b;
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor line.Construct;
|
|
begin
|
|
x1:=x1_;
|
|
y1:=y1_;
|
|
x2:=x2_;
|
|
y2:=y2_;
|
|
f :=0;
|
|
|
|
end;
|
|
|
|
{ REWIND }
|
|
procedure line.rewind;
|
|
begin
|
|
f:=0;
|
|
|
|
end;
|
|
|
|
{ VERTEX }
|
|
function line.vertex;
|
|
begin
|
|
if f = 0 then
|
|
begin
|
|
inc(f );
|
|
|
|
x^:=x1;
|
|
y^:=y1;
|
|
|
|
result:=path_cmd_move_to;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
if f = 1 then
|
|
begin
|
|
inc(f );
|
|
|
|
x^:=x2;
|
|
y^:=y2;
|
|
|
|
result:=path_cmd_line_to;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
result:=path_cmd_stop;
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor curve.Construct;
|
|
begin
|
|
c.Construct;
|
|
c.init4(
|
|
x1 ,y1 ,
|
|
x1 - (y2 - y1 ) * k ,
|
|
y1 + (x2 - x1 ) * k ,
|
|
x2 + (y2 - y1 ) * k ,
|
|
y2 - (x2 - x1 ) * k ,
|
|
x2 ,y2 );
|
|
|
|
end;
|
|
|
|
{ DESTRUCT }
|
|
destructor curve.Destruct;
|
|
begin
|
|
c.Destruct;
|
|
|
|
end;
|
|
|
|
{ REWIND }
|
|
procedure curve.rewind;
|
|
begin
|
|
c.rewind(path_id );
|
|
|
|
end;
|
|
|
|
{ VERTEX }
|
|
function curve.vertex;
|
|
begin
|
|
result:=c.vertex(x ,y );
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor stroke_draft_simple.Construct;
|
|
begin
|
|
s:=src;
|
|
|
|
end;
|
|
|
|
{ REWIND }
|
|
procedure stroke_draft_simple.rewind;
|
|
begin
|
|
s.rewind(path_id );
|
|
|
|
end;
|
|
|
|
{ VERTEX }
|
|
function stroke_draft_simple.vertex;
|
|
begin
|
|
s.vertex(x ,y );
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor stroke_draft_arrow.Construct;
|
|
begin
|
|
s.Construct(src );
|
|
ma.Construct;
|
|
s.set_markers(@ma );
|
|
ah.Construct;
|
|
m.Construct(s.markers ,@ah );
|
|
c.Construct(@s ,@m );
|
|
|
|
ah.head_ (0 ,10 ,5 ,0 );
|
|
s.shorten_(10.0 );
|
|
|
|
end;
|
|
|
|
{ DESTRUCT }
|
|
destructor stroke_draft_arrow.Destruct;
|
|
begin
|
|
s.Destruct;
|
|
ma.Destruct;
|
|
|
|
end;
|
|
|
|
{ REWIND }
|
|
procedure stroke_draft_arrow.rewind;
|
|
begin
|
|
c.rewind(path_id );
|
|
|
|
end;
|
|
|
|
{ VERTEX }
|
|
function stroke_draft_arrow.vertex;
|
|
begin
|
|
result:=c.vertex(x ,y );
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor stroke_fine_simple.Construct;
|
|
begin
|
|
s.Construct(src );
|
|
s.width_ (w );
|
|
|
|
end;
|
|
|
|
{ DESTRUCT }
|
|
destructor stroke_fine_simple.Destruct;
|
|
begin
|
|
s.Destruct;
|
|
|
|
end;
|
|
|
|
{ REWIND }
|
|
procedure stroke_fine_simple.rewind;
|
|
begin
|
|
s.rewind(path_id );
|
|
|
|
end;
|
|
|
|
{ VERTEX }
|
|
function stroke_fine_simple.vertex;
|
|
begin
|
|
result:=s.vertex(x ,y );
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor stroke_fine_arrow.Construct;
|
|
begin
|
|
s.Construct(src );
|
|
ma.Construct;
|
|
s.set_markers(@ma );
|
|
ah.Construct;
|
|
m.Construct(s.markers ,@ah );
|
|
c.Construct(@s ,@m );
|
|
|
|
s.width_ (w );
|
|
ah.head_ (0 ,10 ,5 ,0 );
|
|
s.shorten_(w * 2.0 );
|
|
|
|
end;
|
|
|
|
{ DESTRUCT }
|
|
destructor stroke_fine_arrow.Destruct;
|
|
begin
|
|
s.Destruct;
|
|
ma.Destruct;
|
|
|
|
end;
|
|
|
|
{ REWIND }
|
|
procedure stroke_fine_arrow.rewind;
|
|
begin
|
|
c.rewind(path_id );
|
|
|
|
end;
|
|
|
|
{ VERTEX }
|
|
function stroke_fine_arrow.vertex;
|
|
begin
|
|
result:=c.vertex(x ,y );
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor dash_stroke_draft_simple.Construct;
|
|
begin
|
|
d.Construct(src );
|
|
d.add_dash (dash_len ,gap_len );
|
|
|
|
end;
|
|
|
|
{ DESTRUCT }
|
|
destructor dash_stroke_draft_simple.Destruct;
|
|
begin
|
|
d.Destruct;
|
|
|
|
end;
|
|
|
|
{ REWIND }
|
|
procedure dash_stroke_draft_simple.rewind;
|
|
begin
|
|
d.rewind(path_id );
|
|
|
|
end;
|
|
|
|
{ VERTEX }
|
|
function dash_stroke_draft_simple.vertex;
|
|
begin
|
|
result:=d.vertex(x ,y );
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor dash_stroke_draft_arrow.Construct;
|
|
begin
|
|
d.Construct(src );
|
|
ma.Construct;
|
|
d.set_markers(@ma );
|
|
ah.Construct;
|
|
m.Construct(d.markers ,@ah );
|
|
c.Construct(@d ,@m );
|
|
|
|
d.add_dash(dash_len ,gap_len );
|
|
|
|
ah.head_ (0 ,10 ,5 ,0 );
|
|
d.shorten_(10.0 );
|
|
|
|
end;
|
|
|
|
{ DESTRUCT }
|
|
destructor dash_stroke_draft_arrow.Destruct;
|
|
begin
|
|
d.Destruct;
|
|
ma.Destruct;
|
|
|
|
end;
|
|
|
|
{ REWIND }
|
|
procedure dash_stroke_draft_arrow.rewind;
|
|
begin
|
|
c.rewind(path_id );
|
|
|
|
end;
|
|
|
|
{ VERTEX }
|
|
function dash_stroke_draft_arrow.vertex;
|
|
begin
|
|
result:=c.vertex(x ,y );
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor dash_stroke_fine_simple.Construct;
|
|
begin
|
|
d.Construct(src );
|
|
s.Construct(@d );
|
|
|
|
d.add_dash(dash_len ,gap_len );
|
|
s.width_ (w );
|
|
|
|
end;
|
|
|
|
{ DESTRUCT }
|
|
destructor dash_stroke_fine_simple.Destruct;
|
|
begin
|
|
d.Destruct;
|
|
s.Destruct;
|
|
|
|
end;
|
|
|
|
{ REWIND }
|
|
procedure dash_stroke_fine_simple.rewind;
|
|
begin
|
|
s.rewind(path_id );
|
|
|
|
end;
|
|
|
|
{ VERTEX }
|
|
function dash_stroke_fine_simple.vertex;
|
|
begin
|
|
result:=s.vertex(x ,y );
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor dash_stroke_fine_arrow.Construct;
|
|
begin
|
|
d.Construct(src );
|
|
ma.Construct;
|
|
d.set_markers(@ma );
|
|
s.Construct(@d );
|
|
ah.Construct;
|
|
m.Construct(d.markers ,@ah );
|
|
c.Construct(@s ,@m );
|
|
|
|
d.add_dash(dash_len ,gap_len );
|
|
s.width_ (w );
|
|
ah.head_ (0 ,10 ,5 ,0 );
|
|
d.shorten_(w * 2.0 );
|
|
|
|
end;
|
|
|
|
{ DESTRUCT }
|
|
destructor dash_stroke_fine_arrow.Destruct;
|
|
begin
|
|
d.Destruct;
|
|
s.Destruct;
|
|
ma.Destruct;
|
|
|
|
end;
|
|
|
|
{ REWIND }
|
|
procedure dash_stroke_fine_arrow.rewind;
|
|
begin
|
|
c.rewind(path_id );
|
|
|
|
end;
|
|
|
|
{ VERTEX }
|
|
function dash_stroke_fine_arrow.vertex;
|
|
begin
|
|
result:=c.vertex(x ,y );
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor the_application.Construct;
|
|
var
|
|
i : int;
|
|
|
|
c1 ,c2 : aggclr;
|
|
|
|
begin
|
|
inherited Construct(format_ ,flip_y_ );
|
|
|
|
m_type.Construct (-1 ,-1 ,-1 ,-1 ,not flip_y_ );
|
|
m_width.Construct(110 + 80 ,8.0 ,110 + 200.0 + 80 ,8.0 + 7.0 ,not flip_y_ );
|
|
|
|
m_benchmark.Construct (110 + 200 + 80 + 8 ,8.0 - 2.0 ,'Benchmark' ,not flip_y_ );
|
|
m_draw_nodes.Construct (110 + 200 + 80 + 8 ,8.0 - 2.0 + 15.0 ,'Draw Nodes' ,not flip_y_ );
|
|
m_draw_edges.Construct (200 + 200 + 80 + 8 ,8.0 - 2.0 + 15.0 ,'Draw Edges' ,not flip_y_ );
|
|
m_draft.Construct (200 + 200 + 80 + 8 ,8.0 - 2.0 ,'Draft Mode' ,not flip_y_ );
|
|
m_translucent.Construct(110 + 80 ,8.0 - 2.0 + 15.0 ,'Translucent Mode' ,not flip_y_ );
|
|
|
|
m_graph.Construct(200 ,100 );
|
|
m_sl.Construct;
|
|
|
|
m_draw:=3;
|
|
|
|
m_gradient_colors.Construct(256 ,sizeof(aggclr ) );
|
|
|
|
add_ctrl(@m_type );
|
|
|
|
m_type.text_size_(8.0 );
|
|
m_type.add_item ('Solid lines' );
|
|
m_type.add_item ('Bezier curves' );
|
|
m_type.add_item ('Dashed curves' );
|
|
m_type.add_item ('Poygons AA' );
|
|
m_type.add_item ('Poygons Bin' );
|
|
m_type.cur_item_ (0 );
|
|
|
|
add_ctrl(@m_width );
|
|
|
|
m_width.num_steps_(20 );
|
|
m_width.range_ (0.0 ,5.0 );
|
|
m_width.value_ (2.0 );
|
|
m_width.label_ ('Width=%1.2f' );
|
|
|
|
m_benchmark.text_size_ (8.0 );
|
|
m_draw_nodes.text_size_(8.0 );
|
|
m_draft.text_size_ (8.0 );
|
|
m_draw_nodes.status_ (true );
|
|
m_draw_edges.status_ (true );
|
|
|
|
add_ctrl(@m_benchmark );
|
|
add_ctrl(@m_draw_nodes );
|
|
add_ctrl(@m_draw_edges );
|
|
add_ctrl(@m_draft );
|
|
add_ctrl(@m_translucent );
|
|
|
|
c1.ConstrDbl(1 ,1 ,0 ,0.25 );
|
|
c2.ConstrDbl(0 ,0 ,1 );
|
|
|
|
for i:=0 to 255 do
|
|
aggclr_ptr(
|
|
m_gradient_colors.array_operator(i ) )^:=c1.gradient(@c2 ,i / 255.0 );
|
|
|
|
end;
|
|
|
|
{ DESTRUCT }
|
|
destructor the_application.Destruct;
|
|
begin
|
|
inherited Destruct;
|
|
|
|
m_type.Destruct;
|
|
m_width.Destruct;
|
|
|
|
m_benchmark.Destruct;
|
|
m_draw_nodes.Destruct;
|
|
m_draw_edges.Destruct;
|
|
m_draft.Destruct;
|
|
m_translucent.Destruct;
|
|
|
|
m_graph.Destruct;
|
|
m_sl.Destruct;
|
|
m_gradient_colors.Destruct;
|
|
|
|
end;
|
|
|
|
{ DRAW_NODES_DRAFT }
|
|
procedure the_application.draw_nodes_draft;
|
|
var
|
|
pixf : pixel_formats;
|
|
|
|
rb : base_renderer;
|
|
prim : primitives_renderer;
|
|
|
|
i : int;
|
|
n : node;
|
|
|
|
begin
|
|
pixfmt_bgr24 (pixf ,rbuf_window );
|
|
rb.Construct (@pixf );
|
|
prim.Construct(@rb );
|
|
|
|
i:=0;
|
|
|
|
while i < m_graph.get_num_nodes do
|
|
begin
|
|
n:=m_graph.get_node(i ,_width ,_height );
|
|
|
|
prim.fill_color_ (aggclr_ptr(m_gradient_colors.array_operator(147 ) ) );
|
|
prim.line_color_ (aggclr_ptr(m_gradient_colors.array_operator(255 ) ) );
|
|
prim.outlined_ellipse(trunc(n.x ) ,trunc(n.y ) ,10 ,10 );
|
|
prim.fill_color_ (aggclr_ptr(m_gradient_colors.array_operator(50 ) ) );
|
|
prim.solid_ellipse (trunc(n.x ) ,trunc(n.y ) ,4 ,4 );
|
|
|
|
inc(i );
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{ DRAW_NODES_FINE }
|
|
procedure the_application.draw_nodes_fine;
|
|
var
|
|
pixf : pixel_formats;
|
|
|
|
sa : gradient_span_alloc;
|
|
rb : base_renderer;
|
|
gf : gradient_function;
|
|
sg : gradient_span_gen;
|
|
|
|
i : int;
|
|
n : node;
|
|
|
|
ell : ellipse;
|
|
mtx : trans_affine;
|
|
tas : trans_affine_scaling;
|
|
tat : trans_affine_translation;
|
|
ren : gradient_renderer;
|
|
|
|
inter : interpolator;
|
|
|
|
x ,y : double;
|
|
|
|
begin
|
|
sa.Construct;
|
|
pixfmt_bgr24(pixf ,rbuf_window );
|
|
rb.Construct(@pixf );
|
|
|
|
i:=0;
|
|
|
|
while i < m_graph.get_num_nodes do
|
|
begin
|
|
n:=m_graph.get_node(i ,_width ,_height );
|
|
|
|
ell.Construct(n.x ,n.y ,5.0 * m_width._value ,5.0 * m_width._value );
|
|
|
|
case m_draw of
|
|
0 :
|
|
begin
|
|
ell.rewind(0);
|
|
|
|
while not is_stop(ell.vertex(@x ,@y ) ) do;
|
|
|
|
end;
|
|
|
|
1 :
|
|
begin
|
|
ras.reset;
|
|
ras.add_path(@ell );
|
|
|
|
end;
|
|
|
|
2 :
|
|
begin
|
|
ras.reset;
|
|
ras.add_path(@ell );
|
|
ras.sort;
|
|
|
|
end;
|
|
|
|
3 :
|
|
begin
|
|
gf.Construct;
|
|
mtx.Construct;
|
|
tas.Construct(m_width._value / 2.0 ); mtx.multiply(@tas );
|
|
tat.Construct(n.x ,n.y ); mtx.multiply(@tat );
|
|
mtx.invert;
|
|
inter.Construct(@mtx );
|
|
sg.Construct (@sa ,@inter ,@gf ,@m_gradient_colors ,0.0 ,10.0 );
|
|
ren.Construct(@rb ,@sg );
|
|
|
|
ras.add_path (@ell);
|
|
render_scanlines(ras ,@m_sl ,@ren );
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
inc(i );
|
|
|
|
end;
|
|
|
|
sa.Destruct;
|
|
|
|
end;
|
|
|
|
{ RENDER_EDGE_FINE }
|
|
procedure the_application.render_edge_fine;
|
|
var
|
|
rgba : aggclr;
|
|
x ,y : double;
|
|
|
|
r ,g ,b ,a : int;
|
|
|
|
begin
|
|
case m_draw of
|
|
0 :
|
|
begin
|
|
src.rewind(0 );
|
|
|
|
while not is_stop(src.vertex(@x ,@y ) ) do;
|
|
|
|
end;
|
|
|
|
1 :
|
|
begin
|
|
ras.reset;
|
|
ras.add_path(src );
|
|
|
|
end;
|
|
|
|
2 :
|
|
begin
|
|
ras.reset;
|
|
ras.add_path(src );
|
|
ras.sort;
|
|
|
|
end;
|
|
|
|
3 :
|
|
begin
|
|
r:=Random($7fff ) and $7F;
|
|
g:=Random($7fff ) and $7F;
|
|
b:=Random($7fff ) and $7F;
|
|
a:=255;
|
|
|
|
if m_translucent._status then
|
|
a:=80;
|
|
|
|
ras.add_path(src );
|
|
|
|
if m_type._cur_item < 4 then
|
|
begin
|
|
rgba.ConstrInt (r ,g ,b ,a );
|
|
ren_fine.color_ (@rgba );
|
|
render_scanlines(ras ,@m_sl ,ren_fine );
|
|
|
|
end
|
|
else
|
|
begin
|
|
rgba.ConstrInt (r ,g ,b ,a );
|
|
ren_draft.color_(@rgba );
|
|
render_scanlines(ras ,@m_sl ,ren_draft );
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{ DRAW_LINES_DRAFT }
|
|
procedure the_application.draw_lines_draft;
|
|
var
|
|
pixf : pixel_formats;
|
|
prim : primitives_renderer;
|
|
rgba : aggclr;
|
|
|
|
rb : base_renderer;
|
|
ras : outline_rasterizer;
|
|
|
|
i ,r ,g ,b ,a : int;
|
|
|
|
l : line;
|
|
s : stroke_draft;
|
|
e : edge;
|
|
n1 ,
|
|
n2 : node;
|
|
|
|
begin
|
|
pixfmt_bgr24(pixf ,rbuf_window );
|
|
|
|
rb.Construct (@pixf );
|
|
prim.Construct(@rb );
|
|
ras.Construct (@prim );
|
|
|
|
i:=0;
|
|
|
|
while i < m_graph.get_num_edges do
|
|
begin
|
|
e :=m_graph.get_edge(i );
|
|
n1:=m_graph.get_node(e.node1 ,_width ,_height );
|
|
n2:=m_graph.get_node(e.node2 ,_width ,_height );
|
|
|
|
l.Construct(n1.x ,n1.y ,n2.x ,n2.y );
|
|
s.Construct(@l ,m_width._value );
|
|
|
|
r:=Random($7fff ) and $7F;
|
|
g:=Random($7fff ) and $7F;
|
|
b:=Random($7fff ) and $7F;
|
|
a:=255;
|
|
|
|
if m_translucent._status then
|
|
a:=80;
|
|
|
|
rgba.ConstrInt (r ,g ,b ,a );
|
|
prim.line_color_(@rgba );
|
|
ras.add_path (@s );
|
|
|
|
s.Destruct;
|
|
|
|
inc(i );
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{ DRAW_CURVES_DRAFT }
|
|
procedure the_application.draw_curves_draft;
|
|
var
|
|
pixf : pixel_formats;
|
|
prim : primitives_renderer;
|
|
rgba : aggclr;
|
|
|
|
rb : base_renderer;
|
|
ras : outline_rasterizer;
|
|
|
|
i ,r ,g ,b ,a : int;
|
|
|
|
c : curve;
|
|
s : stroke_draft;
|
|
e : edge;
|
|
n1 ,
|
|
n2 : node;
|
|
|
|
begin
|
|
pixfmt_bgr24(pixf ,rbuf_window );
|
|
|
|
rb.Construct (@pixf );
|
|
prim.Construct(@rb );
|
|
ras.Construct (@prim );
|
|
|
|
i:=0;
|
|
|
|
while i < m_graph.get_num_edges do
|
|
begin
|
|
e :=m_graph.get_edge(i );
|
|
n1:=m_graph.get_node(e.node1 ,_width ,_height );
|
|
n2:=m_graph.get_node(e.node2 ,_width ,_height );
|
|
|
|
c.Construct(n1.x ,n1.y ,n2.x ,n2.y );
|
|
s.Construct(@c ,m_width._value );
|
|
|
|
r:=Random($7fff ) and $7F;
|
|
g:=Random($7fff ) and $7F;
|
|
b:=Random($7fff ) and $7F;
|
|
a:=255;
|
|
|
|
if m_translucent._status then
|
|
a:=80;
|
|
|
|
rgba.ConstrInt (r ,g ,b ,a );
|
|
prim.line_color_(@rgba );
|
|
ras.add_path (@s );
|
|
|
|
c.Destruct;
|
|
s.Destruct;
|
|
|
|
inc(i );
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{ DRAW_DASHES_DRAFT }
|
|
procedure the_application.draw_dashes_draft;
|
|
var
|
|
pixf : pixel_formats;
|
|
prim : primitives_renderer;
|
|
rgba : aggclr;
|
|
|
|
rb : base_renderer;
|
|
ras : outline_rasterizer;
|
|
|
|
i ,r ,g ,b ,a : int;
|
|
|
|
c : curve;
|
|
s : dash_stroke_draft;
|
|
e : edge;
|
|
n1 ,
|
|
n2 : node;
|
|
|
|
begin
|
|
pixfmt_bgr24(pixf ,rbuf_window );
|
|
|
|
rb.Construct (@pixf );
|
|
prim.Construct(@rb );
|
|
ras.Construct (@prim );
|
|
|
|
i:=0;
|
|
|
|
while i < m_graph.get_num_edges do
|
|
begin
|
|
e :=m_graph.get_edge(i );
|
|
n1:=m_graph.get_node(e.node1 ,_width ,_height );
|
|
n2:=m_graph.get_node(e.node2 ,_width ,_height );
|
|
|
|
c.Construct(n1.x ,n1.y ,n2.x ,n2.y );
|
|
s.Construct(@c ,6.0 ,3.0 ,m_width._value );
|
|
|
|
r:=Random($7fff ) and $7F;
|
|
g:=Random($7fff ) and $7F;
|
|
b:=Random($7fff ) and $7F;
|
|
a:=255;
|
|
|
|
if m_translucent._status then
|
|
a:=80;
|
|
|
|
rgba.ConstrInt (r ,g ,b ,a );
|
|
prim.line_color_(@rgba );
|
|
ras.add_path (@s );
|
|
|
|
c.Destruct;
|
|
s.Destruct;
|
|
|
|
inc(i );
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{ DRAW_LINES_FINE }
|
|
procedure the_application.draw_lines_fine;
|
|
var
|
|
i : int;
|
|
b : edge;
|
|
l : line;
|
|
s : stroke_fine;
|
|
|
|
n1 ,n2 : node;
|
|
|
|
begin
|
|
i:=0;
|
|
|
|
while i < m_graph.get_num_edges do
|
|
begin
|
|
b :=m_graph.get_edge(i );
|
|
n1:=m_graph.get_node(b.node1 ,_width ,_height );
|
|
n2:=m_graph.get_node(b.node2 ,_width ,_height );
|
|
|
|
l.Construct(n1.x ,n1.y ,n2.x ,n2.y );
|
|
s.Construct(@l ,m_width._value );
|
|
|
|
render_edge_fine(ras ,solid ,draft ,@s );
|
|
|
|
s.Destruct;
|
|
|
|
inc(i );
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{ DRAW_CURVES_FINE }
|
|
procedure the_application.draw_curves_fine;
|
|
var
|
|
i : int;
|
|
b : edge;
|
|
c : curve;
|
|
s : stroke_fine;
|
|
|
|
n1 ,n2 : node;
|
|
|
|
begin
|
|
i:=0;
|
|
|
|
while i < m_graph.get_num_edges do
|
|
begin
|
|
b :=m_graph.get_edge(i );
|
|
n1:=m_graph.get_node(b.node1 ,_width ,_height );
|
|
n2:=m_graph.get_node(b.node2 ,_width ,_height );
|
|
|
|
c.Construct(n1.x ,n1.y ,n2.x ,n2.y );
|
|
s.Construct(@c ,m_width._value );
|
|
|
|
render_edge_fine(ras ,solid ,draft ,@s );
|
|
|
|
c.Destruct;
|
|
s.Destruct;
|
|
|
|
inc(i );
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{ DRAW_DASHES_FINE }
|
|
procedure the_application.draw_dashes_fine;
|
|
var
|
|
i : int;
|
|
b : edge;
|
|
c : curve;
|
|
s : dash_stroke_fine;
|
|
|
|
n1 ,n2 : node;
|
|
|
|
begin
|
|
i:=0;
|
|
|
|
while i < m_graph.get_num_edges do
|
|
begin
|
|
b :=m_graph.get_edge(i );
|
|
n1:=m_graph.get_node(b.node1 ,_width ,_height );
|
|
n2:=m_graph.get_node(b.node2 ,_width ,_height );
|
|
|
|
c.Construct(n1.x ,n1.y ,n2.x ,n2.y );
|
|
s.Construct(@c ,6.0 ,3.0 ,m_width._value );
|
|
|
|
render_edge_fine(ras ,solid ,draft ,@s );
|
|
|
|
c.Destruct;
|
|
s.Destruct;
|
|
|
|
inc(i );
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{ DRAW_POLYGONS }
|
|
procedure the_application.draw_polygons;
|
|
var
|
|
i : int;
|
|
b : edge;
|
|
c : curve;
|
|
|
|
n1 ,n2 : node;
|
|
|
|
gm_no : gamma_none;
|
|
gm_th : gamma_threshold;
|
|
|
|
begin
|
|
if m_type._cur_item = 4 then
|
|
begin
|
|
gm_th.Construct(0.5 );
|
|
ras.gamma (@gm_th );
|
|
|
|
end;
|
|
|
|
i:=0;
|
|
|
|
while i < m_graph.get_num_edges do
|
|
begin
|
|
b :=m_graph.get_edge(i );
|
|
n1:=m_graph.get_node(b.node1 ,_width ,_height );
|
|
n2:=m_graph.get_node(b.node2 ,_width ,_height );
|
|
|
|
c.Construct(n1.x ,n1.y ,n2.x ,n2.y );
|
|
|
|
render_edge_fine(ras ,solid ,draft ,@c );
|
|
|
|
c.Destruct;
|
|
|
|
inc(i );
|
|
|
|
end;
|
|
|
|
gm_no.Construct;
|
|
ras.gamma(@gm_no );
|
|
|
|
end;
|
|
|
|
{ DRAW_SCENE }
|
|
procedure the_application.draw_scene;
|
|
var
|
|
gm_no : gamma_none;
|
|
|
|
begin
|
|
gm_no.Construct;
|
|
ras.gamma(@gm_no );
|
|
|
|
RandSeed:=100;
|
|
|
|
if m_draw_nodes._status then
|
|
if m_draft._status then
|
|
draw_nodes_draft
|
|
else
|
|
draw_nodes_fine(ras );
|
|
|
|
if m_draw_edges._status then
|
|
if m_draft._status then
|
|
case m_type._cur_item of
|
|
0 : draw_lines_draft;
|
|
1 : draw_curves_draft;
|
|
2 : draw_dashes_draft;
|
|
|
|
end
|
|
else
|
|
case m_type._cur_item of
|
|
0 :
|
|
draw_lines_fine(ras ,solid ,draft );
|
|
|
|
1 :
|
|
draw_curves_fine(ras ,solid ,draft );
|
|
|
|
2 :
|
|
draw_dashes_fine(ras ,solid ,draft );
|
|
|
|
3 ,4 :
|
|
draw_polygons(ras ,solid ,draft );
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{ ON_DRAW }
|
|
procedure the_application.on_draw;
|
|
var
|
|
pixf : pixel_formats;
|
|
rgba : aggclr;
|
|
|
|
ras : scanline_rasterizer;
|
|
rb : base_renderer;
|
|
|
|
solid : solid_renderer;
|
|
draft : draft_renderer;
|
|
|
|
begin
|
|
// Initialize structures
|
|
ras.Construct;
|
|
|
|
pixfmt_bgr24(pixf ,rbuf_window );
|
|
|
|
rb.Construct (@pixf );
|
|
solid.Construct(@rb );
|
|
draft.Construct(@rb );
|
|
|
|
rgba.ConstrDbl(1 ,1 ,1 );
|
|
rb.clear (@rgba );
|
|
|
|
// Render
|
|
draw_scene(@ras ,@solid ,@draft );
|
|
|
|
// Render the controls
|
|
ras.filling_rule(fill_non_zero );
|
|
|
|
render_ctrl(@ras ,@m_sl ,@solid ,@m_type );
|
|
render_ctrl(@ras ,@m_sl ,@solid ,@m_width );
|
|
render_ctrl(@ras ,@m_sl ,@solid ,@m_benchmark );
|
|
render_ctrl(@ras ,@m_sl ,@solid ,@m_draw_nodes );
|
|
render_ctrl(@ras ,@m_sl ,@solid ,@m_draw_edges );
|
|
render_ctrl(@ras ,@m_sl ,@solid ,@m_draft );
|
|
render_ctrl(@ras ,@m_sl ,@solid ,@m_translucent );
|
|
|
|
// Free AGG resources
|
|
ras.Destruct;
|
|
|
|
end;
|
|
|
|
{ ON_CTRL_CHANGE }
|
|
procedure the_application.on_ctrl_change;
|
|
var
|
|
pixf : pixel_formats;
|
|
|
|
i : int;
|
|
fd : text;
|
|
|
|
ras : scanline_rasterizer;
|
|
rb : base_renderer;
|
|
|
|
solid : solid_renderer;
|
|
draft : draft_renderer;
|
|
|
|
buf : array[0..255 ] of char;
|
|
times : array[0..4 ] of double;
|
|
|
|
begin
|
|
if m_benchmark._status then
|
|
begin
|
|
on_draw;
|
|
update_window;
|
|
|
|
ras.Construct;
|
|
|
|
pixfmt_bgr24(pixf ,rbuf_window );
|
|
|
|
rb.Construct (@pixf );
|
|
solid.Construct(@rb );
|
|
draft.Construct(@rb );
|
|
|
|
if m_draft._status then
|
|
begin
|
|
start_timer;
|
|
|
|
for i:=0 to 9 do
|
|
draw_scene(@ras ,@solid ,@draft );
|
|
|
|
sprintf(@buf[0 ] ,'%3.3f milliseconds' ,elapsed_time );
|
|
|
|
end
|
|
else
|
|
begin
|
|
m_draw:=0;
|
|
|
|
while m_draw < 4 do
|
|
begin
|
|
start_timer;
|
|
|
|
for i:=0 to 9 do
|
|
draw_scene(@ras ,@solid ,@draft );
|
|
|
|
times[m_draw ]:=elapsed_time;
|
|
|
|
inc(m_draw );
|
|
|
|
end;
|
|
|
|
m_draw:=3;
|
|
|
|
times[4 ]:=times[3 ];
|
|
times[3 ]:=times[3 ] - times[2 ];
|
|
times[2 ]:=times[2 ] - times[1 ];
|
|
times[1 ]:=times[1 ] - times[0 ];
|
|
|
|
AssignFile(fd ,'benchmark' );
|
|
rewrite (fd );
|
|
|
|
sprintf(@buf[0 ] ,'%10.3f ' ,times[0 ] );
|
|
sprintf(@buf[StrLen(@buf ) ] ,'%10.3f ' ,times[1 ] );
|
|
sprintf(@buf[StrLen(@buf ) ] ,'%10.3f ' ,times[2 ] );
|
|
sprintf(@buf[StrLen(@buf ) ] ,'%10.3f ' ,times[3 ] );
|
|
sprintf(@buf[StrLen(@buf ) ] ,'%10.3f' ,times[4 ] );
|
|
|
|
writeln(fd ,PChar(@buf[0 ] ) );
|
|
close (fd );
|
|
|
|
sprintf(@buf[0 ] ,' pipeline add_path sort render total'#13'%10.3f ' ,times[0 ] );
|
|
sprintf(@buf[StrLen(@buf ) ] ,'%10.3f ' ,times[1 ] );
|
|
sprintf(@buf[StrLen(@buf ) ] ,'%10.3f ' ,times[2 ] );
|
|
sprintf(@buf[StrLen(@buf ) ] ,'%10.3f ' ,times[3 ] );
|
|
sprintf(@buf[StrLen(@buf ) ] ,'%10.3f' ,times[4 ] );
|
|
|
|
end;
|
|
|
|
message_(@buf[0 ] );
|
|
|
|
m_benchmark.status_(false );
|
|
force_redraw;
|
|
|
|
ras.Destruct;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{ ON_KEY }
|
|
procedure the_application.on_key;
|
|
begin
|
|
if key = key_f1 then
|
|
message_(
|
|
'Yet another example of the "general" kind. It was used mostly to compare '#13 +
|
|
'the performance of different steps of rendering in order to see the weaknesses. '#13 +
|
|
'The WIn GDI+ analog of it looks worse and works slower. Try "GDI_graph_test.zip"'#13 +
|
|
'(from www.antigrain.com/demo) and compare it with the AGG one. '#13 +
|
|
'The most disappointing thing in GDI+ is that it cannot draw Bezier curves correctly. '#13#13 +
|
|
'How to play with:'#13#13 +
|
|
'Run the GDI+ example, choose menu Image/Bezier curves, expand the window to '#13 +
|
|
'about 1000x1000 pixels, and then gradually change the size of the window. You will '#13 +
|
|
'see that some curves miss the destination points (the centers of the node circles).' +
|
|
#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(600 + 100 ,500 + 30 ,window_resize ) then
|
|
app.run;
|
|
|
|
app.Destruct;
|
|
|
|
END. |