Speedo-Gonzales: Ein Schriftsystem lernt laufen! Teil 2

Hat sich unser letzter Artikel zu Speedo im wesentlichen an den reinen Anwender gewandt, in der Hoffnung, ihm die Installation zu erleichtern, möchten wir in diesem Beitrag vor allem den Programmierern eine Stütze bieten. Aber auch der Anwender kann von dem hier Dargebotenen ein wenig profitieren. Allzu oft sind Probleme mit Anwendungen besser zu beschreiben, wenn man die internen Zusammenhänge ein wenig überschaut und Problembereiche enger fassen kann.

Damit hilft man den Programmierern (und indirekt natürlich auch sich selbst), Fehler in bestehenden Programmen auszumerzen.

Bei dem in der letzten Ausgabe angesprochenen Problem der doppelten Zeichensatzkennung von Raster- und Vektor-Fonts zeichnet sich am Horizont eine Lösung ab. Es ist wohl wahrscheinlich, daß man die IDs der Vektorzeichensätze durch Addition einer Konstanten in einen Bereich verlegt, der normalerweise noch nie durch Rasterzeichensätze belegt war. Wir empfehlen daher, bis zur Lösung der Problematik entweder Pixel-Zeichensätze oder Vektorzeichensätze zu benutzen.

User’s Freud und Programmierers Leid

Die vielseitigen neuen Möglichkeiten, die sich durch den Einsatz der SpeedoGDOS -Erweiterung für den Benutzer ergeben, bedeuten für den engagierten Programmierer aber auch eine Menge Arbeit, denn es sind einige neue VDI-Funktionen ins System eingefügt worden. Leider existiert im Moment noch keine offiziell verfügbare und vor allem verbindliche Dokumentation zu SpeedoGDOS. Seit der ersten Auslieferung haben sich doch einige Probleme gezeigt, die natürlich auch in der Dokumentation noch Eingang finden müssen. Dennoch wollen wir Ihnen die neuen Funktionen von SpeedoGDOS näher bringen. damit nicht durch munteres Rätselraten falsche Gerüchte über Funktionen aufkommen. Sie finden dazu eine nüchterne Auflistung in den nebenstehenden Kästen und im Text eine tiefergehende Beschreibung der Vorgänge. Die im Artikel benannten Funktionsaufrufe sind in dieser Form auch in der aktuellen Pure-C-Library zu finden. In den Bindings finden Sie drei Funktionen, auf die wir im Text nicht weiter eingehen wollen: vqt_advance(), vst_arbpt() und vst_setsize(). Diese Funktionen sind im wesentlichen aus Kompatibilitätsgründen zum FSMGDOS vorhanden, werden aber unter Speedo durch vqt_advance32(), vst_arbpt32() und vst_setsize32() abgelöst, da diese einen neuen Datentyp unterstützen (s. Schweizer Präzision).

Bevor Sie uns in die Höhle des SpeedoGDOS folgen, rufen Sie sich bitte Ihr Wissen über GDOS-Systeme in Erinnerung (vgl. Heft 7/1993). damit Sie die Unterschiede zw ischen SpeedoGDOS und normalem GDOS erkennen.

,Negative‘ Neigung(en)
,Positive‘ Neigung
Zu starke Neigung

Schweizer Präzision

Bevor es mit dem Programmieren so richtig losgeht, müssen wir noch etw as für die Grundlagen tun. Wer schon unter dem alten GDOS programmiert hat, stellte sicher schon fest, daß die Genauigkeit, mit der das GDOS arbeitet, nicht ausreicht, um auf modernen Ausgabesystemen wie 300-(600,1200)-dpi-Lasern optimale Ausgaben zu ermöglichen. Diesem Umstand hat ATARI jetzt Rechnung getragen, indem ein neuer Datentyp eingeführt wurde. Dieser Datentyp, sein Name ist fix31, stellt vorzeichenbehaftete 32-Bit-Zahlen in einer Fixkommadarstellung bereit. Dabei ist das oberste Bit das Vorzeichen, während die unteren 31 Bit den eigentlichen Wert tragen. Die neue Darstellung ist für alle Funktionen relevant, die mit metrischen Informationen arbeiten, und reicht in der Genauigkeit bis auf 1/65536 pt (lpt = 1/72 inch ~= 0.35mm) hinab. Führen Sie sich bitte folgende Beispiele in fix31-Notation vor Augen:

0x00010000 = 1,0 pt
0xFFFF0000 = -1,0 pt
0x00018000 = 1,5 pt

Diese genaue Positionierung hat nicht nur für das Setzen der Schriftgröße eine wichtige Bedeutung, sondern ermöglicht im Zusammenhang mit neu eingeführten Ker-ning-Fähigkeiten eine sehr genaue Positionierung über verschiedene Geräteauflösungen hinweg. Wir werden später noch einmal darauf eingehen.

Take-off

Damit Sie nicht gleich bei den ersten Flugversuchen auf der Nase landen, gehen wir bei der Entwicklung einer Applikation Schritt für Schritt vor (frei nach dem Motto: ,Hand in Hand ins Datenland’). Den Beginn Ihrer Applikation leiten wie immer die beiden zentralen Funktionen appl_init() und v_openvwk() ein (vgl. Beispielcode). Der Ergebnisparameter der Funktion v_openvwk() stellt das VDI-Handle Ihrer (virtuellen) Arbeitsstation dar. Über dieses Handle werden wir dann auf die Funktionen des GDOS bzw. Speedo zugreifen. Wie wir später noch sehen werden, müssen wir neben dem virtuellen Handle für die Bildschirmausgabe auch physikalische Handles für den/die Drucker verwalten.

„Halt! Parole! Wer da...?“

Die erste wichtige Frage, die sich bei der Programmierung stellt, ist die, unter welcher Systemumgebung das Programm zur Arbeit gerufen wird. Es gibt dabei eine alte und eine neue Lesart.

Die erste ist einfach, aber auch ein wenig ungenau. Bei den meisten Bibliotheken zu C-Compilern findet sich die Funktion vq_gdos(), deren Rückgabewerte erst einmal die generelle Existenz einer GDOS-Erweiterung signalisieren können. Sie kennt nur die Zustände an oder aus. In den Pure-C-Libraries existiert aber auch ein neuer Funktionsaufruf namens vq_vgdos(). Damit läßt sich schon etwas mehr über das System aussagen. Derzeit liefert die Funktion vier Rückgabewerte:

   
-2 Kein GDOS aktiv
0x5F464E54 (_FNT) FontGDOS
0X5F46534D (_FSM) Font Scaling Mechanism
0x???????? Ein anderes GDOS

Da Speedo ein frei skalierbares Schriftsystem bietet, liefert die Funktion hier auch korrekterweise _FSM. Damit sind Sie allerdings noch nicht auf der sicheren Seite, denn auch das ,alte‘ FSMGDOS liefert hier diese Kennung. Auch wenn Speedo abwärtskompatibel zum FSMGDOS ist, kann ein Aufruf der neuen Funktionen mit falschen Parametern unliebsame Effekte nach sich ziehen. Eine genauere Spezifikation wird aber auf diesem Weg nicht möglich sein, daher verweisen wir dringend auf nachfolgende Möglichkeit.

Die empfohlene und auch unterstützte Erkennung läuft unter Speedo über den Cookie-Jar (vgl. Profibuch) ab. In der Boot-Phase legt Speedo hier einen Cookie namens FSMC an. Der dazugehörige 4 Byte lange Wert zeigt auf einen 4 Byte langen, nicht ,0‘-terminierten String, der die eingesetzte Vektorschrifterweiterung genau identifiziert. Speedo gibt sich mit der Zeichenkette SPD zu erkennen. Die als Listing angegebene Funktion _speedo_active() beschreitet genau den obigen Weg. Sie sollten diese Funktion nur einmal zu Beginn Ihrer Applikation aufrufen und sich den Rückgabewert merken. Die Unterfunktion search_cookie() wird nämlich im Supervisor-Modus ausgeführt und sperrt unter Multitasking-Systemen den Task-Wechsel. Auch wenn die Funktion kurz ist und auch schnell ausgeführt wird, sollte man aus Prinzip möglichst selten den Taskswitch unterdrücken.

Bevor wir uns den Ausgabefunktionen widmen können, müssen unter Speedo noch ein paar Einstellungen getroffen werden, die einen erfolgreichen Lauf Ihrer Programme sichern sollen.

Irren ist menschlich oder... Computer machen auch Fehler

Obwohl man bemüht war, bei der Entwicklung von SpeedoGDOS ein gewisses Maß an Sorgfalt an den Tag zu legen, gibt es auch unter Speedo ein paar kritische Situationen, die vor allem auf Speichermangel zurückzuführen sind. So produzierte Fehler landen unter Speedo normalerweise direkt auf dem Schirm, allerdings ist diese Form der Fehlermeldung natürlich nicht eben zeitgemäß. Damit dieses Verhalten nicht den Ablauf Ihres Programmes stört, kann man unter Speedo die Fehlermeldung in eine Variable umleiten, um Sie dann z.B. in einer Alarmbox dem User näherzubringen. Der Funktionsprototyp dazu sieht wie folgt aus:

void vst_error
    (int handle, int mode, int *errorvar)

Handle bezeichnet das VDI-Handle, also aus unserem Beispiel die Variable Screen-VHondle. Mit mode beschreiben Sie, ob die Fehlermeldungen auf den Bildschirm (mode = 1) ausgegeben oder in der übergebenen Fehlervariablen (mode = 0) gespeichert werden sollen. Die Fehlervariable wird unter errorvar an die Funktion durchgereicht und sollte mit 0 initialisiert sein. ATARI empfiehlt, nach jedem aufgetretenen Fehler diese Funktion erneut aufzurufen und den Wert von errorvar auf 0 zurückzusetzen. Eine Liste mit den von der Funktion gelieferten Errorcodes ist leider im Moment noch nicht verfügbar, wird aber - sobald vorhanden - nachgereicht.

Boah ey, metallic oder was?

Auch bei den Texteffekten hat sich durch die Einführung der Vektorschriften einiges getan. Das alte Schriftensystem erzeugte mit Hilfe der im Zeichensatz angegebenen Masken auf Pixel-Ebene in einem speziellen Puffer (dem ,Scratch Buffer') die benötigten Zeichen (vgl. vst_effects()). Dieses Verfahren kann aber nur eine Behelfsmaßnahme sein, da nicht alle Zeichen bei einer schematischen Berechnung ein akzeptables Schriftbild liefern, - mal ganz abgesehen von der Tatsache, daß sich dadurch die Zeichensatzinformation verändert, weil Zeichen schmaler oder breiter werden können. Wie schon im vorangegangenen Artikel beschrieben, gehen professionelle Schriftanbieter daher auch den Weg, jeden Texteffekt (sog. Schnitte) als einen getrennten Zeichensatz anzubieten, so auch Bitstream mit den Speedo-Schriften. Nun muß aber ATARI, um kompatibel mit alten Anwendungen zu bleiben, auch für die Vektorzeichensätze die Texteffekte zulassen. Problem dabei ist die Größe des benötigten Scratch-Buffers. Werden nur Pixel-Schriften eingesetzt, so läßt sich schon beim Laden einfach feststellen, wie groß der Puffer sein muß, um auch das größte Zeichen in allen Effekten zu fassen. Bei Vektorschriften, die in ihrer Größe dynamisch sind, ist aber diese Festlegung nicht so einfach möglich und daher von dem System nur näherungsweise machbar.

Eine moderne Applikation sollte auf diese Problematik eingehen, indem sie bei Vektorschriften das Setzen der Texteffekte nicht zuläßt. In Ergänzung dazu stellt die Funktion vst_scratch() Möglichkeiten zur Verfügung, das Anlegen des Scratch-Buffers zu kontrollieren.

Sie sollten also in Ihrer Applikation nach Möglichkeit den Puffer unter Modus 1 anlegen lassen und für Vektor-Fonts keine Effekte zulassen. Evtl. können Sie in Ihrem Programm ganz auf Pixel-Zeichensätze verzichten, dann können Sie den Puffer auch komplett abschalten.

Zeigt her Eure Zeichen

Nachdem diese grundsätzlichen Einstellungen geklärt sind, können wir uns endlich den Vektorschriften selber zu wenden.

Wie im ursprünglichen GDOS-System die Pixel-Schriften, werden auch die Vektorzeichensätze unter Speedo mittels der Funktion vst_load_fonts() der Applikation zugänglich gemacht. Die Funktion liefert die Anzahl der (neu-)geladenen Zeichensätze. Zusammen mit der in workout[10] bei v_openwk() (oder v_openvwk()) zurückgelieferten Zahl ergibt sich die Gesamtzahl aller verfügbaren Zeichensätze für das entsprechende Ausgabegerät. Für alle so geladenen Zeichensätze ruft man anschließend die Funktion vqt_name() auf, denn diese liefert neben dem Namen des Zeichensatzes auch die FontID, die man braucht, um später auf diesen Zeichensatz zugreifen zu können. Daneben teilt sie aber auch noch mit, ob es sich bei dem Zeichensatz um einen Vektorzeichensatz handelt. Die in name zurückgelieferten Werte tragen in den ersten 32 Bytes den Namen (auch Typeface genannt) und im 33. Byte ein Flag, daß im gesetzten Zustand (name[33] == 1) einen Vektor-Font signalisiert. An dieser Stelle sei nochmals darauf verwiesen, daß das Wegkopieren mit strcpy() unter Speedo zu Abstürzen führt, wenn Vektor-Fonts geladen sind. Kopieren Sie daher das Typeface immer mit strncpy(...,32) in Ihre Variablen, und setzen Sie anschließend das 33. Byte auf ,0‘. Wie Sie die so ermittelten Fonts verwalten, bleibt letztlich Ihre Sache, doch bietet sich hier eine einfach (oder zweifach) verkettete Liste an, so daß man flexibel bei den zu erwartenden Datenmengen ist. Vielleicht können Sie sich folgendem Vorschlag anschließen:

#define GDOS_BITMAPFONT 0 
#define GDOS_VECTORFONT 1 
#define GDOS_TYPEFACE_LEN 32

typedef struct _font 
{
    struct _font *next,*prev; 
    int type; 
    int id;
    char typeface
        [GDOS_TYPEFACE_LEN+1];
}FONT;

typedef FONT* FONTLIST;

Nachdem Sie nun auf die Zeichensätze zugreifen können, wollen wir jetzt die Ermittlung der Zeichenhöhen angehen. Kümmern wir uns zuerst einmal um die Bitmapfonts, die mit Hilfe der o.a. Struktur leicht identifiziert werden können.

Input, ich brauche mehr Input

Im allgemeinen reicht es für eine Applikation völlig aus, die vom SpeedoGDOS gelieferten Informationen über einen Zeichensatz auszuwerten. Sollten Sie jedoch einmal mehr über einen Font wissen wollen, bemühen Sie am besten vqt_fontheader(). Diese Funktion speichert in einem von Ihnen übergebenen (mind. 421 Byte großen) Puffer alle Informationen, die über den Zeichensatz nach außen gereicht werden können. Der Inhalt des Puffers ist nach dem Aufruf der Funkion identisch mit den 421 Bytes am Anfang der Font-Datei. Den genauen Aufbau können wir aus Platzgründen leider nicht veröffentlichen, er wird sich jedoch auf der Monatsdiskette dieses Heftes befinden.

Wahre Größe

Erschreckenderweise bietet das GDOS keine Funktion an, die die Größenliste zu einem geladenen Zeichensatz liefert. Daher müssen wir die Funktion vst_point() entfremden, um an die Größen heranzukommen, denn Sie liefert immer die Größe zurück, die tatsächlich gesetzt werden konnte (die angeforderte oder die nächstkleinere Größe). Also geeigneten Startwert (2835 = lm hoher Buchstabe) reinstecken und Funktionsergebnis anschauen. Solange dies kleiner oder gleich dem hineingesteckten Wert ist, ist das Funktionsergebnis eine korrekte Größe. Die Ermittlung des nächsten Startwerts ist einfach. Er entspricht der letzten gesetzten Größe -1. Irgendwann ist dann der gewünschte Wert kleiner als das Funktionsergebnis, und man hat alle Größen für diesen Zeichensatz ermittelt. Eine unrühmliche Eigenschaft des vst_point() sei noch angesprochen. Leider liefert die Funktion auch für jede tatsächlich existierende Zeichensatzgröße eine (genau doppelt hohe) Vergrößerung. Diese läßt sich nicht von den realen Größen unterscheiden, ist jedoch aufgrund der Pixel-Vergrößerung (bei Bitmapfonts) nicht schön anzusehen.

int NewSize, OldSize;
NewSize = OldSize = 2836;
while(NewSize <= OldSize && NewSize > -1)
{
    Oldsize = NewSize-1;
    NewSize=vst_point(handle,OldSize,&chw,&chh,&cew,&ceh);
}

Bei den Vektorzeichensätzen kann man natürlich dieselbe Funktion benutzen, doch wird man hier nur die Punktgrößen erhalten, die in der EXTEND.SYS (POINTS =) eingetragen wurden. Darauf hat ihr Programm natürlich nur sehr geringen Einfluß, da diese Eintragungen vom User getätigt werden müssen. Daher schlage ich folgendes Verfahren vor. Legen Sie sich auch für Vektor-Fonts eine Größenliste an. Tragen Sie dort gleich zu Beginn ein paar Standardwerte ein, die für Ihre Applikation sinnvoll erscheinen (z.B. 6.8,9,10, 12, 14, 18, 20, 24, 28, 36, 48, 60, 72). Rufen Sie dann per vst_point() die in der EXTEND.SYS eingetragenen Größen ab und tragen Sie diese zusätzlich in die Liste ein (achten Sie dabei auf doppelte Einträge!). Wenn Sie dann auch noch auf Bedarf eine freie Größeneinstellung erlauben, kommen Sie den Bedürfnissen der Benutzer sicherlich entgegen.

Nicht alle Ausgaben kann man absetzen

Die angesammelten Daten wollen wir jetzt aber endlich nutzen, um Ausgaben zu machen. Der erste Aufruf gilt natürlich dem Setzen des zu benutzenden Fonts. Hier gibt es noch keine Unterschiede zwischen den verschiedenen Schriftarten, denn beide werden mit vst_font(handle,id) gesetzt. Im nächsten Schritt geht es an das Setzen der Punktgröße. Ist für die Pixel-Schriften nach wie vor die Funktion vst_point() (bzw. vst_height()) zuständig, so übernimmt für Speedo-Schriften vst_arbpt32() diese Aufgabe. Damit lassen sich neben den per vst_point() ermittelten Schriften auch freie Größen setzen (z.B. die Standardwerte aus der von uns vorgegebenen Liste). Hier treffen wir auch zum ersten Mal auf die Anwendung des fix31-Datentyps, der neben den ganzen Punktgrößen auch solche mit Nachkommastellen erlaubt.

Gegenüber den alten Schriftsätzen hat man unter Speedo mit Vektorzeichensätzen auch die Möglichkeit, die Schriftbreite zu setzen. Ein Aufruf von vst_setsize() mit der gewünschten Zeichenbreite verändert die Zeichenbreite solange, bis ein Aufruf von vst_point(), vst_height(), vst_arbpt() oder vst_arbpt32() abgesetzt wird. Natürlich wird das bei extremen Verbreiterungen kein schönes Schriftbild mehr liefern, hier sollte man eher auf einen geeigneten Schriftschnitt ausweichen.

Die eigentliche Textausgabe kann wie bislang mit v_gtext() vorgenommen werden, besser aber ist die Benutzung von v_ftext() oder v_ftext_offset(). Die Vorteile der neuen Funktionen liegen vor allem in der exakteren Positionierbarkeit der Zeichen durch das System. Im Falle von v_ftext_offset() kann der Programmierer noch manuell in die Zeichenplazierung eingreifen, indem er ein offset-array angibt, das die Plazierung der jeweils nächsten Zeichen bestimmt.

Wollen Sie bei der Textausgabe mit einem Cursor arbeiten, sollten Sie sich ebenfalls mit den Funktionen vqt_advance32() und v_f_extent() vertraut machen. Auf Zeichenebene hilft Ihnen vqt_advance(), die Position des nächsten Zeichens zu finden. Dazu liefert die Funktion für ein übergebenes Zeichen die Positionsänderung in x- und y-Richtung, um das darauf folgende Zeichen korrekt plazieren zu können. Beachtet werden dabei auch Rotationen, die nicht ein Vielfaches von 90° bilden. Um die Ausmaße eines ganzen Strings zu erfragen, sollte man sich v_f_extent() bedienen. Ergebnis sind die Breite und die Höhe des übergebenen Strings inklusive der Positionierung mittels Track- und Pair-Kerning.

ATARIs „Echte Kernige”

Jetzt wurde schon so oft vom Kerning gesprochen, und wir haben noch keine einzige Funktion kennengelernt, die sich damit beschäftigt. Das wollen wir nun nachholen. Zentraler Punkt des Geschehens ist vst_kern(), mit dessen Hilfe sowohl das Track- als auch das Pair-Kerning eingestellt werden können. Pair-Kerning ist, wie der Name schon andeutet, ein Kerning, das paarweise organisiert ist. Das bedeutet, daß eine Tabelle existiert, in der zu jedem Buchstabenpaar ein Kerning-Wert eingetragen werden kann. Natürlich wird hier niemand alle möglichen Kombinationen eintragen, denn bei 32768 möglichen Zeichen wäre die Tabelle riesengroß. Statt dessen beschränkt man sich in der Praxis auf die interessanten Fälle, bei denen das Benutzen eines Standardabstandes keine akzeptablen Ergebnisse liefert (z.B. ’W’, ’P’ etc).

Das ebenfalls verfügbare Track-Kerning stellt dagegen nur eine allgemeine Abstandsregelung dar. Es kann in drei Stufen eingestellt werden, wobei eine Kombination mit Pair-Kerning ebenfalls erlaubt ist. Die Rückgabeergebnisse der Funktion kann man als interessant bezeichnen. Entweder erhält man den gesetzten Modus des Track-Kernings oder, wenn das Pair-Kerning eingeschaltet wird, die Anzahl der für den Zeichensatz verfügbaren Abstandspaare.

Manchmal ist es von Interesse, die Kerning-Informationen direkt erfragen zu können. SpeedoGDOS wartet hier mit der Funktion vqt_trackkern() auf, die die x- und y-Distanz zwischen zwei Buchstaben berechnet bzw. zurückgibt. Auch für das Erfragen des Pair-Kernings hat man eine Schnittstelle vorgesehen. Die Funktion vqt_pairkern() liefert für die beiden übergebenen Zeichen den dazwischenliegenden Abstand.

Effekthascherei

Wie schon in einem der vorstehenden Abschnitte erwähnt, sollte man unter Spee-do weitgehend auf die Anwendung von Texteffekten verzichten. Als kleines Ersatzbonbon steht statt dessen vst_skew() zur Verfügung, das zur Schrägstellung eines Zeichens dient. Es sind dabei Neigungswinkel von -90° (stark linksgeneigt) bis +90° (extrem rechtslastig) zugelassen. Die Funktion ist kein echter Ersatz für einen eigenen Italic-Schnitt des betreffenden Zeichensatzes, sie liefert jedoch im nahen Bereich um 0° sehr brauchbare Ergebnisse.

Mitesser

Leider kann Speedo nicht in allen Anwendungsfällen voll genutzt werden. Kritisch ist nach wievor die Ausgabe in sogenannte Offscreen-Bitmaps. Das heißt, die Ausgabe soll nicht direkt auf dem Bildschirm ,landen‘, sondern in einem von der Applikation angegebenen Speicherbereich. Es existiert zwar ein GDOS-Treiber, der eine solche Aufgabe übernehmen könnte (MEMORY.SYS), doch leider ist er noch nicht ganz fehlerfrei und arbeitet nur auf monochromen Bitmaps. Dieser Umstand ist gerade für die neuen Grafikprogramme sehr ärgerlich, und man mußte befürchten, daß sie in der Zukunft auch keine Speedo-Unterstützung bieten. Abhilfe findet man aber in der Funktion v_getbitmap_info(). Wie Sie den Bindings entnehmen können, liefert die Funktion unter anderem einen Zeiger auf die Pixel-Darstellung (**bitmap). Diese Pixel-Darstellung können Sie natürlich in eigene Speicherbereiche wegkopieren, damit können auch Nicht-GDOS-Applikationen von Speedo profitieren. Als Ergebnis der Funktion stehen ebenfalls die x- und y-Offsets zur Verfügung, die Ihnen unter GDOS vqt_advance32() liefert. Damit werden Sie in die Lage versetzt, die selbe genaue Positionierung von Zeichen durchzuführen, die auch Speedo bietet.

Soweit für diesmal. Wir werden noch einen kurzen dritten Teil folgen lassen, in dem wir ein paar Worte über die neuen Bézier-Möglichkeiten des Speedo verlieren wollen und auch die Möglichkeiten aufzeigen werden, die sich aus Kontrollfunktionen zum Cache-System ergeben.

Literatur:

[1] Jankowsky, Reschke, Rabisch: „ATARI Profibuch ST-STE-TT“, Sybex
[2] GDOS Addendum 2.1, ATARI Corporation, Copyright 1993 (Denis Fung)

Modifizierte VDI-Aufrufe unter Speedo

Inquire Face Name and Index (VD1130)

Die Funktion liefert nun einen zusätzlichen Rückgabewert. In intout[33] wird ein Flag zurückgegeben, das einen Vektor-Font odereinen Pixelfont signalisiert.

Prototyp:

int vqt_name( int handle, int element_num, char *name)

GEM-Arrays

contrl      = 130
contrl+2    = 0
contrl+6    = 1
contrl+12   = handle
intin       = element_num (Nummer, unter der der
              Font geladen wurde. Nicht seine FontID.)
contrl+4    = 0
contrl+8    = 34
intout      = index (Rückgabewert = FontID)
intout+2    = name
...
intout+64
intout+66   = flag (1 Vektor-Font, 0 Pixelfont)

Neue VDI-Aufrufe unter Speedo

Inquire Speedo header information (VDI232)

Kopiert die Informationen aus dem Fontheader des aktuell eingestellten Speedofonts in den übergebenen Puffer (gebraucht werden 421 Bytes) Außerdem liefert die Funktion den vollen Zugriffspfad auf die zugehörige TDF-Datei.

Prototyp:

void vqt_fontheader( int handle, char *buffer, char *pathname);

GEM-Arrays:

contrl      = 232
contrl+2    = 0
contrl+6    = 2
contrl+12   = handle
intin       = buffer (die oberen 2 Bytes der Adresse
              des Puffers)
intin+2     = buffer (die unteren 2 Bytes der Adresse des Puffers)
intout      = pathname
...
contrl(2)   = 0
contrl(4)   = Länge des Pfadnamens

inquire track kerning information (VDI 234)

Liefert den Korrekturfaktor für Zetchenabstände mit Track-Kerning.

Prototyp:

void vqt_trackkern(int handle, fix31 *x, fix31 *y);

GEM-Arrays:

contrl      = 234
contrl+2    = 0
contrl+12   = handle
contrl+8    = 4
intout
intout+2    = x (in fix31-Notation) 
intout+4
intout+6    = y (in fix31-Notation)

Inquire pair kerning information (VDI235)

Liefert den Korrekturfaktor fur Abstände der beiden übergebenen Zeichen mit Pair-Kerning Prototyp

void vqt_pairkern( int handle, int ch1, int ch2, fix31 *x fix31 *y):

GEM-Arrays:

contrl      = 235
contrl+2    = 0
contrl+6    = 2
contrl+12   = handle
intin       = ch1 (das 'linke' der beiden Zeichen)
intin+2     = ch2 (das 'rechte' der beiden Zeichen)
contrl+8    = 4
intout
intout+2    = x (in fix31 Notation) 
intout+4
intout+6    = y(mfix31 Notation)\end{verbatim}

Set character mapping mode (VDI 236)

Schaltet zwischen ATARI- und BIOS-(Bitstream)-Zeichensatzindizierung um.

Prototyp:

void vst_charmap( int handle, int mode);

GEM-Arrays:

contrl      = 236
contrl+2    = 0
contrl+6    = 1
contrl+12   = handle
intin       = mode (0 = ATARI ASCII; 1 = Bitstream;

Set kerning mode (VDI 237)

Setzen der verschiedenen Kerning-Modi unter Speedo

Prototyp

void vsl_kern( int handle, int tmode, int pmode, int *tracks, int *pairs)

GEM-Arrays:

contrl      = 237
contrl+2    = 0
contrl+6    = 2
contrl+12   = handle
intin       = tmode
              { 0 = Kein Kerning
                1 = Normales Kerning
                2 = Enges Kerning
                3 = Sehr enges Kerning}
intin+2     = pmode
              (0 = Pair-Kerning aus 
               1 = Pair-Kerning ein)
contrl+4    = 2
intout      = tracks (gesetzter Track-Kerning-Modus)
intout+2    = pairs (Anzahl der Kerning-Paare im Zeichensatz)

Get Character Bitmap Information (VDI239)

Liefert Angaben über ein einzelnes Vektorzeichen (x/y-Position für das darauffolgende Zeichen: x/y-Offset innerhalb der Pixel-Darstellung: Breite und Höhe der Pixel-Darstellung des Zeichens; Zeiger auf die Bitmap des Zeichens)

Prototyp:

void v_getbitmap_info( int handle, int ch, fix31 *advx, 
            fix31 *advy, fix31 *xoff, fix31 *yoff, 
            int *width, int *height, int **bitmap):

GEM-Arrays:

contrl      = 239
contrl+2    = 0
contrl+6    = 1
contrl+12   = handle
intin(0)    -- character

Output:

contrl+4    = 0
contrl+8    = 12
intout      = width (in Pixeln)
intout+2    = height (in Pixeln)
intout+4
intout+6    = advx (x-Distanz der nächsten Zeichenposition (fix31))
intout+8
intout+10   = advy (y-Distanz der nächsten Zeichenposition (fix31))
intout+12
intout+14   = xoff (Beginn des Zeichens innerhalb der Bitmap (fix31))
intout+16
intout+18   = yoff (Beginn des Zeichens mneihalb der Bitmap (fix31))
intout+20
intout+22   = Zeiger auf die Adresse der Pixel-Darstellung des Zeichens

Inquire outline font text extent (VDI 240)

Arbeitet wie vqt_extent(). Es werden jedoch Kerning-Werte beachtet

void vqt_f_extent( int handle, char *string, int *extent );

GEM-Arrays:

contrl      = 240
contrl+2    = 0
contrl+6    = Länge des übergebenen Strings
contrl+12   = handle
intin       = string (In der aktuellen Zeichensatzkodierung)
contrl+4    = 4
contrl+8    = 0
ptsout      = extent (vgl. vqt_extent())

Outline Font Text (VDI241)

Die Funktionsweise und der Aufruf gleichen exakt dem Aufruf von v_gtext() unter normalem GDOS. Die Einstellungen des Kernings werden hier mitbeachtet. Das zweite Funktions-Binding erlaubt es überdies, ein Feld mit 16Bit-Werten zu übergeben, die anstelle der vom System beiechneten Zeichen-Offsets benutzt werden sollen. Damit erhält man die absolute Kontrolle über das Setzen der Zeichen auf dem Ausgabegerät.

Prototyp:

void v_ftext( int handle int x, int y, char *string ); 
void v_ftext_offset( int handle, int x, int y, char *string, int *offset);

GEM-Arrays:

contrl      = 241
contrl+2    = 1 + Anzahl der Zeichen
contrl+6    = Länge des Strings
contrl+12   = handle

intin       = string (i. d. akt. Zeichensatzkodierung)

ptsin       = x
ptsin+2     = y
ptsin+4     = offset[0] (x-Offset des ersten Zeichens)
ptsin+6     = offset[1] (y-Offset des ersten Zeichens)
            .
            .
ptsin+2n    = offset[n-1] (x-Offset des ersten Zeichens)
ptsin+(2n+1)= offset[n] (y-Offset des ersten Zeichens)

contrl+4    = 0
contrl+8    = 0

handle      = contrl[6]
string      = intin
x           = ptsin[0]
y           = ptsin[1]

Set scratch buffer allocation mode (VDI 244)

Legt die Art fest, mit der der Scratch-Buffer angelegt werden soll.

Prototyp

void vst_scratch( int handle, int mode);

GEM-Arrays

contrl      = 244
contrl+2    = 0
contrl+6    = 1
contrl+12   = handle

intin(0)    = mode ( 0 = Scratch-Buffer für Pixel- und
              Vektorzeichensatze
              1 = Scratch-Buffer nur für Pixel-Zeichensätze
              2 = Kein Scratch-Buffer)

contrl+4    = 1
contrl+8    = 0

Set SpeedoGDOS error mode (VDI 245)

Setzt die Art der Fehlermeldungen unter Speedo.

Prototyp:

void vst_error( int handle, int mode, int *errorvar);

GEM-Arrays:

contrl      = 245
contrl+2    = 0
contrl+6    = 3
contrl+12   = handle

intin       = mode
            ( 0 = Der Fehler wird in der unter errorvar 
            spezifizierten Adresse abgelegt.
            1 = Die Fehlermeldungen werden auf den 
            Bildschirm ausgegeben)

intin+2
intin+4     = errorvar (Adresse der Fehlervariablen)

contrl+4    = 1
contrl+8    = 0

Set character cell height by arbitrary points (VDI246)

Setzt die Größe des aktuellen Zeichensatzes auf die in Point (pt) angegebene Größe. Zwei Varianten. Eine mit, die andere ohne fix31-Unterstützung.

Prototyp:

int vsl_arbpt( int handle, int point, int *chwd, int *chht, int *cellwd, int *cellht);
fix31 vst_arbpt32( int handle, fix31 point, int *chwd, int *chht, int *cellwd, int *cellht)

GEM-Arrays:

contrl      = 246
contrl+2    = 0
contrl+6    = 1 = Angaben in Integer-Notation
              2 = Angaben in fix31-Notation
contrl+12   = handle

intin       = point (Integer-Notation)
intin
intin+2     = point (fix31 -Notation.)

contrl+4    = 2
contrl+8    = 1

intout      = Gesetzte Größe (Integer-Notation)
intout
intout+2    = Gesetzte Größe (fix31-Notation)

ptsout(0)   = chwd (Zeichenbreite) 
ptsout(1)   = chht (Zeichenhöhe)
ptsout(2)   = cellwd (Zeichenzellenbreite) 
ptsout(3)   = cellht (Zeichenzellenhöhe)

Inquire outline font text advance placement vector (VDI 247)

Die Funktion liefert die x- und y-Offsets für das nächste Zeichen zurück, so daß man den Cursor auf die richtige Position setzen kann. Vor allem dann interessant, wenn der Textrotationswinkel verschieden von 0, 90, 180 und 270° ist. Zwei Varianten. Eine mit, die andere ohne fix31-Unterstützung

Prototyp:

void vqt_advance( int handle, int ch, int *advx, int *advy, int *remx, int *remy);
void vqt_advance32( int handle, int ch, fix31 *advx, fix31 *advy);

GEM-Arrays:

contrl      = 247
contrl+2    = 0
contrl+6    = 1
contrl+12   = handle

intin       = ch (das nächste Zeichen)

contrl+4    = 4
contrl+8    = 0

ptsout      = advx (Integer-Notation)
ptsout+2    = advy (Integer-Notation)
ptsout+4    = remx (mod 16384) (Integer-Notation)
ptsout+6    = remy (mod 16384) (Integer-Notation) 
ptsout+8
ptsout+10   = advx (fix31-Notation) 
ptsout+12
ptsout+14   = advy (fix31-Notation)

Inquire device status information (VDI 248)

Liefert den Namen und die Verfügbarkeit der angesprochenen Ausgabeeinheit.

Prototyp:

void vqt_devinfo( int handle, int devnum, int *devexits, char *devstr);

GEM-Arrays:

contrl      = 248
contrl+2    = 0
contrl+6    = 1
contrl+12   = handle

intin       = devnum (Treibernummer in der Assign.sys)

contrl+4    = 1
contrl+8    = Lönge des Treibernamens

intout
intout+2
...         = devstr (Der Treibername)

ptsout      = devexists
              (1 = Treiber installiert 
              0  = Treiber nicht installiert)

Set character cell width by arbitrary points (VDI 252)

Setzt die Zeichenzellenbreite. Ein Aufruf von vst_point(), vst_arbpt() oder vst_height() nimmt die Einstellungen von vst_setsize() zurück. Zwei Varianten. Eine mit, die andere ohne fix31-Unterstützung.

Prototyp

int vst_setsize( int handle, int point, int *chwd, int *chht, int *cellwd, int *cellht);
fix31 vst_setsize32( int handle, fix31 point, int *chwd, int *chht, int *cellwd, int *cellht);

GEM-Arrays:

contrl      = 252
contrl+2    = 0
contrl+6    = 1 = Angaben in Integer-Notation
              2 = Angaben in fix31-Notation
contrl+12   = handle

intin       = point (Zellenbreite in Points (pt) (Integer-Notation))

oder

intin
intin+2     = point (Zellenbreite in Points (pt) (fix31-Notation))

contrl+4    = 2
contrl+8    = 1 = Angaben in Integer-Notation
              2 = Angaben in fix31-Notation

ptsout      = chwd (Zeichenbreite)
ptsout+2    = chht (Zeichenhöhe)
ptsout+4    = cellwd (Zeichenzellenbreite)
ptsout+6    = cellht (Zeichenzellenhöhe)

Set outline font skew (VOI253)

Schrägstellen von Vektorzeichen. Die Schrägstellung kann von -90 bis +90° reichen und wird in 1/10° (-900 ... +900) angegeben. Negative Werte lassen die Buchstaben nach links, positive nach rechts 'kippen'. (Je näher die Werte an 90° liegen, desto verzerrter und unleserlicher wird die Darstellung.)

Prototyp:

int vst_skew( int handle, int skew)

GEM-Arrays:

contrl      = 253
contrl+2    = 0
contrl+6    = 1
contrl+12   = handle

intin       = skew (Die Neigung in 1/10 )
intout      = Die eingestellte Neigung

#define COOKIE_PTR 0x5A0L #define FALSE 0 #define TRUE 1 typedef struct { char magic[4]; long value; } COOKIE_ENTRY ; /*----------------------------------------------* Name search_ cookie Beschreibung Sucht den durch 'magic' spe- zifizierten Cookie und liefert einen Zeiger auf den Cookie Parameter *magic Name des Cookies Ergebnis Zeiger auf den Cookie *-----------------------------------------------*/ COOKIE_ENTRY *search_cookie(char *magic) { long save _sp; COOKIE_ENTRY *ptr; save_sp = (long)Super(0L); ptr = *(COOKIE_ENTRY**)COOKIE_PTR; if(ptr != NULL) { while( strncmp((char*)ptr,magic,4) && ptr != NULL) ptr++; } Super((char*)save_sp); return(ptr); } /*----------------------------------------------* Name speedo_active Beschreibung Prüft ob Speedo-GDOS aktiv ist Ergebnis 0 (FALSE) Speedo nicht aktiv 1 (TRUE) Speedo aktiv *-----------------------------------------------*/ int speedo_active(void) { COOKIE_ENTRY *cookie; int ret_val = FALSE; if({cookie = search cookie("FSMC")) != NULL) { if( strncmp((char *) cookie->value,"_SPD",4) == 0) { ret_val = TRUE; } } return ret_val; } /**************************** * Start der Applikation * ****************************/ int ApplicationID, ScreenVHandle, CharW,CharH,CellW,CellH; int WorkIn[128] = {1,1,1,1,1,1,1,1,1,1,2}, WorkOut[57]; int SPEEDO; /**************************************** * Zuerst das Programm bei AES anmelden * ****************************************/ int main() { if ((ApplicationID = appl_init())>=0) { /************************************ * Virtuelle Arbeitsstation für den * * Bildschirm beim VDI anfordern * ************************************/ WorkIn[0] = ScreenVHandle = graf_handle(&CharW,&CharH,&CellW,&CellH); v_opnvwk(WorkIn,&ScreenVHandle,WorkOut); if( ScreenVHandle != 0 ) { SPEEDO = speedo_active(); /* ... hier sollte das eigentliche */ /* Programm stehen */ v_clsvwk(ScreenVHandle); } /********************************** * Und auch beim AES melden wir * * uns wieder ordentlich ab * **********************************/ appl_exit(); } return 0 ; }

Das Listing enthält das Grundgerüst eines Programmes, das SPEEDO-GDOS nutzen kann.


Erik Dick
Links

Copyright-Bestimmungen: siehe Über diese Seite
Classic Computer Magazines
[ Join Now | Ring Hub | Random | << Prev | Next >> ]