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