Alternativzeichen und Ligaturen

Alternativzeichen sind Varianten eines Zeichens für gewisse typographische Effekte. Sie ähneln etwas den Zeichenvarianten, die wir unter Erweiterte Unicode-Zeichen kennengelernt haben. Anders als dort gibt es hier aber keine speziellen Selektorzeichen. Ich stelle hier zwei Arten von Alternativzeichen vor, nämlich Kapitälchen und Mediävalziffern.

Kapitälchen sind verkleinerte Versionen der Grossbuchstaben, welche anstelle von Kleinbuchstaben verwendet werden können. Anders als die bereits behandelten falschen Kapitälchen handelt es sich hier um speziell für diesen Zweck erstellte Varianten.

Mediävalziffern sind Ziffern, welche typischerweise nur die Höhe eines kleinen x haben. Die Ziffern 3, 4, 5, 7 und 9 reichen dafür unter die Grundlinie. Die Ziffern 6 und 8 sind normal. Solche Ziffern wurden früher verwendet, weil sie sich optisch besser in Fliesstext einpassen. Heute verwendet man sie praktisch nur noch des Effekts wegen.

Ligaturen wiederum sind Zeichen, die aus mehreren Einzelzeichen zusammengesetzt werden. Sie werden vor allem verwendet, um typographisch heikle Zeichenkombinationen besser abzubilden, oder wo bestimmte Zeichenkombinationen generell anders geschrieben werden, als wenn die Zeichen einzeln stehen. Typische Beispiele sind Ligaturen für „fi“, „fl“ oder „ff??. Ligaturen solltem möglichst immer angewendet werden, ausser wenn der Zeichenabstand erhöht wurde (Anweisung Tc). Bei erhöhtem Zeichenabstand sollte man auf Ligaturen verzichten, da die Einzelzeichen sonst zu nahe aneinander stehen.

Der „GSUB“ Block enthält diverse Umsetztabellen, mit denen man anhand der normalen GID(s) die GID der Alternativzeichen bzw. Ligaturen ermitteln kann. Logischerweise können wir diese Information nur Nutzen, wenn wir die Schrift per Direktzugriff verwenden.

der Blockheader

Der „GSUB“ Block beginnt immer mit folgenden Angaben:

Position GrösseTyp Inhalt
04 Byteuint32Version
42 Byteuint16Position Schrift/Sprachtabelle
62 Byteuint16Position Featuretabelle
82 Byteuint16Position Lookuptabelle

Damit lassen sich mit dem unter Das Schriftfeaturesystem erwähnten Verfahren die Position des Unterblocks bzw. der Unterblöcke ermitteln. Die gesuchten Feature-IDs sind:

smcpKapitälchen
onumMediävalziffern
ligaLigaturen

Der Inhalt des Unterblocks hängt von der Typnummer im Lookupeintrag ab. Für diese Features sind die Nummern 1, 4 und 7 möglich.

Typ 1 enthält eine Tabelle, deren Einträge von einer GID auf eine andere Verweisen. Dieses Format ist geeignet für Kapitälchen und Mediävalziffern.

Typ 4 enthält eine Tabelle, deren Einträge von einer Sequenz von GIDs auf eine einzelne GID verweisen. Dieses Format ist geeignet für Ligaturen.

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

Falls für ein Feature mehrere Unterblöcke vorhanden sind, so müssen sie in der vorgegebenen Reihenfolge abgearbeitet werden, bis das zu ersetzende Zeichen (bzw. die Zeichenkombination) gefunden wurde. Spätere Blöcke können ignoriert werden.

Typ 7

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

PositionGrösseTyp Inhalt
02 Byteuint16Typ
22 Byteuint16Format
44 Byteuint32Position

Die Position ist ab dem Anfang des Unterblocks gerechnet.

Typ 1

Dieser Unterblock enthält eine Umsetztabelle, deren Einträge von einer GID zur anderen verweisen. Es gibt dabei zwei Formate. Welches Format wir haben, ist an einem uint16 am Anfang des Unterblocks erkennbar, welcher den Wert 1 oder 2 enthalten muss.

Format 1

Im diesem Format besteht der Unterblock lediglich aus folgenden Einträgen:

PositionGrösseTyp Inhalt
02 Byteuint16Format (immer 1)
22 Byteuint16Position Zeichenliste
42 Byteuint16GID Delta

Die Zeichenliste enthält eine Liste aller Zeichen, die ersetzt werden sollen. Die Position ist gerechnet ab dem Anfang des Unterblocks.

Um das Alternativzeichen zu erhalten, müssen wir zur GID des Originalzeichens das GID Delta addieren. Erhalten wir dabei eine Zahl grösser 0x10000, so müssen wir 0x10000 subtrahieren.

Format 2

Bei diesem Format beginnt der Unterblock folgendermassen:

PositionGrösseTyp Inhalt
02 Byteuint16Format (immer 2)
22 Byteuint16Position Zeichenliste
42 Byteuint16Anzahl Zeichen

Auch hier enthält die Zeichenliste eine Liste aller Zeichen, die ersetzt werden sollen, und die Position ist gerechnet ab dem Anfang des Unterblocks. Die „Anzahl Zeichen“ sollte mit der Anzahl in der Zeichenliste identisch sein.

Danach folgt ein Eintrag für jedes Zeichen:

PositionGrösseTyp Inhalt
02 Byteuint16GID Alternativzeichen

Die GID des Originalzeichens ist nicht angegeben. Diese ergibt sich aus der Zeichenliste oben. Das heisst der erste Eintrag hier ersetzt das erste Zeichen der Zeichenliste, der zweite Einträg ersetzt das zweite Zeichen der Zeichenliste, und so weiter.

Typ 4

Dieser Unterblock enthält eine Umsetztabelle, deren Einträge von jeweils einer Serie von GIDs auf eine einzelne GID verweisen. Der Unterblock beginnt immer folgendermassen:

PositionGrösseTyp Inhalt
02 Byteuint16Format (immer 1)
22 Byteuint16Position Zeichenliste
42 Byteuint16Anzahl Ligatursätze

Die Zeichenliste enthält eine Liste aller Zeichen, mit welchen eine Ligatur beginnen kann. Die Position ist gerechnet ab dem Beginn des Unterblocks.

Die Ligaturen sind in Ligatursätze gruppiert. Es gibt einen Ligatursatz für jedes Zeichen, mit dem Ligaturen beginnen können. Die Anzahl Ligatursätze sollte folglich identisch sein mit der Anzahl Zeichen in der Zeichenliste.

Nun folgt für jeden Ligatursatz folgender Eintrag:

PositionGrösseTyp Inhalt
02 Byteuint16Position Ligatursatz

Die Position ist gerechnet ab dem Beginn des Unterblocks. Die Ligatursätze hier sind gleich angeordnet, wie die Zeichen in der Zeichenliste. Das heisst, der erste Ligatursatz deckt alle Ligaturen ab, die mit dem ersten Zeichen der Zeichenliste beginnen, der zweite Ligatursatz alle, die mit dem zweite Zeichen der Zeichenliste beginnen, und so weiter.

Der Ligatursatz selbst beginnt folgendermassen:

PositionGrösseTyp Inhalt
02 Byteuint16Anzahl Ligaturen

Daraufhin folgt für jede Ligatur folgender Eintrag:

PositionGrösseTyp Inhalt
02 Byteuint16Position Ligatur

Die Position ist gerechnet ab dem Beginn des Ligatursatzes. Die Ligatur wiederum beginnt folgendermassen:

PositionGrösseTyp Inhalt
02 Byteuint16GID Ligatur
22 Byteuint16Anzahl Zeichen

Mit „Anzahl Zeichen“ ist hier die Anzahl der in der Ligatur zusammengefassten Zeichen gemeint. Darauf folgt der Reihe nach für jedes Zeichen ausser dem ersten (welches ja schon bekannt ist) folgende Angabe:

PositionGrösseTyp Inhalt
02 Byteuint16GID Originalzeichen

Vorsicht: Da „Anzahl Zeichen“ alle Zeichen der Ligatur zählt, diese Liste aber alle Zeichen ausser dem Ersten aufführt, ist die Länge der Liste um einen Eintrag kürzer.

Gerade bei Ligaturen kann es vorkommen, dass für eine bestimmte Textstelle mehrere Ligaturen möglich sind. In diesem Fall gilt immer der erste mögliche Treffer in der Liste.

ToUnicode

Die Alternativzeichen und Ligaturen sollte man ebenfalls im ToUnicode Stream vermerken, damit die Volltextsuche sowie Copy&Paste auch mit so gesetzten Texten funktionieren.

Bei Ligaturen verweist die GID aber natürlich nicht auf ein einzelnes Unicode-Zeichen, sondern auf eine ganze Serie. Hier gilt, was ich schon unter Erweiterte Unicode-Zeichen gesagt habe: Die Definition verweist genaugenommen nicht auf Unicode-Nummern, sondern auf UTF-16BE Strings in Hexschreibweise. Auch hier gilt, das analoge Segmente möglich sind. Dabei wird das letzte Byte des Strings hochgezählt, wobei die restlichen Bytes innerhalb des Segments identisch sein müssen.

Für manche häufig verwendete Ligaturen wie „fi“, „fl“ oder „ff“ gibt es Unicode-Nummern. Bei vielen Schriften, welche diese Ligaturen verwenden, ist im cmap Block auch ein Verweis von der jeweiligen Unicode-Nummer auf die GID enthalten. Für den ToUnicode Stream ist es aber besser, von der GID auf einen String mit den Einzelzeichen zu verweisen.