fontbanner source
Marco Mercinelli
marco at cselt.UUCP
Tue Jan 7 20:56:06 AEST 1986
/* fontbanner 21/3/1985 */
/*
* fontbanner: print banners using UNIX fonts
*
* fontbanner [-vh] [-12] [-f font] [-d dir] [strings] ...
*
* Author: Marco Mercinelli (CSELT - IS) mcvax!i2unix!cselt!marco
*/
#define COPYRIGHT "fontbanner 1985 - by Marco Mercinelli, CSELT-IS (Italy)"
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <ctype.h>
#include <vfont.h>
#ifdef VFONT_MAGIC
short fontmagic = VFONT_MAGIC;
#else
short fontmagic = 0436;
#endif
#define DEFAULTDIR "/usr/lib/vfont"
#define DEFAULT_FONT "bocklin.14"
#define WHITE ' '
#define BLACK '#'
#define BLACK2 'O'
#define HALFRIGHT ')'
#define HALFLEFT '('
#define NEXT '\n'
#define MAXUNPRINTABLE 10 /* Max number of unprintable char (> \177) allowed */
char *USAGE="usage:fontbanner [-vh] [-12] [-f font] [-d dir] [strings] ...\n";
char fontsdir[256];
struct header FontHeader;
struct dispatch disptable[256] ;
int fontfd = -1; /* File descriptor del file font */
long fbase; /* Puntatore all'inizio delle bit map nel file */
short vertical = 0; /* Indica banner verticale o orizzontale */
short nochange = 1; /* Indica se e' cambiato il font corrente */
short fontchanged = 0; /* Indica se non e' stata data risposta a Font: */
char style = '1'; /* Stile di plottaggio ('1' o '2') */
short istty; /* Indica se stdout e' una tty */
char fontname[80]; /* Nome del font corrente */
short error = 0; /* Indica un errore nel caricamento di un font */
short defaultfdir = 1; /* Indica che la dir dei fonts e' DEFAULTFDIR */
short unprintable = 0; /* Caratteri non stampabili (> \177) incontrati */
char newline = '\n';
int interactive_mode = 1;
extern int errno;
char *gets(), *strcpy(), *strncpy(), *strcat(), *strncat(), *sprintf(),
*malloc(), *realloc(),
*listfonts();
long lseek();
main(argc,argv)
int argc;
char **argv;
{
fbase = sizeof(FontHeader)+sizeof(disptable);
*fontname = *fontsdir = '\0';
while ( --argc && (**++argv == '-') ) /* tratta argomenti */
getoptions(&argc, &argv);
interactive_mode = !argc; /* =1 se non ci sono stringhe da stampare */
istty = isatty(1);
if ( defaultfdir )
if ( accessdir(DEFAULTDIR) )
(void)strncpy(fontsdir, DEFAULTDIR, sizeof(fontsdir));
else {
fprintf(stderr,
".... Cannot open default fonts directory \"%s\"\n",
DEFAULTDIR);
if ( !interactive_mode )
exit(2);
*fontsdir = '\0';
defaultfdir = 0;
}
if ( interactive_mode )
interactive();
else
not_interactive(argc, argv);
if ( !istty )
printf("\n\n%s\f\n", COPYRIGHT);
} /* main */
/*- NOT INTERACTIVE COMMAND HANDLER -------------- ------------------------*/
not_interactive(argc, argv)
int argc;
char **argv;
{
register char *c;
if ( fontfd < 0 ){
if ( defaultfdir ){
/*
* CARICA FONT DI DEFAULT
*/
if ( (fontfd = load_font(DEFAULT_FONT)) < 0 ){
fprintf(stderr,
".... Cannot load default font \"%s\"\n", DEFAULT_FONT);
exit(4);
}
} else {
fprintf(stderr, ".... No font specified\n");
goto bad;
}
}
/*
* TRATTA ARGOMENTI RIMANENTI
*/
do {
if ( error ) /* errore nel caricamento del font specificato */
goto bad;
if ( *(c = *argv) != '-' ) {
/*
* E' UNA STRINGA DA PLOTTARE
*/
if ( *c == '\\' && ( c[1] == '-' || c[1] == '\\' ) )
/*
* '\' elimina il significato di '-' o '\'
*/
c++;
plot_string(c);
} else
getoptions(&argc, &argv);
argv++;
} while ( --argc );
bad:
fputs(USAGE, stderr);
exit(7);
} /* not_interactive */
/*-- INTERACTIVE COMMAND HANDLER --------------------------------------------*/
interactive()
{
register char *s;
char string[256];
int newfontfd;
short notify = 1;
if ( !*fontsdir )
(void)strcpy(fontsdir, ".");
fprintf(stderr, ".... Current fonts directory is \"%s\"\n", fontsdir);
if ( defaultfdir && !error && fontfd < 0 ){
/*
* Se non ho specificato nessun font come argomento
* cerca di caricare il font di default
*/
if ( (fontfd = load_font(DEFAULT_FONT)) < 0 ) {
fprintf(stderr, ".... Cannot load default font \"%s\"\n", DEFAULT_FONT);
*fontname = '\0';
} else {
(void)strcpy(fontname, DEFAULT_FONT);
}
}
for(;;){
if ( fontfd < 0 ){
fputs(".... Please choose a font file\n", stderr);
} else do {
/*
* NOTIFICA IL FONT CORRENTE E IL MODO DI STAMPA
* SE C'E' STATA UNA MODIFICA
*/
if ( notify ){
/* (void)fputc(newline, stderr); */
fputs("\n[ Current font is ", stderr);
if ( fontchanged )
fputs("now ", stderr);
if ( nochange ){
fputs("still ", stderr);
nochange = 0;
}
fprintf(stderr, "\"%s\",", fontname);
fprintf(stderr, " plot style %c ", style);
if ( style == '1' )
fputs("(compact),", stderr);
else
fputs("(accurate),", stderr);
if ( vertical )
fputs(" vertical", stderr);
else
fputs(" horizontal", stderr);
(void)fputs(" ]\n", stderr);
notify = 0;
}
/*
* CHIEDE MESSAGGIO
*/
fputs("Message : ", stderr);
if ( (s = gets(string)) == NULL ){
/*
* EOF: fine del lavoro
*/
(void)fputc(newline, stderr);
return;
}
if ( *s )
plot_string(s);
} while ( *s );
/*
* CHIEDE FONT
*/
askfont:
error = 0;
/* (void)fputc(newline, stderr); */
fputs("Font : ", stderr);
if ( (s = gets(string)) == NULL ){
/*
* EOF: fine del lavoro
*/
(void)fputc(newline, stderr);
return;
}
while ( isspace(*s) ) s++;
/*
* TRATTA LE OPZIONI
*/
while ( *s == '-' ) {
while ( *++s && !isspace(*s) ){ /* gruppo di opzioni */
switch ( *s ){
case 'v': /* VERTICAL */
if ( !vertical ){
vertical = 1;
notify = 1;
}
break;
case 'h': /* HORIZONTAL */
if ( vertical ){
vertical = 0;
notify = 1;
}
break;
case '1': /* PLOTTING STYLE 1/2 */
case '2':
if ( style != *s ){
style = *s;
notify = 1;
}
break;
case 'f': /* -f default */
break;
case 'd': /* CHANGE FONTS DIRECTORY */
/* elimina blanks */
for ( s++ ; *s && isspace(*s) ; s++ );
if ( !*s )
fputs(".... Missing fonts directory name\n", stderr);
else {
register char *d;
register int i;
char pathbuf[100];
d = pathbuf;
i = 1;
while ( *s && !isspace(*s) && ++i < sizeof(fontsdir))
*d++ = *s++;
*d = '\0';
s--;
if ( !accessdir(pathbuf) ){
fprintf(stderr,
".... Cannot access fonts directory %s \n",
pathbuf);
fprintf(stderr,
".... Fonts directory is still \"%s\"\n",
fontsdir);
} else {
(void)strncpy(fontsdir, pathbuf, sizeof(fontsdir));
fprintf(stderr,
".... Current fonts directory is now \"%s\"\n",
fontsdir);
}
}
goto askfont;
break;
case 'l': /* LIST FONTS */
/* elimina blanks fino al pattern */
for ( s++ ; *s && isspace(*s) ; s++ );
s = listfonts(s);
/* s deve puntare all'ultimo dei */
/* caratteri considerati */
s--;
/* Si presuppone che se l'utente ha */
/* chiesto la lista dei font voglia */
/* cambiare il font corrente per cui */
/* viene ripetuta la richiesta del */
/* nome di un font */
goto askfont;
break;
default:
fprintf(stderr, ".... Bad option \"%c\"\n", *s);
error = 1;
goto askfont;
}
}
while ( *s && isspace(*s) ) s++;
}
newfontfd = -1;
fontchanged = 0;
if ( *s && !error ){
/*
* E' stato specificato il nome di un nuovo font
*/
while ( isspace(*s) ) s++;
if ( strcmp(fontname, s) ){
/* E' il nome di un nuovo font */
if ( (newfontfd = load_font(s)) >= 0){
fontfd = newfontfd;
(void)strcpy(fontname, s);
fontchanged = 1;
notify = 1;
} else {
/* errore nel caricamento del font. Ripete domanda */
error = 1;
goto askfont;
}
}
} else {
if ( !notify ){
/* non ci sono cambiamenti di nessun tipo segnala errore */
/* per la notify */
notify = 1;
nochange = 1;
}
}
} /* for ever */
/* NOT REACHED */
} /* interactive */
/*-- UTILITY ROUTINES -------------------------------------------------------*/
/*
* GETOPTIONS tratta un insieme di opzioni in modo non interattivo
* esce appena trova un argomento che non e' una opzione
*/
getoptions(pargc, pargv)
int *pargc;
char **pargv[];
{
register int argc;
register char **argv;
register char *c;
argc = *pargc;
argv = *pargv;
c = *argv;
/*
* TRATTA OPZIONI
*/
while ( *++c ){
switch ( *c ){
case 'v':
vertical = 1;
break;
case 'h':
vertical = 0;
break;
case '1':
case '2':
style = *c;
break;
case 'd': /* change default fonts directory */
if ( ! --argc ){
fputs(".... Missing fonts directory name\n", stderr);
goto bad;
}
(void)strncpy(fontsdir, *++argv, sizeof(fontsdir));
if ( !accessdir(fontsdir) ){
fprintf(stderr,
".... Cannot access fonts directory \"%s\"\n", fontsdir);
goto bad;
}
defaultfdir = 0;
break;
case 'f':
/*
* carica un nuovo font
*/
if ( ! --argc ){
fputs(".... Missing font name\n", stderr);
goto bad;
}
if ((fontfd = load_font(*++argv)) < 0){
error = 1;
} else {
(void)strncpy(fontname, *argv, sizeof(fontsdir));
fontchanged = 1;
}
break;
default:
fprintf(stderr, ".... Bad option \"%c\"\n", *c);
goto bad;
} /* switch */
} /* while */
*pargv = argv;
*pargc = argc;
return;
bad:
fputs(USAGE, stderr);
exit(4);
} /* getoptions */
/*
* LISTFONTS esegue il comando:
* ls -F fontsdir/pattern >&2 se e' passato un pattern valido
* altrimanti esegue
* ls -F -d fontsdir/* >&2
* Ritorna il puntatore al primo carattere dopo il pattern
*/
char *
listfonts(paddr)
register char *paddr;
{
register char *p;
char shcmd[100], buf[100];
short slashs = 0; /* indica che il pattern contiene degli '/' */
char cbuf;
fputs(".... List \"", stderr);
p = paddr;
if ( *p && !isspace(*p) ){ /* c'e' un pattern specificato */
/* cerca fine pattern e gli mette temporaneamente \0 e */
/* intanto controlla se il pattern contiene degli '/' */
for ( p; *p && !isspace(*p) ; p++){
if ( *p == '/' )
slashs = 1;
if ( *p == '&' || !isprint(*p) ) /* puo' confondere lo shell */
*p = '?';
}
cbuf = *p;
*p = '\0';
/* controlla se il pattern contiene un path */
/* se non lo contiene premette cd fontsdir */
if ( !slashs && *paddr != '.' ){
/* il pattern non contiene un path */
/* esegue cd fontsdir;ls -F -d pattern */
(void)sprintf(shcmd,"cd %s;ls -F -d %s", fontsdir, paddr);
(void)sprintf(buf, "%s/%s", fontsdir, paddr);
if ( accessdir(buf) )
(void)strcat(shcmd, "/*");
fprintf(stderr, "%s/", fontsdir);
} else {
/* il pattern contiene un path */
/* esegue ls -F -d pattern */
(void)sprintf(shcmd, "ls -F -d %s", paddr);
if ( accessdir(paddr) )
(void)strcat(shcmd, "/*");
if ( *paddr != '.' && *paddr != '/' )
fputs("./", stderr);
}
(void)fputs(paddr, stderr);
/* ripristina carattere di fine pattern */
*p = cbuf;
} else { /* non c'e' un pattern specificato */
/* esegue cd fontsdir;ls -F */
(void)sprintf(shcmd, "cd %s;ls -F", fontsdir);
fprintf(stderr, fontsdir);
}
(void)strcat(shcmd, " >&2");
(void)fputs("\"\n", stderr);
if ( system(shcmd) )
fputs( ".... Shell error\n", stderr);
return(--p);
} /* listfonts */
/*
* ACCESSDIR retorna 1 se il path si riferisce a una directory
*/
accessdir(path)
char *path;
{
struct stat statbuf;
if ( stat(path, &statbuf) < 0 )
return(0);
return( ((statbuf.st_mode & S_IFMT) == S_IFDIR) &&
(statbuf.st_mode & S_IEXEC) );
}
/*-- PLOTTING ROUTINES ------------------------------------------------------*/
static short backslash;
static short controlchar;
plot_string(string)
char * string;
{
register char *s;
char ch;
backslash = 0;
controlchar = 0;
s = string;
while ( (ch = *s++) != '\0' ){
if ( ch < ' ' ){
controlchar++;
ch += '\100';
plot_char(ch);
continue;
}
if ( ch > '\177' ){
fprintf(stderr,
"unprintable char '\\%o' skipped\n", ch);
if ( ++unprintable > MAXUNPRINTABLE ){
fputs(".... Too many unprintable chars\n",
stderr);
exit(1);
}
continue;
}
/* '\' toglie al carattere successivo l'eventuale */
/* significato speciale ( \\ \^ ) */
if ( backslash ){
backslash = 0;
plot_char(ch);
continue;
}
switch ( ch ){
case '\\':
if ( *s )
backslash = 1;
else
plot_char('\\');
break;
/* se un carattere e' preceduto da '^' stampa i caratteri */
/* corrispondenti da '\000' a '\037' (da cntrl-@ a cntrl-_) */
case '^':
if ( controlchar || !*s || !(*s >= '@' && *s <= '_' ) )
/* Se il carattere precedente era '^': control ^ */
/* oppure sono a fine stringa */
/* oppure il carattere successivo non e' compreso */
/* fra '@' e '_' (non sarebbe un control...) */
plot_char('^');
else
controlchar = 1;
break;
default:
plot_char(ch);
}/*switch*/
}/*while*/
if ( !istty )
/*
* se la stampa non e' su tty separa le stringhe con blank
*/
plot_char(' ');
} /* plot_string */
plot_char(c)
char c;
{
register struct dispatch *pdisp; /* Dispatch table del carattere */
register int len, col, bit;
int ch; /* Carattere da plottare (ch = c) */
static int prevch = -1; /* Ricorda l'ultimo carattere plottato */
static char *charbits; /* Buffer per la bitmap del carattere */
static unsigned buflen = 0; /* Attuale dimensione del buffer */
unsigned bmlen; /* Numero di byte componenti la bitmap */
static int H; /* Altezza della bitmap del carattere in bit */
static int W; /* Larghezza della bitmap carattere in bit */
static int WB; /* Numero di byte in ogni riga della bit map */
static int HB; /* Indice dell'ultimo byte della prima col. */
/* (primo byte dell'ultima linea) */
char *byteind; /* Punta al byte della bit map da plottare */
register short thisbyte; /* Contiene il byte puntato da byteind */
register short thisbit; /* Maschera per il bit corrente in thisbyte */
int vspace; /* Spazio fra 2 caratteri in verticale */
ch = c;
if ( controlchar )
ch -= 0100;
pdisp = &(disptable[ch]);
if ( (ch != ' ') && ((bmlen = pdisp->nbytes) == 0) ){
fputs("character \"", stderr);
if ( controlchar )
(void)fputc('^', stderr);
fprintf(stderr,"%c\" is not provided by font\n",c);
if ( istty )
goto out;
ch = ' ';
}
if ( ch == ' ' ){
/*
* TRATTA CARATTERE BLANK
*/
if ( vertical ){
/* Somma l'altezza del carattere '|' se */
/* questo non e' previsto prova con il */
/* carattere 'a'. Se anche questo non */
/* e' previsto somma la massima altezza */
if ( disptable['|'].nbytes )
bmlen = disptable['|'].up;
else {
if ( disptable['a'].nbytes )
bmlen = disptable['a'].up;
else
bmlen = FontHeader.maxx;
}
} else {
/* Se il carattere blank non e' previsto allora */
/* sommo solo la larghezza del carattere 'a' e se */
/* anche questo non e' previsto prendo la massima */
/* larghezza di un carattere */
if ( pdisp->nbytes == 0 ){
if ( disptable['a'].nbytes )
bmlen = disptable['a'].width;
else
bmlen = FontHeader.maxx;
}
else
bmlen = pdisp->width;
}
for ( col=0 ; col < bmlen ; col++ )
plot_dot(NEXT);
} else {
/*
* TRATTA I CARATTERI STAMPABILI
*/
if ( prevch != ch || fontchanged ){
/* se il carattere non e' uguale a quello precedente */
/* (o non ho cambiato font) */
/* LEGGE LA BITMAP DEL CARATTERE */
if (lseek(fontfd,(long)(fbase+pdisp->addr),0)<(long)0){
perror("lseek");
exit(errno);
}
if ( buflen ){
if ( bmlen > buflen ){
/*
* l'attuale dimensione del buffer
* non e' sufficiente quindi questo
* viene espanso
*/
charbits = realloc(charbits, bmlen);
if ( charbits == NULL){
perror("realloc");
exit(errno);
}
buflen = bmlen;
}
} else {
/* non esiste ancora un buffer allocato */
if ((charbits = malloc(buflen=bmlen)) == NULL){
perror("malloc");
exit(errno);
}
}
if ( read(fontfd, charbits, (int)bmlen) != bmlen ){
fputs(".... Error reading bit maps\n", stderr);
perror("read");
exit(2);
}
/* ALTEZZA DELLA BITMAP (in bit) */
H = (pdisp->up) + (pdisp->down);
/* LARGHEZZA DELLA BITMAP (in bit) */
W = (pdisp->left) + (pdisp->right);
/* NUMERO DI BYTES CHE FORMANO UNA RIGA DELLA BITMAP */
WB = (W+7)>>3;
/* INDICE DELL'ULTIMO BYTE DELLA PRIMA COLONNA */
HB = (H-1)*WB;
}
/*
* PLOTTA CARATTERE
*/
thisbit = 0x80; /* primo bit in un byte */
if ( vertical ){
/*
* CARATTERE PLOTTATO IN VERTICALE
*/
byteind = charbits; /* primo byte della bit map */
thisbyte = *byteind & 0xff;
for ( len=0 ; len < H ; len++ ){
/* per tutte le linee */
/* GLI SPAZI A SINISTRA DEL CARATTERE NON */
/* SONO COMPRESI NELLA BIT MAP SE left < 0 */
for ( col=pdisp->left ; col < 0 ; col++ )
plot_dot(WHITE);
for ( bit = 0 ; bit < W ; bit++ ){
/* per tutti i bit di una linea */
if ( thisbyte & thisbit )
/* se il bit e' settato */
plot_dot(BLACK);
else
plot_dot(WHITE);
thisbit >>= 1; /* bit successivo */
if ( !thisbit ){
/*
* Passa al byte successivo
*/
thisbyte = *++byteind & 0xff;
thisbit = 0x80;
}
}
if ( thisbit != 0x80 ){
/*
* L'ultimo byte della linea non era
* totalmente utilizzato: forza il
* il passaggio al byte successivo
*/
thisbyte = *++byteind & 0xff;
thisbit = 0x80;
}
plot_dot(NEXT);
}
/*
* SE down < 0 GLI SPAZI SOTTO IL CARATTERE NON SONO
* COMPRESI NELLA BITMAP: QUINDI DEVO AGGIUNGERLI ...
*/
/* OLD: lascia troppo o troppo poco spazio !!!
*
* for ( len=pdisp->down ; len < 0 ; len++ )
* plot_dot(NEXT);
*/
/* NEW:
* lascio sempre un ottavo di maxy (se down < 0)
* e comunque al minimo 1 carattere
*/
if ( pdisp->down < 0 ) {
if ( fontchanged )
/* ricalcola vspace */
if ( (vspace=FontHeader.maxy>>3) == 0)
vspace = 1;
for ( len=0 ; len < vspace ; len++ )
plot_dot(NEXT);
}
} else {
/*
* CARATTERE PLOTTATO IN ORIZZONTALE
*/
/* GLI SPAZI A SINISTRA DEL CARATTERE NON SONO */
/* COMPRESI NELLA BIT MAP SE left < 0 */
for ( col=pdisp->left ; col < 0 ; col++ )
plot_dot(NEXT);
byteind = &charbits[HB]; /* 1o byte ultima linea */
for ( col=0 ; col < W ; col++ ){
/* per tutte le colonne */
/* GLI SPAZI SOTTO IL CARATTERE NON SONO */
/* COMPRESI NELLA BIT MAP SE down < 0 */
for ( bit=pdisp->down ; bit < 0 ; bit++ )
plot_dot(WHITE);
thisbyte = *byteind & 0xff;
for ( bit = H-1 ; bit >= 0 ; bit-- ){
/* per tutti i bit di una colonna */
if ( thisbyte & thisbit )
/* il bit e' settato */
plot_dot(BLACK);
else
plot_dot(WHITE);
byteind -= WB; /* linea precedente */
thisbyte = *byteind & 0xff;
}
byteind += HB+WB; /* Torna a ultima linea */
/* NB non cambia colonna */
thisbit >>= 1; /* bit successivo nel byte */
if ( !thisbit ){
/*
* Passa al byte successivo stessa linea
* (ultimo byte colonna successiva)
*/
++byteind;
thisbit = 0x80;
}
plot_dot(NEXT);
}
/* LASCIA LO SPAZIO FINO AL PROSSIMO CARATTERE */
for( col=pdisp->width - W ; col > 0 ; col-- )
plot_dot(NEXT);
}
}
out:
prevch = ch;
if ( controlchar )
controlchar = 0;
} /* plot_char */
#define PSIZE (float)1.66 /* rapporto fra altezza e larghezza di un */
/* carattere sulla stampante */
plot_dot(newpoint)
char newpoint;
/* Prepara la linea di stampa in base al valore di newpoint:
*
* WHITE aggiunge spazi bianchi;
* BLACK aggiunge un punto nero
* NEXT stampa la linea corrente e passa alla successiva
*
* Se si deve tracciare un segmento (bianco o nero) la sua lunghezza in
* caratteri della stampante viene calcolata approssimando la dimensione
* di ogni punto che la compone a 1.66 caratteri
*/
{
static char line[256]; /* Buffer di stampa */
static char *firstfree; /* Prima posizione libera in line */
static char previous = NEXT; /* Carattere precedente */
static int pointnum; /* Lunghezza del segmento in punti */
static float reminder = 0.0; /* resto dell'arrotondamento prec. */
int numchar; /* lunghezza segmento in caratteri */
double vnumchar; /* lunghezza virtuale segmento */
short halfleft = 0;
short halfright = 0;
char newchar;
/* Se il carattere attuale e' diverso dal precedente vuol */
/* dire che e' cambiato il tipo di segmento: calcolo la */
/* lunghezza del segmento in caratteri della stampante e */
/* riempio opportunamente line. */
/* Se il carattere attuale e' uguale al precedente */
/* incremento il conto della lunghezza del segmento */
/* Se lo stile e' il secondo: usa BLACK2 invece di BLACK */
/* se la lunghezza del segmento e' compresa fra 0.33333 e */
/* 0.66666 viene stampato un carattere intermedio che e' */
/* HALFLEFT se inizia un segmento BLACK e HALFLEFT se lo */
/* termina. */
if ( newpoint == previous ){
/*
* PERMANENZA
*/
if ( newpoint == NEXT ) { /* LINEA VUOTA */
if ( write(1, &newline, 1) < 0 ){
perror("write");
exit(errno);
}
} else
pointnum++; /* incrementa la lunghezza del segmento */
} else {
/*
* VARIAZIONE
*/
if ( previous == NEXT ){
/*
* INIZIO LINEA NON VUOTA O PRIMISSIMA ESECUZIONE
*/
firstfree = line;
pointnum = 1;
reminder = 0.0;
} else {
/*
* inserisco segmento precedente in line
*/
register int i;
register char *f; /* firstfree */
f = firstfree;
vnumchar = PSIZE*pointnum + reminder;
numchar = vnumchar;
reminder = vnumchar - numchar;
if ( style == '2' ){
if ( reminder >= 0.66666 ){
/*
* approssima per eccesso
*/
numchar++;
reminder -= 1.0;
} else {
if ( reminder >= 0.33333 ){
/*
* approssimazione intermedia
*/
if ( previous == BLACK )
halfright++;
else
if ( newpoint == BLACK )
halfleft++;
reminder -= 1.0;
}
} /* altrimenti approssima per eccesso */
if ( previous == BLACK )
newchar = BLACK2;
else
newchar = previous;
for ( i=0 ; i < numchar ; i++ )
*f++ = newchar;
if ( halfright ){
*f++ = HALFRIGHT;
} else
if ( halfleft ){
*f++ = HALFLEFT;
}
} else { /* style 1 */
if ( reminder >= 0.5 ){
/*
* approssima per eccesso
*/
numchar++;
reminder -= 1.0;
}
for ( i=0 ; i < numchar ; i++ )
*f++ = previous;
}
if ( newpoint == NEXT ){ /* FINE LINEA */
/*
* STAMPA LINEA
*/
*f++ = newline;
*f = '\0';
if ( write(1, line, strlen(line)) < 0 ){
perror("write");
exit(errno);
}
pointnum = 0;
} else {
/*
* TRANSIZIONE DA WHITE A BLACK O VICEVERSA
*/
pointnum = 1;
}
firstfree = f;
}
previous = newpoint;
}
} /* plot_dot */
/*-- LOAD FONT ROUTINES -----------------------------------------------*/
load_font(fontfile)
char *fontfile;
/* This routine reads in the appropriate font file */
{
register char *pf;
char fontpath[100];
int f;
short doinvert=0;
fontpath[0] = '\0';
/* vede se il nome del font contiene gia' un pathname */
pf = fontfile;
while(*pf && *pf != '/' ) pf++;
if ( *pf != '/' ){ /* aggiungo il path */
(void)strcpy(fontpath, fontsdir);
(void)strcat(fontpath, "/");
}
(void)strcat(fontpath,fontfile);
if((f = open(fontpath,0)) < 0 ){
fprintf(stderr,".... Cannot open font file \"%s\"\n",fontpath);
return(-1);
}
/* Get the FontHeader and check magic number */
if(read(f,(char *)&FontHeader,sizeof(FontHeader)) != sizeof(FontHeader)){
fprintf(stderr,".... Bad FontHeader in font file %s\n",fontpath);
return(-1);
}
if(FontHeader.magic != fontmagic){
/*
* L'header e' formato da short che su vax sono di 2 byte.
* Su alcuni processori (es. sun) i byte in uno short sono invertiti.
* Prova quindi a invertire prima di dichiarare bad magic
*/
invert((u_short *)&FontHeader.magic);
if(FontHeader.magic != fontmagic){
fprintf(stderr,".... Bad magic number in font file %s\n", fontpath);
return(-1);
} else {
invert(&FontHeader.size);
invert((u_short *)&FontHeader.maxx);
invert((u_short *)&FontHeader.maxy);
invert((u_short *)&FontHeader.xtend);
doinvert = 1;
}
}
/* Get disptablees */
if(read(f,(char *)disptable,sizeof(disptable)) != sizeof(disptable)){
fprintf(stderr,".... Bad disptable array in font file %s\n",fontpath);
return(-1);
}
if ( doinvert ) {
register int i;
register struct dispatch *pd;
pd = disptable;
for ( i = 0 ; i<256 ; i++ ){
invert((u_short *)&(pd->nbytes));
invert((u_short *)&(pd->addr));
invert((u_short *)&(pd->width));
pd++;
}
}
return(f);
} /* load_font */
/*
* Inverte i due byte in uno short (16 bit)
*/
invert(s)
u_short *s;
{
char tmp;
register char *c1,*c2;
c1 = c2 = (char *)s;
c2++;
tmp = *c1;
*c1 = *c2;
*c2 = tmp;
}
More information about the Comp.sources.unix
mailing list