Unterschneidung

Informationen über Unterschneidung finden sich beim Schriftfeaturesystem in einem „GPOS“ Block. Dieser Block kann noch andere Informationen zur Zeichenplatzierung enthalten. Die Strukturen sind darum allgemeiner ausgerichtet, als dies im „kern“ Block der Fall ist.

der Blockheader

Der „GPOS“ Block beginnt immer mit folgenden Angaben:

Position Grösse Typ Inhalt
04 Byte uint32 Version
42 Byte uint16 Position Schrift/Sprachtabelle
62 Byte uint16 Position Featuretabelle
82 Byte uint16 Position Lookuptabelle

Damit lassen sich mit dem unter Das Schriftfeaturesystem erwähnten Verfahren die Position des Unterblocks bzw. der Unterblöcke ermitteln. Die gesuchte Feature-ID ist dabei „kern“.

Der Inhalt der Unterblocks hängt von der Typnummer im Lookupeintrag ab. Für „kern“ sind die Nummern 2, 8 und 9 erlaubt.

2 steht für normale Unterschneidung.

8 steht für kontextabhängige Unterschneidung. Das ist eine recht komplexe und selten gebrauchte Art der Unterschneidung, bei der die Buchstaben vor und nach dem Buchstabenpaar eine Rolle spielen. Ich gehe hier nicht darauf ein.

9 ist ein Spezialfall. Dieser Unterblock wird verwendet, wenn der uint16 im Lookupeintrag nicht ausreicht, um die eigentliche Position des Unterblocks abzubilden (bei grossen „GPOS“ Blöcken).

Typ 9

Dieser Unterblock verweist lediglich auf den eigentlichen Unterblock. Er ist folgendermassen aufgebaut:

Position Grösse Typ Inhalt
02 Byte uint16 Version
22 Byte uint16 Typ
44 Byte uint32 Position

Die Position ist ab dem Anfang des Unterblocks gerechnet.

Typ 2

Dieser Unterblock enthält die Unterschneidungsinformationen. Dabei ist er flexibler als der „kern“ Block (zumindest flexibler als der allgemein unterstützte Minimalstandard des „kern“ Blocks).

Zum einen unterstützt er neben der normalen Unterschneidung auf Basis von Zeichenpaaren auch solche auf Basis von Zeichenklassenpaaren. Dabei werden die Zeichen in Zeichenklassen eingeteilt, und dann Unterschneidungswerte festgelegt für Kombinationen von bestimmten Zeichenklassen. Dieser Wert gilt dann für alle Kombinationen eines Zeichens aus der linken Klasse mit einem Zeichen aus der rechten Klasse. Auf diese Weise lässt sich Unterschneidung für grosse Zeichensätze definieren, wo die Kombinationsmöglichkeiten sonst schnell in die Milliarden gehen würden.

Zum anderen ist es möglich, mehrere Unterblocks zu definieren. Die Werte der Unterblocks wirken dabei kumulativ. Das heisst, falls sich für ein Zeichenpaar in mehreren Unterblocks Unterschneidungswerte ergeben, so müssen diese addiert werden. Dies wird vor allem in Zusammenhang mit Zeichenklassen verwendet.

Je nachdem, ob die Unterschneidung auf Zeichenpaaren oder Zeichenklassenpaaren basiert, wird mit einem anderen Format gearbeitet. Die Formatnummer ist in einem uint16 am Anfang des Unterblocks festgehalten.

Format 1

Dieses Format kommt für einfache Unterschneidung auf Basis von Zeichenpaaren zur Anwendung. Der Unterblock beginnt folgendermassen:

Position Grösse Typ Inhalt
02 Byte uint16 Format (immer 1)
22 Byte uint16 Position Zeichenliste
42 Byte uint16 Werteformat 1
62 Byte uint16 Werteformat 2
82 Byte uint16 Anzahl Paarlisten

Die Zeichenliste enthält eine Liste der möglichen Zeichen links. Die Position ist ab dem Beginn des Unterblocks gerechnet.

Die beiden Einträge für das Werteformat bestimmen, wie die Werteeinträge aufgebaut sind. Für klassische Unterschneidung muss das Werteformat 1 auf 4 oder 68 stehen, das Werteformat 2 auf 0. Steht etwas anderes, haben wir es wahrscheinlich mit komplexer Unterschneidung zu tun, welche Vertikalversatz enthält. Ähnlich wie bei kontextabhängiger Unterschneidung ist auch dies selten gebraucht und mühsam umzusetzen, weshalb ich nicht darauf eingehe.

Nun kommen wir zu den Paarlisten. Für jedes mögliche Zeichen links gibt es eine Paarliste, welche die dazu passenden möglichen Zeichen rechts und den jeweiligen Unterschneidungswert enthält. Das heisst, die Anzahl Paarlisten sollte identisch sein mit der Anzahl Zeichen in der Zeichenliste.

Auf die erwähnten Angaben folgt zunächst für jeder Paarliste folgender Eintrag:

Position Grösse Typ Inhalt
02 Byte uint16 Position Paarliste

Die Position ist jeweils ab dem Anfang des Unterblocks gerechnet. An der Position findet sich dann die eigentliche Liste. Sie beginnt folgendermassen:

Position Grösse Typ Inhalt
02 Byte uint16 Anzahl Einträge

Daraufhin folgen die Einträge. Ist das Werteformat 1 auf 4 gesetzt, sehen sie folgendermassen aus:

Position Grösse Typ Inhalt
02 Byte uint16 GID rechts
22 Byte int16 Unterschneidung

Ist das Werteformat 1 auf 68 gesetzt, sehen die Einträge so aus:

Position Grösse Typ Inhalt
02 Byte uint16 GID rechts
22 Byte int16 Unterschneidung
42 Byte uint16 Position Hintingtabelle

Die Unterschneidung muss, wie im „kern“ Block, in Promille der Schriftgrösse umgerechnet, und negiert werden, damit die Zahl für den Einsatz in PDF brauchbar ist.

Die Hintingtabelle ist für dein Einsatz in PDF uninteressant. Wir müssen den Eintrag aber natürlich überlesen.

Wie man sieht, ist die GID links nicht explizit aufgeführt. Sie ergibt sich aus der Zeichenliste. Die erste Paarliste deckt das erste Zeichen der Zeichenliste ab, die zweite Paarliste das zweite Zeichen der Zeichenliste, und so weiter.

Format 2

Dieses Format kommt für Unterschneidung auf der Basis von Zeichenklassen zur Anwendung. Es ist folglich ein klein wenig komplexer. Der Unterblock beginnt folgendermassen:

Position Grösse Typ Inhalt
02 Byte uint16 Format (immer 2)
22 Byte uint16 Position Zeichenliste
42 Byte uint16 Werteformat 1
62 Byte uint16 Werteformat 2
82 Byte uint16 Position Klassendefinition links
102 Byte uint16 Position Klassendefinition rechts
122 Byte uint16 Anzahl Klassen links
142 Byte uint16 Anzahl Klassen rechts

Für die Zeichenliste und die Werteformate gilt hier grundsätzlich das gleiche, wie im Format 1. Allerdings benötigen wir die Zeichenliste nicht, da die Einträge hier nicht danach geordnet sind.

Die Positionen der Klassendefinitionen sind ab dem Beginn des Unterblocks gerechnet. Ähnlich wie bei den Zeichenlisten gibt es auch bei der Klassendefinition zwei Formate, die sich anhand eines uint16 am Anfang unterscheiden lassen:

Klassendefinition Format 1

Dieses Format beginnt folgendermassen:

Position Grösse Typ Inhalt
02 Byte uint16 Format (immer 1)
22 Byte uint16 erste GID
42 Byte uint16 Anzahl GIDs

Danach folgt für jede GID ein Eintrag:

Position Grösse Typ Inhalt
02 Byte uint16 Klassennummer

Der erste Eintrag steht dabei für die „erste GID“, der nächste für die erste GID plus 1, und so weiter. Alle nicht aufgeführten GIDs sind in der Klasse 0.

Klassendefinition Format 2

Dieses Format beginnt folgendermassen:

Position Grösse Typ Inhalt
02 Byte uint16 Format (immer 2)
22 Byte uint16 Anzahl GID-Bereiche

Danach folgt für jeden GID-Bereich ein Eintrag:

Position Grösse Typ Inhalt
02 Byte uint16 erste GID
22 Byte uint16 letzte GID
42 Byte uint16 Klassennummer

Alle GIDs von der ersten bis und mit der letzten GID werden dabei der jeweiligen Klassennummer zugeteilt. Die Bereiche dürfen sich dabei nicht überschneiden (ein Zeichen ist immer in genau einer Klasse). Alle GIDs, die in keinem der aufgeführten Bereiche sind, werden der Klasse 0 zugeteilt.

die Unterschneidungstabelle

Nachdem wir nun wissen, welche Zeichen in welcher Klasse sind, können wir die Klassenpaare auslesen. Die „Anzahl Klassen links“ und „Anzahl Klassen rechts“ vom Anfang des Blocks sollte dabei mit der jeweiligen Anzahl definierter Klassen übereinstimmen (einschliesslich der Klasse 0).

Die Tabelle beginnt direkt nach den Angaben am Beginn des Unterblocks (also an Position 16 des Unterblocks). Dabei hat es nacheinander einen Eintrag für jede mögliche Kombination der Klassen links und rechts in folgender Reihenfolge: Zunächst je ein Eintrag für die Kombination der Klasse 0 links mit jeder der Klassen rechts von 0 an aufsteigend. Dann je ein Eintrag für die Klasse 1 links mit jeder der Klassen rechts, und so weiter.

Die Einträge sind wiederum vom Werteformat 1 abhängig. Bei Format 4 sehen sie folgendermassen aus:

Position Grösse Typ Inhalt
02 Byte int16 Unterschneidung

Bei Format 68 folgendermassen:

Position Grösse Typ Inhalt
02 Byte int16 Unterschneidung
22 Byte uint16 Position Hintingtabelle

Auch hier muss die Unterschneidung in Promille der Schriftgrösse umgerechnet sowie negiert werden, und auch hier können wir die Hintingtabelle ignorieren.

Diskussion

Geben Sie Ihren Kommentar ein. Wiki-Syntax ist zugelassen:
P A C G V
 
typographie/fontfeatures/unterschneidung.txt · Zuletzt geändert: 2013/01/17 10:06 (Externe Bearbeitung)
 
Falls nicht anders bezeichnet, ist der Inhalt dieses Wikis unter der folgenden Lizenz veröffentlicht: CC0 1.0 Universal
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki