20030519 release
authorNick Downing <downing.nick@gmail.com>
Mon, 30 Nov 2015 15:36:47 +0000 (02:36 +1100)
committerNick Downing <downing.nick@gmail.com>
Mon, 30 Nov 2015 15:36:47 +0000 (02:36 +1100)
69 files changed:
bin/checksum
bin/font/apibus.hfm [new file with mode: 0644]
bin/font/lcd0.cmd
bin/font/lcd1.cmd
bin/n.ucp
bin/runonce.sh
bin/uzboot.bin
bin/uzboot.gz
bin/uzidisk.dat
relnotes/20030519.txt [new file with mode: 0644]
src/bin/bmp2txt.exe
src/bin/chs2cmd.exe
src/bin/hfmdump.exe [new file with mode: 0644]
src/bin/hfmtool.exe [new file with mode: 0644]
src/bin/txt2chs.exe
src/font/apibus$.txt [new file with mode: 0644]
src/font/apibus%.txt [new file with mode: 0644]
src/font/apibus.hfm [new file with mode: 0644]
src/font/apibus.txt [new file with mode: 0644]
src/font/lcd0.cmd
src/font/lcd1.cmd
src/font/n.bat
src/font/sans-la.psd [new file with mode: 0644]
src/font/sans-sm.psd [new file with mode: 0644]
src/font/sans07b.bmp [new file with mode: 0644]
src/font/sans07c.bmp [new file with mode: 0644]
src/font/sans07r.bmp [new file with mode: 0644]
src/font/sans09r.bmp [new file with mode: 0644]
src/font/sans12r.bmp [new file with mode: 0644]
src/font/sans16r.bmp [new file with mode: 0644]
src/font/serif-la.psd [new file with mode: 0644]
src/font/serif-sm.psd [new file with mode: 0644]
src/font/serif07b.bmp [new file with mode: 0644]
src/font/serif07i.bmp [new file with mode: 0644]
src/font/serif07r.bmp [new file with mode: 0644]
src/font/serif09r.bmp [new file with mode: 0644]
src/font/serif12r.bmp [new file with mode: 0644]
src/font/serif15r.bmp [new file with mode: 0644]
src/mkfont/apibus.hfm [new file with mode: 0644]
src/mkfont/apibus.txt [new file with mode: 0644]
src/mkfont/bmp2txt.cpp
src/mkfont/bmp2txt.exe
src/mkfont/bmp2txt.h [new file with mode: 0644]
src/mkfont/chs2cmd.cpp
src/mkfont/chs2cmd.exe
src/mkfont/chs2cmd.h [new file with mode: 0644]
src/mkfont/hdmlib.c [new file with mode: 0644]
src/mkfont/hdmlib.h [new file with mode: 0644]
src/mkfont/hfmdump.c [new file with mode: 0644]
src/mkfont/hfmdump.exe [new file with mode: 0644]
src/mkfont/hfmlib.c [new file with mode: 0644]
src/mkfont/hfmlib.h [new file with mode: 0644]
src/mkfont/hfmtool.cpp [new file with mode: 0644]
src/mkfont/hfmtool.exe [new file with mode: 0644]
src/mkfont/hycache.cpp [new file with mode: 0644]
src/mkfont/hycache.h [new file with mode: 0644]
src/mkfont/hyfile.cpp
src/mkfont/hyfile.h
src/mkfont/hyfs.h
src/mkfont/hylist.cpp [new file with mode: 0644]
src/mkfont/hylist.h [new file with mode: 0644]
src/mkfont/hymb.h
src/mkfont/hystring.cpp [new file with mode: 0644]
src/mkfont/hystring.h [new file with mode: 0644]
src/mkfont/n.bat
src/mkfont/t.bat [new file with mode: 0644]
src/mkfont/txt2chs.cpp
src/mkfont/txt2chs.exe
src/mkfont/txt2chs.h [new file with mode: 0644]

index 26858fb..0359c1f 100644 (file)
Binary files a/bin/checksum and b/bin/checksum differ
diff --git a/bin/font/apibus.hfm b/bin/font/apibus.hfm
new file mode 100644 (file)
index 0000000..fc1c9f0
Binary files /dev/null and b/bin/font/apibus.hfm differ
index b01407f..2cf784c 100644 (file)
Binary files a/bin/font/lcd0.cmd and b/bin/font/lcd0.cmd differ
index 5e9496d..8128008 100644 (file)
Binary files a/bin/font/lcd1.cmd and b/bin/font/lcd1.cmd differ
index 213a1d2..a05d5fe 100644 (file)
--- a/bin/n.ucp
+++ b/bin/n.ucp
@@ -370,6 +370,7 @@ mkdir tmac
 cd /lib/font\r
 bget font\lcd0.cmd lcd0.cmd\r
 bget font\lcd1.cmd lcd1.cmd\r
+bget font\apibus.hfm apibus.hfm\r
 cd /lib/term\r
 bget term\tab37 tab37\r
 cd /lib/tmac\r
index 73906a5..3c0692c 100644 (file)
@@ -6,6 +6,7 @@ echo ""
 \r
 cp -v /usr/lib/font/lcd0.cmd /dev/lcd0\r
 cp -v /usr/lib/font/lcd1.cmd /dev/lcd1\r
+cp -v /usr/lib/font/apibus.hfm /lib\r
 \r
 umask 022\r
 mkdir /wnd\r
index 4a3da4b..4294bfd 100644 (file)
Binary files a/bin/uzboot.bin and b/bin/uzboot.bin differ
index d98900b..ba5fffb 100644 (file)
Binary files a/bin/uzboot.gz and b/bin/uzboot.gz differ
index 096a219..072c05d 100644 (file)
Binary files a/bin/uzidisk.dat and b/bin/uzidisk.dat differ
diff --git a/relnotes/20030519.txt b/relnotes/20030519.txt
new file mode 100644 (file)
index 0000000..41f3aa5
--- /dev/null
@@ -0,0 +1,82 @@
+HYTECH-INTERNATIONAL BV\r
+CMX/UZI TESTRELEASE FOR SOFTWARE DEPARTMENT 030519SD\r
+\r
+MANIFEST\r
+\r
+-rw-r--r--    1 nick     users     2320458 May 19 19:23 uzipatch.zip\r
+\r
+Please download the files for this release from:\r
+http://www.hytechscales.com/release/nld/test/030519SD\r
+\r
+INTRODUCTION\r
+\r
+Improved support for fonts.  This release should be installed on top of the\r
+previous 030512SD release.  Some files and folders will be added, and several\r
+will be changed.  The loading scripts are slightly revised for the new files.\r
+\r
+INSTALLATION PROCEDURE\r
+\r
+1.  You must already have installed the "/uzi" folder from "uzi.zip" as\r
+described in the notes for the previous release, "030512SD test readme.txt".\r
+\r
+2.  Remove the folder "/uzi/src/mkfont", eg. by renaming to "/uzi/src/mkfont$".\r
+\r
+3.  Remove the folder "/uzi/src/font", eg. by renaming to "/uzi/src/font$".\r
+\r
+4.  Remove the folder "/uzi/src/bin", eg. by renaming to "/uzi/src/bin$".\r
+\r
+5.  If you changed the files "/uzi/bin/runonce.sh" and "/uzi/bin/n.ucp", please\r
+back them up now.  These will be overwritten when you unpack the "uzipatch.zip"\r
+as described here, so you need to combine your changes after the unpacking.  If\r
+you didn't change the files, you can skip this step and go on to step 6.\r
+\r
+6.  Unpack the "uzipatch.zip" with a destination folder of "/uzi".  (If you are\r
+using a Windows based unzipping tool, this should read "c:\uzi" instead).\r
+\r
+7.  If you need to restore the files "/uzi/bin/runonce.sh" and "/uzi/bin/n.ucp"\r
+then please do so.  If you do this, you must run "/uzi/bin/mkboot.bat" and then\r
+run "/uzi/bin/n.bat".  This will rebuild the zipped boot image, and also the\r
+flash card image.  If you didn't change either file, don't bother with this\r
+step, because I already rebuilt the images and included them in "uzipatch.zip".\r
+\r
+DETAILS OF THE HYTECH FONT MANAGER\r
+\r
+This section is not yet complete.  Briefly, you control which fonts are loaded\r
+into which device, via the new font manager script "/uzi/src/font/apibus.txt".\r
+Two sample fontsets are provided, "sans*.bmp" and "serif*.bmp".  To load Nick's\r
+example configuration (sans) you should copy "apibus$.txt" over "apibus.txt"\r
+and issue the "n.bat" command.  To load Nick's example configuration (serif)\r
+you should copy "apibus%.txt" over "apibus.txt" and issue the "n.bat" command.\r
+In each case you can then run "hfmdump apibus.hfm" to list the loaded fonts.\r
+\r
+From the programmatic viewpoint you access the data in the "apibus.hfm" file by\r
+linking to the new "hfmlib.c" routine which I've provided.  This encapsulates\r
+the process of searching for fonts, since it's quite a complicated procedure.\r
+Please see "/uzi/src/mkfont/hfmlib.c" and "/uzi/src/mkfont/hfmlib.h".  Fuller\r
+documentation to follow.  For now, you can get a taste of the new functionality\r
+by running the "hfmdump" command with some parameters.  For example, you could\r
+execute the following steps at your PC based command prompt:\r
+\r
+cd \uzi\src\font\r
+hfmdump apibus.hfm 0 6 9 sans bold\r
+\r
+This will search the fontset that you selected (by editing the apibus.txt file)\r
+and report on whether the font you described is available.  In your code, you\r
+will achieve the same result by calling "hfm_search_family_auto()" followed by\r
+"hfm_search_style_auto()".  The hfmdump utility is provided so that you can\r
+familiarise yourself with the font searching algorithm, and trouble-shoot any\r
+strange responses you might receive when calling the "hfm_search_xxx_auto()"\r
+routines.  It also lets you check you loaded a valid and consistent fontset.\r
+\r
+DETAILS OF THE HYTECH DEVICE MANAGER\r
+\r
+This section is not yet complete.  Briefly, I provided a new module which takes\r
+care of opening and closing the devices (eg. "/dev/lcd0") and encapsulates any\r
+hard coded information needed to do this (eg.  the "/dev/" path names).  The\r
+module is not yet complete, but a sample routine has been provided, please see\r
+"/uzi/src/mkfont/hdmlib.c" function "hdm_select()".  This will send the "esc"\r
+sequence to the customer display or touchscreen which selects a character set.\r
+Joost, I hope you could move some of the "wnd.c" code into "hdmlib.c" as the\r
+development progresses.  In the process it will need to be converted to use the\r
+new function "hdm_putc()" for the output.  Please see the "hdm_select()" code.\r
+\r
index fdf4e30..966e71a 100644 (file)
Binary files a/src/bin/bmp2txt.exe and b/src/bin/bmp2txt.exe differ
index f355dbb..dc24d95 100644 (file)
Binary files a/src/bin/chs2cmd.exe and b/src/bin/chs2cmd.exe differ
diff --git a/src/bin/hfmdump.exe b/src/bin/hfmdump.exe
new file mode 100644 (file)
index 0000000..cd36868
Binary files /dev/null and b/src/bin/hfmdump.exe differ
diff --git a/src/bin/hfmtool.exe b/src/bin/hfmtool.exe
new file mode 100644 (file)
index 0000000..2c5aa4e
Binary files /dev/null and b/src/bin/hfmtool.exe differ
index e5eb754..f151880 100644 (file)
Binary files a/src/bin/txt2chs.exe and b/src/bin/txt2chs.exe differ
diff --git a/src/font/apibus$.txt b/src/font/apibus$.txt
new file mode 100644 (file)
index 0000000..f4da09a
--- /dev/null
@@ -0,0 +1,44 @@
+# apibus.txt\r
+\r
+# bmp2txt infile.bmp [outfile.txt]\r
+bmp2txt sans07r.bmp\r
+bmp2txt sans07b.bmp\r
+bmp2txt sans09r.bmp\r
+bmp2txt sans12r.bmp\r
+bmp2txt sans16r.bmp\r
+bmp2txt sans07c.bmp\r
+\r
+# txt2chs infile.txt [outfile.chs] x_space y_space\r
+txt2chs sans07r.txt 1 3\r
+txt2chs sans07b.txt 1 3\r
+txt2chs sans09r.txt 1 4\r
+txt2chs sans12r.txt 2 5\r
+txt2chs sans16r.txt 2 7\r
+txt2chs sans07c.txt 1 3\r
+\r
+# chs2cmd infile.chs [outfile.cmd] slot\r
+chs2cmd sans07r.chs lcd0.cmd 1\r
+chs2cmd sans07b.chs lcd0.cmd 2\r
+chs2cmd sans09r.chs lcd0.cmd 3\r
+chs2cmd sans12r.chs lcd0.cmd 4\r
+chs2cmd sans16r.chs lcd0.cmd 5\r
+chs2cmd sans07c.chs lcd0.cmd 6\r
+chs2cmd sans07r.chs lcd1.cmd 1\r
+chs2cmd sans07b.chs lcd1.cmd 2\r
+chs2cmd sans09r.chs lcd1.cmd 3\r
+chs2cmd sans12r.chs lcd1.cmd 4\r
+chs2cmd sans16r.chs lcd1.cmd 5\r
+\r
+# chs2hfm infile.chs device slot family style\r
+chs2hfm sans07r.chs 0 1 sans regular\r
+chs2hfm sans07b.chs 0 2 sans bold\r
+chs2hfm sans09r.chs 0 3 sans regular\r
+chs2hfm sans12r.chs 0 4 sans regular\r
+chs2hfm sans16r.chs 0 5 sans regular\r
+chs2hfm sans07c.chs 0 6 sans condensed\r
+chs2hfm sans07r.chs 1 1 sans regular\r
+chs2hfm sans07b.chs 1 2 sans bold\r
+chs2hfm sans09r.chs 1 3 sans regular\r
+chs2hfm sans12r.chs 1 4 sans regular\r
+chs2hfm sans16r.chs 1 5 sans regular\r
+\r
diff --git a/src/font/apibus%.txt b/src/font/apibus%.txt
new file mode 100644 (file)
index 0000000..6c2dce1
--- /dev/null
@@ -0,0 +1,44 @@
+# apibus.txt\r
+\r
+# bmp2txt infile.bmp [outfile.txt]\r
+bmp2txt serif07r.bmp\r
+bmp2txt serif07b.bmp\r
+bmp2txt serif09r.bmp\r
+bmp2txt serif12r.bmp\r
+bmp2txt serif15r.bmp\r
+bmp2txt serif07i.bmp\r
+\r
+# txt2chs infile.txt [outfile.chs] x_space y_space\r
+txt2chs serif07r.txt 1 3\r
+txt2chs serif07b.txt 1 3\r
+txt2chs serif09r.txt 1 4\r
+txt2chs serif12r.txt 2 5\r
+txt2chs serif15r.txt 2 7\r
+txt2chs serif07i.txt 1 3\r
+\r
+# chs2cmd infile.chs [outfile.cmd] slot\r
+chs2cmd serif07r.chs lcd0.cmd 1\r
+chs2cmd serif07b.chs lcd0.cmd 2\r
+chs2cmd serif09r.chs lcd0.cmd 3\r
+chs2cmd serif12r.chs lcd0.cmd 4\r
+chs2cmd serif15r.chs lcd0.cmd 5\r
+chs2cmd serif07i.chs lcd0.cmd 6\r
+chs2cmd serif07r.chs lcd1.cmd 1\r
+chs2cmd serif07b.chs lcd1.cmd 2\r
+chs2cmd serif09r.chs lcd1.cmd 3\r
+chs2cmd serif12r.chs lcd1.cmd 4\r
+chs2cmd serif15r.chs lcd1.cmd 5\r
+\r
+# chs2hfm infile.chs device slot family style\r
+chs2hfm serif07r.chs 0 1 serif regular\r
+chs2hfm serif07b.chs 0 2 serif bold\r
+chs2hfm serif09r.chs 0 3 serif regular\r
+chs2hfm serif12r.chs 0 4 serif regular\r
+chs2hfm serif15r.chs 0 5 serif regular\r
+chs2hfm serif07i.chs 0 6 serif italic\r
+chs2hfm serif07r.chs 1 1 serif regular\r
+chs2hfm serif07b.chs 1 2 serif bold\r
+chs2hfm serif09r.chs 1 3 serif regular\r
+chs2hfm serif12r.chs 1 4 serif regular\r
+chs2hfm serif15r.chs 1 5 serif regular\r
+\r
diff --git a/src/font/apibus.hfm b/src/font/apibus.hfm
new file mode 100644 (file)
index 0000000..fc1c9f0
Binary files /dev/null and b/src/font/apibus.hfm differ
diff --git a/src/font/apibus.txt b/src/font/apibus.txt
new file mode 100644 (file)
index 0000000..f4da09a
--- /dev/null
@@ -0,0 +1,44 @@
+# apibus.txt\r
+\r
+# bmp2txt infile.bmp [outfile.txt]\r
+bmp2txt sans07r.bmp\r
+bmp2txt sans07b.bmp\r
+bmp2txt sans09r.bmp\r
+bmp2txt sans12r.bmp\r
+bmp2txt sans16r.bmp\r
+bmp2txt sans07c.bmp\r
+\r
+# txt2chs infile.txt [outfile.chs] x_space y_space\r
+txt2chs sans07r.txt 1 3\r
+txt2chs sans07b.txt 1 3\r
+txt2chs sans09r.txt 1 4\r
+txt2chs sans12r.txt 2 5\r
+txt2chs sans16r.txt 2 7\r
+txt2chs sans07c.txt 1 3\r
+\r
+# chs2cmd infile.chs [outfile.cmd] slot\r
+chs2cmd sans07r.chs lcd0.cmd 1\r
+chs2cmd sans07b.chs lcd0.cmd 2\r
+chs2cmd sans09r.chs lcd0.cmd 3\r
+chs2cmd sans12r.chs lcd0.cmd 4\r
+chs2cmd sans16r.chs lcd0.cmd 5\r
+chs2cmd sans07c.chs lcd0.cmd 6\r
+chs2cmd sans07r.chs lcd1.cmd 1\r
+chs2cmd sans07b.chs lcd1.cmd 2\r
+chs2cmd sans09r.chs lcd1.cmd 3\r
+chs2cmd sans12r.chs lcd1.cmd 4\r
+chs2cmd sans16r.chs lcd1.cmd 5\r
+\r
+# chs2hfm infile.chs device slot family style\r
+chs2hfm sans07r.chs 0 1 sans regular\r
+chs2hfm sans07b.chs 0 2 sans bold\r
+chs2hfm sans09r.chs 0 3 sans regular\r
+chs2hfm sans12r.chs 0 4 sans regular\r
+chs2hfm sans16r.chs 0 5 sans regular\r
+chs2hfm sans07c.chs 0 6 sans condensed\r
+chs2hfm sans07r.chs 1 1 sans regular\r
+chs2hfm sans07b.chs 1 2 sans bold\r
+chs2hfm sans09r.chs 1 3 sans regular\r
+chs2hfm sans12r.chs 1 4 sans regular\r
+chs2hfm sans16r.chs 1 5 sans regular\r
+\r
index b01407f..2cf784c 100644 (file)
Binary files a/src/font/lcd0.cmd and b/src/font/lcd0.cmd differ
index 5e9496d..8128008 100644 (file)
Binary files a/src/font/lcd1.cmd and b/src/font/lcd1.cmd differ
index 754176f..6e531d5 100644 (file)
@@ -1,27 +1,6 @@
-bmp2txt set01.bmp\r
-bmp2txt set02.bmp\r
-bmp2txt set03.bmp\r
-bmp2txt set04.bmp\r
-bmp2txt set05.bmp\r
-bmp2txt set06.bmp\r
-\r
-txt2chs set01.txt 1 3\r
-txt2chs set02.txt 1 3\r
-txt2chs set03.txt 1 4\r
-txt2chs set04.txt 2 5\r
-txt2chs set05.txt 2 7\r
-txt2chs set06.txt 1 3\r
-\r
-chs2cmd set01.chs 1\r
-chs2cmd set02.chs 2\r
-chs2cmd set03.chs 3\r
-chs2cmd set04.chs 4\r
-chs2cmd set05.chs 5\r
-chs2cmd set06.chs 6\r
-\r
-copy/b set01.cmd+set02.cmd+set03.cmd+set04.cmd+set05.cmd+set06.cmd lcd0.cmd\r
-copy/b set01.cmd+set02.cmd+set03.cmd+set04.cmd+set05.cmd lcd1.cmd\r
+hfmtool apibus.txt\r
 \r
 copy lcd0.cmd ..\..\bin\font\r
 copy lcd1.cmd ..\..\bin\font\r
+copy apibus.hfm ..\..\bin\font\r
 \r
diff --git a/src/font/sans-la.psd b/src/font/sans-la.psd
new file mode 100644 (file)
index 0000000..7387125
Binary files /dev/null and b/src/font/sans-la.psd differ
diff --git a/src/font/sans-sm.psd b/src/font/sans-sm.psd
new file mode 100644 (file)
index 0000000..1b3a4c0
Binary files /dev/null and b/src/font/sans-sm.psd differ
diff --git a/src/font/sans07b.bmp b/src/font/sans07b.bmp
new file mode 100644 (file)
index 0000000..fb7957c
Binary files /dev/null and b/src/font/sans07b.bmp differ
diff --git a/src/font/sans07c.bmp b/src/font/sans07c.bmp
new file mode 100644 (file)
index 0000000..bb81922
Binary files /dev/null and b/src/font/sans07c.bmp differ
diff --git a/src/font/sans07r.bmp b/src/font/sans07r.bmp
new file mode 100644 (file)
index 0000000..93fcf72
Binary files /dev/null and b/src/font/sans07r.bmp differ
diff --git a/src/font/sans09r.bmp b/src/font/sans09r.bmp
new file mode 100644 (file)
index 0000000..da370f5
Binary files /dev/null and b/src/font/sans09r.bmp differ
diff --git a/src/font/sans12r.bmp b/src/font/sans12r.bmp
new file mode 100644 (file)
index 0000000..6976af9
Binary files /dev/null and b/src/font/sans12r.bmp differ
diff --git a/src/font/sans16r.bmp b/src/font/sans16r.bmp
new file mode 100644 (file)
index 0000000..99da9a7
Binary files /dev/null and b/src/font/sans16r.bmp differ
diff --git a/src/font/serif-la.psd b/src/font/serif-la.psd
new file mode 100644 (file)
index 0000000..cec02e8
Binary files /dev/null and b/src/font/serif-la.psd differ
diff --git a/src/font/serif-sm.psd b/src/font/serif-sm.psd
new file mode 100644 (file)
index 0000000..1b0db63
Binary files /dev/null and b/src/font/serif-sm.psd differ
diff --git a/src/font/serif07b.bmp b/src/font/serif07b.bmp
new file mode 100644 (file)
index 0000000..c638dbc
Binary files /dev/null and b/src/font/serif07b.bmp differ
diff --git a/src/font/serif07i.bmp b/src/font/serif07i.bmp
new file mode 100644 (file)
index 0000000..8f91755
Binary files /dev/null and b/src/font/serif07i.bmp differ
diff --git a/src/font/serif07r.bmp b/src/font/serif07r.bmp
new file mode 100644 (file)
index 0000000..2349831
Binary files /dev/null and b/src/font/serif07r.bmp differ
diff --git a/src/font/serif09r.bmp b/src/font/serif09r.bmp
new file mode 100644 (file)
index 0000000..2e23d9f
Binary files /dev/null and b/src/font/serif09r.bmp differ
diff --git a/src/font/serif12r.bmp b/src/font/serif12r.bmp
new file mode 100644 (file)
index 0000000..4ead20c
Binary files /dev/null and b/src/font/serif12r.bmp differ
diff --git a/src/font/serif15r.bmp b/src/font/serif15r.bmp
new file mode 100644 (file)
index 0000000..a215ecd
Binary files /dev/null and b/src/font/serif15r.bmp differ
diff --git a/src/mkfont/apibus.hfm b/src/mkfont/apibus.hfm
new file mode 100644 (file)
index 0000000..bb9647a
Binary files /dev/null and b/src/mkfont/apibus.hfm differ
diff --git a/src/mkfont/apibus.txt b/src/mkfont/apibus.txt
new file mode 100644 (file)
index 0000000..07a312a
--- /dev/null
@@ -0,0 +1,44 @@
+# apibus.txt\r
+\r
+# bmp2txt infile.bmp [outfile.txt]\r
+bmp2txt set01.bmp\r
+bmp2txt set02.bmp\r
+bmp2txt set03.bmp\r
+bmp2txt set04.bmp\r
+bmp2txt set05.bmp\r
+bmp2txt set06.bmp\r
+\r
+# txt2chs infile.txt [outfile.chs] x_space y_space\r
+txt2chs set01.txt 1 3\r
+txt2chs set02.txt 1 3\r
+txt2chs set03.txt 1 4\r
+txt2chs set04.txt 2 5\r
+txt2chs set05.txt 2 7\r
+txt2chs set06.txt 1 3\r
+\r
+# chs2cmd infile.chs [outfile.cmd] slot\r
+chs2cmd set01.chs lcd0.cmd 1\r
+chs2cmd set02.chs lcd0.cmd 2\r
+chs2cmd set03.chs lcd0.cmd 3\r
+chs2cmd set04.chs lcd0.cmd 4\r
+chs2cmd set05.chs lcd0.cmd 5\r
+chs2cmd set06.chs lcd0.cmd 6\r
+chs2cmd set01.chs lcd1.cmd 1\r
+chs2cmd set02.chs lcd1.cmd 2\r
+chs2cmd set03.chs lcd1.cmd 3\r
+chs2cmd set04.chs lcd1.cmd 4\r
+chs2cmd set05.chs lcd1.cmd 5\r
+\r
+# chs2hfm infile.chs device slot family style\r
+chs2hfm set01.chs 0 1 sans regular\r
+chs2hfm set02.chs 0 2 sans bold\r
+chs2hfm set03.chs 0 3 sans regular\r
+chs2hfm set04.chs 0 4 sans regular\r
+chs2hfm set05.chs 0 5 sans regular\r
+chs2hfm set06.chs 0 6 sans condensed\r
+chs2hfm set01.chs 1 1 sans regular\r
+chs2hfm set02.chs 1 2 sans bold\r
+chs2hfm set03.chs 1 3 sans regular\r
+chs2hfm set04.chs 1 4 sans regular\r
+chs2hfm set05.chs 1 5 sans regular\r
+\r
index 2612200..73d1000 100644 (file)
@@ -7,29 +7,75 @@
 #include <string.h>\r
 #include <windows.h>\r
 #pragma hdrstop\r
+\r
+#ifndef DEBUG\r
+#define DEBUG 0\r
+#endif\r
+\r
 #include "hymb.h"\r
 #include "hyfs.h"\r
 #include "hyfile.h"\r
 #include "hyimage.h"\r
+#include "hylist.h"\r
+#include "hycache.h"\r
+#include "bmp2txt.h"\r
+\r
+// ----------------------------------------------------------------------------\r
+// local preprocessor definitions\r
+\r
+#define LINE_MAX       0x200\r
+#define PATH_MAX       0x200\r
 \r
+#define CACHE_MAX      0x10 // note:  this is smaller than hfmtool's setting\r
+\r
+#define OUTPUT_BUFFER  0x100000 // to create output files of up to 1 Megabyte\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+#ifdef STANDALONE\r
 int main(int argc, char **argv);\r
-int fiProcess(FILETAG *pftOut, BMPTAG *pbtIn);\r
+#endif\r
+static int fiProcess(FILETAG *pftOut, BMPTAG *pbtIn);\r
 \r
 // ----------------------------------------------------------------------------\r
 \r
-BMPTAG btIn;\r
-char *pszInFileName;\r
+#ifdef STANDALONE\r
+int main(int argc, char **argv)\r
+       {\r
+       int i;\r
+        LISTTAG ltCache;\r
+\r
+       // set up the cache to track intermediate memory files\r
+        CacheEntrySetup(&ltCache, CACHE_MAX);\r
 \r
-FILETAG ftOut;\r
-char *pszOutFileName;\r
-char szOutFileName[512];\r
+       // run the real program, passing in the cache descriptor\r
+       i = iBmp2Txt(&ltCache, argc, argv);\r
+\r
+       // it just goes on and on my friend\r
+       CacheExitFlush(&ltCache, 3); // force writing of intermediate files\r
+       CacheExitCleanup(&ltCache); // deallocate memory, though it's redundant\r
+\r
+       return i;\r
+       }\r
+#endif\r
 \r
 // ----------------------------------------------------------------------------\r
 \r
-int main(int argc, char **argv)\r
+int iBmp2Txt(LISTTAG *pltCache, int argc, char **argv)\r
        {\r
        int i;\r
 \r
+       BMPTAG btIn;\r
+       char *pszInFileName;\r
+\r
+       int iCacheOut;\r
+       FILETAG *pftOut;\r
+       char *pszOutFileName;\r
+       char szOutFileName[PATH_MAX];\r
+\r
+       pszInFileName = NULL;\r
+       pszOutFileName = NULL;\r
+\r
        if (argc > 1)\r
                {\r
                pszInFileName = argv[1];\r
@@ -85,27 +131,27 @@ int main(int argc, char **argv)
               btIn.iSampleAppend);\r
 \r
        // prepare an output buffer for character set data\r
-       FileAllocate(&ftOut, 0x100000); // 64 kbytes\r
+       CacheAllocate(pltCache, &iCacheOut, OUTPUT_BUFFER);\r
+       pftOut = pftCacheItem(pltCache, iCacheOut);\r
 \r
        // search for characters and write character set files\r
-       if (fiProcess(&ftOut, &btIn) == FALSE)\r
+       if (fiProcess(pftOut, &btIn) == FALSE)\r
                {\r
                exit(1);\r
                }\r
 \r
        // ready to write the output we found\r
-       FileWriteOut(&ftOut, pszOutFileName);\r
+       CacheWriteOut(pltCache, iCacheOut, pszOutFileName);\r
 \r
-       // all done my friend\r
+       // some people started singing it not knowing what it was\r
        BmpFree(&btIn);\r
-       FileFree(&ftOut);\r
 \r
        return 0;\r
        }\r
 \r
 // ----------------------------------------------------------------------------\r
 \r
-int fiProcess(FILETAG *pftOut, BMPTAG *pbtIn)\r
+static int fiProcess(FILETAG *pftOut, BMPTAG *pbtIn)\r
        {\r
        int m, x, y, t;\r
        int i, j, k, l;\r
index fdf4e30..966e71a 100644 (file)
Binary files a/src/mkfont/bmp2txt.exe and b/src/mkfont/bmp2txt.exe differ
diff --git a/src/mkfont/bmp2txt.h b/src/mkfont/bmp2txt.h
new file mode 100644 (file)
index 0000000..0fb2988
--- /dev/null
@@ -0,0 +1,9 @@
+// bmp2txt.h by Nick for Hytech Font Metrics system\r
+\r
+#ifndef _INC_BMP2TXT\r
+#define _INC_BMP2TXT\r
+\r
+int iBmp2Txt(LISTTAG *pltCache, int argc, char **argv);\r
+\r
+#endif\r
+\r
index 4a2af96..2580eea 100644 (file)
 #include <stdlib.h>\r
 #include <windows.h>\r
 #pragma hdrstop\r
+\r
+#ifndef DEBUG\r
+#define DEBUG 0\r
+#endif\r
+\r
 #include "hymb.h"\r
 #include "hyfs.h"\r
 #include "hyfile.h"\r
+#include "hylist.h"\r
+#include "hycache.h"\r
+#include "chs2cmd.h"\r
+\r
+// ----------------------------------------------------------------------------\r
+// local preprocessor definitions\r
+\r
+#define LINE_MAX       0x200\r
+#define PATH_MAX       0x200\r
+\r
+#define CACHE_MAX      0x10 // note:  this is smaller than hfmtool's setting\r
 \r
+#define OUTPUT_BUFFER  0x10000 // to create output files of up to 64 kbytes\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+#ifdef STANDALONE\r
 int main(int argc, char **argv);\r
-int fiProcess(FILETAG *ftOut, FILETAG *ftIn, int iICS, int iILS);\r
-int iCompare(const void *pvLeft, const void *pvRight);\r
-int iUpdateCRC(char *pcBase, int iCount, int iCRC);\r
+#endif\r
+static int fiProcess(FILETAG *pftOut, FILETAG *pftIn, int iSlot);\r
 \r
 // ----------------------------------------------------------------------------\r
 \r
-FILETAG ftIn;\r
-char *pszInFileName;\r
+#ifdef STANDALONE\r
+int main(int argc, char **argv)\r
+       {\r
+       int i;\r
+        LISTTAG ltCache;\r
+\r
+       // set up the cache to track intermediate memory files\r
+        CacheEntrySetup(&ltCache, CACHE_MAX);\r
+\r
+       // run the real program, passing in the cache descriptor\r
+       i = iChs2Cmd(&ltCache, argc, argv);\r
+\r
+       // it just goes on and on my friend\r
+       CacheExitFlush(&ltCache, 3); // force writing of intermediate files\r
+       CacheExitCleanup(&ltCache); // deallocate memory, though it's redundant\r
 \r
-FILETAG ftOut;\r
-char *pszOutFileName;\r
-char szOutFileName[512];\r
+       return i;\r
+       }\r
+#endif\r
 \r
 // ----------------------------------------------------------------------------\r
 \r
-int main(int argc, char **argv)\r
+int iChs2Cmd(LISTTAG *pltCache, int argc, char **argv)\r
        {\r
-       int i, iSetNo;\r
+       int i, iSlot;\r
+#if 0 // modification so that we will append to files cached earlier\r
+       CACHETAG *pct;\r
+#endif\r
+\r
+       int iCacheIn;\r
+       FILETAG *pftIn;\r
+       char *pszInFileName;\r
+\r
+       int iCacheOut;\r
+       FILETAG *pftOut;\r
+       char *pszOutFileName;\r
+       char szOutFileName[PATH_MAX];\r
+\r
+       pszInFileName = NULL;\r
+       pszOutFileName = NULL;\r
 \r
        if (argc > 1)\r
                {\r
                pszInFileName = argv[1];\r
                }\r
 \r
-       iSetNo = 0;\r
+       iSlot = 0;\r
        if (argc > 2)\r
                {\r
-               iSetNo = atoi(argv[2]);\r
-               if (iSetNo < 1 || iSetNo > 0xff)\r
+               iSlot = atoi(argv[2]);\r
+               if (iSlot < 1 || iSlot > 0xff)\r
                        {\r
                        pszOutFileName = argv[2];\r
                        if (argc > 3)\r
                                {\r
-                               iSetNo = atoi(argv[3]);\r
+                               iSlot = atoi(argv[3]);\r
                                }\r
                        }\r
                }\r
 \r
        if (pszInFileName == NULL)\r
                {\r
-               printf("usage: chs2cmd infile.txt [outfile.cmd] [setno]\n");\r
+               printf("usage: chs2cmd infile.txt [outfile.cmd] [slot]\n");\r
+\r
                exit(1);\r
                }\r
 \r
@@ -79,31 +128,84 @@ int main(int argc, char **argv)
                strcat(pszOutFileName, ".cmd");\r
                }\r
 \r
-       if (!strcmp(pszInFileName, pszOutFileName))\r
+       if (strcmp(pszInFileName, pszOutFileName) == 0)\r
                {\r
                printf("Input and output filenames identical\n");\r
                exit(1);\r
                }\r
 \r
-       // read the input bmp file entirely to a malloc'd block\r
-       FileReadIn(&ftIn, pszInFileName);\r
+       // read the input chs file entirely to a malloc'd block\r
+       CacheReadIn(pltCache, &iCacheIn, pszInFileName);\r
+       pftIn = pftCacheItem(pltCache, iCacheIn);\r
+\r
+#if 1 // modification so that we will append to files cached earlier\r
+       if (fiCacheSearch(pltCache, &iCacheOut, pszOutFileName))\r
+               {\r
+               // the file was found in the cache, assume block is oversized\r
+               }\r
+       else\r
+               {\r
+               CacheAllocate(pltCache, &iCacheOut, OUTPUT_BUFFER);\r
+               }\r
+       pftOut = pftCacheItem(pltCache, iCacheOut);\r
+\r
+       // append esc plus character set data to output buffer\r
+       if (fiProcess(pftOut, pftIn, iSlot) == FALSE)\r
+               {\r
+               exit(1);\r
+               }\r
+#else\r
+       // grab an unallocated cache entry for FileCopyPadded()\r
+       iCacheOut = pltCache->iItemAppend; // this must be done first\r
+       pct = (CACHETAG *) pcListPut(pltCache); // this will bomb if full\r
+       pct->iDirty = 1; // emulate the action of CacheAllocate()\r
+       pftOut = &pct->ft; // emulate the action of pftCacheItem()\r
 \r
        // create output buffer with esc plus character set data\r
-       FileCopyPadded(&ftOut, &ftIn, 5, 0);\r
-       ftOut.pcBase[0] = 0x1b;\r
-       ftOut.pcBase[1] = '.';\r
-       ftOut.pcBase[2] = iSetNo + '0';\r
-       *(short *)&ftOut.pcBase[3] = ftIn.pcAppend - ftIn.pcBase;\r
+       FileCopyPadded(pftOut, pftIn, 5, 0);\r
+       pftOut->pcBase[0] = 0x1b;\r
+       pftOut->pcBase[1] = '.';\r
+       pftOut->pcBase[2] = iSlot + '0';\r
+       *(short *)&pftOut->pcBase[3] = iFileSize(pftIn);\r
+#endif\r
 \r
        // ready to write the output we found\r
-       FileWriteOut(&ftOut, pszOutFileName);\r
-\r
-       // all done my friend\r
-       FileFree(&ftIn);\r
-       FileFree(&ftOut);\r
+       CacheWriteOut(pltCache, iCacheOut, pszOutFileName);\r
+       pctCacheItem(pltCache, iCacheOut)->iDirty = 4; // extra dirty\r
 \r
+       // it's the song that doesn't end\r
        return 0;\r
        }\r
 \r
 // ----------------------------------------------------------------------------\r
 \r
+static int fiProcess(FILETAG *pftOut, FILETAG *pftIn, int iSlot)\r
+       {\r
+       char *pc;\r
+       int iSizeIn, iSizeOut;\r
+\r
+       // append esc plus character set data to output buffer\r
+       iSizeIn = iFileSize(pftIn);\r
+       iSizeOut = 5 + iSizeIn;\r
+\r
+       if (pftOut->pcAppend + iSizeOut > pftOut->pcLimit)\r
+               {\r
+               printf("No room left to append output file\n");\r
+               return FALSE;\r
+               }\r
+\r
+       pc = pftOut->pcAppend;\r
+\r
+       pc[0] = 0x1b;\r
+       pc[1] = '.';\r
+       pc[2] = iSlot + '0';\r
+       *(short *)&pc[3] = iSizeIn;\r
+\r
+       memcpy(&pc[5], pftIn->pcBase, iSizeIn);\r
+\r
+       pftOut->pcAppend += iSizeOut;\r
+       return TRUE;\r
+       }\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
index f355dbb..dc24d95 100644 (file)
Binary files a/src/mkfont/chs2cmd.exe and b/src/mkfont/chs2cmd.exe differ
diff --git a/src/mkfont/chs2cmd.h b/src/mkfont/chs2cmd.h
new file mode 100644 (file)
index 0000000..63f38be
--- /dev/null
@@ -0,0 +1,9 @@
+// chs2cmd.h by Nick for Hytech Font Metrics system\r
+\r
+#ifndef _INC_CHS2CMD\r
+#define _INC_CHS2CMD\r
+\r
+int iChs2Cmd(LISTTAG *pltCache, int argc, char **argv);\r
+\r
+#endif\r
+\r
diff --git a/src/mkfont/hdmlib.c b/src/mkfont/hdmlib.c
new file mode 100644 (file)
index 0000000..3f09344
--- /dev/null
@@ -0,0 +1,93 @@
+/* hdmlib.c by Nick for Hytech Device Manager system */\r
+\r
+/* ------------------------------------------------------------------------- */\r
+/* header and preprocessor directives */\r
+\r
+#include <stdio.h>\r
+#include <malloc.h>\r
+\r
+#include "hfmlib.h"\r
+#include "hdmlib.h"\r
+\r
+#ifndef TRUE\r
+#define TRUE 1\r
+#endif\r
+\r
+#ifndef FALSE\r
+#define FALSE 0\r
+#endif\r
+\r
+/* ------------------------------------------------------------------------- */\r
+/* global variables */\r
+\r
+/* note:  the library is allowed exactly 1 global variable, which must be of */\r
+/* pointer type.  if there is a need for more, we must implement a global_t */\r
+\r
+hdm_t *hdm;\r
+\r
+/* ------------------------------------------------------------------------- */\r
+/* exported functions */\r
+\r
+int hdm_open(void)\r
+       {\r
+       FILE *stream;\r
+\r
+       if (hdm)\r
+               {\r
+               fprintf(stderr, HDM_PATH_LCD0 ": already open\n");\r
+               return FALSE;\r
+               }\r
+\r
+       stream = fopen(HDM_PATH_LCD0, "rw");\r
+       if (stream == NULL)\r
+               {\r
+               perror(HDM_PATH_LCD0);\r
+               return FALSE;\r
+               }\r
+\r
+       hdm = malloc(sizeof(hdm_t));\r
+       if (hdm == NULL)\r
+               {\r
+               fprintf(stderr, HDM_PATH_LCD0 ": out of memory\n");\r
+               return FALSE;\r
+               }\r
+\r
+       hdm->hdm_stream[HDM_DEVICE_LCD0] = stream;\r
+       hdm->hdm_stream[HDM_DEVICE_LCD1] = fopen(HDM_PATH_LCD1, "rw");\r
+       hdm->hdm_stream[HDM_DEVICE_LPR0] = fopen(HDM_PATH_LPR0, "rw");\r
+       return TRUE;\r
+       }\r
+\r
+void hdm_close(void)\r
+       {\r
+       if (hdm)\r
+               {\r
+               fclose(hdm->hdm_stream[HDM_DEVICE_LCD0]);\r
+               fclose(hdm->hdm_stream[HDM_DEVICE_LCD1]);\r
+               fclose(hdm->hdm_stream[HDM_DEVICE_LPR0]);\r
+\r
+               free(hdm);\r
+               hdm = NULL;\r
+               }\r
+       }\r
+\r
+/* ------------------------------------------------------------------------- */\r
+\r
+void hdm_select(int device, int slot)\r
+       {\r
+       hdm_putc(device, 0x1b);\r
+       hdm_putc(device, '0' + slot);\r
+       }\r
+\r
+int hdm_print_in_field(int device, int slot, char *string,\r
+                      int field_width, int *width_ret)\r
+       {\r
+       int count;\r
+\r
+       count = hfm_count_in_field(device, slot, string,\r
+                                  field_width, width_ret);\r
+       return hdm_write(device, string, count);\r
+       }\r
+\r
+/* ------------------------------------------------------------------------- */\r
+\r
diff --git a/src/mkfont/hdmlib.h b/src/mkfont/hdmlib.h
new file mode 100644 (file)
index 0000000..c6d24b5
--- /dev/null
@@ -0,0 +1,61 @@
+/* hdmlib.h by Nick for Hytech Device Manager system */\r
+\r
+/* ------------------------------------------------------------------------- */\r
+/* preprocessor definitions */\r
+\r
+#define HDM_DEVICES 3\r
+\r
+#define HDM_DEVICE_LCD0 0\r
+#define HDM_DEVICE_LCD1 1\r
+#define HDM_DEVICE_LPR0 2\r
+\r
+#define HDM_PATH_LCD0 "/dev/lcd0"\r
+#define HDM_PATH_LCD1 "/dev/lcd1"\r
+#define HDM_PATH_LPR0 "/dev/lpr0"\r
+\r
+/* ------------------------------------------------------------------------- */\r
+/* struct and type definitions */\r
+\r
+typedef struct s_hdm\r
+       {\r
+       FILE *hdm_stream[HDM_DEVICES];\r
+       } hdm_t;\r
+\r
+/* ------------------------------------------------------------------------- */\r
+/* exported function prototypes */\r
+\r
+int hdm_open(void);\r
+void hdm_close(void);\r
+\r
+void hdm_select(int device, int slot);\r
+int hdm_print_in_field(int device, int slot, char *string,\r
+                      int field_width, int *width_ret);\r
+\r
+/* ------------------------------------------------------------------------- */\r
+/* exported inline functions */\r
+\r
+#define hdm_getc(device) \\r
+       fgetc(hdm->hdm_stream[(device)])\r
+\r
+#define hdm_putc(device, value) \\r
+       fputc((value), hdm->hdm_stream[(device)])\r
+\r
+#define hdm_read(device, buffer, count) \\r
+       fread((buffer), (count), sizeof(char), hdm->hdm_stream[(device)])\r
+\r
+#define hdm_write(device, buffer, count) \\r
+       fwrite((buffer), (count), sizeof(char), hdm->hdm_stream[(device)])\r
+\r
+#define hdm_print(device, buffer) \\r
+       fputs((buffer), hdm->hdm_stream[(device)])\r
+\r
+#define hdm_flush(device) \\r
+       fflush(hdm->hdm_stream[(device)])\r
+\r
+/* ------------------------------------------------------------------------- */\r
+/* exported global variables */\r
+\r
+extern hdm_t *hdm;\r
+\r
+/* ------------------------------------------------------------------------- */\r
+\r
diff --git a/src/mkfont/hfmdump.c b/src/mkfont/hfmdump.c
new file mode 100644 (file)
index 0000000..f829eec
--- /dev/null
@@ -0,0 +1,308 @@
+/* hfmdump.c by Nick for Hytech Font Manager system */\r
+\r
+/* ------------------------------------------------------------------------- */\r
+/* header and preprocessor directives */\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+#ifndef DEBUG\r
+#define DEBUG 0\r
+#endif\r
+\r
+#include "hfmlib.h"\r
+\r
+#ifndef TRUE\r
+#define TRUE 1\r
+#endif\r
+\r
+#ifndef FALSE\r
+#define FALSE 0\r
+#endif\r
+\r
+#define FONT_MAX       0x100\r
+\r
+/* ------------------------------------------------------------------------- */\r
+/* function prototypes */\r
+\r
+int main(int argc, char **argv);\r
+static int walk_tree(void);\r
+static int try_query(void);\r
+\r
+/* ------------------------------------------------------------------------- */\r
+/* global variables */\r
+\r
+int family_found[FONT_MAX];\r
+int height_found[FONT_MAX];\r
+int style_found[FONT_MAX]; /* note:  too many fonts in .hfm will cause crash */\r
+\r
+int query, device, height_min, height_max, family, style;\r
+\r
+/* ------------------------------------------------------------------------- */\r
+\r
+int main(int argc, char **argv)\r
+       {\r
+       if (argc < 2)\r
+               {\r
+               printf("usage: hfmdump infile.hfm"\r
+                      " [device height_min height_max family style]\n");\r
+               return 1;\r
+               }\r
+\r
+       if (argc < 3)\r
+               {\r
+               query = 0;\r
+               }\r
+       else if (argc == 7)\r
+               {\r
+               query = 1;\r
+\r
+               device = atoi(argv[2]);\r
+               height_min = atoi(argv[3]);\r
+               height_max = atoi(argv[4]);\r
+\r
+               family = hfm_family_string_to_int(argv[5]);\r
+               if (family < 0)\r
+                       {\r
+                       printf("Family must be one of:\n"\r
+                              "\t" HFMSTR_SANS "\n"\r
+                              "\t" HFMSTR_SERIF "\n");\r
+                       return 1;\r
+                       }\r
+\r
+               style = hfm_style_string_to_int(argv[6]);\r
+               if (style < 0)\r
+                       {\r
+                       printf("Style must be one of:\n"\r
+                              "\t" HFMSTR_CONDENSED "\n"\r
+                              "\t" HFMSTR_REGULAR "\n"\r
+                              "\t" HFMSTR_BOLD "\n"\r
+                              "\t" HFMSTR_ITALIC "\n"\r
+                              "\t" HFMSTR_UNDERLINE "\n");\r
+                       return 1;\r
+                       }\r
+               }\r
+       else\r
+               {\r
+               printf("Invalid number of parameters\n");\r
+               return 1;\r
+               }\r
+\r
+       if (hfm_load(argv[1]) == FALSE)\r
+               {\r
+               return 1;\r
+               }\r
+\r
+       if (walk_tree() == FALSE)\r
+               {\r
+               hfm_free();\r
+               return 1;\r
+               }\r
+\r
+       if (query && try_query() == FALSE)\r
+               {\r
+               hfm_free();\r
+               return 1;\r
+               }\r
+\r
+       hfm_free();\r
+       return 0;\r
+       }\r
+\r
+/* ------------------------------------------------------------------------- */\r
+\r
+static int walk_tree(void)\r
+       {\r
+       hfm_device_t *hfmd;\r
+       int hfmd_index, hfmd_count;\r
+\r
+       hfm_slot_t *hfmsl;\r
+       int hfmsl_index, hfmsl_count;\r
+\r
+       hfm_family_t *hfmf;\r
+       int hfmf_index, hfmf_count;\r
+\r
+       hfm_style_t *hfmst;\r
+       int hfmst_index, hfmst_count;\r
+\r
+       hfmd_count = hfm->hfm_device_count;\r
+       hfmd = (hfm_device_t *) HFM_DEREF(hfm, hfm->hfm_device_table);\r
+       for (hfmd_index = 0; hfmd_index < hfmd_count; hfmd_index++)\r
+               {\r
+               hfmsl_count = hfmd->hfmd_slot_count;\r
+               hfmsl = (hfm_slot_t *)\r
+                       HFM_DEREF(hfm, hfmd->hfmd_slot_table);\r
+\r
+               hfmf_count = hfmd->hfmd_family_count;\r
+               hfmf = (hfm_family_t *)\r
+                      HFM_DEREF(hfm, hfmd->hfmd_family_table);\r
+\r
+               if (query == 0)\r
+                       {\r
+                       printf("Device %d (slots %d, families %d)\n",\r
+                              hfmd_index, hfmsl_count, hfmf_count);\r
+\r
+                       for (hfmsl_index = 0; hfmsl_index < hfmsl_count; hfmsl_index++)\r
+                               {\r
+                               printf("\tSlot %d: "\r
+                                      " range=%d,%d"\r
+                                      " width=0x%04x bitmap=0x%04x"\r
+                                      " total=%d,%d space=%d,%d\n",\r
+                                      hfmsl_index,\r
+                                      hfmsl->hfmsl_char_first,\r
+                                      hfmsl->hfmsl_char_count,\r
+                                      hfmsl->hfmsl_width_table,\r
+                                      hfmsl->hfmsl_bitmap_table,\r
+                                      hfmsl->hfmsl_x_total,\r
+                                      hfmsl->hfmsl_y_total,\r
+                                      hfmsl->hfmsl_x_space,\r
+                                      hfmsl->hfmsl_y_space);\r
+\r
+                               hfmsl++;\r
+                               }\r
+                       }\r
+\r
+               for (hfmf_index = 0; hfmf_index < hfmf_count; hfmf_index++)\r
+                       {\r
+                       hfmst_count = hfmf->hfmf_style_count;\r
+                       hfmst = (hfm_style_t *)\r
+                               HFM_DEREF(hfm, hfmf->hfmf_style_table);\r
+\r
+                       if (query == 0)\r
+                               {\r
+                               printf("\tFamily %d \"%s\" (styles %d)\n",\r
+                                      hfmf_index,\r
+                                      hfm_family_int_to_string(hfmf_index),\r
+                                      hfmst_count);\r
+                               }\r
+\r
+                       for (hfmst_index = 0; hfmst_index < hfmst_count;\r
+                                             hfmst_index++)\r
+                               {\r
+                               if (query == 0)\r
+                                       {\r
+                                       printf("\t\tStyle %d: "\r
+                                              " height=%d style=%d \"%s\""\r
+                                              " slot=%d\n",\r
+                                              hfmst_index,\r
+                                              hfmst->hfmst_height,\r
+                                              hfmst->hfmst_style,\r
+                                              hfm_style_int_to_string(\r
+                                                       hfmst->hfmst_style),\r
+                                              hfmst->hfmst_slot);\r
+                                       }\r
+\r
+                               if (query && hfmd_index == device)\r
+                                       {\r
+                                       family_found[hfmst->hfmst_slot] =\r
+                                                       hfmf_index;\r
+                                       height_found[hfmst->hfmst_slot] =\r
+                                                       hfmst->hfmst_height;\r
+                                       style_found[hfmst->hfmst_slot] =\r
+                                                       hfmst->hfmst_style;\r
+                                       }\r
+\r
+                               hfmst++;\r
+                               }\r
+\r
+                       hfmf++;\r
+                       }\r
+\r
+               if (query == 0)\r
+                       {\r
+                       printf("\n");\r
+                       }\r
+\r
+               hfmd++;\r
+               }\r
+\r
+       return TRUE;\r
+       }\r
+\r
+/* ------------------------------------------------------------------------- */\r
+\r
+static int try_query(void)\r
+       {\r
+       hfm_style_t *hfmst;\r
+       int hfmst_index, hfmst_count;\r
+\r
+       hfm_family_t hfmf;\r
+\r
+       int slot;\r
+       hfm_slot_t *hfmsl;\r
+\r
+       printf("Searching for"\r
+              " device=%d family=%d \"%s\""\r
+              " height_min=%d height_max=%d\n",\r
+              device, family, hfm_family_int_to_string(family),\r
+              height_min, height_max);\r
+\r
+       if (hfm_search_family_auto(device, family,\r
+                                  height_min, height_max, &hfmf) == FALSE)\r
+               {\r
+               printf("Intersection of family and height is empty\n");\r
+               return FALSE;\r
+               }\r
+\r
+       hfmst_count = hfmf.hfmf_style_count;\r
+       hfmst = (hfm_style_t *) HFM_DEREF(hfm, hfmf.hfmf_style_table);\r
+\r
+       printf("\tFound %d possibilities\n", hfmst_count);\r
+\r
+       for (hfmst_index = 0; hfmst_index < hfmst_count; hfmst_index++)\r
+               {\r
+               printf("\t\tStyle %d: "\r
+                      " height=%d style=%d \"%s\" slot=%d\n",\r
+                      hfmst_index,\r
+                      hfmst->hfmst_height,\r
+                      hfmst->hfmst_style,\r
+                      hfm_style_int_to_string(hfmst->hfmst_style),\r
+                      hfmst->hfmst_slot);\r
+\r
+               hfmst++;\r
+               }\r
+\r
+       printf("\n");\r
+\r
+       printf("Searching within the returned results for style=%d \"%s\"\n",\r
+              style, hfm_style_int_to_string(style));\r
+\r
+       if (hfm_search_style_auto(&hfmf, style, &slot) == FALSE)\r
+               {\r
+               printf("Style is not available for this family and height\n");\r
+               return FALSE;\r
+               }\r
+\r
+       hfmsl = hfm_locate(device, slot);\r
+\r
+       printf("\tSlot %d: "\r
+              " range=%d,%d"\r
+              " width=0x%04x bitmap=0x%04x"\r
+              " total=%d,%d space=%d,%d\n",\r
+              slot,\r
+              hfmsl->hfmsl_char_first,\r
+              hfmsl->hfmsl_char_count,\r
+              hfmsl->hfmsl_width_table,\r
+              hfmsl->hfmsl_bitmap_table,\r
+              hfmsl->hfmsl_x_total,\r
+              hfmsl->hfmsl_y_total,\r
+              hfmsl->hfmsl_x_space,\r
+              hfmsl->hfmsl_y_space);\r
+\r
+       printf("\tReverse lookup on slot %d: "\r
+              " height=%d family=%d \"%s\" style=%d \"%s\"\n",\r
+              slot,\r
+              height_found[slot],\r
+              family_found[slot],\r
+              hfm_family_int_to_string(family_found[slot]),\r
+              style_found[slot],\r
+              hfm_style_int_to_string(style_found[slot]));\r
+\r
+       printf("\n");\r
+\r
+       return TRUE;\r
+       }\r
+\r
+/* ------------------------------------------------------------------------- */\r
+\r
diff --git a/src/mkfont/hfmdump.exe b/src/mkfont/hfmdump.exe
new file mode 100644 (file)
index 0000000..cd36868
Binary files /dev/null and b/src/mkfont/hfmdump.exe differ
diff --git a/src/mkfont/hfmlib.c b/src/mkfont/hfmlib.c
new file mode 100644 (file)
index 0000000..8a8b924
--- /dev/null
@@ -0,0 +1,451 @@
+/* hfmlib.c by Nick for Hytech Font Manager system */\r
+\r
+/* ------------------------------------------------------------------------- */\r
+/* header and preprocessor directives */\r
+\r
+#include <stdio.h>\r
+#ifdef _MSC_VER\r
+#include <windows.h>\r
+#include <io.h>\r
+#else\r
+#include <unistd.h>\r
+#endif\r
+#include <fcntl.h>\r
+#include <string.h>\r
+#include <malloc.h>\r
+\r
+#include "hfmlib.h"\r
+\r
+#ifndef TRUE\r
+#define TRUE 1\r
+#endif\r
+\r
+#ifndef FALSE\r
+#define FALSE 0\r
+#endif\r
+\r
+/* ------------------------------------------------------------------------- */\r
+/* global variables */\r
+\r
+/* note:  the library is allowed exactly 1 global variable, which must be of */\r
+/* pointer type.  if there is a need for more, we must implement a global_t */\r
+\r
+hfm_t *hfm;\r
+\r
+/* ------------------------------------------------------------------------- */\r
+/* exported functions */\r
+\r
+int hfm_load(char *hfm_path)\r
+       {\r
+       int fd;\r
+       unsigned int u, v;\r
+       hfm_t hdr;\r
+\r
+       if (hfm)\r
+               {\r
+               fprintf(stderr, "%s: already loaded\n", hfm_path);\r
+               return FALSE;\r
+               }\r
+\r
+       fd = open(hfm_path, O_RDONLY | O_BINARY);\r
+       if (fd < 0)\r
+               {\r
+               goto hfm_load_perror; /* use a goto to save code space */\r
+               }\r
+\r
+       if (read(fd, &hdr, sizeof(hfm_t)) < sizeof(hfm_t) ||\r
+                       hdr.hfm_magic != HFM_MAGIC ||\r
+                       hdr.hfm_format != HFM_FORMAT ||\r
+                       hdr.hfm_file_size < sizeof(hfm_t))\r
+               {\r
+               fprintf(stderr, "%s: bad header\n", hfm_path);\r
+               return FALSE;\r
+               }\r
+\r
+       hfm = (hfm_t *)malloc(hdr.hfm_file_size);\r
+       if (hfm == NULL)\r
+               {\r
+               fprintf(stderr, "%s: out of memory\n", hfm_path);\r
+               return FALSE;\r
+               }\r
+       memcpy(hfm, (char *)&hdr, sizeof(hfm_t));\r
+\r
+       u = hdr.hfm_file_size - sizeof(hfm_t);\r
+       v = read(fd, (char *)hfm + sizeof(hdr), u);\r
+\r
+       close(fd);\r
+       if (v == u)\r
+               {\r
+               return TRUE; /* success, access the block via hfm_t *hfm */\r
+               }\r
+\r
+       free(hfm); /* had an error, so don't leak the temporary buffer */\r
+       hfm = NULL; /* politely inform everyone there's really no file */\r
+\r
+       if (v < u)\r
+               {\r
+               fprintf(stderr, "%s: too short\n", hfm_path);\r
+               return FALSE;\r
+               }\r
+\r
+hfm_load_perror:\r
+       perror(hfm_path);\r
+       return FALSE;\r
+       }\r
+\r
+void hfm_free(void)\r
+       {\r
+       if (hfm)\r
+               {\r
+               free(hfm);\r
+               hfm = NULL;\r
+               }\r
+       }\r
+\r
+/* ------------------------------------------------------------------------- */\r
+\r
+int hfm_search_family(int device, int family,\r
+                     int height_min, int height_max,\r
+                     hfm_family_t *hfmf_ret)\r
+       {\r
+       int i, j, k;\r
+       hfm_device_t *hfmd;\r
+       hfm_family_t *hfmf;\r
+       hfm_style_t *p, *q;\r
+\r
+       /* find the specified device */\r
+\r
+       if (hfm == NULL || device < 0 || device >= hfm->hfm_device_count)\r
+               {\r
+               return FALSE; /* no file yet or device index too large */\r
+               }\r
+\r
+       hfmd = (hfm_device_t *)HFM_DEREF(hfm, hfm->hfm_device_table) +\r
+              device;\r
+\r
+       /* in the device description, find the specified family */\r
+\r
+       if (family < 0 || family >= hfmd->hfmd_family_count)\r
+               {\r
+               return FALSE; /* device not in use or family index too large */\r
+               }\r
+\r
+       hfmf = (hfm_family_t *)HFM_DEREF(hfm, hfmd->hfmd_family_table) +\r
+              family;\r
+\r
+       /* in the family description, find all styles with height in range */\r
+\r
+       k = hfmf->hfmf_style_count;\r
+\r
+       /* step 1:  find the first font which satisfies the height minimum */\r
+\r
+       p = (hfm_style_t *)HFM_DEREF(hfm, hfmf->hfmf_style_table);\r
+       for (i = 0; i < k; i++)\r
+               {\r
+               if (p->hfmst_height >= height_min)\r
+                       {\r
+                       break;\r
+                       }\r
+               p++;\r
+               }\r
+\r
+       /* step 2:  find the first font which violates the height maximum */\r
+\r
+       q = p;\r
+       for (j = i; j < k; j++)\r
+               {\r
+               if (q->hfmst_height >= height_max)\r
+                       {\r
+                       break;\r
+                       }\r
+               q++;\r
+               }\r
+\r
+       /* found at least one font for the device, family and height range? */\r
+\r
+       if (j > i)\r
+               {\r
+               hfmf_ret->hfmf_style_count = j - i;\r
+               hfmf_ret->hfmf_style_table = HFM_REF(hfm, p);\r
+               return TRUE; /* yes, return a family descriptor to the user */\r
+               }\r
+\r
+       return FALSE; /* no, don't bother to fill in the user's descriptor */\r
+       }\r
+\r
+int hfm_search_family_auto(int device, int family,\r
+                          int height_min, int height_max,\r
+                          hfm_family_t *hfmf_ret)\r
+       {\r
+       /* step 1:  see if any fonts in the user's preferred family will */\r
+       /* satisfy the given height requirement (at least 1 style available) */\r
+\r
+       if (hfm_search_family(device, family,\r
+                             height_min, height_max, hfmf_ret))\r
+               {\r
+               return TRUE; /* the user's preferred family is available */\r
+               }\r
+\r
+       /* step 2:  try the standard system font (sans serif) */\r
+       /* unless we already tried this in the initial search */\r
+\r
+       if (family != HFMF_SANS && hfm_search_family(device, HFMF_SANS,\r
+                                                    height_min, height_max,\r
+                                                    hfmf_ret))\r
+               {\r
+               return TRUE; /* standard (sans serif) family is available */\r
+               }\r
+\r
+       /* step 3:  try the alternate system font (seriffed) */\r
+       /* unless we already tried this in the initial search */\r
+\r
+       if (family != HFMF_SERIF && hfm_search_family(device, HFMF_SERIF,\r
+                                                     height_min, height_max,\r
+                                                     hfmf_ret))\r
+               {\r
+               return TRUE; /* alternate (seriffed) family is available */\r
+               }\r
+\r
+       return FALSE; /* no automatic font-change available in height range */\r
+       }\r
+\r
+/* ------------------------------------------------------------------------- */\r
+\r
+int hfm_search_style(hfm_family_t *hfmf, int style, int *slot_ret)\r
+       {\r
+       int k;\r
+       hfm_style_t *p;\r
+\r
+       /* using the given family description, find a particular style */\r
+\r
+       k = hfmf->hfmf_style_count;\r
+\r
+       /* search backwards for the tallest font with the requested style */\r
+\r
+       p = (hfm_style_t *) HFM_DEREF(hfm, hfmf->hfmf_style_table) + k;\r
+       while (k--)\r
+               {\r
+               p--;\r
+               if (p->hfmst_style == style)\r
+                       {\r
+                       *slot_ret = p->hfmst_slot;\r
+                       return TRUE; /* user's requested style is available */\r
+                       }\r
+               }\r
+\r
+       return FALSE; /* user's requested style is not available */\r
+       }\r
+\r
+int hfm_search_style_auto(hfm_family_t *hfmf, int style, int *slot_ret)\r
+       {\r
+       /* step 1:  see if the user's preferred style is available */\r
+\r
+       if (hfm_search_style(hfmf, style, slot_ret))\r
+               {\r
+               return TRUE; /* the user's preferred style is available */\r
+               }\r
+\r
+       /* step 2:  try the regular style unless we already tried this */\r
+\r
+       if (style != HFMST_REGULAR && hfm_search_style(hfmf, HFMST_REGULAR,\r
+                                                      slot_ret))\r
+               {\r
+               return TRUE; /* standard (regular) style is available */\r
+               }\r
+\r
+       /* step 3:  try the condensed style unless we already tried this */\r
+\r
+       if (style != HFMST_CONDENSED && hfm_search_style(hfmf, HFMST_CONDENSED,\r
+                                                        slot_ret))\r
+               {\r
+               return TRUE; /* alternate (condensed) style is available */\r
+               }\r
+\r
+       return FALSE; /* no automatic style-change available in family */\r
+       }\r
+\r
+/* ------------------------------------------------------------------------- */\r
+\r
+hfm_slot_t *hfm_locate(int device, int slot)\r
+       {\r
+       hfm_device_t *hfmd;\r
+\r
+       /* find the specified device */\r
+\r
+       if (hfm == NULL || device < 0 || device >= hfm->hfm_device_count)\r
+               {\r
+               return FALSE; /* no file yet or device index too large */\r
+               }\r
+\r
+       hfmd = (hfm_device_t *)HFM_DEREF(hfm, hfm->hfm_device_table) +\r
+              device;\r
+\r
+       /* in the device description, find the specified slot */\r
+\r
+       if (slot < 0 || slot >= hfmd->hfmd_slot_count)\r
+               {\r
+               return FALSE; /* device not in use or slot index too large */\r
+               }\r
+\r
+       return (hfm_slot_t *)HFM_DEREF(hfm, hfmd->hfmd_slot_table) +\r
+              slot;\r
+       }\r
+\r
+/* ------------------------------------------------------------------------- */\r
+\r
+int hfm_width(int device, int slot, char *string)\r
+       {\r
+       hfm_slot_t *hfmsl;\r
+       char *hfmw;\r
+       unsigned int u, char_first, char_count;\r
+       int width;\r
+\r
+       hfmsl = hfm_locate(device, slot);\r
+       char_first = hfmsl->hfmsl_char_first;\r
+       char_count = hfmsl->hfmsl_char_count;\r
+\r
+       hfmw = (char *)HFM_DEREF(hfm, hfmsl->hfmsl_width_table);\r
+       width = 0;\r
+\r
+       u = *(unsigned char *)string; /* get first char, unsigned!! */\r
+       while (u)\r
+               {\r
+               u -= char_first; /* offset it for start of table */\r
+               if (u < char_count) /* does character exist in table? */\r
+                       {\r
+                       width += hfmw[u]; /* yes, proportional width */\r
+                       }\r
+               else\r
+                       {\r
+                       width += hfmsl->hfmsl_x_total; /* no, standard width */\r
+                       }\r
+\r
+               u = *(unsigned char *)++string; /* get next char, unsigned!! */\r
+               }\r
+\r
+       return width; /* note:  we do not return the count here!! */\r
+       }\r
+\r
+int hfm_count_in_field(int device, int slot, char *string,\r
+                      int field_width, int *width_ret)\r
+       {\r
+       hfm_slot_t *hfmsl;\r
+       char *hfmw;\r
+       unsigned int u, char_first, char_count;\r
+       int w, width, count;\r
+\r
+       hfmsl = hfm_locate(device, slot);\r
+       char_first = hfmsl->hfmsl_char_first;\r
+       char_count = hfmsl->hfmsl_char_count;\r
+\r
+       hfmw = (char *)HFM_DEREF(hfm, hfmsl->hfmsl_width_table);\r
+       width = 0;\r
+       count = 0;\r
+\r
+       u = *(unsigned char *)string; /* get first char, unsigned!! */\r
+       while (u)\r
+               {\r
+               u -= char_first; /* offset it for start of table */\r
+               if (u < char_count) /* does character exist in table? */\r
+                       {\r
+                       w = hfmw[u]; /* yes, proportional width */\r
+                       }\r
+               else\r
+                       {\r
+                       w = hfmsl->hfmsl_x_total; /* no, standard width */\r
+                       }\r
+\r
+               width += w;\r
+               if (width > field_width)\r
+                       {\r
+                       width -= w; /* restore width so far */\r
+                       break; /* too wide, truncate before this ch */\r
+                       }\r
+\r
+               count++;\r
+\r
+               u = *(unsigned char *)++string; /* get next char, unsigned!! */\r
+               }\r
+\r
+       if (width_ret != NULL)\r
+               {\r
+               *width_ret = width;\r
+               }\r
+\r
+       return count;\r
+       }\r
+\r
+/* ------------------------------------------------------------------------- */\r
+\r
+#ifdef _MSC_VER\r
+char *hfm_family_int_to_string(int family)\r
+       {\r
+       switch (family)\r
+               {\r
+       case HFMF_SANS:\r
+               return HFMSTR_SANS;\r
+       case HFMF_SERIF:\r
+               return HFMSTR_SERIF;\r
+               }\r
+       return "";\r
+       }\r
+\r
+int hfm_family_string_to_int(char *family)\r
+       {\r
+       if (strcmp(family, HFMSTR_SANS) == 0)\r
+               {\r
+               return HFMF_SANS;\r
+               }\r
+       if (strcmp(family, HFMSTR_SERIF) == 0)\r
+               {\r
+               return HFMF_SERIF;\r
+               }\r
+       return -1;\r
+       }\r
+\r
+char *hfm_style_int_to_string(int style)\r
+       {\r
+       switch (style)\r
+               {\r
+       case HFMST_CONDENSED:\r
+               return HFMSTR_CONDENSED;\r
+       case HFMST_REGULAR:\r
+               return HFMSTR_REGULAR;\r
+       case HFMST_BOLD:\r
+               return HFMSTR_BOLD;\r
+       case HFMST_ITALIC:\r
+               return HFMSTR_ITALIC;\r
+       case HFMST_UNDERLINE:\r
+               return HFMSTR_UNDERLINE;\r
+               }\r
+       return "";\r
+       }\r
+\r
+int hfm_style_string_to_int(char *style)\r
+       {\r
+       if (strcmp(style, HFMSTR_CONDENSED) == 0)\r
+               {\r
+               return HFMST_CONDENSED;\r
+               }\r
+       if (strcmp(style, HFMSTR_REGULAR) == 0)\r
+               {\r
+               return HFMST_REGULAR;\r
+               }\r
+       if (strcmp(style, HFMSTR_BOLD) == 0)\r
+               {\r
+               return HFMST_BOLD;\r
+               }\r
+       if (strcmp(style, HFMSTR_ITALIC) == 0)\r
+               {\r
+               return HFMST_ITALIC;\r
+               }\r
+       if (strcmp(style, HFMSTR_UNDERLINE) == 0)\r
+               {\r
+               return HFMST_UNDERLINE;\r
+               }\r
+       return -1;\r
+       }\r
+#endif\r
+\r
+/* ------------------------------------------------------------------------- */\r
+\r
diff --git a/src/mkfont/hfmlib.h b/src/mkfont/hfmlib.h
new file mode 100644 (file)
index 0000000..9c14f38
--- /dev/null
@@ -0,0 +1,113 @@
+/* hfmlib.h by Nick for Hytech Font Manager system */\r
+\r
+/* ------------------------------------------------------------------------- */\r
+/* preprocessor definitions */\r
+\r
+#define HFM_MAGIC 0x6668\r
+\r
+#define        HFM_FORMAT 1\r
+\r
+#define HFMF_SANS 0\r
+#define HFMF_SERIF 1\r
+\r
+#define HFMST_CONDENSED 0\r
+#define HFMST_REGULAR 1\r
+#define HFMST_BOLD 2\r
+#define HFMST_ITALIC 3\r
+#define HFMST_UNDERLINE 4\r
+\r
+#define HFMSTR_SANS "sans"\r
+#define HFMSTR_SERIF "serif"\r
+#define HFMSTR_CONDENSED "condensed"\r
+#define HFMSTR_REGULAR "regular"\r
+#define HFMSTR_BOLD "bold"\r
+#define HFMSTR_ITALIC "italic"\r
+#define HFMSTR_UNDERLINE "underline"\r
+\r
+#define        HFM_PATH "/lib/apibus.hfm"\r
+\r
+#define HFM_REF(base, pointer) ((char *)pointer - (char *)(base))\r
+#define HFM_DEREF(base, offset) ((char *)(base) + (int)(offset))\r
+\r
+/* ------------------------------------------------------------------------- */\r
+/* struct and type definitions */\r
+\r
+typedef struct s_hfm\r
+       {\r
+       unsigned short hfm_magic;               /* int = HFM_MAGIC */\r
+       unsigned short hfm_format;              /* int = HFM_FORMAT */\r
+       unsigned short hfm_file_size;           /* int = char count for file */\r
+       unsigned short hfm_device_count;        /* int = hfm_device_t count */\r
+       unsigned short hfm_device_table;        /* ptr -> hfm_device_t array */\r
+       } hfm_t;\r
+\r
+typedef struct s_hfm_device\r
+       {\r
+       unsigned short hfmd_slot_count;         /* int = hfm_slot_t count */\r
+       unsigned short hfmd_slot_table;         /* ptr -> hfm_slot_t array */\r
+       unsigned short hfmd_family_count;       /* int = hfm_family_t count */\r
+       unsigned short hfmd_family_table;       /* ptr -> hfm_family_t array */\r
+       } hfm_device_t;\r
+\r
+typedef struct s_hfm_slot\r
+       {\r
+       unsigned short hfmsl_char_first;        /* int = first char (ascii) */\r
+       unsigned short hfmsl_char_count;        /* int = count (from first) */\r
+       unsigned short hfmsl_width_table;       /* ptr -> char array */\r
+       unsigned short hfmsl_bitmap_table;      /* ptr -> ptr array */\r
+\r
+       unsigned short hfmsl_x_total;           /* int = cell width pixels */\r
+       unsigned short hfmsl_y_total;           /* int = cell height pixels */\r
+       unsigned short hfmsl_x_space;           /* int = interchar space pix */\r
+       unsigned short hfmsl_y_space;           /* int = interline space pix */\r
+       } hfm_slot_t;\r
+\r
+typedef struct s_hfm_family\r
+       {\r
+       unsigned short hfmf_style_count;        /* int = hfm_style_t count */\r
+       unsigned short hfmf_style_table;        /* ptr -> hfm_style_t array */\r
+       } hfm_family_t;\r
+\r
+typedef struct s_hfm_style\r
+       {\r
+       unsigned short hfmst_height;            /* int = font height pixels */\r
+       unsigned short hfmst_style;             /* int = font style HFMST_? */\r
+       unsigned short hfmst_slot;              /* int = device's font index */\r
+       } hfm_style_t;\r
+\r
+/* ------------------------------------------------------------------------- */\r
+/* exported function prototypes */\r
+\r
+int hfm_load(char *hfm_path);\r
+void hfm_free(void);\r
+\r
+int hfm_search_family(int device, int family,\r
+                     int height_min, int height_max,\r
+                     hfm_family_t *hfmf_ret);\r
+int hfm_search_family_auto(int device, int family,\r
+                          int height_min, int height_max,\r
+                          hfm_family_t *hfmf_ret);\r
+\r
+int hfm_search_style(hfm_family_t *hfmf, int style, int *slot_ret);\r
+int hfm_search_style_auto(hfm_family_t *hfmf, int style, int *slot_ret);\r
+\r
+hfm_slot_t *hfm_locate(int device, int slot);\r
+\r
+int hfm_width(int device, int slot, char *string);\r
+int hfm_count_in_field(int device, int slot, char *string,\r
+                      int field_width, int *width_ret);\r
+\r
+#ifdef _MSC_VER\r
+char *hfm_family_int_to_string(int family);\r
+int hfm_family_string_to_int(char *family);\r
+char *hfm_style_int_to_string(int style);\r
+int hfm_style_string_to_int(char *style);\r
+#endif\r
+\r
+/* ------------------------------------------------------------------------- */\r
+/* exported global variables */\r
+\r
+extern hfm_t *hfm;\r
+\r
+/* ------------------------------------------------------------------------- */\r
+\r
diff --git a/src/mkfont/hfmtool.cpp b/src/mkfont/hfmtool.cpp
new file mode 100644 (file)
index 0000000..f48c59d
--- /dev/null
@@ -0,0 +1,669 @@
+// hfmtool.cpp by Nick for Hytech Font Metrics system\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+#include <stdio.h>\r
+#include <math.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <windows.h>\r
+#pragma hdrstop\r
+\r
+#ifndef DEBUG\r
+#define DEBUG 0\r
+#endif\r
+\r
+#include "hymb.h"\r
+#include "hyfs.h"\r
+#include "hyfile.h"\r
+#include "hylist.h"\r
+#include "hycache.h"\r
+#include "hystring.h"\r
+#include "bmp2txt.h"\r
+#include "txt2chs.h"\r
+#include "chs2cmd.h"\r
+\r
+#include "hfmlib.h"\r
+\r
+// ----------------------------------------------------------------------------\r
+// local preprocessor definitions\r
+\r
+#define LINE_MAX       0x200\r
+//#define PATH_MAX     0x200\r
+\r
+#define OUTPUT_BUFFER  0x10000 // to create output files of up to 64 kbytes\r
+#define CACHE_MAX      0x100 // the maximum number of files to operate on\r
+\r
+#define ARGUMENT_MAX   0x100 // the maximum number of arguments per command\r
+#define FONT_MAX       0x100 // the maximum number of fonts in the output file\r
+\r
+// ----------------------------------------------------------------------------\r
+// local struct and type definitions\r
+\r
+typedef struct\r
+       {\r
+       int iDevice;\r
+       int iSlot;\r
+\r
+       int ixTotal;\r
+       int iyTotal;\r
+       int ixSpace;\r
+       int iySpace;\r
+\r
+       char cWidth[0x100];\r
+       } SLOTTAG;\r
+\r
+typedef struct\r
+       {\r
+       int iDevice;\r
+       int iFamily;\r
+       int iHeight;\r
+       int iStyle;\r
+\r
+       int iSlot;\r
+       } INFOTAG;\r
+\r
+typedef struct\r
+       {\r
+       char *pszVerb;\r
+       int (*pfiHandler)(LISTTAG *pltCache, int argc, char **argv);\r
+       } VERBTAG;\r
+\r
+// ----------------------------------------------------------------------------\r
+// local function prototypes\r
+\r
+int main(int argc, char **argv);\r
+\r
+static int fiExecute(LISTTAG *pltCache, FILETAG *ftIn);\r
+static int fiConstruct(LISTTAG *pltCache, FILETAG *ftOut);\r
+static int iCompareInfo(const void *pvLeft, const void *pvRight);\r
+static int iCompareSlot(const void *pvLeft, const void *pvRight);\r
+\r
+static int iChs2Hfm(LISTTAG *pltCache, int argc, char **argv);\r
+static int fiProcess(SLOTTAG *pst, INFOTAG *pit, FILETAG *pftIn);\r
+\r
+// ----------------------------------------------------------------------------\r
+// global variables\r
+\r
+LISTTAG ltSlot; // list of type SLOTTAG\r
+LISTTAG ltInfo; // list of type INFOTAG\r
+\r
+VERBTAG vtVerb[] =\r
+       {\r
+       { "bmp2txt", iBmp2Txt },\r
+       { "txt2chs", iTxt2Chs },\r
+       { "chs2cmd", iChs2Cmd },\r
+       { "chs2hfm", iChs2Hfm }\r
+       };\r
+\r
+#define VERBS (sizeof(vtVerb) / sizeof(VERBTAG))\r
+\r
+#if DEBUG\r
+int fiDebug; // this one is really accessible to all modules\r
+#endif\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+int main(int argc, char **argv)\r
+       {\r
+       int i;\r
+        LISTTAG ltCache;\r
+\r
+       int iCacheIn;\r
+        FILETAG *pftIn;\r
+       char *pszInFileName;\r
+\r
+       int iCacheOut;\r
+        FILETAG *pftOut;\r
+       char *pszOutFileName;\r
+       char szOutFileName[LINE_MAX+1];\r
+\r
+       pszInFileName = NULL;\r
+       pszOutFileName = NULL;\r
+\r
+       if (argc > 1)\r
+               {\r
+               pszInFileName = argv[1];\r
+               }\r
+\r
+#if DEBUG\r
+       fiDebug = 0;\r
+#endif\r
+       if (argc > 2)\r
+               {\r
+#if DEBUG\r
+               i = atoi(argv[2]);\r
+               if (i < 1 || i > 0xff)\r
+                       {\r
+#endif\r
+                       pszOutFileName = argv[2];\r
+#if DEBUG\r
+                       if (argc > 3)\r
+                               {\r
+                               fiDebug = atoi(argv[3]);\r
+                               }\r
+                       }\r
+               else\r
+                       {\r
+                       fiDebug = i;\r
+                       }\r
+#endif\r
+               }\r
+\r
+       if (pszInFileName == NULL)\r
+               {\r
+               printf("usage: hfmtool infile.txt [outfile.hfm]"\r
+#if DEBUG\r
+                      " [debuglevel]"\r
+#endif\r
+                      "\n");\r
+               exit(1);\r
+               }\r
+\r
+       if (pszOutFileName == NULL)\r
+               {\r
+               pszOutFileName = szOutFileName;\r
+               strcpy(pszOutFileName, pszInFileName);\r
+\r
+               i = strlen(pszOutFileName);\r
+               while (i--)\r
+                       {\r
+                       if (pszOutFileName[i] == '\\')\r
+                               {\r
+                               break; /* no extension, so don't strip it */\r
+                               }\r
+                       if (pszOutFileName[i] == '.')\r
+                               {\r
+                               pszOutFileName[i] = 0; /* strip dot and extension */\r
+                               break; /* ready to concatenate our extension */\r
+                               }\r
+                       }\r
+\r
+               strcat(pszOutFileName, ".hfm");\r
+               }\r
+\r
+       if (!strcmp(pszInFileName, pszOutFileName))\r
+               {\r
+               printf("Input and output filenames identical\n");\r
+               exit(1);\r
+               }\r
+\r
+       // set up the cache to track intermediate memory files\r
+        CacheEntrySetup(&ltCache, CACHE_MAX); // to handle CACHE_MAX files\r
+\r
+       // allocate font list to collect information about fonts\r
+       ListAllocate(&ltSlot, FONT_MAX, sizeof(SLOTTAG));\r
+       ListAllocate(&ltInfo, FONT_MAX, sizeof(INFOTAG));\r
+\r
+       // read the input txt file entirely to a malloc'd block\r
+       CacheReadIn(&ltCache, &iCacheIn, pszInFileName);\r
+        pftIn = pftCacheItem(&ltCache, iCacheIn);\r
+\r
+       // interpret commands and construct intermediate files\r
+       if (fiExecute(&ltCache, pftIn) == FALSE)\r
+               {\r
+               exit(1);\r
+               }\r
+\r
+       // prepare an output buffer for font metric data\r
+       CacheAllocate(&ltCache, &iCacheOut, OUTPUT_BUFFER);\r
+        pftOut = pftCacheItem(&ltCache, iCacheOut);\r
+\r
+       // construct output based on the font information collected\r
+       if (fiConstruct(&ltCache, pftOut) == FALSE)\r
+               {\r
+               exit(1);\r
+               }\r
+\r
+       // ready to write the output we found\r
+       CacheWriteOut(&ltCache, iCacheOut, pszOutFileName);\r
+#if 1\r
+       pctCacheItem(&ltCache, iCacheOut)->iDirty = 4; // extra dirty\r
+#else\r
+       CacheFlush(&ltCache, iCacheOut, 3); // force immediate writing\r
+#endif\r
+\r
+       // junk the internal font list buffer\r
+       ListFree(&ltInfo);\r
+       ListFree(&ltSlot);\r
+\r
+       // it just goes on and on my friend\r
+#if DEBUG\r
+       CacheExitFlush(&ltCache, 3); // force writing of intermediate files\r
+#else\r
+       CacheExitFlush(&ltCache, 4); // force writing of output files only\r
+#endif\r
+       CacheExitCleanup(&ltCache); // deallocate memory, though it's redundant\r
+\r
+       return 0;\r
+       }\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+static int fiExecute(LISTTAG *pltCache, FILETAG *pftIn)\r
+       {\r
+       int i;\r
+       char sz[LINE_MAX+1];\r
+       int argc;\r
+       char *argv[ARGUMENT_MAX];\r
+       hfm_t *hfm;\r
+       int iSize, iSizeArg;\r
+       char *pcArg;\r
+\r
+       // execute the user's script file (similar to unix shell)\r
+       while (fiFileGetLine(pftIn, sz, sizeof(sz) - 1, &iSize))\r
+               {\r
+               argc = 0;\r
+\r
+               i = iStringIsolate(0, sz, iSize, &pcArg, &iSizeArg);\r
+               while (iSizeArg && argc < ARGUMENT_MAX)\r
+                       {\r
+                       argv[argc++] = pcArg; // stash reference to string\r
+                       pcArg[iSizeArg] = 0; // add null terminator\r
+\r
+                       i = iStringIsolate(i + 1, sz, iSize,\r
+                                                 &pcArg, &iSizeArg);\r
+                       }\r
+\r
+               if (argc < 1 || argv[0][0] == '#')\r
+                       {\r
+                       continue; // comments and blank file lines ignored\r
+                       }\r
+\r
+#if DEBUG\r
+               for (i = 0; i < argc; i++)\r
+                       {\r
+                       printf("Argument %d = \"%s\"\n", i, argv[i]);\r
+                       }\r
+#endif\r
+\r
+               for (i = 0; i < VERBS; i++)\r
+                       {\r
+                       if (strcmp(argv[0], vtVerb[i].pszVerb) == 0)\r
+                               {\r
+                               break;\r
+                               }\r
+                       }\r
+\r
+               if (i >= VERBS)\r
+                       {\r
+                       printf("Unrecognised command \"%s\"\n", argv[0]);\r
+                       return FALSE;\r
+                       }\r
+\r
+               i = (vtVerb[i].pfiHandler)(pltCache, argc, argv);\r
+#if DEBUG\r
+               printf("Exitcode = %d\n", i);\r
+#endif\r
+               if (i)\r
+                       {\r
+                       printf("Command \"%s\" reports failure\n", argv[0]);\r
+                       return FALSE;\r
+                       }\r
+               }\r
+\r
+       return TRUE;\r
+       }\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+static int fiConstruct(LISTTAG *pltCache, FILETAG *pftOut)\r
+       {\r
+       char *pc;\r
+       int i, j, iDevice, iSlot, iFamily;\r
+       LISTTAG lthfmd; // list of type hfm_device_t\r
+       LISTTAG lthfmsl; // list of type hfm_slot_t\r
+       LISTTAG lthfmf; // list of type hfm_family_t\r
+       LISTTAG lthfmst; // list of type hfm_style_t\r
+       hfm_t *phfm;\r
+       hfm_device_t *phfmd;\r
+       hfm_slot_t *phfmsl;\r
+       hfm_family_t *phfmf;\r
+       hfm_style_t *phfmst;\r
+       SLOTTAG *pst;\r
+       INFOTAG *pit;\r
+\r
+       // sort the font information collected\r
+       qsort(ltSlot.pcBase, ltSlot.iAppend, sizeof(SLOTTAG), iCompareSlot);\r
+       qsort(ltInfo.pcBase, ltInfo.iAppend, sizeof(INFOTAG), iCompareInfo);\r
+\r
+       // create the Hytech Font Manager header\r
+       pc = pftOut->pcBase;\r
+\r
+       phfm = (hfm_t *)pc;\r
+       memset(pc, 0, sizeof(hfm_t));\r
+       pc += sizeof(hfm_t);\r
+\r
+       phfm->hfm_magic = HFM_MAGIC;\r
+       phfm->hfm_format = HFM_FORMAT;\r
+\r
+       // allocate temporary buffers to be reused several times\r
+       ListAllocate(&lthfmd, FONT_MAX, sizeof(hfm_device_t));\r
+       ListAllocate(&lthfmsl, FONT_MAX, sizeof(hfm_slot_t));\r
+       ListAllocate(&lthfmf, FONT_MAX, sizeof(hfm_family_t));\r
+       ListAllocate(&lthfmst, FONT_MAX, sizeof(hfm_style_t));\r
+\r
+       // set up one item of lookahead in slot table\r
+       ltSlot.iPosition = 0;\r
+       pst = (SLOTTAG *) pcListCanGet(&ltSlot);\r
+\r
+       // set up one item of lookahead in info table\r
+       ltInfo.iPosition = 0;\r
+       pit = (INFOTAG *) pcListCanGet(&ltInfo);\r
+\r
+       // write one device at a time, zeroing missing devices\r
+       iDevice = 0;\r
+       lthfmd.iAppend = 0;\r
+       while (pst || pit)\r
+               {\r
+               phfmd = (hfm_device_t *) pcListPut(&lthfmd);\r
+\r
+               // collect one slot at a time, zeroing missing slots\r
+               iSlot = 0;\r
+               lthfmsl.iAppend = 0;\r
+               while (pst && pst->iDevice == iDevice)\r
+                       {\r
+                       phfmsl = (hfm_slot_t *) pcListPut(&lthfmsl);\r
+\r
+                       if (pst->iSlot < iSlot)\r
+                               {\r
+                               printf("Duplicate slot %d\n", iSlot);\r
+                               return FALSE;\r
+                               }\r
+\r
+                       if (pst->iSlot == iSlot)\r
+                               {\r
+                               for (i = 0; i < 0x100; i++)\r
+                                       {\r
+                                       if (pst->cWidth[i] != pst->ixTotal)\r
+                                               {\r
+                                               break;\r
+                                               }\r
+                                       }\r
+\r
+                               for (j = 0xff; j > i; j--)\r
+                                       {\r
+                                       if (pst->cWidth[j] != pst->ixTotal)\r
+                                               {\r
+                                               j++;\r
+                                               break;\r
+                                               }\r
+                                       }\r
+\r
+                               if (j > i)\r
+                                       {\r
+                                       j -= i;\r
+                                       phfmsl->hfmsl_char_first = i;\r
+                                       phfmsl->hfmsl_char_count = j;\r
+                                       phfmsl->hfmsl_width_table =\r
+                                                       pc - pftOut->pcBase;\r
+                                       memcpy(pc, pst->cWidth + i, j);\r
+                                       pc += j;\r
+                                       }\r
+\r
+                               phfmsl->hfmsl_x_total = pst->ixTotal;\r
+                               phfmsl->hfmsl_y_total = pst->iyTotal;\r
+                               phfmsl->hfmsl_x_space = pst->ixSpace;\r
+                               phfmsl->hfmsl_y_space = pst->iySpace;\r
+\r
+                               pst = (SLOTTAG *) pcListCanGet(&ltSlot);\r
+                               }\r
+\r
+                       iSlot++;\r
+                       }\r
+\r
+               // write the collected slot information for the device\r
+               if (lthfmsl.iAppend)\r
+                       {\r
+                       phfmd->hfmd_slot_count = lthfmsl.iAppend;\r
+                       phfmd->hfmd_slot_table = pc - pftOut->pcBase;\r
+                       j = lthfmsl.iAppend * sizeof(hfm_slot_t);\r
+                       memcpy(pc, lthfmsl.pcBase, j);\r
+                       pc += j;\r
+                       }\r
+\r
+               // collect one family at a time, zeroing missing families\r
+               iFamily = 0;\r
+               lthfmf.iAppend = 0;\r
+               while (pit && pit->iDevice == iDevice)\r
+                       {\r
+                       phfmf = (hfm_family_t *) pcListPut(&lthfmf);\r
+\r
+                       // collect one height/style at a time, with no gaps\r
+                       lthfmst.iAppend = 0;\r
+                       while (pit && pit->iDevice == iDevice &&\r
+                                     pit->iFamily == iFamily)\r
+                               {\r
+                               phfmst = (hfm_style_t *) pcListPut(&lthfmst);\r
+\r
+                               phfmst->hfmst_height = pit->iHeight;\r
+                               phfmst->hfmst_style = pit->iStyle;\r
+                               phfmst->hfmst_slot = pit->iSlot;\r
+\r
+                               pit = (INFOTAG *) pcListCanGet(&ltInfo);\r
+                               }\r
+\r
+                       if (lthfmst.iAppend)\r
+                               {\r
+                               phfmf->hfmf_style_count = lthfmst.iAppend;\r
+                               phfmf->hfmf_style_table = pc - pftOut->pcBase;\r
+                               j = lthfmst.iAppend * sizeof(hfm_style_t);\r
+                               memcpy(pc, lthfmst.pcBase, j);\r
+                               pc += j;\r
+                               }\r
+\r
+                       iFamily++;\r
+                       }\r
+\r
+               // write the collected family information for the device\r
+               if (lthfmf.iAppend)\r
+                       {\r
+                       phfmd->hfmd_family_count = lthfmf.iAppend;\r
+                       phfmd->hfmd_family_table = pc - pftOut->pcBase;\r
+                       j = lthfmf.iAppend * sizeof(hfm_family_t);\r
+                       memcpy(pc, lthfmf.pcBase, j);\r
+                       pc += j;\r
+                       }\r
+\r
+               iDevice++;\r
+               }\r
+\r
+       // write the collected device information\r
+       if (lthfmd.iAppend)\r
+               {\r
+               phfm->hfm_device_count = lthfmd.iAppend;\r
+               phfm->hfm_device_table = pc - pftOut->pcBase;\r
+               j = lthfmd.iAppend * sizeof(hfm_device_t);\r
+               memcpy(pc, lthfmd.pcBase, j);\r
+               pc += j;\r
+               }\r
+\r
+       // free temporary buffers\r
+       ListFree(&lthfmd);\r
+       ListFree(&lthfmsl);\r
+       ListFree(&lthfmf);\r
+       ListFree(&lthfmst);\r
+\r
+       // set the file length in the header\r
+       phfm->hfm_file_size = pc - pftOut->pcBase;\r
+\r
+       // set the file length to be written\r
+       pftOut->pcAppend = pc;\r
+\r
+       return TRUE;\r
+       }\r
+\r
+static int iCompareSlot(const void *pvLeft, const void *pvRight)\r
+       {\r
+       if (((SLOTTAG *) pvLeft)->iDevice < ((SLOTTAG *) pvRight)->iDevice)\r
+               {\r
+               return -1;\r
+               }\r
+\r
+       if (((SLOTTAG *) pvLeft)->iDevice > ((SLOTTAG *) pvRight)->iDevice)\r
+               {\r
+               return 1;\r
+               }\r
+\r
+       if (((SLOTTAG *) pvLeft)->iSlot < ((SLOTTAG *) pvRight)->iSlot)\r
+               {\r
+               return -1;\r
+               }\r
+\r
+       if (((SLOTTAG *) pvLeft)->iSlot > ((SLOTTAG *) pvRight)->iSlot)\r
+               {\r
+               return 1;\r
+               }\r
+\r
+       return 0;\r
+       }\r
+\r
+static int iCompareInfo(const void *pvLeft, const void *pvRight)\r
+       {\r
+       if (((INFOTAG *) pvLeft)->iDevice < ((INFOTAG *) pvRight)->iDevice)\r
+               {\r
+               return -1;\r
+               }\r
+\r
+       if (((INFOTAG *) pvLeft)->iDevice > ((INFOTAG *) pvRight)->iDevice)\r
+               {\r
+               return 1;\r
+               }\r
+\r
+       if (((INFOTAG *) pvLeft)->iFamily < ((INFOTAG *) pvRight)->iFamily)\r
+               {\r
+               return -1;\r
+               }\r
+\r
+       if (((INFOTAG *) pvLeft)->iFamily > ((INFOTAG *) pvRight)->iFamily)\r
+               {\r
+               return 1;\r
+               }\r
+\r
+       if (((INFOTAG *) pvLeft)->iHeight < ((INFOTAG *) pvRight)->iHeight)\r
+               {\r
+               return -1;\r
+               }\r
+\r
+       if (((INFOTAG *) pvLeft)->iHeight > ((INFOTAG *) pvRight)->iHeight)\r
+               {\r
+               return 1;\r
+               }\r
+\r
+       if (((INFOTAG *) pvLeft)->iStyle < ((INFOTAG *) pvRight)->iStyle)\r
+               {\r
+               return -1;\r
+               }\r
+\r
+       if (((INFOTAG *) pvLeft)->iStyle > ((INFOTAG *) pvRight)->iStyle)\r
+               {\r
+               return 1;\r
+               }\r
+\r
+       return 0;\r
+       }\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+int iChs2Hfm(LISTTAG *pltCache, int argc, char **argv)\r
+       {\r
+       int i, iDevice, iSlot;\r
+       char *pszFamily, *pszStyle;\r
+       INFOTAG *pit;\r
+       SLOTTAG *pst;\r
+\r
+       int iCacheIn;\r
+       FILETAG *pftIn;\r
+       char *pszInFileName;\r
+\r
+       if (argc < 6)\r
+               {\r
+               printf("usage: infile.chs device slot family style\n");\r
+               exit(1);\r
+               }\r
+\r
+       pszInFileName = argv[1];\r
+       iDevice = atoi(argv[2]);\r
+       iSlot = atoi(argv[3]);\r
+       pszFamily = argv[4];\r
+       pszStyle = argv[5];\r
+\r
+       pit = (INFOTAG *) pcListPut(&ltInfo);\r
+       pit->iDevice = iDevice;\r
+       pit->iSlot = iSlot;\r
+\r
+       pit->iFamily = hfm_family_string_to_int(pszFamily);\r
+       if (pit->iFamily < 0)\r
+               {\r
+               printf("Family must be one of:\n"\r
+                      "\t" HFMSTR_SANS "\n"\r
+                      "\t" HFMSTR_SERIF "\n");\r
+               exit(1);\r
+               }\r
+\r
+       pit->iStyle = hfm_style_string_to_int(pszStyle);\r
+       if (pit->iStyle < 0)\r
+               {\r
+               printf("Style must be one of:\n"\r
+                      "\t" HFMSTR_CONDENSED "\n"\r
+                      "\t" HFMSTR_REGULAR "\n"\r
+                      "\t" HFMSTR_BOLD "\n"\r
+                      "\t" HFMSTR_ITALIC "\n"\r
+                      "\t" HFMSTR_UNDERLINE "\n");\r
+               exit(1);\r
+               }\r
+\r
+       pst = (SLOTTAG *) pcListPut(&ltSlot);\r
+       pst->iDevice = iDevice;\r
+       pst->iSlot = iSlot;\r
+\r
+       // read the input chs file entirely to a malloc'd block\r
+       CacheReadIn(pltCache, &iCacheIn, pszInFileName);\r
+       pftIn = pftCacheItem(pltCache, iCacheIn);\r
+\r
+       // extract font width and height info, and character widths\r
+       if (fiProcess(pst, pit, pftIn) == FALSE)\r
+               {\r
+               return 1;\r
+               }\r
+\r
+       return 0;\r
+       }\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+static int fiProcess(SLOTTAG *pst, INFOTAG *pit, FILETAG *pftIn)\r
+       {\r
+       unsigned short *pus;\r
+       int i;\r
+       char *pc;\r
+\r
+       if (iFileSize(pftIn) < 0x214)\r
+               {\r
+               printf("Input chs file is unexpectedly short\n");\r
+               return FALSE;\r
+               }\r
+\r
+       pc = &pftIn->pcBase[0x210];\r
+       pst->ixTotal = *pc++;\r
+       pst->iyTotal = *pc++;\r
+       pst->ixSpace = *pc++;\r
+       pst->iySpace = *pc++;\r
+       memset(pst->cWidth, pst->ixTotal, 0x100);\r
+       pit->iHeight = pst->iyTotal - pst->iySpace;\r
+\r
+       pus = (unsigned short *) &pftIn->pcBase[0x10];\r
+       for (i = 0; i < 0x100; i++)\r
+               {\r
+               pc = &pftIn->pcBase[0x10 + *pus++];\r
+               if (*pc & 0x20) // got width for character?\r
+                       {\r
+                       pst->cWidth[i] = *(pc - 1); // yes, save it\r
+                       }\r
+               }\r
+\r
+       return TRUE;\r
+       }\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
diff --git a/src/mkfont/hfmtool.exe b/src/mkfont/hfmtool.exe
new file mode 100644 (file)
index 0000000..2c5aa4e
Binary files /dev/null and b/src/mkfont/hfmtool.exe differ
diff --git a/src/mkfont/hycache.cpp b/src/mkfont/hycache.cpp
new file mode 100644 (file)
index 0000000..7d79426
--- /dev/null
@@ -0,0 +1,230 @@
+// hycache.cpp\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+#include <io.h>\r
+#include <fcntl.h>\r
+#include <sys/stat.h>\r
+#include <stdio.h>\r
+#include <windows.h>\r
+#pragma hdrstop\r
+#include "hymb.h"\r
+#include "hyfs.h"\r
+#include "hyfile.h"\r
+#include "hylist.h"\r
+#include "hycache.h"\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+void CacheEntrySetup(LISTTAG *plt, int iItemCount)\r
+     {\r
+     // allocate the cache list via the lower level wrapper\r
+     ListAllocate(plt, iItemCount, sizeof(CACHETAG));\r
+     }\r
+\r
+void CacheExitCleanup(LISTTAG *plt)\r
+     {\r
+     int i;\r
+\r
+     // free all active cache tags in the cache\r
+     for (i = 0; i < plt->iAppend; i++)\r
+          {\r
+          CacheFree(plt, i);\r
+          }\r
+\r
+     // free the cache list via the lower level wrapper\r
+     ListFree(plt);\r
+     }\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+void CacheExitFlush(LISTTAG *plt, int iDirtiness)\r
+     {\r
+     int i;\r
+\r
+     // write out all dirty cache tags in the cache\r
+     for (i = 0; i < plt->iAppend; i++)\r
+          {\r
+          CacheFlush(plt, i, iDirtiness);\r
+          }\r
+     }\r
+\r
+int fiCacheFlush(LISTTAG *plt, int iItem, int iDirtiness)\r
+     {\r
+     CACHETAG *pct;\r
+\r
+     plt->iPosition = iItem;\r
+     pct = (CACHETAG *) pcListCanGet(plt);\r
+     if (pct == NULL)\r
+          {\r
+          return FALSE; // the user passed an invalid token\r
+          }\r
+\r
+     if (pct->iDirty >= iDirtiness) // got name for the entry, and is it dirty?\r
+          {\r
+#if 1 // highly temporary, add a diagnostic (but error now bombs!!\r
+ FileWriteOut(&pct->ft, pct->mbh.pcBase);\r
+#else\r
+          if (fiFileWriteOut(&pct->ft, pct->mbh.pcBase) == 0)\r
+               {\r
+               return FALSE;\r
+               }\r
+#endif\r
+\r
+          pct->iDirty = 2; // preserve the entry, it is now clean\r
+          }\r
+\r
+     return TRUE;\r
+     }\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+int fiCacheAllocate(LISTTAG *plt, int *piItem, int iSize)\r
+     {\r
+     CACHETAG *pct;\r
+\r
+     plt->iPosition = plt->iAppend;\r
+\r
+     pct = (CACHETAG *) pcListCanPut(plt);\r
+     if (pct == NULL)\r
+          {\r
+          return FALSE; // no more entries in the cache\r
+          }\r
+\r
+     if (fiFileAllocate(&pct->ft, iSize) == 0)\r
+          {\r
+          plt->iAppend = plt->iPosition;\r
+          return FALSE; // not enough memory for the data\r
+          }\r
+\r
+     pct->iDirty = 1; // unnamed\r
+     *piItem = plt->iPosition; // return token to user\r
+     return TRUE;\r
+     }\r
+\r
+int fiCacheFree(LISTTAG *plt, int iItem)\r
+     {\r
+     CACHETAG *pct;\r
+     int fiSuccess;\r
+\r
+     plt->iPosition = iItem;\r
+     pct = (CACHETAG *) pcListCanGet(plt);\r
+     if (pct == NULL)\r
+          {\r
+          return FALSE; // the user passed an invalid token\r
+          }\r
+\r
+     // if nothing is to be done, indicate success\r
+     fiSuccess = TRUE;\r
+\r
+     // unconditionally delete this entry from the cache\r
+     if (pct->iDirty >= 2) // got a name for the entry?\r
+          {\r
+          fiSuccess &= fiMBFree(&pct->mbh);\r
+          }\r
+\r
+     if (pct->iDirty >= 1) // got any data for the entry?\r
+          {\r
+          fiSuccess &= fiFileFree(&pct->ft);\r
+          }\r
+\r
+     pct->iDirty = 0; // return the cache entry to the pool\r
+     return fiSuccess; // if this is FALSE, a grievious error has occurred\r
+     }\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+int fiCacheSearch(LISTTAG *plt, int *piItem, char *pszName)\r
+     {\r
+     CACHETAG *pct;\r
+\r
+     plt->iPosition = 0;\r
+     while (pct = (CACHETAG *) pcListCanGet(plt))\r
+          {\r
+          if (pct->iDirty >= 2 && // got a name for the entry?\r
+                    strcmp(pszName, pct->mbh.pcBase) == 0) // matching name?\r
+               {\r
+               plt->iPosition--; // it was advanced by pcListCanGet()\r
+\r
+               *piItem = plt->iPosition; // return token to user\r
+               return TRUE; // the file name was found in the cache\r
+               }\r
+          }\r
+\r
+     // we will now rely on plt->iPosition == plt->iAppend\r
+     return FALSE;\r
+     }\r
+\r
+int fiCacheReadIn(LISTTAG *plt, int *piItem, char *pszName)\r
+     {\r
+     CACHETAG *pct;\r
+\r
+     if (fiCacheSearch(plt, piItem, pszName))\r
+          {\r
+          return TRUE; // the file name was found in the cache\r
+          }\r
+\r
+     // we will now rely on plt->iPosition == plt->iAppend\r
+     pct = (CACHETAG *) pcListCanPut(plt);\r
+     if (pct == NULL)\r
+          {\r
+          return FALSE; // no more entries in the cache\r
+          }\r
+\r
+     if (fiMBAlloc(&pct->mbh, strlen(pszName) + 1) == 0)\r
+          {\r
+          plt->iAppend = plt->iPosition;\r
+          return FALSE; // not enough memory for the file name\r
+          }\r
+     strcpy(pct->mbh.pcBase, pszName); // stash the file name\r
+\r
+     if (fiFileReadIn(&pct->ft, pszName) == 0)\r
+          {\r
+          fiMBFree(&pct->mbh);\r
+          plt->iAppend = plt->iPosition;\r
+          return FALSE; // file not found or not enough memory\r
+          }\r
+\r
+     pct->iDirty = 2; // clean\r
+     *piItem = plt->iPosition; // return token to user\r
+     return TRUE; // the file was successfully read into the cache\r
+     }\r
+\r
+int fiCacheWriteOut(LISTTAG *plt, int iItem, char *pszName)\r
+     {\r
+     CACHETAG *pct;\r
+     MBHANDLE mbh;\r
+\r
+     plt->iPosition = iItem;\r
+     pct = (CACHETAG *) pcListCanGet(plt);\r
+     if (pct == NULL || pct->iDirty < 1)\r
+          {\r
+          return FALSE; // the user passed an invalid token\r
+          }\r
+\r
+     if (pct->iDirty >= 2 && // got a name for the entry?\r
+               strcmp(pszName, pct->mbh.pcBase) == 0) // matching name?\r
+          {\r
+          return TRUE; // no action needed, maybe pszName == pct->mbh.pcBase\r
+          }\r
+\r
+     if (fiMBAlloc(&mbh, strlen(pszName) + 1) == 0)\r
+          {\r
+          return FALSE; // not enough memory for the new file name\r
+          }\r
+     strcpy(mbh.pcBase, pszName); // stash the file name\r
+\r
+     if (pct->iDirty >= 2 && // got an existing name for the entry?\r
+               fiMBFree(&pct->mbh) == 0) // if so, it's now safe to free it\r
+          {\r
+          fiMBFree(&mbh);\r
+          return FALSE; // couldn't free the existing name storage\r
+          }\r
+     memcpy(&pct->mbh, &mbh, sizeof(MBHANDLE)); // can now clobber the old mbh\r
+\r
+     pct->iDirty = 3; // dirty\r
+     return TRUE; // the new name has been registered, flush the data later\r
+     }\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
diff --git a/src/mkfont/hycache.h b/src/mkfont/hycache.h
new file mode 100644 (file)
index 0000000..afaea5a
--- /dev/null
@@ -0,0 +1,191 @@
+// hycache.h\r
+\r
+#ifndef _INC_HYCACHE\r
+#define _INC_HYCACHE\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+typedef struct\r
+{\r
+     int iDirty; // 0 = free, 1 = unnamed, 2 = clean, 3 = dirty\r
+     MBHANDLE mbh; // smallish memory block containing the filename\r
+     FILETAG ft; // potentially large memory block containing the data\r
+} CACHETAG;\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+void CacheEntrySetup(LISTTAG *plt, int iItemCount);\r
+void CacheExitCleanup(LISTTAG *plt);\r
+\r
+void CacheExitFlush(LISTTAG *plt, int iDirtiness);\r
+int fiCacheFlush(LISTTAG *plt, int iItem, int iDirtiness);\r
+\r
+int fiCacheAllocate(LISTTAG *plt, int *piItem, int iSize);\r
+int fiCacheFree(LISTTAG *plt, int iItem);\r
+\r
+int fiCacheSearch(LISTTAG *plt, int *piItem, char *pszName);\r
+int fiCacheReadIn(LISTTAG *plt, int *piItem, char *pszName);\r
+int fiCacheWriteOut(LISTTAG *plt, int iItem, char *pszName);\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+inline CACHETAG *pctCacheItem(LISTTAG *plt, int iItem)\r
+     {\r
+     // return pointer to start of item, casted to cache item\r
+     return (CACHETAG *) pcListItem(plt, iItem);\r
+     }\r
+\r
+inline MBHANDLE *pmbhCacheItem(LISTTAG *plt, int iItem)\r
+     {\r
+     // return pointer to memory block handle within item, no casting needed\r
+     return &pctCacheItem(plt, iItem)->mbh;\r
+     }\r
+\r
+inline FILETAG *pftCacheItem(LISTTAG *plt, int iItem)\r
+     {\r
+     // return pointer to file tag within item, no casting needed\r
+     return &pctCacheItem(plt, iItem)->ft;\r
+     }\r
+\r
+// ----------------------------------------------------------------------------\r
+// handy functions for the client, not important to the interface:\r
+\r
+#ifdef _INC_STDIO\r
+inline void CacheAllocate(LISTTAG *plt, int *piItem, int iSize)\r
+     {\r
+     if (fiCacheAllocate(plt, piItem, iSize) == FALSE)\r
+          {\r
+          printf("CacheAllocate: "\r
+                 "Could not allocate cache 0x%08x size 0x%08x", iSize);\r
+          exit(1);\r
+          }\r
+\r
+#if DEBUG\r
+     printf("CacheAllocate: "\r
+            "Allocated cache 0x%08x item %d size 0x%08x\n",\r
+            plt, *piItem, iSize);\r
+#endif\r
+     }\r
+\r
+inline void CacheFree(LISTTAG *plt, int iItem)\r
+     {\r
+     if (fiCacheFree(plt, iItem) == FALSE)\r
+          {\r
+          printf("CacheFree: Could not free cache 0x%08x item %d\n",\r
+                 plt, iItem);\r
+          exit(1);\r
+          }\r
+\r
+#if DEBUG\r
+     printf("CacheFree: Freed cache 0x%08x item %d\n", plt, iItem);\r
+#endif\r
+     }\r
+\r
+inline void CacheFlush(LISTTAG *plt, int iItem, int iDirtiness)\r
+     {\r
+     if (fiCacheFlush(plt, iItem, iDirtiness) == FALSE)\r
+          {\r
+          printf("CacheFlush: Could not flush cache 0x%08x item %d\n",\r
+                 plt, iItem);\r
+          exit(1);\r
+          }\r
+\r
+//     printf(\r
+//#if DEBUG\r
+//            "CacheFlush: "\r
+//#endif\r
+//            "Flushed "\r
+//#if DEBUG\r
+//            "cache 0x%08x "\r
+//#endif\r
+//            "item %d, file %s size 0x%08x\n",\r
+//#if DEBUG\r
+//            plt,\r
+//#endif\r
+//            iItem,\r
+//            pmbhCacheItem(plt, iItem)->pcBase,\r
+//            iFileSize(pftCacheItem(plt, iItem)));\r
+\r
+#if DEBUG\r
+     printf("CacheFlush: Flushed cache 0x%08x item %d\n", plt, iItem);\r
+#endif\r
+     }\r
+\r
+inline void CacheSearch(LISTTAG *plt, int *piItem, char *pszName)\r
+     {\r
+     if (fiCacheSearch(plt, piItem, pszName) == FALSE)\r
+          {\r
+          printf("CacheSearch: Could not find cache 0x%08x, file %s\n",\r
+                 plt, pszName);\r
+          exit(1);\r
+          }\r
+\r
+     printf(\r
+#if DEBUG\r
+            "CacheSearch: "\r
+#endif\r
+           "Found "\r
+#if DEBUG\r
+            "cache 0x%08x "\r
+#endif\r
+            "item %d, file %s size 0x%08x\n",\r
+#if DEBUG\r
+            plt,\r
+#endif\r
+            *piItem, pszName, iFileSize(pftCacheItem(plt, *piItem)));\r
+     }\r
+\r
+inline void CacheReadIn(LISTTAG *plt, int *piItem, char *pszName)\r
+     {\r
+     if (fiCacheReadIn(plt, piItem, pszName) == FALSE)\r
+          {\r
+          printf("CacheReadIn: Could not read cache 0x%08x, file %s\n",\r
+                 plt, pszName);\r
+          exit(1);\r
+          }\r
+\r
+     printf(\r
+#if DEBUG\r
+            "CacheReadIn: "\r
+#endif\r
+           "Loaded "\r
+#if DEBUG\r
+            "cache 0x%08x "\r
+#endif\r
+            "item %d, file %s size 0x%08x\n",\r
+#if DEBUG\r
+            plt,\r
+#endif\r
+            *piItem, pszName, iFileSize(pftCacheItem(plt, *piItem)));\r
+     }\r
+\r
+inline void CacheWriteOut(LISTTAG *plt, int iItem, char *pszName)\r
+     {\r
+     if (fiCacheWriteOut(plt, iItem, pszName) == FALSE)\r
+          {\r
+          printf("CacheWriteOut: "\r
+                 "Could not write cache 0x%08x item %d, file %s\n",\r
+                 plt, iItem, pszName);\r
+          exit(1);\r
+          }\r
+\r
+     printf(\r
+#if DEBUG\r
+            "CacheWriteOut: "\r
+#endif\r
+            "Cached "\r
+#if DEBUG\r
+            "cache 0x%08x "\r
+#endif\r
+            "item %d, file %s size 0x%08x\n",\r
+#if DEBUG\r
+            plt,\r
+#endif\r
+            iItem, pszName, iFileSize(pftCacheItem(plt, iItem)));\r
+     }\r
+#endif\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+#endif\r
+\r
index f39efc3..df8e2e0 100644 (file)
@@ -51,29 +51,6 @@ int fiFileFree(FILETAG *pft)
 \r
 // ----------------------------------------------------------------------------\r
 \r
-int fiFileWriteOut(FILETAG *pft, char *pszName)\r
-     {\r
-     int iSize;\r
-     FSHANDLE fsh;\r
-\r
-     // attempt to create or truncate file for writing\r
-     if (fiFSCreate(&fsh, pszName) == FALSE)\r
-          {\r
-          return FALSE; // probably directory not found\r
-          }\r
-\r
-     // attempt to write the exact amount of data\r
-     iSize = iFileSize(pft);\r
-     if (iFSWrite(&fsh, pft->pcBase, iSize) != iSize)\r
-          {\r
-          fiFSClose(&fsh);\r
-          return FALSE;\r
-          }\r
-\r
-     fiFSClose(&fsh);\r
-     return TRUE; // says we wrote the file\r
-     }\r
-\r
 int fiFileReadIn(FILETAG *pft, char *pszName)\r
      {\r
      int iSize;\r
@@ -124,6 +101,29 @@ int fiFileReadIn(FILETAG *pft, char *pszName)
      return TRUE; // says we read the file\r
      }\r
 \r
+int fiFileWriteOut(FILETAG *pft, char *pszName)\r
+     {\r
+     int iSize;\r
+     FSHANDLE fsh;\r
+\r
+     // attempt to create or truncate file for writing\r
+     if (fiFSCreate(&fsh, pszName) == FALSE)\r
+          {\r
+          return FALSE; // probably directory not found\r
+          }\r
+\r
+     // attempt to write the exact amount of data\r
+     iSize = iFileSize(pft);\r
+     if (iFSWrite(&fsh, pft->pcBase, iSize) != iSize)\r
+          {\r
+          fiFSClose(&fsh);\r
+          return FALSE;\r
+          }\r
+\r
+     fiFSClose(&fsh);\r
+     return TRUE; // says we wrote the file\r
+     }\r
+\r
 // ----------------------------------------------------------------------------\r
 \r
 int fiFileCopy(FILETAG *pft, FILETAG *pftIn)\r
@@ -145,7 +145,7 @@ int fiFileCopy(FILETAG *pft, FILETAG *pftIn)
      i = pft->pcBase - pftIn->pcBase;\r
 \r
      // copy the entire file tag item data area, avoiding leaks\r
-     memcpy(pft, pftIn, iSize);\r
+     memcpy(pft, pftIn, sizeof(FILETAG));\r
 \r
      // apply the required adjustment to all fields of filetag\r
      pft->pcBase += i;\r
@@ -155,6 +155,10 @@ int fiFileCopy(FILETAG *pft, FILETAG *pftIn)
 \r
      // another slight adjustment because the copy trims to size\r
      pft->pcLimit = pft->pcAppend;\r
+\r
+     // copy the data area attached to the input file tag\r
+     memcpy(pft->pcBase, pftIn->pcBase, iSize);\r
+\r
      return TRUE; // indicates copied and new tag item filled out\r
      }\r
 \r
@@ -198,38 +202,6 @@ int fiFileCopyPadded(FILETAG *pft, FILETAG *pftIn, int iLeft, int iRight)
 \r
 // ----------------------------------------------------------------------------\r
 \r
-int fiFilePutLine(FILETAG *pft, char *pszLine)\r
-     {\r
-     int iTemp;\r
-\r
-     // calculate length once\r
-     iTemp = 0;\r
-     if (pszLine != NULL)\r
-          {\r
-          iTemp = strlen(pszLine);\r
-          }\r
-\r
-     // do not go past end of memory\r
-     if ((pft->pcPosition + iTemp + 2) > pft->pcLimit)\r
-          {\r
-          return FALSE;\r
-          }\r
-\r
-     // copy line and crlf terminator out to heap\r
-     if (pszLine != NULL)\r
-          {\r
-          memcpy(pft->pcPosition, pszLine, iTemp);\r
-          }\r
-     memcpy(pft->pcPosition + iTemp, "\r\n", 2);\r
-     pft->pcPosition += iTemp + 2;\r
-\r
-     // set file length possibly truncating\r
-     pft->pcAppend = pft->pcPosition;\r
-\r
-     // say we stored a line\r
-     return TRUE;\r
-     }\r
-\r
 int fiFileGetLine(FILETAG *pft, char *pszLine, int iLimit, int *piCount)\r
      {\r
      int i;\r
@@ -303,5 +275,37 @@ int fiFileGetLine(FILETAG *pft, char *pszLine, int iLimit, int *piCount)
      return TRUE;\r
      }\r
 \r
+int fiFilePutLine(FILETAG *pft, char *pszLine)\r
+     {\r
+     int iTemp;\r
+\r
+     // calculate length once\r
+     iTemp = 0;\r
+     if (pszLine != NULL)\r
+          {\r
+          iTemp = strlen(pszLine);\r
+          }\r
+\r
+     // do not go past end of memory\r
+     if ((pft->pcPosition + iTemp + 2) > pft->pcLimit)\r
+          {\r
+          return FALSE;\r
+          }\r
+\r
+     // copy line and crlf terminator out to heap\r
+     if (pszLine != NULL)\r
+          {\r
+          memcpy(pft->pcPosition, pszLine, iTemp);\r
+          }\r
+     memcpy(pft->pcPosition + iTemp, "\r\n", 2);\r
+     pft->pcPosition += iTemp + 2;\r
+\r
+     // set file length possibly truncating\r
+     pft->pcAppend = pft->pcPosition;\r
+\r
+     // say we stored a line\r
+     return TRUE;\r
+     }\r
+\r
 // ----------------------------------------------------------------------------\r
 \r
index 0d8a1dd..c59fcf2 100644 (file)
@@ -18,14 +18,14 @@ typedef struct
 int fiFileAllocate(FILETAG *pft, int iSize);\r
 int fiFileFree(FILETAG *pft);\r
 \r
-int fiFileWriteOut(FILETAG *pft, char *pszName);\r
 int fiFileReadIn(FILETAG *pft, char *pszName);\r
+int fiFileWriteOut(FILETAG *pft, char *pszName);\r
 \r
 int fiFileCopy(FILETAG *pft, FILETAG *pftIn);\r
 int fiFileCopyPadded(FILETAG *pft, FILETAG *pftIn, int iLeft, int iRight);\r
 \r
-int fiFilePutLine(FILETAG *pft, char *pszLine);\r
 int fiFileGetLine(FILETAG *pft, char *pszLine, int iLimit, int *piCount);\r
+int fiFilePutLine(FILETAG *pft, char *pszLine);\r
 \r
 // ----------------------------------------------------------------------------\r
 \r
@@ -43,13 +43,13 @@ inline void FileAllocate(FILETAG *pft, int iSize)
      {\r
      if (fiFileAllocate(pft, iSize) == FALSE)\r
           {\r
-          printf("FileAllocate: Could not allocate %08x bytes\n", iSize);\r
+          printf("FileAllocate: Could not allocate 0x%08x bytes\n", iSize);\r
           exit(1);\r
           }\r
 \r
-#ifdef DEBUG\r
+#if DEBUG\r
      printf("FileAllocate: "\r
-            "Allocated file %08x, %08x bytes\n", pft, iSize);\r
+            "Allocated file 0x%08x, 0x%08x bytes\n", pft, iSize);\r
 #endif\r
      }\r
 \r
@@ -57,15 +57,34 @@ inline void FileFree(FILETAG *pft)
      {\r
      if (fiFileFree(pft) == FALSE)\r
           {\r
-          printf("FileFree: Could not free file %08x\n", pft);\r
+          printf("FileFree: Could not free file 0x%08x\n", pft);\r
           exit(1);\r
           }\r
 \r
-#ifdef DEBUG\r
-     printf("FileFree: Freed file %08x\n", pft);\r
+#if DEBUG\r
+     printf("FileFree: Freed file 0x%08x\n", pft);\r
 #endif\r
      }\r
 \r
+inline void FileCopy(FILETAG *pft, FILETAG *pftIn)\r
+     {\r
+     if (fiFileCopy(pft, pftIn) == FALSE)\r
+          {\r
+          printf("FileCopy: Could not copy 0x%08x bytes\n", iFileSize(pftIn));\r
+          exit(1);\r
+          }\r
+     }\r
+\r
+inline void FileCopyPadded(FILETAG *pft, FILETAG *pftIn, int iLeft, int iRight)\r
+     {\r
+     if (fiFileCopyPadded(pft, pftIn, iLeft, iRight) == FALSE)\r
+          {\r
+          printf("FileCopyPadded: Could not copy 0x%08x bytes\n",\r
+                 iFileSize(pftIn) + iLeft + iRight);\r
+          exit(1);\r
+          }\r
+     }\r
+\r
 inline void FileReadIn(FILETAG *pft, char *pszName)\r
      {\r
      if (fiFileReadIn(pft, pszName) == FALSE)\r
@@ -75,11 +94,10 @@ inline void FileReadIn(FILETAG *pft, char *pszName)
           }\r
 \r
      printf(\r
-#ifdef DEBUG\r
+#if DEBUG\r
             "FileReadIn: "\r
 #endif\r
-           "Loaded %s, 0x%08x bytes\n",\r
-            pszName, pft->pcAppend - pft->pcBase);\r
+           "Loaded %s, 0x%08x bytes\n", pszName, iFileSize(pft));\r
      }\r
 \r
 inline void FileWriteOut(FILETAG *pft, char *pszName)\r
@@ -91,31 +109,10 @@ inline void FileWriteOut(FILETAG *pft, char *pszName)
           }\r
 \r
      printf(\r
-#ifdef DEBUG\r
+#if DEBUG\r
             "FileWriteOut: "\r
 #endif\r
-            "Created %s, 0x%08x bytes\n",\r
-            pszName, pft->pcAppend - pft->pcBase);\r
-     }\r
-\r
-inline void FileCopy(FILETAG *pft, FILETAG *pftIn)\r
-     {\r
-     if (fiFileCopy(pft, pftIn) == FALSE)\r
-          {\r
-          printf("FileCopy: Could not copy 0x%08x bytes\n",\r
-                 pftIn->pcAppend - pftIn->pcBase);\r
-          exit(1);\r
-          }\r
-     }\r
-\r
-inline void FileCopyPadded(FILETAG *pft, FILETAG *pftIn, int iLeft, int iRight)\r
-     {\r
-     if (fiFileCopyPadded(pft, pftIn, iLeft, iRight) == FALSE)\r
-          {\r
-          printf("FileCopyPadded: Could not copy 0x%08x bytes\n",\r
-                 (pftIn->pcAppend - pftIn->pcBase) + iLeft + iRight);\r
-          exit(1);\r
-          }\r
+            "Created %s, 0x%08x bytes\n", pszName, iFileSize(pft));\r
      }\r
 #endif\r
 \r
index cb85160..8ed943f 100644 (file)
@@ -48,7 +48,7 @@ inline void FSOpen(FSHANDLE *pfsh, char *pszName)
           }\r
 \r
      printf("FSOpen: "\r
-            "Handle %08x file %s opened, read mode\n", pfsh, pszName);\r
+            "Handle 0x%08x file %s opened, read mode\n", pfsh, pszName);\r
      }\r
 \r
 inline void FSCreate(FSHANDLE *pfsh, char *pszName)\r
@@ -61,7 +61,7 @@ inline void FSCreate(FSHANDLE *pfsh, char *pszName)
           }\r
 \r
      printf("FSCreate: "\r
-            "Handle %08x file %s opened, write mode\n", pfsh, pszName);\r
+            "Handle 0x%08x file %s opened, write mode\n", pfsh, pszName);\r
      }\r
 \r
 inline void FSClose(FSHANDLE *pfsh)\r
@@ -69,12 +69,12 @@ inline void FSClose(FSHANDLE *pfsh)
      if (fiFSClose(pfsh) == 0)\r
           {\r
           printf("FSClose: "\r
-                 "Could not close handle %08x, exiting\n", pfsh);\r
+                 "Could not close handle 0x%08x, exiting\n", pfsh);\r
           exit(1);\r
           }\r
 \r
      printf("FSClose: "\r
-            "Handle %08x file %s closed, %s mode\n",\r
+            "Handle 0x%08x file %s closed, %s mode\n",\r
             pfsh, pfsh->pszName, pfsh->iMode ? "write" : "read");\r
 \r
      printf("Loaded file %s, size %d bytes\n",\r
@@ -89,13 +89,13 @@ inline void FSRead(FSHANDLE *pfsh, char *pcOut, int iLimit)
      if (iCount != iLimit)\r
           {\r
           printf("FSRead: "\r
-                 "End of file, handle %08x, request %d, return %d\n",\r
+                 "End of file, handle 0x%08x, request %d, return %d\n",\r
                  pfsh, iLimit, iCount);\r
           exit(1);\r
           }\r
 \r
      printf("FSRead: "\r
-            "Handle %08x file %s read, request %d, return %d\n",\r
+            "Handle 0x%08x file %s read, request %d, return %d\n",\r
             pfsh, pfsh->pszName, iLimit, iCount);\r
      }\r
 \r
@@ -107,13 +107,13 @@ inline void FSWrite(FSHANDLE *pfsh, char *pcIn, int iLimit)
      if (iCount != iLimit)\r
           {\r
           printf("FSWrite: "\r
-                 "Disk full, handle %08x, request %d, return %d\n",\r
+                 "Disk full, handle 0x%08x, request %d, return %d\n",\r
                  pfsh, iLimit, iCount);\r
           exit(1);\r
           }\r
 \r
      printf("FSWrite: "\r
-            "Handle %08x file %s written, request %d, return %d\n",\r
+            "Handle 0x%08x file %s written, request %d, return %d\n",\r
             pfsh, pfsh->pszName, iLimit, iCount);\r
      }\r
 \r
diff --git a/src/mkfont/hylist.cpp b/src/mkfont/hylist.cpp
new file mode 100644 (file)
index 0000000..75f55e7
--- /dev/null
@@ -0,0 +1,201 @@
+// hylist.cpp\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+#include <io.h>\r
+#include <fcntl.h>\r
+#include <sys/stat.h>\r
+#include <stdio.h>\r
+#include <windows.h>\r
+#pragma hdrstop\r
+#include "hymb.h"\r
+#include "hyfs.h"\r
+#include "hylist.h"\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+int fiListAllocate(LISTTAG *plt, int iItemCount, int iItemSize)\r
+     {\r
+     // zero the entire list tag item data area, avoiding leaks\r
+     memset(plt, 0, sizeof(LISTTAG));\r
+\r
+     // allocate via the lower level wrapper, relying on the fact\r
+     // that the LISTTAG structure is compatible with MBHANDLE !!\r
+     if (fiMBAlloc((MBHANDLE *) plt, iItemCount * iItemSize) == 0)\r
+          {\r
+          return FALSE; // indicates failure to allocate block\r
+          }\r
+\r
+     // set position to start and list to null\r
+     plt->iBase = 0;\r
+     plt->iLimit = iItemCount;\r
+     plt->iPosition = 0;\r
+     plt->iAppend = 0;\r
+\r
+     // save the item size for use in addressing calcuations\r
+     plt->iItemSize = iItemSize;\r
+\r
+     // say it is now allocated\r
+     return TRUE;\r
+     }\r
+\r
+int fiListFree(LISTTAG *plt)\r
+     {\r
+     // free via the lower level wrapper, relying on the fact\r
+     // that the LISTTAG structure is compatible with MBHANDLE !!\r
+     if (fiMBFree((MBHANDLE *) plt) == 0)\r
+          {\r
+          return FALSE; // indicates failure to free block\r
+          }\r
+\r
+     // zero the entire list tag item data area, avoiding leaks\r
+     memset(plt, 0, sizeof(LISTTAG));\r
+\r
+     return TRUE; // indicates block freed and tag item zeroed\r
+     }\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+int fiListReadIn(LISTTAG *plt, char *pszName, int iItemSize)\r
+     {\r
+     int iSize;\r
+     FSHANDLE fsh;\r
+\r
+     // zero the entire list tag item data area, avoiding leaks\r
+     memset(plt, 0, sizeof(LISTTAG));\r
+\r
+     // attempt to open list for reading, get size\r
+     if (fiFSOpen(&fsh, pszName) == FALSE)\r
+          {\r
+          return FALSE; // probably file not found\r
+          }\r
+     iSize = filelength(fsh.iHandle); // assume can get size\r
+\r
+#if 0\r
+     // sanity check for list much too large\r
+     if (iSize > 0x100000) // 1 megabyte\r
+          {\r
+          fiFSClose(&fsh);\r
+          return FALSE;\r
+          }\r
+#endif\r
+\r
+     // allocate heap to hold entire list\r
+     // note: simpler than the array or pool implementation,\r
+     // because the original limit, position, append info lost\r
+     if (fiListAllocate(plt, (iSize + iItemSize - 1) / iItemSize,\r
+                             iItemSize) == FALSE)\r
+          {\r
+          fiFSClose(&fsh);\r
+          return FALSE;\r
+          }\r
+\r
+     // attempt read the exact amount of data\r
+     if (iFSRead(&fsh, plt->pcBase, iSize) != iSize)\r
+          {\r
+          fiListFree(plt);\r
+          fiFSClose(&fsh);\r
+          return FALSE;\r
+          }\r
+\r
+     fiFSClose(&fsh);\r
+\r
+     // set position to start and length to length read\r
+     plt->iBase = 0;\r
+     plt->iLimit = (iSize + iItemSize - 1) / iItemSize;\r
+     plt->iPosition = 0;\r
+     plt->iAppend = iSize / iItemSize;\r
+\r
+     // save the item size for use in addressing calcuations\r
+     plt->iItemSize = iItemSize;\r
+\r
+     return TRUE; // says we read the list\r
+     }\r
+\r
+int fiListWriteOut(LISTTAG *plt, char *pszName)\r
+     {\r
+     int iSize;\r
+     FSHANDLE fsh;\r
+\r
+     // attempt to create or truncate list for writing\r
+     if (fiFSCreate(&fsh, pszName) == FALSE)\r
+          {\r
+          return FALSE; // probably directory not found\r
+          }\r
+\r
+     // attempt to write the exact amount of data\r
+     iSize = iListSize(plt) * plt->iItemSize;\r
+     if (iFSWrite(&fsh, plt->pcBase, iSize) != iSize)\r
+          {\r
+          fiFSClose(&fsh);\r
+          return FALSE;\r
+          }\r
+\r
+     fiFSClose(&fsh);\r
+     return TRUE; // says we wrote the list\r
+     }\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+int fiListCopy(LISTTAG *plt, LISTTAG *pltIn, int iItemSize)\r
+     {\r
+     int i, iSize;\r
+\r
+     // zero the entire list tag item data area, avoiding leaks\r
+     memset(plt, 0, sizeof(LISTTAG));\r
+\r
+     // allocate via the lower level wrapper, relying on the fact\r
+     // that the LISTTAG structure is compatible with MBHANDLE !!\r
+     iSize = iListSize(pltIn) * pltIn->iItemSize;\r
+     if (fiMBAlloc((MBHANDLE *) plt, iSize) == FALSE)\r
+          {\r
+          return FALSE; // indicates failure to allocate block\r
+          }\r
+\r
+     // calculate the required adjustment, before clobbering plt!\r
+     i = plt->pcBase - pltIn->pcBase;\r
+\r
+     // copy the entire list tag item data area, avoiding leaks\r
+     memcpy(plt, pltIn, sizeof(LISTTAG));\r
+\r
+     // apply the required adjustment to all fields of listtag\r
+     plt->pcBase += i;\r
+\r
+     // another slight adjustment because the copy trims to size\r
+     plt->pcLimit = plt->pcBase + iSize;\r
+     plt->iLimit = iSize;\r
+\r
+     // copy the data area attached to the input list tag\r
+     memcpy(plt->pcBase, pltIn->pcBase, iSize);\r
+\r
+     return TRUE; // indicates copied and new tag item filled out\r
+     }\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+char *pcListCanGet(LISTTAG *plt)\r
+     {\r
+     if (plt->iPosition >= plt->iAppend)\r
+          {\r
+          return NULL; // indicates no more items available in list\r
+          }\r
+\r
+     return pcListItem(plt, plt->iPosition++);\r
+     }\r
+\r
+char *pcListCanPut(LISTTAG *plt)\r
+     {\r
+     char *pc;\r
+\r
+     if (plt->iAppend >= plt->iLimit)\r
+          {\r
+          return NULL; // indicates no room to append a new item\r
+          }\r
+\r
+     pc = pcListItem(plt, plt->iAppend++);\r
+     memset(pc, 0, plt->iItemSize);\r
+     return pc;\r
+     }\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
diff --git a/src/mkfont/hylist.h b/src/mkfont/hylist.h
new file mode 100644 (file)
index 0000000..ceead3e
--- /dev/null
@@ -0,0 +1,154 @@
+// hylist.h\r
+\r
+#ifndef _INC_HYLIST\r
+#define _INC_HYLIST\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+typedef struct\r
+{\r
+     char *pcBase;                 // also the handle for the malloc'd buffer\r
+     char *pcLimit;                // offset just after end of malloc'd buffer\r
+\r
+     int iBase; // usually 0 unless client wants to do advanced looping\r
+     int iLimit; // iAppend or larger if block is of arbitrary size\r
+     int iPosition; // for general use, initialised to 0 for client\r
+     int iAppend; // calculated for client, pbih->biHeight * iSamplesLine\r
+\r
+     int iItemSize; // bytes per item, to convert above into char pointers\r
+} LISTTAG;\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+int fiListAllocate(LISTTAG *plt, int iItemCount, int iItemSize);\r
+int fiListFree(LISTTAG *plt);\r
+\r
+int fiListReadIn(LISTTAG *plt, char *pszName, int iItemSize);\r
+int fiListWriteOut(LISTTAG *plt, char *pszName);\r
+\r
+int fiListCopy(LISTTAG *plt, LISTTAG *pltIn);\r
+\r
+char *pcListCanGet(LISTTAG *plt);\r
+char *pcListCanPut(LISTTAG *plt);\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+inline int iListSize(LISTTAG *plt)\r
+     {\r
+     // return size in bytes, for use by ListReadIn etc family\r
+     return plt->iAppend /*- plt->iBase*/; // note: the trimmed size\r
+     }\r
+\r
+inline char *pcListItem(LISTTAG *plt, int iItem)\r
+     {\r
+     // return pointer to start of item, caller has to cast it\r
+     return plt->pcBase + iItem * plt->iItemSize;\r
+     }\r
+\r
+inline char *pcListGet(LISTTAG *plt)\r
+     {\r
+     char *pc;\r
+\r
+     pc = pcListCanGet(plt);\r
+     if (pc == NULL)\r
+          {\r
+          printf("pcListGet: Could not read from list 0x%08x\n", plt);\r
+          exit(1);\r
+          }\r
+     return pc;\r
+     }\r
+\r
+inline char *pcListPut(LISTTAG *plt)\r
+     {\r
+     char *pc;\r
+\r
+     pc = pcListCanPut(plt);\r
+     if (pc == NULL)\r
+          {\r
+          printf("pcListPut: Could not append to list 0x%08x\n", plt);\r
+          exit(1);\r
+          }\r
+     return pc;\r
+     }\r
+\r
+// ----------------------------------------------------------------------------\r
+// handy functions for the client, not important to the interface:\r
+\r
+#ifdef _INC_STDIO\r
+inline void ListAllocate(LISTTAG *plt, int iItemCount, int iItemSize)\r
+     {\r
+     if (fiListAllocate(plt, iItemCount, iItemSize) == FALSE)\r
+          {\r
+          printf("ListAllocate: "\r
+                 "Could not allocate 0x%08x items of 0x%08x bytes\n",\r
+                 iItemCount, iItemSize);\r
+          exit(1);\r
+          }\r
+\r
+#if DEBUG\r
+     printf("ListAllocate: "\r
+            "Allocated list 0x%08x, 0x%08x items of 0x%08x bytes\n",\r
+            plt, iItemCount, iItemSize);\r
+#endif\r
+     }\r
+\r
+inline void ListFree(LISTTAG *plt)\r
+     {\r
+     if (fiListFree(plt) == FALSE)\r
+          {\r
+          printf("ListFree: Could not free list 0x%08x\n", plt);\r
+          exit(1);\r
+          }\r
+\r
+#if DEBUG\r
+     printf("ListFree: Freed list 0x%08x\n", plt);\r
+#endif\r
+     }\r
+\r
+inline void ListCopy(LISTTAG *plt, LISTTAG *pltIn)\r
+     {\r
+     if (fiListCopy(plt, pltIn) == FALSE)\r
+          {\r
+          printf("ListCopy: Could not copy 0x08x items of 0x%08x bytes\n",\r
+                 iListSize(pltIn), pltIn->iItemSize);\r
+          exit(1);\r
+          }\r
+     }\r
+\r
+inline void ListReadIn(LISTTAG *plt, char *pszName, int iItemSize)\r
+     {\r
+     if (fiListReadIn(plt, pszName, iItemSize) == FALSE)\r
+          {\r
+          printf("ListReadIn: Could not read %s\n", pszName);\r
+          exit(1);\r
+          }\r
+\r
+     printf(\r
+#if DEBUG\r
+            "ListReadIn: "\r
+#endif\r
+           "Loaded %s, 0x%08x items of 0x%08x bytes\n",\r
+            pszName, iListSize(plt), iItemSize);\r
+     }\r
+\r
+inline void ListWriteOut(LISTTAG *plt, char *pszName)\r
+     {\r
+     if (fiListWriteOut(plt, pszName) == FALSE)\r
+          {\r
+          printf("ListWriteOut: Could not write %s\n", pszName);\r
+          exit(1);\r
+          }\r
+\r
+     printf(\r
+#if DEBUG\r
+            "ListWriteOut: "\r
+#endif\r
+            "Created %s, 0x%08x items of 0x%08x bytes\n",\r
+            pszName, iListSize(plt), plt->iItemSize);\r
+     }\r
+#endif\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+#endif\r
+\r
index 86e60e6..66d4e64 100644 (file)
@@ -48,13 +48,13 @@ inline void MBAlloc(MBHANDLE *pmbh, int iBytes)
      if (fiMBAlloc(pmbh, iBytes) == FALSE)\r
           {\r
           printf("MBAlloc: "\r
-                 "Could not allocate %08x bytes, exiting\n", iBytes);\r
+                 "Could not allocate 0x%08x bytes, exiting\n", iBytes);\r
           exit(1);\r
           }\r
 \r
-#ifdef DEBUG\r
+#if DEBUG\r
      printf("MBAlloc: "\r
-            "Allocated memory block %08x size %08x\n", pmbh, iBytes);\r
+            "Allocated memory block 0x%08x size 0x%08x\n", pmbh, iBytes);\r
 #endif\r
      }\r
 \r
@@ -63,13 +63,13 @@ inline void MBRealloc(MBHANDLE *pmbh, int iBytes)
      if (fiMBRealloc(pmbh, iBytes) == FALSE)\r
           {\r
           printf("MBRealloc: "\r
-                 "Could not reallocate %08x bytes, exiting\n", iBytes);\r
+                 "Could not reallocate 0x%08x bytes, exiting\n", iBytes);\r
           exit(1);\r
           }\r
 \r
-#ifdef DEBUG\r
+#if DEBUG\r
      printf("MBRealloc: "\r
-            "Reallocated memory block %08x size %08x\n", pmbh, iBytes);\r
+            "Reallocated memory block 0x%08x size 0x%08x\n", pmbh, iBytes);\r
 #endif\r
      }\r
 \r
@@ -78,13 +78,13 @@ inline void MBFree(MBHANDLE *pmbh)
      if (fiMBFree(pmbh) == FALSE)\r
           {\r
           printf("MBFree: "\r
-                 "Could not free memory block %08x, exiting\n", pmbh);\r
+                 "Could not free memory block 0x%08x, exiting\n", pmbh);\r
           exit(1);\r
           }\r
 \r
-#ifdef DEBUG\r
+#if DEBUG\r
      printf("MBFree: "\r
-            "Freed memory block %08x\n", pmbh);\r
+            "Freed memory block 0x%08x\n", pmbh);\r
 #endif\r
      }\r
 #endif\r
diff --git a/src/mkfont/hystring.cpp b/src/mkfont/hystring.cpp
new file mode 100644 (file)
index 0000000..9efcd3f
--- /dev/null
@@ -0,0 +1,192 @@
+// hystring.cpp\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+#include <windows.h>\r
+#pragma hdrstop\r
+#include "hystring.h"\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+int fiStringEqual(char *psz0, int iCount0, char *psz1, int iCount1)\r
+     {\r
+     if (iCount0 != iCount1)\r
+          return FALSE;\r
+\r
+     return memcmp(psz0, psz1, iCount0) == 0;\r
+     }\r
+\r
+int iStringCompare(char *psz0, int iCount0, char *psz1, int iCount1)\r
+     {\r
+     if (iCount0 < iCount1)\r
+          return memcmp(psz0, psz1, iCount0) > 0 ? 1 : -1;\r
+\r
+     if (iCount0 > iCount1)\r
+          return memcmp(psz0, psz1, iCount1) < 0 ? -1 : 1;\r
+\r
+     return memcmp(psz0, psz1, iCount0);\r
+     }\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+void StringCopy(char *psz, char *pszIn, int iCount)\r
+     {\r
+     int i;\r
+\r
+     // copy as much as we can\r
+     for (i = 0; i < iCount; i++)\r
+          {\r
+          if (pszIn[i] == 0)\r
+               {\r
+               break;\r
+               }\r
+\r
+          psz[i] = pszIn[i];\r
+          }\r
+\r
+     // terminate the string politely\r
+     psz[i] = 0;\r
+     }\r
+\r
+int iStringAppend(int iIndex, char *psz, int iLimit, char *pszIn, int iCount)\r
+     {\r
+     int i;\r
+\r
+     if (iIndex >= iLimit)\r
+          {\r
+          return iIndex; // in this case no terminator can be saved\r
+          }\r
+\r
+     iCount = min(iCount, iLimit - iIndex);\r
+     if (iCount < 1)\r
+          {\r
+          psz[iIndex] = 0;\r
+          return iIndex;\r
+          }\r
+\r
+     // copy as much as we can\r
+     for (i = 0; i < iCount; i++)\r
+          {\r
+          if (pszIn[iIndex + i] == 0)\r
+               {\r
+               break;\r
+               }\r
+\r
+          psz[iIndex + i] = pszIn[iIndex + i];\r
+          }\r
+\r
+     // terminate the string politely\r
+     iIndex += iCount;\r
+     if (iIndex < iLimit)\r
+          {\r
+          psz[iIndex] = 0;\r
+          }\r
+\r
+     return iIndex;\r
+     }\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+void StringToLower(char *psz, char *pszIn, int iCount)\r
+     {\r
+     int i;\r
+\r
+     // copy as much as we can\r
+     for (i = 0; i < iCount; i++)\r
+          {\r
+          if (pszIn[i] == 0)\r
+               {\r
+               break;\r
+               }\r
+\r
+          // convert to lower case in the process\r
+          psz[i] = tolower(pszIn[i]);\r
+          }\r
+\r
+     // terminate the string politely\r
+     psz[i] = 0;\r
+     }\r
+\r
+void StringToUpper(char *psz, char *pszIn, int iCount)\r
+     {\r
+     int i;\r
+\r
+     // copy as much as we can\r
+     for (i = 0; i < iCount; i++)\r
+          {\r
+          if (pszIn[i] == 0)\r
+               {\r
+               break;\r
+               }\r
+\r
+          // convert to upper case in the process\r
+          psz[i] = toupper(pszIn[i]);\r
+          }\r
+\r
+     // terminate the string politely\r
+     psz[i] = 0;\r
+     }\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+int iStringIsolate(int iIndex, char *psz, int iLimit,\r
+                   char **ppsz, int *piCount)\r
+     {\r
+     int i, j, iCount;\r
+\r
+     iCount = iLimit - iIndex;\r
+     if (iCount < 1)\r
+          {\r
+          *ppsz = NULL;\r
+          *piCount = 0;\r
+          return iIndex;\r
+          }\r
+\r
+     // scan past any leading whitespace\r
+     for (i = 0; i < iCount; i++)\r
+          {\r
+          switch (psz[iIndex + i])\r
+               {\r
+          case 0x09:\r
+          case 0x0a:\r
+          case 0x0c:\r
+          case 0x0d:\r
+          case 0x20:\r
+               continue;\r
+               }\r
+          break;\r
+          }\r
+\r
+     // scan past as much argument text as possible\r
+     j = i;\r
+     for (; i < iCount; i++)\r
+          {\r
+          switch (psz[iIndex + i])\r
+               {\r
+          case 0x00: // in this case terminator is also a condition\r
+          case 0x09:\r
+          case 0x0a:\r
+          case 0x0c:\r
+          case 0x0d:\r
+          case 0x20:\r
+               goto mybreak;\r
+               }\r
+          }\r
+mybreak:\r
+\r
+     // validate length, as argument must have length to exist\r
+     if (i <= j)\r
+          {\r
+          *ppsz = NULL;\r
+          *piCount = 0;\r
+          return iIndex + i;\r
+          }\r
+\r
+     // valid argument, so return start and length to caller\r
+     *ppsz = psz + iIndex + j;\r
+     *piCount = i - j;\r
+     return iIndex + i;\r
+     }\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
diff --git a/src/mkfont/hystring.h b/src/mkfont/hystring.h
new file mode 100644 (file)
index 0000000..795d353
--- /dev/null
@@ -0,0 +1,19 @@
+// hystring.h\r
+\r
+// ----------------------------------------------------------------------------\r
+// prototypes for hystring.cpp\r
+\r
+int fiStringEqual(char *psz0, int iCount0, char *psz1, int iCount1);\r
+int iStringCompare(char *psz0, int iCount0, char *psz1, int iCount1);\r
+\r
+void StringCopy(char *psz, char *pszIn, int iCount);\r
+int iStringAppend(int iIndex, char *psz, int iLimit, char *pszIn, int iCount);\r
+\r
+void StringToLower(char *psz, char *pszIn, int iCount);\r
+void StringToUpper(char *psz, char *pszIn, int iCount);\r
+\r
+int iStringIsolate(int iIndex, char *psz, int iLimit,\r
+                   char **ppsz, int *piCount);\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
index c01cf7b..72c50ba 100644 (file)
@@ -1,12 +1,20 @@
-cl -Zi -I. bmp2txt.cpp hyimage.cpp hyfile.cpp hyfs.cpp hymb.cpp\r
+cl -Zi -TP -I. -DDEBUG=0 hfmdump.c hfmlib.c\r
+@if errorlevel 1 goto failure\r
+copy hfmdump.exe ..\bin\r
+\r
+cl -Zi -I. -DDEBUG=0 hfmtool.cpp hfmlib.obj bmp2txt.cpp txt2chs.cpp chs2cmd.cpp hystring.cpp hycache.cpp hylist.cpp hyimage.cpp hyfile.cpp hyfs.cpp hymb.cpp\r
+@if errorlevel 1 goto failure\r
+copy hfmtool.exe ..\bin\r
+\r
+cl -Zi -I. -DDEBUG=0 -DSTANDALONE bmp2txt.cpp hycache.obj hylist.obj hyimage.obj hyfile.obj hyfs.obj hymb.obj\r
 @if errorlevel 1 goto failure\r
 copy bmp2txt.exe ..\bin\r
 \r
-cl -Zi -I. txt2chs.cpp hyfile.cpp hyfs.cpp hymb.cpp\r
+cl -Zi -I. -DDEBUG=0 -DSTANDALONE txt2chs.cpp hycache.obj hylist.obj hyfile.obj hyfs.obj hymb.obj\r
 @if errorlevel 1 goto failure\r
 copy txt2chs.exe ..\bin\r
 \r
-cl -Zi -I. chs2cmd.cpp hyfile.cpp hyfs.cpp hymb.cpp\r
+cl -Zi -I. -DDEBUG=0 -DSTANDALONE chs2cmd.cpp hycache.obj hylist.obj hyfile.obj hyfs.obj hymb.obj\r
 @if errorlevel 1 goto failure\r
 copy chs2cmd.exe ..\bin\r
 \r
diff --git a/src/mkfont/t.bat b/src/mkfont/t.bat
new file mode 100644 (file)
index 0000000..1cfcd86
--- /dev/null
@@ -0,0 +1 @@
+gcc hdmlib.c hfmlib.c -o hdmlib.exe\r
index 46f6c4a..b114d5c 100644 (file)
@@ -8,30 +8,77 @@
 #include <stdlib.h>\r
 #include <windows.h>\r
 #pragma hdrstop\r
+\r
+#ifndef DEBUG\r
+#define DEBUG 0\r
+#endif\r
+\r
 #include "hymb.h"\r
 #include "hyfs.h"\r
 #include "hyfile.h"\r
+#include "hylist.h"\r
+#include "hycache.h"\r
+#include "txt2chs.h"\r
+\r
+// ----------------------------------------------------------------------------\r
+// local preprocessor definitions\r
+\r
+#define LINE_MAX       0x200\r
+#define PATH_MAX       0x200\r
+\r
+#define CACHE_MAX      0x10 // note:  this is smaller than hfmtool's setting\r
 \r
+#define OUTPUT_BUFFER  0x10000 // to create output files of up to 64 kbytes\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+#ifdef STANDALONE\r
 int main(int argc, char **argv);\r
-int fiProcess(FILETAG *ftOut, FILETAG *ftIn, int iICS, int iILS);\r
-int iCompare(const void *pvLeft, const void *pvRight);\r
-int iUpdateCRC(char *pcBase, int iCount, int iCRC);\r
+#endif\r
+static int fiProcess(FILETAG *pftOut, FILETAG *pftIn, int iICS, int iILS);\r
+static int iCompare(const void *pvLeft, const void *pvRight);\r
+static int iUpdateCRC(char *pcBase, int iCount, int iCRC);\r
 \r
 // ----------------------------------------------------------------------------\r
 \r
-FILETAG ftIn;\r
-char *pszInFileName;\r
+#ifdef STANDALONE\r
+int main(int argc, char **argv)\r
+       {\r
+       int i;\r
+        LISTTAG ltCache;\r
+\r
+       // set up the cache to track intermediate memory files\r
+        CacheEntrySetup(&ltCache, CACHE_MAX);\r
 \r
-FILETAG ftOut;\r
-char *pszOutFileName;\r
-char szOutFileName[512];\r
+       // run the real program, passing in the cache descriptor\r
+       i = iTxt2Chs(&ltCache, argc, argv);\r
+\r
+       // it just goes on and on my friend\r
+       CacheExitFlush(&ltCache, 3); // force writing of intermediate files\r
+       CacheExitCleanup(&ltCache); // deallocate memory, though it's redundant\r
+\r
+       return i;\r
+       }\r
+#endif\r
 \r
 // ----------------------------------------------------------------------------\r
 \r
-int main(int argc, char **argv)\r
+int iTxt2Chs(LISTTAG *pltCache, int argc, char **argv)\r
        {\r
        int i, iICS, iILS;\r
 \r
+       int iCacheIn;\r
+       FILETAG *pftIn;\r
+       char *pszInFileName;\r
+\r
+       int iCacheOut;\r
+       FILETAG *pftOut;\r
+       char *pszOutFileName;\r
+       char szOutFileName[PATH_MAX];\r
+\r
+       pszInFileName = NULL;\r
+       pszOutFileName = NULL;\r
+\r
        if (argc > 1)\r
                {\r
                pszInFileName = argv[1];\r
@@ -41,8 +88,8 @@ int main(int argc, char **argv)
        iILS = 0;\r
        if (argc > 2)\r
                {\r
-               iICS = atoi(argv[2]);\r
-               if (iICS < 1 || iICS > 0xff)\r
+               i = atoi(argv[2]);\r
+               if (i < 1 || i > 0xff)\r
                        {\r
                        pszOutFileName = argv[2];\r
                        if (argc > 3)\r
@@ -56,6 +103,7 @@ int main(int argc, char **argv)
                        }\r
                else\r
                        {\r
+                       iICS = i;\r
                        if (argc > 3)\r
                                {\r
                                iILS = atoi(argv[3]);\r
@@ -97,34 +145,33 @@ int main(int argc, char **argv)
                exit(1);\r
                }\r
 \r
-       // read the input bmp file entirely to a malloc'd block\r
-       FileReadIn(&ftIn, pszInFileName);\r
+       // read the input txt file entirely to a malloc'd block\r
+       CacheReadIn(pltCache, &iCacheIn, pszInFileName);\r
+       pftIn = pftCacheItem(pltCache, iCacheIn);\r
 \r
        // prepare an output buffer for character set data\r
-       FileAllocate(&ftOut, 0x100000); // 64 kbytes\r
+       CacheAllocate(pltCache, &iCacheOut, OUTPUT_BUFFER);\r
+       pftOut = pftCacheItem(pltCache, iCacheOut);\r
 \r
        // search for characters and write character set files\r
-       if (fiProcess(&ftOut, &ftIn, iICS, iILS) == FALSE)\r
+       if (fiProcess(pftOut, pftIn, iICS, iILS) == FALSE)\r
                {\r
                exit(1);\r
                }\r
 \r
        // ready to write the output we found\r
-       FileWriteOut(&ftOut, pszOutFileName);\r
-\r
-       // all done my friend\r
-       FileFree(&ftIn);\r
-       FileFree(&ftOut);\r
+       CacheWriteOut(pltCache, iCacheOut, pszOutFileName);\r
 \r
+       // and now they'll all be singing it forever just because\r
        return 0;\r
        }\r
 \r
 // ----------------------------------------------------------------------------\r
 \r
-int fiProcess(FILETAG *pftOut, FILETAG *pftIn, int iICS, int iILS)\r
+static int fiProcess(FILETAG *pftOut, FILETAG *pftIn, int iICS, int iILS)\r
        {\r
        char *pc;\r
-       char sz[0x203];\r
+       char sz[LINE_MAX+3];\r
        int i, j, c, d;\r
        int x, y, cx, cy;\r
        int tx, ty, bx, fx;\r
@@ -140,6 +187,7 @@ int fiProcess(FILETAG *pftOut, FILETAG *pftIn, int iICS, int iILS)
 \r
        strcpy(pc, "XXXXYYMMDDHHMMSS");\r
        pc += 0x10;\r
+\r
        pus = (unsigned short *)pc;\r
        memset(pc, 0, 0x208);\r
        pc += 0x208;\r
@@ -147,43 +195,43 @@ int fiProcess(FILETAG *pftOut, FILETAG *pftIn, int iICS, int iILS)
        // create the microspace characters\r
        *pc++ = 1; // inter character space should be ignored here\r
        pus[1] = pc - (char *)pus;\r
-       *pc++ = 0x60; // indicates we have width but nothing else\r
+       *pc++ = 0x20; // indicates we have width but nothing else\r
 \r
        *pc++ = 2; // inter character space should be ignored here\r
        pus[2] = pc - (char *)pus;\r
-       *pc++ = 0x60; // indicates we have width but nothing else\r
+       *pc++ = 0x20; // indicates we have width but nothing else\r
 \r
        *pc++ = 3; // inter character space should be ignored here\r
        pus[3] = pc - (char *)pus;\r
-       *pc++ = 0x60; // indicates we have width but nothing else\r
+       *pc++ = 0x20; // indicates we have width but nothing else\r
 \r
        *pc++ = 4; // inter character space should be ignored here\r
        pus[4] = pc - (char *)pus;\r
-       *pc++ = 0x60; // indicates we have width but nothing else\r
+       *pc++ = 0x20; // indicates we have width but nothing else\r
 \r
        *pc++ = -4; // inter character space should be ignored here\r
        pus[5] = pc - (char *)pus;\r
-       *pc++ = 0x60; // indicates we have width but nothing else\r
+       *pc++ = 0x20; // indicates we have width but nothing else\r
 \r
        *pc++ = -3; // inter character space should be ignored here\r
        pus[6] = pc - (char *)pus;\r
-       *pc++ = 0x60; // indicates we have width but nothing else\r
+       *pc++ = 0x20; // indicates we have width but nothing else\r
 \r
        *pc++ = -2; // inter character space should be ignored here\r
        pus[7] = pc - (char *)pus;\r
-       *pc++ = 0x60; // indicates we have width but nothing else\r
+       *pc++ = 0x20; // indicates we have width but nothing else\r
 \r
        *pc++ = -1; // inter character space should be ignored here\r
        pus[8] = pc - (char *)pus;\r
-       *pc++ = 0x60; // indicates we have width but nothing else\r
+       *pc++ = 0x20; // indicates we have width but nothing else\r
 \r
        *pc++ = 12; // inter character space should be ignored here\r
        pus[0x1c] = pc - (char *)pus;\r
-       *pc++ = 0x60; // indicates we have width but nothing else\r
+       *pc++ = 0x20; // indicates we have width but nothing else\r
 \r
        *pc++ = -12; // inter character space should be ignored here\r
        pus[0x1d] = pc - (char *)pus;\r
-       *pc++ = 0x60; // indicates we have width but nothing else\r
+       *pc++ = 0x20; // indicates we have width but nothing else\r
 \r
        if (iICS < 1 || iICS > 0xff)\r
                {\r
@@ -256,8 +304,10 @@ int fiProcess(FILETAG *pftOut, FILETAG *pftIn, int iICS, int iILS)
 \r
                        tx = max(0, x1 - x0); // trimmed width in pixels\r
                        ty = max(0, y1 - y0); // trimmed height in pixels\r
+#if DEBUG\r
                        printf("at %d,%d trim %d,%d origin %d,%d\n",\r
                               x0, y0, tx, ty, x2, y2);\r
+#endif\r
 \r
                        iWidth[d] = tx; // save for median calculation\r
                        iHeight[d] = ty; // save for median calculation\r
@@ -327,8 +377,6 @@ int fiProcess(FILETAG *pftOut, FILETAG *pftIn, int iICS, int iILS)
                        }\r
                }\r
 \r
-       printf("%d characters in range %d,%d inclusive\n", d, 0x21, c - 1);\r
-\r
        // post process widths/heights now we've had all characters\r
        mx = 0;\r
        my = 0;\r
@@ -341,13 +389,18 @@ int fiProcess(FILETAG *pftOut, FILETAG *pftIn, int iICS, int iILS)
                my = iHeight[d / 2]; // find median height\r
                }\r
 \r
-       printf("median %d,%d cell %d,%d space %d,%d\n",\r
-              mx, my, mx + iICS, my + iILS, iICS, iILS);\r
+       printf("Success: "\r
+              " range=%d,%d median=%d,%d total=%d,%d space=%d,%d\n",\r
+              0x21, d, mx, my, mx + iICS, my + iILS, iICS, iILS);\r
 \r
        // create the space character (now that we have width)\r
+#if 1 // unused chars must end up with their width = x cell width!!\r
+       *pc++ = mx + iICS;\r
+#else\r
        *pc++ = mx; // should be mx + iICS but we cheat a little\r
+#endif\r
        pus[' '] = pc - (char *)pus;\r
-       *pc++ = 0x60; // indicates we have width but nothing else\r
+       *pc++ = 0x20; // indicates we have width but nothing else\r
 \r
        // set file length, as all data has now been appended\r
        pftOut->pcAppend = pc;\r
@@ -357,11 +410,15 @@ int fiProcess(FILETAG *pftOut, FILETAG *pftIn, int iICS, int iILS)
                {\r
                if (pus[c] == 0)\r
                        {\r
+#if 1 // always fill out table with spaces, as width must = x cell width\r
+                       pus[c] = pus[' '];\r
+#else\r
                        pus[c] = pus['-'];\r
                        if (pus[c] == 0)\r
                                {\r
                                pus[c] = pus[' ']; // or space if no minus\r
                                }\r
+#endif\r
                        }\r
                }\r
 \r
@@ -373,7 +430,7 @@ int fiProcess(FILETAG *pftOut, FILETAG *pftIn, int iICS, int iILS)
        *pc++ = iILS;\r
        *pc++ = 'O'; // character to use for uncrossed zero\r
        *pc++ = 0; // spare\r
-       *(int *)pc = pftOut->pcAppend - pftOut->pcBase;\r
+       *(unsigned short *)pc = iFileSize(pftOut);\r
 \r
        // calculate and insert CRC using character set algorithm\r
        pc = pftOut->pcBase + 4;\r
@@ -389,7 +446,7 @@ int fiProcess(FILETAG *pftOut, FILETAG *pftIn, int iICS, int iILS)
        return TRUE;\r
        }\r
 \r
-int iCompare(const void *pvLeft, const void *pvRight)\r
+static int iCompare(const void *pvLeft, const void *pvRight)\r
        {\r
        if (*(int *)pvLeft < *(int *)pvRight)\r
                {\r
@@ -404,7 +461,7 @@ int iCompare(const void *pvLeft, const void *pvRight)
        return 0;\r
        }\r
 \r
-int iUpdateCRC(char *pcBase, int iCount, int iCRC)\r
+static int iUpdateCRC(char *pcBase, int iCount, int iCRC)\r
        {\r
        int i, j;\r
 \r
index e5eb754..f151880 100644 (file)
Binary files a/src/mkfont/txt2chs.exe and b/src/mkfont/txt2chs.exe differ
diff --git a/src/mkfont/txt2chs.h b/src/mkfont/txt2chs.h
new file mode 100644 (file)
index 0000000..06d4c51
--- /dev/null
@@ -0,0 +1,9 @@
+// txt2chs.h by Nick for Hytech Font Metrics system\r
+\r
+#ifndef _INC_TXT2CHS\r
+#define _INC_TXT2CHS\r
+\r
+int iTxt2Chs(LISTTAG *pltCache, int argc, char **argv);\r
+\r
+#endif\r
+\r