True Type Font
Die Geschichte der True-Type-Fonts und wie sich sich in Java einfach nutzen lassen.
Grafische Oberflächen stellen wie Drucker Zeichensätze wie selbstverständlich dar. Doch der Weg von Datei bis Darstellung ist lang gewesen und führt unweigerlich über die Firma Adobe, die erstmalig die standardisierte Zeichendefinition PostScript öffentlich machte. Genauer gesagt definiert PostScript noch etwas mehr, doch das soll uns hier nicht interessieren. Die erste kommerzielle Zeichensatzrevolution begann dann 1985, als der Drucker LaserWriter von Apple das Adobe Format PostScript rastern könnte. Die Definition eines Zeichensatzes lag bis dahin nur in Bitmaps vor, doch die Postscript Zeichensätze, wie auch die TrueType Zeichensätze, um die es später gehen soll, lagen als Punktbeschreibung vor. Die Rasterung übersetzte diese Punkt in eine Bitmap, die dann entweder auf dem Bildschirm oder Drucker ausgegeben wird. Durch die Punktebeschreibung waren also nicht mehr größenabhängige Beschreibungen vorhanden sondern die Zeichen (auch Glyphs genannt) wurden durch Linien und Kurven in kubischen Bézier-Kurven beschrieben.
Die Visualisierung der Zeichensätze machte Microsoft und Apple Sorgen, da Adobe mehrere Defintionen der PostScript Zeichensätze pflegte, darunter Type 1 (PS-1) und Type 3 (PS-3). Type 1 nutzen sogenannte Hints, um auch bei unterschiedlichen Größen und grafischen Oberflächen optimale Darstellungen zuzulassen. Diese Definition war jedoch geheim. Zeichensätze vom Typ 3 sahen zwar auf dem Papier gut aus, nicht aber auf dem Bildschirm mit niedriger Auflösung - hier fehlen die Informationen aus den Hints (engl. Hinweis). Microsoft und Apple wollten nun ihre Zeichensatzausgabe nicht Adobe überlassen (die natürlich einen Type 1 Rasterer im Programm hatten), sondern sie definierten ihre eigene Font-Technologie, die nicht mehr auf Bézier-Kurven, sondern auf quadratischen B-Splines basiert. Apple machte dabei den Anfang mit Royal, welches später in TrueType (TT) umgetauft wurde. Von Anfang an achtete daher Apple an eine weitgehende Unterstützung der Hints, die im Vergleich zu den Hints in PS-Fonts herausragt. Dies war sechs Jahre nach den PostScript Fonts. Der einzige Hersteller, der dennoch bei PostScript Type 1 Zeichensätze geblieben ist, ist IBM mit dem Betriebssystem OS/2. Daneben nutze auch NeXtStep diese Zeichensatzdefinitionen, doch das System hallte nicht lange nach.
Nachdem Apple den Anfang mit TT gemacht hatte und es 1991 in MacOS integrierte, übernahm auch Microsoft (die bis sich bis dahin an einem wenig lauffähigen PostScript-Clone TrueImage versuchten) die Technologie für Windows 3.1. Adobe erkannte die Konsequenz dieser Allianz früh und öffnete die Spezifikation für PostScript Type 1 Zeichensätze im März 1990. In der Mitte des Jahre lieferte Adobe zusätzlich den Adobe Type Manager (ATM) aus, der Type 1 (aber keine Type 3) PostScript Zeichensätze für den Bildschirm und für nicht-PostScript fähige Drucker darstellte. Heutzutage existieren beide Definitionen immer noch parallel und für Drucker ist die Frage welches nun besser ist, nicht zu beantworten. Moderne Drucker haben auch einen eigenen TrueType Raster im ROM eingebaut. In der Zukunft wird die Unterscheidung wohl auch unwichtiger werden, da Microsoft die ›offene‹ OpenType Spezifikation (auch TrueType Open Version 2 genannt) nach vorne bringt. Ein Zeichensätze PS-1 oder TrueType wird dabei in einer OpenType Datei gekapselt und dem Raster übergeben und berechnet. Dabei übernimmt die PS-1 Rasterung Adobe, die eine Zusammenarbeit mit Microsoft unterstützen und die TT Rasterung Microsoft. In Zukunft möchte Microsoft und Adobe Zeichensätze im OpenType unterstützen und nach bringen.
TTF in Java nutzen
Eine Einschränkung mit den gegeben vordefinierten Standard-Zeichensätzen (Dialog, DialogInput, Monospaced, Serif, SansSerif, Symbol) ist, dass dies zu wenig sind. Doch die Font Kasse bietet die statisch Methode createFont() an, die zu einen Eingabestrom auf ein TrueType Zeichensatz das entsprechende Fontobjekt zurückgibt.
Font f = Font.createFont( Font.TRUETYPE_FONT,
new FileInputStream("f.ttf") );
Der erste Parameter ist die fest vorgeschriebene Konstante Font.TRUETYPE_FONT, andere Parameter sind nicht definiert und führen zu einer IllegalArgumentException("font format not recognized"). Der zweite Parameter ist ein Eingabestrom zu der Binärdatei mit den Zeichensatzinformationen. Die Daten werden ausgelesen und zu einem Font Objekt verarbeitet. Da die Daten intern über einen gepufferten Datenstrom in eine temporäre Datei geschrieben wird, ist eine eigene Pufferung über einen BufferedInputStream nur doppelter Overhead. Waren die Beschreibungsinformationen in der Datei ungültig, so erzeugt die Fontklasse eine FontFormatException("Unable to create font - bad font data"). Dateifehler fallen hier nicht drunter und werden extra über eine IOException angezeigt. Der Datenstrom wird anschließend nicht wieder geschlossen.
Wir wundern uns vielleicht an dieser Stelle, dass die Methode createFont() von der Arbeitsweise mit dem Konstruktor ähnlich sein müsste, aber der Parameterliste die Attribute fehlen. Das liegt daran, dass die Methode automatisch einen Zeichensatz der Größe 1 im Stil PLAIN erzeugt. Um daher einen größeren Zeichensatz zu erzeugen, müssen wie ein zweites Font Objekt anlegen. Dies geschieht am einfachsten mit der Methode deriveFont().
font = f.deriveFont( 20f );
Der Parameter ist ein float und kein double