Metropoli BBS
VIEWER: fe.c MODE: TEXT (ASCII)
/*
 * Font editor for MICROCAD and FAX25 programs.
 *
 * Copyright 1991-1995 Dave Dunfield
 * All rights reserved.
 *
 * Permission granted for personal (non-commercial) use only.
 *
 * Compile command: cc fe -fop
 */
#include <stdio.h>
#include <video.h>
#include <file.h>

unsigned font[96][24];		/* Font buffer */

char *menu1[] = {			/* Termination menu */
	"Resume editing  ",
	"Save FONT & exit",
	"Quit/Don't save ",
	0 };

main(argc, argv)			/* Main program */
	int argc;
	char *argv[];
{
	unsigned cnum, cbuf[24], c, x, y, i, j;
	HANDLE fh;

	if(argc < 2)
		abort("Font Editor\n\nUse: FE <font file>\n\nCopyright 1991-1995 Dave Dunfield\nAll rights reserved.\n");

	for(i=0; i < 24; ++i)
		cbuf[i] = 0;
	memset(font, x = y = cnum = 0, sizeof(font));

	vopen();

	vgotoxy(40, 4); vprintf("File: '%s'", argv[1]);
	if(fh = open(argv[1], F_READ)) {
		read(font, sizeof(font), fh);
		close(fh);
		reverse(); }
	else {
		vputs("  ** NEW **"); }

	vgotoxy(40,  6); vputs("Space   = Toggle bit value");
	vgotoxy(40,  7); vputs("Home    = Clear character");
	vgotoxy(40,  8); vputs("PgDn    = Next character");
	vgotoxy(40,  9); vputs("Pgup    = Previous character");
	vgotoxy(40, 10); vputs("F1      = Shift line left");
	vgotoxy(40, 11); vputs("F2      = Shift line right");
	vgotoxy(40, 12); vputs("F3      = Goto character");
	vgotoxy(40, 13); vputs("ESC     = Undo changes");
	vgotoxy(40, 14); vputs("End     = Exit FONT editor");

	memcpy(cbuf, font[cnum], sizeof(cbuf));

top:	/* Draw the initial character */
	for(i=0; i < 24; ++i) {
		vgotoxy(0, i);
		vprintf("%2u  ", i+1);
		c = cbuf[i];
		for(j=0; j < 16; ++j) {
			vputs(c & 0x8000 ? "\xDB\xDB" : "\xFA ");
			c <<= 1; } }
	vgotoxy(8, 24); vprintf("Char ID = %-2u, '", cnum);
	vputc(cnum+' ' | 0xFF00); vprintf("' (%02x)", cnum+' ');

	/* Edit the matrix */
	vcursor_off();
	for(;;) {
		vgotoxy(x+x+4, y);
		vputs((i = cbuf[y] & (0x8000 >> x)) ? "\xB2\xB2" : "\xB0\xB0");
		vgotoxy(x+x+4, y);
		c = vgetc();
		vputs(i ? "\xDB\xDB" : "\xFA ");
		switch(c) {
			case _KUA :	y = y ? y-1 : 23;			break;
			case _KDA : y = (y >= 23) ? 0 : y+1;	break;
			case _KLA : x = x ? x-1 : 15;			break;
			case _KRA : x = (x >= 15) ? 0 : x+1;	break;
			case _KPU :
				memcpy(font[cnum], cbuf, sizeof(cbuf));
				memcpy(cbuf, font[cnum = cnum ? cnum-1 : 95], sizeof(cbuf));
				goto top;
			case _KPD :
				memcpy(font[cnum], cbuf, sizeof(cbuf));
				memcpy(cbuf, font[cnum = (cnum >= 95) ? 0 : cnum+1], sizeof(cbuf));
				goto top;
			case ' '  :
				vgotoxy(x+x+4, y);
				c = cbuf[y] ^= 0x8000 >> x;
				vputs(c & (0x8000 >> x) ? "\xDB\xDB" : "\xFA ");
				break;
			case _K1  : cbuf[y] <<= 1;	goto top;
			case _K2  : cbuf[y] >>= 1;	goto top;
			case _K3  :
				vgotoxy(40, 16);
				vputs("Enter character? ");
				vcursor_line();
				c = vgetc() - ' ';
				vcursor_off();
				vgotoxy(40, 16);
				vcleol();
				if(c > 95) {
					vputc(7);
					break; }
				memcpy(font[cnum], cbuf, sizeof(cbuf));
				cnum = c;
			case 0x1B :	memcpy(cbuf, font[cnum], sizeof(cbuf)); goto top;
			case _KHO : memset(cbuf, 0, sizeof(cbuf)); goto top;
			case _KEN :
				c = 0;
				vmenu(40, 16,menu1,-1,&c);
				switch(c) {
					case 1 :
						memcpy(font[cnum], cbuf, sizeof(cbuf));
						if(fh = open(argv[1], F_WRITE)) {
							reverse();
							write(font, sizeof(font), fh);
							close(fh); }
						else {
							vgotoxy(40, 24);
							vputs("Cannot open output file");
							break; }
					case 2 :
						vclscr();
						vcursor_line();
						return; } } }
}

/*
 * Reverse the font data to compensate for the "little endian"
 * architecture of the intel format unsigned data type.
 */
reverse()
{
	char *ptr, c;
	int i;

	ptr = (char *) font;
	for(i=0; i < sizeof(font); i += 2) {
		c = *ptr;
		*ptr = *++ptr;
		*ptr++ = c; }
}
[ RETURN TO DIRECTORY ]