I'm doing a brain dump for posterity on this task; you can tune out of this email; it's mostly meant for Google archiving purposes.
I've spent far more time than I should on this implementation; I originally did a quick + dirty version that was not binary compatible with Windows .fot files. Worked like a charm; I could run Civ III (yay!).
But Alexandre said, gee, it should be easy to make it create a binary compatible .fot file, take an afternoon and do that, why don't you, Jer? Several weeks and a lot of swearing later, I now know far more about the format of .fot files and fontdir resource structures than I care to.
I'm attaching a program that was useful to me; it dumped many chunks of info about a .ttf file from FreeType. Comparing that to a .fot file generated on Windows was helpful. I'm also attaching a hex dump of a .fot file with my annotation on the basic structure.
The hard parts were that the .fot format seems to be an NE image, but it seems to have subtle bugs in it and that the FONTDIR resource structure is not well documented. I've mostly sussed out how to use Freetype to replicate most of the members; there are still a few I don't have quite right. (And I probably get this all wrong in non US or double byte locales. :-/)
The previous patches contain essentially all of my hard won knowledge of the FONTDIR structure.
Cheers,
Jeremy
Annotated hex dump of lucon.fot, a file created on Windows with CreateScalableFontResource against lucon.ttf. Useful for determining the structure of .fot files.
DOS 00000000 4d 5a 01 00 02 00 00 00 04 00 0f 00 ff ff 00 00 |MZ..............| 00000010 b8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 |........@.......| 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000030 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 |................| 00000040 0e 1f ba 0e 00 b4 09 cd 21 b8 01 4c cd 21 54 68 |........!..L.!Th| 00000050 69 73 20 69 73 20 61 20 54 72 75 65 54 79 70 65 |is is a TrueType| 00000060 20 66 6f 6e 74 2c 20 6e 6f 74 20 61 20 70 72 6f | font, not a pro| 00000070 67 72 61 6d 2e 0d 0d 0a 24 00 4b 69 65 73 61 00 |gram....$.Kiesa.|
NE 00000080 4e 45 05 10 8a 00 02 00 00 00 00 00 00 80 00 00 |NE..............| 00000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000000a0 1a 00 40 00 40 00 74 00 7f 00 7f 00 0e 01 00 00 |..@.@.t.........| 000000b0 00 00 04 00 02 00 02 00 00 00 00 00 00 00 00 03 |................|
START RESOURCE TABLE Shift 000000c0 04 00
Type + Name 0 07 80 01 00 00 00 00 00 48 00 0a 00 50 0c |..........H...P.| 000000d0 2c 00 00 00 00 00
Type + Name 1 cc 80 01 00 00 00 00 00 40 00 |,.............@.| 000000e0 08 00 50 0c 01 80 00 00 00 00
Flag to end all types + names 00 00 07 46 4f 4e |..P..........FON| 000000f0 54 44 49 52 05 4c 55 43 4f 4e 00 |TDIR.LUCON. | END RESOURCE TABLE
^^^
This is odd. That's fairly clearly the last string in the name/type string part of the resource table. Further, just a little further along, we have a clear place where the resident name table should start. But the header says it starts at 0x74 relative, which is right there. And the clear place for it to start is at 0x7f.
Mystery bytes: (0xf9, 0x79 relative) 00 00 00 00
Apparent resident name table: (0xff, 0x7f relative) 0a | .| 00000100 4c 55 43 4f 4e 2e 54 54 46 00 |LUCON.TTF. |
Apparent module reference table: (0x10a, 0x8a relative) 00 00 00 00
Non resident name table: (0x10e) 1a 46 | .F| 00000110 4f 4e 54 52 45 53 3a 4c 75 63 69 64 61 20 43 6f |ONTRES:Lucida Co| 00000120 6e 73 6f 6c 65 00 00 00 00 00 00 00 00 00 00 00 |nsole...........| 00000130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000001a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000001c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000200 c3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
^^^
What the hell!?!?!
00000210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000220 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000230 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000240 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000250 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000260 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000270 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000280 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000290 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000002a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000002b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000002c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000002d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000002e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000002f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000300 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000310 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000320 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000340 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000350 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000360 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000370 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000380 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000390 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000003a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000003b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000003c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000003d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000003e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000003f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000400 43 3a 5c 57 49 4e 44 4f 57 53 5c 66 6f 6e 74 73 |C:\WINDOWS\fonts| 00000410 5c 4c 55 43 4f 4e 2e 54 54 46 00 00 00 00 00 00 |\LUCON.TTF......| 00000420 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000430 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000440 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000450 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000460 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000470 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000480 01 00 00 00 00 02 95 00 00 00 57 69 6e 64 6f 77 |..........Window| 00000490 73 21 20 57 69 6e 64 6f 77 73 21 20 57 69 6e 64 |s! Windows! Wind| 000004a0 6f 77 73 21 00 10 03 01 01 00 00 00 00 00 00 00 |ows!............| 000004b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000004c0 00 00 00 00 00 00 03 40 00 08 48 00 48 00 50 06 |.......@..H.H.P.| 000004d0 00 00 00 00 00 00 00 90 01 00 00 00 00 08 36 d2 |..............6.| 000004e0 04 d2 04 1e ff 01 02 00 00 00 00 00 00 76 00 00 |.............v..| 000004f0 00 0c 00 00 00 ff 4c 75 63 69 64 61 20 43 6f 6e |......Lucida Con| 00000500 73 6f 6c 65 00 4c 75 63 69 64 61 20 43 6f 6e 73 |sole.Lucida Cons| 00000510 6f 6c 65 00 52 65 67 75 6c 61 72 00 00 00 00 00 |ole.Regular.....| 00000520 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000530 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000540 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000550 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000560 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000570 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000580 00 |.| 00000581