927 lines
18 KiB
C
927 lines
18 KiB
C
/*
|
|
* 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
|
|
* $FreeBSD$
|
|
*/
|
|
|
|
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" );
|
|
}
|