^1F.F.F.F.F.F.! (Find Fast Funds For Fancy Fonds) von LeidPen Eigene Schriften im Grafikmodus zu erzeugen ist ein beliebter Sport, wie die vielen Programme zeigen, die dafr erfunden wurden. Wer so etwas nur gelegent- lich tut und mit eigenen Mitteln auskommen will, wird in der Regel von einer der vorgegebenen Standardschriften ausgehen und diese lediglich modifizieren wollen. Die Frage ist dann, wie man an die Pixelmuster der Standardschriften herankommt. Weil in der Regel im Grafikmodus gearbeitet werden muá, bietet es sich an, die gewnschte Vorlage des Zeichens zun„chst an einer unauff„lligen Stelle auf den Bildschirm zu bringen (in Basic z.B. mit PRINT), und das Muster pixelweise abzutasten, wozu in Basic die Funktion POINT(x,y) zur Verfgung steht. Fr die weitere Verarbeitung kann man die Abtastwerte in einem Feld speichern. Ein Beispiel dafr ist das Programm "Text mit Farbverlauf" von The Real Adok. Es geht aber auch anders. MS-DOS (jedenfalls Version 5.0) stellt n„mlich in der Datei \DOS\EGA.CPI die Pixelmuster aller eingebauten Schriften zur Verf- gung. Man braucht sie also nicht erst auf den Bildschirm holen, sondern kann sie direkt auslesen. Dazu ”ffnet man EGA.CPI als Bin„rdatei mit Direktzugriff und liest sie Byte fr Byte. Jedes Byte enth„lt das Pixelmuster fr genau eine Punktzeile (8 Pixel) eines bestimmten Zeichens in einer der drei Schriftarten 8*16, 8*14 und 8*8. Ein Beispiel dafr bietet das folgende QBasic-Programm. ^0'DOSFONTS.BAS ^0'Liest Pixelmuster der ASCII-Zeichen aus der Datei DOS\EGA.CPI ^0'und schreibt sie im Textmodus vergr”áert auf den Bildschirm ^0'Autor: Roland Heer ^0'Sprache: QBasic ^0'Stand: 18.9.96 ^0'------------------------------------------------------------- ^0DEFINT A-Z ^0DECLARE SUB Pixel (ascii, x, y) ^0SCREEN 0 ^0CLS ^0start: ^0INPUT " Font 8*16(1) 8*14(2) 8*8(3) 1/2/3 ? ", font ^0'zhoehe = Zeichenh”he in Pixeln ^0'offset = erstes Byte des Pixelmusters von CHR$(0) ^0SELECT CASE font ^0CASE 1 '8*16 beginnt bei Byte Nr. 65 ^0 zhoehe = 16 ^0 offset = 65 ^0CASE 2 '8*14 beginnt bei Byte Nr. 4167 ^0 zhoehe = 14 ^0 offset = 256 * 16 + 71 ^0CASE 3 '8*8 beginnt bei Byte Nr. 7757 ^0 zhoehe = 8 ^0 offset = 256 * 16 + 256 * 14 + 77 ^0CASE ELSE ^0 LOCATE 1, 1: PRINT " Falsche Eingabe"; TAB(80); ^0 GOTO start ^0END SELECT ^0zchzhl = 10 'Zahl der gleichzeitig dargestellten Zeichen ^0'** Die Pixelmuster werden im Feld inbyte() gespeichert ^0DIM inbyte(1 TO zhoehe, 1 TO zchzhl) AS STRING * 1 ^0DO ^0 INPUT " Lies ab CHR$(n): n = ", anf ^0 anf = anf * zhoehe + offset ^0'** Zeichen lesen ^0 OPEN "c:\dos\ega.cpi" FOR BINARY AS #1 ^0 FOR j = 1 TO zchzhl ^0 FOR i = 1 TO zhoehe ^0 GET #1, anf + i + (j - 1) * zhoehe, inbyte(i, j) ^0 NEXT i ^0 NEXT j ^0 CLOSE ^0'** Zeichen schreiben ^0 WIDTH 80, 50 ^0 FOR j = 1 TO zchzhl ^0 FOR i = 1 TO zhoehe ^0 ascii = ASC(inbyte(i, j)) ^0 CALL Pixel(ascii, 7 + (j - 1) * 8, i) ^0 NEXT i ^0 NEXT j ^0 LOCATE 49, 1 ^0 PRINT " Weiter mit beliebiger Taste oder fr Abbruch"; ^0 DO: key$ = INKEY$ ^0 LOOP UNTIL LEN(key$) ^0 WIDTH 80, 25 ^0 IF key$ = CHR$(27) THEN SYSTEM ^0LOOP ^0END ^0DEFINT A - Z ^0SUB Pixel (ascii, x, y) ^0'** Wandelt ascii in Bin„rzahl und setzt entsprechende Zeichen ^0 FOR i = 0 TO 7 ^0 bit = ascii MOD 2 ^0 LOCATE y + 1, x + 1 - i ^0 IF bit THEN PRINT "Û" ELSE PRINT "ù" ^0 ascii = ascii \ 2 ^0 NEXT i ^0END SUB "Suchet, so werdet ihr finden!" - und wieder mal hat die Bibel recht: im Bios- Segment C000h wird man fndig. Dort hat mein Phoenix (-Bios) seine Eier ver- steckt, n„mlich die Fonts fr 8*8, 8*14 und 8*16. Sogar zwei Kuckuckseier sind darunter: Fonts, die sich nur als 8*15 bzw. 8*17 auslesen lassen, und die fr 9*14- und 9*16-Matrizen miábraucht werden. Um diese Eier auszubrten, muá man sie erst mal gefunden haben. Es steht aber nirgends geschrieben, daá einer sie selber suchen muá. Dafr hat man schlieálich sein Personal - in diesem Falle den Interrupt 10h, Funktion 11h, Unterfunktion 30h, der im Register ES das Segment und im Register BP den Offset im Speicher verr„t, wo der gew„hlte Zei- chensatz beginnt (siehe Programm F1130.BAS). šbrigens sind die Kuckuckseier gr”átenteils hohl, denn sie enthalten nur solche Zeichen, die sich nicht aus den 8*x - Fonts durch Wiederholung der letzten Spalte darstellen lassen. Und so kann man es in Quick Basic ausprobieren: ^0'BIOSFONT.BAS ^0'Liest Pixelmuster der ASCII-Zeichen aus dem Speicher ^0'und schreibt sie im Textmodus vergr”áert auf den Bildschirm ^0'Autor: Roland Heer ^0'Sprache: Quick Basic ^0'Stand: 1.11.96 ^0'Public Domain ^0'------------------------------------------------------------- ^0'$INCLUDE: 'qb.bi' ^0DEFINT A-Z ^0DECLARE SUB Pixel (byte, x, y) ^0DIM Regs AS RegTypeX ^0Regs.ax = &H1130 'INT 10h: Funktion 11h, Unterfunktion 30h ^0 'Segment (ES) und Offset (BP) des ersten ^0 'Zeichens von dem in BH angegebenen BIOS- ^0 'Font ermitteln ^0SCREEN 0: CLS ^0FOR i = 2 TO 7 ^0 Regs.bx = i * 256 ^0 CALL INTERRUPTX(&H10, Regs, Regs) ^0 offset(i) = Regs.bp 'Offset-Adressen speichern in offset() ^0NEXT i ^0start: ^0INPUT " Font 8*8(1) 8*14(2) 9*14(3) 8*16(4) 9*16(5) 1/2/3/4/5 ? ", font ^0'zhoehe = Zeichenh”he in Pixeln ^0'offset = erstes Byte vom Pixelmuster des ersten Zeichens ^0'a = Abstand bei 9*x-Matrix ^0'ende = Ende des Zeichensatzes (Anfang des n„chsten Fonts) ^0SELECT CASE font ^0CASE 0 ^0 SYSTEM ^0CASE 1 ^0 zhoehe = 8 ^0 offset = offset(3) - 1 ^0 a = 0 ^0 ende = offset(2) ^0CASE 2 ^0 zhoehe = 14 ^0 offset = offset(2) - 1 ^0 a = 0 ^0 ende = offset(5) ^0CASE 3 ^0 zhoehe = 15 ^0 offset = offset(5) - 1 ^0 a = 1 ^0 ende = offset(6) ^0CASE 4 ^0 zhoehe = 16 ^0 offset = offset(6) - 1 ^0 a = 0 ^0 ende = offset(7) ^0CASE 5 ^0 zhoehe = 17 ^0 offset = offset(7) ^0 a = 1 ^0 ende = offset(7) + 916 ^0CASE ELSE ^0 LOCATE 1, 1: PRINT " Falsche Eingabe"; TAB(80); ^0 GOTO start ^0END SELECT ^0zchzhl = 10 'Zahl der gleichzeitig dargestellten Zeichen ^0'** Die Pixelmuster werden im Feld inbyte() gespeichert ^0REDIM inbyte(1 TO zhoehe, 1 TO zchzhl) ^0WIDTH 80, 50 ^0DO ^0'** Zeichen lesen ^0 DEF SEG = Regs.es ^0 FOR j = 1 TO zchzhl ^0 FOR i = 1 TO zhoehe ^0 inbyte(i, j) = PEEK(offset + i + (j - 1) * zhoehe) ^0 NEXT i ^0 NEXT j ^0 DEF SEG ^0'** Zeichen schreiben ^0 FOR j = 1 TO zchzhl - a ^0 FOR i = 1 TO zhoehe - a ^0 CALL Pixel(inbyte(i + a, j), 7 + (j - 1) * (8 + a), i) ^0 NEXT i ^0 NEXT j ^0 LOCATE 49, 1 ^0 PRINT " Weiter mit beliebiger Taste oder fr Abbruch"; ^0 DO: key$ = INKEY$ ^0 LOOP UNTIL LEN(key$) ^0 IF key$ = CHR$(27) THEN ^0 WIDTH 80, 25 ^0 SYSTEM ^0 END IF ^0 offset = offset + (zchzhl - a) * zhoehe ^0 IF offset > ende THEN ^0 WIDTH 80, 25 ^0 GOTO start ^0 END IF ^0LOOP ^0END ^0SUB Pixel (byte, x, y) ^0'** Wandelt byte in Bin„rzahl und setzt entsprechende Zeichen ^0 FOR i = 0 TO 7 ^0 bit = byte AND 1 ^0 LOCATE y + 1, x + 1 - i ^0 IF bit THEN PRINT "Û" ELSE PRINT "ù" ^0 byte = byte \ 2 ^0 NEXT i ^0END SUB ^4Also sprach LeidPen.