ST-Ecke - Line-A, Teil 3: Buchstäblich

Im dritten Teil des Line-A-Kurses werden wir uns mit der Textausgabe des ST beschäftigen, wobei wir auch die Struktur eines Zeichensatzes des GEM unter die Lupe nehmen. Vielleicht gibt es dann in absehbarer Zeit ein paar eifrige Programmierer unter unseren Lesern, die einen schönen Zeichensatzeditor schreiben, der auch in der Lage ist, Proportional-Zeichensätze zu gestalten.

Das Image eines Zeichens

Um die Methode zu verstehen, mit der der ST seine Zeichen ausgibt, müssen wir uns zunächst einmal anschauen, wie der Zeichensatz (englisch FONT) des ST aufgebaut ist. Stellen Sie sich vor, Sie würden alle Ihre zur Verfügung stehenden Zeichen nebeneinander schreiben, dann ergäbe sich ein Bild (englisch IMAGE), welches die Höhe des größten in der Zeichenmenge vorkommenden Zeichens hätte. Die Breite Ihres Bildes ergäbe sich aus der Summe der Breiten der einzelnen Zeichen. Bei Zeichensätzen unterscheidet man prinzipiell zwischen zwei Arten: proportional und unproportional. Bei einem unproportionalen Zeichensatz sind alle Zeichen gleich breit, bei einem proportionalen sind die Breiten der Zeichen unterschiedlich, so daß ein ‘i’ beispielsweise schmäler als ein ‘w’ ist. Nehmen wir einen Zeichensatz, der unproportional ist, also eine gleiche Breite aller Zeichen von beispielsweise 8 Punkten, wobei die Höhe des größten Zeichens 16 sei, so ergibt sich eine Zeichensatzbildbreite von 256(Zeichen)*8(Breite)=2048 Punkten und einer Höhe von 16 Punkten. Ordnet man die Bytes der Zeichen nun so an, wie Sie es von der hohen Auflösung des ST gewohnt sind, so steht im ersten Byte die oberste Zeile des ersten Zeichens, im zweiten Byte die oberste Zeile des zweiten Zeichens,... im 257. Byte die zweite Zeile des ersten Zeichens und so weiter. Bleiben wir weiter bei der Vorstellung, daß der Zeichensatz ein breites aber nicht sehr hohes Bild ist, so bräuchten wir an sich nur eine Routine, die in der Lage ist, aus einem solchen Bild einen Block (sprich Zeichen) auszuschneiden, und ihn in einen ‘normalen’ Bildspeicher zu kopieren - dadurch würde das Schreiben eines Zeichens auf ein simples Kopieren eines Blocks reduziert werden.

Die Kopie vom Image

Sicherlich wissen Sie von der letzten Folge der ST-Ecke, daß die BitBlt-Routine in der Lage ist, aus einem beliebig angeordneten Bildschirmspeicher einen Block in einen anderen Bildspeicher zu kopieren. Auf diese Weise verwendet Line-A intern die eigene Bitbit-Routine als Ausgaberoutine eines Zeichens. Nun stellt sich sicherlich die Frage, warum man einen solchen Aufwand treibt, wenn es doch einfacher wäre, ein Zeichen Byte für Byte zu kopieren. Nichts einfacher als das, aber was machen wir bei einem Proportional-Zeichensatz? In diesem Zeichensatz sind nicht alle Zeichen gleich breit, mit anderen Worten, ein Zeichen fängt nicht immer an einer Bytegrenze an, ganz zu schweigen davon, daß ein Zeichen 8 Bit (Punkte) breit ist. Einen solchen Zeichensatz kann man byteweise schlecht übertragen.

Kluger Kopf

Glücklicherweise beschränkt sich die Textausgaberoutine des Line-A nicht nur auf das schlichte Kopieren eines Buchstabens, sondern mit ihr sind auch einige Manipulationen eines Buchstabens möglich, so daß ein Text fett, hell und kursiv oder in unterschiedlichen Größen ausgegeben werden kann. Daher ist dem Zeichensatzbild bei GEM-Zeichensätzen der sogenannte Header (Kopf) vorangestellt, in dem einige Aussagen über die Art und Verwendungsweise eines Zeichensatzes gemacht werden (Listing 3). Als ersten Eintrag findet man die Font-Identifikation, die schlichtweg eine Zahl darstellt. Leider hat ATARI für die Numerierung der Zeichensätze keine Normung festgelegt. Die bisher bekannten Zeichensätze, die sich auf der von ATARI verbreiteten GDOS-Diskette befinden, haben folgende Nummern: Systemzeichensatz(01), Swiss-Helvetica(02), Dutch-Times(14) und Typewriter-Courier(15). Als nächste Angabe folgt die Punktgröße der Schrift. Diese Angabe besagt, wie groß die Schrift auf Papier (auf dem Monitor hat diese Angabe natürlich keine Bedeutung) erscheinen wird, wobei einem Punkt 12 Cicero und einem Cicero circa 4.5 mm entsprechen - daraus ergeben sich 0.375 mm pro Punkt. Als weitere Kennzeichnung läßt sich der Name der Schriftart im Header unterbringen, wofür 32 Zeichen zur Verfügung stehen. First ade und Last ade geben an, welche Zeichen vorhanden sind, das heißt, das zwar nicht alle 256 vorhanden sein müssen, aber alle Zeichen zwischen dem Zeichencode first_ade und last_ade.

Gefangen in einer Zelle

Jedes Zeichen hat man sich in einem Rechteck (Zelle) vorzustellen, in dem es positioniert wird. Dabei werden bestimmte Linien für jeden Zeichensatz festgelegt, ähnlich denen in einem Schreibübungsheft für Schulkinder (Bild 1). Die Abstände zwischen den unterschiedlichen Zeilen findet man in den Einträgen bottom, descent, half, ascent und top, wobei immer Bezug auf die Basisline genommen wird. Im folgenden wird die größte Zeichenbreite und die größte Zellenbreite angegeben - die Zellenbreite ist dabei natürlich größer oder gleich der Zeichenbreite. Bei Kursivschrift wird das entsprechende Zeichen breiter, wobei diese nicht nur nach rechts, sondern auch nach links (Unterlängen eines Zeichens) Auswirkung zeigen kann - diese Überbreite wird in left_offset und right_offset vermerkt.

Bei Fettschrift hat die Ausgaberoutine die Aufgabe, zusätzliche Punkte zur bestehenden Schrift hinzuzufügen - der Verbreiterungswert steht in thicken. Soll ein Zeichen unterstrichen werden, hängt es von der Schriftart ab, wie dick der Unterstrich ist, so daß man in ul_size die Dicke des Unterstrichs angeben kann. Leider unterstützt Line-A das Feature des Unterstreichens bei der Textausgabe nicht! Im weiteren findet man bei skew und lighten Masken für Kursiv- und Hellschrift, mit denen das Zeichen verknüpft wird. Mit flags lassen sich folgende Parameter einstellen (1):

Bit 0: Systemfont
Bit 1: horizontale Offset-Tabelle verwenden
Bit 2: INTEL(0)- oder Motorola(1)-Format bei GDOS-Fonts muß das Bit gelöscht sein!
Bit 3: unproportional

Nach den Flags folgen drei Zeiger, auf die wir etwas genauer eingehen wollen: Die off_table (character offset table) dient dazu, bei unproportionalen Zeichensätzen die X-Position des entsprechenden Zeichens anzugeben, so daß sie in dem Moment benutzt werden muß, wenn Bit 3 in flags gesetzt worden ist. Hor_table wird meines Wissens bisher noch nicht genutzt, was, wie oben schon erwähnt, durch Bit 1 in flags ausgesagt wird. Man kann mit ihr einen weiteren horizontalen Versatz pro Zeichen erzwingen. Der dritte Zeiger zeigt direkt auf den Speicherbereich, in dem unser Zeichensatzbild liegt - also bitte nicht etwa denken, daß dieses Bild direkt hinter dem Kopf liegen wird. Die nächsten Parameter sind schnell erläutert: form_width gibt die Breite und form_height die Höhe des Bildes an. Darauf folgt nxt_font, der als Zeiger auf den nächsten verfügbaren Fontheader zeigt, so daß sich im Speicher eine verkettete Liste ergibt, an der man sich gegebenenfalls entlanghangeln kann. Im Profi-Buch war noch ein letzter Parameter font_seg vorhanden, der, wie ich von einem der Autoren, Herrn Reschke, erfahren konnte, eine Fehlinformation von ATARI gewesen ist, das heißt, es gibt ihn doch nicht.

Die Sache mit dem WRMODE

Als ich die Line-A-Struktur übernahm, habe ich angestrebt, kompatibel zum Profi-Buch von Sybex zu sein, allerdings ist mir erst jetzt aufgefallen, daß im Buch WMODE und in der Veröffentlichung der letzten beiden ST-Ecken WRMODE steht. Bitte ändern Sie daher in den letzten beiden Folgen WRMODE in WMODE um, besonders natürlich in line_a.h, in der hoffentlich Ihre Line-A-Struktur zu finden ist.

Noch mehr Variables

Wenden wir uns also der eigentlichen Routine des Line-A zu, die in der Lage ist, ein Zeichen auf dem Bildschirm erscheinen zu lassen. Wie Sie in Listing 2 erkennen können, stellt auch diese Routine eine Vielzahl von Variablen zur Verfügung, die es nach Wichtigkeit zu unterscheiden gilt. Dabei werden wir wie so oft feststellen, daß bei der Ausgabe eines Zeichens nicht immer wieder alle Parameter gesetzt werden müssen. Daher habe ich die Routine set_line_font (Listing 4) zur Verfügung gestellt, mit der die Grundeinstellungen für die Textausgabe durchgeführt werden. Später werden bei der Textausgabe nur noch vier Parameter benötigt. MODE, CLIP, XMINCL, XMAXCL, YMINCL und YMAXCL übergehen wir ganz schnell, da wir diese schon zur Genüge bei der Erklärung der anderen Routinen 'breitgetreten’ haben. XDDA ist eine etwas seltsame Variable, da sie immer auf $8000 gesetzt werden muß - wer weiß warum?! Mit SCALE läßt sich die Skalierung, das heißt Vergrößerung oder Verkleinerung, ein(1)- und ausschalten(0), wobei der Vergrößerungsfaktor in DDAINC verewigt wird. Möchte man die Buchstaben verkleinern, hat man in SCALDIR eine 0 hineinzuschreiben, soll aber der Buchstabe vergrößert werden, so ist der Wert eine 1. Wie wir schon vom Kopf des Zeichensatzes wissen, gibt es eine Unterscheidung zwischen gleichbreiten (mono_spaced) und unterschiedlich breiten Zeichen, was für LINE-A in der Variablen MONO vermerkt wird - den Wert holen wir uns direkt aus dem Kopf des Zeichensatzes. In der Textform-Variablen STYLE wird bitweise vermerkt, welche unterschiedlichen Merkmale die Schriftart haben soll. Dabei bedeuten:

Bit 0: Fettschritt
Bit 1: Hellschritt
Bit 2: Kursivschrift
Bit 3: Unterstrichene Schrift
Bit 4: Umrißschrift

Nebenbei sei bemerkt, daß die Ausgabezeit mit jeder zusätzlichen Schriftform zunimmt, da der Rechner nicht unwesentliche Arbeiten erledigen muß. Bei jedem Zeichensatz müssen die entsprechenden Masken gesetzt werden, die uns der Kopf des Zeichensatzes glücklicherweise liefert. Diese Masken werden in LITEMASK für Hellschrift und SKEWMASK für Kursivschrift geschrieben. Auch die weiteren Variablen WEIGHT (Fettschriftdicke), LOFF (linker Offset) und ROFF (rechter Offset) holen wir uns aus dem Kopf des Zeichensatzes. Die Rotation der Schrift, die zwar in zehntel Grad angegeben aber nur in 90°-Schritten (0, 90, 180 und 270 Grad) verwendet werden kann, wird in die Variable CHUP geschrieben. Bei der Textdarstellung kann die Farbe des Vordergrundes, also des eigentlichen Zeichens, sowie des Hintergrundes mit TEXTFG und TEXTBG eingestellt werden. Da die Routine einige interne Berechnungen durchzuführen hat, braucht sie einen Puffer, in dem diese Berechnungen durchgeführt werden können. Diesen Puffer hat man als Programmierer dem LINE-A zur Verfügung zu stellen, wobei man die Adresse des Puffers in SCRTCHP schreibt. Dieser Puffer muß so groß sein, daß er zweimal die Maximalgröße des Zeichens aufnehmen kann. In SCRPT2 muß dann noch die Mitte dieses Puffers, also die Maximalgröße eines Zeichens, hineingeschrieben werden. Die Höhe eines Zeichens erfährt man im Fontheader in form_height und schreibt sie in die Line-A-Variable DELY. Die Breite des Zeichensatzbildes möchte Line-A in FWIDTH haben, wobei wir auch diese aus form_width des Kopfes holen. Das Wichtigste vom Ganzen ist die Adresse des eigentlichen Zeichensatzbildes, die wir aus dat_table holen und in FBASE des LINE-A schreiben. Damit wäre auch schon die Routine set_line_font() beschrieben, und Sie sehen, wie wenig für die Ausgabe eines Zeichens übriggeblieben ist.

Bild 1: Zeichenzeilen

Der letzte Rest...

Viel ist jetzt nicht mehr übrig, und dazu schauen wir uns die Routine a008() in Listing 2 an. Ihr übergeben wir das auszugebende Zeichen, die X/Y-Koordinate sowie die Adresse des zu verwendenden Font-Headers. Zunächst prüfen wir, ob überhaupt eine Adresse übergeben worden ist, ansonsten wird die Routine sofort beendet. Dann unterscheiden wir, ob es sich um Proportional- oder Normalschrift handelt, was wir an Bit 3 der flags im Fontheader erkennen. Schauen wir uns zunächst die Normalschrift an und ermitteln wir die X-Adresse des Buchstabens im Zeichensatzbild (SOURCEX):

Dazu ziehen wir die erste verfügbare Zeichennummer von der Nummer unseres Zeichens ab und nehmen dies mit der Breite eines Zeichens mal. Angenommen, das erste verfügbare Zeichen hat die Nummer 10, unseres die Nummer 65, und die Breite ist 8 Pixel, dann ergibt sich die X-Koordinate 55*8=440. Handelt es sich bei dem verwendeten Zeichensatz um Proportionalschrift, kann man die Koordinate natürlich nicht durch Multiplikation mit der Breite ermitteln. Allerdings gibt es eine Tabelle, in der für jedes Zeichen seine X-Position innerhalb des Zeichensatzbildes steht. Den Zeiger für die Tabelle finden wir im Fontheader unter dem Namen off_table, wobei wir den Index für die Tabelle wiederum dadurch erhalten, indem wir von unserer Zeichennummer die erste vorhandene abziehen. Die Breite des Zeichens erhalten wir, indem wir die X-Koordinate dieses Zeichens von der X-Koordinate des folgenden abziehen und dann in DELX des Line-A schreiben. Die Y-Adresse des Zeichens kann man meist mit 0 annehmen, so daß wir SOURCEY einfach auf 0 setzen. Die Zielkoordinaten DESTX und DESTY geben an, wohin wir unser Zeichen schreiben wollen. Nun berechnen wir uns. sozusagen als besonderen Service, die X-Position des nächsten auszugebenden Zeichens, indem wir zur aktuellen X-Position die Breite des Zeichens hinzuaddieren. Dabei müssen wir natürlich auch die Texteffekte beachten, denn ein Zeichen wird breiter, wenn beispielsweise Kursivschrift verwendet wird. Nun folgt der Aufruf von Line-A-A008, und das Zeichen steht auf dem Bildschirm. Anschließend geben wir die nächste Zeichenposition zurück.

Demonstration

Damit die Angelegenheit nicht ganz so trocken ist, habe ich eine kleine Demonstration programmiert, die ein paar Zeichen in den unterschiedlichsten Schriftarten ausgibt.

Im Laufe dieser ST-Ecke habe ich mich entschlossen, die Mausroutinen auf das nächste Mal zu verschieben, um nicht so viel auf einmal durcheinanderzubringen. Spielen Sie am besten noch ein wenig mit den umfangreichen Möglichkeiten von A008 herum, und freuen Sie sich mit mir auf die nächste ST-Ecke, in der ich Ihnen zeigen werde, wie Sie als Mauszeiger ein kleines Mäuschen mit Line-A hinzaubern und auch verschwinden lassen können.

SH

#include <line_a.h>
#include <gemdefs.h>
#include <stdio.h>
#include <osbind.h>

/* Zeichenmodi, am besten in gemdefs.h oder line_a.h übernehmen */

#define MD_REPLACE  0 /* Überschreibmodus */
#define MD_TRANS    1 /* Transparent */
#define MD_XOR      2 /* Xor-Modus */
#define MD_ITRANS   3 /* Inverse transparent */

#define BIG_CHAR   16 /* größtes Zeichen, sollte mind, max (s. set_line_font) */
                      /* aller Zeichensätze sein */

#define void /**/     /* Nur definieren, falls nicht bekannt */

#ifndef abs /* Makro für Absolutbetrag */
    #define abs(x) (x<0) ? x*-1:x
#endif

LINE_A *linea, *a000(); /* Zeiger auf Line-A-Variablen   */
long *fonts, *routines; /* Zeiger auf Routinen und Fonts */

int scratch_buf[BIG_CHAR*2];   /* Puffer für Texteffekte */
MFDB bildschirm={0L,640,400,40,0,1,0,0,0};  /* Monochrom */

int fill[]={                   /* Füllmuster, 16 Zeilen hoch */
0x2E74,0xA5A5,0x300C,0x9C39,
0xCFF3,0x4812,0x6426,0xD3CB,
0xD3CB,0x6426,0x4812,0xCFF3,
0x9C39,0x300C,0xA5A5,0x2E74};

                              /* Ein Ufo-Sprite */ 
int sprite_array[]={0x0000,0x0000,0x0001,0x0002,0x0005,
                    0x0000,0x0000,0x0FF0,0x0000,
                    0x1FF8,0x0FF0,0x3FFC,0x1FF8,
                    0x7FFE,0x3FFC,0xFFFF,0x7FFE,
                    0x4002,0x2AAC,0x3FFC,0x1FF8,
                    0x1FF8,0x0FF0,0x0FF0,0x0000, 
                    0x0000,0x0000,0x0000,0x0000,
                    0x0000,0x0000,0x0000,0x0000,
                    0x0000,0x0000,0x0000,0x0000};

                            /* Eine Maus-Maus */ 
int mouse[]= { 0x0000,0x0008,0x0001,0x0000,0x0001, 
               0x0000,0x0030,0x0038,0x0FFC,
               0x1FFC,0x3FFC,0x6FFC,0xFFFC,
               0xFFF8,0xFFF8,0x0000,0x0000,
               0x0000,0x0000,0x0000,0x0000, 
               0x0000,0x0000,0x0010,0x0028,
               0x0F88,0x1FC8,0x2FF8,0x7FF8,
               0xFFF0,0x1040,0x0000,0x0000, 
               0x0000,0x0000,0x0000,0x0000} ;

main()
{
    /* Hier kommen die unter AUFRUF aufgeführten Aufrufe hinein */ 
    linear a000(&fonts,&routines);      /* Initialisierung */
}

Listing 1: Der Hauptteil


Eingabe: WMODE:     Schreib- und Zeichenmodus (siehe Text)
         CLIP:      Clipping ein(1)- oder ausschalten(2)
         XMINCL, YMINCL,
         XMAXCL, YMAXCL : Clipping-Koordinaten geben ein Rechteck an
         XDDA:      immer auf $8000 setzen
         DDAINC:    Vergrößerungsfaktor
         SCALDIR:   Vergrößerungsrichtung
         MONO:      unterschiedliche Zeichenbreite ein(1)/aus(0)
         SOURCEX, SOURCEY: X/Y-Position im Zeichensatz-Bild
         DESTX, DESTY: X/Y-Koordinate im Zielbild
         DELX, DELY: Breite und Höhe des Zeichens
         FBASE:     Zeiger auf Zeichensatzdaten
         FWIDTH:    Breite des Zeichensatzbildes
         STYLE:     Texteffekte
         LITEMASK:  Maske für Hellschrift
         SKEWMASK:  Maske für Kursivschrift
         WEIGHT:    zusätzliche Breite für Fettschrift
         LOFF, ROFF: linker/rechter Offset bei Kursivschrift
         SCALE:     Skalierung ein(1)/aus(0)
         CHUP:      Schriftrichtung in 1/10 Grad (0, 90, 180, 270)
         TEXTFG, TEXTBG: Vordergrund- und Hintergrundfarbe
         SCRTCHP:   Zeiger auf Buffer - 2*Maximal_Zeichengröße 
         SCRPT2:    Offset zur Mitte des Buffers

Ausgabe: keine

Routine:

/***********************************************/
/* ch:  Zeichen, das ausgegeben werden soll    */
/* x,y: Koordinate, an der Zeichen stehen soll */
/* font: Adresse des Fontheaders               */
/***********************************************/
int a008(ch, x, y, font) 
char ch;
FONT_HDR *font;
{
    int back_x; /* nächste Zeichenausgabestelle */

    if (!font)  /* Fontheaderadresse = 0? */ 
        return; /* Ja, dann zurück */


    if (!font->flags&8) /* Proportionalschrift */
    {
        linea->SOURCEX= font->off_table[ch-(font->first_ade)]; 
        linea->DELX   = font->off_table[ch+1-(font->first_ade)]-(linea->SOURCEX);
    }
    else /* Keine Offsettabelle verwenden */
    {
        linea->SOURCEX=(ch-(font->first_ade))*(font->max_cell_width); 
        linea->DELX = font->max_cell_width;
    }

    linea->SOURCEY= 0; /* meist 0 */
    linea->DESTX=   x; /* X-Koordinate */
    linea->DESTY=   y; /* Y-Koordinate */
                /* altes X + Breite des Zeichens */
    back_x=x+linea->DELX+((linea->STYLE&4)!=0)*(font->left_offset+font->right_offset)+((linea->STYLE&16)!=0)*2;

    asm
    {
        dc.w 0xa008 /* Textausgabe */
    }
    return(back_x); /* nächste Koordinate */
}

Aufruf:

void demo_a008()
{
    int x,y,i,s;
    FONT_HDR *font;

    printf("\33E\n");
    font= (FONT_HDR*)*(fonts+1); /* 2. Zeichensatz verwenden */

    set_line_a(0L,0,0,1,0,0,0,0,0); /* kein Clipping */ 
    linea->WMODE=MD_REPLACE;     /* Zeichenmodus */

    for(y=s=0; y<400; y+=2*font->form_height, s++) /* ein paar Zeilen */
    {                            /* neuen Style setzen */
        set_line_font(font,1,0,0,0,s,0,scratch_buf); 
        for(x=10,i='0'; i<'Z'; i++) /* ein paar Zeichen */ 
            x=a008(i,x,y,font);  /* ausgeben */
    }
    Crawcin();      /* auf Zeicheneingabe warten */
}

Listing 2: Textausgabe mit Line-A-A008

Bitte in 'line_a.h' oder 'gemdefs.h' kopieren

typedef struct{
    int font_id;        /* Fontnummer */
    int point;          /* Punktgröße des Fonts */
    char name[32];      /* Name des Zeichensatzes */
    int first_ade;      /* 1.Zeichen im Zeichensatz */
    int last_ade;       /* letzt. Zeichen i . Zeichens . */
    int top;            /* Abstand Topline/Baseline */
    int ascent;         /* Abst.Ascentline/Baseline */
    int half;           /* Abst.Halfline/Baseline */
    int descent;        /* Abst.Descentline/Baseline */
    int bottom;         /* Abst.Bottomline/Baseline */
    int max_char_width; /* größte Zeichenbreite */
    int max cell_width; /* größte Zeichenzellenbreite */ 
    int left_offset;    /* linker Offset für Kursivschrift */
    int right_offset;   /* rechter Offset für kursiv */
    int thicken;        /* Verbreit, für Fettschrift */
    int ul_size;        /* Dicke der Unterstreichung */
    int lighten;        /* Maske für Hellschrift */
    int skew;           /* Maske für kurs.Schrifttyp */
    int flags;          /* allgemeine Flags */
    unsigned char *hor_table; /* Zeiger auf Horxzontaltab. /
    unsigned int *off_table;  /* Zeiger auf Offsettabelle */
    unsigned int *dat_table;  /* Zeiger auf Zeichensatzbrld */
    int form_width;     /* Breite des Zeichensatzbildes */
    int form height;    /* Höhe d.Zeichensatzbildes */
    int *nxt_fnt;   /* Zeiger auf nächsten Fontheader */
}FONT_HDR;

Listing 3: Der Fontheader eines GEM-Zeichensatzes

void set_line_font(font,col_fg,col_bg,direc,change,style,rot,scratch) 
int col_fg, col_bg, direc, change, style, rot; 
int *scratch;
FONT_HDR *font;
{
    int max;

    if (!font) 
        return;

    linea->XDDA=    0x8000;             /* das ist immer so */
    linea->SCALE=   (change>0);         /* Wenn folgender Wert>0 */
    linea->DDAINC=  change;             /* Änderung der Skalierung */
    linea->SCALD1R= direc;              /* Vergrößern=1/Verkleinern=0*/
    linea->MONO=(font->flags&8>0);      /* gleiche Breiten? */
    linea->STYLE=   style;              /* Texteffekte */
    linea->LITEMASK= font->lighten;     /* Maske für Hellschnft */
    linea->SKEWMASK= font->skew;        /* Maske für Kursivschrift */
    linea->WEIGHT=  font->thicken;      /* Fettschriftänderung */
    linea->LOFF=    font->left_offset;  /* linker Offset für Kursivschrift */ 
    linea->ROFF=    font->right—offset; /* rechter Offset für Kursivschrift */
    linea->CHUP= rot;                   /* Drehrichtung: 0,900,1800,2700 ♦/
    linea->TEXTFG=  col_fg;             /* Textfarbe */
    linea->TEXTBG=  col_bg;             /* Hintergrund */
    linea->SCRTCHP= (long) scratch;     /* Puffer für Texteffekte */
    max= ((font->max_cell_width)>(font->form_height)) ? font->max_cell_width: font->form_height; 
    linea->SCRPT2=  max;                /* maximale Größe eines Zeichens */
    linea->DELY =   font->form_height;  /* Höhe des Zeichens */
    linea->FBASE=   font->dat_table;    /* Adresse des Font-Bildes */
    linea->FWIDTH=  font->form_width;   /* Breite des Font-Bildes */
}

Listing 4: Routine zum Setzen der Fontparameter



Aus: ST-Computer 06 / 1989, Seite 100

Links

Copyright-Bestimmungen: siehe Über diese Seite