Hosted by
|
with Messages; use Messages;
with Outlines; use Outlines;
with Lines; use Lines;
with Straights; use Straights;
with Cubics; use Cubics;
with Real_Vectors; use Real_Vectors;
package body Nocurves is
function Distance
(Start : in Vector;
A, B : access Line'Class)
return Real
is
Result : Real := 0.0;
Part : Real;
begin
for Index in 1 .. 24 loop
Part := Real(Index * 2 - 1) / 48.0;
Result := Real'Max(Result, abs(
Way_Point(Start, A, Part) -
Way_Point(Start, B, Part)));
end loop;
return Result;
end Distance;
procedure Halve
(Start : in Vector;
This : access Line'Class;
Curve_1 : out Line_Access;
Curve_2 : out Line_Access)
is
A : Vector := Start;
B : Vector := Cubic_Access(This).Control_A;
C : Vector := Cubic_Access(This).Control_B;
D : Vector := This.To;
AB : Vector := (A + B) / 2.0;
BC : Vector := (B + C) / 2.0;
CD : Vector := (C + D) / 2.0;
ABBC : Vector := (AB + BC) / 2.0;
BCCD : Vector := (BC + CD) / 2.0;
ABBCBCCD : Vector := (ABBC + BCCD) / 2.0;
begin
Curve_1 := Create(Control_A => AB, Control_B => ABBC, To => ABBCBCCD);
Curve_2 := Create(Control_A => BCCD, Control_B => CD, To => D);
end Halve;
procedure Make_Straight
(Start : in Vector;
This : access Line'Class;
Tolerance : in Real;
Insert : access Outline)
is
use Line_Lists;
Test : Line_Access := Create(This.To);
Curve_1 : Line_Access;
Curve_2 : Line_Access;
begin
if Distance(Start, This, Test) <= Tolerance then
Insert_Before_Current(Insert, Test);
else
Halve(Start, This, Curve_1, Curve_2);
Make_Straight(Start, Curve_1, Tolerance, Insert);
Make_Straight(Curve_1.To, Curve_2, Tolerance, Insert);
end if;
end Make_Straight;
procedure Make_Straight
(This : access Outline;
Tolerance : in Real)
is
use Line_Lists;
Start : Vector := Last(This).To;
Curve : Line_Access;
begin
Reset(This);
Next(This);
while not End_Of_List(This) loop
Curve := Current(This);
Make_Straight(Start, Curve, Tolerance, This);
Remove_Current(This);
Start := Curve.To;
end loop;
end Make_Straight;
procedure Make_Straight
(This : access Glyph;
Tolerance : in Real)
is
use Glyphs.Outline_Lists;
Outlines : Outline_List_Access;
Outline : Outline_Access;
begin
Outlines := Get_Outlines(This);
Reset(Outlines);
while Next(Outlines) loop
Outline := Current(Outlines);
Make_Straight(Outline, Tolerance);
end loop;
end Make_Straight;
end Nocurves;
|