TheDraw Fonts File (.TDF) Specifications

Comments: No Comments
Published on: April 23, 2014

I spend quite some time on my “FONTS COLLECTION” for the MS DOS ANSI/ASCII Text Editor “TheDraw“. The font file is in binary format and I wondered how it is structured to maybe write later some tools around it, like a Font Viewer for Windows, Converter to and from ANSI and stuff like that.

Note that this is not an official specifications document, I reverse engineered it by testing, so there might be cases I am unaware of, although I am pretty confident that I covered everything about it.

“TheDraw” Fonts Files have the extension “.TDF” (which is short for “TheDraw Font” duh :)).

One .TDF Fonts file is by default designed as a “collection” of multiple fonts, even if it only holds a single font (like after exporting a single font to an extra file). It can hold up to 34 fonts. More are not possible, if used with TheDraw itself or with it’s external TDFONTS.EXE Fonts Editor utility.

An empty fonts file without any font in it yet is always 232 bytes in size. The actual character data are always stored after those 232 bytes and can vary in size, depending on the size, type and complexity of the font characters. Every additional font added to the collection is 212 bytes long if without any character data.

Font Header

OffsetLengthDescriptionSample Value
0 1 Character 19 (13h) 13
1 18 Fix String TheDraw FONTS file
19 1 Character 26 (1Ah) 1A
20 4 Fix 4 Bytes Sequence Indicating the Start of a new Font Definition 55 AA 00 FF
24 1 Byte: Length of the Font Name (max. is 12 characters) 0B
25 12 Font Name (String). Only use the number of bytes specified in byte 24 and ignore any after (it might be 00 values or maybe garbage) MY NEW FONT
37 4 unused as far I know. Typically all 0 bytes 00 00 00 00
41 1 Font Type (byte): 00 = Outline, 01 = Block, 02 = Color 02
42 1 Letter Spacing: 01h – 29h, representing the range 0-40 as decimal values 0129
43 2 Block Size (Word, Little Endian) Size of character data after main font definition block, including terminating 0 if followed by another font (last font in collection is not Null terminated) 7F 04 (= 1,151)
45 188 2 bytes (Word, Little Endian) for each character from ASC(33) (“!”) to ASC(126) (“~”) (94 characters total) with the offset (starting at 0) after the font header definition where the character data start (e.g. 0 would mean that character data start at byte 233 [for the first font in the file only]) FF FF = char not defined
233 BlockSize Character Detail Data  

The Characters

  !"#$%&'()*+,-./0123456789:;<=>[email protected]

Offset Addresses

Font 1 Header 20
Font 1 Data 233
Font 2 Header 232 + Font 1 Block Size + 1
Font 2 Data Font 2 Header + 212 + 1
Font 3 Header Font 2 Data + Font 2 Block Size + 1
Font 3 Data Font 3 Header + 212 + 1
Font X …


Font Character

OffsetLengthDescriptionSample Value
0 1 Max Width of Character ( 1 <= W <= 30 (1Eh) ) 0A
1 1 Max Height of Character** ( 1<= H <= 12 (0Ch) ) 05

** The Max Height Value is not reliable. If a line ends with a &, this line is not counted in the Max Height. For Example, if a character is 6 lines high and line 5 and line 4 end with a & character, the value for Max Height will be 4 and not 6. The Max Height value can only be used to determine the “Line Height” to determine where to position the cursor after a line-break. To read the full character data, always read to the Null (Chr(0)) terminator.

Byte 1 (All Font Types)

The individual characters for Fonts of type “Block” or “Outline” are single bytes only where “Block” using the actual ASCII character code. For Fonts of type “Color“, each character takes up 2 bytes. The first byte is the character itself and the 2nd byte is to specify the background and foreground colors used for the character. “Outline” Font Types store Letters, which are used as character reference. For visualization purposes you might want to use the following mapping.

Letter Chr Dec/HexDescriptionOut-/Inside
A 205 / CD    
B 196 / C4    
C 179 / B3    
D 186 / BA    
E 213 / D5 Upper-left outer corner
Up-to-Right outer corner
F 187 / BB Upper-right outer corner
Right-to-Down outer corner
G 214 / D6 Up-to-Right inner corner
Upper-left inner corner
H 191 / BF Right-to-Down inner corner
Upper-right inner corner
I 200 / C8 Lower-left inner corner inside
J 190 / BE Lower-right inner corner inside
K 192 / C0 Lower-left outer corner outside
L 189 / BD Lower-right outer corner outside
M 181 / B5    
N 199 / C7    
O 247 / F7 Hard space for all spaces inside a character  
@ @ 064 / 40 Filler for all leading spaces  
& & 038 / 26 Descender mark  

Byte 2 (“Color” Font Type Only)

00 - FF, the first part (or Floor(Value / 16)) holds the background color (0,1,2,3 .. max. 7) and the second part (or Value mod 16) holds the foreground color (0,1,2,3 .. max. F). See the Color Table below for the available colors.


The end of each line in the character is terminated by the Carriage Return character (ASC(13) or 0Dh)

A character value = 0 (Null) indicates the end of the current character (Note: that a color value of “00” for fonts of type “Color” is perfectly legal and should not be interpreted as Null termination).


General Notes

  • If the current line is being terminated before the specified “Max. Width” is reached, everything after the break will be treated as non-existent or transparent space. I tried to illustrate this behavior in the following drawing.
  • If the characters of your “Color” font are too large, TheDraw might run into a problem because the space needed exceed the maximum possible offset value in the font base definition. Keep in mind that only 2 bytes are reserved, providing a max. offset of 65534 (=FEh, remember that FFh = no character defined). Taking a color font using 2 bytes per char and maximum dimensions per character of 30×12 + up-to 11 line-breaks and 1 null termination for a total of 94 characters, you are running out of address space much earlier than the end of character 93.
  • Remember that the “Outline” font type has restrictions regarding the use of characters. Those rules are enforced by the font-editor tool though and not by the font file format, so be careful, if you are going to create new .TDF font files yourself.
  • If a character is created using the “Copy” character feature by the TDFonts.exe font editor, the target character will point to the same offset position for the character data as the source character. Only if the target character is changed afterwards will the character data be stored at a different offset location. This reduces space and can be solution for the address space issue mentioned at the first bullet point.


From the TheDraw Documentation

Outline Fonts

│ ╓─────────┐ ║     ╒══╗         Horizontal Beam
│ ╚═══╗ ╒═══╛ ║     │  ║           ╒═════════╗
└───┐ ║ │ ╓───╜     │  ║           └─────────╜
    │ ║ │ ║         │  ║
    │ ║ │ ║         │  ║ <── Vertical Beam
    │ ╚═╛ ║         └──╜

Pay special attention to how the top/right of the outside border, and the bottom/left of the inside border were done. Of particular importance are the corners. The following characters must be used in the described locations.

For outside borders:
╒     Upper–left outer corner
╗     Upper–right outer corner
└     Lower–left outer corner
╜     Lower–right outer corner
╓     Up–to–Right inner corner
┐     Right–to–Down inner corner

For inside borders:
╓     Upper–left inner corner
┐     Upper–right inner corner
╚     Lower–left inner corner
╛     Lower–right inner corner
╒     Up–to–Right outer corner
╗     Right–to–Down outer corner

In general the drawing rules are:

  • Double lines are always the rightmost side of a column.
  • Double lines are always the topmost side of a beam.

The reserved characters are for solid spaces and descender line markers. Typically solid spaces are used to fill the inside of columns and beams. These are drawn with “≈” characters. ie:

              ╒════════╗  ╒════════╗
              │≈≈≈≈≈≈≈≈║  │≈≈≈≈≈≈≈≈║      Note that solid
              │≈≈╓──┐≈≈║  │≈≈╔══╕≈≈║      spaces are always
              │≈≈╚══╛≈≈║  │≈≈║  │≈≈║      visible in TDFonts
              │≈≈≈≈≈≈≈≈║  │≈≈╙──┘≈≈║        editor verses the
              │≈≈╓──┐≈≈║  │≈≈≈≈≈≈≈≈║      TheDraw editor).
              └──╜  └──╜  └────┐≈≈╓╜

TheDraw specially tracks descenders so to align symbols and handle carriage returns properly. A carriage return should move the same number of lines for either A’s or Q’s for instance. If decenders were not marked, following kind of alignment error occurs:

                   ▄▄▄▄▄   █▀▀▀█
                   █   █   █   █
                   █▀▀▀█   ▀▀▀█▀

Symbols demanding descenders should be marked as shown in the above “Q” symbol. Lines marked with ampersands are not counted when TheDraw aligns the symbols. Font symbols typically needing the descender marks are:

                $ , ; _ Q g j p q y

Others symbols may require them also, depending on how your font is designed or implemented.

 Wrapping Up

That’s all actually, there is nothing more to it I believe. I am pretty sure that you will hear more of this from me in the future, probably some kind of tools, which I already mentioned briefly at the beginning of this post.

I hope that you find this information useful. Let me know, if you decide to do something yourself with this information and write some tool of your own etc. Just contact me :).

Carsten aka Roy/SAC



No Comments
  1. […] « TheDraw Fonts File (.TDF) Specifications […]

  2. […] TheDraw Fonts File (.TDF) Specifications […]

  3. […] are limited in Size. It only supports font sizes up to 30 characters wide and 12 characters high (See TDF File format specifications). Figlet does not have this limitation. During the import, fonts that are too large, are simply […]

  4. […] TheDraw Fonts File (.TDF) Specifications […]

  5. […] TheDraw Fonts File (.TDF) Specifications […]

  6. […] TheDraw Fonts File (.TDF) Specifications […]

  7. […] TheDraw Fonts File (.TDF) Specifications […]

  8. […] TheDraw Fonts File (.TDF) Specifications […]

  9. […] TheDraw Fonts File (.TDF) Specifications […]