From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on ip-172-31-65-14.ec2.internal X-Spam-Level: X-Spam-Status: No, score=-1.9 required=3.0 tests=BAYES_00,FREEMAIL_FROM, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Received: by 2002:a05:620a:4886:b0:762:1e66:3920 with SMTP id ea6-20020a05620a488600b007621e663920mr116130qkb.11.1692025802485; Mon, 14 Aug 2023 08:10:02 -0700 (PDT) X-Received: by 2002:a17:90b:4393:b0:263:3437:a0b0 with SMTP id in19-20020a17090b439300b002633437a0b0mr2178472pjb.3.1692025801858; Mon, 14 Aug 2023 08:10:01 -0700 (PDT) Path: eternal-september.org!news.eternal-september.org!2.eu.feeder.erje.net!feeder.erje.net!proxad.net!feeder1-2.proxad.net!209.85.160.216.MISMATCH!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Mon, 14 Aug 2023 08:10:01 -0700 (PDT) In-Reply-To: Injection-Info: google-groups.googlegroups.com; posting-host=65.130.210.206; posting-account=uAiShQoAAABL1dOXlVllWlQArz9o0jAG NNTP-Posting-Host: 65.130.210.206 References: User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: <5290b261-c8d8-4f0a-87f5-941d275a1e6dn@googlegroups.com> Subject: Re: Unifont static compiled and stack size... From: Micah Waddoups Injection-Date: Mon, 14 Aug 2023 15:10:02 +0000 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Xref: news.eternal-september.org comp.lang.ada:65522 List-Id: On Monday, August 14, 2023 at 4:06:39=E2=80=AFAM UTC-6, Jeffrey R.Carter wr= ote: > On 2023-08-13 18:16, Micah Waddoups wrote:=20 > > I tried to compile the Unifont hex file, converted with a script into v= ariable 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=20 > a maximum of 32 bytes per code point. A straightforward representation of= this is=20 >=20 > package Unifont is=20 > type Byte is mod 2 ** 8 with Size =3D> 8;=20 >=20 > type Line is array (1 .. 2) of Byte with Size =3D> 16;=20 >=20 > type Bitmap is array (1 .. 16) of Line with Size =3D> 256;=20 >=20 > function Width_8 (Map : in Bitmap) return Boolean is=20 > (for all L of Map =3D> L (2) =3D 0);=20 >=20 > type Code_Point is mod 16#FFFF# + 1;=20 >=20 > type Font_Map is array (Code_Point) of Bitmap with Size =3D> 2 ** 24;=20 >=20 > Font : constant Font_Map :=3D (others =3D> (others =3D> (others =3D> 0) )= );=20 > end Unifont;=20 >=20 > Font will occupy 2 MB.=20 >=20 > We can test this with=20 >=20 > with Ada.Text_IO;=20 > with Unifont;=20 >=20 > procedure Unifont_Test is=20 > -- Empty=20 > begin -- Unifont_Test=20 > Ada.Text_IO.Put_Line (Item =3D> Unifont.Font (0) (1) (1)'Image);=20 > end Unifont_Test;=20 >=20 > and see what happens:=20 >=20 > $ gnatmake -m -j0 -gnat12 -gnatan -gnato2 -O2 -fstack-check unifont_test.= adb=20 > x86_64-linux-gnu-gcc-12 -c -gnat12 -gnatan -gnato2 -O2 -fstack-check=20 > unifont_test.adb=20 > x86_64-linux-gnu-gcc-12 -c -gnat12 -gnatan -gnato2 -O2 -fstack-check unif= ont.ads=20 > x86_64-linux-gnu-gnatbind-12 -x unifont_test.ali=20 > x86_64-linux-gnu-gnatlink-12 unifont_test.ali -O2 -fstack-check=20 > $ ./unifont_test=20 > 0=20 >=20 > so this representation seems to be workable. It should be trivial to writ= e a=20 > program to read the file and produce the real array aggregate for Font.= =20 >=20 > --=20 > Jeff Carter=20 > "I wave my private parts at your aunties."=20 > Monty Python & the Holy Grail=20 > 13 Thank you all for replying while I was working away from home. =20 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 shoul= d 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 t= he 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 pret= ty big. Good looking code, by the way. Very easy to read. Mine is append= ed, but it was really a quick hack of a job with too little sleep. I proba= bly should have done a Z Shell script (maybe take 20 seconds?), but I thoug= ht 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. T= hank you. Dmitry, Thank you for trying to understand. Since both methods of renderin= g fonts made available by GTK, I consider it GTK providing it. I don't wan= t any more imports than I can provide easily with a static compile or as ac= companying dynamic modules (reason hereafter mentioned), and Licensing need= s to be the most permissive possible. The idea is to be able to create a s= hell 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 othe= r most available options, so the font is important, even if I'm just drawin= g 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 interfac= e 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 c= ollection of code is supposed to support all that with very limited modific= ation to say transfer from Linux to macOS or MS Windows? I hope this s an= swered 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 :=3D "./src/unifont.ads"; Source_Name: String :=3D "unifont_all-15.0.06.hex"; Target: aliased File_Type; Source: aliased File_Type; Buffer: aliased String (1 .. 96) :=3D (others=3D>' '); Index, F: Positive :=3D 1; Previous, Current, Length, L: Natural :=3D 0; Finished: aliased Boolean:=3D False; subtype Hex_Character is Character range '0' .. 'f' with Static_Predicate=3D> (Hex_Character in '0' .. '9') or (Hex_Charac= ter 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 :=3D 0; Byte_X: Byte :=3D 0; function Find (Item: Character) return Natural is begin for N in Buffer'Range loop if Item =3D Buffer(N) then return N; end if; end loop; return 0; end Find; function Enum return Natural is First: Positive :=3D 1; Last: Natural :=3D Integer'Max ((Find (':') -1), 0); begin return R: Natural do R :=3D 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 :=3D 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 H= ex codes in string... line " &Current'Img &", string =3D> " & S; end if; end if; end loop; if S (Index) in Hex_Character and S (Index +1) in Hex_Character then Byte_X :=3D Byte'Value ("16#" &S (Index..Index +1) &"#"); Bit_X :=3D 0; Index :=3D Index +2; end if; end Next_Byte; procedure Next_Line is begin for N in Buffer'First .. Length loop Buffer (N):=3D ' '; end loop; begin Get_Line (Source, Buffer, Length); exception when others =3D> 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:=3D Current; Current:=3D Enum; if ((Previous + 1) =3D Current) or else (Current =3D 0) then F:=3D Find (':') +1; L:=3D Length; Next_Byte; else F:=3D Find (':') +1; L:=3D 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:=3D Y_Type'First; X: aliased X_Type:=3D 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 =3D ((Byte_X / 2 **(7 - Natural(Bit_X))) and 1) then if Bit_X =3D Bit'Last then Next_Byte; else Bit_X :=3D Bit_X +1; end if; return "True"; else if Bit_X =3D Bit'Last then Next_Byte; else Bit_X :=3D Bit_X +1; end if; return "False"; end if; end Dot; Cache_Size: Size_Set_Access :=3D new Size_Set_Type'(others =3D> (16, 8))= ; Size: Size_Set_Type renames Cache_Size.all; begin begin Open (Source, In_File, Source_Name); exception when others =3D> raise Status_Error with " Source File not found: " &Source_Name; end; begin Create (Target, Out_File, Target_Name); exception when others =3D> 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 Wi= de_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 :=3D 1;= X: aliased X_Type :=3D 1; end record;"); Put_Line (Target, "type Size_Set_Type is array (Index_Type) of aliase= d Size_Type;"); Put_Line (Target, "type Glyph_Type is array (Y_Type, X_Type) of Boole= an"); Put_Line (Target, "with Pack, Size=3D> 256;"); Put_Line (Target, "type Glyph_Set_Type is array (Index_Type) of alias= ed Glyph_Type;"); Put_Line (Target, "Glyph: constant Glyph_Set_Type :=3D"); 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) :=3D (16, 16); Put_Line (Target, "Wide_Wide_Character'Val (" &Integer'Image(Cu= rrent) &") =3D>"); Put (Target, "("); for Y in 1 .. 16 loop Put_Line (Target, Y'Img &" =3D>"); 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(Cu= rrent) &") =3D>"); Put (Target, "("); for Y in 1 .. 16 loop Put_Line (Target, Y'Img &" =3D>"); 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 =3D> (others =3D> (others =3D> False)));"); New_Line (Target); Put_Line (Target, "Size: constant Size_Set_Type :=3D"); Put (Target, "("); for N in Index_Type'Range loop Put (Target, "Wide_Wide_Character'Val (" &Integer'Image(N) &") =3D= >"); Put (Target, "(" &Integer'Image(Size(N).Y) &", " &Integer'Image(Si= ze(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;