#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 256
char width[FSIZE];
char kern[FSIZE];
char code[FSIZE];
#define NFONT 60
char fname[NFONT][10];
int fflag = 0;
int fdout;
char *fout = "DESC.out";
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 %s\n", argv[1]);
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) {
p = chname;
dev.nchtab = 0;
while (fscanf(fin, "%s", p) != EOF) {
chtab[dev.nchtab++] = p - chname;
while (*p++)
;
}
dev.lchname = p - chname;
chtab[dev.nchtab++] = 0;
} else
fprintf(stderr, "makedev: unknown command %s\n", cmd);
}
if (argc > 0 && 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]);
exit(0);
return (0);
}
int
dofont(name)
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);
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 {
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 >= nw)
n = dev.biggestfont;
else {
if (dev.biggestfont > 0)
fprintf(stderr, "font %s too big\n", name);
n = nw;
}
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;
}
int
getlig(fin)
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;
}