/*
 * DEVICE dependent, type1 font
 */

#include	"defs.h"
#include	"emit.h"
#include	"global.h"
#include	"bifont.h"
#include	"ps.h"

void
dev_t1_initfontdict(fe, bii, t1path, encpath)
struct font_entry *fe;
struct biinitfontinfo *bii;
char *t1path, *encpath;
{
    char t1font[BUFSIZ];
    struct psbiops po;

    fe->k = dev_newdevfont();
    if (t1path != NULL) {
	read_type1_file(fe, bii, t1path, t1font, encpath);
	t1tobi(tfmfinfo(fe)->tfm_bf, t1font);
    }
    get_tfm_psbiops(fe, &po);
    psfindfontop(psfname(fe->k), &po);
    fe->ncdl = 0;
}

read_type1_file(fe, bii, fn, t1f, en)
struct font_entry *fe;
struct biinitfontinfo *bii;
char *fn, *t1f, *en;
{
    FILE *fp;
    char buffer[BUFSIZ], *b;
    char *type1id1 = "%!FontType1-";
    char *type1id2 = "%!PS-AdobeFont-";
    BOOLEAN istype1, ispfa;
    int idlen, i;
    int len, n, c;

    if ((fp = BINARYOPEN(fn)) == NULL)
	Fatal("Unable to open type1font file %s", fn);
    if (getc(fp) == 0x80) {
	if (getc(fp) == 1) {
	    (void)fseek(fp, 6L, SEEK_SET);
	    ispfa = FALSE;
	} else
	    Fatal("%s is not type1font file", fn);
    } else {
	(void)fseek(fp, 0L, SEEK_SET);
	ispfa = TRUE;
    }
    for (b = buffer; (c = getc(fp)) != '\r' && c != '\n'; b++)
	*b = c;
    *b = '\0';
    if (!strncmp(buffer, type1id1, strlen(type1id1))) {
	idlen = strlen(type1id1);
	istype1 = TRUE;
    } else if (!strncmp(buffer, type1id2, strlen(type1id2))) {
	idlen = strlen(type1id2);
	istype1 = TRUE;
    } else
	istype1 = FALSE;
    if (!istype1) {
	(void)fclose(fp);
	Fatal("%s is not type1font file", fn);
    }

    for (i = idlen; buffer[i] != ':' && buffer[i] != '\0'; i++)
	;
    if (buffer[i] == ':') {
	for (i++; buffer[i] == ' '; i++)
	    ;
	for (b = t1f; buffer[i] != ' '; b++, i++)
	    *b = buffer[i];
	*b = '\0';
    } else {
	b = strrchr(fn, '/');
	if (b == NULL) {
	    b = fn;
	} else {
	    b++;
	}
	i = b - fn;
	for (b = t1f; fn[i] != '\0' && fn[i] != '.'; i++, b++) {
	    *b = fn[i];
	}
	*b = '\0';
    }

    EMIT(outfp, "%%%%BeginFont: %s\n", t1f);
    if (G_t1part)
	t1_subset(fn, en, bii->mark);
    else if (ispfa)
	copy_type1_pfa(fp);
    else
	copy_type1_pfb(fp, fn);
    EMIT(outfp, "%%%%EndFont\n");
    (void)fclose(fp);
}

void
copy_type1_pfa(fp)
FILE *fp;
{
    int n, c;

    (void)fseek(fp, 0L, SEEK_SET);
    if (G_removecomments)
	for (n = '\n'; (c = getc(fp)) != EOF; ) {
	    if (c == '%' && n == '\n') {
		while ((c = getc(fp)) != EOF)
		    if (c == '\n')
			break;
	    } else {
		EMITC(c);
		n = c;
	    }
	}
    else
	for (; (c = getc(fp)) != EOF; )
	    EMITC(c);
}

#define	BINLEN	32
static char *hexdig = "0123456789ABCDEF";

void
copy_type1_pfb(fp, fn)
FILE *fp;
char *fn;
{
    int i, c;
    long len, n;

    (void)fseek(fp, 1L, SEEK_SET);
    for (;;) {
	switch (c = getc(fp)) {
	case 1:
	    for (len = 0, n = 1, i = 1; i <= 4; n = n*256, i++)
		len += n*getc(fp);
	    for (; len > 0; --len) {
		if ((c = getc(fp)) == EOF)
		    Fatal("premature EOF in type1 font file %s", fn);
		if (c == '\r')
		    EMITC('\n');
		else
		    EMITC(c);
	    }
	    break;
	case 2:
	    for (len = 0, n = 1, i = 1; i <= 4; n = n*256, i++)
		len += n*getc(fp);
	    for (i = 0; len > 0; --len) {
		if ((c = getc(fp)) == EOF)
		    Fatal("premature EOF in type1 font file %s", fn);
		EMITC(hexdig[c>>4]);
		EMITC(hexdig[c&0xf]);
		i++;
		if (i == BINLEN) {
		    EMITC('\n');
		    i = 0;
		}
	    }
	    if (i > 0)
		EMITC('\n');
	    break;
	case 3:
	    return;
	case EOF:
	    Fatal("Premature EOF in type1 font file %s", fn);
	}
    }
}
