Hosted by
|
with Integer_Strings; use Integer_Strings;
with Enum_Strings; use Enum_Strings;
with Messages; use Messages;
package body Boxes.Keys is
function Create
(Key : in Key_Access;
Middle_C : in Integer)
return Key_Box_Access
is
Result : Key_Box_Access := new Key_Box;
begin
Result.Key := Key;
Result.Middle_C := Middle_C;
return Result;
end Create;
function Get_Key
(This : access Key_Box)
return Key_Access is
begin
return This.Key;
end Get_Key;
function Get_Middle_C
(This : access Key_Box)
return Integer is
begin
return This.Middle_C;
end Get_Middle_C;
function Get_Center
(This : access Key_Box;
Index : in Accidentals)
return Vector is
begin
return (Real(Index) * 100.0 - 50.0, -50.0 * Real(This.Offsets(Index)));
end Get_Center;
procedure Layout
(This : access Key_Box;
Font : access Font_Loader) is
begin
if not Quiet then Debug("preparing key layout"); end if;
if Get_Fifths(This.Key) > 0 then
case This.Middle_C is
when -6 => This.Offsets := (4, 1, 5, 2, -1, 3, 0);
when 6 => This.Offsets := (2, -1, 3, 0, -3, 1, -2);
when => This.Offsets := (3, 0, 4, 1, -2, 2, -1);
when 2 => This.Offsets := (-2, 2, -1, 3, 0, 4, 1);
when others => Error("unsupported middle C position" & This.Middle_C'Img);
end case;
for Index in 1 .. Get_Fifths(This.Key) loop
This.Glyphs(Index) := Load_Glyph(Font, "accidentals/sharp");
if Index = 1 then
This.Bounds :=
Get_Bounds(This.Glyphs(Index)) + Get_Center(This, Index);
else
This.Bounds := Max(This.Bounds,
Get_Bounds(This.Glyphs(Index)) + Get_Center(This, Index));
end if;
end loop;
elsif Get_Fifths(This.Key) < 0 then
case This.Middle_C is
when -6 => This.Offsets := (0, 3, -1, 2, -2, 1, -3);
when 6 => This.Offsets := (-2, 1, -3, 0, -4, -1, 2);
when => This.Offsets := (-1, 2, -2, 1, -3, 0, -4);
when 2 => This.Offsets := (1, 4, 0, 3, -1, 2, -2);
when others => Error("unsupported middle C position" & This.Middle_C'Img);
end case;
for Index in 1 .. -Get_Fifths(This.Key) loop
This.Glyphs(Index) := Load_Glyph(Font, "accidentals/flat");
if Index = 1 then
This.Bounds :=
Get_Bounds(This.Glyphs(Index)) + Get_Center(This, Index);
else
This.Bounds := Max(This.Bounds,
Get_Bounds(This.Glyphs(Index)) + Get_Center(This, Index));
end if;
end loop;
end if;
end Layout;
procedure Print
(This : access Key_Box;
To : access Printer'Class;
Center : in Vector) is
begin
for Index in 1 .. abs(Get_Fifths(This.Key)) loop
Print(To, This.Glyphs(Index),
Center + This.Center + Get_Center(This, Index));
end loop;
Print_Bounds(This, To, Center);
end Print;
end Boxes.Keys;
|