home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS - Coast to Coast
/
simteldosarchivecoasttocoast2.iso
/
sprint
/
spfonts4.zip
/
SPFONTED.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-06-24
|
11KB
|
503 lines
/* SPFONTED - SPFONT Font Editor */
#include <stdio.h>
#include <fcntl.h>
#include <sys\stat.h>
#include <dos.h>
#ifdef RAMFONT
#define MAXFONTS 12
#define CHARSPERFONT 256
#define CHAROFFSET 0
#else
#define MAXFONTS 8
#define CHARSPERFONT 224
#define CHAROFFSET 32
#endif
#define MAXCHARHEIGHT 16
#define BLOCKSPERPIXEL 2
#define NORMAL 0x07
int charheight;
/***************************************************************************/
imax(int a, int b)
{
return((a > b) ? a : b);
}
/***************************************************************************/
static int VidRow, VidCol;
VidGotoRC(int row, int column)
{
VidRow = row;
VidCol = column;
_DX = (row * 256) + column;
_BX = 0;
_AH = 0x02;
geninterrupt(0x10);
}
VidClearScreen()
{
_BH = NORMAL;
_CX = 0x0000;
_DX = 0x184F;
_AX = 0x0600; /* scroll whole window = clear */
geninterrupt(0x10);
VidGotoRC(VidRow = 0, VidCol = 0);
}
/* Place a char at the current cursor position */
VidPlaceChr(int ch)
{
_BX = NORMAL;
_CX = 1;
_AX = ch;
_AH = 0x09;
geninterrupt(0x10);
}
/* Print a char. Supports backspace. */
VidPutChr(int ch)
{
if (ch == '\b')
{
if (0 < VidCol)
VidGotoRC(VidRow, --VidCol);
}
else
{
VidPlaceChr(ch);
VidGotoRC(VidRow, ++VidCol);
}
}
VidRptChr(int ch, int n)
{
while (0 < n--)
VidPutChr(ch);
}
VidPutStr(char *str)
{
while (*str)
{
VidPutChr(*str++);
}
}
VidBox(int upperrow, int leftcolumn, int lowerrow, int rightcolumn)
{
int r, c;
VidGotoRC(upperrow, leftcolumn); VidPlaceChr('┌');
for (c = leftcolumn+1; c <= rightcolumn-1; c++)
{ VidGotoRC(upperrow, c); VidPlaceChr('─'); }
VidGotoRC(upperrow, rightcolumn); VidPlaceChr('┐');
for (r = upperrow+1; r <= lowerrow-1; r++)
{ VidGotoRC(r, rightcolumn); VidPlaceChr('│'); }
VidGotoRC(lowerrow, rightcolumn); VidPlaceChr('┘');
for (c = rightcolumn-1; c >= leftcolumn+1; c--)
{ VidGotoRC(lowerrow, c); VidPlaceChr('─'); }
VidGotoRC(lowerrow, leftcolumn); VidPlaceChr('└');
for (r = lowerrow-1; r >= upperrow+1; r--)
{ VidGotoRC(r, leftcolumn); VidPlaceChr('│'); }
}
/***************************************************************************/
KbdGetch()
{
int key;
if ((key = getch()) == 0)
return(256 + getch());
else
return(key);
}
/* input up to n-1 characters into buf. backspace & del are the only
* editing characters. input is terminated by any control character
* (which is not echoed). returns the (effective) number of chars typed,
* or -1 if ESC was pressed.
*/
KbdGetStr(char *buf, int n)
{
char *bp;
int c;
bp = buf;
for (;;)
{
c = KbdGetch();
if (' ' <= c && c <= 0x7e)
{
if (bp < buf+n)
VidPutChr(*bp++ = c);
}
else if (c == '\b' || c == 0x7f)
{
if (buf < bp)
{
VidPutStr("\b \b");
bp--;
}
}
else if (c == '\r')
break;
else if (c == 0x1b)
{
buf[0] = '\0';
return(-1);
}
}
*bp = '\0';
return(bp - buf);
}
/* input a string, with default. return NULL is ESC pressed during entry */
char *
KbdAskStr(str, x, y, prompt, defalt, width)
char *str, *prompt, *defalt;
int x, y, width;
{
char def[80+1];
int len;
strcpy(def, defalt); /* save 'cause str & default may be the same */
VidGotoRC(x, y);
if (prompt)
{
VidPutStr(prompt);
if (*prompt)
VidPutStr(" ? ");
}
VidPutStr(def);
VidRptChr('_', imax(width-strlen(def), 0));
VidRptChr('\b', imax(strlen(def), width));
if ((len = KbdGetStr(str, width)) == -1)
return(NULL);
else if (len == 0)
{
strcpy(str, def);
VidPutStr(str);
}
VidRptChr(' ', imax(width-strlen(str), 0));
return(str);
}
/***************************************************************************/
#define ROWBASE 2
#define COLBASE 15
static int mask[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 } ;
FontPrintBackground()
{
int r;
VidClearScreen();
VidPutStr("SPFONTED - SPFONT Font Editor");
VidGotoRC(ROWBASE, 0); VidPutStr("Font");
VidGotoRC(ROWBASE+1, 0); VidPutStr("Char");
VidBox(ROWBASE, COLBASE, ROWBASE+charheight+1, COLBASE+(BLOCKSPERPIXEL*8)+1);
r = 0;
VidGotoRC(r++, 50); VidPutStr("Key Functions");
VidGotoRC(r++, 50); VidPutStr("");
VidGotoRC(r++, 50); VidPutStr("F next Font");
VidGotoRC(r++, 50); VidPutStr("");
VidGotoRC(r++, 50); VidPutStr("PgUp previous char");
VidGotoRC(r++, 50); VidPutStr("PgDn next char");
VidGotoRC(r++, 50); VidPutStr("");
VidGotoRC(r++, 50); VidPutChr(24); VidPutStr(" pixel up");
VidGotoRC(r++, 50); VidPutChr(27); VidPutStr(" pixel left");
VidGotoRC(r++, 50); VidPutChr(26); VidPutStr(" pixel right");
VidGotoRC(r++, 50); VidPutChr(25); VidPutStr(" pixel down");
VidGotoRC(r++, 50); VidPutStr("");
VidGotoRC(r++, 50); VidPutStr("Ins,+ pixel on");
VidGotoRC(r++, 50); VidPutStr("Del,- pixel off");
VidGotoRC(r++, 50); VidPutStr("space pixel toggle");
VidGotoRC(r++, 50); VidPutStr("");
VidGotoRC(r++, 50); VidPutStr("^Z Zap (clear) char");
VidGotoRC(r++, 50); VidPutStr("");
VidGotoRC(r++, 50); VidPutStr("W Write font file");
VidGotoRC(r++, 50); VidPutStr("ESC exit program");
}
FontTogglePixel(char *map, int r, int c)
{
map[r] = (map[r] ^ mask[c]);
FontPrintPixel(map, r, c);
}
FontClearPixel(char *map, int r, int c)
{
map[r] = (map[r] & ~mask[c]);
FontPrintPixel(map, r, c);
}
FontSetPixel(char *map, int r, int c)
{
map[r] = (map[r] | mask[c]);
FontPrintPixel(map, r, c);
}
FontPrintPixel(char *map, int r, int c)
{
VidGotoRC(ROWBASE+1+r, COLBASE+1+((7-c)*BLOCKSPERPIXEL));
VidPlaceChr((map[r] & mask[c]) ? 0xf : ' ');
}
FontPrintChar(int fnum, int cnum, char *map)
{
int r, c, i;
char work[10], pixch;
itoa(fnum, work, 10);
VidGotoRC(ROWBASE, 5+2); VidPutStr(work); VidPutStr(" ");
itoa(CHAROFFSET+cnum, work, 10);
VidGotoRC(ROWBASE+1, 5); VidPutStr(work); VidPutStr(" ");
for (r = 0; r < charheight; r++)
{
for (c = 7; 0 <= c; c--)
{
FontPrintPixel(map, r, c);
}
}
VidGotoRC(ROWBASE+1, COLBASE+1);
}
/***************************************************************************/
#define PROMPTLINE 21
#define STRINGSIZE 60
ClearPromptLine()
{
VidGotoRC(PROMPTLINE, 0);
VidRptChr(' ', 79);
VidGotoRC(PROMPTLINE, 0);
}
WriteFile(char *defname, char font[MAXFONTS][CHARSPERFONT][MAXCHARHEIGHT])
{
char fname[STRINGSIZE+1], *result;
int fd;
int fnt, chr;
result = KbdAskStr(fname, PROMPTLINE, 0, "Write to", defname, STRINGSIZE);
if (result == NULL)
{
ClearPromptLine();
return(0);
}
if ((fd = open(fname, O_WRONLY|O_CREAT|O_BINARY, S_IREAD|S_IWRITE)) < 0)
{
ClearPromptLine();
VidPutStr("can't create font file! press any key.");
KbdGetch();
return(0);
}
for (fnt = 0; fnt < MAXFONTS; fnt++)
for (chr = 0; chr < CHARSPERFONT; chr++)
{
if (write(fd, font[fnt][chr], charheight) != charheight)
{
ClearPromptLine();
VidPutStr("can't write font file! press any key.");
KbdGetch();
return(0);
}
}
close(fd);
ClearPromptLine();
VidPutStr("Saved! press any key.");
KbdGetch();
return(1);
}
main(int ac, char *av[])
{
char font[MAXFONTS][CHARSPERFONT][MAXCHARHEIGHT];
int fd;
struct stat fntstat;
int dirty, reprint;
char resp[1+1], *result;
int fnt, chr;
int byt, bit;
if (ac != 2)
{
fprintf(stderr, "usage: SPFONTED fontfile\n");
exit(1);
}
if ((fd = open(av[1], O_RDONLY|O_BINARY)) < 0)
{
fprintf(stderr, "can't open font file: %s\n", av[1]);
exit(2);
}
fstat(fd, &fntstat);
charheight = fntstat.st_size / (MAXFONTS*CHARSPERFONT);
for (fnt = 0; fnt < MAXFONTS; fnt++)
for (chr = 0; chr < CHARSPERFONT; chr++)
{
if (read(fd, font[fnt][chr], charheight) != charheight)
{
fprintf(stderr, "can't read font file\n");
exit(2);
}
}
close(fd);
dirty = 0;
FontPrintBackground();
fnt = 0; chr = 0;
reprint = 1;
for (;;)
{
if (reprint)
{
FontPrintChar(fnt, chr, font[fnt][chr]);
byt = 0; bit = 7;
reprint = 0;
}
switch (KbdGetch())
{
case 'F':
case 'f':
if (MAXFONTS <= ++fnt)
fnt = 0;
reprint = 1;
break;
case 256+81: /* PgDn */
if (CHARSPERFONT <= ++chr)
chr = 0;
reprint = 1;
break;
case 256+73: /* PgUp */
if (--chr < 0)
chr = CHARSPERFONT-1;
reprint = 1;
break;
case 0x1a: /* ^Z */
for (byt = 0; byt < charheight; byt++)
font[fnt][chr][byt] = '\0';
reprint = 1;
break;
case 0x04: /* ^D */
for (byt = charheight-2; 0 <= byt; byt--)
font[fnt][chr][byt+1] = font[fnt][chr][byt];
font[fnt][chr][0] = '\0';
reprint = 1;
break;
case 0x15: /* ^U */
for (byt = 0; byt <= charheight-2; byt++)
font[fnt][chr][byt] = font[fnt][chr][byt+1];
font[fnt][chr][charheight-1] = '\0';
reprint = 1;
break;
case 256+77: /* Right */
if (0 < bit)
bit--;
FontPrintPixel(font[fnt][chr], byt, bit);
break;
case 256+75: /* Left */
if (bit < 7)
bit++;
FontPrintPixel(font[fnt][chr], byt, bit);
break;
case 256+72: /* Up */
if (0 < byt)
byt--;
FontPrintPixel(font[fnt][chr], byt, bit);
break;
case 256+80: /* Down */
if (byt < (charheight-1))
byt++;
FontPrintPixel(font[fnt][chr], byt, bit);
break;
case ' ':
FontTogglePixel(font[fnt][chr], byt, bit);
dirty = 1;
break;
case 256+82: /* Ins */
FontSetPixel(font[fnt][chr], byt, bit);
dirty = 1;
break;
case 256+83: /* Del */
FontClearPixel(font[fnt][chr], byt, bit);
dirty = 1;
break;
case 'W':
case 'w':
if (WriteFile(av[1], font))
dirty = 0;
reprint = 1;
break;
case 0x1b:
if (dirty)
{
asksave: result = KbdAskStr(resp, PROMPTLINE, 0, "Font file has been modified, save it (Y/N)", "Y", 1);
if (result == NULL)
{
ClearPromptLine();
reprint = 1;
break;
}
else if (resp[0] == 'Y' || resp[0] == 'y')
{
if (WriteFile(av[1], font))
{
VidGotoRC(23, 0);
exit(0);
}
else
reprint = 1;
}
else if (resp[0] == 'N' || resp[0] == 'n')
{
VidGotoRC(23, 0);
exit(0);
}
else
goto asksave; /* so I'm a lousy programmer -- sue me! */
}
else
{
VidGotoRC(23, 0);
exit(0);
}
break;
}
}
}