User:Lucas Brooks/Researches/Windows 1.x Font Format

Introduction[edit | edit source]

The standard FONTS.FON file provided with Windows includes fonts for both 2:1 and 1:1 aspect ratio displays and only the fonts whose aspect ratio matches the display are actually used. There are three sizes of fonts provided in the ANSI character set: 6, 8, and 11 pixels high for 2:1 displays and 12, 16, and 22 pixels high for 1:1 displays. There is only one 1:1 and one 2:1 OEM-dependent font. There are both Terminal and Document faces in each size.

Windows is capable of synthesizing attributes, such as bold, italic, and underlined, so such fonts are not in FONTS.FON. The fonts that do not correspond to the user's display aspect ratio are nevertheless generic raster fonts that can be used for output devices such as bitmap printers.


Font File Formats[edit | edit source]

Formats for font files are defined for both raster and vector fonts. These formats may be used by smart text generators in some GDI support modules. The vector formats, in particular, are more frequently used by GDI itself than by support modules.

Both types of files begin with information which is common to both, and then continue with information which differs for each type of file. Font files are stored with a .fnt extension of the form name.fnt. The information at the beginning of both types of files is as follows:

Field Definition
dfVersion Two bytes specifying the version of the file (currently 256).
dfSize Four bytes specifying the total file size in bytes.
dfCopyright Sixty (60) bytes specifying copyright information.
dfType Two bytes specifying the type of font file. The low-order byte is for exclusive GDI use. If the low-order bit of the word is 0, it is a bitmap (rastor) font file. If the low-order bit is 1, it is a vector font file. The second bit is reserved and must be zero. If no bits follow in the file and the bits are located in memory at a fixed address specified in dfBitsOffset, the third bit is set to 1; otherwise, the bit is set to 0. The high bit of the low-order byte is set if the font was realized by a device. The remaining bits in the low-order byte are reserved and set to zero.


The high-order byte is reserved for device use and will always be set to zero for GDI realized standard fonts. Physical fonts with the high bit of the low-order byte set may use this byte to describe themselves. GDI will never inspect the high-order byte.

dfPoints Two bytes specifying the nominal point size at which this character set looks best.
dfVertRes Two bytes specifying the nominal vertical resolution (dots per inch) at which this character set was digitized.
dfHorizRes Two bytes specifying the nominal horizontal resolution (dots per inch) at which this character set was digitized.
dfAscent Two bytes specifying the distance from the top of a character definition cell to the baseline of the typographical font. It is useful for aligning the baseline of fonts of different heights.
dflnternalLeading Two bytes specifying the amount of leading inside the bounds set by dfPixHeight. Accent marks may occur in this area. This may be zero at the designer's option.
dfExternalLeading Two bytes specifying the amount of extra leading that the designer requests the application add between rows. Since this area is outside of the font proper, it contains no marks, and will not be altered by text output calls in either OPAQUE or TRANSPARENT mode. This may be zero at the designer's option.
dfItalic One byte specifying whether the character definition data represent an italic font. The low-order bit is one if the flag is set. All other bits are zero.
dfUnderline One byte specifying whether the character definition data represent an underlined font. The low-order bit is one if the flag is set. All other bits are zero.
dfStrikeOut One byte specifying whether the character definition data represent a strikeout font. The low-order bit is one if the flag is set. All other bits are zero.
dfWeight Two bytes specifying the weight of the characters in the character definition data, on a scale from 1-1000. A weight of 100 is the usual for light type, 200 specifies regular, 300 semibold, and so forth.
dfCharSet One byte specifying the character set defined by this font. The IBM® PC hardware font has been assigned the designation 377 octal (FF hexadecimal or 255 decimal).
dfPixWidth Two bytes. For vector fonts, specifies the width of the grid on which the font was digitized. For raster fonts, if dfPixWidth is nonzero, it represents the width for all characters in the bitmap; if it is zero, the font has variable width characters whose widths are specified in the dfCharOffset array.
dfPixHeight Two bytes specifying the height of the character bitmap (raster fonts), or the height of the grid on which a vector font was digitized.
dfPitchAndFamily Specifies the pitch and font family. The low bit is set if the font is variable-pitch. The four high-order bits give the family name of the font. The values are:

  FF_DONTCARE     (0<<4)
  FF_ROMAN   (1<<4)
  FF_SWISS   (2<<4)
  FF_MODERN   (3<<4)
  FF_SCRIPT   (4<<4)
  FF_DECORATIVE    (5<<4)

Font families describe in a general way the look of a font. They are intended for specifying fonts when the exact facename desired is not available. The families are: FF_DONTCARE
   Don't care or don't know.
FF_ROMAN
   Fonts with variable stroke width, serifed. Times Roman, Century Schoolbook, etc.
FF_SWISS
   Fonts with variable stroke width, sans-serifed. Helvetica, Swiss, etc.
FF_MODERN
   Fonts with constant stroke width, serifed or sans-serifed. Fixed-pitch fonts are usually modern. Pica, Elite, Courier, etc.
FF_SCRIPT
   Cursive, etc.
FF_DECORATIVE
   Old English, etc.

dfAvgWidth Two bytes specifying the width of characters in the font. For fixed-pitch fonts this is the same as dfPixWidth. For variable-pitch fonts this is the width of the character 'X'.
dfMaxWidth Two bytes specifying the maximum pixel width of any character in the font. For fixed-pitch fonts, this is simply dfPixWidth.
dfFirstChar One byte specifying the first character code defined by this font. Character definitions are stored only for the characters actually present in a font, so use this field when calculating indexes into either dfBits or dfCharOffset.
dfLastChar One byte specifying the last character code defined by this font. Note that all characters with codes between dfFirstChar and dfLastChar must be present in the font character definitions.
dfDefaultChar One byte specifying the character to substitute whenever a string contains a character out of the range dfFirstChar through dfLastChar. The character is given relative to dfFirstChar so that dfDefaultChar is the actual value of the character less dfFirstChar. dfDefaultChar should indicate a special character in the font which is not a space.
dfBreakChar One byte specifying the character that will define word breaks. This character defines word breaks for word wrapping and word spacing justification. The character is given relative to dfFirstChar so that dfBreakChar is the actual value of the character less dfFirstChar. dfBreakChar is normally (32 - dfFirstChar), which is an ASCII space.
dfWidthBytes Two bytes specifying the number of bytes in each row of the bitmap (raster fonts). No meaning for vector fonts. dfWidthBytes is always an even quantity so that rows of the bitmap start on word boundaries.
dfDevice Four bytes specifying the offset in the file to the string giving the device name. For a generic device, this value will be zero (0).
dfFace Four bytes specifying the offset in the file to the null-terminated string that names the face.
dfBitsPointer Four bytes specifying the absolute machine address of the bitmap. This is set by GDI at load time. dfBitsPointer is guaranteed to be even.
dfBitsOffset Four bytes specifying the offset in the file to the beginning of the bitmap information. If the 04h bit in dfType is set, then dfBitsOffset is an absolute address of the bitmap. (Probably in ROM) For raster fonts, it points to a sequence of bytes that makes up the bitmap of the font, whose height is the height of the font, and whose width is the sum of the widths of the characters in the font rounded up to the next word boundary. For vector fonts, it points to a string of bytes or words (depending on the size of the grid on which the font was digitized) specifying the strokes for each character of the font. dfBitsOffset must be even.
dfCharOffset For proportionally spaced raster fonts, this field contains two bytes giving the offset from the start of each bitmap row for each character in the set. The number of characters present in the set is calculated as ((dfLastChar-dfFirstChar)+1) and one spare, used for the sentinel offset. The total is therefore ((dfLastChar-dfFirstChar)+2) entries, each of two bytes. For equal-width raster fonts, this field collapses to zero size because all widths may be obtained by looking up the width in dfPixWidth.


For fixed-pitch vector fonts, each two-byte entry in this array specifies the offset from the start of the bitmap to the beginning of the string of stroke-specification units for the character. The number of bytes or words to be used for a particular character is calculated in the same fashion as the width of a raster character (i.e., subtract its entry from the next one), so that both types of font require a sentinel value at the end of the array of values.


For proportionally spaced vector fonts, each four-byte entry is divided into two two-byte fields. The first field gives the starting offset from the start of the bitmap of the character strokes as for fixed-pitch fonts. The second field gives the pixel width of the character.

<facename> An ASCII character string specifying the name of the font face. The size of this field is the length of the string plus a null terminator.
<devicename> An ASCII character string specifying the name of the device if this font file is for a specific device. The size of this field is the length of the string plus a null terminator.
<bitmaps> This field contains the bitmap definitions. The size of this field depends on the length of the bitmap definitions. Each row of a raster bitmap must start on a word boundary. This implies that the end of each row must be padded to an even length.


Raster Font File Format[edit | edit source]

In addition to the information in the header to the file, a raster font file contains a string of bytes which is the actual bitmap, just as it will be loaded into contiguous memory. That string begins in the file at the offset specified in the fiBits field above.


Vector Font File Format[edit | edit source]

The header information for a vector font file is as described in Section 2, "Font File Formats." This section describes some additional information for vector font files.

The CharOffset field is used to specify the location and usage of the character strokes in the bitmap area. For fixed-pitch fonts, each two-byte entry is an offset from the start of the bitmap to the beginning of the strokes for the character. For variable-pitch fonts, each four-byte entry consists of two bytes giving the offset (as for fixed-pitch) and two bytes giving the width of the character.

For both fixed- and variable- pitch fonts, the bitmap area is the same. Each character is composed of a series of vectors consisting of a pair of signed relative coordinate pairs starting from the character cell origin. Each pair may be preceded by a special value indicating that the next coor­dinate is to be a pen-up move. The special pen-up value depends on how the coordinates are stored. For one-byte quantities, it is -128 (080H) and for two-byte quantities, it is -32768 (08000H).

The character cell origin must be at the upper left corner of the cell so that the character hangs down and to the right of where it is placed.

The storage format for the coordinates depends on the size of the font. If either dfPixHeight or dfMaxWidth is greater than 128, the coordinates are stored as 2-byte quantities; otherwise, they are stored as 1-byte quantities.


ANSI Character Set[edit | edit source]

Table 1

ANSI Character Set For Windows

    00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █
10  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █
20     !  "  #  $  %  &  '  (  )  *  +  ,  -  .  /
30  0  1  2  3  4  5  6  7  8  9  :  ;  <  =  >  ?
40  @  A  B  C  D  E  F  G  H  I  J  K  L  M  N  O
50  P  Q  R  S  T  U  V  W  X  Y  Z  [  \  ]  ^  _
60  `  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o
70  p  q  r  s  t  u  v  w  x  y  z  {  |  }  ~  █
80  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █
90  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █
A0     ¡  ¢  £  ¤  ¥  ¦  §  ¨  ©  ª  «  ¬  ­  ®  ¯
B0  °  ±  ²  ³  ´  µ  ¶  ·  ¸  ¹  º  »  ¼  ½  ¾  ¿
C0  À  Á  Â  Ã  Ä  Å  Æ  Ç  È  É  Ê  Ë  Ì  Í  Î  Ï
D0  Ð  Ñ  Ò  Ó  Ô  Õ  Ö  █  Ø  Ù  Ú  Û  Ü  Ý  Þ  ß
E0  à  á  â  ã  ä  å  æ  ç  è  é  ê  ë  ì  í  î  ï
F0  ð  ñ  ò  ó  ô  õ  ö  █  ø  ù  ú  û  ü  ý  þ  ÿ