typedef struct { int16_t *contrl; /* Zeiger auf contrl-Array */ int16_t *intin; /* Zeiger auf intin-Array */ int16_t *ptsin; /* Zeiger auf ptsin-Array */ int16_t *intout; /* Zeiger auf intout-Array */ int16_t *ptsout; /* Zeiger auf ptsout-Array */ } VDIPB;
typedef struct { int16_t nbplanes; int16_t width; int16_t height; } BIT_IMAGE;
Die Union COLOR_ENTRY enthält den Farbtabelleneintrag. Zukünftig sind auch andere Farbräume als RGB möglich:
typedef union { COLOR_RGB rgb; COLOR_CMYK cmyk; } COLOR_ENTRY;
typedef struct { uint16 reserved; /* auf 0 oder den Index des Eintrags setzen */ uint16 red; /* Rot: 0<->65535 */ uint16 green; /* Grün: 0<->65535 */ uint16 blue; /* Blau: 0<->65535 */ } COLOR_RGB;
Falls in einem Programm die Farbdaten bereits in einem vernünftigen Format (z.B. 8 Bit pro Kanal) vorliegen, kann man sich eine Umwandlung mit Multiplikation und Division ersparen. Die Shift- und OR-Funktion des Prozessors erledigt das dann schneller und eleganter.
Beispiel: Der Farbwert sei durch die Byte-Variablen r, g, b beschrieben. Die korrekte Umsetzung auf das 16-Bit-Format der COLOR_RGB-Struktur erfolgt dann so:
COLOR_RGB color; color.reserved = 0; color.red = r; color.red |= (color.red << 8); color.green = g; color.green |= (color.green << 8); color.blue = b; color.blue |= (color.blue << 8);
Das Strukturelement reserved sollte auf 0 gesetzt werden oder (beim Aufbau einer Farbtabelle) den Index des Eintrags enthalten. In jedem Fall müssen aber die oberen 8 Bits von reserved auf 0 gesetzt werden, da sie von den Farbroutinen ggf. für Flags verwendet werden.
typedef struct /* Farbtabelle */ { int32 magic; /* 'ctab' */ int32 length; int32 format; /* Format (0) */ int32 reserved; /* reserviert, auf 0 setzen */ int32 map_id; /* Kennung der Farbtabelle */ int32 color_space; /* Farbraum (z.Zt. nur CSPACE_RGB) */ int32 flags; /* VDI-interne Flags, auf 0 setzen */ int32 no_colors; /* Anzahl der Farbeintäge */ int32 reserved1; /* reserviert, auf 0 setzen */ int32 reserved2; /* reserviert, auf 0 setzen */ int32 reserved3; /* reserviert, auf 0 setzen */ int32 reserved4; /* reserviert, auf 0 setzen */ COLOR_ENTRY colors[]; } COLOR_TAB;
Der Datentyp fix31 entspricht dem Typ LONG, und wird in Zusammenhang mit Vektorfonts benötigt, wo mit Positonen und Schrittweiten in 1/65536 gerechnet wird. Dabei entspricht die Weite eines Pixels dem Wert 65536. Die oberen 16 Bit repräsentieren den Vorkommaanteil und die unteren 16 Bit die Nachkommastellen.
Beispiele:
hex. | dez. | |
$00010000 | 65536 | 1.0 Pixel |
$0001c000 | 114688 | 1.75 Pixel |
$fffec000 | -81920 | -1.25 Pixel |
$fffe4000 | -114688 | -1.75 Pixel |
Wichtig: Der Nachkommateil darf niemals abgeschnitten werden!
Um Schrittweiten aufzusummieren (z.B. von vqt_advance) und dann die Pixelposition für die korrekte Positionierung des Cursors zu berechnen, sollte man wie folgt vorgehen:
int16_t fix31_to_pixel( fix31 a ) { int16_t b; b = (int16_t) (( a + 32768L ) >> 16 ); /* runden !! */ return( b ); /* Pixelwert zurückgeben */ }
Querverweis: GDOS NVDI SpeedoGDOS
Die folgende Struktur beschreibt den Datei-Header für einen Bitmap Zeichensatz im Digital Research Standardformat. In diesem Format wird der Font als breites, monochromes Rasterbild organisiert; die Breite des Rasters ist die Summe aller Zeichenbreiten, die Rasterhöhe entspricht der Höhe eines einzelnen Zeichens. Daraus folgt: Der linke Rand eines Zeichens muss nicht unbedingt auf eine Bytegrenze fallen; nur am Ende jeder Rasterzeile wird soweit mit Null-Bits aufgefüllt, bis der nächste Zeilenbeginn wieder auf eine Wortgrenze fällt.
typedef struct font_hdr { int16_t font_id; /* Zeichensatz-Nummer */ int16_t point; /* Größe in Punkten */ int8_t name[32]; /* Name des Zeichensatzes */ uint16_t first_ade; /* erstes Zeichen im Zeichensatz */ uint16_t last_ade; /* letztes Zeichen im Zeichensatz */ uint16_t top; /* Abstand: Topline <-> Baseline */ uint16_t ascent; /* Abstand: Ascentline <-> Baseline */ uint16_t half; /* Abstand: Halfline <-> Baseline */ uint16_t descent; /* Abstand: Descentline <-> Baseline */ uint16_t bottom; /* Abstand: Bottomline <-> Baseline */ uint16_t max_char_width; /* größte Zeichenbreite */ uint16_t max_cell_width; /* größte Zeichenzellenbreite */ uint16_t left_offset; /* linker Offset für Kursivschrift */ uint16_t right_offset; /* rechter Offset für Kursivschrift */ uint16_t thicken; /* Verbreiterungsfaktor für Fettschrift */ uint16_t ul_size; /* Dicke der Unterstreichung */ uint16_t lighten; /* Maske für helle Schrift (0x5555) */ uint16_t skew; /* Maske für Kursivschrift (0x5555) */ uint16_t flags; /* verschiedene Flags: gesetzt falls System-Font Bit-1: gesetzt falls Horizontal Offset-Table benutzt wird Bit-2: gesetzt falls Motorola-Format Bit-3: gesetzt falls nicht proport. */ uint8_t *hor_table; /* Zeiger auf Horizontal-Offset-Table */ uint16_t *off_table; /* Zeiger auf Character-Offset-Table */ uint16_t *dat_table; /* Zeiger auf Fontimage */ uint16_t form_width; /* Breite des Zeichensatz-Image */ uint16_t form_height; /* Höhe des Zeichensatz-Image */ font_hdr *next_font; /* Zeiger auf nächsten Font-Header */ } FONT_HDR;
Hinweis: Da das GEM ursprünglich auf dem PC entwickelt wurde, liegen alle Daten normalerweise im Intel-Format vor, so daß auf Maschinen mit Motorola-Prozessoren bei allen Wörtern oberes und unteres Byte vertauscht werden müssen. Achtung: Um das Motorola/Intel-Flag (Bit-2 der Komponente flags) abfragen zu können, muss eigentlich schon bekannt sein, in welchem Format der Zeichensatz vorliegt. Die Lösung des Problems: Davon ausgehen, dass Bit-10 der Flags niemals benutzt sein wird, und testen, ob Bit-2 im 67-ten Byte des Headers gesetzt ist (denn dann liegt der Zeichensatz im Motorola-Format vor).
Die Character-Offset-Table besitzt Einträge von 16-Bit-Werten, die den horizontalen Pixeloffset für jedes Zeichen innerhalb des Fontrasters angibt. Als Index muss man also den ASCII-Code abzüglich des ASCII-Codes des ersten Zeichens im Zeichensatz benutzen (Komponente first_ade). Die Breite eines Zeichens ergibt sich aus der Differenz zum Offsetwert des nächsthöheren Zeichens; damit diese Formel auch für das letzte Zeichen funktioniert, enthält die Tabelle übrigens stets einen Eintrag mehr, als Zeichen verfügbar sind.
Die Horizontal-Offset-Table enthält positive oder negative Offsetwerte die vor der Ausgabe eines Zeichens auf die x-Position addiert werden; sie wird allerdings nur bei wenigen Zeichensätzen unterstützt.
Last but not least sei darauf hingewiesen, daß sich eine normale Anwendung niemals mit diesem Format befassen muß; lediglich für Entwickler von Zeichensatzeditoren oder GDOS-Versionen sind diese Informationen wichtig.
Querverweis:
GDOS NVDI SpeedoGDOS Vektorfonts vst_alignment
vst_load_fonts vst_unload_fonts vqt_fontheader
/* * öffentliche Bitmapbeschreibung (Struktur * mit Versionsheader) */ typedef struct _gcbitmap { LONG magic; /* Strukturkennung 'cbtm' */ LONG length; /* Strukturlänge */ LONG format; /* Strukturformat (0) */ LONG reserved; /* reserviert (0) */ BYTE *addr; /* Adresse der Bitmap */ LONG width; /* Breite einer Zeile in Bytes */ LONG bits; /* Bittiefe */ ULONG px_format; /* Pixelformat */ LONG xmin; /* minimale diskrete x-Koordinate der Bitmap */ LONG ymin; /* minimale diskrete y-Koordinate der Bitmap */ LONG xmax; /* maximale diskrete x-Koordinate der Bitmap + 1 */ LONG ymax; /* maximale diskrete y-Koordinate der Bitmap + 1 */ CTAB_REF ctab; /* Verweis auf die Farbtabelle oder 0L */ ITAB_REF itab; /* Verweis auf die inverse Farbtabelle oder 0L */ LONG reserved0; /* reserviert (muß auf 0 gesetzt werden) */ LONG reserved1; /* reserviert (muß auf 0 gesetzt werden) */ } GCBITMAP;
Querverweis: NVDI v_open_bm vr_transfer_bits
Der Memory Form Definition Block ist eine Datenstruktur, die vom VDI für die Rasteroperationen benutzt wird, um die Ziel- und Quellspeicherbereiche zu beschreiben.
C-Deklaration:
typedef struct mfdb { VOID *fd_addr; /* Zeiger auf den Beginn des */ /* Speicherbereichs, z. B. */ /* Bildspeicherbasisadresse */ WORD fd_w; /* Blockbreite in Pixeln */ WORD fd_h; /* Höhe des Blocks in Pixeln */ WORD fd_wdwidth; /* Blockbreite in Integern */ WORD fd_stand; /* 0 = geräteabhängiges Format */ /* 1 = Standardformat */ WORD fd_nplanes; /* Anzahl der Farbebenen */ WORD fd_r1, fd_r2, fd_r3; /* reserviert */ } MFDB;
Hinweis: Wenn die Komponente fd_addr eine 0 enthält, muß der Rest des MFDBs nicht ausgefüllt werden. Die Rasteroperationen vrt_cpyfm und vro_cpyfm beziehen sich dann automatisch auf den Bildschirm (oder im Fall eines Druckertreibers auf die Druckerbitmap). Die reservierten Worte fd_r1, fd_r2 und fd_r3 sollten hinsichtlich zukünftiger Erweiterungen auf 0 gesetzt werden!
Querverweis: Rasterformate Rasterfunktionen
typedef struct /* Punkt für 16-Bit-Koordinaten */ { int16 x; int16 y; } POINT16;
typedef struct /* Punkt für 32-Bit-Koordinaten */ { int32 x; int32 y; } POINT32;
wird im VDI benutzt um verschiedene grafische Objekte anhand von mehreren Koordinatenpaaren (x,y) darzustellen. Beispiele für die Anwendung des pxyarrays sind die Darstellung von Rechtecken.
pxyarray[0] | x-Koordinate des oberen linken Eckpunktes |
pxyarray[1] | y-Koordinate des oberen linken Eckpunktes |
pxyarray[2] | x-Koordinate des unteren rechten Eckpunktes |
pxyarray[3] | y-Koordinate des unteren rechten Eckpunktes |
oder allgemein von n Punktepaaren
pxyarray[0] | x-Koordinate des ersten Punktepaares |
pxyarray[1] | y-Koordinate des ersten Punktepaares |
pxyarray[2] | x-Koordinate des zweiten Punktepaares |
pxyarray[3] | y-Koordinate des zweiten Punktepaares |
: | |
: | |
: | |
pxyarray[2*n - 2] | x-Koordinate des n-ten Punktepaares |
pxyarray[2*n - 1] | y-Koordinate des n-ten Punktepaares |
Querverweis: VDI VDI-Bindings
typedef struct /* Rechteck für 16-Bit-Koordinaten */ { int16 x1; int16 y1; int16 x2; int16 y2; } RECT16;
typedef struct /* Rechteck für 32-Bit-Koordinaten */ { int32 x1; int32 y1; int32 x2; int32 y2; } RECT32;
Diese Struktur ist wie folgt definiert:
typedef struct { int32_t size; /* Länge der Struktur (vor Aufruf setzen!) */ int16_t format; /* Fontformat */ int16_t id; /* Font-ID */ int16_t index; /* Index */ int8_t font_name[50]; /* vollständiger Fontname */ int8_t family_name[50]; /* Name der Fontfamilie */ int8_t style_name[50]; /* Name des Fontstils */ int8_t file_name1[200]; /* Name der 1. Fontdatei */ int8_t file_name2[200]; /* Name der optionalen 2. Fontdatei */ int8_t file_name3[200]; /* Name der optionalen 3. Fontdatei */ int16_t pt_cnt; /* Anzahl der Punkthöhen für vst_point */ int16_t pt_sizes[64]; /* verfügbare Punkthöhen */ } XFNT_INFO;
Hinweis: Damit die Informationen in die Struktur eingetragen werden, muß die Größe der Struktur in die Komponente size eingetragen werden.
Für die Komponente format gilt:
1 | = | Bitmap-Font |
2 | = | Speedo-Font |
4 | = | TrueType-Font |
8 | = | Type 1-Font |
Alle Zeichenketten sind null-terminierte Strings im C-Format. Strukturelemente die nicht angefordert wurden, haben keinen definierten Inhalt.
Querverweis: GEM NVDI vqt_xfntinfo