~ubuntu-branches/ubuntu/saucy/lazarus/saucy

« back to all changes in this revision

Viewing changes to components/aggpas/bezier_div.dpr

  • Committer: Package Import Robot
  • Author(s): Paul Gevers, Abou Al Montacir, Bart Martens, Paul Gevers
  • Date: 2013-06-08 14:12:17 UTC
  • mfrom: (1.1.9)
  • Revision ID: package-import@ubuntu.com-20130608141217-7k0cy9id8ifcnutc
Tags: 1.0.8+dfsg-1
[ Abou Al Montacir ]
* New upstream major release and multiple maintenace release offering many
  fixes and new features marking a new milestone for the Lazarus development
  and its stability level.
  - The detailed list of changes can be found here:
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_release_notes
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_fixes_branch
* LCL changes:
  - LCL is now a normal package.
      + Platform independent parts of the LCL are now in the package LCLBase
      + LCL is automatically recompiled when switching the target platform,
        unless pre-compiled binaries for this target are already installed.
      + No impact on existing projects.
      + Linker options needed by LCL are no more added to projects that do
        not use the LCL package.
  - Minor changes in LCL basic classes behaviour
      + TCustomForm.Create raises an exception if a form resource is not
        found.
      + TNotebook and TPage: a new implementation of these classes was added.
      + TDBNavigator: It is now possible to have focusable buttons by setting
        Options = [navFocusableButtons] and TabStop = True, useful for
        accessibility and for devices with neither mouse nor touch screen.
      + Names of TControlBorderSpacing.GetSideSpace and GetSpace were swapped
        and are now consistent. GetSideSpace = Around + GetSpace.
      + TForm.WindowState=wsFullscreen was added
      + TCanvas.TextFitInfo was added to calculate how many characters will
        fit into a specified Width. Useful for word-wrapping calculations.
      + TControl.GetColorResolvingParent and
        TControl.GetRGBColorResolvingParent were added, simplifying the work
        to obtain the final color of the control while resolving clDefault
        and the ParentColor.
      + LCLIntf.GetTextExtentExPoint now has a good default implementation
        which works in any platform not providing a specific implementation.
        However, Widgetset specific implementation is better, when available.
      + TTabControl was reorganized. Now it has the correct class hierarchy
        and inherits from TCustomTabControl as it should.
  - New unit in the LCL:
      + lazdialogs.pas: adds non-native versions of various native dialogs,
        for example TLazOpenDialog, TLazSaveDialog, TLazSelectDirectoryDialog.
        It is used by widgetsets which either do not have a native dialog, or
        do not wish to use it because it is limited. These dialogs can also be
        used by user applications directly.
      + lazdeviceapis.pas: offers an interface to more hardware devices such
        as the accelerometer, GPS, etc. See LazDeviceAPIs
      + lazcanvas.pas: provides a TFPImageCanvas descendent implementing
        drawing in a LCL-compatible way, but 100% in Pascal.
      + lazregions.pas. LazRegions is a wholly Pascal implementation of
        regions for canvas clipping, event clipping, finding in which control
        of a region tree one an event should reach, for drawing polygons, etc.
      + customdrawncontrols.pas, customdrawndrawers.pas,
        customdrawn_common.pas, customdrawn_android.pas and
        customdrawn_winxp.pas: are the Lazarus Custom Drawn Controls -controls
        which imitate the standard LCL ones, but with the difference that they
        are non-native and support skinning.
  - New APIs added to the LCL to improve support of accessibility software
    such as screen readers.
* IDE changes:
  - Many improvments.
  - The detailed list of changes can be found here:
    http://wiki.lazarus.freepascal.org/New_IDE_features_since#v1.0_.282012-08-29.29
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_release_notes#IDE_Changes
* Debugger / Editor changes:
  - Added pascal sources and breakpoints to the disassembler
  - Added threads dialog.
* Components changes:
  - TAChart: many fixes and new features
  - CodeTool: support Delphi style generics and new syntax extensions.
  - AggPas: removed to honor free licencing. (Closes: Bug#708695)
[Bart Martens]
* New debian/watch file fixing issues with upstream RC release.
[Abou Al Montacir]
* Avoid changing files in .pc hidden directory, these are used by quilt for
  internal purpose and could lead to surprises during build.
[Paul Gevers]
* Updated get-orig-source target and it compinion script orig-tar.sh so that they
  repack the source file, allowing bug 708695 to be fixed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//
2
 
// AggPas 2.4 RM3 Demo application
3
 
// Note: Press F1 key on run to see more info about this demo
4
 
//
5
 
// Paths: src;src\ctrl;src\svg;src\util;src\platform\win;expat-wrap
6
 
//
7
 
program
8
 
 bezier_div ;
9
 
 
10
 
uses
11
 
 Math ,SysUtils ,
12
 
 
13
 
 agg_basics ,
14
 
 agg_platform_support ,
15
 
 
16
 
 agg_color ,
17
 
 agg_pixfmt ,
18
 
 agg_pixfmt_rgb ,
19
 
 
20
 
 agg_ctrl ,
21
 
 agg_slider_ctrl ,
22
 
 agg_rbox_ctrl ,
23
 
 agg_cbox_ctrl ,
24
 
 agg_bezier_ctrl ,
25
 
 
26
 
 agg_renderer_base ,
27
 
 agg_renderer_scanline ,
28
 
 agg_rasterizer_scanline_aa ,
29
 
 agg_scanline ,
30
 
 agg_scanline_u ,
31
 
 agg_render_scanlines ,
32
 
 agg_renderer_outline_aa ,
33
 
 agg_renderer_outline_image ,
34
 
 
35
 
 agg_conv_transform ,
36
 
 agg_conv_stroke ,
37
 
 agg_conv_dash ,
38
 
 agg_pattern_filters_rgba ,
39
 
 agg_arc ,
40
 
 agg_array ,
41
 
 agg_curves ,
42
 
 agg_bezier_arc ,
43
 
 agg_vertex_sequence ,
44
 
 agg_math ,
45
 
 agg_math_stroke ,
46
 
 agg_path_storage ,
47
 
 agg_gsv_text ,
48
 
 agg_ellipse ;
49
 
 
50
 
{$I agg_mode.inc }
51
 
{$I- }
52
 
const
53
 
 flip_y = true;
54
 
 
55
 
type
56
 
 curve_point_ptr = ^curve_point;
57
 
 curve_point = object
58
 
   x ,y ,dist ,mu : double;
59
 
 
60
 
   constructor Construct; overload;
61
 
   constructor Construct(x1 ,y1 ,mu1 : double ); overload;
62
 
 
63
 
  end;
64
 
 
65
 
 the_application = object(platform_support )
66
 
   m_ctrl_color : aggclr;
67
 
 
68
 
   m_curve1 : bezier_ctrl;
69
 
 
70
 
   m_angle_tolerance     ,
71
 
   m_approximation_scale ,
72
 
   m_cusp_limit          ,
73
 
   m_width               : slider_ctrl;
74
 
 
75
 
   m_show_points  ,
76
 
   m_show_outline : cbox_ctrl;
77
 
   m_curve_type   ,
78
 
   m_case_type    ,
79
 
   m_inner_join   ,
80
 
   m_line_join    ,
81
 
   m_line_cap     : rbox_ctrl;
82
 
 
83
 
   m_cur_case_type : int;
84
 
 
85
 
   constructor Construct(format_ : pix_format_e; flip_y_ : boolean );
86
 
   destructor  Destruct;
87
 
 
88
 
   function  measure_time(curve : curve_ptr ) : double;
89
 
   function  find_point  (path : pod_deque_ptr; dist : double; i ,j : unsigned_ptr ) : boolean;
90
 
 
91
 
   function  calc_max_error(curve : curve_ptr; scale : double; max_angle_error : double_ptr ) : double;
92
 
 
93
 
   procedure on_draw; virtual;
94
 
 
95
 
   procedure on_key(x ,y : int; key ,flags : unsigned ); virtual;
96
 
   procedure on_ctrl_change; virtual;
97
 
 
98
 
  end;
99
 
 
100
 
{ BEZIER4_POINT }
101
 
procedure bezier4_point(
102
 
           x1 ,y1 ,x2 ,y2 ,x3 ,y3 ,x4 ,y4 ,mu : double;
103
 
           x ,y : double_ptr );
104
 
var
105
 
 mum1 ,mum13 ,mu3 : double;
106
 
 
107
 
begin
108
 
 mum1 :=1 - mu;
109
 
 mum13:=mum1 * mum1 * mum1;
110
 
 mu3  :=mu * mu * mu;
111
 
 
112
 
 x^:=mum13 * x1 + 3 * mu * mum1 * mum1 * x2 + 3 * mu * mu * mum1 * x3 + mu3 * x4;
113
 
 y^:=mum13 * y1 + 3 * mu * mum1 * mum1 * y2 + 3 * mu * mu * mum1 * y3 + mu3 * y4;
114
 
 
115
 
end;
116
 
 
117
 
{ CONSTRUCT }
118
 
constructor curve_point.Construct;
119
 
begin
120
 
 x   :=0;
121
 
 y   :=0;
122
 
 dist:=0;
123
 
 mu  :=0;
124
 
 
125
 
end;
126
 
 
127
 
{ CONSTRUCT }
128
 
constructor curve_point.Construct(x1 ,y1 ,mu1 : double );
129
 
begin
130
 
 x   :=x1;
131
 
 y   :=y1;
132
 
 dist:=0;
133
 
 mu  :=mu1;
134
 
 
135
 
end;
136
 
 
137
 
{ CONSTRUCT }
138
 
constructor the_application.Construct;
139
 
begin
140
 
 inherited Construct(format_ ,flip_y_ );
141
 
 
142
 
 m_ctrl_color.ConstrDbl(0 ,0.3 ,0.5 ,0.8 );
143
 
 
144
 
 m_angle_tolerance.Construct    (5.0 ,5.0 ,240.0 ,12.0 ,not flip_y_ );
145
 
 m_approximation_scale.Construct(5.0 ,17 + 5.0 , 240.0 ,17 + 12.0 ,not flip_y_ );
146
 
 m_cusp_limit.Construct         (5.0 ,17 + 17 + 5.0 ,240.0 ,17 + 17 + 12.0 ,not flip_y_ );
147
 
 m_width.Construct              (245.0 ,5.0 ,495.0 ,12.0 ,not flip_y_ );
148
 
 m_show_points.Construct        (250.0 ,15 + 5 ,'Show Points' ,not flip_y_ );
149
 
 m_show_outline.Construct       (250.0 ,30 + 5 ,'Show Stroke Outline' ,not flip_y_ );
150
 
 m_curve_type.Construct         (535.0 ,5.0 ,535.0 + 115.0 ,55.0 ,not flip_y_ );
151
 
 m_case_type.Construct          (535.0 ,60.0 ,535.0 + 115.0 ,195.0 ,not flip_y_ );
152
 
 m_inner_join.Construct         (535.0 ,200.0 ,535.0 + 115.0 ,290.0 ,not flip_y_ );
153
 
 m_line_join.Construct          (535.0 ,295.0 ,535.0 + 115.0 ,385.0 ,not flip_y_ );
154
 
 m_line_cap.Construct           (535.0 ,395.0 ,535.0 + 115.0 ,455.0 ,not flip_y_ );
155
 
 
156
 
 m_cur_case_type:=-1;
157
 
 
158
 
 m_curve1.Construct;
159
 
 m_curve1.line_color_(@m_ctrl_color );
160
 
 
161
 
 m_curve1.curve_(170 ,424 ,13 ,87 ,488 ,423 ,26 ,333 );
162
 
 //m_curve1.curve_(26.000 ,333.000 ,276.000 ,126.000 ,402.000 ,479.000 ,26.000 ,333.000 ); // Loop with p1==p4
163
 
 //m_curve1.curve_(378.000 ,439.000 ,378.000 ,497.000 ,487.000 ,432.000 ,14.000 ,338.000 ); // Narrow loop
164
 
 //m_curve1.curve_(288.000 ,283.000 ,232.000 ,89.000 ,66.000 ,197.000 ,456.000 ,241.000 ); // Loop
165
 
 //m_curve1.curve_(519.000 ,142.000 ,97.000 ,147.000 ,69.000 ,147.000 ,30.000 ,144.000 ); // Almost straight
166
 
 //m_curve1.curve_(100 ,100 ,200 ,100 ,100 ,200 ,200 ,200 ); // A "Z" case
167
 
 //m_curve1.curve_(150 ,150 ,350 ,150 ,150 ,150 ,350 ,150 ); // Degenerate
168
 
 //m_curve1.curve_(409 ,330 ,300 ,200 ,200 ,200 ,401 ,263 ); // Strange cusp
169
 
 //m_curve1.curve_(129 ,233 ,172 ,320 ,414 ,253 ,344 ,236 ); // Curve cap
170
 
 //m_curve1.curve_(100 ,100 ,100 ,200 ,100 ,100 ,110 ,100 ); // A "boot"
171
 
 //m_curve1.curve_(225 ,150 ,60 ,150 ,460 ,150 ,295 ,150 ); // 2----1----4----3
172
 
 //m_curve1.curve_(162.2 ,248.801 ,162.2 ,248.801 ,266 ,284 ,394 ,335 );  // Coinciding 1-2
173
 
 //m_curve1.curve_(162.200 ,248.801 ,162.200 ,248.801 ,257.000 ,301.000 ,394.000 ,335.000 ); // Coinciding 1-2
174
 
 //m_curve1.curve_(394.000 ,335.000 ,257.000 ,301.000 ,162.200 ,248.801 ,162.200 ,248.801 ); // Coinciding 3-4
175
 
 //m_curve1.curve_(84.200000 ,302.80100 ,84.200000 ,302.80100 ,79.000000 ,292.40100 ,97.001000 ,304.40100 ); // From tiger.svg
176
 
 //m_curve1.curve_(97.001000 ,304.40100 ,79.000000 ,292.40100 ,84.200000 ,302.80100 ,84.200000 ,302.80100 ); // From tiger.svg opposite dir
177
 
 //m_curve1.curve_(475 ,157 ,200 ,100 ,453 ,100 ,222 ,157 ); // Cusp, failure for Adobe SVG
178
 
 
179
 
 add_ctrl(@m_curve1 );
180
 
 
181
 
 m_curve1.no_transform;
182
 
 
183
 
 m_angle_tolerance.label_('Angle Tolerance=%.0f deg' );
184
 
 m_angle_tolerance.range_(0 ,90 );
185
 
 m_angle_tolerance.value_(15 );
186
 
 
187
 
 add_ctrl(@m_angle_tolerance );
188
 
 
189
 
 m_angle_tolerance.no_transform;
190
 
 
191
 
 m_approximation_scale.label_('Approximation Scale=%.3f' );
192
 
 m_approximation_scale.range_(0.1 ,5 );
193
 
 m_approximation_scale.value_(1.0 );
194
 
 
195
 
 add_ctrl(@m_approximation_scale );
196
 
 
197
 
 m_approximation_scale.no_transform;
198
 
 
199
 
 m_cusp_limit.label_('Cusp Limit=%.0f deg' );
200
 
 m_cusp_limit.range_(0 ,90);
201
 
 m_cusp_limit.value_(0 );
202
 
 
203
 
 add_ctrl(@m_cusp_limit );
204
 
 
205
 
 m_cusp_limit.no_transform;
206
 
 
207
 
 m_width.label_('Width=%.2f' );
208
 
 m_width.range_(0.0 ,100 );
209
 
 m_width.value_(50.0 );
210
 
 
211
 
 add_ctrl(@m_width );
212
 
 
213
 
 m_width.no_transform;
214
 
 
215
 
 add_ctrl(@m_show_points );
216
 
 
217
 
 m_show_points.no_transform;
218
 
 m_show_points.status_(true );
219
 
 
220
 
 add_ctrl(@m_show_outline );
221
 
 
222
 
 m_show_outline.no_transform;
223
 
 m_show_outline.status_(true );
224
 
 
225
 
 m_curve_type.add_item ('Incremental' );
226
 
 m_curve_type.add_item ('Subdiv' );
227
 
 m_curve_type.cur_item_(1 );
228
 
 
229
 
 add_ctrl(@m_curve_type );
230
 
 
231
 
 m_curve_type.no_transform;
232
 
 
233
 
 m_case_type.text_size_     (7 );
234
 
 m_case_type.text_thickness_(1.0 );
235
 
 
236
 
 m_case_type.add_item('Random' );
237
 
 m_case_type.add_item('13---24' );
238
 
 m_case_type.add_item('Smooth Cusp 1' );
239
 
 m_case_type.add_item('Smooth Cusp 2' );
240
 
 m_case_type.add_item('Real Cusp 1' );
241
 
 m_case_type.add_item('Real Cusp 2' );
242
 
 m_case_type.add_item('Fancy Stroke' );
243
 
 m_case_type.add_item('Jaw' );
244
 
 m_case_type.add_item('Ugly Jaw' );
245
 
 
246
 
 add_ctrl(@m_case_type );
247
 
 
248
 
 m_case_type.no_transform;
249
 
 
250
 
 m_inner_join.text_size_(8 );
251
 
 
252
 
 m_inner_join.add_item ('Inner Bevel' );
253
 
 m_inner_join.add_item ('Inner Miter' );
254
 
 m_inner_join.add_item ('Inner Jag' );
255
 
 m_inner_join.add_item ('Inner Round' );
256
 
 m_inner_join.cur_item_(3 );
257
 
 
258
 
 add_ctrl(@m_inner_join );
259
 
 
260
 
 m_inner_join.no_transform;
261
 
 
262
 
 m_line_join.text_size_(8 );
263
 
 
264
 
 m_line_join.add_item ('Miter Join' );
265
 
 m_line_join.add_item ('Miter Revert' );
266
 
 m_line_join.add_item ('Miter Round' );
267
 
 m_line_join.add_item ('Round Join' );
268
 
 m_line_join.add_item ('Bevel Join' );
269
 
 m_line_join.cur_item_(1 );
270
 
 
271
 
 add_ctrl(@m_line_join );
272
 
 
273
 
 m_line_join.no_transform;
274
 
 
275
 
 m_line_cap.text_size_(8 );
276
 
 
277
 
 m_line_cap.add_item ('Butt Cap' );
278
 
 m_line_cap.add_item ('Square Cap' );
279
 
 m_line_cap.add_item ('Round Cap' );
280
 
 m_line_cap.cur_item_(0 );
281
 
 
282
 
 add_ctrl(@m_line_cap );
283
 
 
284
 
 m_line_cap.no_transform;
285
 
 
286
 
end;
287
 
 
288
 
{ DESTRUCT }
289
 
destructor the_application.Destruct;
290
 
begin
291
 
 inherited Destruct;
292
 
 
293
 
 m_angle_tolerance.Destruct;
294
 
 m_approximation_scale.Destruct;
295
 
 m_cusp_limit.Destruct;
296
 
 m_width.Destruct;
297
 
 m_show_points.Destruct;
298
 
 m_show_outline.Destruct;
299
 
 m_curve_type.Destruct;
300
 
 m_case_type.Destruct;
301
 
 m_inner_join.Destruct;
302
 
 m_line_join.Destruct;
303
 
 m_line_cap.Destruct;
304
 
 m_curve1.Destruct;
305
 
 
306
 
end;
307
 
 
308
 
{ MEASURE_TIME }
309
 
function the_application.measure_time;
310
 
var
311
 
 i : int;
312
 
 
313
 
 x ,y : double;
314
 
 
315
 
begin
316
 
 start_timer;
317
 
 
318
 
 for i:=0 to 99 do
319
 
  begin
320
 
   curve.init4(
321
 
    m_curve1._x1 ,m_curve1._y1 ,
322
 
    m_curve1._x2 ,m_curve1._y2 ,
323
 
    m_curve1._x3 ,m_curve1._y3 ,
324
 
    m_curve1._x4 ,m_curve1._y4 );
325
 
 
326
 
   curve.rewind(0 );
327
 
 
328
 
   while not is_stop(curve.vertex(@x ,@y ) ) do;
329
 
 
330
 
  end;
331
 
 
332
 
 result:=elapsed_time * 10;
333
 
 
334
 
end;
335
 
 
336
 
{ FIND_POINT }
337
 
function the_application.find_point;
338
 
var
339
 
 k : int;
340
 
 
341
 
begin
342
 
 j^:=path.size - 1;
343
 
 i^:=0;
344
 
 
345
 
 while j^ - i^ > 1 do
346
 
  begin
347
 
   k:=shr_int32(i^ + j^ ,1 );
348
 
 
349
 
   if dist < vertex_dist_ptr(path.array_operator(k ) ).dist then
350
 
    j^:=k
351
 
   else
352
 
    i^:=k;
353
 
 
354
 
  end;
355
 
 
356
 
 result:=true;
357
 
 
358
 
end;
359
 
 
360
 
{ CALC_MAX_ERROR }
361
 
function the_application.calc_max_error;
362
 
var
363
 
 cmd ,i ,idx1 ,idx2 : unsigned;
364
 
 
365
 
 x ,y ,curve_dist ,mu ,reference_dist ,max_error ,err ,aerr ,a1 ,a2 ,da : double;
366
 
 
367
 
 curve_points ,reference_points : pod_deque;
368
 
 
369
 
 vd : vertex_dist;
370
 
 cp : curve_point;
371
 
 
372
 
begin
373
 
 curve_points.Construct    (sizeof(vertex_dist ) ,8 );
374
 
 reference_points.Construct(sizeof(curve_point ) ,8 );
375
 
 
376
 
 curve.approximation_scale_(m_approximation_scale._value * scale );
377
 
 
378
 
 curve.init4(
379
 
  m_curve1._x1 ,m_curve1._y1 ,
380
 
  m_curve1._x2 ,m_curve1._y2 ,
381
 
  m_curve1._x3 ,m_curve1._y3 ,
382
 
  m_curve1._x4 ,m_curve1._y4 );
383
 
 
384
 
 curve.rewind(0 );
385
 
 
386
 
 vd.dist:=0;
387
 
 
388
 
 cmd:=curve.vertex(@x ,@y );
389
 
 
390
 
 while not is_stop(cmd ) do
391
 
  begin
392
 
   if is_vertex(cmd ) then
393
 
    begin
394
 
     vd.x:=x;
395
 
     vd.y:=y;
396
 
 
397
 
     curve_points.add(@vd );
398
 
 
399
 
    end;
400
 
 
401
 
   cmd:=curve.vertex(@x ,@y );
402
 
 
403
 
  end;
404
 
 
405
 
 curve_dist:=0;
406
 
 
407
 
 i:=1;
408
 
 
409
 
 while i < curve_points.size do
410
 
  begin
411
 
   vertex_dist_ptr(curve_points.array_operator(i - 1 ) ).dist:=curve_dist;
412
 
 
413
 
   curve_dist:=
414
 
    curve_dist +
415
 
    calc_distance(
416
 
     vertex_dist_ptr(curve_points.array_operator(i - 1 ) ).x ,
417
 
     vertex_dist_ptr(curve_points.array_operator(i - 1 ) ).y ,
418
 
     vertex_dist_ptr(curve_points.array_operator(i ) ).x ,
419
 
     vertex_dist_ptr(curve_points.array_operator(i ) ).y );
420
 
 
421
 
   inc(i );
422
 
 
423
 
  end;
424
 
 
425
 
 vertex_dist_ptr(curve_points.array_operator(curve_points.size - 1 ) ).dist:=curve_dist;
426
 
 
427
 
 for i:=0 to 4095 do
428
 
  begin
429
 
   mu:=i / 4095.0;
430
 
 
431
 
   bezier4_point(
432
 
    m_curve1._x1 , m_curve1._y1 ,
433
 
    m_curve1._x2 , m_curve1._y2 ,
434
 
    m_curve1._x3 , m_curve1._y3 ,
435
 
    m_curve1._x4 , m_curve1._y4 ,
436
 
    mu ,@x ,@y );
437
 
 
438
 
   cp.Construct(x ,y ,mu );
439
 
 
440
 
   reference_points.add(@cp );
441
 
 
442
 
  end;
443
 
 
444
 
 reference_dist:=0;
445
 
 
446
 
 i:=1;
447
 
 
448
 
 while i < reference_points.size do
449
 
  begin
450
 
   curve_point_ptr(reference_points.array_operator(i - 1 ) ).dist:=reference_dist;
451
 
 
452
 
   reference_dist:=
453
 
    reference_dist +
454
 
    calc_distance(
455
 
     curve_point_ptr(reference_points.array_operator(i - 1 ) ).x ,
456
 
     curve_point_ptr(reference_points.array_operator(i - 1 ) ).y ,
457
 
     curve_point_ptr(reference_points.array_operator(i ) ).x ,
458
 
     curve_point_ptr(reference_points.array_operator(i ) ).y );
459
 
 
460
 
   inc(i );
461
 
 
462
 
  end;
463
 
 
464
 
 curve_point_ptr(reference_points.array_operator(reference_points.size - 1 ) ).dist:=reference_dist;
465
 
 
466
 
 idx1:=0;
467
 
 idx2:=1;
468
 
 
469
 
 max_error:=0;
470
 
 
471
 
 i:=0;
472
 
 
473
 
 while i < reference_points.size do
474
 
  begin
475
 
   if find_point(
476
 
       @curve_points ,
477
 
       curve_point_ptr(reference_points.array_operator(i ) ).dist ,
478
 
       @idx1 ,@idx2 ) then
479
 
    begin
480
 
     err:=
481
 
      Abs(
482
 
       calc_line_point_distance(
483
 
        vertex_dist_ptr(curve_points.array_operator(idx1 ) ).x ,
484
 
        vertex_dist_ptr(curve_points.array_operator(idx1 ) ).y ,
485
 
        vertex_dist_ptr(curve_points.array_operator(idx2 ) ).x ,
486
 
        vertex_dist_ptr(curve_points.array_operator(idx2 ) ).y ,
487
 
        curve_point_ptr(reference_points.array_operator(i ) ).x ,
488
 
        curve_point_ptr(reference_points.array_operator(i ) ).y ) );
489
 
 
490
 
     if err > max_error then
491
 
      max_error:=err;
492
 
 
493
 
    end;
494
 
 
495
 
   inc(i );
496
 
 
497
 
  end;
498
 
 
499
 
 aerr:=0;
500
 
 
501
 
 i:=2;
502
 
 
503
 
 while i < curve_points.size do
504
 
  begin
505
 
   a1:=
506
 
    ArcTan2(
507
 
     vertex_dist_ptr(curve_points.array_operator(i - 1 ) ).y -
508
 
     vertex_dist_ptr(curve_points.array_operator(i - 2 ) ).y ,
509
 
     vertex_dist_ptr(curve_points.array_operator(i - 1 ) ).x -
510
 
     vertex_dist_ptr(curve_points.array_operator(i - 2 ) ).x );
511
 
 
512
 
   a2:=
513
 
    ArcTan2(
514
 
     vertex_dist_ptr(curve_points.array_operator(i ) ).y -
515
 
     vertex_dist_ptr(curve_points.array_operator(i - 1 ) ).y ,
516
 
     vertex_dist_ptr(curve_points.array_operator(i ) ).x -
517
 
     vertex_dist_ptr(curve_points.array_operator(i - 1 ) ).x );
518
 
 
519
 
   da:=Abs(a1 - a2 );
520
 
 
521
 
   if da >= pi then
522
 
    da:=2 * pi - da;
523
 
 
524
 
   if da > aerr then
525
 
    aerr:=da;
526
 
 
527
 
   inc(i );
528
 
 
529
 
  end;
530
 
 
531
 
 max_angle_error^:=aerr * 180.0 / pi;
532
 
 
533
 
 result:=max_error * scale;
534
 
 
535
 
 curve_points.Destruct;
536
 
 reference_points.Destruct;
537
 
 
538
 
end;
539
 
 
540
 
{ ON_DRAW }
541
 
procedure the_application.on_draw;
542
 
var
543
 
 ren_base : renderer_base;
544
 
 rgba     : aggclr;
545
 
 
546
 
 pf  : pixel_formats;
547
 
 ren : renderer_scanline_aa_solid;
548
 
 ras : rasterizer_scanline_aa;
549
 
 sl  : scanline_u8;
550
 
 
551
 
 path    : path_storage;
552
 
 curve   : curve4;
553
 
 stroke  ,
554
 
 stroke2 : conv_stroke;
555
 
 
556
 
 ell : ellipse;
557
 
 buf : array[0..511 ] of char;
558
 
 
559
 
 t  : gsv_text;
560
 
 pt : conv_stroke;
561
 
 
562
 
 cmd ,num_points1 : unsigned;
563
 
 
564
 
 x ,y ,curve_time ,
565
 
 
566
 
 max_angle_error_01  ,
567
 
 max_angle_error_1   ,
568
 
 max_angle_error1    ,
569
 
 max_angle_error_10  ,
570
 
 max_angle_error_100 ,
571
 
 
572
 
 max_error_01  ,
573
 
 max_error_1   ,
574
 
 max_error1    ,
575
 
 max_error_10  ,
576
 
 max_error_100 : double;
577
 
 
578
 
 a : ellipse;
579
 
 
580
 
begin
581
 
// Initialize structures
582
 
 pixfmt_bgr24(pf ,rbuf_window );
583
 
 
584
 
 ren_base.Construct(@pf );
585
 
 rgba.ConstrDbl    (1.0 ,1.0 ,0.95 );
586
 
 ren_base.clear    (@rgba );
587
 
 
588
 
 ren.Construct(@ren_base );
589
 
 
590
 
 ras.Construct;
591
 
 sl.Construct;
592
 
 
593
 
// Render Curve
594
 
 path.Construct;
595
 
 
596
 
 curve_time:=0;
597
 
 
598
 
 path.remove_all;
599
 
 curve.Construct;
600
 
 
601
 
 curve.approximation_method_(curve_approximation_method_e(m_curve_type._cur_item ) );
602
 
 curve.approximation_scale_ (m_approximation_scale._value );
603
 
 
604
 
 curve.angle_tolerance_(deg2rad(m_angle_tolerance._value ) );
605
 
 curve.cusp_limit_     (deg2rad(m_cusp_limit._value ) );
606
 
 
607
 
 curve_time:=measure_time(@curve );
608
 
 
609
 
 max_angle_error_01 :=0;
610
 
 max_angle_error_1  :=0;
611
 
 max_angle_error1   :=0;
612
 
 max_angle_error_10 :=0;
613
 
 max_angle_error_100:=0;
614
 
 max_error_01       :=0;
615
 
 max_error_1        :=0;
616
 
 max_error1         :=0;
617
 
 max_error_10       :=0;
618
 
 max_error_100      :=0;
619
 
 
620
 
 max_error_01 :=calc_max_error(@curve ,0.01 ,@max_angle_error_01 );
621
 
 max_error_1  :=calc_max_error(@curve ,0.1  ,@max_angle_error_1 );
622
 
 max_error1   :=calc_max_error(@curve ,1    ,@max_angle_error1 );
623
 
 max_error_10 :=calc_max_error(@curve ,10   ,@max_angle_error_10 );
624
 
 max_error_100:=calc_max_error(@curve ,100  ,@max_angle_error_100 );
625
 
 
626
 
 curve.approximation_scale_(m_approximation_scale._value );
627
 
 curve.angle_tolerance_    (deg2rad(m_angle_tolerance._value ) );
628
 
 curve.cusp_limit_         (deg2rad(m_cusp_limit._value ) );
629
 
 
630
 
 curve.init4(
631
 
  m_curve1._x1 ,m_curve1._y1 ,
632
 
  m_curve1._x2 ,m_curve1._y2 ,
633
 
  m_curve1._x3 ,m_curve1._y3 ,
634
 
  m_curve1._x4 ,m_curve1._y4 );
635
 
 
636
 
 path.add_path(@curve ,0 ,false );
637
 
 
638
 
 stroke.Construct(@path );
639
 
 stroke.width_   (m_width._value );
640
 
 
641
 
 stroke.line_join_        (m_line_join._cur_item );
642
 
 stroke.line_cap_         (m_line_cap._cur_item );
643
 
 stroke.inner_join_       (m_inner_join._cur_item );
644
 
 stroke.inner_miter_limit_(1.01 );
645
 
 
646
 
 ras.add_path    (@stroke );
647
 
 rgba.ConstrDbl  (0 ,0.5 ,0 ,0.5 );
648
 
 ren.color_      (@rgba );
649
 
 render_scanlines(@ras ,@sl ,@ren );
650
 
 
651
 
// Render internal points
652
 
 num_points1:=0;
653
 
 
654
 
 path.rewind(0 );
655
 
 
656
 
 cmd:=path.vertex(@x ,@y );
657
 
 
658
 
 while not is_stop(cmd ) do
659
 
  begin
660
 
   if m_show_points._status then
661
 
    begin
662
 
     ell.Construct(x ,y ,1.5 ,1.5 ,8 );
663
 
 
664
 
     ras.add_path    (@ell );
665
 
     rgba.ConstrDbl  (0 ,0 ,0 ,0.5 );
666
 
     ren.color_      (@rgba );
667
 
     render_scanlines(@ras ,@sl ,@ren );
668
 
 
669
 
    end;
670
 
 
671
 
   inc(num_points1 );
672
 
 
673
 
   cmd:=path.vertex(@x ,@y );
674
 
 
675
 
  end;
676
 
 
677
 
// Render outline
678
 
 if m_show_outline._status then
679
 
  begin
680
 
  // Draw a stroke of the stroke to see the internals
681
 
   stroke2.Construct(@stroke );
682
 
   ras.add_path     (@stroke2 );
683
 
   rgba.ConstrDbl   (0 ,0 ,0 ,0.5 );
684
 
   ren.color_       (@rgba);
685
 
   render_scanlines (@ras ,@sl ,@ren );
686
 
 
687
 
  end;
688
 
 
689
 
// Check ellipse and arc for the number of points
690
 
 {a.Construct     (100 ,100 ,m_width.value ,m_width.value ,0 );
691
 
 ras.add_path    (@a );
692
 
 rgba.ConstrDbl  (0.5 ,0 ,0 ,0.5 );
693
 
 ren.color       (@rgba );
694
 
 render_scanlines(@ras ,@sl ,@ren );
695
 
 
696
 
 a.rewind(0 );
697
 
 
698
 
 cmd:=a.vertex(@x ,@ y);
699
 
 
700
 
 while not is_stop(cmd ) do
701
 
  begin
702
 
   if is_vertex(cmd ) then
703
 
    begin
704
 
     ell.Construct   (x ,y ,1.5 ,1.5 ,8 );
705
 
     ras.add_path    (@ell );
706
 
     rgba.ConstrDbl  (0 ,0 ,0 ,0.5 );
707
 
     ren.color       (@rgba );
708
 
     render_scanlines(@ras ,@sl ,@ren );
709
 
 
710
 
    end;
711
 
 
712
 
   cmd:=a.vertex(@x ,@y );
713
 
 
714
 
  end;{}
715
 
 
716
 
// Render text
717
 
 t.Construct;
718
 
 t.size_(8.0 );
719
 
 
720
 
 pt.Construct (@t );
721
 
 pt.line_cap_ (round_cap );
722
 
 pt.line_join_(round_join );
723
 
 pt.width_    (1.5 );
724
 
 
725
 
 sprintf(@buf[0 ]             ,'Num Points=%d ' ,num_points1 );
726
 
 sprintf(@buf[StrLen(@buf ) ] ,'Time=%.2fmks'#13#13 ,curve_time );
727
 
 sprintf(@buf[StrLen(@buf ) ] ,' Dist Error: x0.01=%.5f ' ,max_error_01 );
728
 
 sprintf(@buf[StrLen(@buf ) ] ,'x0.1=%.5f ' ,max_error_1 );
729
 
 sprintf(@buf[StrLen(@buf ) ] ,'x1=%.5f ' ,max_error1 );
730
 
 sprintf(@buf[StrLen(@buf ) ] ,'x10=%.5f ' ,max_error_10 );
731
 
 sprintf(@buf[StrLen(@buf ) ] ,'x100=%.5f'#13#13 ,max_error_100 );
732
 
 sprintf(@buf[StrLen(@buf ) ] ,'Angle Error: x0.01=%.1f ' ,max_angle_error_01 );
733
 
 sprintf(@buf[StrLen(@buf ) ] ,'x0.1=%.1f ' ,max_angle_error_1 );
734
 
 sprintf(@buf[StrLen(@buf ) ] ,'x1=%.1f ' ,max_angle_error1 );
735
 
 sprintf(@buf[StrLen(@buf ) ] ,'x10=%.1f ' ,max_angle_error_10 );
736
 
 sprintf(@buf[StrLen(@buf ) ] ,'x100=%.1f' ,max_angle_error_100 );
737
 
 
738
 
 t.start_point_(10.0 ,85.0 );
739
 
 t.text_       (@buf[0 ] );
740
 
 
741
 
 ras.add_path    (@pt );
742
 
 rgba.ConstrDbl  (0 ,0 ,0 );
743
 
 ren.color_      (@rgba );
744
 
 render_scanlines(@ras ,@sl ,@ren );
745
 
 
746
 
// Render the controls
747
 
 render_ctrl(@ras ,@sl ,@ren ,@m_curve1 );
748
 
 render_ctrl(@ras ,@sl ,@ren ,@m_angle_tolerance );
749
 
 render_ctrl(@ras ,@sl ,@ren ,@m_approximation_scale );
750
 
 render_ctrl(@ras ,@sl ,@ren ,@m_cusp_limit );
751
 
 render_ctrl(@ras ,@sl ,@ren ,@m_width );
752
 
 render_ctrl(@ras ,@sl ,@ren ,@m_show_points );
753
 
 render_ctrl(@ras ,@sl ,@ren ,@m_show_outline );
754
 
 render_ctrl(@ras ,@sl ,@ren ,@m_curve_type );
755
 
 render_ctrl(@ras ,@sl ,@ren ,@m_case_type );
756
 
 render_ctrl(@ras ,@sl ,@ren ,@m_inner_join );
757
 
 render_ctrl(@ras ,@sl ,@ren ,@m_line_join );
758
 
 render_ctrl(@ras ,@sl ,@ren ,@m_line_cap );
759
 
 
760
 
// Free AGG resources
761
 
 ras.Destruct;
762
 
 sl.Destruct;
763
 
 
764
 
 path.Destruct;
765
 
 curve.Destruct;
766
 
 stroke.Destruct;
767
 
 stroke2.Destruct;
768
 
 
769
 
 t.Destruct;
770
 
 pt.Destruct;
771
 
 
772
 
end;
773
 
 
774
 
{ ON_KEY }
775
 
procedure the_application.on_key;
776
 
var
777
 
 fd  : text;
778
 
 buf : array[0..255 ] of char;
779
 
 
780
 
begin
781
 
 if key = byte(' ' ) then
782
 
  begin
783
 
   AssignFile(fd ,'coord' );
784
 
   rewrite   (fd );
785
 
 
786
 
   sprintf(@buf[0 ]             ,'%.3f, ' ,m_curve1._x1 );
787
 
   sprintf(@buf[StrLen(@buf ) ] ,'%.3f, ' ,m_curve1._y1 );
788
 
   sprintf(@buf[StrLen(@buf ) ] ,'%.3f, ' ,m_curve1._x2 );
789
 
   sprintf(@buf[StrLen(@buf ) ] ,'%.3f, ' ,m_curve1._y2 );
790
 
   sprintf(@buf[StrLen(@buf ) ] ,'%.3f, ' ,m_curve1._x3 );
791
 
   sprintf(@buf[StrLen(@buf ) ] ,'%.3f, ' ,m_curve1._y3 );
792
 
   sprintf(@buf[StrLen(@buf ) ] ,'%.3f, ' ,m_curve1._x4 );
793
 
   sprintf(@buf[StrLen(@buf ) ] ,'%.3f'   ,m_curve1._y4 );
794
 
 
795
 
   write(fd ,PChar(@buf[0 ] ) );
796
 
   close(fd );
797
 
 
798
 
  end;
799
 
 
800
 
 if key = key_f1 then
801
 
  message_(
802
 
   'Demonstration of new methods of Bezier curve approximation. You can compare '#13 +
803
 
   'the old, incremental method with adaptive De Casteljau''s subdivion. The new '#13 +
804
 
   'method uses two criteria to stop subdivision: estimation of distance and estimation  '#13 +
805
 
   'of angle. It gives us perfectly smooth result even for very sharp turns and loops.  '#13#13 +
806
 
   'How to play with:'#13#13 +
807
 
   'Use the mouse to change the shape of the curve.'#13 +
808
 
   'Press the spacebar to dump the curve''s coordinates into the "coord" file.' +
809
 
   #13#13'Note: F2 key saves current "screenshot" file in this demo''s directory.  ' );
810
 
 
811
 
end;
812
 
 
813
 
{ ON_CTRL_CHANGE }
814
 
procedure the_application.on_ctrl_change;
815
 
var
816
 
 w ,h : int;
817
 
 
818
 
begin
819
 
 if m_case_type._cur_item <> m_cur_case_type then
820
 
  begin
821
 
   case m_case_type._cur_item of
822
 
    0 : //m_case_type.add_item("Random");
823
 
     begin
824
 
      w:=trunc(_width - 120 );
825
 
      h:=trunc(_height - 80 );
826
 
 
827
 
      m_curve1.curve_(
828
 
       Random($7fff ) mod w ,Random($7fff ) mod h + 80 ,
829
 
       Random($7fff ) mod w ,Random($7fff ) mod h + 80 ,
830
 
       Random($7fff ) mod w ,Random($7fff ) mod h + 80 ,
831
 
       Random($7fff ) mod w ,Random($7fff ) mod h + 80 );
832
 
 
833
 
     end;
834
 
 
835
 
    1 : //m_case_type.add_item("13---24");
836
 
     m_curve1.curve_(150 ,150 ,350 ,150 ,150 ,150 ,350 ,150 );
837
 
 
838
 
    2 : //m_case_type.add_item("Smooth Cusp 1");
839
 
     m_curve1.curve_(50 ,142 ,483 ,251 ,496 ,62 ,26 ,333 );
840
 
 
841
 
    3 : //m_case_type.add_item("Smooth Cusp 2");
842
 
     m_curve1.curve_(50 ,142 ,484 ,251 ,496 ,62 ,26 ,333 );
843
 
 
844
 
    4 : //m_case_type.add_item("Real Cusp 1");
845
 
     m_curve1.curve_(100 ,100 ,300 ,200 ,200 ,200 ,200 ,100 );
846
 
 
847
 
    5 : //m_case_type.add_item("Real Cusp 2");
848
 
     m_curve1.curve_(475 ,157 ,200 ,100 ,453 ,100 ,222 ,157 );
849
 
 
850
 
    6 : //m_case_type.add_item("Fancy Stroke");
851
 
     begin
852
 
      m_curve1.curve_(129 ,233 ,32 ,283 ,258 ,285 ,159 ,232 );
853
 
      m_width.value_ (100 );
854
 
 
855
 
     end;
856
 
 
857
 
    7 : //m_case_type.add_item("Jaw");
858
 
     m_curve1.curve_(100 ,100 ,300 ,200 ,264 ,286 ,264 ,284 );
859
 
 
860
 
    8 : //m_case_type.add_item("Ugly Jaw");
861
 
     m_curve1.curve_(100 ,100 ,413 ,304 ,264 ,286 ,264 ,284 );
862
 
 
863
 
   end;
864
 
 
865
 
  force_redraw;
866
 
 
867
 
  m_cur_case_type:=m_case_type._cur_item;
868
 
 
869
 
 end;
870
 
 
871
 
end;
872
 
 
873
 
VAR
874
 
 app : the_application;
875
 
 
876
 
BEGIN
877
 
 app.Construct(pix_format_bgr24 ,flip_y );
878
 
 app.caption_ ('AGG Example (F1-Help)' );
879
 
 
880
 
 if app.init(655 ,520 ,window_resize ) then
881
 
  app.run;
882
 
 
883
 
 app.Destruct;
884
 
 
885
 
END.
 
 
b'\\ No newline at end of file'