Programmiererecke: Zeichenzauber

Im vergangenen Monat berichteten wir über »SpeedoGDOS/MEMORY.SYS«. Diesmal geht es um Farbzeichensätze und pixelorientierte Schriftzüge.

Die bereits in der letzten Ausgabe beschrieben, bietet »SpeedoGDOS« keine Möglichkeit, die Zeichenbreite im Pixelformat einzustellen. Das ist normalerweise kein Problem; wenn jedoch der mit einer höheren DPI-Rate als der Bildschirm compilierte »MEMORY.SYS«-Treiber Verwendung findet, kommt es zu Unstimmigkeiten. Deshalb muß auf Wunsch »zu Fuß« nachkorrigiert und dabei die Pixelgröße umgerechnet werden. Wie so etwas in der Praxis aussehen könnte, zeigt unser Listing, das aber nur ein Codesegment, nicht jedoch ein lauffähiges Programm ist.

Ein Argument gegen die Verwendung von Speedo-Zeichensätzen war bislang die Tatsache, daß GEM-Zeichensätze grundsätzlich einfarbig sind: lobenswert, daß GEM überhaupt in der Lage ist, Schriftzüge unter Verwendung verschiedener Farben auszugeben, jedoch genügt ein einfarbiger Schriftzug in den seltensten Fällen gehobenen Ansprüchen.

Im DTP-Bereich mag man mit einfarbigen Zeichen eine Zeit lang ganz gut leben können, zumal gedruckte Zeichen mit Farb- oder Grauverläufen den Leser ohnehin nur verwirren und selten zu einer Verbesserung des Druckbildes beitragen. Im Videobereich sind mehrfarbige Schriften jedoch absolut unverzichtbar. Das liegt zum einen daran, daß im Videobereich nur in den sehenden Fällen Schriftzüge auf eine ebenfarbige Unterlage gedruckt werden, wie dies bei Papier üblicherweise der Fall ist. Videobilder sind bewegte Bilder und als solche starken Schwankungen bei Farbe und Helligkeit unterworfen. Eine weiße Schrift versagt z. B. bei heller Kleidung, eine dunkle Schrift ist auf den meisten Farbtönen unlesbar. Da die Helligkeit der Schrift des optischen Eindrucks wegen und aus technischen Gründen nicht ständig wechseln oder sich der Umgebung anpassen kann, unterlegt man in der Videotechnik grundsätzlich helle Schrift mit dunklen Rahmen. Soweit so gut. Dunkle Rahmen kann GEM mit dem Textattribut »OUTLINED« auch erzeugen. Leider kann der Programmierer jedoch weder Abstand noch Dicke dieses Rahmens angeben. Was also tun? Eine Lösung sind eigene Fontformate. Da jedoch ein kleines Unternehmen niemals die Zeichensatzfülle und -qualität der Branchenriesen erreichen wird, kann diese Insellösung nur als erster Schritt betrachtet werden. Für etablierte Schriftsätze muß sich der Programmierer etwas besseres einfallen lassen. Das Verfahren, das wir an dieser Stelle vorstellen, ist dem Programm Overlay entlehnt, das neben eigenen Fonts die Fähigkeit bietet, jede beliebige Bitmap mit einem Rahmen beliebiger Farbe zu versehen. Dazu verwendet es zunächst den MEMORY.SYS-Treiber um einen Speedo-Bitstream-Schriftzug ins 1-Plane-Bitmap-Format zu bringen.

Diese Bitmap wird nun auf Wunsch des Anwenders um einige Pixel versetzt um sich selbst rotiert und mit einer anderen Farbe gestanzt. Der Vorteil: Sowohl Farbe als auch Abstand des Rahmens sind frei wählbar. Darüberhinaus bleibt das Programm »sauber«, weil es für die nötigen Kopieraktionen ausschließlich die GEM-Rasterfunktionen benötigt. Mit etwas Geschick meistern Sie so gleich noch ein weiteres Problem: Die Auflösung von Fernsehbildern ist stark begrenzt. Der Atari »Falcon 030« besitzt beispielsweise Auflösungen, die in ihrer Pixeldichte das Fernsehbild bei weitem übertreffen. Dennoch sind billige, computergenerierte Zeichensätze leicht an ihren Kamen zu erkennen: sobald die Kanten zu scharf werden, treten die einzelnen Pixel hervor und stören das leicht verwaschene Fernsehbild. Deshalb benutzen Experten handbearbeitete Zeichensätze, in denen sie die Ecken und Kanten ihrer Zeichen mit immer dunkler werdenden Farben füllen, so daß der Eindruck eines fließenden und damit gleichmäßigeren Übergangs entsteht. Dieser Effekt heißt »Antialiasing« und ist beispielsweise bei vielen Computerspielen zu bewundern, in denen Bildschirmkünstler mit primitivsten Mitteln (meist genügen ihnen drei oder vier Farbtöne) Schriftzüge erzeugen, die in ihrer Brillianz kaum zu übertreffen sind. So etwas läßt sich schwer automatisieren, zumal eine gehörige Portion Erfahrung und handwerkliches Geschick dazu gehören, hochwertige Zeichensätze zu erzeugen.

Mit dem hier beschriebenen Verfahren ist man in der Lage binnen kürzester Zeit Schriftzüge entwerfen, die erheblich weniger »anecken«: zwei bis drei Rahmen mit abfallender Farbintensität tun‘s in den meisten Fällen. Ähnlich lassen sich auch »echte« Schatten erzeugen. Dabei sind Winkel und Abstand des generierten Schatten frei wählbar und nicht auf einen festen Wert beschränkt. Wenn man sich einmal darüber klar geworden ist, wie ein Schatten gestanzt werden muß, um mit dem Originalobjekt in Kombination ein schattiertes Objekt zu bilden, sind nur noch einige trigonometrische Funktionen notwendig, die aus Winkel und Abstand die nötigen Koordinatentransformationen für die VDI-Rasterkopiefunktionen zusammenpuzzlen.

Jetzt hören wir schon einige Zweifler nörgeln: »Das hätten wir aber auch mit den GEM-Zeichensatzfunktionen bewerkstelligen können, ohne die Schriftzüge in Raster zu konvertieren«. Mag sein. Aber edle und teure Zeichensätze aus der Videotechnik haben keine einfarbigen Oberflächen, sondern geringfügige Farbverläufe. Diese sind jedoch mit den GEM-Textfunktionen beim besten Willen nicht zu machen; wohl aber mit den Rasterfunktionen. Sind die Schriftzüge einmal mit Hilfe des MEMORY.SYS-Treibers ins 1-plane-Rasterformat gebracht, lassen sich mit ihnen beliebige Muster stanzen und dadurch Muster und Bilder auf Bit-Mapped-Schriftzüge projizieren. Das funktioniert übrigens nicht nur mit MEMORY.SYS-Schriften.

Auch der Atari-Laserdrucker-Treiber ist in der Lage, Schriftzüge zu erzeugen, die dann auf Pixelebene mit Mustern, Bildern oder auch anderen Texten überlagert werden können. Sinnvoll ist das aber nur dann, wenn Sie sehr große Texte mit kleineren Objekten überlagern, weil das Schriftbild unter weißen Pixeln auf weißem Grund mitunter stark leidet. (uw) /* @(#) width.c @(#) Laurenz Prüßner (c) 1993 */

#include <vdi.h>
#include <portab.h>

LONG my_vst_setsize (WORD handle, LONG point, WORD *chwd, WORD *chht,
                     WORD *cellwd, WORD *cellht)
{
	VDIPB PB;
	LONG  l;

	PB.contrl = _VDIParBlk.contrl;
	PB.intin  = _VDIParBlk.intin;
	PB.ptsin  = _VDIParBlk.ptsin;
	PBAntout  = _VDIParBlk.intout;
	PB.ptsout = _VDIParBlk.ptsout;

	_VDIParBlk.contrl[0]  = 252;
	_VDIParBlk.contrl[1]  =   0;
	_VDIParBlk.contrl[3]  =   2;
	_VDIParBlk.contr1[6]  = handle;
	_VDIParBlk.intin[0]   = (WORD) (point >> 16);
	_VDIParBlk.intin[1]   = (WORD) point;

	vdi (&PB);

	*chwd   = _VDIParBlk.ptsout[0];
	*chht   = _VDIParBlk.ptsout[1];
	*cellwd = _VDIParBlk.ptsout[2];
	*cellht = _VDIParBlk.ptsout[3];

	l = _VDIParBlk.intout[0];
	l <<= 16;
	l += _VDIParBlk.intout[1];

	return 1;
}

VOID fit_width( WORD handle, WORD x_screen, WORD x_msys, WORD font_psize_screen)
{
	WORD dummy;
	LONG width;
	double c;

	c = font_psize_screen;
	c /= x_screen;
	c *= x_msys;
	c *= 65636L;

	width = (LONG) c;
	my_vst_setsize (handle, width, &dummy, &dummy, &dummy, &dummy);
}

Laurenz Prüßner
Aus: ST-Magazin 05 / 1993, Seite 40

Links

Copyright-Bestimmungen: siehe Über diese Seite