Hosted by
|
with Integer_Strings; use Integer_Strings;
package body Printers.PGM is
function Create
(Filename : in String)
return PGM_Printer_Access
is
Result : PGM_Printer_Access := new PGM_Printer;
begin
To_String_Access(Filename, Result.Filename);
return Result;
end Create;
function Get_Format
(This : access PGM_Printer)
return String is
begin
return "PGM";
end Get_Format;
procedure Set_Bounds
(This : access PGM_Printer;
Bounds : in Rectangle;
Staff_Height : in Real)
is
type Parent_Access is access all Printer;
begin
Set_Bounds(Parent_Access(This), Bounds, Staff_Height);
This.Image := Bounds_To_Image(This.Bounds, Staff_Height);
Fill(This.Image, White);
Print_Staff_Lines(This);
end Set_Bounds;
procedure Print_Staff_Lines
(This : access PGM_Printer)
is
H : Natural;
H1, H2 : Natural;
Line_Y : Integer;
begin
H := Natural(This.Image.Staff_Height / 40.0);
if H > 0 then H := H - 1; end if;
H1 := H / 2;
H2 := H - H1;
for Index in -2 .. 2 loop
Line_Y := Integer(This.Image.Center.Y + This.Image.Staff_Height / 4.0 * Real(Index));
for Y in Line_Y - H1 .. Line_Y + H2 loop
if Y in This.Image.Pixels'Range(1) then
for X in This.Image.Pixels'Range(2) loop
This.Image.Pixels(Y, X) := 0;
end loop;
end if;
end loop;
end loop;
end Print_Staff_Lines;
procedure Print
(This : access PGM_Printer;
Add : access Glyph;
Center : in Vector) is
begin
Glyphs.Print(Add, This.Image, Center);
end Print;
procedure To_Pixels
(This : access PGM_Printer;
Box : in Rectangle;
Left : out Integer;
Top : out Integer;
Right : out Integer;
Bottom : out Integer)
is
Width, Height : Integer;
begin
Left := Integer(This.Image.Center.X + Box.Left * This.Image.Staff_Height / 400.0);
Top := Integer(This.Image.Center.Y + Box.Top * This.Image.Staff_Height / 400.0);
Width := Integer(Get_Width(Box) * This.Image.Staff_Height / 400.0);
Height := Integer(Get_Height(Box) * This.Image.Staff_Height / 400.0);
Right := Left + Width;
Bottom := Top + Height;
end To_Pixels;
procedure Darken_Pixel
(This : access PGM_Printer;
Y, X : in Integer;
Color : in Gray_Pixel)
is
use type Gray_Images.Gray_Pixel;
begin
if Y in This.Image.Pixels'Range(1)
and X in This.Image.Pixels'Range(2)
then
if This.Image.Pixels(Y, X) > Color then
This.Image.Pixels(Y, X) := Color;
end if;
end if;
end Darken_Pixel;
procedure Frame_Box
(This : access PGM_Printer;
Box : in Rectangle;
Color : in Gray_Pixel)
is
Left, Top, Right, Bottom : Integer;
begin
To_Pixels(This, Box, Left, Top, Right, Bottom);
for X in Left .. Right loop
Darken_Pixel(This, Top, X, Color);
Darken_Pixel(This, Bottom, X, Color);
end loop;
for Y in Top .. Bottom loop
Darken_Pixel(This, Y, Left, Color);
Darken_Pixel(This, Y, Right, Color);
end loop;
end Frame_Box;
procedure Fill_Box
(This : access PGM_Printer;
Box : in Rectangle;
Color : in Gray_Pixel)
is
Left, Top, Right, Bottom : Integer;
begin
To_Pixels(This, Box, Left, Top, Right, Bottom);
for X in Left .. Right loop
for Y in Top .. Bottom loop
Darken_Pixel(This, Y, X, Color);
end loop;
end loop;
end Fill_Box;
procedure Write
(This : access PGM_Printer) is
begin
Write(To_String(This.Filename), This.Image);
end Write;
end Printers.PGM;
|