/*
 * DEVICE dependent, wadalab font
 */

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


static char *FontBase="Wadalab";
static char *version_str="001.001";

/* jfm
 */
static struct pd pd;
static struct psbiops po;

dev_wl_begfontdict(fe)
struct font_entry *fe;
{
    initpd(pd);
    get_jfm_psbiops(fe, &po);
}

#define	hex(c)	(c>='a' ? c-'a'+10 : c-'0')

void
dev_wl_initfontdict(fe, wlfi, k, c, nc, kfp)
struct font_entry *fe;
struct wlfntinfo *wlfi;
int k, c, nc;
FILE *kfp;
{
    char buffer[WFLEN], *be;
    int len, i;
    char *charstr, *p;
    int c1, c2;
    struct wlchar_entry *ce;

    while (fgets(buffer, WFLEN, kfp) != NULL) {
	len = strlen(buffer);
	if (buffer[0] == '<' && !strncmp(buffer+len-6, "CompD", 5)) {
	    if (c == htoi(buffer+len-12, &be)) {
		len = (len-16)/2;
		charstr = (char *)malloc((unsigned)len);
		for (i = 0, p = charstr; i < len; i++) {
		    c1 = buffer[i*2+1];
		    c2 = buffer[i*2+2];
		    *p++ = (hex(c1)<<4) | hex(c2);
		}
		ce = wlfi->ch+k;
		/* open font dict before first char */
		if (getpd(&pd)) {
		    wl_type1_prologue1(pd.pd_font);
		    cnum_type1_encoding(nc >= NPACKPSCHARS ? NPACKPSCHARS : nc);
		    wl_type1_prologue2();
		}
		ce->dev_font = pd.pd_font;
		ce->dev_char = pd.pd_char;
		wl_type1_char(ce->dev_char, charstr, len);
		if (lastpd(pd))
		    wl_endfontdict();
		free(charstr);
		return;
	    }
	}
    }
    Warning("The charstring of char %x in %s (wadalab) missing", c, fe->n);
}

dev_wl_endfontdict()
{
    if (!lastpd(pd))
	wl_endfontdict();
}

wl_endfontdict()
{
    char dictname[STRSIZE];

    wl_type1_epilogue();
    (void)sprintf(dictname, "%s-p%d", FontBase, pd.pd_font);
    po.po_dev_name = dictname;
    psfindfontop(psfname(pd.pd_font), &po);
}

void
dev_wl_initfe(fe)
struct font_entry *fe;
{
    DEV_FONT wl_fontdict();
    int wl_setchar(), wl_setstring();
    int wl_setchar_abs(), wl_setstring_abs();

    fe->dev_fontdict = wl_fontdict;
    if (bifpos_rel(jfmfinfo(fe)->jfm_bf)) {
	fe->dev_setchar = wl_setchar;
	fe->dev_setstring = wl_setstring;
    } else {
	fe->dev_setchar = wl_setchar_abs;
	fe->dev_setstring = wl_setstring_abs;
    }
}

wl_setchar(c)
int c;
{
    struct wlchar_entry *ce;
    int cw;

    ce = &(wlfinfo(curfontent)->ch[jis_to_idx94(c)]);
    begin_string();
    pschar(ce->dev_char);
    *ps_move += (cw = ce->tfmw);
    return cw;
}

/* ARGSUSED */
wl_setstring(s, len)
char *s;
int len;
{
    Fatal("%s implementation error: wl_setstring", G_progname);
}

wl_setchar_abs(c)
int c;
{
    int cw;

    cw = wl_setchar(c);
    dev_setposn_abs(ps_h, ps_v);
    return cw;
}

/* ARGSUSED */
wl_setstring_abs(s, len)
char *s;
int len;
{
    Fatal("%s implementation error: wl_setstring_abs", G_progname);
}


/* jstfm
 */
dev_jswl_begfontdict(fe)
struct font_entry *fe;
{
    pd.pd_char = LASTPACKPSCHAR;
    get_jstfm_psbiops(fe, &po);
}

void
dev_jswl_initfe(fe)
struct font_entry *fe;
{
    DEV_FONT jswl_fontdict();
    int jswl_setchar(), jswl_setstring();
    int jswl_setchar_abs(), jswl_setstring_abs();

    fe->dev_fontdict = jswl_fontdict;
    if (bifpos_rel(jstfmfinfo(fe)->js_bf)) {
	fe->dev_setchar = jswl_setchar;
	fe->dev_setstring = jswl_setstring;
    } else {
	fe->dev_setchar = jswl_setchar_abs;
	fe->dev_setstring = jswl_setstring_abs;
    }
}

jswl_setchar(c)
int c;
{
    struct jstfmfntinfo *jsfi;
    int cw;

    jsfi = jstfmfinfo(curfontent);
    begin_string();
    pschar(jswlfinfo(jsfi)->ch[jsub_to_idx94(jsfi->jsubfont,c)].dev_char);
    *ps_move += (cw = jsfi->ch[c].tfmw);
    return cw;
}

/* ARGSUSED */
jswl_setstring(s, len)
char *s;
int len;
{
    char *sp;
    struct jstfmchar_entry *ce = jstfmfinfo(curfontent)->ch;
    struct jstfmfntinfo *jsfi;
    int cw;

    jsfi = jstfmfinfo(curfontent);
    begin_string();
    for (sp = s, cw = 0; sp < s+len; sp++) {
	pschar(jswlfinfo(jsfi)->ch[jsub_to_idx94(jsfi->jsubfont,*sp)].dev_char);
	cw += (ce+*sp)->tfmw;
    }
    *ps_move += cw;
    return cw;
}

jswl_setchar_abs(c)
int c;
{
    int cw;

    cw = jswl_setchar(c);
    dev_setposn_abs(ps_h, ps_v);
    return cw;
}

/* ARGSUSED */
jswl_setstring_abs(s, len)
char *s;
int len;
{
    char *sp;
    struct jstfmchar_entry *ce = jstfmfinfo(curfontent)->ch;
    struct jstfmfntinfo *jsfi;
    int cw, w;

    jsfi = jstfmfinfo(curfontent);
    for (sp = s, cw = 0; sp < s+len; sp++) {
	begin_string();
	pschar(jswlfinfo(jsfi)->ch[jsub_to_idx94(jsfi->jsubfont,*sp)].dev_char);
	end_string();
	cw += (w = (ce+*sp)->tfmw);
	*ps_move += w;
	dev_setposn_abs(ps_h, ps_v);
    }
    return cw;
}


/*
 */
static char *StdHW="32";
static char *StdVW="32";
/*static char *UniqueId="9876";*/

time_t time();
char *ctime();

wl_type1_prologue1(fid)
int fid;
{
    /*time_t now = time((time_t *)NULL);*/

    EMIT(outfp, "%%%%BeginFont: %s-p%d\n", FontBase, fid);

    EMIT(outfp, "%%!PS-AdobeFont-1.0: %s-p%d %s\n",
	 FontBase, fid, version_str);
    /*EMIT(outfp, "%%%%Creation Date: %s", ctime(&now));*/
    EMIT(outfp, "%%%%VMusage: 100000 100000\n");	/* dummy */
    EMIT(outfp, "11 dict begin\n");
    EMIT(outfp, "/FontInfo 8 dict dup begin\n");
    EMIT(outfp, "/version (%s) readonly def\n", version_str);
    EMIT(outfp, "/FullName (%s-p%d) readonly def\n", FontBase, fid);
    EMIT(outfp, "/FamilyName (%s) readonly def\n", FontBase);
    EMIT(outfp, "/Weight (Regular) readonly def\n");
    EMIT(outfp, "/ItalicAngle 0 def\n");
    EMIT(outfp, "/isFixedPitch true def\n");
    EMIT(outfp, "/UnderlinePosition 0 def\n");
    EMIT(outfp, "/UnderlineThickness 0 def\n");
    EMIT(outfp, "end readonly def\n");
    EMIT(outfp, "/FontName /%s-p%d def\n", FontBase, fid);
}

wl_type1_prologue2()
{
    EMIT(outfp, "/PaintType 0 def\n");
    EMIT(outfp, "/FontType 1 def\n");
    EMIT(outfp, "/FontMatrix [.001 0 0 .001 0 -0.16] readonly def\n");
    /* should not have Uniqueid */
    /*EMIT(outfp, "/UniqueId %s def\n", UniqueId);*/
    EMIT(outfp, "/FontBBox [0 0 1000 1000] readonly def\n");
    EMIT(outfp, "currentdict end\n");
    EMIT(outfp, "currentfile eexec\n");

    begin_eexec();
    e_printf("dup /Private 14 dict dup begin\n");
    e_printf("/-|{string currentfile exch readstring pop}executeonly def\n");
    e_printf("/|-{noaccess def}executeonly def\n");
    e_printf("/|{noaccess put}executeonly def\n");
    e_printf("/BlueValues [] |-\n");
    e_printf("/OtherBlues [] |-\n");
    e_printf("/MinFeature{16 16} |-\n");
    e_printf("/StdHW [ %s ] |-\n", StdHW);
    e_printf("/StdVW [ %s ] |-\n", StdVW);
    e_printf("/ForceBold false def\n");
    e_printf("/password 5839 def\n");
    /* should not have Uniqueid */
    /*e_printf("/UniqueId %s def\n", UniqueId);*/
    e_printf("/OtherSubrs [] |-\n");
    e_printf("/Subrs 5 array\n");
    e_printf("dup 0 15 -| \020\2771p|\020\024\020=-\223D\\\342R |\n");
    e_printf("dup 1 9 -| \020\2771py\274\366Uz |\n");
    e_printf("dup 2 9 -| \020\2771py\275\304\236i |\n");
    e_printf("dup 3 5 -| \020\2771p\371 |\n");
    e_printf("dup 4 12 -| \020\2771p~\266+6\034\3446z |\n");
    e_printf("|-\n");
    e_printf("2 index /CharStrings 257 dict dup begin\n");
    e_printf("/.notdef 10 -| \020\277\061\160\171\312\070\217\347\143 |-\n");
}

wl_type1_char(c, cstr, len)
int c;
char *cstr;
int len;
{
    int i;

    e_printf("/c%02X %d -| ", c, len);
    for (i = 0; i < len; i++)
	e_putchar((unsigned)*(cstr+i));
    e_printf(" |-\n");
}

wl_type1_epilogue()
{
    e_printf("end\n");
    e_printf("end\n");
    e_printf("readonly put\n");
    e_printf("noaccess put\n");
    e_printf("dup/FontName get exch definefont pop\n");
    e_printf("mark currentfile closefile\n");
    end_eexec();

    EMIT(outfp, "cleartomark\n");

    EMIT(outfp, "%%%%EndFont\n");
}
