From: Micah Waddoups <micah.waddoups@gmail.com>
Subject: Re: Unifont static compiled and stack size...
Date: Mon, 14 Aug 2023 08:10:01 -0700 (PDT) [thread overview]
Message-ID: <5290b261-c8d8-4f0a-87f5-941d275a1e6dn@googlegroups.com> (raw)
In-Reply-To: <ubcubb$28epd$1@dont-email.me>
On Monday, August 14, 2023 at 4:06:39 AM UTC-6, Jeffrey R.Carter wrote:
> On 2023-08-13 18:16, Micah Waddoups wrote:
> > I tried to compile the Unifont hex file, converted with a script into variable Ada code, but it went on forever, gradually blowing up my memory. I used an .ads file and aimed for a static build, but I suspect I would have hit the stack size limit for executables if I succeeded
> As I understand it, the file in question is for code points 0 .. 16#FFFF#, with
> a maximum of 32 bytes per code point. A straightforward representation of this is
>
> package Unifont is
> type Byte is mod 2 ** 8 with Size => 8;
>
> type Line is array (1 .. 2) of Byte with Size => 16;
>
> type Bitmap is array (1 .. 16) of Line with Size => 256;
>
> function Width_8 (Map : in Bitmap) return Boolean is
> (for all L of Map => L (2) = 0);
>
> type Code_Point is mod 16#FFFF# + 1;
>
> type Font_Map is array (Code_Point) of Bitmap with Size => 2 ** 24;
>
> Font : constant Font_Map := (others => (others => (others => 0) ) );
> end Unifont;
>
> Font will occupy 2 MB.
>
> We can test this with
>
> with Ada.Text_IO;
> with Unifont;
>
> procedure Unifont_Test is
> -- Empty
> begin -- Unifont_Test
> Ada.Text_IO.Put_Line (Item => Unifont.Font (0) (1) (1)'Image);
> end Unifont_Test;
>
> and see what happens:
>
> $ gnatmake -m -j0 -gnat12 -gnatan -gnato2 -O2 -fstack-check unifont_test.adb
> x86_64-linux-gnu-gcc-12 -c -gnat12 -gnatan -gnato2 -O2 -fstack-check
> unifont_test.adb
> x86_64-linux-gnu-gcc-12 -c -gnat12 -gnatan -gnato2 -O2 -fstack-check unifont.ads
> x86_64-linux-gnu-gnatbind-12 -x unifont_test.ali
> x86_64-linux-gnu-gnatlink-12 unifont_test.ali -O2 -fstack-check
> $ ./unifont_test
> 0
>
> so this representation seems to be workable. It should be trivial to write a
> program to read the file and produce the real array aggregate for Font.
>
> --
> Jeff Carter
> "I wave my private parts at your aunties."
> Monty Python & the Holy Grail
> 13
Thank you all for replying while I was working away from home.
Jeff, you missed a digit - it's five F's 16#FFFFF# because that is as high as Unifont goes in my copy of the hex file. Of course the technique should be able to go higher if that changes, but Unicode is pretty exhaustive as it is and Unifont is meant to keep up with every version and addition to the Unicode code points, so I sincerely hope for no trouble for a while yet. I checked, and it seem my system has about 8 megabytes as the stack size limit, so with the ranges left empty it is not 32 megabytes, but still pretty big. Good looking code, by the way. Very easy to read. Mine is appended, but it was really a quick hack of a job with too little sleep. I probably should have done a Z Shell script (maybe take 20 seconds?), but I thought the two second efficiency of writing a compiled composer was worth it ...somehow...
Niklas, I think you have the most actionable suggestions for me to test. Thank you.
Dmitry, Thank you for trying to understand. Since both methods of rendering fonts made available by GTK, I consider it GTK providing it. I don't want any more imports than I can provide easily with a static compile or as accompanying dynamic modules (reason hereafter mentioned), and Licensing needs to be the most permissive possible. The idea is to be able to create a shell or a variety of other programs using my library as a very focused kind of interface that supports more characters and more languages that my other most available options, so the font is important, even if I'm just drawing to the Linux frame buffer. I meant a transfer of code from one platform to another. Sometimes in a graphical window that acts like a text interface window, sometimes on the linux frame buffer, and in the extreme case some times on the text console without any particular font support. The main collection of code is supposed to support all that with very limited modification to say transfer from Linux to macOS or MS Windows? I hope this s answered your questions.
Oh, and to all, I have already abandon the idea of using Boolean with Pack, since it no longer seems to work and was a bit *too* verbose
pragma Ada_2012;
pragma Wide_Character_Encoding (UTF8);
with Ada.Text_IO;
use Ada.Text_IO;
procedure Unifont_Hex_To_Ada is
Target_Name: String := "./src/unifont.ads";
Source_Name: String := "unifont_all-15.0.06.hex";
Target: aliased File_Type;
Source: aliased File_Type;
Buffer: aliased String (1 .. 96) := (others=>' ');
Index, F: Positive := 1;
Previous, Current, Length, L: Natural := 0;
Finished: aliased Boolean:= False;
subtype Hex_Character is Character range '0' .. 'f'
with Static_Predicate=> (Hex_Character in '0' .. '9') or (Hex_Character in 'A' .. 'F') or (Hex_Character in 'a' .. 'f');
type Byte is mod 2 **8;
type Bit is mod 8;
--type Bytes is array (Natural range <>) of aliased Byte;
Bit_X: Bit := 0;
Byte_X: Byte := 0;
function Find (Item: Character)
return Natural
is
begin
for
N in Buffer'Range
loop
if Item = Buffer(N)
then return N;
end if;
end loop;
return 0;
end Find;
function Enum return Natural
is
First: Positive := 1;
Last: Natural := Integer'Max ((Find (':') -1), 0);
begin
return R: Natural
do
R := Natural'Value ("16#" &Buffer (First..Last) &'#');
end return;
end Enum;
procedure Next_Byte
is
S: String renames Buffer (F .. L);
begin
loop
if
(Index in S'Range) and (Index +1 in S'Range)
then
exit;
else
Index := S'First;
if
(Index in S'Range) and (Index +1 in S'Range)
then
exit;
else
raise Program_Error with "Next_Byte-> Somehow there are no Hex codes in string... line " &Current'Img &", string => " & S;
end if;
end if;
end loop;
if
S (Index) in Hex_Character
and
S (Index +1) in Hex_Character
then
Byte_X := Byte'Value ("16#" &S (Index..Index +1) &"#");
Bit_X := 0;
Index := Index +2;
end if;
end Next_Byte;
procedure Next_Line
is
begin
for
N in Buffer'First .. Length
loop
Buffer (N):= ' ';
end loop;
begin
Get_Line (Source, Buffer, Length);
exception
when others => null;
end;
if
Length < 32
then
Put_Line (Standard_Error, "empty or incomplete line at code point " &Natural'Image (Enum) &" (" &Current'Img &" + 1)");
else
Previous:= Current;
Current:= Enum;
if
((Previous + 1) = Current)
or else (Current = 0)
then
F:= Find (':') +1;
L:= Length;
Next_Byte;
else
F:= Find (':') +1;
L:= Length;
Next_Byte;
Put_Line (Standard_Error, " Missing character range in Source: " &Previous'Img &" .. " &Current'Img);
end if;
end if;
end Next_Line;
subtype Index_Type is Natural range 0 .. 16#FFFFF#;
subtype Y_Type is Integer range 1 .. 16;
subtype X_Type is Integer range 1 .. 16;
type Size_Type is
record
Y: aliased Y_Type:= Y_Type'First;
X: aliased X_Type:= X_Type'First;
end record;
type Size_Set_Type is array (Index_Type) of aliased Size_Type;
type Size_Set_Access is access all Size_Set_Type;
function Dot return String is
begin
if
1 = ((Byte_X / 2 **(7 - Natural(Bit_X))) and 1)
then
if
Bit_X = Bit'Last
then
Next_Byte;
else
Bit_X := Bit_X +1;
end if;
return "True";
else
if
Bit_X = Bit'Last
then
Next_Byte;
else
Bit_X := Bit_X +1;
end if;
return "False";
end if;
end Dot;
Cache_Size: Size_Set_Access := new Size_Set_Type'(others => (16, 8));
Size: Size_Set_Type renames Cache_Size.all;
begin
begin
Open (Source, In_File, Source_Name);
exception
when others =>
raise Status_Error with " Source File not found: " &Source_Name;
end;
begin
Create (Target, Out_File, Target_Name);
exception
when others =>
Open (Target, Out_File, Target_Name);
end;
begin
Put_Line (Target, "pragma Ada_2012;");
Put_Line (Target, "pragma Wide_Character_Encoding (UTF8);");
New_Line (Target, 2);
--Put_Line (Target, "with ada.unchecked_conversion;");
--New_Line (Target, 2);
Put_Line (Target, "package Unifont is");
Put_Line (Target, "subtype Index_Type is Wide_Wide_Character range Wide_Wide_Character'Val (0) .. Wide_Wide_Character'Val (16#FFFFF#);");
Put_Line (Target, "subtype Y_Type is Integer range 1 .. 16;");
Put_Line (Target, "subtype X_Type is Integer range 1 .. 16;");
Put_Line (Target, "type Size_Type is record Y: aliased Y_Type := 1; X: aliased X_Type := 1; end record;");
Put_Line (Target, "type Size_Set_Type is array (Index_Type) of aliased Size_Type;");
Put_Line (Target, "type Glyph_Type is array (Y_Type, X_Type) of Boolean");
Put_Line (Target, "with Pack, Size=> 256;");
Put_Line (Target, "type Glyph_Set_Type is array (Index_Type) of aliased Glyph_Type;");
Put_Line (Target, "Glyph: constant Glyph_Set_Type :=");
Put (Target, "(");
loop
exit when End_Of_File (Source);
Next_Line; -- Load Next Line and extract Code Point index
if
Length > 64
then
Size (Current) := (16, 16);
Put_Line (Target, "Wide_Wide_Character'Val (" &Integer'Image(Current) &") =>");
Put (Target, "(");
for Y in 1 .. 16
loop
Put_Line (Target, Y'Img &" =>");
Put (Target, "(");
for X in 1 .. 16
loop
if
X < 16
then
Put (Target, Dot &", ");
else
Put (Target, Dot &")");
end if;
end loop;
if
Y < 16
then
Put_Line (Target, ",");
else
Put_Line (Target, "),");
end if;
end loop;
elsif
Length > 32
then
Put_Line (Target, "Wide_Wide_Character'Val (" &Integer'Image(Current) &") =>");
Put (Target, "(");
for Y in 1 .. 16
loop
Put_Line (Target, Y'Img &" =>");
Put (Target, "(");
for X in 1 .. 8
loop
Put (Target, Dot &", ");
end loop;
for X in 9 .. 16
loop
if
X < 16
then
Put (Target, "False, ");
else
Put (Target, "False)");
end if;
end loop;
if
Y < 16
then
Put_Line (Target, ",");
else
Put_Line (Target, "),");
end if;
end loop;
end if;
end loop;
Close (Source);
Put_Line (Target, "others => (others => (others => False)));");
New_Line (Target);
Put_Line (Target, "Size: constant Size_Set_Type :=");
Put (Target, "(");
for N in Index_Type'Range
loop
Put (Target, "Wide_Wide_Character'Val (" &Integer'Image(N) &") =>");
Put (Target, "(" &Integer'Image(Size(N).Y) &", " &Integer'Image(Size(N).X) &")");
if
N < Index_Type'Last
then
Put_Line (Target, ",");
else
Put_Line (Target, ");");
end if;
end loop;
Put_Line (Target, "end Unifont;");
Put_Line (Target, "");
Put_Line (Target, "");
Put_Line (Target, "");
Put_Line (Target, "");
Put_Line (Target, "");
Put_Line (Target, "");
Put_Line (Target, "");
Put_Line (Target, "");
Put_Line (Target, "");
Put_Line (Target, "");
Put_Line (Target, "");
Put_Line (Target, "");
Put_Line (Target, "");
Put_Line (Target, "");
Put_Line (Target, "");
Put_Line (Target, "");
Close (Target);
end;
end Unifont_Hex_To_Ada;
next prev parent reply other threads:[~2023-08-14 15:10 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-13 16:16 Unifont static compiled and stack size Micah Waddoups
2023-08-13 21:19 ` DrPi
2023-08-14 0:29 ` Micah Waddoups
2023-08-14 8:21 ` Dmitry A. Kazakov
2023-08-14 8:07 ` Niklas Holsti
2023-08-14 8:31 ` Dmitry A. Kazakov
2023-08-14 9:25 ` Kevin Chadwick
2023-08-14 9:30 ` Kevin Chadwick
2023-08-14 9:43 ` Dmitry A. Kazakov
2023-08-14 9:39 ` Dmitry A. Kazakov
2023-08-15 8:40 ` G.B.
2023-08-16 6:17 ` Dmitry A. Kazakov
2023-08-18 3:04 ` Randy Brukardt
2023-08-14 10:06 ` Jeffrey R.Carter
2023-08-14 15:10 ` Micah Waddoups [this message]
2023-08-14 15:59 ` Jeffrey R.Carter
2023-08-14 16:02 ` Dmitry A. Kazakov
2023-08-15 4:48 ` Micah Waddoups
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox