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