/*
 * config for builtin font
 */

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

BOOLEAN usespsmod = FALSE;


/* bifont & bikanji
 */
void getbuiltin();
struct confop mapcop = {
    "map",
    getbuiltin
};
struct confop bicop = {
    "builtin",
    getbuiltin
};
void getbifont();
struct confop bfcop = {
    "bifont",
    getbifont
};
void getbikanji();
struct confop bkcop = {
    "bikanji",
    getbikanji
};

#define	BF_NAME_STRICT	0
#define	BF_NAME_INITIAL	1
#define	BF_NAME_REG	2

#define	BF_TYPE_TFM	0
#define	BF_TYPE_KAN	1	/* backward compatibility */
#define	BF_TYPE_SUB	2	/* subfont */
#define	BF_TYPE_JFM	3

#define	BF_FONT_TFM	0
#define	BF_FONT_NAT	1
#define	BF_FONT_EQU	2
#define	BF_FONT_SPC	3
#define	BF_FONT_FRC	4
#define	BF_FONT_EM	5
#define	BF_FONT_SCL	6

#define	BF_POS_CLOSED	0
#define	BF_POS_REL	1
#define	BF_POS_ABS	2
#define	BF_POS_UNDEF	3

#define	BF_KIND_PSNAME	0
#define	BF_KIND_PSEXEC	1
#define	BF_KIND_TYPE1	2
#define	BF_KIND_FT	3
#define	BF_KIND_FTO	4
#define	BF_KIND_VFLIB	5
#define	BF_KIND_VFLIBO	6

static int mf_kind[] = {
    MF_KIND_PRINTER,
    MF_KIND_PRINTER,
    MF_KIND_TYPE1,
    MF_KIND_FT,
    MF_KIND_FTO,
    MF_KIND_VFLIB,
    MF_KIND_VFLIBO,
};

struct bifont {
    char *bf_name;
    int bf_len;
    char bf_mode_name;
    char bf_mode_type;
    char bf_mode_font;
    char bf_mode_pos;
    int bf_stand;
    int bf_scale;
    char bf_font_kind;
    int bf_bold;
    char *bf_cs_enc;
    char *bf_psfont;	/* PSfont name */
    char *bf_psfile;	/* PSfont file (type1, truetype) */
    char *bf_psmod;	/* modification by PS program */
    char *bf_psenc;
    char bf_coding;
    struct font_entry *bf_repfe;
    struct bifont *bf_next;
};
struct bifont *bifonts = NULL;
struct bifont **nextbf = &bifonts;

struct bifont selfbifont = {
    "", 0,
    BF_NAME_STRICT, BF_TYPE_TFM, BF_FONT_TFM, BF_POS_REL,
    0, 0, BF_KIND_PSNAME, 0, NULL,
    NULL, NULL, NULL, NULL, BF_CODING_JIS,
    NULL, NULL,
};

void getbuiltinfont();

void
getbuiltin()
{
    getbuiltinfont("builtin", &nextbf,
		   BF_NAME_STRICT, BF_TYPE_TFM, BF_FONT_TFM, BF_FONT_SPC);
}

void
getbifont()
{
    getbuiltinfont("bifont", &nextbf,
		   BF_NAME_STRICT, BF_TYPE_TFM, BF_FONT_TFM, BF_FONT_SPC);
}

void
getbikanji()
{
    getbuiltinfont("bikanji", &nextbf,
		   BF_NAME_INITIAL, BF_TYPE_KAN, BF_FONT_NAT, BF_FONT_NAT);
}

void
getbuiltinfont(cop, next, defm_name, defm_type, defm_font, defm_font_fix)
char *cop;
struct bifont ***next;
char defm_name, defm_type, defm_font, defm_font_fix;
{
    char field_name[STRSIZE];
    char field_mode[STRSIZE];
    char field_psfont[STRSIZE];
    char field_psopt1[STRSIZE];
    char field_psopt2[STRSIZE];
    struct bifont *bf;
    char *mode, *he, *psf, *psfl, *psm, *pse, *p;
    char path[PATHLEN];
    char encpath[PATHLEN];

    getfield(field_name);
    getfield(field_mode);
    getqfield(field_psfont);
    getoqfield(field_psopt1);
    getoqfield(field_psopt2);
    skipline();
    bf = NEW(struct bifont, cop);
    bf->bf_name = strsave(field_name);
    bf->bf_len = strlen(field_name);
    if (strcmp(field_mode, "fixed") == 0) {
	bf->bf_mode_name = defm_name;
	bf->bf_mode_type = defm_type;
	bf->bf_mode_font = defm_font_fix;
	bf->bf_mode_pos = BF_POS_UNDEF;
    } else if (strcmp(field_mode, "var") == 0) {
	bf->bf_mode_name = defm_name;
	bf->bf_mode_type = defm_type;
	bf->bf_mode_font = BF_FONT_TFM;
	bf->bf_mode_pos = BF_POS_UNDEF;
    } else {
	mode = field_mode;
	switch (*mode++) {
	case 'T':
	    bf->bf_mode_type = BF_TYPE_TFM;
	    break;
	case 'K':
	    bf->bf_mode_type = BF_TYPE_KAN;
	    break;
	case 'S':
	    bf->bf_mode_type = BF_TYPE_SUB;
	    break;
	case 'J':
	    bf->bf_mode_type = BF_TYPE_JFM;
	    break;
	case '*':
	default:
	    bf->bf_mode_type = defm_type;
	    break;
	}
	switch (*mode++) {
	case 'S':
	    bf->bf_mode_name = BF_NAME_STRICT;
	    break;
	case 'I':
	    bf->bf_mode_name = BF_NAME_INITIAL;
	    break;
	case 'R': /* not implemented */
	case '*':
	default:
	    bf->bf_mode_name = defm_name;
	    break;
	}
	switch (*mode++) {
	case 'T':
	    if (*mode == '(') {
		bf->bf_mode_font = BF_FONT_SCL;
		bf->bf_scale = strtol(mode+1, &he, 10);
		/* *he == ')' */
		mode = he+1;
	    } else
		bf->bf_mode_font = BF_FONT_TFM;
	    break;
	case 'N':
	    bf->bf_mode_font = BF_FONT_NAT;
	    break;
	case 'E':
	    bf->bf_mode_font = BF_FONT_EQU;
	    /* *mode == '(' */
	    bf->bf_stand = htoi(++mode, &he);
	    /* *he == ')' */
	    mode = he+1;
	    break;
	case 'S':
	    bf->bf_mode_font = BF_FONT_SPC;
	    break;
	case 'F':
	    bf->bf_mode_font = BF_FONT_FRC;
	    /* *mode == '(' */
	    bf->bf_stand = htoi(++mode, &he);
	    /* *he == ')' */
	    mode = he+1;
	    break;
	case 'M':
	    bf->bf_mode_font = BF_FONT_EM;
	    break;
	case '*':
	default:
	    bf->bf_mode_font = defm_font;
	    break;
	}
	switch (*mode++) {
	case 'R':
	default:
	    bf->bf_mode_pos = BF_POS_REL;
	    break;
	case 'A':
	    bf->bf_mode_pos = BF_POS_ABS;
	    break;
	case '*':
	    bf->bf_mode_pos = BF_POS_UNDEF;
	    break;
	}
    }
    psf = psfl = psm = pse = NULL;
    if (field_psfont[0] == FDQUO) {
	bf->bf_font_kind = BF_KIND_PSEXEC;
	field_psfont[strlen(field_psfont)-1] = '\0';
	psf = field_psfont+1;
	if (field_psopt1[0] == '<') {
	    defexpand(encpath, field_psopt1+1);
	    pse = encpath;
	}
    } else {
	if (field_psopt1[0] != '\0') {
	    psm = field_psopt1;
	    if (psm[0] == FDQUO) {
		psm[strlen(psm)-1] = '\0';
		psm++;
	    }
	}
	if (field_psfont[0] == '<') {
	    bf->bf_font_kind = BF_KIND_TYPE1;
	    psfl = field_psfont+1;
	    if (psfl[0] == '<')	/* backward compatibility for wadalab font */
		psfl++;
	    defexpand(path, psfl);
	    psfl = path;
	    if (field_psopt2[0] == '<') {
		defexpand(encpath, field_psopt2+1);
		pse = encpath;
	    }
	} else if (field_psfont[0] == ':') {
	    psfl = field_psfont+1;
	    if (psfl[0] == '*') {
		bf->bf_font_kind = BF_KIND_FT;
		psfl++;
	    } else
		bf->bf_font_kind = BF_KIND_FTO;
	    if (psfl[0] == '(') {
		bf->bf_bold = strtol(psfl+1, &he, 10);
		/* *he == ')' */
		psfl = he+1;
	    } else
		bf->bf_bold = -1;
	    if (psfl[0] == '[') {
		for (p = psfl+1; *p != ']' && *p != '\0'; p++)
		    ;
		if (*p == '\0') {
		    Warning("illegal map line");
		    return;
		}
		*p = '\0';
		bf->bf_cs_enc = strsave(psfl+1);
		psfl = p+1;
	    } else
		bf->bf_cs_enc = "";
	    defexpand(path, psfl);
	    psfl = path;
	    if (field_psopt2[0] == '<') {
		defexpand(encpath, field_psopt2+1);
		pse = encpath;
	    }
	} else if (field_psfont[0] == '^') {
	    psfl = field_psfont+1;
	    if (psfl[0] == '*') {
		bf->bf_font_kind = BF_KIND_VFLIB;
		psfl++;
	    } else
		bf->bf_font_kind = BF_KIND_VFLIBO;
	} else {
	    if (field_psopt1[0] == '@') {
		if (field_psopt1[1] == 'j')
		    bf->bf_coding = BF_CODING_JIS;
		else if (field_psopt1[1] == 'e')
		    bf->bf_coding = BF_CODING_EUC;
		else
		    bf->bf_coding = BF_CODING_SJIS;
	    } else
		bf->bf_coding = BF_CODING_JIS;
	    bf->bf_font_kind = BF_KIND_PSNAME;
	    psf = field_psfont;
	    psm = NULL;
	}
    }
    bf->bf_psfont = (psf != NULL) ? strsave(psf) : NULL;
    bf->bf_psfile = (psfl != NULL) ? strsave(psfl) : NULL;
    bf->bf_psmod = (psm != NULL) ? strsave(psm) : NULL;
    bf->bf_psenc = (pse != NULL) ? strsave(pse) : NULL;
    bf->bf_repfe = NULL;
    bf->bf_next = NULL;
    **next = bf;
    *next = &(bf->bf_next);
}

comp_bfname(fname, bf)
char *fname;
struct bifont *bf;
{
    char *bname;

    for (bname = bf->bf_name; *bname != '\0'; bname++, fname++) {
	if (*bname == '%') {
	    if (*++bname == 'd') {
		if ('0' <= *fname && *fname <= '9') {
		    for (fname++; '0' <= *fname && *fname <= '9'; fname++)
			;
		    --fname;
		    continue;
		} else
		    return FALSE;
	    } else
		return FALSE;
	} else if (*bname != *fname)
	    return FALSE;
    }
    if (*fname == '\0')
	return TRUE;
    else
	return (bf->bf_mode_name == BF_NAME_INITIAL);
}

struct bifont *
findbifont(name)
char *name;
{
    struct bifont *bf;

    for (bf = bifonts; bf != NULL; bf = bf->bf_next)
	if (bf->bf_mode_type == BF_TYPE_TFM)
	    if (comp_bfname(name, bf))
		return bf;
    return NULL;
}

struct bifont *
findbksub(name)
char *name;
{
    struct bifont *bf;
    char *subbeg, *subend;

    for (bf = bifonts; bf != NULL; bf = bf->bf_next) {
	if (bf->bf_mode_type == BF_TYPE_SUB) {
	    if (match_subf(bf->bf_name, name,
			   bf->bf_mode_name == BF_NAME_INITIAL,
			   &subbeg, &subend))
		return bf;
	} else if (bf->bf_mode_type == BF_TYPE_KAN) {
	    if (comp_bfname(name, bf)) {
		foundjsubf = getjsubfont(name+bf->bf_len, &subend);
		return bf;
	    }
	}
    }
    return NULL;
}

struct bifont *
findbkjfm(name)
char *name;
{
    struct bifont *bf;

    for (bf = bifonts; bf != NULL; bf = bf->bf_next)
	if (bf->bf_mode_type == BF_TYPE_JFM ||
	    bf->bf_mode_type == BF_TYPE_KAN)
	    if (comp_bfname(name, bf))
		return bf;
    return NULL;
}

dev_set_repfe(bi, fe)
struct bifont *bi;
struct font_entry *fe;
{
    bi->bf_repfe = fe;
}

struct font_entry *
dev_get_repfe(bi)
struct bifont *bi;
{
    return bi->bf_repfe;
}

char *
dev_fontpath(bi)
struct bifont *bi;
{
    return bi->bf_psfile;
}

dev_bold(bi)
struct bifont *bi;
{
    return bi->bf_bold;
}

char *
dev_cs_enc(bi)
struct bifont *bi;
{
    return bi->bf_cs_enc;
}

char *
dev_encfile(bi)
struct bifont *bi;
{
    return bi->bf_psenc;
}

dev_mf_kind(bf)
struct bifont *bf;
{
    return mf_kind[bf->bf_font_kind];
}

dev_is_tfm(fe, tfmmode)
struct font_entry *fe;
int tfmmode;
{
    struct bifont *bi;

    if ((bi = findbifont(fe->n)) == NULL) {
	if (tfmmode&ACC_SELF)
	    bi = &selfbifont;
	else
	    return FALSE;
    }
    biaccinfo(fe)->bf = bi;
    if (bi->bf_font_kind == BF_KIND_PSEXEC || bi->bf_psmod != NULL)
	usespsmod = TRUE;
    return TRUE;
}

dev_tfm_kind(fe)
struct font_entry *fe;
{
    return mf_kind[tfmfinfo(fe)->tfm_bf->bf_font_kind];
}

static void
bipave(path, proto, biname)
char *path, *proto, *biname;
{
    char *p, *s, *t;
    char *pend;
    int len;
    char buf[32];

    for (p = path, s = proto, pend = path+PATHLEN-1; *s != '\0'; s++)
	if (*s == '%') {
	    switch (*++s) {
	    case 'b':
		t = biname;
		break;
	    default:
		*(t = buf) = *s;  *(t+1) = '\0';
		break;
	    }
	    if (p + (len = strlen(t)) <= pend) {
		(void)strncpy(p, t, len);
		p += len;
	    } else
		Fatal("font path too long %s", proto);
	} else if (p < pend) {
	    *p++ = *s;
	} else
	    Fatal("font path too long %s", proto);
    *p = '\0';
}

t1tobi(bi, t1fname)
struct bifont *bi;
char *t1fname;
{
    char psprog[PATHLEN];

    if (bi->bf_font_kind == BF_KIND_TYPE1) {
	if (bi->bf_psmod == NULL) {
	    bi->bf_font_kind = BF_KIND_PSNAME;
	    bi->bf_psfont = strsave(t1fname);
	} else {
	    bi->bf_font_kind = BF_KIND_PSEXEC;
	    bipave(psprog, bi->bf_psmod, t1fname);
	    bi->bf_psfont = strsave(psprog);
	}
    }
}

fttobi(bi, ftfname)
struct bifont *bi;
char *ftfname;
{
    char psprog[PATHLEN];

    if (bi->bf_font_kind == BF_KIND_FTO) {
	if (bi->bf_psmod == NULL) {
	    bi->bf_font_kind = BF_KIND_PSNAME;
	    bi->bf_psfont = strsave(ftfname);
	} else {
	    bi->bf_font_kind = BF_KIND_PSEXEC;
	    bipave(psprog, bi->bf_psmod, ftfname);
	    bi->bf_psfont = strsave(psprog);
	}
    }
}

dev_is_jstfm(fe, tfmmode)
struct font_entry *fe;
int tfmmode;
{
    struct bifont *bi;

    foundjsubf = 0;
    if ((bi = findbksub(fe->n)) != NULL)
	if (foundjsubf != 0) {
	    biaccinfo(fe)->bf = bi;
	    biaccinfo(fe)->jsubf = foundjsubf;
	    if (bi->bf_font_kind == BF_KIND_PSEXEC || bi->bf_psmod != NULL)
		usespsmod = TRUE;
	    return TRUE;
	}
    return FALSE;
}

char *
dev_jstfm_parent(bf, name)
struct bifont *bf;
char *name;
{
    char *subbeg, *subend;
    int prelen;
    static char pname[PATHLEN];

    if (bf->bf_mode_type == BF_TYPE_SUB) {
	if (match_subf(bf->bf_name, name,
		       bf->bf_mode_name == BF_NAME_INITIAL,
		       &subbeg, &subend)) {
	    prelen = subbeg-name;
	    strncpy(pname, name, prelen);
	    strcpy(pname+prelen, subend+1);
	    return pname;
	}
    } else if (bf->bf_mode_type == BF_TYPE_KAN) {
	if (getjsubfont(name+bf->bf_len, &subend)) {
	    strncpy(pname, name, bf->bf_len);
	    strcpy(pname, subend+1);
	    return pname;
	}
    }
    Fatal("%s implementation error: dev_jstfm_parent", G_progname);
}

dev_jstfm_kind(fe)
struct font_entry *fe;
{
    return mf_kind[jstfmfinfo(fe)->js_bf->bf_font_kind];
}

dev_is_jfm(fe, tfmmode)
struct font_entry *fe;
int tfmmode;
{
    struct bifont *bi;

    if ((bi = findbkjfm(fe->n)) == NULL) {
	if (tfmmode&ACC_SELF)
	    bi = &selfbifont;
	else
	    return FALSE;
    }
    biaccinfo(fe)->bf = bi;
    if (bi->bf_font_kind == BF_KIND_PSEXEC || bi->bf_psmod != NULL)
	usespsmod = TRUE;
    return TRUE;
}

dev_jfm_kind(fe)
struct font_entry *fe;
{
    return mf_kind[jfmfinfo(fe)->jfm_bf->bf_font_kind];
}


bifpos_relun(bf)
struct bifont *bf;
{
    return (bf->bf_mode_pos == BF_POS_REL ||
	    bf->bf_mode_pos == BF_POS_UNDEF);
}

bifpos_rel(bf)
struct bifont *bf;
{
    return (bf->bf_mode_pos == BF_POS_REL);
}

bif_coding(bf)
struct bifont *bf;
{
    return bf->bf_coding;
}

char *
newbifontname()
{
    static int bifcount = 0;
    static char newbifname[STRSIZE];

    (void)sprintf(newbifname, "bf%d", bifcount++);
    return newbifname;
}

char *
newbifont(bf)
struct bifont *bf;
{
    char *nbf;

    if (bf->bf_font_kind == BF_KIND_PSEXEC) {
	EMIT(outfp, "/%s %s\n", nbf = newbifontname(), bf->bf_psfont);
	bf->bf_psfont = strsave(nbf);
	bf->bf_font_kind = BF_KIND_PSNAME;
    }
    return bf->bf_psfont;
}

struct {
    char *opname;
    BOOLEAN extraarg;
} pops[] = {
    {"BFT", FALSE},	/* BF_FONT_TFM */
    {"BFE", FALSE},	/* BF_FONT_NAT */
    {"BFE", FALSE},	/* BF_FONT_EQU */
    {"BFF", TRUE},	/* BF_FONT_SPC */
    {"BFF", TRUE},	/* BF_FONT_FRC */
    {"BFE", FALSE},	/* BF_FONT_EM */
    {"BFE", FALSE},	/* BF_FONT_SCL */
};

get_tfm_psbiops(fe, po)
struct font_entry *fe;
struct psbiops *po;
{
    struct tfmfntinfo *tfmfi;
    struct bifont *bf;

    tfmfi = tfmfinfo(fe);
    bf = tfmfi->tfm_bf;
    switch (bf->bf_mode_font) {
    case BF_FONT_TFM:
	po->po_size = fe->s;
	break;
    case BF_FONT_NAT:
	po->po_size = tfmfi->ch[tfmfi->lastfntchar].tfmw;
	break;
    case BF_FONT_EQU:
	po->po_size = tfmfi->ch[bf->bf_stand].tfmw;
	break;
    case BF_FONT_SPC:
	po->po_size = tfmfi->ch[0x20].tfmw;
	po->po_stand = 0x20;
	po->po_stlen = 1;
	break;
    case BF_FONT_FRC:
	po->po_size = tfmfi->ch[bf->bf_stand].tfmw;
	po->po_stand = bf->bf_stand;
	po->po_stlen = 1;
	break;
    case BF_FONT_EM:
	po->po_size = tfmfi->em;
	break;
    case BF_FONT_SCL:
	po->po_size = scale(bf->bf_scale,fe->s);
	break;
    }
    if (bf == &selfbifont)
	po->po_dev_name = fe->n;
    else {
	po->po_dev_name = NULL;
	po->po_bf = bf;
    }
    po->po_mode_font = bf->bf_mode_font;
}

get_jstfm_psbiops(fe, po)
struct font_entry *fe;
struct psbiops *po;
{
    struct jstfmfntinfo *jstfmfi;
    struct bifont *bf;

    jstfmfi = jstfmfinfo(fe);
    bf = jstfmfi->js_bf;
    switch (bf->bf_mode_font) {
    case BF_FONT_TFM:
	po->po_size = fe->s;
	break;
    case BF_FONT_NAT:
	/* For now, it is ok to assume that lastchars of all subfonts
	   have the same `standard' metric */
	po->po_size = jstfmfi->ch[jstfmfi->lastfntchar].tfmw;
	break;
    case BF_FONT_EQU:	/* TO DO */
	po->po_size = jstfmfi->ch[bf->bf_stand].tfmw;
	break;
    case BF_FONT_SPC:	/* TO DO */
	po->po_size = jstfmfi->ch[0x20].tfmw;
	po->po_stand = 0x20;
	po->po_stlen = 1;
	break;
    case BF_FONT_FRC:	/* TO DO */
	po->po_size = jstfmfi->ch[bf->bf_stand].tfmw;
	po->po_stand = bf->bf_stand;
	po->po_stlen = 1;
	break;
    case BF_FONT_EM:
	po->po_size = jstfmfi->em;
	break;
    case BF_FONT_SCL:
	po->po_size = scale(bf->bf_scale,fe->s);
	break;
    }
    po->po_dev_name = NULL;
    po->po_bf = bf;
    po->po_mode_font = bf->bf_mode_font;
}

char *
tmp_psf(bi)
struct bifont *bi;
{
    return bi->bf_psfont;
}

get_jfm_psbiops(fe, po)
struct font_entry *fe;
struct psbiops *po;
{
    struct jfmfntinfo *jfmfi;
    struct bifont *bf;

    jfmfi = jfmfinfo(fe);
    bf = jfmfi->jfm_bf;
    switch (bf->bf_mode_font) {
    case BF_FONT_TFM:
	po->po_size = fe->s;
	break;
    case BF_FONT_NAT:
	po->po_size = jfmfi->ch[0].tfmw;	/* == zw */
	break;
    case BF_FONT_EQU:
	po->po_size = jfmfi->ch[getctype(bf->bf_stand,jfmfi)].tfmw;
	break;
    case BF_FONT_SPC:
	po->po_size = jfmfi->ch[getctype(0x2121,jfmfi)].tfmw;
	po->po_stand = 0x2121;
	po->po_stlen = 2;
	break;
    case BF_FONT_FRC:
	po->po_size = jfmfi->ch[getctype(bf->bf_stand,jfmfi)].tfmw;
	po->po_stand = bf->bf_stand;
	po->po_stlen = 2;
	break;
    case BF_FONT_EM:
	po->po_size = jfmfi->em;
	break;
    case BF_FONT_SCL:
	po->po_size = scale(bf->bf_scale,fe->s);
	break;
    }
    if (bf == &selfbifont)
	po->po_dev_name = fe->n;
    else {
	po->po_dev_name = NULL;
	po->po_bf = bf;
    }
    po->po_mode_font = bf->bf_mode_font;
}

psgetfontsize(po)
struct psbiops *po;
{
    return po->po_size;
}

psfindfontop(psfn, po)
char *psfn;
struct psbiops *po;
{
    if (po->po_dev_name == NULL)
	po->po_dev_name = newbifont(po->po_bf);
    psfindfop(psfn, po);
}

psfindsubfop(psfn, po)
char *psfn;
struct psbiops *po;
{
    struct bifont *bf;
    char psprog[PATHLEN];

    bf = po->po_bf;
    if (bf->bf_psmod != NULL) {
	bipave(psprog, bf->bf_psmod, po->po_dev_name);
	EMIT(outfp, "/%s %s\n", po->po_dev_name = newbifontname(), psprog);
    }
    psfindfop(psfn, po);
}

psfindfop(psfn, po)
char *psfn;
struct psbiops *po;
{
    if (pops[po->po_mode_font].extraarg)
	codetopsstr(po->po_stand, po->po_stlen);
    EMIT(outfp, "/%s /%s %.3f %.3f %s\n", psfn, po->po_dev_name,
	 (float)(po->po_size)/(float)hconv, -(float)(po->po_size)/(float)vconv,
	 pops[po->po_mode_font].opname);
}

getpd(pd)
struct pd *pd;
{
    if (pd->pd_char++ == LASTPACKPSCHAR) {
	pd->pd_font = dev_newdevfont();
	pd->pd_char = FIRSTPACKPSCHAR;
	return TRUE;
    } else if (pd->pd_char == NPACKPSCHARS)
	pd->pd_char = 0;
    return FALSE;
}
