home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume4
/
troff2lj-v2
/
part01
/
dumpfont.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-02-03
|
8KB
|
371 lines
/*
* dumpfont - ASCII display of HP LaserJet font
* Usage: dumpfont [-s] [-c first-last] fontfile
* Options:
* -s summary output only
* -c first-last restrict range of chars dumped
*
* David MacKenzie
* Latest revision: 07/26/88
*/
#include <stdio.h>
#include "hpfont.h"
int sflag = 0;
main(argc, argv)
int argc;
char **argv;
{
extern int optind;
extern char *optarg;
int c;
int first = 0; /* First char to dump. */
int last = 255; /* Last char to dump. */
while ((c = getopt(argc, argv, "sc:")) != EOF)
switch (c) {
case 's':
sflag = 1;
break;
case 'c':
parserange(optarg, &first, &last);
break;
default:
usage(argv[0]);
}
if (optind != argc - 1)
usage(argv[0]);
dumpfont(argv[optind], first, last);
exit(0);
}
/*
* Parse a character range of the form a-b, where a and b are
* optional ASCII characters.
*/
parserange(range, first, last)
char *range;
int *first;
int *last;
{
if (!*range) {
/* Null range: print none of the characters. */
*first = 256;
*last = -1;
return;
} else if (*range != '-')
*first = *range++;
else
*first = 0;
if (*range++ != '-')
err("Illegal character range");
if (!*range)
*last = 255;
else
*last = *range;
if (*last < *first)
err("Last character is less than first character");
}
dumpfont(file, first, last)
char *file;
register int first;
register int last;
{
FILE *fp;
char path[150];
fontdesc fd;
chardesc cde;
chardata cda;
register int ccode;
if (*file != '/')
strcpy(path, FONTDIR);
else
path[0] = 0;
strcat(path, file);
if (!(fp = fopen(path, "r"))) {
perror(path);
exit(1);
}
printf("file: %s\n\n", file);
readfontdesc(fp, &fd);
if (!sflag) {
dumpfdesc(&fd);
printf("\n");
}
while ((ccode = readchar(fp, &cde, &cda)) != EOF) {
if (ccode >= first && ccode <= last) {
printf("character %3d", ccode);
if (ccode > 32 && ccode < 127)
printf(" (%c)", ccode);
printf(":\n");
if (!sflag) {
dumpchar(&fd, &cde, &cda);
printf("\n");
}
}
free(cda.d_data);
}
fclose(fp);
}
readfontdesc(fp, fdp)
FILE *fp;
fontdesc *fdp;
{
char buf[500]; /* Trash receptacle. */
int fdlen; /* No. of bytes in font descriptor. */
if (fscanf(fp, "\033)s%dW", &fdlen) != 1)
err("Can't read font creation sequence");
if (!fread(fdp, sizeof(fontdesc), 1, fp))
err("Can't read font descriptor");
if (fdlen > sizeof(fontdesc))
if (!fread(buf, fdlen - sizeof(fontdesc), 1, fp))
err("Can't read continuation of font descriptor");
/* Swap byte order in integers if necessary. */
swap16(fdp->f_baseline);
swap16(fdp->f_cwidth);
swap16(fdp->f_cheight);
swap16(fdp->f_symset);
swap16(fdp->f_pitch);
swap16(fdp->f_height);
}
dumpfdesc(fdp)
fontdesc *fdp;
{
/* From p. 3-14, Technical Reference Manual. */
static char *tftab[] = {
"Line Printer", "Pica", "Elite", "Courier", "Helvetica",
"Times Roman", "Gothic", "Script", "Prestige", "Caslon",
"Orator"
};
/* From p. 3-12, Technical Reference Manual. */
static struct {
int field;
char term;
char *desc;
} sstab[] = {
8, 'U', "Roman-8",
8, 'K', "Kana-8",
8, 'M', "Math-8",
0, 'U', "USASCII",
0, 'B', "Line Draw",
0, 'A', "Math Symbols",
1, 'U', "US Legal",
0, 'E', "Roman Extension",
0, 'D', "ISO Denmark/Norway",
1, 'E', "ISO United Kingdom",
0, 'F', "ISO France",
0, 'G', "ISO German",
0, 'I', "ISO Italy",
0, 'S', "ISO Sweden/Finland",
1, 'S', "ISO Spain",
0, 0, NULL
};
int field;
char term;
register int i;
printf("font type (bits): %d\n", fdp->f_type + 7);
printf("from top of cell to baseline (dots): %d\n", fdp->f_baseline);
printf("cell width (dots): %d\n", fdp->f_cwidth);
printf("cell height (dots): %d\n", fdp->f_cheight);
printf("orientation: %s\n", fdp->f_orient ?
"landscape" : "portrait");
printf("spacing: %s\n", fdp->f_spacing ?
"proportional" : "fixed");
field = (fdp->f_symset >> 5) & 0x0f;
term = (fdp->f_symset & 0x1f) | 64;
printf("symbol set: %d = %d%c", fdp->f_symset, field, term);
for (i = 0; sstab[i].desc; ++i)
if (field == sstab[i].field && term == sstab[i].term) {
printf(" (%s)\n", sstab[i].desc);
break;
}
if (!sstab[i].desc)
printf(" (unknown)\n");
printf("pitch (horizontal dots per character): %g\n", fdp->f_pitch / 4.0);
printf("vertical dots per character: %g\n", fdp->f_height / 4.0);
printf("style: %s\n", fdp->f_style ? "italic" : "upright");
printf("stroke weight: %d\n", fdp->f_weight);
printf("typeface: %d", fdp->f_typeface);
if (fdp->f_typeface < 11)
printf(" (%s)\n", tftab[fdp->f_typeface]);
else
printf(" (unknown)\n");
/* Points = quarter_dots / 4 * 72 / 300. */
printf("point size: %d\n", (int) ((double) fdp->f_height * 0.06));
}
readchar(fp, cdep, cdap)
FILE *fp;
chardesc *cdep;
chardata *cdap;
{
char *Malloc();
int ccode; /* Character code (character number). */
int cdlen; /* No. of bytes in character descriptor. */
switch (fscanf(fp, "\033*c%dE", &ccode)) {
case 1:
break;
case EOF:
return EOF;
default:
err("Can't read character code");
}
if (fscanf(fp, "\033(s%dW", &cdlen) != 1)
err("Can't read character download sequence");
if (!fread(cdep, sizeof(chardesc), 1, fp))
err("Can't read character descriptor");
/* Swap byte order in integers if necessary. */
swap16(cdep->c_leftoff);
swap16(cdep->c_topoff);
swap16(cdep->c_width);
swap16(cdep->c_height);
swap16(cdep->c_delta_x);
cdap->d_len = cdlen - sizeof(chardesc);
cdap->d_data = Malloc(cdap->d_len);
if (!fread(cdap->d_data, cdap->d_len, 1, fp))
err("Can't read character data");
return ccode;
}
dumpchar(fdp, cdep, cdap)
fontdesc *fdp;
chardesc *cdep;
chardata *cdap;
{
dumpcdesc(cdep);
plotchar(fdp, cdep, cdap);
}
dumpcdesc(cdep)
chardesc *cdep;
{
printf("orientation: %s\n", cdep->c_orient ?
"landscape" : "portrait");
}
/*
* The main loop for plotting a character.
*/
plotchar(fdp, cdep, cdap)
fontdesc *fdp;
chardesc *cdep;
chardata *cdap;
{
register int x,y; /* First row & col are numbered 1. */
char graphchar;
initplot(cdap);
for (y = 1; y <= fdp->f_cheight; ++y) {
for (x = 1; x <= fdp->f_cwidth; ++x) {
graphchar = inbox(x, y, fdp, cdep) ?
nextdot(cdep) ? '*' : '-' :
y == fdp->f_baseline + 1 ? '=' :
'.';
putchar(graphchar);
}
if (y == fdp->f_baseline + 1)
printf(" baseline");
putchar('\n');
}
}
static char *bytep; /* Byte being dissected. */
static char masknum; /* Index into masktab to mask off bit. */
static int bitcnt; /* Number of current bit in current row. */
/*
* Set up for nextdot().
*/
initplot(cdap)
chardata *cdap;
{
bytep = cdap->d_data;
masknum = 0;
bitcnt = 0;
}
/*
* Boolean: is the next dot on?
*/
nextdot(cdep)
chardesc *cdep;
{
/* Table to isolate bit currently being analyzed. */
static char masktab[] = { 128, 64, 32, 16, 8, 4, 2, 1 };
int val; /* Return value. */
val = *bytep & masktab[masknum];
/* Check if we've reached the end of a row. */
if (++bitcnt == cdep->c_width) {
/* Skip the byte boundary padding bits. */
++bytep;
masknum = 0;
bitcnt = 0;
} else if (++masknum == 8) {
/* Go on to the next byte. */
++bytep;
masknum = 0;
}
return val;
}
/*
* Boolean: is point (x,y) in the character box?
*/
inbox(x, y, fdp, cdep)
register int x, y;
fontdesc *fdp;
chardesc *cdep;
{
return y >= fdp->f_baseline - cdep->c_topoff + 1 &&
y <= fdp->f_baseline - cdep->c_topoff + cdep->c_height &&
x >= cdep->c_leftoff &&
x <= cdep->c_leftoff + cdep->c_width - 1;
}
char *
Malloc(size)
unsigned size;
{
char *malloc();
register char *s;
if (!(s = malloc(size))) {
perror("malloc");
exit(1);
}
return s;
}
err(s)
char *s;
{
fprintf(stderr, "%s\n", s);
exit(1);
}
usage(file)
char *file;
{
fprintf(stderr, "Usage: %s [-s] [-c first-last] fontfile\n", file);
exit(1);
}