TrueType/OpenType

Dies ist ein binäres Format in Big-Endian Anordnung. Folgende Datentypen kommen zur Anwendung:

char String mit 8-Bit Kodierung
wchar String mit 16-Bit Kodierung
int16 vorzeichenbehaftete 16-Bit Zahl
uint16 vorzeichenlose 16-Bit Zahl
uint24 vorzeichenlose 24-Bit Zahl
uint32 vorzeichenlose 32-Bit Zahl

Die Daten sind in Blöcken organisiert. Der erste Block enthält ein Verzeichnis der anderen Blöcke.

Verzeichnis

Details Verzeichnis

Dieser Block steht am Anfang der Datei, und verweist auf die anderen Blöcke.

PositionGrösse Typ Wert
04 Byte char Signatur
42 Byte uint16 Anzahl Blocks
62 Byte uint16 Suchrahmen
82 Byte uint16 Selektorgrösse
102 Byte uint16 Suchüberschuss

Die Signatur ist <00 01 00 00> bei TrueType, „OTTO“ bei Type1.

Darauf folgt eine Liste mit folgenden Daten für jeden Block:

PositionGrösse Typ Wert
04 Byte char ID
44 Byte uint32 Prüfsumme
84 Byte uint32 Position
124 Byte uint32 Länge

Prüfsummenalgorithmus:

Prüfsumme = 0
Wertposition = Blockposition
solange Wertposition < (Blockposition + Länge):
Wert lesen (uint32)
falls Wertposition == (Blockposition + 8) und Block-ID == "head":
Wert = 0
Prüfsumme = (Prüfsumme + Wert) modulo 0x100000000
Wertposition = Wertposition + 4

Eine Prüfsumme über die gesamte Datei nach dem obigen Algorithmus (ohne die Sonderregelung für den „head“ Block) ergibt immer 0xB1B0AFBA.

"name" Block

Details "name" Block
Details Schriftartenname

PositionGrösse Typ Wert
02 Byte uint16 Blockformatversion
22 Byte uint16 Anzahl Strings
42 Byte uint16 Startposition Strings

Darauf folgt ein Verzeichnis mit folgenden Daten für jeden String:

PositionGrösse Typ Wert
02 Byte uint16 Plattform
22 Byte uint16 Kodierung
42 Byte uint16 Sprache
62 Byte uint16 Typ
82 Byte uint16 Länge
102 Byte uint16 Position

Folgende Strings sind von Interesse:

PlattformKodierung Sprache Typ Inhalt
3 0 0x409 1Schriftart (symbolische Schrift)
3 0 0x409 4Schriftname (OS/symbolische Schrift)
3 1 0x409 1Schriftart (normale Schrift)
3 1 0x409 4Schriftname (OS/normale Schrift)
3 * * 6Schriftname (Postscript)

Die Strings selbst sind folgendermassen abgelegt:

Position Grösse Typ
Startposition + Stringposition Stringlänge wchar

Die Kodierung ist UTF-16BE.

"head" Block

Details "head" Block
Details Mac-Style

PositionGrösse Typ Wert
182 Byte uint16 Skala
362 Byte int16 BBox x1
382 Byte int16 BBox y1
402 Byte int16 BBox x2
422 Byte int16 BBox y2
442 Byte uint16 Mac-Style

Die Skala gibt an, welcher Wert innerhalb der Datei als Äquivalent zur Zeilenhöhe gilt.

Mac-Style ist ungerade bei Fettschrift, gerade bei normal dicker Schrift.

"OS/2" Block

Details "OS/2" Block
Details Lizenz
Details Zeilendurchschuss
Details Hoch- und Tiefstellung

PositionGrösse Typ Wert
02 Byte uint16 Blockformatversion
82 Byte uint16 Lizenz
122 Byte uint16 Grösse Tiefstellung
162 Byte uint16 Absenkung Tiefstellung
202 Byte uint16 Grösse Hochstellung
242 Byte uint16 Anhebung Hochstellung
682 Byte int16 Oberlänge
702 Byte int16 Unterlänge
722 Byte int16 Zeilendurchschuss
882 Byte int16 Versalhöhe

Die Versalhöhe ist nur abgelegt, falls die Blockformatversion 2 oder höher ist. Ansonsten ist der Block kürzer.

"post" Block

Details "post" Block
Details Unterstreichung

PositionGrösse Typ Wert
42 Byte int16 Schrägung Ganzzahlteil
62 Byte uint16 Schrägung Bruchteil
82 Byte int16 Unterstreichungsabstand
102 Byte int16 Unterstreichungsdicke
124 Byte uint32 Fixbreitenschrift

Der Unterstreichungsabstand ist die Distanz zur Oberkante der Unterstreichungslinie, nicht zur Linienmitte.

Ein Wert 0 in „Fixbreitenschrift“ bezeichnet eine Proportionalschrift. Ein Wert ungleich 0 ist eine Fixbreitenschrift.

"hhea" Block

Details "hhea" Block

PositionGrösse Typ Wert
342 Byte uint16 Anzahl GIDs mit expliziter Zeichenbreite

"hmtx" Block

Details "hmtx" Block

Der „hmtx“ Block besteht aus einer Liste mit folgenden Angaben für jede GID mit expliziter Zeichenbreite:

PositionGrösse Typ Wert
02 Byte uint16 Zeichenbreite
22 Byte int16 Weissraum links

Die GID 0 ist immer das Zeichen, welches ausgegeben wird, wenn ein zu druckendes Zeichen in der Schrift fehlt.

GIDs ohne explizite Zeichenbreite haben dieselbe Zeichenbreite, wie der letzte Eintrag dieser Liste.

"cmap" Block

Details "cmap" Block

PositionGrösse Typ Wert
02 Byte uint16 Blockversion
22 Byte uint16 Anzahl Unterblocks

Darauf folgt eine Liste mit folgenden Angaben für jeden Unterblock:

PositionGrösse Typ Wert
02 Byte uint16 Plattform
22 Byte uint16 Kodierung
44 Byte uint32 Position

Plattform und Kodierung können unter anderem folgende für uns interessante Kombinationen sein:

PlattformKodierung Typ
3 0symbolische Schrift
3 1Unicode (UCS-2)
3 10Unicode (voll)
0 5Unicode-Varianten

Unterblocks für symbolische Schriften und UCS-2 sollten im Format 4 sein. Unterblocks für Vollzugriff auf Unicode sollten im Format 12 oder 13 sein. Unterblocks für Unicode-Variantenselektoren müssen im Format 14 sein.

Format 4 Unterblock

Details Format 4 Unterblock

PositionGrösse Typ Wert
02 Byte uint16 Format
22 Byte uint16 Länge
42 Byte uint16 Sprache
62 Byte uint16 Listenlänge
82 Byte uint16 Suchrahmen
102 Byte uint16 Selektorgrösse
122 Byte uint16 Suchüberlauf

Darauf folgen folgende Daten:

Grösse Inhalt
Listenlänge Liste der Endcodes
2 Byte 0-Bytes
Listenlänge Liste der Startcodes
Listenlänge Deltaliste
Listenlänge Offsetliste

Alle Listen enthalten einen uint16 (2 Byte) Eintrag für jedes Segment.

Algorithmus zur Ermittlung GID anhand Unicode-Nummer:

erstes Segment mit Endcode >= Unicode-Nummer suchen
falls Startcode > Unicode-Nummer:
GID = 0
Abbruch
falls Offset > 0:
Position GID = 16 + Listenlänge * 3 + Segmentnummer * 2 + Offset + (Unicode-Nummer - Startcode) * 2
GID lesen (uint16)
sonst:
GID = Unicode-Nummer
falls Delta > 0:
GID = (GID + Delta) modulo 0x10000

Format 12/13 Unterblock

Details Format 12/13 Unterblock

PostionLänge Typ Inhalt
02 Byte uint16 Format
22 Byte uint16 unbenutzt
44 Byte uint32 Länge
84 Byte uint32 Sprache
124 Byte uint32 Anzahl Segmente

Darauf folgt eine Liste mit folgenden Angaben für jedes Segment:

PositionLänge Typ Inhalt
04 Byte uint32 Startcode
44 Byte uint32 Endcode
84 Byte uint32 erste GID

Bei Format 12 erhält der Startcode die „erste GID“. Für die übrigen Codes werden die GIDs analog zu den Unicode-Nummern hochgezählt.

Bei Format 13 erhalten alle Unicode-Nummern des Segments die angegebene GID.

Format 14 Unterblock

Details Format 14 Unterblock

PositionLänge Typ Inhalt
02 Byteuint16Format
24 Byteuint32Länge
64 Byteuint32Anzahl Selektorcodes

Darauf folgt eine Liste mit folgenden Angaben für jeden Selektorcode:

PositionLänge Typ Inhalt
03 Byteuint24Unicode-Nummer Selektor
34 Byteuint32Position Standardliste
74 Byteuint32Position Abweichungsliste

Nur die Abweichungsliste ist von Interesse. Ist die Position 0, so existiert keine Abweichungsliste für diesen Code. Ansonsten ist die Position vom Beginn des Unterblocks an gerechnet.

Die Abweichungsliste beginnt folgendermassen:

PositionLänge Typ Inhalt
04 Byteuint32Anzahl Abweichungen

Darauf folgt eine Liste mit folgenden Angaben für jede Abweichung:

PositionLänge Typ Inhalt
03 Byteuint24Unicode-Nummer
32 Byteuint16GID

"kern" Block

Details "kern" Block

Dieser Block ist optional.

An dieser Stelle ist nur der de facto Minimalstandard beschrieben, der von allen Systemen unterstützt wird.

PositionGrösseTyp Inhalt
02 Byteuint16Version
22 Byteuint16Anzahl Unterblocks

Die Version muss 0 sein, ansonsten muss der Block ignoriert werden.

Daraufhin folgen die einzlnen Unterblocks direkt hintereinander. Die Unterblocks sind so aufgebaut:

PositionGrösseTyp Inhalt
02 Byteuint16Version
22 Byteuint16Unterblocklänge
42 Byteuint16Unterblocktyp
62 Byteuint16Anzahl Einträge
82 Byteuint16Suchrahmen
102 Byteuint16Selektorgrösse
122 Byteuint16Suchüberschuss

Der Unterblocktyp muss 0 für vertikale Schreibrichtung oder 1 für horizontale Schreibrichtung sein. Bei anderen Werten muss der Unterblock ignoriert werden.

Danach folgt eine Liste mit der angegebenen Anzahl Einträge. Die Einträge sind folgendermasen aufgebaut:

PositionGrösseTyp Inhalt
02 Byteuint16GID Zeichen links
22 Byteuint16GID Zeichen rechts
42 Byteint16 Unterschneidung

"GPOS" und "GSUB" Block

siehe Schriftfeaturesystem

"CFF " Block

Dieser Block enthält eine Schriftdatei im CFF-Format