/*
 * make vf which converts ASCII-dvi to BK-dvi
 * mka2bkjvf [-kXX] rml 10 min10 /.../min10.tfm afm data [VFDIR]
 *	data --- code new-llx
 * --> min10.vf
 */
#include	<stdio.h>
#include	"defs.h"
#include	"vfcodes.h"
#include	"bifont.h"
#include	"parseAFM.h"

#define	UNIT	1048576		/* 1 fixpoint real = 2^20 */
int abk_ratio;	/* (ASC/BK)*UNIT */
char *bk1, *bk2;
char *ascfont;
int vfds;
char *vfdir;
FILE *jfm, *afm, *fix, *vf;
int lastku;
char shortform;

/* set by readjfm */
extern char header[];
extern char width[];
extern int id, nt, lh, bc, ec, nw, ds;
extern struct jfmfntinfo *jfmfi;

/* set by parseFile */
FontInfo *fi;

CharMetricInfo *curcmi;

BOOLEAN hasafm;
#define	BUFSIZE		256
#define	NFIXCHARS	200
struct fixdata {
    int code;
    float adj, dadj;
} fixdata[NFIXCHARS], *curfix;

main(ac, av)
int ac;
char *av[];
{
    char name[64];

    if (av[1][0] == '-') {
	shortform = TRUE;
	lastku = atoi(av[1]+2);
	--ac, av++;
    } else {
	shortform = FALSE;
	lastku = 84;
    }
    bk1 = av[1];
    bk2 = av[2];
    vfds = atoi(bk2)<<20;
    ascfont = av[3];
    if ((jfm = fopen(av[4], "r")) == NULL) {
	fprintf(stderr, "cannot read %s\n", av[4]);
	exit(1);
    }
    if (!readjfm(jfm)) {
	fprintf(stderr, "%s is not jfm\n", av[4]);
	exit(1);
    }
    abk_ratio = jfmfi->ch[0].tfmw;
    if (strcmp(av[5], "-") == 0)
	hasafm = FALSE;
    else if ((afm = fopen(av[5], "r")) == NULL) {
	fprintf(stderr, "cannot read %s\n", av[5]);
	exit(1);
    } else {
	hasafm = TRUE;
	parseFile(afm, &fi, P_M);
	curcmi = fi->cmi;
    }
    if ((fix = fopen(av[6], "r")) == NULL) {
	fprintf(stderr, "cannot read %s\n", av[6]);
	exit(1);
    }
    read_fixdata(fix);
    curfix = fixdata;

    vfdir = (ac > 7) ? av[7] : "";
    sprintf(name, "%s%s.vf", vfdir, ascfont);
    if ((vf = fopen(name, "w")) == NULL) {
	fprintf(stderr, "cannot write %s\n", name);
	exit(1);
    }
    ascvf();
    fclose(vf);

    exit(0);
}

read_fixdata(fix)
FILE *fix;
{
    char line[BUFSIZE], *l;
    struct fixdata *f;

    for (f = fixdata; fgets(line, BUFSIZE, fix) != NULL; f++) {
	sscanf(line, "%X", &(f->code));
	for (l = line; *l != ' '; l++)
	    ;
	for (; *l == ' '; l++)
	    ;
	if (*l == '&')
	    sscanf(l+2, "%f %f", &(f->adj), &(f->dadj));
	else {
	    sscanf(l, "%f", &(f->adj));
	    f->dadj = 0;
	}
    }
    f->code = 0;
}

#define	makejis(k,t)	((k+0x20)*256+t+0x20)

ascvf()
{
    int ku, ten;
    long len;
    int i;

    putuint(vf, VF_PRE, 1);
    putuint(vf, VF_ID, 1);
    putuint(vf, 0, 1);	/* no comment */
    putbytes(vf, header, 2*4);	/* check sum & design size */

    putuint(vf, FNT_DEF1, 1);
    putuint(vf, 1, 1);
    putuint(vf, 0, 4);
    putuint(vf, abk_ratio, 4);
    putuint(vf, vfds, 4);
    putuint(vf, 0, 1);
    putuint(vf, strlen(bk1), 1);
    putbytes(vf, bk1, strlen(bk1));

    vfchar0();
    for (ku = 1; ku <= lastku; ku++)
	for (ten = 1; ten <= 94; ten++)
	    vfchar(makejis(ku, ten));

    len = ftell(vf);
    for (i = 0; i < 4 - len%4; i++)
	putuint(vf, VF_POST, 1);
}

vfchar0()
{
    int pl;
    int ct;

    pl = 3;	/* SET2 jis */
    
    putuint(vf, VF_LONG_CHAR, 1);
    putuint(vf, pl, 4);
    putuint(vf, 0, 4);	/* char 0 */
    putuint(vf, jfmfi->ch[0].tfmw, 4);
    putuint(vf, SET2, 1);
    putuint(vf, 0x2121, 2);
}

vfchar(jis)
int jis;
{
    int pl, n, dn;
    int ct, gl, dgl, l;
    byte b[sizeof(int)], db[sizeof(int)];

    if ((ct = getctype(jis, jfmfi)) == 0)
	return;
    pl = 3;	/* SET2 jis */
    for (; 0 < curfix->code && curfix->code < jis; curfix++)
	;
    if (curfix->code == jis) {
	if (hasafm) {
	    for (; curcmi->code < jis; curcmi++)
		;
	    if (curcmi->code == jis) {
		if (id == JFM_ID)
		    l = curcmi->charBBox.llx+curcmi->charBBox.urx;
		else /* tategaki */
		    l = -(curcmi->charBBox.lly+curcmi->charBBox.ury);
		gl = -((l*UNIT)/1000 - jfmfi->ch[ct].tfmw) / 2
		    + (curfix->adj*UNIT)/1000;
	    }
	} else
	    gl = (curfix->adj*UNIT)/1000;
	dgl = (curfix->dadj*UNIT)/1000;
    } else
	gl = dgl = 0;
    if (gl == 0 && dgl == 0 && jfmfi->ch[ct].tfmw == jfmfi->ch[0].tfmw)
	return;
    if (gl != 0) {
	n = inttob(b, gl, TRUE);
	pl += 1+n;
    }
    if (dgl != 0) {
	dn = inttob(db, dgl, TRUE);
	pl += 1+dn;
    }
    
    putuint(vf, VF_LONG_CHAR, 1);
    putuint(vf, pl, 4);
    putuint(vf, jis, 4);
    putuint(vf, jfmfi->ch[ct].tfmw, 4);
    if (gl != 0) {
	putuint(vf, RIGHT1+n-1, 1);
	putbytes(vf, b, n);
    }
    if (dgl != 0) {
	putuint(vf, DOWN1+dn-1, 1);
	putbytes(vf, db, dn);
    }
    putuint(vf, SET2, 1);
    putuint(vf, jis, 2);
}
