v13i076: Font edit program for VT220 terminals

Rich Salz rsalz at bbn.com
Wed Mar 2 10:01:45 AEST 1988


Submitted-by: "Eric A. Pearce" <eap at bucsf.bu.edu>
Posting-number: Volume 13, Issue 76
Archive-name: vt220fontedit


This screen-oriented program lets you edit downloaded fonts for the VT220
terminal.  This version runs on SysV and BSD.
                             - Eric Pearce, Boston University

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README Makefile fontedit.1 fontedit.c

PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f README -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(1482 characters\)
sed "s/^X//" >README <<'END_OF_README'
XWhen I first saw this posted to rn, I tried to compile this on a machine 
Xrunning BSD UNIX.  Much to my dissapointment, It said "unable to find
X/usr/include/termio.h" and thus it sat for a couple months.  I was able to
Xcompile it on a 3b5, but I didn't have a vt220 hooked up to it.  I was doing
Xsome unrelated work with ioctl calls and finally realized that it would not be
Xtoo hard to convert it from System V to BSD.  It also looked kind of strange
Xwith the cursor on, so I turned this off.  To implement this, compile with
Xthe "-DCURFIX" flag in the Makefile.  
XI am working on a new version that uses curses and that would enable you to 
Xchange the file that your are working on without leaving the program.  
XI thought I'd post it as it is now, since it has a lot of uses right away.
XImagine changing your favorite game to have objects that look like what they 
Xare instead of the regular characters.  Also, I think people should post their
Xown character sets, if they come up with some neat stuff. 
X             Please send any comments or suggestions to:
X                                                  
X                 UUCP   : ..!harvard!bu-cs!bucsb!eap
X                 ARPANET: eap at bucsb.bu.edu  
X                 CSNET  : eap%bucsb at bu-cs   
X                                        
X                                       Have fun,
X
X                                            - Eric Pearce
X                                              Boston University
X
X
X
X
X
X
X
X
X
X
X
X
END_OF_README
if test 1482 -ne `wc -c <README`; then
    echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefile\"
else
echo shar: Extracting \"Makefile\" \(222 characters\)
sed "s/^X//" >Makefile <<'END_OF_Makefile'
X# BSD   (new version, uses Berkeley specific ioctl calls) 
X# SYSV  (old version, uses System V specific ioctl calls)
X# CURFIX (turn off cursor on display)
Xfontedit : fontedit.c
X	cc fontedit.c -O -o fontedit -DBSD -DCURFIX
END_OF_Makefile
if test 222 -ne `wc -c <Makefile`; then
    echo shar: \"Makefile\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f fontedit.1 -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"fontedit.1\"
else
echo shar: Extracting \"fontedit.1\" \(1927 characters\)
sed "s/^X//" >fontedit.1 <<'END_OF_fontedit.1'
X.TH FONTEDIT 1 LOCAL
X.SH NAME
Xfontedit \- Edit fonts.
X.SH SYNOPSIS
X.B fontedit file
X.SH DESCRIPTION
X.I Fontedit
Xis used to edit the down line reloadable character set (DRCS) of a VT220
Xterminal.  The editor has two display areas, one for displaying the
Xentry currently being manipulated, and one for displaying the complete
XDRCS.  Commands to the editor take the form of function keys.
X.PP
X.I Fontedit 
Xtakes one command line parameter, a file name.  This file is
Xused to save the character set.  If the file exists when \fIfontedit\fP
Xis invoked, it is read in to initialize the DRCS.  The file is written
Xto when \fIfontedit\fP exits.
X.PP
XCommands to fontedit take the form of function keys.  The current
Xdefinitions are:
X.IP \fBHELP\fP
XDisplay a help screen.
X.IP \fBF6\fP
XTurn the pixel under the cursor on.
X.IP \fBF7\fP
XTurn the pixel under the cursor off.
X.IP \fBF13\fP
XClear the display area.
X.IP \fBFind\fP
XSave the current font in the font table.  Update the DRCS display.
X.IP \fBSelect\fP
XExtract the entry selected by the cursor in the DRCS display.
X.IP \fBPrev\fP
XMove the cursor to the previous entry in the DRCS display.
X.IP \fBNext\fP
XMove the cursor to the next entry in the DRCS display.
X.IP \fBInsert\fP
XInsert a blank line at the current cursor position.  The bottom row is lost.
X.IP \fBRemove\fP
XRemove the row at the current cursor position.  All rows below the
Xcurrent one are shifted up.
X.IP \fBCursors\fP
XMove the cursor in the main display area.
X.PP
XIf the screen gets garbled, press <control-L>.
X.PP
XTo exit \fIfontedit\fP, press <control-D>.  The DRCS will be saved in
X\fIfile\fP.  To exit without saving the DRCS, hit interrupt (usually
XDEL). 
X.SH DIAGNOSTICS
X.I Fontedit
Xwill issue a warning when the entry being worked on is not saved, and
Xsome potentially destructive command, like \fBSelect\fP is used.  To
Xoverride the warning message, immediately reissue the command.
X.SH AUTHOR
XGreg Franks.
X
X
END_OF_fontedit.1
if test 1927 -ne `wc -c <fontedit.1`; then
    echo shar: \"fontedit.1\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f fontedit.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"fontedit.c\"
else
echo shar: Extracting \"fontedit.c\" \(17714 characters\)
sed "s/^X//" >fontedit.c <<'END_OF_fontedit.c'
X/*
X * fontedit
X *	Fonteditor for VT220
X *
X *  BUGS:
X *	o Cursor motion is less than optimal (but who cares at 9600),
X *
X *  COMPILE:
X *	cc -O fontedit.c -o fontedit
X *      (use Makefile)
X *
X *	Copyright (c) 1987 by Greg Franks.
X *
X *	Permission is granted to do anything you want with this program
X *	except claim that you wrote it.
X *
X *
X *      REVISION HISTORY:
X *
X *      Nov 21, 1987 - Fixed man page to say "Fontedit" instead of "Top" 
X *      Nov 22, 1987 - Added BSD Compatible ioctl, turned cursor on/off
X *                     - eap at bucsf.bu.edu
X */
X
X#include <stdio.h>
X#ifdef SYSV
X#include <sys/termio.h>
X#endif SYSV
X#ifdef BSD
X#include <sys/ioctl.h>
X#endif BSD
X#include <signal.h>
X
X#ifdef CURFIX
X#define CURSORON  "\033[?25h"
X#define CURSOROFF "\033[?25l"
X#endif CURFIX
X
X#define	MAX_ROWS	10
X#define	MAX_COLS	8
X
Xtypedef enum { false, true } bool;
X
X#define	KEY_FIND 	0x0100
X#define	KEY_INSERT 	0x0101
X#define	KEY_REMOVE 	0x0102
X#define	KEY_SELECT 	0x0103
X#define	KEY_PREV 	0x0104
X#define	KEY_NEXT 	0x0105
X#define	KEY_F6		0X0106
X#define	KEY_F7		0x0107
X#define	KEY_F8		0x0108
X#define	KEY_F9		0x0109
X#define	KEY_F10		0x010a
X#define	KEY_F11		0x010b
X#define	KEY_F12		0x010c
X#define	KEY_F13		0x010d
X#define	KEY_F14		0x010e
X#define	KEY_HELP	0x010f
X#define	KEY_DO		0x0110
X#define	KEY_F17		0x0111
X#define	KEY_F18		0x0112
X#define	KEY_F19		0x0113
X#define	KEY_F20		0x0114
X#define	KEY_UP 		0x0115
X#define	KEY_DOWN 	0x0116
X#define	KEY_RIGHT 	0x0117
X#define	KEY_LEFT 	0x0118
X
X/*
X * Position of main drawing screen.
X */
X
X#define	ROW_OFFSET	3
X#define COL_OFFSET	10
X
X/* 
X * Position of the DRCS table.
X */
X
X#define	TABLE_ROW	4
X#define	TABLE_COL	50
X
X/*
X *
X */
X
X#define	ERROR_ROW	20
X#define ERROR_COL	40
X
Xbool	display_table[MAX_ROWS][MAX_COLS];
X
X#define	TOTAL_ENTRIES	(128 - 32)
X#define	SIXELS_PER_CHAR	16
X
Xchar	font_table[TOTAL_ENTRIES][SIXELS_PER_CHAR];
Xunsigned int	current_entry;
X
X#ifdef SYSV
Xstruct termio old_stty, new_stty;
X#endif SYSV
X#ifdef BSD
Xstruct sgttyb old_stty, new_stty;
X#endif BSD
X
XFILE * font_file = (FILE *)0;
X
X
X/*
X * Interrupt
X *	Exit gracefully.
X */
X
Xinterrupt()
X{
X	void clear_screen();
X#ifdef CURFIX
X        printf("%s\n",CURSORON);   
X#endif CURFIX   
X#ifdef SYSV
X	ioctl( 0, TCSETA, &old_stty );
X#endif SYSV
X#ifdef BSD
X        ioctl( 0, TIOCSETP, &old_stty );
X#endif BSD
X	clear_screen();
X	exit( 0 );
X}
X
X
X/*
X * Main
X *	Grab input/output file and call main command processor.
X */
X	
Xmain( argc, argv )
Xint argc;
Xchar *argv[];
X{
X	void command(), init_restore(), clear_screen();
X	void save_table(), get_table(), extract_entry();
X
X	if ( argc != 2 ) {
X		fprintf( stderr, "useage: fontedit filename\n" );
X		exit( 1 );
X	}
X
X	printf( "Press HELP for help\n" );
X	printf( "\033P1;1;2{ @\033\\" );	/* Clear font buffer	*/
X	fflush( stdout );
X	sleep( 1 );			/* Let terminal catch up	*/
X					/* otherwise we get frogs	*/
X
X	if ( ( font_file = fopen( argv[1], "r" ) ) != (FILE *)0 ) {
X		get_table( font_file );
X		fclose( font_file );
X	}
X
X	if ( ( font_file = fopen( argv[1], "r+" ) ) == (FILE *)0 ) {
X		fprintf( stderr, "Cannot open %s for writing\n", argv[1] );
X		exit( 1 );
X	}
X#ifdef CURFIX
X        printf("%s\n",CURSOROFF);
X#endif CURFIX
X#ifdef SYSV
X	ioctl( 0, TCGETA, &old_stty );
X#endif SYSV
X#ifdef BSD
X        ioctl( 0, TIOCGETP, &old_stty );
X#endif BSD
X	signal( SIGINT, interrupt );
X
X	new_stty = old_stty;
X#ifdef SYSV
X	new_stty.c_lflag &= ~ICANON;
X	new_stty.c_cc[VMIN] = 1;
X	ioctl( 0, TCSETA, &new_stty );
X#endif SYSV
X#ifdef BSD
X	new_stty.sg_flags |= CBREAK;               
X        new_stty.sg_flags &= ~ECHO;
X	ioctl( 0, TIOCSETP, &new_stty );
X#endif BSD
X	current_entry = 1;
X	extract_entry( current_entry );
X	init_restore();
X	command();
X#ifdef SYSV
X	ioctl( 0, TCSETA, &old_stty );
X#endif SYSV
X#ifdef BSD
X	ioctl( 0, TIOCSETP, &old_stty );
X#endif BSD
X	clear_screen();
X
X	/* Overwrite the old file. */
X
X	fseek( font_file, 0L, 0 );
X	save_table( font_file );
X	fclose( font_file );
X#ifdef CURFIX
X        printf("%s\n",CURSORON);
X#endif CURFIX
X}
X
X
X
X/*
X * Command
X *	Process a function key. 
X *
X *	The user cannot fill in slots 0 or 95 (space and del respecitively).
X */
X
Xvoid
Xcommand()
X{
X	register int c;
X	register int row, col;
X	register int i, j;
X	bool change, error, override;
X
X	void build_entry(), extract_entry(), send_entry(), print_entry();
X	void highlight(), draw_current(), init_restore(), help();
X	void warning();
X
X	change = false;
X	error = false;
X	override = false;
X	row = 0; col = 0;
X	highlight( row, col, true );
X
X	for ( ;; ) {
X		c = get_key();
X		highlight( row, col, false );	/* turn cursor off	*/
X
X		if ( error ) {
X			move ( ERROR_ROW, ERROR_COL );
X			printf( "\033[K" );		/* Clear error message	*/
X			move ( ERROR_ROW+1, ERROR_COL );
X			printf( "\033[K" );		/* Clear error message	*/
X			error = false;
X		} else {
X			override = false;
X		}
X
X		switch ( c ) {
X
X		case KEY_FIND:		/* update DRCS 	*/
X			if ( !change && !override ) {
X				warning( "No changes to save" );
X				override = true;
X				error = true;
X			} else {
X				build_entry( current_entry );
X				send_entry( current_entry );
X				print_entry( current_entry, true );
X				change = false;
X			}
X			break;
X
X		case KEY_F6:		/* Turn on pixel	*/
X			change = true;
X			display_table[row][col] = true;
X			highlight( row, col, false );
X			col = ( col + 1 ) % MAX_COLS;
X			if ( col == 0 )
X				row = ( row + 1 ) % MAX_ROWS;
X			break;
X
X		case KEY_F7:		/* Turn off pixel	*/
X			change = true;
X			display_table[row][col] = false;
X			highlight( row, col, false );
X			col = ( col + 1 ) % MAX_COLS;
X			if ( col == 0 )
X				row = ( row + 1 ) % MAX_ROWS;
X			break;
X
X		case KEY_INSERT:	/* Insert a blank row	*/
X			change = true;
X			for ( j = 0; j < MAX_COLS; ++j ) {
X				for ( i = MAX_ROWS - 1; i > row; --i ) {
X					display_table[i][j] = display_table[i-1][j];
X				}
X				display_table[row][j] = false;
X			}
X			draw_current();
X			break;
X	
X		case KEY_REMOVE:	/* Remove a row	*/
X			change = true;
X			for ( j = 0; j < MAX_COLS; ++j ) {
X				for ( i = row; i < MAX_ROWS - 1; ++i ) {
X					display_table[i][j] = display_table[i+1][j];
X				}
X				display_table[MAX_ROWS-1][j] = false;
X			}
X			draw_current();
X			break;
X
X		case KEY_F13:		/* Clear buffer	*/
X			if ( change && !override ) {
X				warning( "Changes not saved" );
X				error = true;
X				override = true;
X			} else {
X				for ( j = 0; j < MAX_COLS; ++j ) {
X					for ( i = 0; i < MAX_ROWS; ++i ) {
X						display_table[i][j] = false;
X					}
X				}
X				draw_current();
X			}
X			break;
X
X		case KEY_SELECT:	/* Select font from DRCS	*/
X			if ( change && !override ) {
X				warning( "Changes not saved" );
X				error = true;
X				override = true;
X			} else { 
X				extract_entry( current_entry );
X				draw_current();
X			}
X			break;
X
X		case KEY_PREV:		/* Move to prev entry in DRCS	*/
X			if ( change && !override ) {
X				warning( "Changes not saved" );
X				override = true;
X				error = true;
X			} else {
X				print_entry( current_entry, false );
X				current_entry = current_entry - 1;
X				if ( current_entry == 0 ) 
X					current_entry = TOTAL_ENTRIES - 2;
X				print_entry( current_entry, true );
X			}
X			break;
X
X		case KEY_NEXT:		/* Move to next entry in DRCS	*/
X			if ( change && !override ) {
X				warning( "Changes not saved" );
X				override = true;
X				error = true;
X			} else {
X				print_entry( current_entry, false );
X				current_entry = current_entry + 1;
X				if ( current_entry  == TOTAL_ENTRIES - 1 )
X					current_entry = 1;
X				print_entry( current_entry, true );
X			}
X			break;
X
X		case KEY_UP:		/* UP one row.			*/
X			if ( row == 0 )
X				row = MAX_ROWS;
X			row = row - 1;
X			break;
X
X		case KEY_DOWN:		/* Guess.			*/
X			row = ( row + 1 ) % MAX_ROWS;
X			break;
X
X		case KEY_RIGHT:
X			col = ( col + 1 ) % MAX_COLS;
X			break;
X
X		case KEY_LEFT:
X			if ( col == 0 ) 
X				col = MAX_COLS;
X			col = col - 1;
X			break;
X
X		case KEY_HELP:		/* Display helpful info		*/
X			clear_screen();
X			help();
X			c = getchar();
X			init_restore();
X			break;
X
X		case '\004':		/* All done!			*/
X			return;
X
X		case '\f':		/* Redraw display		*/
X			init_restore();
X			break;
X
X		default:		/* user is a klutzy  typist	*/
X			move ( ERROR_ROW, ERROR_COL );
X			printf( "Unknown key: " );
X			if ( c < 0x20 ) {
X				printf( "^%c", c );
X			} else if ( c < 0x0100 ) {
X				printf( "%c", c );
X			} else {
X				printf( "0x%04x", c );
X			}
X			fflush( stdout );
X			error = true;
X		}
X
X		highlight( row, col, true );	/* turn cursor on	*/
X	}
X}
X
X
X
Xchar *key_table[]	= {
X	"\033[1~",		/* Find		*/
X	"\033[2~",		/* Insert	*/
X	"\033[3~",		/* Remove	*/
X	"\033[4~",		/* Select	*/
X	"\033[5~",		/* Prev		*/
X	"\033[6~",		/* Next		*/
X	"\033[17~",
X	"\033[18~",
X	"\033[19~",
X	"\033[20~",
X	"\033[21~",
X	"\033[23~",
X	"\033[24~",
X	"\033[25~",
X	"\033[26~",
X	"\033[28~",
X	"\033[29~",
X	"\033[31~",
X	"\033[32~",
X	"\033[33~",
X	"\033[34~",
X	"\033[A",
X	"\033[B",
X	"\033[C",
X	"\033[D",
X	(char *)0 };
X
X/*
X * get_key
X *	Convert VT220 escape sequence into something more reasonable.
X */
X
Xint
Xget_key()
X{
X	register char	*p;
X	char	s[10];
X	register int i, j;
X
X	p = s;
X	for ( i = 0; i < 10; ++i ) {
X		*p = getchar();
X		if ( i == 0 && *p != '\033' )
X			return( (int)*p );	/* Not an escape sequence */
X		if ( *p != '\033' && *p < 0x0020 )
X			return( (int)*p );	/* Control character	*/
X		*++p = '\0';			/* Null terminate	*/
X		for ( j = 0; key_table[j]; ++j ) {
X			if ( strcmp( s, key_table[j] ) == 0 )
X				return( j | 0x0100 );
X		}
X	}
X	return( -1 );
X}
X
X
X
X/*
X * pad
X *	Emit nulls so that the terminal can catch up.
X */
X
Xpad()
X{
X	int i;
X
X	for ( i = 0; i < 20; ++i )
X		putchar( '\000' );
X	fflush( stdout );
X}
X
X
X
X/*
X * init_restore
X *	refresh the main display table.
X */
X
Xvoid
Xinit_restore()
X{
X	register int row, col;
X	register int i;
X	
X	void  draw_current(), clear_screen(), print_entry();
X
X	clear_screen();
X
X	for ( col = 0; col < MAX_COLS; ++col ) {
X		move( ROW_OFFSET - 2, col * 3 + COL_OFFSET + 1 );
X		printf( "%d", col );
X	}
X	move( ROW_OFFSET - 1, COL_OFFSET );
X	printf( "+--+--+--+--+--+--+--+--+" );
X	move( ROW_OFFSET + MAX_ROWS * 2, COL_OFFSET );
X	printf( "+--+--+--+--+--+--+--+--+" );
X
X	for ( row = 0; row < MAX_ROWS; ++row ) {
X		if ( row != 0 && row != 7 )  {
X			move( row * 2 + ROW_OFFSET, COL_OFFSET - 2 );
X			printf( "%d|", row );
X			move( row * 2 + ROW_OFFSET + 1, COL_OFFSET - 1 );
X			printf( "|" );
X			move( row * 2 + ROW_OFFSET, COL_OFFSET + MAX_COLS * 3 );
X			printf( "|" );
X			move( row * 2 + ROW_OFFSET + 1, COL_OFFSET + MAX_COLS * 3 );
X			printf( "|" );
X		} else {
X			move( row * 2 + ROW_OFFSET, COL_OFFSET - 2 );
X			printf( "%d*", row );
X			move( row * 2 + ROW_OFFSET + 1, COL_OFFSET - 1 );
X			printf( "*" );
X			move( row * 2 + ROW_OFFSET, COL_OFFSET + MAX_COLS * 3 );
X			printf( "*" );
X			move( row * 2 + ROW_OFFSET + 1, COL_OFFSET + MAX_COLS * 3 );
X			printf( "*" );
X		}
X	}
X	draw_current();
X
X	move( TABLE_ROW - 1, TABLE_COL - 1 );
X	printf( "+-+-+-+-+-+-+-+-+-+-+-+-+" );
X	move( TABLE_ROW + 8 * 2 - 1, TABLE_COL - 1 );
X	printf( "+-+-+-+-+-+-+-+-+-+-+-+-+" );
X	for ( i = 0; i < 8; ++i ) {
X		move ( TABLE_ROW + i * 2, TABLE_COL - 1 );
X		printf( "|" );
X		move ( TABLE_ROW + i * 2 + 1, TABLE_COL - 1 );
X		printf( "+" );
X		move ( TABLE_ROW + i * 2, TABLE_COL + 12 * 2 - 1);
X		printf( "|" );
X		move ( TABLE_ROW + i * 2 + 1, TABLE_COL +12 * 2 - 1);
X		printf( "+" );
X	}	
X	for ( i = 0; i < TOTAL_ENTRIES; ++i )
X		print_entry( i, (i == current_entry) ? true : false );
X}
X
X
X
X/*
X * draw_current
X *	Draw the complete current entry.
X */
X
Xvoid
Xdraw_current()
X{
X	register int row, col;
X
X	printf( "\033)0" );		/* Special graphics in G1	*/
X	printf( "\016" );		/* Lock in G1 (SO)		*/
X
X	for ( row = 0; row < MAX_ROWS; ++row ) {
X		for ( col = 0; col < MAX_COLS; ++col ) {
X			if ( display_table[row][col] ) {
X				move( row * 2 + ROW_OFFSET,     col * 3 + COL_OFFSET );
X				printf( "\141\141\141" );
X				move( row * 2 + ROW_OFFSET + 1, col * 3 + COL_OFFSET );
X				printf( "\141\141\141" );
X			} else {
X				move( row * 2 + ROW_OFFSET,     col * 3 + COL_OFFSET );
X				printf( "   " ); 	/* erase splat	*/
X				move( row * 2 + ROW_OFFSET + 1, col * 3 + COL_OFFSET );
X				printf( "   " ); 	/* erase splat	*/
X			}
X		}
X		pad();
X	}
X	printf( "\017" );		/* Lock in G0 (SI)	*/
X	fflush( stdout );
X}
X
X
X
X/*
X * highlight
X *	Draw the cursor in the main display area.
X */
X 
Xvoid
Xhighlight( row, col, on )
Xunsigned int row, col;
Xbool on;
X{
X
X	printf( "\033)0" );		/* Special graphics in G1	*/
X	printf( "\016" );		/* Lock in G1 (SO)		*/
X	if ( on ) {
X		printf( "\033[7m" );	/* Reverse video cursor		*/
X	}
X
X	if ( display_table[row][col] ) {
X		move( row * 2 + ROW_OFFSET,     col * 3 + COL_OFFSET );
X		printf( "\141\141\141" );
X		move( row * 2 + ROW_OFFSET + 1, col * 3 + COL_OFFSET );
X		printf( "\141\141\141" );
X	} else {
X		move( row * 2 + ROW_OFFSET,     col * 3 + COL_OFFSET );
X		printf( "   " ); 	/* erase splat	*/
X		move( row * 2 + ROW_OFFSET + 1, col * 3 + COL_OFFSET );
X		printf( "   " ); 	/* erase splat	*/
X	}
X	pad();
X	printf( "\017" );		/* Lock in G0 (SI)	*/
X	printf( "\033[0m" );		/* normal video		*/
X	printf( "\b" );			/* Back up one spot	*/
X	fflush( stdout );
X}
X
X
X
X/*
X * Clear_screen
X */
X 
Xvoid
Xclear_screen()
X{
X	printf( "\033[H\033[J" );		/* Clear screen.	*/
X	fflush( stdout );
X}
X
X
X
X/*
X * move
X */
X
Xmove( y, x )
Xint y, x;
X{
X	printf( "\033[%d;%df", y, x );
X}
X
X
X
X/*
X * Build_entry
X *	Convert the bit pattern used in the main display area into something
X *	that the vt220 can digest - namely sixels...
X */
X 
Xvoid
Xbuild_entry( entry_no )
Xunsigned int entry_no;
X{
X	register int row, col;
X	register unsigned int mask;
X
X	for ( col = 0; col < 8; ++col ) {
X
X		/* Top set of sixels	*/
X
X		mask = 0;
X		for ( row = 5; row >= 0; --row ) {
X			mask = mask << 1;
X			if ( display_table[row][col] )
X				mask |= 1;
X		}
X		font_table[entry_no][col] = mask + 077;
X
X		/*  Bottom set of sixels	*/
X
X		mask = 0;
X		for ( row = 9; row >= 6; --row ) {
X			mask = mask << 1;
X			if ( display_table[row][col] )
X				mask |= 1;
X		}
X		font_table[entry_no][col+8] = mask + 077;
X	}
X		
X}
X
X
X
X/*
X * Extract_engry
X *	convert sixel representation into an array of bits.
X */
X
Xvoid
Xextract_entry( entry_no )
Xunsigned int entry_no;
X{
X	register int row, col;
X	register unsigned int mask;
X
X	for ( col = 0; col < 8; ++col ) {
X
X		/* Top set of sixels	*/
X
X		mask = font_table[entry_no][col];
X		if ( mask >= 077 ) 
X			mask -= 077;
X		else
X			mask = 0;		/* Bogus entry	*/
X
X		for ( row = 0; row <= 5; ++row ) {
X			display_table[row][col] = (bool)(mask & 0x0001);
X			mask = mask >> 1;
X		}
X
X		/*  Bottom set of sixels	*/
X
X		mask = font_table[entry_no][col+8];
X		if ( mask >= 077 )
X			mask -= 077;
X		else
X			mask = 0;
X
X		for ( row = 6; row <= 9; ++row ) {
X			display_table[row][col] = (bool)(mask & 0x0001);
X			mask = mask >> 1;
X		}
X	}
X		
X}
X
X
X
X/*
X * Send_entry
X *	Emit the stuff used by the VT220 to load a character into the
X *	DRCS.  We could, of course, send more than one entry at a time...
X */
X
Xvoid
Xsend_entry( entry_no )
Xint entry_no;
X{
X	register char *fp	= font_table[entry_no];
X
X	printf( "\033P1;%d;1;0;0;0{ @%c%c%c%c%c%c%c%c/%c%c%c%c%c%c%c%c\033\\", 
X		entry_no,
X		fp[ 0], fp[ 1], fp[ 2], fp[ 3], fp[ 4], fp[ 5], fp[ 6], fp[ 7],
X		fp[ 8], fp[ 9], fp[10], fp[11], fp[12], fp[13], fp[14], fp[15] );
X}
X
X
X
X/*
X * Print_entry
X *	The terminal normally has G0 in GL.  We don't want to change
X *	this, nor do we want to use GR.  Sooooo send out the necessary
X *	magic for shifting in G2 temporarily for the character that we
X *	want to display.
X */
X
Xvoid
Xprint_entry( entry_no, highlight )
Xregister unsigned int entry_no;
Xbool highlight;
X{
X
X	register int y, x;
X
X	y = entry_no & 0x07;
X	x = entry_no >> 3 & 0x1f;
X	entry_no += 32;			/* Map up to G set	*/
X
X	move( y * 2 + TABLE_ROW, x * 2 + TABLE_COL );
X
X	if ( highlight )
X		printf( "\033[7m" );
X
X	printf( "\033* @" );		/* select DRCS into G2	*/
X	printf( "\033N" );		/* select single shift	*/
X	printf( "%c", entry_no );	/* Draw the character	*/
X
X	if ( highlight )
X		printf( "\033[0m" );
X}
X
X
X
X/*
X * Save_table
X *	Save a font table
X */
X
Xvoid
Xsave_table( font_file )
XFILE *font_file;
X{
X	register char *fp;
X	register int i;
X
X	for ( i = 0; i < TOTAL_ENTRIES; ++i ) {
X		fp = font_table[i];
X		fprintf( font_file, "\033P1;%d;1;0;0;0{ @%c%c%c%c%c%c%c%c/%c%c%c%c%c%c%c%c\033\\\n", 
X			i, 
X			fp[ 0], fp[ 1], fp[ 2], fp[ 3], fp[ 4], fp[ 5], fp[ 6], fp[ 7],
X			fp[ 8], fp[ 9], fp[10], fp[11], fp[12], fp[13], fp[14], fp[15] );
X	}
X}
X
X
X
X/*
X * Get_table
X *	Extract font table entries from a file
X */
X
Xvoid
Xget_table( font_file )
XFILE *font_file;
X{
X	char	s[256];
X	register char	*p;
X	char	*fp;
X	int i;
X	register int j;
X
X	while( fgets( s, 255, font_file ) ) {
X		if ( strncmp( s, "\033P1;", 4 ) !=  0 ) 
X			continue;	/* Bogus line	*/
X		p = &s[4];
X		if ( sscanf( p, "%d", &i ) != 1 ) 
X			continue;	/* Illegal entry number	*/
X
X		if ( i <= 0 || TOTAL_ENTRIES <= i )
X			continue;	/* Bogues entry	*/
X
X		fp = font_table[i];
X
X		while ( *p && *p != '@' )
X			++p;		/* Skip to font definition */
X		if ( ! *p++ ) 
X			continue;	/* Skip @	*/
X
X		for ( j = 0; *p && *p != '\033' && j < 16; ++j, ++p ) {
X			if ( *p == '/' ) {
X				j = 8; 
X				++p;
X			}
X			fp[j] = *p;
X		}
X		send_entry( i );
X	}
X}
X
X
X
X/*
X * Help
X *	Print out help information.
X */
X 
Xvoid
Xhelp()
X{
X	printf( "Font editor\n\n" );
X	printf( "F6     - Pixel on\n" );
X	printf( "F7     - Pixel off\n" );
X	printf( "F13    - Clear display area\n" );
X	printf( "HELP   - This screen\n" );
X	printf( "FIND   - Update font table\n" );
X	printf( "INSERT - Insert a blank row\n" );
X	printf( "REMOVE - Remove a row\n" );
X	printf( "SELECT - Select current font table entry\n" );
X	printf( "PREV   - Move to previous font table entry\n" );
X	printf( "NEXT   - Move to next font table entry\n" );
X	printf( "^D     - Exit\n" );
X	printf( "\n\n\n\nPress any key to continue\n" );
X}
X
X
X
X/*
X * Warning
X *	Issue a warning to the regarding the current status.
X */
X
Xvoid
Xwarning( s )
Xchar *s;
X{
X	move( ERROR_ROW, ERROR_COL );
X	printf( "Warning: %s!\n", s );
X	move( ERROR_ROW+1, ERROR_COL );
X	printf( "         Reissue command to override\n" );
X}
END_OF_fontedit.c
if test 17714 -ne `wc -c <fontedit.c`; then
    echo shar: \"fontedit.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0

-- 
For comp.sources.unix stuff, mail to rsalz at uunet.uu.net.



More information about the Comp.sources.unix mailing list