diff options
author | Peter Wemm <peter@FreeBSD.org> | 1999-01-01 08:32:05 +0000 |
---|---|---|
committer | Peter Wemm <peter@FreeBSD.org> | 1999-01-01 08:32:05 +0000 |
commit | 5f809d76a37e5a2b0cfc87f568998827b4d41651 (patch) | |
tree | deb7cb2e3e206a42369d1644977a1a9b37d06846 /usr.sbin/pcvt/fontedit | |
parent | ff4c4cec98d4f22eeef23860e10747632f9a824f (diff) | |
download | src-5f809d76a37e5a2b0cfc87f568998827b4d41651.tar.gz src-5f809d76a37e5a2b0cfc87f568998827b4d41651.zip |
Part 4 of pcvt/voxware revival: pcvt userland
Reviewed by: core
Notes
Notes:
svn path=/head/; revision=42222
Diffstat (limited to 'usr.sbin/pcvt/fontedit')
-rw-r--r-- | usr.sbin/pcvt/fontedit/Makefile | 3 | ||||
-rw-r--r-- | usr.sbin/pcvt/fontedit/README | 36 | ||||
-rw-r--r-- | usr.sbin/pcvt/fontedit/fontedit.1 | 58 | ||||
-rw-r--r-- | usr.sbin/pcvt/fontedit/fontedit.c | 925 |
4 files changed, 1022 insertions, 0 deletions
diff --git a/usr.sbin/pcvt/fontedit/Makefile b/usr.sbin/pcvt/fontedit/Makefile new file mode 100644 index 000000000000..9cbe4e5a5b56 --- /dev/null +++ b/usr.sbin/pcvt/fontedit/Makefile @@ -0,0 +1,3 @@ +PROG= fontedit + +.include <bsd.prog.mk> diff --git a/usr.sbin/pcvt/fontedit/README b/usr.sbin/pcvt/fontedit/README new file mode 100644 index 000000000000..1854129b63d7 --- /dev/null +++ b/usr.sbin/pcvt/fontedit/README @@ -0,0 +1,36 @@ +When I first saw this posted to rn, I tried to compile this on a machine +running BSD UNIX. Much to my dissapointment, It said "unable to find +/usr/include/termio.h" and thus it sat for a couple months. I was able to +compile it on a 3b5, but I didn't have a vt220 hooked up to it. I was doing +some unrelated work with ioctl calls and finally realized that it would not be +too hard to convert it from System V to BSD. It also looked kind of strange +with the cursor on, so I turned this off. To implement this, compile with +the "-DCURFIX" flag in the Makefile. +I am working on a new version that uses curses and that would enable you to +change the file that your are working on without leaving the program. +I thought I'd post it as it is now, since it has a lot of uses right away. +Imagine changing your favorite game to have objects that look like what they +are instead of the regular characters. Also, I think people should post their +own character sets, if they come up with some neat stuff. + Please send any comments or suggestions to: + + UUCP : ..!harvard!bu-cs!bucsb!eap + ARPANET: eap@bucsb.bu.edu + CSNET : eap%bucsb@bu-cs + + Have fun, + + - Eric Pearce + Boston University + + + + + + + + + + + + diff --git a/usr.sbin/pcvt/fontedit/fontedit.1 b/usr.sbin/pcvt/fontedit/fontedit.1 new file mode 100644 index 000000000000..8b55edb46a6a --- /dev/null +++ b/usr.sbin/pcvt/fontedit/fontedit.1 @@ -0,0 +1,58 @@ +.TH FONTEDIT 1 LOCAL +.SH NAME +fontedit \- Edit fonts. +.SH SYNOPSIS +.B fontedit file +.SH DESCRIPTION +.I Fontedit +is used to edit the down line reloadable character set (DRCS) of a VT220 +terminal. The editor has two display areas, one for displaying the +entry currently being manipulated, and one for displaying the complete +DRCS. Commands to the editor take the form of function keys. +.PP +.I Fontedit +takes one command line parameter, a file name. This file is +used to save the character set. If the file exists when \fIfontedit\fP +is invoked, it is read in to initialize the DRCS. The file is written +to when \fIfontedit\fP exits. +.PP +Commands to fontedit take the form of function keys. The current +definitions are: +.IP \fBHELP\fP +Display a help screen. +.IP \fBF6\fP +Turn the pixel under the cursor on. +.IP \fBF7\fP +Turn the pixel under the cursor off. +.IP \fBF13\fP +Clear the display area. +.IP \fBFind\fP +Save the current font in the font table. Update the DRCS display. +.IP \fBSelect\fP +Extract the entry selected by the cursor in the DRCS display. +.IP \fBPrev\fP +Move the cursor to the previous entry in the DRCS display. +.IP \fBNext\fP +Move the cursor to the next entry in the DRCS display. +.IP \fBInsert\fP +Insert a blank line at the current cursor position. The bottom row is lost. +.IP \fBRemove\fP +Remove the row at the current cursor position. All rows below the +current one are shifted up. +.IP \fBCursors\fP +Move the cursor in the main display area. +.PP +If the screen gets garbled, press <control-L>. +.PP +To exit \fIfontedit\fP, press <control-D>. The DRCS will be saved in +\fIfile\fP. To exit without saving the DRCS, hit interrupt (usually +DEL). +.SH DIAGNOSTICS +.I Fontedit +will issue a warning when the entry being worked on is not saved, and +some potentially destructive command, like \fBSelect\fP is used. To +override the warning message, immediately reissue the command. +.SH AUTHOR +Greg Franks. + + diff --git a/usr.sbin/pcvt/fontedit/fontedit.c b/usr.sbin/pcvt/fontedit/fontedit.c new file mode 100644 index 000000000000..d9ed357c6e85 --- /dev/null +++ b/usr.sbin/pcvt/fontedit/fontedit.c @@ -0,0 +1,925 @@ +/* + * fontedit + * Fonteditor for VT220 + * + * BUGS: + * o Cursor motion is less than optimal (but who cares at 9600), + * + * COMPILE: + * cc -O fontedit.c -o fontedit + * (use Makefile) + * + * Copyright (c) 1987 by Greg Franks. + * + * Permission is granted to do anything you want with this program + * except claim that you wrote it. + * + * + * REVISION HISTORY: + * + * Nov 21, 1987 - Fixed man page to say "Fontedit" instead of "Top" + * Nov 22, 1987 - Added BSD Compatible ioctl, turned cursor on/off + * - eap@bucsf.bu.edu + */ + +void clear_screen(); +#include <stdio.h> +#ifdef SYSV +#include <sys/termio.h> +#endif SYSV +#ifdef BSD +#include <sys/ioctl.h> +#endif BSD +#if defined (__NetBSD__) || defined (__FreeBSD__) +#include <sys/termios.h> +#include <sys/ioctl.h> +#endif /* __NetBSD__ || __FreeBSD__ */ +#include <signal.h> + +#ifdef CURFIX +#define CURSORON "\033[?25h" +#define CURSOROFF "\033[?25l" +#endif CURFIX + +#define MAX_ROWS 10 +#define MAX_COLS 8 + +typedef enum { false, true } bool; + +#define KEY_FIND 0x0100 +#define KEY_INSERT 0x0101 +#define KEY_REMOVE 0x0102 +#define KEY_SELECT 0x0103 +#define KEY_PREV 0x0104 +#define KEY_NEXT 0x0105 +#define KEY_F6 0X0106 +#define KEY_F7 0x0107 +#define KEY_F8 0x0108 +#define KEY_F9 0x0109 +#define KEY_F10 0x010a +#define KEY_F11 0x010b +#define KEY_F12 0x010c +#define KEY_F13 0x010d +#define KEY_F14 0x010e +#define KEY_HELP 0x010f +#define KEY_DO 0x0110 +#define KEY_F17 0x0111 +#define KEY_F18 0x0112 +#define KEY_F19 0x0113 +#define KEY_F20 0x0114 +#define KEY_UP 0x0115 +#define KEY_DOWN 0x0116 +#define KEY_RIGHT 0x0117 +#define KEY_LEFT 0x0118 + +/* + * Position of main drawing screen. + */ + +#define ROW_OFFSET 3 +#define COL_OFFSET 10 + +/* + * Position of the DRCS table. + */ + +#define TABLE_ROW 4 +#define TABLE_COL 50 + +/* + * + */ + +#define ERROR_ROW 20 +#define ERROR_COL 40 + +bool display_table[MAX_ROWS][MAX_COLS]; + +#define TOTAL_ENTRIES (128 - 32) +#define SIXELS_PER_CHAR 16 + +char font_table[TOTAL_ENTRIES][SIXELS_PER_CHAR]; +unsigned int current_entry; + +#ifdef SYSV +struct termio old_stty, new_stty; +#endif SYSV +#ifdef BSD +struct sgttyb old_stty, new_stty; +#endif BSD +#if defined (__NetBSD__) || defined (__FreeBSD__) +struct termios old_stty, new_stty; +#endif /* __NetBSD__ || __FreeBSD__ */ +FILE * font_file = (FILE *)0; + + +/* + * Interrupt + * Exit gracefully. + */ + +interrupt() +{ + void clear_screen(); +#ifdef CURFIX + printf("%s\n",CURSORON); +#endif CURFIX +#ifdef SYSV + ioctl( 0, TCSETA, &old_stty ); +#endif SYSV +#ifdef BSD + ioctl( 0, TIOCSETP, &old_stty ); +#endif BSD +#if defined (__NetBSD__) || defined (__FreeBSD__) + ioctl( 0, TIOCSETA, &old_stty ); +#endif /* __NetBSD__ || __FreeBSD__ */ + clear_screen(); + exit( 0 ); +} + + +/* + * Main + * Grab input/output file and call main command processor. + */ + +main( argc, argv ) +int argc; +char *argv[]; +{ + void command(), init_restore(), clear_screen(); + void save_table(), get_table(), extract_entry(); + + if ( argc != 2 ) { + fprintf( stderr, "usage: fontedit filename\n" ); + exit( 1 ); + } + + printf( "Press HELP for help\n" ); + printf( "\033P1;1;2{ @\033\\" ); /* Clear font buffer */ + fflush( stdout ); + sleep( 1 ); /* Let terminal catch up */ + /* otherwise we get frogs */ + + if ( ( font_file = fopen( argv[1], "r" ) ) == (FILE *)0 ) { + if ( ( font_file = fopen( argv[1], "w" ) ) == (FILE *)0 ) { + fprintf( stderr, "Cannot create file %s \n", argv[1] ); + exit( 1 ); + } + } + fclose( font_file ); + + if ( ( font_file = fopen( argv[1], "r" ) ) != (FILE *)0 ) { + get_table( font_file ); + fclose( font_file ); + } + + if ( ( font_file = fopen( argv[1], "r+" ) ) == (FILE *)0 ) { + fprintf( stderr, "Cannot open %s for writing\n", argv[1] ); + exit( 1 ); + } +#ifdef CURFIX + printf("%s\n",CURSOROFF); +#endif CURFIX +#ifdef SYSV + ioctl( 0, TCGETA, &old_stty ); +#endif SYSV +#ifdef BSD + ioctl( 0, TIOCGETP, &old_stty ); +#endif BSD +#if defined (__NetBSD__) || defined (__FreeBSD__) + ioctl( 0, TIOCGETA, &old_stty ); +#endif /* __NetBSD__ || __FreeBSD__ */ + signal( SIGINT, (void *) interrupt ); + new_stty = old_stty; +#ifdef SYSV + new_stty.c_lflag &= ~ICANON; + new_stty.c_cc[VMIN] = 1; + ioctl( 0, TCSETA, &new_stty ); +#endif SYSV +#if defined (__NetBSD__) || defined (__FreeBSD__) + new_stty.c_lflag &= ~ICANON; + new_stty.c_lflag &= ~ECHO; + new_stty.c_cc[VMIN] = 1; + ioctl( 0, TIOCSETA, &new_stty ); +#endif /* __NetBSD__ || __FreeBSD__ */ +#ifdef BSD + new_stty.sg_flags |= CBREAK; + new_stty.sg_flags &= ~ECHO; + ioctl( 0, TIOCSETP, &new_stty ); +#endif BSD + current_entry = 1; + extract_entry( current_entry ); + init_restore(); + command(); +#ifdef SYSV + ioctl( 0, TCSETA, &old_stty ); +#endif SYSV +#ifdef BSD + ioctl( 0, TIOCSETP, &old_stty ); +#endif BSD +#if defined (__NetBSD__) || defined (__FreeBSD__) + ioctl( 0, TIOCSETA, &old_stty ); +#endif /* __NetBSD__ || __FreeBSD__ */ + clear_screen(); + + /* Overwrite the old file. */ + + fseek( font_file, 0L, 0 ); + save_table( font_file ); + fclose( font_file ); +#ifdef CURFIX + printf("%s\n",CURSORON); +#endif CURFIX +} + + + +/* + * Command + * Process a function key. + * + * The user cannot fill in slots 0 or 95 (space and del respecitively). + */ + +void +command() +{ + register int c; + register int row, col; + register int i, j; + bool change, error, override; + + void build_entry(), extract_entry(), send_entry(), print_entry(); + void highlight(), draw_current(), init_restore(), help(); + void warning(); + + change = false; + error = false; + override = false; + row = 0; col = 0; + highlight( row, col, true ); + + for ( ;; ) { + c = get_key(); + highlight( row, col, false ); /* turn cursor off */ + + if ( error ) { + move ( ERROR_ROW, ERROR_COL ); + printf( "\033[K" ); /* Clear error message */ + move ( ERROR_ROW+1, ERROR_COL ); + printf( "\033[K" ); /* Clear error message */ + error = false; + } else { + override = false; + } + + switch ( c ) { + + case KEY_FIND: /* update DRCS */ + if ( !change && !override ) { + warning( "No changes to save" ); + override = true; + error = true; + } else { + build_entry( current_entry ); + send_entry( current_entry ); + print_entry( current_entry, true ); + change = false; + } + break; + + case KEY_F6: /* Turn on pixel */ + change = true; + display_table[row][col] = true; + highlight( row, col, false ); + col = ( col + 1 ) % MAX_COLS; + if ( col == 0 ) + row = ( row + 1 ) % MAX_ROWS; + break; + + case KEY_F7: /* Turn off pixel */ + change = true; + display_table[row][col] = false; + highlight( row, col, false ); + col = ( col + 1 ) % MAX_COLS; + if ( col == 0 ) + row = ( row + 1 ) % MAX_ROWS; + break; + + case KEY_INSERT: /* Insert a blank row */ + change = true; + for ( j = 0; j < MAX_COLS; ++j ) { + for ( i = MAX_ROWS - 1; i > row; --i ) { + display_table[i][j] = display_table[i-1][j]; + } + display_table[row][j] = false; + } + draw_current(); + break; + + case KEY_REMOVE: /* Remove a row */ + change = true; + for ( j = 0; j < MAX_COLS; ++j ) { + for ( i = row; i < MAX_ROWS - 1; ++i ) { + display_table[i][j] = display_table[i+1][j]; + } + display_table[MAX_ROWS-1][j] = false; + } + draw_current(); + break; + + case KEY_F13: /* Clear buffer */ + if ( change && !override ) { + warning( "Changes not saved" ); + error = true; + override = true; + } else { + for ( j = 0; j < MAX_COLS; ++j ) { + for ( i = 0; i < MAX_ROWS; ++i ) { + display_table[i][j] = false; + } + } + draw_current(); + } + break; + + case KEY_SELECT: /* Select font from DRCS */ + if ( change && !override ) { + warning( "Changes not saved" ); + error = true; + override = true; + } else { + extract_entry( current_entry ); + draw_current(); + } + break; + + case KEY_PREV: /* Move to prev entry in DRCS */ + if ( change && !override ) { + warning( "Changes not saved" ); + override = true; + error = true; + } else { + print_entry( current_entry, false ); + current_entry = current_entry - 1; + if ( current_entry == 0 ) + current_entry = TOTAL_ENTRIES - 2; + print_entry( current_entry, true ); + } + break; + + case KEY_NEXT: /* Move to next entry in DRCS */ + if ( change && !override ) { + warning( "Changes not saved" ); + override = true; + error = true; + } else { + print_entry( current_entry, false ); + current_entry = current_entry + 1; + if ( current_entry == TOTAL_ENTRIES - 1 ) + current_entry = 1; + print_entry( current_entry, true ); + } + break; + + case KEY_UP: /* UP one row. */ + if ( row == 0 ) + row = MAX_ROWS; + row = row - 1; + break; + + case KEY_DOWN: /* Guess. */ + row = ( row + 1 ) % MAX_ROWS; + break; + + case KEY_RIGHT: + col = ( col + 1 ) % MAX_COLS; + break; + + case KEY_LEFT: + if ( col == 0 ) + col = MAX_COLS; + col = col - 1; + break; + + case KEY_HELP: /* Display helpful info */ + clear_screen(); + help(); + c = getchar(); + init_restore(); + break; + + case '\004': /* All done! */ + return; + + case '\f': /* Redraw display */ + init_restore(); + break; + + default: /* user is a klutzy typist */ + move ( ERROR_ROW, ERROR_COL ); + printf( "Unknown key: " ); + if ( c < 0x20 ) { + printf( "^%c", c ); + } else if ( c < 0x0100 ) { + printf( "%c", c ); + } else { + printf( "0x%04x", c ); + } + fflush( stdout ); + error = true; + } + + highlight( row, col, true ); /* turn cursor on */ + } +} + + + +char *key_table[] = { + "\033[1~", /* Find */ + "\033[2~", /* Insert */ + "\033[3~", /* Remove */ + "\033[4~", /* Select */ + "\033[5~", /* Prev */ + "\033[6~", /* Next */ + "\033[17~", + "\033[18~", + "\033[19~", + "\033[20~", + "\033[21~", + "\033[23~", + "\033[24~", + "\033[25~", + "\033[26~", + "\033[28~", + "\033[29~", + "\033[31~", + "\033[32~", + "\033[33~", + "\033[34~", + "\033[A", + "\033[B", + "\033[C", + "\033[D", + (char *)0 }; + +/* + * get_key + * Convert VT220 escape sequence into something more reasonable. + */ + +int +get_key() +{ + register char *p; + char s[10]; + register int i, j; + + p = s; + for ( i = 0; i < 10; ++i ) { + *p = getchar(); + if ( i == 0 && *p != '\033' ) + return( (int)*p ); /* Not an escape sequence */ + if ( *p != '\033' && *p < 0x0020 ) + return( (int)*p ); /* Control character */ + *++p = '\0'; /* Null terminate */ + for ( j = 0; key_table[j]; ++j ) { + if ( strcmp( s, key_table[j] ) == 0 ) { + return( j | 0x0100 ); + } + } + } + return( -1 ); +} + + + +/* + * pad + * Emit nulls so that the terminal can catch up. + */ + +pad() +{ + int i; + + for ( i = 0; i < 20; ++i ) + putchar( '\000' ); + fflush( stdout ); +} + + + +/* + * init_restore + * refresh the main display table. + */ + +void +init_restore() +{ + register int row, col; + register int i; + + void draw_current(), clear_screen(), print_entry(); + + clear_screen(); + + for ( col = 0; col < MAX_COLS; ++col ) { + move( ROW_OFFSET - 2, col * 3 + COL_OFFSET + 1 ); + printf( "%d", col ); + } + move( ROW_OFFSET - 1, COL_OFFSET ); + printf( "+--+--+--+--+--+--+--+--+" ); + move( ROW_OFFSET + MAX_ROWS * 2, COL_OFFSET ); + printf( "+--+--+--+--+--+--+--+--+" ); + + for ( row = 0; row < MAX_ROWS; ++row ) { + if ( row != 0 && row != 7 ) { + move( row * 2 + ROW_OFFSET, COL_OFFSET - 2 ); + printf( "%d|", row ); + move( row * 2 + ROW_OFFSET + 1, COL_OFFSET - 1 ); + printf( "|" ); + move( row * 2 + ROW_OFFSET, COL_OFFSET + MAX_COLS * 3 ); + printf( "|" ); + move( row * 2 + ROW_OFFSET + 1, COL_OFFSET + MAX_COLS * 3 ); + printf( "|" ); + } else { + move( row * 2 + ROW_OFFSET, COL_OFFSET - 2 ); + printf( "%d*", row ); + move( row * 2 + ROW_OFFSET + 1, COL_OFFSET - 1 ); + printf( "*" ); + move( row * 2 + ROW_OFFSET, COL_OFFSET + MAX_COLS * 3 ); + printf( "*" ); + move( row * 2 + ROW_OFFSET + 1, COL_OFFSET + MAX_COLS * 3 ); + printf( "*" ); + } + } + draw_current(); + + move( TABLE_ROW - 1, TABLE_COL - 1 ); + printf( "+-+-+-+-+-+-+-+-+-+-+-+-+" ); + move( TABLE_ROW + 8 * 2 - 1, TABLE_COL - 1 ); + printf( "+-+-+-+-+-+-+-+-+-+-+-+-+" ); + for ( i = 0; i < 8; ++i ) { + move ( TABLE_ROW + i * 2, TABLE_COL - 1 ); + printf( "|" ); + move ( TABLE_ROW + i * 2 + 1, TABLE_COL - 1 ); + printf( "+" ); + move ( TABLE_ROW + i * 2, TABLE_COL + 12 * 2 - 1); + printf( "|" ); + move ( TABLE_ROW + i * 2 + 1, TABLE_COL +12 * 2 - 1); + printf( "+" ); + } + for ( i = 0; i < TOTAL_ENTRIES; ++i ) + print_entry( i, (i == current_entry) ? true : false ); +} + + + +/* + * draw_current + * Draw the complete current entry. + */ + +void +draw_current() +{ + register int row, col; + + printf( "\033)0" ); /* Special graphics in G1 */ + printf( "\016" ); /* Lock in G1 (SO) */ + + for ( row = 0; row < MAX_ROWS; ++row ) { + for ( col = 0; col < MAX_COLS; ++col ) { + if ( display_table[row][col] ) { + move( row * 2 + ROW_OFFSET, col * 3 + COL_OFFSET ); + printf( "\141\141\141" ); + move( row * 2 + ROW_OFFSET + 1, col * 3 + COL_OFFSET ); + printf( "\141\141\141" ); + } else { + move( row * 2 + ROW_OFFSET, col * 3 + COL_OFFSET ); + printf( " " ); /* erase splat */ + move( row * 2 + ROW_OFFSET + 1, col * 3 + COL_OFFSET ); + printf( " " ); /* erase splat */ + } + } + pad(); + } + printf( "\017" ); /* Lock in G0 (SI) */ + fflush( stdout ); +} + + + +/* + * highlight + * Draw the cursor in the main display area. + */ + +void +highlight( row, col, on ) +unsigned int row, col; +bool on; +{ + + printf( "\033)0" ); /* Special graphics in G1 */ + printf( "\016" ); /* Lock in G1 (SO) */ + if ( on ) { + printf( "\033[7m" ); /* Reverse video cursor */ + } + + if ( display_table[row][col] ) { + move( row * 2 + ROW_OFFSET, col * 3 + COL_OFFSET ); + printf( "\141\141\141" ); + move( row * 2 + ROW_OFFSET + 1, col * 3 + COL_OFFSET ); + printf( "\141\141\141" ); + } else { + move( row * 2 + ROW_OFFSET, col * 3 + COL_OFFSET ); + printf( " " ); /* erase splat */ + move( row * 2 + ROW_OFFSET + 1, col * 3 + COL_OFFSET ); + printf( " " ); /* erase splat */ + } + pad(); + printf( "\017" ); /* Lock in G0 (SI) */ + printf( "\033[0m" ); /* normal video */ + printf( "\b" ); /* Back up one spot */ + fflush( stdout ); +} + + + +/* + * Clear_screen + */ + +void +clear_screen() +{ + printf( "\033[H\033[J" ); /* Clear screen. */ + fflush( stdout ); +} + + + +/* + * move + */ + +move( y, x ) +int y, x; +{ + printf( "\033[%d;%df", y, x ); +} + + + +/* + * Build_entry + * Convert the bit pattern used in the main display area into something + * that the vt220 can digest - namely sixels... + */ + +void +build_entry( entry_no ) +unsigned int entry_no; +{ + register int row, col; + register unsigned int mask; + + for ( col = 0; col < 8; ++col ) { + + /* Top set of sixels */ + + mask = 0; + for ( row = 5; row >= 0; --row ) { + mask = mask << 1; + if ( display_table[row][col] ) + mask |= 1; + } + font_table[entry_no][col] = mask + 077; + + /* Bottom set of sixels */ + + mask = 0; + for ( row = 9; row >= 6; --row ) { + mask = mask << 1; + if ( display_table[row][col] ) + mask |= 1; + } + font_table[entry_no][col+8] = mask + 077; + } + +} + + + +/* + * Extract_engry + * convert sixel representation into an array of bits. + */ + +void +extract_entry( entry_no ) +unsigned int entry_no; +{ + register int row, col; + register unsigned int mask; + + for ( col = 0; col < 8; ++col ) { + + /* Top set of sixels */ + + mask = font_table[entry_no][col]; + if ( mask >= 077 ) + mask -= 077; + else + mask = 0; /* Bogus entry */ + + for ( row = 0; row <= 5; ++row ) { + display_table[row][col] = (bool)(mask & 0x0001); + mask = mask >> 1; + } + + /* Bottom set of sixels */ + + mask = font_table[entry_no][col+8]; + if ( mask >= 077 ) + mask -= 077; + else + mask = 0; + + for ( row = 6; row <= 9; ++row ) { + display_table[row][col] = (bool)(mask & 0x0001); + mask = mask >> 1; + } + } + +} + + + +/* + * Send_entry + * Emit the stuff used by the VT220 to load a character into the + * DRCS. We could, of course, send more than one entry at a time... + */ + +void +send_entry( entry_no ) +int entry_no; +{ + register char *fp = font_table[entry_no]; + + printf( "\033P1;%d;1;0;0;0{ @%c%c%c%c%c%c%c%c/%c%c%c%c%c%c%c%c\033\\", + entry_no, + fp[ 0], fp[ 1], fp[ 2], fp[ 3], fp[ 4], fp[ 5], fp[ 6], fp[ 7], + fp[ 8], fp[ 9], fp[10], fp[11], fp[12], fp[13], fp[14], fp[15] ); +} + + + +/* + * Print_entry + * The terminal normally has G0 in GL. We don't want to change + * this, nor do we want to use GR. Sooooo send out the necessary + * magic for shifting in G2 temporarily for the character that we + * want to display. + */ + +void +print_entry( entry_no, highlight ) +register unsigned int entry_no; +bool highlight; +{ + + register int y, x; + + y = entry_no & 0x07; + x = entry_no >> 3 & 0x1f; + entry_no += 32; /* Map up to G set */ + + move( y * 2 + TABLE_ROW, x * 2 + TABLE_COL ); + + if ( highlight ) + printf( "\033[7m" ); + + printf( "\033* @" ); /* select DRCS into G2 */ + printf( "\033N" ); /* select single shift */ + printf( "%c", entry_no ); /* Draw the character */ + + if ( highlight ) + printf( "\033[0m" ); +} + + + +/* + * Save_table + * Save a font table + */ + +void +save_table( font_file ) +FILE *font_file; +{ + register char *fp; + register int i; + + for ( i = 0; i < TOTAL_ENTRIES; ++i ) { + fp = font_table[i]; + 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", + i, + fp[ 0], fp[ 1], fp[ 2], fp[ 3], fp[ 4], fp[ 5], fp[ 6], fp[ 7], + fp[ 8], fp[ 9], fp[10], fp[11], fp[12], fp[13], fp[14], fp[15] ); + } +} + + + +/* + * Get_table + * Extract font table entries from a file + */ + +void +get_table( font_file ) +FILE *font_file; +{ + char s[256]; + register char *p; + char *fp; + int i; + register int j; + + while( fgets( s, 255, font_file ) ) { + if ( strncmp( s, "\033P1;", 4 ) != 0 ) + continue; /* Bogus line */ + p = &s[4]; + if ( sscanf( p, "%d", &i ) != 1 ) + continue; /* Illegal entry number */ + + if ( i <= 0 || TOTAL_ENTRIES <= i ) + continue; /* Bogues entry */ + + fp = font_table[i]; + + while ( *p && *p != '@' ) + ++p; /* Skip to font definition */ + if ( ! *p++ ) + continue; /* Skip @ */ + + for ( j = 0; *p && *p != '\033' && j < 16; ++j, ++p ) { + if ( *p == '/' ) { + j = 8; + ++p; + } + fp[j] = *p; + } + send_entry( i ); + } +} + + + +/* + * Help + * Print out help information. + */ + +void +help() +{ + printf( "Font editor\n\n" ); + printf( "F6 - Pixel on\n" ); + printf( "F7 - Pixel off\n" ); + printf( "F13 - Clear display area\n" ); + printf( "HELP - This screen\n" ); + printf( "FIND - Update font table\n" ); + printf( "INSERT - Insert a blank row\n" ); + printf( "REMOVE - Remove a row\n" ); + printf( "SELECT - Select current font table entry\n" ); + printf( "PREV - Move to previous font table entry\n" ); + printf( "NEXT - Move to next font table entry\n" ); + printf( "^D - Exit\n" ); + printf( "\n\n\n\nPress any key to continue\n" ); +} + + + +/* + * Warning + * Issue a warning to the regarding the current status. + */ + +void +warning( s ) +char *s; +{ + move( ERROR_ROW, ERROR_COL ); + printf( "Warning: %s!\n", s ); + move( ERROR_ROW+1, ERROR_COL ); + printf( " Reissue command to override\n" ); +} |