/*
 * VFlib font (family of vector fonts)
 */
#include	"defs.h"
#include	"global.h"
#include	"bifont.h"

/* ratio of depth of char (1 = 1<<20) */
#define	DEPTHRATIO	165565

char *vfontcap = NULL;
BOOLEAN vfl_init = FALSE;

void getvfcap();
struct confop vfccop = {
    "vfontcap",
    getvfcap
};

void
getvfcap()
{
    char field_file[PATHLEN];
    char vfcap[PATHLEN];

    getfield(field_file);
    skipline();
    defexpand(vfcap, field_file);
    vfontcap = strsave(vfcap);
}

int depthratio = DEPTHRATIO;

void getvflbase();
struct confop vfbcop = {
    "vflbaseline",
    getvflbase
};

void
getvflbase()
{
    char field_number[PATHLEN];
    char ratio[PATHLEN];

    getfield(field_number);
    skipline();
    defexpand(ratio, field_number);
    depthratio = atoi(ratio);
}

#ifdef VFLIB

void
init_vfl_fontinfo(fe)
struct font_entry *fe;
{
    int	jmm_markchar();
    void read_vfl_fontinfo();

    biinifinfo(fe) = alloc_jbiinif(biaccinfo(fe)->bf);
    fe->fnt_markchar = jmm_markchar;
    fe->fnt_readfontinfo = read_vfl_fontinfo;
}

vfl_initialize()
{
    if (!vfl_init) {
#ifdef DEBUG
	if (Debuguser)
	    (void)fprintf(stderr, "VFlib initializing with %s\n", vfontcap);
#endif
	if (VF_Init(vfontcap) < 0)
	    Fatal("VFlib cannot be initialized");
	vfl_init = TRUE;
    }
}

struct vflfntinfo *
read_vfl_finfo(fe, bii, tfmw, settfmw)
struct font_entry *fe;
struct biinitfontinfo *bii;
int tfmw;
BOOLEAN settfmw;
{
    struct vflfntinfo *vflfi;
    char *vfln;
    BOOLEAN raster;
    int fid;
    int width, depth, height, bwid, size;
    int xoff, nwidth, ndepth, nheight;
    char *pixel, *npixel;
    long *outline;
    int i, c;
    extern int hconv, vconv;
    long *VF_GetOutline();

    vflfi = (struct vflfntinfo *)
	alloc_check(malloc((unsigned)sizeof(struct vflfntinfo)+
			   bii->maxc*sizeof(struct vflchar_entry)),
		    "vflfont info");
    vflfi->vfl_bf = bii->bf;

    for (i = 0; i <= bii->maxc; i++)
	vflfi->ch[i].dev_font = DEV_NULLFONT;
    vfln = dev_fontpath(vflfi->vfl_bf);
    raster = dev_mf_kind(vflfi->vfl_bf) == MF_KIND_VFLIB;
#ifdef DEBUG
    if (Debuguser)
	(void)fprintf(stderr, "VFlib openfont %s (for %s, %s)\n", vfln, fe->n,
		      raster ? "raster" : "outline");
#endif
    if ((fid = VF_OpenFont(vfln)) < 0) {
	Warning("VFlib font %s cannot be opened", vfln);
	return vflfi;
    }

    width = pixround(tfmw, hconv);
    depth = pixround(scale(tfmw,depthratio), vconv);
    height = pixround(tfmw, vconv);
    bwid = (width+7)>>3;
    size = height*bwid;
    if (raster) {
	if ((pixel = malloc(size)) == NULL)
	    Fatal("Unable to allocate memory for VFlib char\n");
	for (i = 0; i <= bii->maxc; i++) {
	    if (!(bii->mark[i]))
		continue;
	    if (settfmw)
		(vflfi->ch+i)->tfmw = tfmw;
	    memset(pixel, 0, size);
	    c = idx94_to_std(i);
	    VF_GetBitmap(c, fid, width, height, bwid, 0, pixel);
	    trim_bitmap(width, bwid, height, 0, depth, pixel,
			&nwidth, &nheight, &xoff, &ndepth, &npixel);
	    dev_jft_initfontdict(fe, vflfi, i, c, tfmw, 
				 nwidth, nheight, xoff, ndepth, npixel);
	}
	free(pixel);
    } else {
	dev_vflo_begfontdict();
	for (i = 0; i <= bii->maxc; i++) {
	    if (!(bii->mark[i]))
		continue;
	    if (settfmw)
		(vflfi->ch+i)->tfmw = tfmw;
	    c = idx94_to_std(i);
	    outline = VF_GetOutline(c, fid);
	    dev_vflo_initfontdict(fe, vflfi, i, c, tfmw,
				  width, height, depth, outline);
	    VF_FreeOutline(outline, fid);
	}
    }

    VF_CloseFont(fid);
    return vflfi;
}

void
read_vfl_fontinfo(fe)
struct font_entry *fe;
{
    struct biinitfontinfo *bii;
    struct jfmfntinfo *jfmfi;
    void read_jfm_finfo();
    int tfmw;

    vfl_initialize();

    bii = biinifinfo(fe);
    jfmfi = NEW(struct jfmfntinfo, "jfmfont info");
    jfmfi->jfm_bf = bii->bf;
    jfmfinfo(fe) = jfmfi;	/* set only to use in read_jfm_finfo */
    read_jfm_finfo(fe);

    dev_jft_initfe(fe);
    tfmw = dev_jft_begfontdict(fe);
    vflfinfo(fe) = read_vfl_finfo(fe, bii, tfmw, TRUE);

    free((char *)bii);
    free((char *)jfmfi->ctype);
    free((char *)jfmfi->ch);
    free((char *)jfmfi);
}


/* jstfm
 */
void
init_jsvfl_fontinfo(fe)
struct font_entry *fe;
{
    struct jsubshare *jss;
    int	jsmm_markchar();
    void read_jsvfl_fontinfo();

    jss = jstfmfinfo(fe)->js_share;
    if (jss->jss_stat < JSS_INIT) {
	jss->jss_info = (struct jssinfo *)alloc_jbiinif(jss->jss_bf);
	jss->jss_stat = JSS_INIT;
    }
    jstfmfinfo(fe)->js_info = jss->jss_info;
    fe->fnt_markchar = jsmm_markchar;
    fe->fnt_readfontinfo = read_jsvfl_fontinfo;
}

void
read_jsvfl_fontinfo(fe)
struct font_entry *fe;
{
    struct biinitfontinfo *bii;
    struct jsubshare *jss;
    struct jstfmfntinfo *jstfmfi;
    void read_jstfm_finfo();
    int tfmw;

    vfl_initialize();

    read_jstfm_finfo(fe);

    dev_jsft_initfe(fe);
    jss = jstfmfinfo(fe)->js_share;
    if (jss->jss_stat < JSS_READ) {
	bii = (struct biinitfontinfo *)jss->jss_info;
	jstfmfi = jstfmfinfo(fe);
	tfmw = dev_jsft_begfontdict(fe);
	jss->jss_info = (struct jssinfo *)
	    read_vfl_finfo(fe, bii, tfmw, FALSE);
	jss->jss_stat = JSS_READ;
	free((char *)bii);
    }
    jstfmfinfo(fe)->js_info = jss->jss_info;
}

#else

void
init_vfl_fontinfo(fe)
struct font_entry *fe;
{
    int null_markchar();
    void read_null_fontinfo();

    Warning("This %s is not compiled with VFlib option.\nFont %s is ignored",
	    G_progname, fe->n);
    fe->fnt_markchar = null_markchar;
    fe->fnt_readfontinfo = read_null_fontinfo;
}

void
init_jsvfl_fontinfo(fe)
struct font_entry *fe;
{
    init_vfl_fontinfo(fe);
}
#endif
