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.
Dieser Block steht am Anfang der Datei, und verweist auf die anderen Blöcke.
Position | Grösse | Typ | Wert |
---|---|---|---|
0 | 4 Byte | char | Signatur |
4 | 2 Byte | uint16 | Anzahl Blocks |
6 | 2 Byte | uint16 | Suchrahmen |
8 | 2 Byte | uint16 | Selektorgrösse |
10 | 2 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:
Position | Grösse | Typ | Wert |
---|---|---|---|
0 | 4 Byte | char | ID |
4 | 4 Byte | uint32 | Prüfsumme |
8 | 4 Byte | uint32 | Position |
12 | 4 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.
Details "name" Block
Details Schriftartenname
Position | Grösse | Typ | Wert |
---|---|---|---|
0 | 2 Byte | uint16 | Blockformatversion |
2 | 2 Byte | uint16 | Anzahl Strings |
4 | 2 Byte | uint16 | Startposition Strings |
Darauf folgt ein Verzeichnis mit folgenden Daten für jeden String:
Position | Grösse | Typ | Wert |
---|---|---|---|
0 | 2 Byte | uint16 | Plattform |
2 | 2 Byte | uint16 | Kodierung |
4 | 2 Byte | uint16 | Sprache |
6 | 2 Byte | uint16 | Typ |
8 | 2 Byte | uint16 | Länge |
10 | 2 Byte | uint16 | Position |
Folgende Strings sind von Interesse:
Plattform | Kodierung | Sprache | Typ | Inhalt |
---|---|---|---|---|
3 | 0 | 0x409 | 1 | Schriftart (symbolische Schrift) |
3 | 0 | 0x409 | 4 | Schriftname (OS/symbolische Schrift) |
3 | 1 | 0x409 | 1 | Schriftart (normale Schrift) |
3 | 1 | 0x409 | 4 | Schriftname (OS/normale Schrift) |
3 | * | * | 6 | Schriftname (Postscript) |
Die Strings selbst sind folgendermassen abgelegt:
Position | Grösse | Typ |
---|---|---|
Startposition + Stringposition | Stringlänge | wchar |
Die Kodierung ist UTF-16BE.
Details "head" Block
Details Mac-Style
Position | Grösse | Typ | Wert |
---|---|---|---|
18 | 2 Byte | uint16 | Skala |
36 | 2 Byte | int16 | BBox x1 |
38 | 2 Byte | int16 | BBox y1 |
40 | 2 Byte | int16 | BBox x2 |
42 | 2 Byte | int16 | BBox y2 |
44 | 2 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.
Details "OS/2" Block
Details Lizenz
Details Zeilendurchschuss
Details Hoch- und Tiefstellung
Position | Grösse | Typ | Wert |
---|---|---|---|
0 | 2 Byte | uint16 | Blockformatversion |
8 | 2 Byte | uint16 | Lizenz |
12 | 2 Byte | uint16 | Grösse Tiefstellung |
16 | 2 Byte | uint16 | Absenkung Tiefstellung |
20 | 2 Byte | uint16 | Grösse Hochstellung |
24 | 2 Byte | uint16 | Anhebung Hochstellung |
68 | 2 Byte | int16 | Oberlänge |
70 | 2 Byte | int16 | Unterlänge |
72 | 2 Byte | int16 | Zeilendurchschuss |
88 | 2 Byte | int16 | Versalhöhe |
Die Versalhöhe ist nur abgelegt, falls die Blockformatversion 2 oder höher ist. Ansonsten ist der Block kürzer.
Details "post" Block
Details Unterstreichung
Position | Grösse | Typ | Wert |
---|---|---|---|
4 | 2 Byte | int16 | Schrägung Ganzzahlteil |
6 | 2 Byte | uint16 | Schrägung Bruchteil |
8 | 2 Byte | int16 | Unterstreichungsabstand |
10 | 2 Byte | int16 | Unterstreichungsdicke |
12 | 4 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.
Position | Grösse | Typ | Wert |
---|---|---|---|
34 | 2 Byte | uint16 | Anzahl GIDs mit expliziter Zeichenbreite |
Der „hmtx“ Block besteht aus einer Liste mit folgenden Angaben für jede GID mit expliziter Zeichenbreite:
Position | Grösse | Typ | Wert |
---|---|---|---|
0 | 2 Byte | uint16 | Zeichenbreite |
2 | 2 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.
Position | Grösse | Typ | Wert |
---|---|---|---|
0 | 2 Byte | uint16 | Blockversion |
2 | 2 Byte | uint16 | Anzahl Unterblocks |
Darauf folgt eine Liste mit folgenden Angaben für jeden Unterblock:
Position | Grösse | Typ | Wert |
---|---|---|---|
0 | 2 Byte | uint16 | Plattform |
2 | 2 Byte | uint16 | Kodierung |
4 | 4 Byte | uint32 | Position |
Plattform und Kodierung können unter anderem folgende für uns interessante Kombinationen sein:
Plattform | Kodierung | Typ |
---|---|---|
3 | 0 | symbolische Schrift |
3 | 1 | Unicode (UCS-2) |
3 | 10 | Unicode (voll) |
0 | 5 | Unicode-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.
Position | Grösse | Typ | Wert |
---|---|---|---|
0 | 2 Byte | uint16 | Format |
2 | 2 Byte | uint16 | Länge |
4 | 2 Byte | uint16 | Sprache |
6 | 2 Byte | uint16 | Listenlänge |
8 | 2 Byte | uint16 | Suchrahmen |
10 | 2 Byte | uint16 | Selektorgrösse |
12 | 2 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
Details Format 12/13 Unterblock
Postion | Länge | Typ | Inhalt |
---|---|---|---|
0 | 2 Byte | uint16 | Format |
2 | 2 Byte | uint16 | unbenutzt |
4 | 4 Byte | uint32 | Länge |
8 | 4 Byte | uint32 | Sprache |
12 | 4 Byte | uint32 | Anzahl Segmente |
Darauf folgt eine Liste mit folgenden Angaben für jedes Segment:
Position | Länge | Typ | Inhalt |
---|---|---|---|
0 | 4 Byte | uint32 | Startcode |
4 | 4 Byte | uint32 | Endcode |
8 | 4 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.
Position | Länge | Typ | Inhalt |
---|---|---|---|
0 | 2 Byte | uint16 | Format |
2 | 4 Byte | uint32 | Länge |
6 | 4 Byte | uint32 | Anzahl Selektorcodes |
Darauf folgt eine Liste mit folgenden Angaben für jeden Selektorcode:
Position | Länge | Typ | Inhalt |
---|---|---|---|
0 | 3 Byte | uint24 | Unicode-Nummer Selektor |
3 | 4 Byte | uint32 | Position Standardliste |
7 | 4 Byte | uint32 | Position 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:
Position | Länge | Typ | Inhalt |
---|---|---|---|
0 | 4 Byte | uint32 | Anzahl Abweichungen |
Darauf folgt eine Liste mit folgenden Angaben für jede Abweichung:
Position | Länge | Typ | Inhalt |
---|---|---|---|
0 | 3 Byte | uint24 | Unicode-Nummer |
3 | 2 Byte | uint16 | GID |
Dieser Block ist optional.
An dieser Stelle ist nur der de facto Minimalstandard beschrieben, der von allen Systemen unterstützt wird.
Position | Grösse | Typ | Inhalt |
---|---|---|---|
0 | 2 Byte | uint16 | Version |
2 | 2 Byte | uint16 | Anzahl Unterblocks |
Die Version muss 0 sein, ansonsten muss der Block ignoriert werden.
Daraufhin folgen die einzlnen Unterblocks direkt hintereinander. Die Unterblocks sind so aufgebaut:
Position | Grösse | Typ | Inhalt |
---|---|---|---|
0 | 2 Byte | uint16 | Version |
2 | 2 Byte | uint16 | Unterblocklänge |
4 | 2 Byte | uint16 | Unterblocktyp |
6 | 2 Byte | uint16 | Anzahl Einträge |
8 | 2 Byte | uint16 | Suchrahmen |
10 | 2 Byte | uint16 | Selektorgrösse |
12 | 2 Byte | uint16 | Suchü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:
Position | Grösse | Typ | Inhalt |
---|---|---|---|
0 | 2 Byte | uint16 | GID Zeichen links |
2 | 2 Byte | uint16 | GID Zeichen rechts |
4 | 2 Byte | int16 | Unterschneidung |
siehe Schriftfeaturesystem
Dieser Block enthält eine Schriftdatei im CFF-Format
Diskussion