Hosted by
 |
with Messages; use Messages;
with Outlines; use Outlines;
with Lines; use Lines;
with Cubics; use Cubics;
with Real_Vectors; use Real_Vectors;
package body Curves is
procedure Make_Cubic
(This : in out Outline;
Tolerance : in Real)
is
use Line_Lists;
Item_1 : Item := Last_Item(This);
Item_2 : Item := First_Item(This);
Item_3 : Item := Next_Item(Item_2);
Item_4 : Item := Next_Item(Item_3);
Stop : Item := Item_3;
Counter : Natural := 2;
Line_1, Line_2, Line_3, Line_4 : Line;
procedure Content is
begin
Line_1 := Item_Content(Item_1);
Line_2 := Item_Content(Item_2);
Line_3 := Item_Content(Item_3);
Line_4 := Item_Content(Item_4);
end Content;
procedure Valid_2 is
begin
if Item_Invalid(Item_2) then
Item_2 := First_Item(This);
end if;
end Valid_2;
procedure Valid_4 is
begin
if Item_Invalid(Item_4) then
Item_4 := First_Item(This);
Counter := 0;
end if;
end Valid_4;
procedure Half_Step is
begin
Counter := Counter + 1;
Item_3 := Item_4;
Item_4 := Next_Item(Item_4);
Valid_4;
Content;
end Half_Step;
procedure Step is
begin
Item_1 := Item_2;
Item_2 := Item_3;
Half_Step;
end Step;
Curve_23 : Line;
Curve_34 : Line;
Error_23 : Real;
Error_34 : Real;
begin
Content;
while Line_Lists.Count(This) > 2 loop
Make_Cubic(Line_1.To, Line_2, Line_3, Curve_23, Error_23);
Make_Cubic(Line_2.To, Line_3, Line_4, Curve_34, Error_34);
if Error_23 <= Tolerance and Error_23 < Error_34 then
Update_Item(Item_3, Line(Curve_23)); -- Join Item_2 into Item_3.
Remove_Item(Item_1, Item_2, This); -- Remove and advance Item_2.
Valid_2; -- Wrap around end of list.
Half_Step; -- Advance Item_3 and Item_4.
Stop := Item_3; -- Set iteration stopper.
elsif Error_34 <= Tolerance then
Update_Item(Item_3, Line(Curve_34)); -- Join Item_4 into Item_3.
Remove_Item(Item_3, Item_4, This); -- Remove and advance Item_4.
Valid_4; -- Wrap around end of list.
Step; -- Advance all.
Stop := Item_3; -- Set iteration stopper.
end if;
Step;
exit when Item_Equals(Item_3, Stop);
end loop;
end Make_Cubic;
procedure Make_Cubic
(This : in Glyph;
Tolerance : in Real)
is
use Glyphs.Outline_Lists;
Outlines : Outline_List;
Current_Outline : Outline;
begin
Outlines := Get_Outlines(This);
Reset(Outlines);
while Next(Outlines) loop
Current_Outline := Current(Outlines);
Make_Cubic(Current_Outline, Tolerance);
end loop;
end Make_Cubic;
end Curves;
|