Author Topic: 3 fnt-windows-v?.trid.xml for Windows Font resource *.fnt  (Read 1454 times)

jenderek

  • Sr. Member
  • ****
  • Posts: 375
3 fnt-windows-v?.trid.xml for Windows Font resource *.fnt
« on: January 30, 2021, 06:44:39 PM »
Hello trid users,

some days ago just for interest i inspect efi executables starting with MZ
magic. Afterwards i look for other MZ-executables on my systems. Such
samples with FON file name extension are Windows fonts.

According to documentation the new executable DLL format is just a container
for Windows FNT fonts.

Unfortunately i only find 1 dedicated FNT sample. That was SAMPLE.FNT. The
other examples are generated from related FON examples. I use Joel Toivonen
font editor Fony.exe to load FON sample and save the fonts as FNT format
with version 2. I also use a hex editor to look inside FON samples and tried
to extract with help of the dd command the embedded FNT samples. I also use
Bert Huijbin FONTEDIT.EXE to save fonts as FNT examples. I also use Simon
Tatham python fonts tools mkwinfont to generate some FNT samples especially
with version 3 from FD text font descriptions.

The FNT Font File Format is described inside the Windows 1.03 Programmer's
Reference found as windows-1.03-sdk-prgref-1986.pdf. That is mentioned on
FNT (Windows Font) page on file formats archive team web site. That is
expressed by line like:
 <RefURL>
 http://fileformats.archiveteam.org/wiki/FNT_(Windows_Font)
 </RefURL>

So i run tridscan recursive on dozens undetected FNT samples with version 2
and i generate a trid definition file fnt-windows-v2.trid.xml. All samples
start with typical dfVersion sequence. That is expressed by XML pattern
block like:
   <Bytes>0002</Bytes>
   <Pos>0</Pos>
For the two other versions (1 and 3) we find there the corresponding values
instead of 2 in this block. Unfortunately the FNT has no real characteristic
magic pattern. The only unique non-nil pattern is the dfVersion value.
Furthermore the above XML construct is also find as the only marker inside
bitmap-pi3-degas.trid.xml. So all version 2 FNT examples are misidentified
as "DEGAS hi-res bitmap" ( See appended v2/output/trid-v.txt). So a more
accurate bitmap-pi3-degas.trid.xml should be generated.

For version 1 the version is described inside fnt-windows-v1.trid.xml by XML
construct like:
   <Bytes>0001</Bytes>
   <Pos>0</Pos>
Furthermore the above XML construct is also find as the only marker inside
bitmap-pi2-degas.trid.xml. So all version 1 FNT examples are misidentified
as "DEGAS med-res bitmap" ( See appended v1/output/trid-v.txt). So a more
accurate bitmap-pi2-degas.trid.xml should be generated.

Furthermore a TARGA picture like pal4.tga looks like version 1 font by
bitmap-tga-000101.trid.xml with XML construct:
   <Bytes>0001010000</Bytes>
   <Pos>0</Pos>
This sample is also misidentified as "WhatsApp encrypted database" by
crypt7.trid.xml with XML construct like:
   <Bytes>000101</Bytes>
   <Pos>0</Pos>

According to documentation at offset 2 the FNT file size is stored as 4 byte
little endian integer. According to documentation 64 KB (65535) is the upper
size limit of Windows 2 fonts.
Since a font can contain a maximum of 255 characters and a few bytes are
required per character description, this size is usually in the thousands
area. When looking in output of file command with magic file for FNT
examples ( See v1/output/file.tmp ) we see such values ( bytes size like
1034 2316 2697 3951 4207 5216 5592 8285 9246 10272). So for me it is very
unlikely that file size exceeds 64 KB limit. So the 2 upper bytes of dfSize
seems to be always nil. That is expressed by XML construct like:
   <Bytes>0000</Bytes>
   <Pos>4</Pos>
So the mis-identification as WhatsApp database or TARGA bitmap vanished.

Many values inside FNT examples are stored as 2 byte little endian
integer. So in theory a maximal unsigned value of 65535 could be stored.
But when looking in output of file command with magic file for FNT examples
( See v2/output/file.tmp ) we see that many short values like width and
height of the characters are low (3 6 8 12 13 16 20). So the upper byte is
nil. For me it seems to be reasonable that this is always true. Then this is
expressed by XML constructs like:
   <Pattern>
      <Bytes>00</Bytes>
      <Pos>87</Pos>
   </Pattern>
   <Pattern>
      <Bytes>00</Bytes>
      <Pos>89</Pos>
   </Pattern>

So i look for all non 1 byte patterns and check the validity of values and
refine the trid definitions according to documentation. Furthermore all
version share the header bytes from offset 2 til 116. So if there some
pattern in one version is not existent then it can also be removed in the
definition for other versions.

At offset 6 a copyright string with 60 bytes is stored. For many examples
this string looks like "Copyright (C) Microsoft Corp 1991.  All rights
reserved." or "(c) Copyright Bitstream Inc. 1984. All rights reserved." (See
appended v2/output/file.tmp). So in my first attempts the word Copyright was
found in FNT examples. That was expressed in side global string section by
line like:
   <String>COPYRIGHT</String>
If this string is short then the remaining bytes of string are padded with
nil bytes. That was expressed by XML construct like:
   <Pattern>
      <Bytes>00000000000000
      <Pos>59</Pos>
   </Pattern>
Some free fonts like fixed.fnt have a message string like "Public domain
font.  Share and enjoy." ( see output/file.tmp). So the global string
section becomes empty and can be removed.
When i use the HB Font editor i can leave this string filled empty ( all
bytes nil) like for example "Bodoni Bd BT.fnt" or can use a 59 byte string
like in example OpenSymbol36Lastchar254_LongCoyright.fnt ( see
output/file.tmp).
Or for some version 1 snuz fonts like CYRILC.fnt, GOTHGRT.fnt and GREEKP.fnt
the message string is padded at the end with space characters ( see
v1/output/file.tmp). So the above nil pattern must be removed.

There exist a similar definition fnt-bitstream.trid.xml for "Bitstream Font"
with 2 patterns like:
 <Bytes>000028632920436F707972696768742042697473747265616D20496E632E20</Bytes>
 <ASCII> . . ( c )   C o p y r i g h t   B i t s t r e a m   I n c</ASCII>
 <Pos>4</Pos>
 <Bytes>2E20416C6C207269676874732072657365727665642E00000000000000000000000000000000000000000000</Bytes>
 <ASCII> .   A l l   r i g h t s   r e s e r v e d</ASCII>
 <Pos>39</Pos>
So i create a variant of ega80woa.fnt. I replaced at offset 86 the width and
height 8x16 by 8x0, at offset 70 dpi values 96x72 by 0x0, at offset 68 the
nominal point size dfPoints value 12 by 0 and at offset 83 the weight value
400 by 512. Now this variant called ega80woa-test.fnt is recognized as
"Bitstream Font" (See v2/output/trid-v.txt).
So it seems that Bitstream fonts are described by one definition
fnt-windows-v?.trid.xml and that this definitions is not needed any more.

At offset 78 the amount of extra leading is stored as 2 byte little endian
integer. Typical values are 0 and 1. So the upper byte is nil. For me it
seems to be reasonable that this is always true.

From offset 80 three properties of the font are saved in one byte
each. These font properties are italic, underlined and strikeout. If the
font has not the property in question, then the corresponding value is nil.
For my inspected version 1 samples these properties are missing. That fact
were described by XML construct like:
   <Bytes>00000000</Bytes>
   <Pos>79</Pos>
In version 3 example ebrima-3props.fnt created by font editor all 3
properties are set. So the above pattern now becomes like:
   <Bytes>00</Bytes>
   <Pos>79</Pos>

Many font have an OEM character set. That is expressed by value 0xFF (255
dfCharSet) at offset 85. That was expressed by XML construct like:
   <Bytes>FF</Bytes>
   <Pos>85</Pos>
But this is not always true. So i remove that pattern inside definition
fnt-windows-v1.trid.xml.

At offset 101 the offset of the device name string is stored as 4 byte
little endian integer. For a generic font, this value is zero. All my
inspected examples have no device name. That is expressed by XML construct:
   <Bytes>00000000</Bytes>
   <Pos>101</Pos>

At offset 66 the type of font file is stored as 2 byte little endian value
dfType. The high-order byte is reserved for device use and will always be
set to zero for GDI realized standard fonts. For a vector font file the
first bit of low-order byte is 1, where as for bitmap (raster) font file
this bit is 0. This gives for many bitmaps a zero value for low byte. So for
bitmap based definition together with null padding of copyright message this
is expressed by XML construct like:
   <Bytes>000000</Bytes>
   <Pos>65</Pos>
So for non nil padded copyright messages and vector fonts without device
name this will now become like:
   <Bytes>00</Bytes>
   <Pos>67</Pos>

At offset 105 the offset of the font (face) name string is stored as 4 byte
little endian integer. If we assume that file size never exceeds 64 KB
limit, than this is also true for the face offset. So the 2 upper bytes of
dfFace seems to be always nil.
At offset 109 the absolute machine address of the bitmap is stored as 4 byte
little endian integer dfBitsPointer. This is set by GDI at load time. So for
all my inspected fonts this was always be null. So these two things are
expressed by XML construct like:
   <Bytes>000000000000</Bytes>
   <Pos>107</Pos>

At offset 113 the offset to bitmap is stored as 4 byte little endian
integer. I found no example with absolute address. If we assume that file
size never exceeds 64 KB limit, than this is also true for this relative
offset value. So the 2 upper bytes of dfBitsOffset seems to be always nil.
For version version 2 and 3 byte at offset 117 is used for word
alignment. So this seems to be always be nil. For version 1 at offset 117
offset from the start of each bitmap row for each character in the set is
stored as 2 byte little endian integer ( Typically dfCharOffset values are
like 0x0 0x100 0x300 0x400 0x800 0x900 0xb00 0x7e00). So in this case the
lower byte seems to be always nil. So these things are expressed by XML
construct like:
   <Bytes>000000</Bytes>
   <Pos>115</Pos>

For version 1 at offset 119 non header starts which is typically the bitmap
information part. So patterns at higher offset are generated by lucky
circumstances ( similar character shapes in font patterns). So i removed
pattern in fnt-windows-v1.trid.xml starting with lines like:
   <Bytes>00</Bytes>
   <Pos>124</Pos>

For version 3 i get XML construct like:
 <Bytes>0000000000000000000000000000000000000000000000000000000000</Bytes>
 <Pos>119</Pos>
At offset 118 flags, which define the format of the Glyph bitmap is stored
as 4 byte little endian integer. Only lowest byte is used. So upper 3 bytes
are always nil. Afterwards three 2 byte values dfAspace, dfBspace and
dfCspace are stored followed by 4 byte little endian integer
dfColorPointer. For my inspected samples these four values are nil by lucky
circumstances. At offset 132 sixteen reserved bytes are stored. So these
bytes seems to be always be nil. So the above construct now becomes like:
 <Bytes>000000</Bytes>
 <Pos>119</Pos>
 <Bytes>0000000000000000000000000000000</Bytes>
 <Pos>132</Pos>

For version 3 at offset 148 non header starts. So patterns at higher offset
are generated by lucky circumstances. So i removed pattern in
fnt-windows-v3.trid.xml starting with lines like:
   <Bytes>00</Bytes>
   <Pos>149</Pos>

For version 2 the documentation is a little bit disagreeing. So i assume
that pattern at higher offsets are triggered by lucky circumstances. So i
delete all high pattern starting wit lines like:
   <Pattern>
      <Bytes>00</Bytes>
      <Pos>119</Pos>
   </Pattern>
   <Pattern>
      <Bytes>00</Bytes>
      <Pos>123</Pos>
   </Pattern>

With the 3 new definition my FNT samples are now recognized (See appended
*output/trid-v-new.txt).

TrID definition, some examples and output are stored in archive fnt.zip. I
hope that my 3 XML files fnt-windows-v1.trid.xml, fnt-windows-v2.trid.xml
and fnt-windows-v3.trid.xml can be used in future version of triddefs.

With best wishes
Jörg Jenderek

Mark0

  • Administrator
  • Hero Member
  • *****
  • Posts: 2743
    • Mark0's Home Page
Re: 3 fnt-windows-v?.trid.xml for Windows Font resource *.fnt
« Reply #1 on: January 30, 2021, 10:32:44 PM »
Many thanks Jörg!