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