anton@ucbvax.ARPA (Jeff Anton) (10/08/85)
jeffg@tekc??? asked about this... is that Jeff Gutow... Oh well... Here it is... Flames & Bugs to /dev/null.... (I don't want to look at this code anymore.. It was written in my early days of UNIX so don't complain.) Money to anton@INGRES.BERKELEY.EDU (anton%ucbingres@berkeley.arpa) ucbvax!anton anton@ucbvax.UUCP FONTBANNER(PUBLIC) UNIX Programmer's Manual FONTBANNER(PUBLIC) NAME fontbanner - print a banner using vtroff fonts SYNOPSIS fontbanner {[-dchrs] [-uCHAR][-p#] [-w#] font [message]}+ DESCRIPTION Fontbanner(PUBLIC) outputs a message in large characters to the standard output. The message may be entered on the command line or you will be prompted for a single line of input. The prompt will be sent to the standard error to allow redirection of the banner output. If you type the message on the command line you must quote it if it contains any spaces or special characters. The size of the banner is determined directly from the point of the selected font. Normally, a point is 1/72 of an inch and the point of a font is the distaince from the lowest descender to the tallest character divided by 72. (A 36 point font is 1/2 an inch tall). Fontbanner, however is much bigger. If you want n column output, n/5.5 point would probably by a good choice. For 132 column output, 26 point is good; for 80 column output, 12 point. Not all fonts are available in all point sizes so look for your font in /usr/lib/vfont/* before using fontbanner. The -d option doubles the size of the font and the -h option halves it, both at the cost of ragged edges. The -u option uses the character 'CHAR' instead of the default '#' for printing. The -s option makes each banner sized character be made up by the printer sized version of the same character, while the -f option uses the contents of a file for each character printed (useful for having a small message inside a bigger one). If the file ends before the banner is printed, the default character (or character specified by the -u option) will be used to complete the banner unless the -r option is given. The -r option causes the input file to be read repeated until the banner is done. The -p option followed by a number specifies an offset in characters from the left side of a page. The -w option followed by a number tells how wide your device is. The default is 132 columns. The -c option causes output to be centered. If -p is given it becomes and advisory when used with the -c option. The whole argument list maybe repeated to allow different fonts and page offsets in a banner. Note that the toggle options, c,d,h,s and u do not reset but must be toggled if one want to change it when using a different font. FILES /usr/lib/vfont/* directory of font files to choose from SEE ALSO banner(6), vfontinfo(1), vfont(5), vtroff(1) _T_h_e _B_e_r_k_e_l_e_y _F_o_n_t _C_a_t_a_l_o_g AUTHOR Jeff Anton (anton@ucbingres) Printed 3/30/84 local 1 /* * $Header: fontbanner.c,v 1.4 84/08/06 11:56:22 anton Exp $ * * $Log: fontbanner.c,v $ * Revision 1.4 84/08/06 11:56:22 anton * Lots of new stuff by Charles Spirakis * * Revision 1.3 84/03/31 00:09:01 anton * Added lots of stuff - jaa * * Revision 1.2 84/02/01 21:27:36 cc-sec * spaceing fixed and RCS stuff added - jaa * */ #include <stdio.h> #include <ctype.h> #include <sys/file.h> #include <vfont.h> #define DEF '#' struct header fhead; struct dispatch dtab[256],*dp; long fbase = sizeof fhead + sizeof dtab; char cbits[4000],*cntl(), *iname; char rept = DEF; int h,w,widthbytes,md, mu, flags; int pwid = 132; #define MAG 1 #define CEN 2 #define HALF 4 #define INP 8 #define REDO 16 main(argc, argv) int argc; char **argv; { char line[132], chr, *cpos, *fontname, *comname; int i, poff; poff = flags = 0; comname = *argv; again: while (--argc && **++argv == '-') { while (chr = *++*argv) switch (chr) { case 'p': if (*++*argv) { poff = atoi(*argv); goto nxtarg; } else if (argc-- > 2) { poff = atoi(*++argv); goto nxtarg; } else goto usage; break; case 'w': if (*++*argv) { pwid = atoi(*argv); goto nxtarg; } else if (argc-- > 2) { pwid = atoi(*++argv); goto nxtarg; } else goto usage; break; case 'u': rept = *(*argv + 1); if (! isprint(rept)) rept = DEF; goto nxtarg; break; case 'f': if (*++*argv) { iname = *argv; flags |= INP; goto nxtarg; } else if (argc-- > 2) { iname = *++argv; flags |= INP; goto nxtarg; } else goto usage; break; case 'd': flags ^= MAG; flags &= ~HALF; break; case 'h': flags ^= HALF; flags &= ~MAG; break; case 'c': flags ^= CEN; break; case 'r': flags ^= REDO; break; default: fprintf(stderr, "usage: -%c flag unknown\n", chr); } nxtarg: ; } cpos = NULL; switch (argc) { case 1: fontname = *argv; break; case 0: usage: fprintf(stderr, "usage: %s {[-dchr] [-uCHAR] [-p#] [-w#] font [\"message\"]}+ (i.e. repeatable)\n", comname); exit(1); default: cpos = argv[1]; fontname = *argv; break; } if (flags & INP) openinp(iname); printban(fontname, comname, cpos, flags, poff); argv++; if (--argc >= 2) goto again; exit(0); } printban(fontname, comname, cpos, flags, poff) char *fontname, *comname, *cpos; int flags, poff; { int fd, spwidth, i; char line[80], *ext, chr; if ((fd = open(fontname, O_RDONLY)) == -1) { strcpy(line, "/usr/lib/vfont/"); strcat(line, fontname); if ((fd = open(line, O_RDONLY)) == -1) { perror(fontname); exit(2); } } ext = fontname + strlen(fontname); if (ext[-1] == 'r') { fprintf(stderr,"%s: can't use rotated fonts\n",comname); exit(5); } while (*--ext != '.'); spwidth = atoi(++ext); spwidth += spwidth >> 1; if (flags & MAG) spwidth <<= 1; else if (flags & HALF) spwidth >>= 1; if (read(fd, &fhead, sizeof fhead) != sizeof fhead || read(fd, dtab, sizeof dtab) != sizeof dtab) { fprintf(stderr, "%s: file too small\n", fontname); exit(3); } if (fhead.magic != 0436) { fprintf(stderr,"%s: magic number wrong\n",fontname); exit(4); } md = mu = 0; for (i = 0, dp = dtab; i < 256; dp++, i++) { if (!dp->nbytes) continue; if (md < dp->down) md = dp->down; if (mu < dp->up) mu = dp->up; } if (2*(poff + mu + md) > pwid) fprintf(stderr, "%s: Warning: %s is too tall for width %d offset %d\n", comname, fontname, pwid, poff); if (flags & CEN) poff = (pwid + poff)/2 - mu - md; if (cpos == NULL) { fprintf(stderr,"Message: "); gets(line); cpos = line; } while (chr = *cpos++) { dp = dtab + chr; if (dp->nbytes == 0) { if (chr == ' ') for (i = 0; i < spwidth; i++) putchar('\n'); else fprintf(stderr,"%s: Warning: '%s' (0x%x) not in %s\n",comname,cntl(chr),chr,fontname); continue; } lseek(fd, fbase + dp->addr, 0); read(fd, cbits, dp->nbytes); h = dp->up + dp->down; w = dp->left + dp->right; widthbytes = ( w + 7 ) >> 3; report(poff); } close(fd); } report(poff) int poff; { int k,l,top; char mstr[9], spstr[9]; switch (flags & (MAG | HALF)) { case MAG: strcpy(spstr, " "); sprintf(mstr, "%c%c%c%c", rept, rept, rept, rept); break; case HALF: strcpy(spstr, " "); sprintf(mstr, "%c", rept); break; default: strcpy(spstr, " "); sprintf(mstr, "%c%c", rept, rept); } for (l = 0; l < dp->width; l++) { for (k = 0; k < poff; k++) putchar(' '); for (top = - dp->up; top <= md && !fbit(top,l); top++); for (k = md; k >= top; k--) { if ((flags & INP) && fbit(k,l)) inpstr(mstr); fputs(fbit(k,l)?mstr:spstr,stdout); } putchar('\n'); if (flags & MAG) { for (k = md; k >= top; k--) { if ((flags & INP) && fbit(k,l)) inpstr(mstr); fputs(fbit(k,l)?mstr:spstr,stdout); } putchar('\n'); } } } fbit(row, col) int row, col; { int thisbyte,thisbit; row += dp->up; if (row < 0 || col < 0 || row >= h || col >= w) return(0); thisbyte = cbits[row * widthbytes + ( col >> 3 )]; thisbit = 0x80 >> (col & 7); return((thisbyte & thisbit) != 0); } char * cntl(chr) char chr; { static char ret[3]; if (chr >= 128 || iscntrl(chr)) ret[0] = '^', ret[1] = chr + '@', ret[2] = '\0'; else ret[0] = chr, ret[1] = '\0'; return(ret); } FILE *inp = NULL; openinp(name) char *name; { if (inp != NULL) fclose(inp); if ((inp = fopen(name, "r")) == NULL) { fprintf(stderr, "\nCouldn't open %s.\n", name); exit(7); } } inpstr(str) char *str; { int i, j; char myget(); switch (flags & (MAG | HALF)) { case MAG: i = 4; break; case HALF: i = 1; break; default: i = 2; } for (j = 0; j < i; j++) *str++ = myget(); *str = '\0'; } char myget() { static int ch, oldchar; while (1) { if ((ch = getc(inp)) == EOF) { if (flags & REDO) { openinp(iname); if ((ch = getc(inp)) == EOF) { fprintf(stderr, "Can't use a null file for input"); exit(8); } } else { return (oldchar = rept); } } if ((oldchar == ' ') && (isspace(ch))) continue; if (isprint(ch)) return (oldchar = ch); if (isspace(ch)) return (oldchar = ' '); } } -- C knows no bounds. Jeff Anton U.C.Berkeley Ingres Group ucbvax!anton anton@BERKELEY.EDU