Für viele ist die Ausgabe auf Drucker, Metadateien und andere Geräte unter GDOS immer noch ein »Buch mit sieben Siegeln«. Wir klären auf.
Kaum ist Eric Smith in Sunnyvale an die Arbeit gegangen, sind auch schon die ersten positiven Auswirkungen in Form von neuen »MiNT«-, »AES«- und »SpeedoGDOS«-Betaversionen zu spüren. Es sieht sogar so aus, als sei Atari ernsthaft entschlossen, bis zur CeBIT alle diese Projekte »serienreif« zu machen (soviel zu meinen pessimistischen Betrachtungen vor zwei Monaten [1]).
Diesen Monat wende ich mich einem Betriebssystemteil zu, der (trotz einiger positiver Ausnahmen) von den Programmierern leider immer noch recht stiefmütterlich genutzt wird: der Grafikausgabe per GDOS auf Drucker, in Metafiles und auf andere Geräte. Diese Vernachlässigung ist natürlich nicht ganz grundlos, wobei zuerst wohl fehlende bzw. unübersichtliche Dokumentation, unklare Lizenzregelungen und mühsame Installation genannt werden müssen. Zumindest des ersten Kritikpunkts will ich mich diesen Monat annehmen (siehe auch [2]).
Ich möchte mit einer vereinfachenden Feststellung beginnen: Jedes Programm, das in der Lage ist, mittels VDIFunktionen auf dem Bildschirm auszugeben, kann auch mit nur geringem Mehraufwand per GDOS auf Drucker oder andere GDOS-Geräte ausgeben. Das liegt ganz einfach daran, daß die VDI-Funktionen von Anfang an geräteunabhängig konzipiert waren und die Ausgabe auf den Bildschirm über den im ROM eingebauten Bildschirmtreiber eben nur ein Spezialfall ist.
So einfach ist es leider nicht: Das VDI-Ausgabesystem trägt durchaus der Tatsache Rechnung, daß nicht jeder Gerätetyp jede Eigenschaft haben kann. Bildschirmtreiber enthalten beispielsweise auch Funktionen zur Eingabe von Tastatur und Maus (die normalerweise nur vom AES benutzt werden dürfen). Andere Geräte, beispielsweise Plotter, können überhaupt keine Raster benutzen und arbeiten per Definitionen immer im »Transparent«-Modus.
Programme, die per VDI auf anderen Geräten als dem Bildschirm ausgeben wollen, müssen also darauf vorbereitet sein, daß einige vertraute VDI-Aufrufe nicht unterstützt werden. Leider ist das besonders bei den Treibern für »pixelorientierte« Drucker (Laserdrucker, Nadeldrucker, Tintenstrahldrucker etc.) der Fall: Die Rasterfunktionen werden im allgemeinen nicht unterstützt, was dazu führt, daß die Ausgabe von Rastergrafiken schwierig (bis unmöglich) ist. Bei den meisten Treibern kann man sich mit einem kleinen Trick behelfen mehr dazu später.
Der Schlüssel zur GDOSAusgabe ist die VDI-Funktion »v_opnwk()«, mit der man eine Workstation öffnet. Genau das tut auch das AES beim Systemstart, um die Bildschirmworkstation zu initialisieren. GEM-Programme, die Bildschirm-Workstations benötigen, müssen daher »virtuelle« Workstations öffnen (dazu muß man per »graf_handle()« die Nummer der vom AES benutzten Workstation erfragen). Jedem Ausgabegerät ist eine spezielle Gerätenummer zugeordnet (das sind genau die Nummern, die in der ASSIGN.SYS-Datei neben den Treibernamen auftauchen). Diese Nummern sind nicht mit dem Handle identisch, über das man die VDI-Aufrufe tätigt!
Gerätenummern zwischen 1 und 60 sind schon für bestimmte Ausgabegeräte reserviert (1 bis 10: Bildschirm in verschiedenen Grafikmodi, 11 bis 20: Plotter, 21 bis 30: Drucker, 31 bis 40: Metafiles, 41 bis 50: Diabelichter bzw. Kamera, 51 bis 60: Grafiktabletts). Die Frage, welche Gerätenummern man unterstützen sollte, ist schwer zu beantworten.
Wer bereit ist, mehr Aufwand zu treiben, öffnet einfach nacheinander alle in Frage kommenden Gerätenummern testweise (also ab 11 aufwärts). Das kann natürlich recht lange dauern, eine Beschränkung auf die ersten 100 Gerätenummern ist sicherlich vertretbar. Die gefundenen Geräte kann man dann beispielsweise in einer Liste zur Auswahl anbieten (s. Abb. 1).
In künftigen GDOS-Versionen von Atari wird man zu einem aktiven Gerätetreiber zumindest den Treibernamen erfragen können (wie etwa »SLM.SYS«. Ein vernünftiger Gerätename (wie »Atari SLM804/605«) wäre allerdings nützlicher. Vielleicht ringen sich die Programmierer zu ein bißchen mehr Komfort durch. Auch eine Funktion, mit der man Informationen über ein Ausgabegerät erfragen kann, ohne es erst öffnen zu müssen, wäre in diesem Zusammenhang sicherlich sehr gut.
Wer es sich einfacher machen will, sollte zumindest zwei Workstations für Drucker anbieten (zum Beispiel durch einen Schalter »Zweiter Drucker« wie in »„Xact«). Damit kann man immerhin noch zwischen den GDOS-Geräten 21 und 22 auswählen (zum Beispiel bei einem Laserdrucker und einen Tintenstrahldrucker). Programm und Benutzerführung werden dadurch nur minimal komplizierter.
Zusätzlich sollte man nach Möglichkeit auch die Ausgabe in Metadateien (also auf GDOS-Gerät 31) vorsehen. Damit kann der Anwender die Grafiken in Vektorgrafikprogrammen wie »EasyDraw« oder »XactDraw« weiterbearbeiten. Ein schönes Beispiel ist das Mathematiksystem »Riemann II«, das beispielsweise 3-D-Flächengrafiken auch als Metadatei speichern kann. Allerdings sind bei der Ausgabe in Metadateien einige zusätzliche Eigenheiten zu berücksichtigen; dazu später.Weitere GDOS-Treiber: Die Firma »GST« legte schon dem „Timeworks Publisher« einen Postscript-Treiber bei. Damit kann man ganz einfach mit VDI-Befehlen Postscript-Dateien erzeugen. Schlechter sieht es mit Plottertreibern und Treibern für Farbdrucker aus (an letzteren arbeitet Atari nach eigener Auskunft). Relativ neu sind Treiber, die in Rasterdateien drucken. Ein Beispiel ist mein Treiber »img0300.sys«, der monochrome IMG-Dateien mit 300 dpi anlegt. Damit kann jedes Programm, das GDOSAusgabe erlaubt, auch direkt in Rasterbilder mit Laserauflösung drucken. Das ist vor allem dann praktisch, wenn ein Programm nur Rasterbilder, aber keine Vektorgrafiken einlesen kann (als Beispiel seien einige TeX-Implementationen auf dem Atari genannt). Der Treiber ist (bei nichtgewerblicher Nutzung) frei kopierbar; bei regelmäßiger Benutzung wird um eine Spende für zu einen gemeinnützigen Zweck gebeten. Die Firma SciLab liefert mit den aktuellen Versionen von »Xact« und »Xact Draw« ähnliche Treiber auch für andere Auflösungen.
Seit der Atari-Messe 92 gibt es einen GDOS-Treiber für die Faxsoftware »TeleOffice« von »TKR«. Damit können alle Programme, die per GDOS ausdrucken können, direkt Faxe ausgeben. Ein mitgeliefertes Autoordner-Programm »FaxRedirector« sorgt automatisch dafür, daß GDOS-Ausgaben für Gerät 21 entweder an den »normalen« Drucker oder an die Faxsoftware weitergeleitet werden (Bezugsquelle: Mailbox der Firma TKR). Jedes Programm, das per GDOS drucken kann, ist damit ohne Änderung zum Versenden von Faxen geeignet.
Von vielen Gerüchten umgeben ist Ataris »Memory-Treiber«, der seit einigen Jahren in Betaversionen durch die Programmiererszene geistert. Er wurde für ein (mittlerweile von der Bildfläche verschwundenes) DTP-Programm entwickelt und erlaubt die GDOS-Ausgabe in eine monochrome Bitmap. Genau wie bei einigen Druckertreibern läßt sich die Anfangsadresse dieser Bitmap abfragen und die »aufgerasterten« Daten nach Belieben weiterverarbeiten. Manko: Auflösung (300 dpi) und Farbtiefe (monochrom) sind fest verdrahtet.
Für das Verständnis einiger Besonderheiten bei der GDOSAusgabe ist es wichtig, das Konzept der VDI-Parameterübergabe richtig zu verstehen: Sämtliche Parameter werden über das ptsin- und das intin-Array übergeben, Ausgaben erfolgen über ptsout- und intout-Array. Die Koordination übernimmt das contrl-Array, in dem auch angegeben ist, wie viele Elemente die anderen Felder jeweils enthalten.
Beim Verarbeiten von Funktionsaufrufen inspizieren die VDI-Funktionen also contrl[1] (Anzahl der Koordinatenpaare in ptsin) und contrl[3] (Anzahl der Einträge in intin). Damit war es möglich, bestimmten VDIFunktionen auf kompatible Weise neue Parameter beizubringen. Ähnlich sieht es mit Funktionsergebnissen aus: contrl[2] enthält die Anzahl der Koordinatenpaare in ptsout, contrl[4] die Anzahl der Werte in intout.
Zu den einzelnen Funktionen: »v_opnwk()« verarbeitet (für einige Geräte) zusätzlich eine Seitengrößenangabe. Dazu übergibt man Breite und Höhe der Seite (in Pixeln) in ptsin[0] und ptsin[I]. contrl[l] muß dementsprechend auf 1 gesetzt sein. Ebenso kann man auch bei »vq_extnd()« die Seitengröße verstellen (bzw. prüfen, ob das Verstellen der Seitengröße erfolgreich war).
In Hinsicht auf die eben angesprochenen Regeln zur Parameterübergabe inkonsistent, aber dennoch wichtig: manche Treiber liefern bei »v_opnwk()« einen Zeiger auf die intern benutzte Bitmap zurück. Praktisch nutzen läßt sich diese (wenn überhaupt) natürlich nur bei monochromen Geräten, und auch nur dann, wenn das VDI-Standardformat benutzt wird (wie zum Beispiel beim Atari-Laserdrucker). Die beiden Hälften des Zeigers werden in contrl[0] (High-Word) und contrl[1] zurückgeliefert (wenn der Zeiger nicht zurückgeliefert wurde: contrl[0]=1 und contrl[1]=0).
Wichtig für Programmierer von GDOS-Replacements: Viele Treiber liefern im Fehlerfall nicht etwa ein Null-Handle, sondern setzen contr[2] und contrl[4] auf Null (und signalisieren damit, daß intout[] und ptsout[] keine Rückgabewerte enthalten). Bei der Benutzung von »v_clrwk()« ist wichtig, daß manche Treiber alle oder auch nur Teile der Workstation-Attribute auf Standardwerte zurücksetzen. Hier sollte man sich nicht auf irgendwelche Beobachtungen verlassen, sondern alle benötigten Attribute neu setzen.
»v_updwk()« liefert bei vielen Treibern in intout[0] einen Return-Wert zurück zu erkennen daran, daß contrl[4] ungleich Null ist. Dabei bedeutet »0«, daß alles in Ordnung war. Positive Fehlerwerte sind offiziell nur für die Atari-Lasertreiber dokumentiert, eine Abfrage auf »ungleich Null« dürfte aber immer sinnvoll sein. Bei der Ausgabe in Metadateien sind einige spezielle Eigenheiten zu berücksichtigen. Das beginnt schon bei der Festlegung des Dateinamens: normalerweise benutzt »META.SYS« automatisch die Datei »GEMFILE.GEM« (im aktuellen Verzeichnis). Das läßt sich mit »vm_filename()« ändern, allerdings nur dann, wenn dieser Befehl als erster nach dem Öffnen der Workstation erfolgt. Die momentan verfügbaren Versionen der Metafile-Treiber lassen dabei »GEMFILE.GEM« stehen, was man allerdings ignorieren kann (irgendwann wird Atari den Fehler schon beseitigen). Der Header einer Metadatei (s. Abb. 3) enthält Informationen, die zur korrekten Weiterverarbeitung unbedingt auf vernünftige Werte voreingestellt werden müssen: Die Angabe der Seitengröße, die man mittels »vm_pagesize()« (in 1/10 Millimeter setzt. Für eine DINA4-Seite würde man also die Werte 2100 und 2970 übergeben. Die beiden anderen Angaben hängen mit der Wahl des Koordinatensystems zusammen. »mf_coords« enthält die Positionen für die linke untere und rechte obere Ecke des benutzten Koordinatensystems und wird mit »vm_coords« gesetzt. Um ein Koordinatensystem wie auf einem »normalen« GDOS-Ausgabegerät zu erhalten (also Nullpunkt in der linken oberen Ecke), muß man also wie in Abb. 4 verfahren.
Selbstverständlich kann man auch den Nullpunkt in die Mitte des Koordinatensystems legen und dann mit positiven und negativen Koordinaten arbeiten.»mf_extents« enthält die maximalen Ausmaße der Grafik und wird ganz analog mit »v_meta_extents« gesetzt. Prinzipiell könnte man dazu über alle VDI-Ausgaben Protokoll führen und am Ende die maximalen Ausmaße einsetzen. Wer es sich einfacher machen will, übergibt einfach die gleichen Koordinaten wie bei »vm_coords«.
Durch Setzen der physikalischen Seitengröße und des Koordinatensystems kann man grundsätzlich auch die Auflösung in dpi verstellen. In unserem Beispiel in Listing 4 passiert das nicht, da zur Berechnung des Koordinatensystems ja gerade die von »v_opnwk()« zurückgelieferte Auflösung benutzt wird. Hält man sich nicht an diese Regel (was durchaus legitim ist, wenn man eine größere Auflösung benötigt), muß man davon ausgehen, daß alle von Pixelgrößen abhängigen VDIFunktionen (wie z. B. »vst_point()«) falsche Resultate liefern.
Noch ein paar Tips zur Ausgabe von Rastergrafiken. Methode Nummer 1: Man nutzt die Funktion »v_udpat()« (User Defined Fill Pattern), indem man immer 16 x 16 Pixel berechnet und diese per »filled rectangle« ausgibt. Die zweite Möglichkeit: Man schreibt die gesamte Bildinformation in eine monochrome Rastergrafik im IMG-Format und benutzt den VDI-Aufruf »v_bitimage«, der mit monochromen IMG-Dateien wunderbar zurecht kommt. Andere verläßliche Methoden sind uns zur Zeit nicht bekannt - hier besteht Handlungsbedarf für die Programmierer in Sunnyvale. Trotz aller Probleme ist das VDI gut dazu geeignet, Grafiken zu Papier zu bringen bzw. auf anderen, neuartigen Geräten auszugeben. (uw)
Quellennachweis:
[1] Julian F. Reschke: »MiNT 0.96 - Shared Text und Debugging«, ST-Magazin 12/1992, Seite 98
[2] Jankowski/Rabich/Reschke: »ATARI Profibuch ST-STE-TT«, 12. Auflage, Sybex Düsseldorf 1992, ISBN 3-88745-888-5
typedef struct
{
WORD mf_header; /* -1 (Metafile-Kennung) */
WORD mf_hlength; /* Länge des Headers in Integers */
WORD mf_version; /* bei der aktuellen Version 101 (Version 1.01) */
WORD mf_ndcrefl; /* NDC/RC-Flag (0 oder 2) */
WORD mf_extents[4] /* maximale Ausmaße der Grafik */
WORD mf_pagesz[2]; /* Seitengröße in 1/10 mm */
WORD mf_coords[4]; /* Koordinatensystem */
WORD mf_imgflag; /* falls Bit 0 = 1, so enthält die Datei Bitimages,
sonst nicht. Die anderen Bits sind immer 0. */
WORD mf_resvd[9]; /* zur Zeit unbenutzt */
} METAHDR;
Der Kopf einer Metadatei
/* Initialisierung des Koordinatensystems */
long tmpx, tmpy;
vm_pagesize (handle, 2100, 2970); /* DIN A4 */
tmpx = (210OL * 100L) / pixel_width; /* von v_opnwk() */
tmpy = (2970L * 100L) / pixel_height;
vm_coords (handle, 0, (int) tmpy-1, (int) tmpx-1, 0);
Setzen des Koordinatensystems