1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4 (Public License)
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4 //
5 // Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
6 // Pascal Port By: Milan Marusinec alias Milano
7 //                 milan@marusinec.sk
8 //                 http://www.aggpas.org
9 // Copyright (c) 2005-2006
10 //
11 // Permission to copy, use, modify, sell and distribute this software
12 // is granted provided this copyright notice appears in all copies.
13 // This software is provided "as is" without express or implied
14 // warranty, and with no claim as to its suitability for any purpose.
15 //
16 //----------------------------------------------------------------------------
17 // Contact: mcseem@antigrain.com
18 //          mcseemagg@yahoo.com
19 //          http://www.antigrain.com
20 //
21 //----------------------------------------------------------------------------
22 //
23 // classes bezier_ctrl_impl, bezier_ctrl
24 //
25 // [Pascal Port History] -----------------------------------------------------
26 //
27 // 23.02.2006-Milano: Unit port establishment
28 //
29 { agg_bezier_ctrl.pas }
30 unit
31  agg_bezier_ctrl ;
32 
33 INTERFACE
34 
35 {$I agg_mode.inc }
36 
37 uses
38  agg_basics ,
39  agg_ctrl ,
40  agg_math ,
41  agg_ellipse ,
42  agg_trans_affine ,
43  agg_color ,
44  agg_curves ,
45  agg_conv_stroke ,
46  agg_conv_curve ,
47  agg_polygon_ctrl ;
48 
49 { TYPES DEFINITION }
50 type
51  bezier_ctrl_impl = object(ctrl )
52    m_curve   : curve4;
53    m_ellipse : ellipse;
54    m_stroke  : conv_stroke;
55    m_poly    : polygon_ctrl_impl;
56    m_idx     : unsigned;
57 
58    constructor Construct;
59    destructor  Destruct; virtual;
60 
61    procedure curve_(x1 ,y1 ,x2 ,y2 ,x3 ,y3 ,x4 ,y4 : double );
_curvenull62    function  _curve : curve4_ptr;
63 
_x1null64    function  _x1 : double;
_y1null65    function  _y1 : double;
_x2null66    function  _x2 : double;
_y2null67    function  _y2 : double;
_x3null68    function  _x3 : double;
_y3null69    function  _y3 : double;
_x4null70    function  _x4 : double;
_y4null71    function  _y4 : double;
72 
73    procedure x1_(x : double );
74    procedure y1_(y : double );
75    procedure x2_(x : double );
76    procedure y2_(y : double );
77    procedure x3_(x : double );
78    procedure y3_(y : double );
79    procedure x4_(x : double );
80    procedure y4_(y : double );
81 
82    procedure line_width_(w : double );
_line_widthnull83    function  _line_width : double;
84 
85    procedure point_radius_(r : double );
_point_radiusnull86    function  _point_radius : double;
87 
88   // Event handlers
in_rectnull89    function  in_rect(x ,y : double ) : boolean; virtual;
90 
on_mouse_button_downnull91    function  on_mouse_button_down(x ,y : double ) : boolean; virtual;
on_mouse_button_upnull92    function  on_mouse_button_up  (x ,y : double ) : boolean; virtual;
93 
on_mouse_movenull94    function  on_mouse_move(x ,y : double; button_flag : boolean ) : boolean; virtual;
on_arrow_keysnull95    function  on_arrow_keys(left ,right ,down ,up : boolean ) : boolean; virtual;
96 
97   // Vertex source interface
num_pathsnull98    function  num_paths : unsigned; virtual;
99    procedure rewind(path_id : unsigned ); virtual;
vertexnull100    function  vertex(x ,y : double_ptr ) : unsigned; virtual;
101 
102   end;
103 
104  bezier_ctrl = object(bezier_ctrl_impl )
105    m_color : aggclr;
106 
107    constructor Construct;
108 
109    procedure line_color_(c : aggclr_ptr );
110 
_colornull111    function  _color(i : unsigned ) : aggclr_ptr; virtual;
112 
113   end;
114 
115  curve3_ctrl_impl = object(ctrl )
116    m_curve   : curve3;
117    m_ellipse : ellipse;
118    m_stroke  : conv_stroke;
119    m_poly    : polygon_ctrl_impl;
120    m_idx     : unsigned;
121 
122    constructor Construct;
123    destructor  Destruct; virtual;
124 
125    procedure curve_(x1 ,y1 ,x2 ,y2 ,x3 ,y3 : double );
_curvenull126    function  _curve : curve3_ptr;
127 
_x1null128    function  _x1 : double;
_y1null129    function  _y1 : double;
_x2null130    function  _x2 : double;
_y2null131    function  _y2 : double;
_x3null132    function  _x3 : double;
_y3null133    function  _y3 : double;
134 
135    procedure x1_(x : double );
136    procedure y1_(y : double );
137    procedure x2_(x : double );
138    procedure y2_(y : double );
139    procedure x3_(x : double );
140    procedure y3_(y : double );
141 
142    procedure line_width_(w : double );
_line_widthnull143    function  _line_width : double;
144 
145    procedure point_radius_(r : double );
_point_radiusnull146    function  _point_radius : double;
147 
148   // Event handlers
in_rectnull149    function  in_rect(x ,y : double ) : boolean; virtual;
150 
on_mouse_button_downnull151    function  on_mouse_button_down(x ,y : double ) : boolean; virtual;
on_mouse_button_upnull152    function  on_mouse_button_up  (x ,y : double ) : boolean; virtual;
153 
on_mouse_movenull154    function  on_mouse_move(x ,y : double; button_flag : boolean ) : boolean; virtual;
on_arrow_keysnull155    function  on_arrow_keys(left ,right ,down ,up : boolean ) : boolean; virtual;
156 
157   // Vertex source interface
num_pathsnull158    function  num_paths : unsigned; virtual;
159    procedure rewind(path_id : unsigned ); virtual;
vertexnull160    function  vertex(x ,y : double_ptr ) : unsigned; virtual;
161 
162   end;
163 
164  curve3_ctrl = object(curve3_ctrl_impl )
165    m_color : aggclr;
166 
167    constructor Construct;
168 
169    procedure line_color_(c : aggclr_ptr );
170 
_colornull171    function  _color(i : unsigned ) : aggclr_ptr; virtual;
172 
173   end;
174 
175 { GLOBAL PROCEDURES }
176 
177 
178 IMPLEMENTATION
179 { LOCAL VARIABLES & CONSTANTS }
180 { UNIT IMPLEMENTATION }
181 { CONSTRUCT }
182 constructor bezier_ctrl_impl.Construct;
183 begin
184  inherited Construct(0 ,0 ,1 ,1 ,false );
185 
186  m_curve.Construct;
187  m_ellipse.Construct;
188  m_stroke.Construct(@m_curve );
189  m_poly.Construct  (4 ,5.0 );
190 
191  m_idx:=0;
192 
193  m_poly.in_polygon_check_(false );
194 
195  m_poly.xn_ptr(0 )^:=100.0;
196  m_poly.yn_ptr(0 )^:=  0.0;
197  m_poly.xn_ptr(1 )^:=100.0;
198  m_poly.yn_ptr(1 )^:= 50.0;
199  m_poly.xn_ptr(2 )^:= 50.0;
200  m_poly.yn_ptr(2 )^:=100.0;
201  m_poly.xn_ptr(3 )^:=  0.0;
202  m_poly.yn_ptr(3 )^:=100.0;
203 
204 end;
205 
206 { DESTRUCT }
207 destructor bezier_ctrl_impl.Destruct;
208 begin
209  m_curve.Destruct;
210  m_stroke.Destruct;
211  m_poly.Destruct;
212 
213 end;
214 
215 { CURVE_ }
216 procedure bezier_ctrl_impl.curve_;
217 begin
218  m_poly.xn_ptr(0 )^:=x1;
219  m_poly.yn_ptr(0 )^:=y1;
220  m_poly.xn_ptr(1 )^:=x2;
221  m_poly.yn_ptr(1 )^:=y2;
222  m_poly.xn_ptr(2 )^:=x3;
223  m_poly.yn_ptr(2 )^:=y3;
224  m_poly.xn_ptr(3 )^:=x4;
225  m_poly.yn_ptr(3 )^:=y4;
226 
227  _curve;
228 
229 end;
230 
231 { _CURVE }
bezier_ctrl_impl._curvenull232 function bezier_ctrl_impl._curve;
233 begin
234  m_curve.init4(
235   m_poly._xn(0 ) ,m_poly._yn(0 ) ,
236   m_poly._xn(1 ) ,m_poly._yn(1 ) ,
237   m_poly._xn(2 ) ,m_poly._yn(2 ) ,
238   m_poly._xn(3 ) ,m_poly._yn(3 ) );
239 
240  result:=@m_curve;
241 
242 end;
243 
244 { _X1 }
bezier_ctrl_impl._x1null245 function bezier_ctrl_impl._x1;
246 begin
247  result:=m_poly._xn(0 );
248 
249 end;
250 
251 { _Y1 }
bezier_ctrl_impl._y1null252 function bezier_ctrl_impl._y1;
253 begin
254  result:=m_poly._yn(0 );
255 
256 end;
257 
258 { _X2 }
bezier_ctrl_impl._x2null259 function bezier_ctrl_impl._x2;
260 begin
261  result:=m_poly._xn(1 );
262 
263 end;
264 
265 { _Y2 }
bezier_ctrl_impl._y2null266 function bezier_ctrl_impl._y2;
267 begin
268  result:=m_poly._yn(1 );
269 
270 end;
271 
272 { _X3 }
bezier_ctrl_impl._x3null273 function bezier_ctrl_impl._x3;
274 begin
275  result:=m_poly._xn(2 );
276 
277 end;
278 
279 { _Y3 }
bezier_ctrl_impl._y3null280 function bezier_ctrl_impl._y3;
281 begin
282  result:=m_poly._yn(2 );
283 
284 end;
285 
286 { _X4 }
bezier_ctrl_impl._x4null287 function bezier_ctrl_impl._x4;
288 begin
289  result:=m_poly._xn(3 );
290 
291 end;
292 
293 { _Y4 }
bezier_ctrl_impl._y4null294 function bezier_ctrl_impl._y4;
295 begin
296  result:=m_poly._yn(3 );
297 
298 end;
299 
300 { X1_ }
301 procedure bezier_ctrl_impl.x1_;
302 begin
303  m_poly.xn_ptr(0 )^:=x;
304 
305 end;
306 
307 { Y1_ }
308 procedure bezier_ctrl_impl.y1_;
309 begin
310  m_poly.yn_ptr(0 )^:=y;
311 
312 end;
313 
314 { X2_ }
315 procedure bezier_ctrl_impl.x2_;
316 begin
317  m_poly.xn_ptr(1 )^:=x;
318 
319 end;
320 
321 { Y2_ }
322 procedure bezier_ctrl_impl.y2_;
323 begin
324  m_poly.yn_ptr(1 )^:=y;
325 
326 end;
327 
328 { X3_ }
329 procedure bezier_ctrl_impl.x3_;
330 begin
331  m_poly.xn_ptr(2 )^:=x;
332 
333 end;
334 
335 { Y3_ }
336 procedure bezier_ctrl_impl.y3_;
337 begin
338  m_poly.yn_ptr(2 )^:=y;
339 
340 end;
341 
342 { X4_ }
343 procedure bezier_ctrl_impl.x4_;
344 begin
345  m_poly.xn_ptr(3 )^:=x;
346 
347 end;
348 
349 { Y4_ }
350 procedure bezier_ctrl_impl.y4_;
351 begin
352  m_poly.yn_ptr(3 )^:=y;
353 
354 end;
355 
356 { LINE_WIDTH_ }
357 procedure bezier_ctrl_impl.line_width_;
358 begin
359  m_stroke.width_(w );
360 
361 end;
362 
363 { _LINE_WIDTH }
bezier_ctrl_impl._line_widthnull364 function bezier_ctrl_impl._line_width;
365 begin
366  result:=m_stroke._width;
367 
368 end;
369 
370 { POINT_RADIUS_ }
371 procedure bezier_ctrl_impl.point_radius_;
372 begin
373  m_poly.point_radius_(r );
374 
375 end;
376 
377 { _POINT_RADIUS }
bezier_ctrl_impl._point_radiusnull378 function bezier_ctrl_impl._point_radius;
379 begin
380  result:=m_poly._point_radius;
381 
382 end;
383 
384 { IN_RECT }
bezier_ctrl_impl.in_rectnull385 function bezier_ctrl_impl.in_rect;
386 begin
387  result:=false;
388 
389 end;
390 
391 { ON_MOUSE_BUTTON_DOWN }
bezier_ctrl_impl.on_mouse_button_downnull392 function bezier_ctrl_impl.on_mouse_button_down;
393 begin
394  inverse_transform_xy(@x ,@y );
395 
396  result:=m_poly.on_mouse_button_down(x ,y );
397 
398 end;
399 
400 { ON_MOUSE_BUTTON_UP }
bezier_ctrl_impl.on_mouse_button_upnull401 function bezier_ctrl_impl.on_mouse_button_up;
402 begin
403  result:=m_poly.on_mouse_button_up(x ,y );
404 
405 end;
406 
407 { ON_MOUSE_MOVE }
bezier_ctrl_impl.on_mouse_movenull408 function bezier_ctrl_impl.on_mouse_move;
409 begin
410  inverse_transform_xy(@x ,@y );
411 
412  result:=m_poly.on_mouse_move(x ,y ,button_flag );
413 
414 end;
415 
416 { ON_ARROW_KEYS }
bezier_ctrl_impl.on_arrow_keysnull417 function bezier_ctrl_impl.on_arrow_keys;
418 begin
419  result:=m_poly.on_arrow_keys(left ,right ,down ,up );
420 
421 end;
422 
423 { NUM_PATHS }
bezier_ctrl_impl.num_pathsnull424 function bezier_ctrl_impl.num_paths;
425 begin
426  result:=7;
427 
428 end;
429 
430 { REWIND }
431 procedure bezier_ctrl_impl.rewind;
432 begin
433  m_idx:=path_id;
434 
435  m_curve.approximation_scale_(scale );
436 
437  case path_id of
438   0 : // Control line 1
439    begin
440     m_curve.init4(
441      m_poly._xn(0 ) ,m_poly._yn(0 ) ,
442      (m_poly._xn(0 ) + m_poly._xn(1 ) ) * 0.5 ,
443      (m_poly._yn(0 ) + m_poly._yn(1 ) ) * 0.5 ,
444      (m_poly._xn(0 ) + m_poly._xn(1 ) ) * 0.5 ,
445      (m_poly._yn(0 ) + m_poly._yn(1 ) ) * 0.5 ,
446      m_poly._xn(1 ) ,m_poly._yn(1 ) );
447 
448     m_stroke.rewind(0 );
449 
450    end;
451 
452   1 : // Control line 2
453    begin
454     m_curve.init4(
455      m_poly._xn(2 ) ,m_poly._yn(2 ) ,
456      (m_poly._xn(2 ) + m_poly._xn(3 ) ) * 0.5,
457      (m_poly._yn(2 ) + m_poly._yn(3 ) ) * 0.5,
458      (m_poly._xn(2 ) + m_poly._xn(3 ) ) * 0.5,
459      (m_poly._yn(2 ) + m_poly._yn(3 ) ) * 0.5,
460      m_poly._xn(3 ) ,m_poly._yn(3 ) );
461 
462      m_stroke.rewind(0 );
463 
464    end;
465 
466   2 : // Curve itself
467    begin
468     m_curve.init4(
469      m_poly._xn(0 ) ,m_poly._yn(0 ) ,
470      m_poly._xn(1 ) ,m_poly._yn(1 ) ,
471      m_poly._xn(2 ) ,m_poly._yn(2 ) ,
472      m_poly._xn(3 ) ,m_poly._yn(3 ) );
473 
474     m_stroke.rewind(0 );
475 
476    end;
477 
478   3 : // Point 1
479    begin
480     m_ellipse.init  (m_poly._xn(0 ) ,m_poly._yn(0 ) ,_point_radius ,_point_radius ,20 );
481     m_ellipse.rewind(0 );
482 
483    end;
484 
485   4 : // Point 2
486    begin
487     m_ellipse.init  (m_poly._xn(1 ) ,m_poly._yn(1 ) ,_point_radius ,_point_radius ,20 );
488     m_ellipse.rewind(0 );
489 
490    end;
491 
492   5 : // Point 3
493    begin
494     m_ellipse.init  (m_poly._xn(2 ) ,m_poly._yn(2 ) ,_point_radius ,_point_radius ,20 );
495     m_ellipse.rewind(0 );
496 
497    end;
498 
499   6 : // Point 4
500    begin
501     m_ellipse.init  (m_poly._xn(3 ) ,m_poly._yn(3 ) ,_point_radius ,_point_radius ,20 );
502     m_ellipse.rewind(0 );
503 
504    end;
505 
506  end;
507 
508 end;
509 
510 { VERTEX }
bezier_ctrl_impl.vertexnull511 function bezier_ctrl_impl.vertex;
512 var
513  cmd : unsigned;
514 
515 begin
516  cmd:=path_cmd_stop;
517 
518  case m_idx of
519   0 ,1 ,2 :
520    cmd:=m_stroke.vertex(x ,y );
521 
522   3 ,4 ,5 ,6 ,7 :
523    cmd:=m_ellipse.vertex(x, y);
524 
525  end;
526 
527  if not is_stop(cmd ) then
528   transform_xy(x ,y );
529 
530  result:=cmd;
531 
532 end;
533 
534 { CONSTRUCT }
535 constructor bezier_ctrl.Construct;
536 begin
537  inherited Construct;
538 
539  m_color.ConstrDbl(0.0 ,0.0 ,0.0 );
540 
541 end;
542 
543 { LINE_COLOR_ }
544 procedure bezier_ctrl.line_color_;
545 begin
546  m_color:=c^;
547 
548 end;
549 
550 { _COLOR }
bezier_ctrl._colornull551 function bezier_ctrl._color;
552 begin
553  result:=@m_color;
554 
555 end;
556 
557 { CONSTRUCT }
558 constructor curve3_ctrl_impl.Construct;
559 begin
560  inherited Construct(0 ,0 ,1 ,1 ,false );
561 
562  m_curve.Construct;
563  m_ellipse.Construct;
564  m_stroke.Construct(@m_curve );
565  m_poly.Construct  (3 ,5.0 );
566 
567  m_idx:=0;
568 
569  m_poly.in_polygon_check_(false );
570 
571  m_poly.xn_ptr(0 )^:=100.0;
572  m_poly.yn_ptr(0 )^:=  0.0;
573  m_poly.xn_ptr(1 )^:=100.0;
574  m_poly.yn_ptr(1 )^:= 50.0;
575  m_poly.xn_ptr(2 )^:= 50.0;
576  m_poly.yn_ptr(2 )^:=100.0;
577 
578 end;
579 
580 { DESTRUCT }
581 destructor curve3_ctrl_impl.Destruct;
582 begin
583  m_curve.Destruct;
584  m_stroke.Destruct;
585  m_poly.Destruct;
586 
587 end;
588 
589 { CURVE_ }
590 procedure curve3_ctrl_impl.curve_;
591 begin
592  m_poly.xn_ptr(0 )^:=x1;
593  m_poly.yn_ptr(0 )^:=y1;
594  m_poly.xn_ptr(1 )^:=x2;
595  m_poly.yn_ptr(1 )^:=y2;
596  m_poly.xn_ptr(2 )^:=x3;
597  m_poly.yn_ptr(2 )^:=y3;
598 
599  _curve;
600 
601 end;
602 
603 { _CURVE }
curve3_ctrl_impl._curvenull604 function curve3_ctrl_impl._curve;
605 begin
606  m_curve.init3(
607   m_poly._xn(0 ) ,m_poly._yn(0 ) ,
608   m_poly._xn(1 ) ,m_poly._yn(1 ) ,
609   m_poly._xn(2 ) ,m_poly._yn(2 ) );
610 
611  result:=@m_curve;
612 
613 end;
614 
615 { _X1 }
curve3_ctrl_impl._x1null616 function curve3_ctrl_impl._x1;
617 begin
618  result:=m_poly._xn(0 );
619 
620 end;
621 
622 { _Y1 }
curve3_ctrl_impl._y1null623 function curve3_ctrl_impl._y1;
624 begin
625  result:=m_poly._yn(0 );
626 
627 end;
628 
629 { _X2 }
curve3_ctrl_impl._x2null630 function curve3_ctrl_impl._x2;
631 begin
632  result:=m_poly._xn(1 );
633 
634 end;
635 
636 { _Y2 }
curve3_ctrl_impl._y2null637 function curve3_ctrl_impl._y2;
638 begin
639  result:=m_poly._yn(1 );
640 
641 end;
642 
643 { _X3 }
curve3_ctrl_impl._x3null644 function curve3_ctrl_impl._x3;
645 begin
646  result:=m_poly._xn(2 );
647 
648 end;
649 
650 { _Y3 }
curve3_ctrl_impl._y3null651 function curve3_ctrl_impl._y3;
652 begin
653  result:=m_poly._yn(2 );
654 
655 end;
656 
657 { X1_ }
658 procedure curve3_ctrl_impl.x1_;
659 begin
660  m_poly.xn_ptr(0 )^:=x;
661 
662 end;
663 
664 { Y1_ }
665 procedure curve3_ctrl_impl.y1_;
666 begin
667  m_poly.yn_ptr(0 )^:=y;
668 
669 end;
670 
671 { X2_ }
672 procedure curve3_ctrl_impl.x2_;
673 begin
674  m_poly.xn_ptr(1 )^:=x;
675 
676 end;
677 
678 { Y2_ }
679 procedure curve3_ctrl_impl.y2_;
680 begin
681  m_poly.yn_ptr(1 )^:=y;
682 
683 end;
684 
685 { X3_ }
686 procedure curve3_ctrl_impl.x3_;
687 begin
688  m_poly.xn_ptr(2 )^:=x;
689 
690 end;
691 
692 { Y3_ }
693 procedure curve3_ctrl_impl.y3_;
694 begin
695  m_poly.yn_ptr(2 )^:=y;
696 
697 end;
698 
699 { LINE_WIDTH_ }
700 procedure curve3_ctrl_impl.line_width_;
701 begin
702  m_stroke.width_(w );
703 
704 end;
705 
706 { _LINE_WIDTH }
curve3_ctrl_impl._line_widthnull707 function curve3_ctrl_impl._line_width;
708 begin
709  result:=m_stroke._width;
710 
711 end;
712 
713 { POINT_RADIUS_ }
714 procedure curve3_ctrl_impl.point_radius_;
715 begin
716  m_poly.point_radius_(r );
717 
718 end;
719 
720 { _POINT_RADIUS }
curve3_ctrl_impl._point_radiusnull721 function curve3_ctrl_impl._point_radius;
722 begin
723  result:=m_poly._point_radius;
724 
725 end;
726 
727 { IN_RECT }
curve3_ctrl_impl.in_rectnull728 function curve3_ctrl_impl.in_rect;
729 begin
730  result:=false;
731 
732 end;
733 
734 { ON_MOUSE_BUTTON_DOWN }
curve3_ctrl_impl.on_mouse_button_downnull735 function curve3_ctrl_impl.on_mouse_button_down;
736 begin
737  inverse_transform_xy(@x ,@y );
738 
739  result:=m_poly.on_mouse_button_down(x ,y );
740 
741 end;
742 
743 { ON_MOUSE_BUTTON_UP }
curve3_ctrl_impl.on_mouse_button_upnull744 function curve3_ctrl_impl.on_mouse_button_up;
745 begin
746  result:=m_poly.on_mouse_button_up(x ,y );
747 
748 end;
749 
750 { ON_MOUSE_MOVE }
curve3_ctrl_impl.on_mouse_movenull751 function curve3_ctrl_impl.on_mouse_move;
752 begin
753  inverse_transform_xy(@x ,@y );
754 
755  result:=m_poly.on_mouse_move(x ,y ,button_flag );
756 
757 end;
758 
759 { ON_ARROW_KEYS }
curve3_ctrl_impl.on_arrow_keysnull760 function curve3_ctrl_impl.on_arrow_keys;
761 begin
762  result:=m_poly.on_arrow_keys(left ,right ,down ,up );
763 
764 end;
765 
766 { NUM_PATHS }
curve3_ctrl_impl.num_pathsnull767 function curve3_ctrl_impl.num_paths;
768 begin
769  result:=6;
770 
771 end;
772 
773 { REWIND }
774 procedure curve3_ctrl_impl.rewind;
775 begin
776  m_idx:=path_id;
777 
778  case path_id of
779   0 : // Control line
780    begin
781     m_curve.init3(
782      m_poly._xn(0 ) ,m_poly._yn(0 ) ,
783      (m_poly._xn(0 ) + m_poly._xn(1 ) ) * 0.5,
784      (m_poly._yn(0 ) + m_poly._yn(1 ) ) * 0.5,
785      m_poly._xn(1 ) ,m_poly._yn(1 ) );
786 
787     m_stroke.rewind(0 );
788 
789    end;
790 
791   1 : // Control line 2
792    begin
793     m_curve.init3(
794      m_poly._xn(1 ) ,m_poly._yn(1 ) ,
795      (m_poly._xn(1 ) + m_poly._xn(2 ) ) * 0.5,
796      (m_poly._yn(1 ) + m_poly._yn(2 ) ) * 0.5,
797      m_poly._xn(2 ) ,m_poly._yn(2 ) );
798 
799      m_stroke.rewind(0 );
800 
801    end;
802 
803   2 : // Curve itself
804    begin
805     m_curve.init3(
806      m_poly._xn(0 ) ,m_poly._yn(0 ) ,
807      m_poly._xn(1 ) ,m_poly._yn(1 ) ,
808      m_poly._xn(2 ) ,m_poly._yn(2 ) );
809 
810     m_stroke.rewind(0 );
811 
812    end;
813 
814   3 : // Point 1
815    begin
816     m_ellipse.init  (m_poly._xn(0 ) ,m_poly._yn(0 ) ,_point_radius ,_point_radius ,20 );
817     m_ellipse.rewind(0 );
818 
819    end;
820 
821   4 : // Point 2
822    begin
823     m_ellipse.init  (m_poly._xn(1 ) ,m_poly._yn(1 ) ,_point_radius ,_point_radius ,20 );
824     m_ellipse.rewind(0 );
825 
826    end;
827 
828   5 : // Point 3
829    begin
830     m_ellipse.init  (m_poly._xn(2 ) ,m_poly._yn(2 ) ,_point_radius ,_point_radius ,20 );
831     m_ellipse.rewind(0 );
832 
833    end;
834 
835  end;
836 
837 end;
838 
839 { VERTEX }
curve3_ctrl_impl.vertexnull840 function curve3_ctrl_impl.vertex;
841 var
842  cmd : unsigned;
843 
844 begin
845  cmd:=path_cmd_stop;
846 
847  case m_idx of
848   0 ,1 ,2 :
849    cmd:=m_stroke.vertex(x ,y );
850 
851   3 ,4 ,5 ,6 :
852    cmd:=m_ellipse.vertex(x ,y );
853 
854  end;
855 
856  if not is_stop(cmd ) then
857   transform_xy(x ,y );
858 
859  result:=cmd;
860 
861 end;
862 
863 { CONSTRUCT }
864 constructor curve3_ctrl.Construct;
865 begin
866  inherited Construct;
867 
868  m_color.ConstrDbl(0.0 ,0.0 ,0.0 );
869 
870 end;
871 
872 { LINE_COLOR_ }
873 procedure curve3_ctrl.line_color_;
874 begin
875  m_color:=c^;
876 
877 end;
878 
879 { _COLOR }
curve3_ctrl._colornull880 function curve3_ctrl._color;
881 begin
882  result:=@m_color;
883 
884 end;
885 
886 END.
887 
888