#include "stdio.h"
#include "dev.h"
#define BYTEMASK 0377
#define skipline(f) while(getc(f) != '\n')
struct dev dev;
struct Font font;
#define NSIZE 100
short size[NSIZE];
#define NCH 256
char chname[5*NCH];
short chtab[NCH];
#define NFITAB (NCH + 128-32)
char fitab[NFITAB];
#define FSIZE 254
char width[FSIZE];
char kern[FSIZE];
char code[FSIZE];
#define BIGGESTFONT FSIZE
#define NFONT 50
char fname[NFONT][10];
int fflag = 0;
int fdout;
char *fout = "DESC.out";
static int dofont(char *);
static int getlig(FILE *);
int
main(int argc, char *argv[])
{
FILE *fin;
char cmd[100], *p;
int i, totfont, v;
if (argc < 2) {
fprintf(stderr, "Usage: makedev [DESC] [fonts]\n");
exit(1);
}
if ((fin = fopen("DESC", "r")) == NULL) {
fprintf(stderr, "makedev: can't open DESC file\n");
exit(1);
}
while (fscanf(fin, "%s", cmd) != EOF) {
if (cmd[0] == '#')
skipline(fin);
else if (strcmp(cmd, "res") == 0) {
fscanf(fin, "%hd", &dev.res);
} else if (strcmp(cmd, "hor") == 0) {
fscanf(fin, "%hd", &dev.hor);
} else if (strcmp(cmd, "vert") == 0) {
fscanf(fin, "%hd", &dev.vert);
} else if (strcmp(cmd, "unitwidth") == 0) {
fscanf(fin, "%hd", &dev.unitwidth);
} else if (strcmp(cmd, "sizescale") == 0) {
fscanf(fin, "%hd", &dev.sizescale);
} else if (strcmp(cmd, "paperwidth") == 0) {
fscanf(fin, "%hd", &dev.paperwidth);
} else if (strcmp(cmd, "paperlength") == 0) {
fscanf(fin, "%hd", &dev.paperlength);
} else if (strcmp(cmd, "biggestfont") == 0) {
fscanf(fin, "%hd", &dev.biggestfont);
} else if (strcmp(cmd, "spare2") == 0) {
fscanf(fin, "%hd", &dev.spare2);
} else if (strcmp(cmd, "sizes") == 0) {
dev.nsizes = 0;
while (fscanf(fin, "%d", &v) != EOF && v != 0)
size[dev.nsizes++] = v;
size[dev.nsizes] = 0;
} else if (strcmp(cmd, "fonts") == 0) {
fscanf(fin, "%hd", &dev.nfonts);
for (i = 0; i < dev.nfonts; i++)
fscanf(fin, "%s", fname[i]);
} else if (strcmp(cmd, "charset") == 0) {
short pchname;
p = chname;
pchname = 0;
dev.nchtab = 0;
while (fscanf(fin, "%s", p) != EOF) {
chtab[dev.nchtab++] = pchname;
while (*p++)
pchname++;
pchname++;
}
dev.lchname = pchname;
chtab[dev.nchtab++] = 0;
} else
fprintf(stderr, "makedev: unknown command %s\n", cmd);
}
if (argc > 1 && strcmp(argv[1], "DESC") == 0) {
fdout = creat(fout, 0666);
if (fdout < 0) {
fprintf(stderr, "makedev: can't open %s\n", fout);
exit(1);
}
write(fdout, &dev, sizeof(struct dev));
write(fdout, size, (dev.nsizes+1) * sizeof(size[0]));
write(fdout, chtab, dev.nchtab * sizeof(chtab[0]));
write(fdout, chname, dev.lchname);
totfont = 0;
for (i = 0; i < dev.nfonts; i++) {
totfont += dofont(fname[i]);
write(fdout, &font, sizeof(struct Font));
write(fdout, width, font.nwfont & BYTEMASK);
write(fdout, kern, font.nwfont & BYTEMASK);
write(fdout, code, font.nwfont & BYTEMASK);
write(fdout, fitab, dev.nchtab+128-32);
}
lseek(fdout, 0L, 0);
dev.filesize =
(dev.nsizes+1) * sizeof(size[0])
+ dev.nchtab * sizeof(chtab[0])
+ dev.lchname * sizeof(char)
+ totfont * sizeof(char);
write(fdout, &dev, sizeof(struct dev));
close(fdout);
argc--;
argv++;
}
for (i = 1; i < argc; i++)
dofont(argv[i]);
return (0);
}
static int
dofont(char *name)
{
FILE *fin;
int fdout;
int i, nw, spacewidth, n, v;
char buf[100], ch[10], s1[10], s2[10], s3[10], cmd[30];
if ((fin = fopen(name, "r")) == NULL) {
fprintf(stderr, "makedev: can't open font %s\n", name);
exit(2);
}
sprintf(cmd, "%s.out", name);
fdout = creat(cmd, 0666);
if (fdout < 0) {
fprintf(stderr, "makedev: can't open %s\n", fout);
exit(1);
}
for (i = 0; i < NFITAB; i++)
fitab[i] = 0;
for (i = 0; i < FSIZE; i++)
width[i] = kern[i] = code[i] = 0;
font.specfont = font.ligfont = spacewidth = 0;
while (fscanf(fin, "%s", cmd) != EOF) {
if (cmd[0] == '#')
skipline(fin);
else if (strcmp(cmd, "name") == 0)
fscanf(fin, "%s", font.namefont);
else if (strcmp(cmd, "internalname") == 0)
fscanf(fin, "%s", font.intname);
else if (strcmp(cmd, "special") == 0)
font.specfont = 1;
else if (strcmp(cmd, "spare1") == 0)
fscanf(fin, "%1s", &font.spare1);
else if (strcmp(cmd, "ligatures") == 0) {
font.ligfont = getlig(fin);
} else if (strcmp(cmd, "spacewidth") == 0) {
fscanf(fin, "%d", &spacewidth);
width[0] = spacewidth;
} else if (strcmp(cmd, "charset") == 0) {
skipline(fin);
nw = 0;
while (fgets(buf, 100, fin) != NULL) {
sscanf(buf, "%s %s %s %s", ch, s1, s2, s3);
if (s1[0] != '"') {
nw++;
width[nw] = atoi(s1);
kern[nw] = atoi(s2);
if (s3[0] == '0')
sscanf(s3, "%o", &i);
else
sscanf(s3, "%d", &i);
code[nw] = i;
}
if (strlen(ch) == 1)
fitab[ch[0] - 32] = nw;
else if (strcmp(ch, "---") != 0) {
for (i = 0; i < dev.nchtab; i++)
if (strcmp(&chname[chtab[i]], ch) == 0) {
fitab[i + 128-32] = nw;
break;
}
if (i >= dev.nchtab)
fprintf(stderr, "makedev: font %s: %s not in charset\n", name, ch);
}
}
nw++;
if (dev.biggestfont > 0)
n = dev.biggestfont + 1;
else
n = BIGGESTFONT;
if ( nw > n ) {
n = nw;
fprintf(stderr, "makedev: warning font %s may only fit in position 0\n", font.namefont);
}
if (n >= NCH) {
fprintf(stderr, "makedev: font has %d characters, too big\n", n);
exit(2);
}
font.nwfont = n;
}
}
if (spacewidth == 0)
width[0] = dev.res * dev.unitwidth / 72 / 3;
fclose(fin);
write(fdout, &font, sizeof(struct Font));
write(fdout, width, font.nwfont & BYTEMASK);
write(fdout, kern, font.nwfont & BYTEMASK);
write(fdout, code, font.nwfont & BYTEMASK);
write(fdout, fitab, dev.nchtab+128-32);
close(fdout);
v = sizeof(struct Font) + 3 * n + dev.nchtab + 128-32;
fprintf(stderr, "%3s: %3d chars, width %3d, size %3d\n",
font.namefont, nw, width[0], v);
return (v);
}
static int
getlig(FILE *fin)
{
int lig;
char temp[100];
lig = 0;
while (fscanf(fin, "%s", temp) != EOF && strcmp(temp, "0") != 0) {
if (strcmp(temp, "fi") == 0)
lig |= LFI;
else if (strcmp(temp, "fl") == 0)
lig |= LFL;
else if (strcmp(temp, "ff") == 0)
lig |= LFF;
else if (strcmp(temp, "ffi") == 0)
lig |= LFFI;
else if (strcmp(temp, "ffl") == 0)
lig |= LFFL;
else
fprintf(stderr, "illegal ligature %s\n", temp);
}
skipline(fin);
return (lig);
}