/*
 * Hershey vector fonts.
 * Stuart Levy, slevy@ncsa.uiuc.edu
 * National Center for Supercomputing Applications,
 * University of Illinois 2001.
 */
#include <stdio.h>
#include <math.h>

#ifdef WIN32
# include <windows.h>
#endif
#include <GL/gl.h>

#include "sfont.h"

	/* Generated by "fonter" script */
char *hvecfont[128+96] = {	/* space .. 0x7F */
/*   */	"\4\4",
/* ! */	"\7\7RFRT RYQZR[SZRY",
/* " */	"\10\10NFNM VFVM",
/* # */	"\12\13SBLb YBRb LOZO KUYU",
/* $ */	"\12\12PBP_ TBT_ YIWGTFPFMGKIKKLMMNOOUQWRXSYUYXWZT[P[MZKX",
/* % */	"\14\14[FI[ NFPHPJOLMMKMIKIIJGLFNFPGSHVHYG[F WTUUTWTYV[X[ZZ[X[VYTWT",
/* & */	"\15\15\\O\\N[MZMYNXPVUTXRZP[L[JZIYHWHUISJRQNRMSKSIRGPFNGMIMKNNPQUXWZY[[[\\Z\\Y",
/* ' */	"\4\5SFRGRM SGRM SFTGRM",
/* ( */	"\7\5VBTDRGPKOPOTPYR]T`Vb",
/* ) */	"\5\7NBPDRGTKUPUTTYR]P`Nb",
/* * */	"\10\10RFRR MIWO WIMO",
/* + */	"\15\15RIR[ IR[R",
/* , */	"\5\5SZR[QZRYSZS\\R^Q_",
/* - */	"\15\15IR[R",
/* . */	"\5\5RYQZR[SZRY",
/* / */	"\7\7K^YF",
/* 0 */	"\12\12QFNGLJKOKRLWNZQ[S[VZXWYRYOXJVGSFQF",
/* 1 */	"\12\12NJPISFS[",
/* 2 */	"\12\12LKLJMHNGPFTFVGWHXJXLWNUQK[Y[",
/* 3 */	"\12\12MFXFRNUNWOXPYSYUXXVZS[P[MZLYKW",
/* 4 */	"\12\12UFKTZT UFU[",
/* 5 */	"\12\12WFMFLOMNPMSMVNXPYSYUXXVZS[P[MZLYKW",
/* 6 */	"\12\12XIWGTFRFOGMJLOLTMXOZR[S[VZXXYUYTXQVOSNRNOOMQLT",
/* 7 */	"\12\12YFO[ KFYF",
/* 8 */	"\12\12PFMGLILKMMONSOVPXRYTYWXYWZT[P[MZLYKWKTLRNPQOUNWMXKXIWGTFPF",
/* 9 */	"\12\12XMWPURRSQSNRLPKMKLLINGQFRFUGWIXMXRWWUZR[P[MZLX",
/* : */	"\5\5RMQNROSNRM RYQZR[SZRY",
/* ; */	"\5\5RMQNROSNRM SZR[QZRYSZS\\R^Q_",
/* < */	"\14\14ZIJRZ[",
/* = */	"\15\15IO[O IU[U",
/* > */	"\14\14JIZRJ[",
/* ? */	"\11\11LKLJMHNGPFTFVGWHXJXLWNVORQRT RYQZR[SZRY",
/* @ */	"\15\16WNVLTKQKOLNMMPMSNUPVSVUUVS QKOMNPNSOUPV WKVSVUXVZV\\T]Q]O\\L[JYHWGTFQFNGLHJJILHOHRIUJWLYNZQ[T[WZYYZX XKWSWUXV",
/* A */	"\10\11RFJ[ RFZ[ MTWT",
/* B */	"\12\12KFK[ KFTFWGXHYJYLXNWOTP KPTPWQXRYTYWXYWZT[K[",
/* C */	"\11\13ZKYIWGUFQFOGMILKKNKSLVMXOZQ[U[WZYXZV",
/* D */	"\12\12KFK[ KFRFUGWIXKYNYSXVWXUZR[K[",
/* E */	"\11\11LFL[ LFYF LPTP L[Y[",
/* F */	"\11\10LFL[ LFYF LPTP",
/* G */	"\11\13ZKYIWGUFQFOGMILKKNKSLVMXOZQ[U[WZYXZVZS USZS",
/* H */	"\12\13KFK[ YFY[ KPYP",
/* I */	"\3\4RFR[",
/* J */	"\7\10VFVVUYTZR[P[NZMYLVLT",
/* K */	"\12\12KFK[ YFKT POY[",
/* L */	"\11\7LFL[ L[X[",
/* M */	"\13\14JFJ[ JFR[ ZFR[ ZFZ[",
/* N */	"\12\13KFK[ KFY[ YFY[",
/* O */	"\12\13PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF",
/* P */	"\12\12KFK[ KFTFWGXHYJYMXOWPTQKQ",
/* Q */	"\12\13PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF SWY]",
/* R */	"\12\12KFK[ KFTFWGXHYJYLXNWOTPKP RPY[",
/* S */	"\11\12YIWGTFPFMGKIKKLMMNOOUQWRXSYUYXWZT[P[MZKX",
/* T */	"\10\10RFR[ KFYF",
/* U */	"\13\13KFKULXNZQ[S[VZXXYUYF",
/* V */	"\11\12JFR[ ZFR[",
/* W */	"\15\14HFM[ RFM[ RFW[ \\FW[",
/* X */	"\12\12KFY[ YFK[",
/* Y */	"\11\11JFRPR[ ZFRP",
/* Z */	"\12\12YFK[ KFYF K[Y[",
/* [ */	"\7\7OBOb PBPb OBVB ObVb",
/* \ */	"\7\7KFY^",
/* ] */	"\7\7TBTb UBUb NBUB NbUb",
/* ^ */	"\13\13JTROZT JTRPZT",
/* _ */	"\10\10J]Z]",
/* ` */	"\5\5SFRGQIQKRLSKRJ",
/* a */	"\10\12XMX[ XPVNTMQMONMPLSLUMXOZQ[T[VZXX",
/* b */	"\11\11LFL[ LPNNPMSMUNWPXSXUWXUZS[P[NZLX",
/* c */	"\10\11XPVNTMQMONMPLSLUMXOZQ[T[VZXX",
/* d */	"\10\12XFX[ XPVNTMQMONMPLSLUMXOZQ[T[VZXX",
/* e */	"\10\11LSXSXQWOVNTMQMONMPLSLUMXOZQ[T[VZXX",
/* f */	"\4\7WFUFSGRJR[ OMVM",
/* g */	"\10\12XMX]W`VaTbQbOa XPVNTMQMONMPLSLUMXOZQ[T[VZXX",
/* h */	"\10\12MFM[ MQPNRMUMWNXQX[",
/* i */	"\3\4QFRGSFREQF RMR[",
/* j */	"\4\5RFSGTFSERF SMS^RaPbNb",
/* k */	"\10\10MFM[ WMMW QSX[",
/* l */	"\3\4RFR[",
/* m */	"\16\17GMG[ GQJNLMOMQNRQR[ RQUNWMZM\\N]Q][",
/* n */	"\10\12MMM[ MQPNRMUMWNXQX[",
/* o */	"\10\12QMONMPLSLUMXOZQ[T[VZXXYUYSXPVNTMQM",
/* p */	"\11\11LMLb LPNNPMSMUNWPXSXUWXUZS[P[NZLX",
/* q */	"\10\12XMXb XPVNTMQMONMPLSLUMXOZQ[T[VZXX",
/* r */	"\6\7OMO[ OSPPRNTMWM",
/* s */	"\7\11XPWNTMQMNNMPNRPSUTWUXWXXWZT[Q[NZMX",
/* t */	"\5\7RFRWSZU[W[ OMVM",
/* u */	"\10\12MMMWNZP[S[UZXW XMX[",
/* v */	"\7\10LMR[ XMR[",
/* w */	"\13\13JMN[ RMN[ RMV[ ZMV[",
/* x */	"\7\11MMX[ XMM[",
/* y */	"\7\10LMR[ XMR[P_NaLbKb",
/* z */	"\7\11XMM[ MMXM M[X[",
/* { */	"\7\7TBRCQDPFPHQJRKSMSOQQ RCQEQGRISJTLTNSPORSTTVTXSZR[Q]Q_Ra QSSUSWRYQZP\\P^Q`RaTb",
/* | */	"\4\4RBRb",
/* } */	"\7\7PBRCSDTFTHSJRKQMQOSQ RCSESGRIQJPLPNQPURQTPVPXQZR[S]S_Ra SSQUQWRYSZT\\T^S`RaPb",
/* ~ */	"\14\14IUISJPLONOPPTSVTXTZS[Q ISJQLPNPPQTTVUXUZT[Q[O",

/*0x7F*/ 0,
	0,0,0,0,0,0,0,0,	/* 0x80 - 0x87 */
	0,0,0,0,0,0,0,0,	/* 0x88 - 0x8F */
	0,0,0,0,0,0,0,0,	/* 0x90 - 0x97 */
	0,0,0,0,0,0,0,0,	/* 0x98 - 0x9F */

	/* upper 128+32 .. 128+95 are from `fonter hrgks.gsf`,
	 * the Hershey Greek Simplex alphabet
	 */
/*   */	"\10\10",
/* ! */	"\5\5RFRT RYQZR[SZRY",
/* " */	"\10\10NFNM VFVM",
/* # */	"\12\13SBLb YBRb LOZO KUYU",
/* $ */	"\12\12PBP_ TBT_ YIWGTFPFMGKIKKLMMNOOUQWRXSYUYXWZT[P[MZKX",
/* % */	"\14\14[FI[ NFPHPJOLMMKMIKIIJGLFNFPGSHVHYG[F WTUUTWTYV[X[ZZ[X[VYTWT",
/* & */	"\15\15\\O\\N[MZMYNXPVUTXRZP[L[JZIYHWHUISJRQNRMSKSIRGPFNGMIMKNNPQUXWZY[[[\\Z\\Y",
/* ' */	"\5\5RHQGRFSGSIRKQL",
/* ( */	"\7\5VBTDRGPKOPOTPYR]T`Vb",
/* ) */	"\5\7NBPDRGTKUPUTTYR]P`Nb",
/* * */	"\10\10RFRR MIWO WIMO",
/* + */	"\15\15RIR[ IR[R",
/* , */	"\5\5SZR[QZRYSZS\\R^Q_",
/* - */	"\15\15IR[R",
/* . */	"\5\5RYQZR[SZRY",
/* / */	"\13\13[BIb",
/* 0 */	"\12\12QFNGLJKOKRLWNZQ[S[VZXWYRYOXJVGSFQF",
/* 1 */	"\12\12NJPISFS[",
/* 2 */	"\12\12LKLJMHNGPFTFVGWHXJXLWNUQK[Y[",
/* 3 */	"\12\12MFXFRNUNWOXPYSYUXXVZS[P[MZLYKW",
/* 4 */	"\12\12UFKTZT UFU[",
/* 5 */	"\12\12WFMFLOMNPMSMVNXPYSYUXXVZS[P[MZLYKW",
/* 6 */	"\12\12XIWGTFRFOGMJLOLTMXOZR[S[VZXXYUYTXQVOSNRNOOMQLT",
/* 7 */	"\12\12YFO[ KFYF",
/* 8 */	"\12\12PFMGLILKMMONSOVPXRYTYWXYWZT[P[MZLYKWKTLRNPQOUNWMXKXIWGTFPF",
/* 9 */	"\12\12XMWPURRSQSNRLPKMKLLINGQFRFUGWIXMXRWWUZR[P[MZLX",
/* : */	"\5\5RMQNROSNRM RYQZR[SZRY",
/* ; */	"\5\5RMQNROSNRM SZR[QZRYSZS\\R^Q_",
/* < */	"\14\14ZIJRZ[",
/* = */	"\15\15IO[O IU[U",
/* > */	"\14\14JIZRJ[",
/* ? */	"\11\11LKLJMHNGPFTFVGWHXJXLWNVORQRT RYQZR[SZRY",
/* @ */	"\15\16WNVLTKQKOLNMMPMSNUPVSVUUVS QKOMNPNSOUPV WKVSVUXVZV\\T]Q]O\\L[JYHWGTFQFNGLHJJILHOHRIUJWLYNZQ[T[WZYYZX XKWSWUXV",
/* A */	"\12\13RFJ[ RFZ[ MTWT",
/* B */	"\12\12KFK[ KFTFWGXHYJYLXNWOTP KPTPWQXRYTYWXYWZT[K[",
/* C */	"\12\12KFY[ K[YF",
/* D */	"\12\13RFJ[ RFZ[ J[Z[",
/* E */	"\12\12LFL[ LFYF LPTP L[Y[",
/* F */	"\12\12RFR[ PKMLLMKOKRLTMUPVTVWUXTYRYOXMWLTKPK",
/* G */	"\12\10LFL[ LFXF",
/* H */	"\13\13KFK[ YFY[ KPYP",
/* I */	"\4\4RFR[",
/* J */	"\13\13PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF OPUP",
/* K */	"\13\12KFK[ YFKT POY[",
/* L */	"\12\13RFJ[ RFZ[",
/* M */	"\14\14JFJ[ JFR[ ZFR[ ZFZ[",
/* N */	"\13\13KFK[ KFY[ YFY[",
/* O */	"\13\13PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF",
/* P */	"\13\13KFK[ YFY[ KFYF",
	0,
/* R */	"\13\12KFK[ KFTFWGXHYJYMXOWPTQKQ",
/* S */	"\12\12KFRPK[ KFYF K[Y[",
/* T */	"\12\12RFR[ KFYF",
/* U */	"\12\12KKKILGMFOFPGQIRMR[ YKYIXGWFUFTGSIRM",
	0,
/* W */	"\12\12K[O[LTKPKLLINGQFSFVGXIYLYPXTU[Y[",
/* X */	"\11\11KFYF OPUP K[Y[",
/* Y */	"\14\14RFR[ ILJLKMLQMSNTQUSUVTWSXQYMZL[L",
/* Z */	"\12\12YFK[ KFYF K[Y[",
/* [ */	"\7\7OBOb PBPb OBVB ObVb",
/* \ */	"\7\7KFY^",
/* ] */	"\7\7TBTb UBUb NBUB NbUb",
/* ^ */	"\10\10PLRITL MORJWO RJR[",
/* _ */	"\10\10J]Z]",
/* ` */	"\5\5SFRGQIQKRLSKRJ",
/* a */	"\12\13QMONMPLRKUKXLZN[P[RZUWWTYPZM QMSMTNUPWXXZY[Z[",
/* b */	"\11\12UFSGQIOMNPMTLZKb UFWFYHYKXMWNUORO ROTPVRWTWWVYUZS[Q[OZNYMV",
/* c */	"\12\12KMMMOOU`WbYb ZMYOWRM]K`Jb",
/* d */	"\11\11TMQMONMPLSLVMYNZP[R[TZVXWUWRVOTMRKQIQGRFTFVGXI",
/* e */	"\10\10WOVNTMQMONOPPRSS SSOTMVMXNZP[S[UZWX",
/* f */	"\13\13ONMOKQJTJWKYLZN[Q[TZWXYUZRZOXMVMTORSPXMb",
/* g */	"\12\12JPLNNMOMQNROSRSVR[ ZMYPXRR[P_Ob",
/* h */	"\12\12IQJOLMNMONOPNTL[ NTPPRNTMVMXOXRWWTb",
/* i */	"\7\5RMPTOXOZP[R[TYUW",
/* j */	"\14\13HQIOKMMMNNNPMUMXNZO[Q[SZUWVUWRXMXJWGUFSFRHRJSMUPWRZT",
/* k */	"\12\11OMK[ YNXMWMUNQROSNS NSPTQUSZT[U[VZ",
/* l */	"\12\10KFMFOGPHX[ RML[",
/* m */	"\14\13OMIb NQMVMYO[Q[SZUXWT YMWTVXVZW[Y[[Y\\W",
/* n */	"\12\11LMOMNSMXL[ YMXPWRUURXOZL[",
/* o */	"\10\12RMPNNPMSMVNYOZQ[S[UZWXXUXRWOVNTMRM",
/* p */	"\13\13PML[ UMVSWXX[ IPKNNM[M",
	0,
/* r */	"\12\11MSMVNYOZQ[S[UZWXXUXRWOVNTMRMPNNPMSIb",
/* s */	"\11\13[MQMONMPLSLVMYNZP[R[TZVXWUWRVOUNSM",
/* t */	"\13\12SMP[ JPLNOMZM",
/* u */	"\13\12IQJOLMNMONOPMVMYO[Q[TZVXXTYPYM",
	0,
/* w */	"\14\13NMLNJQITIWJZK[M[OZQW RSQWRZS[U[WZYWZTZQYNXM",
/* x */	"\10\10TFRGQHQIRJUKXK UKRLPMOOOQQSTTVT TTPUNVMXMZO\\S^T_TaRbPb",
/* y */	"\16\14VFNb GQHOJMLMMNMPLULXMZO[Q[TZVXXUZP[M",
/* z */	"\10\10TFRGQHQIRJUKXK XKTMQONRMUMWNYP[S]T_TaSbQbP`",
/* { */	"\7\7TBRCQDPFPHQJRKSMSOQQ RCQEQGRISJTLTNSPORSTTVTXSZR[Q]Q_Ra QSSUSWRYQZP\\P^Q`RaTb",
/* | */	"\4\4RBRb",
/* } */	"\7\7PBRCSDTFTHSJRKQMQOSQ RCSESGRIQJPLPNQPURQTPVPXQZR[S]S_Ra SSQUQWRYSZT\\T^S`RaPb",
/* ~ */	"\10\10LTLRMPOPUSWSXR LRMQOQUTWTXRXP",
	0,
};


char **sfont = hvecfont;
int sfontchars = sizeof(hvecfont) / sizeof(hvecfont[0]);

#define SFONTSCALE  33.0f	/* magic Hershey font scaling */

float sfStrWidth( CONST char *str )
{
    int iwidth;
    int c;
    const unsigned char *s;

    if(str == NULL)
	return 0;
    for(s = (const unsigned char *)str, iwidth = 0; *s != '\0'; s++) {
	if((c = *s - ' ') < 0 || c >= 96 || sfont[c] == NULL)
	    continue;

	iwidth += sfont[c][0] + sfont[c][1];
    }
    return (float)iwidth / SFONTSCALE;
}

float sfStrDraw( CONST char *str, float height, CONST Point *base )
{
    float scl = height / SFONTSCALE; 
    const unsigned char *s, *fs;
    Point at;
    int width, xoff;
    float atx0;

    if(str == NULL)
	return 0;
    if(base)
	at = *base;
    else
	at.x[0] = at.x[1] = at.x[2] = 0;
    atx0 = at.x[0];

    for(s = (const unsigned char *)str; *s != '\0'; s++) {
	fs = (unsigned char *)sfont[ (*s >= ' ' && *s < ' '+sfontchars) ? (*s - ' ') : 0 ];
	if(fs == NULL)
	    continue;
	width = fs[0] + fs[1];
	xoff = -82+fs[0];

	glBegin( GL_LINE_STRIP );
	for(fs += 2; *fs != '\0' && fs[1] != '\0'; fs++) {
	    if(*fs == ' ') {
		glEnd();
		glBegin( GL_LINE_STRIP );
	    } else {
		glVertex3f(
			at.x[0] + (fs[0]+xoff) * scl,
			at.x[1] + (91-fs[1]) * scl,
			at.x[2] );
		fs++;
	    }
	}
	glEnd();

	at.x[0] += width*scl;
    }
    return at.x[0] - atx0;
}

float sfStrDrawTJ( CONST char *str, float height, CONST Point *base, CONST Matrix *tfm, CONST char *just )
{
    float scl = height / SFONTSCALE; 
    const unsigned char *s, *fs;
    Point at;
    int width, xoff;
    float atx0;
    Matrix mytfm;

    if(str == NULL)
	return 0;
    at.x[0] = at.x[1] = at.x[2] = 0;
    if(tfm) {
	mytfm = *tfm;
	if(base) {
	    Point transl;
	    vgettranslation( &transl, &mytfm );
	    vadd( &transl, &transl, base );
	    vsettranslation( &mytfm, &transl );
	}
    } else if(base) {
	at = *base;
    }
    atx0 = at.x[0];

    /* just -- one of n e w s ne nw sw se c */
    if(just) {
	float xjust = -.5, yjust = -.5;
	while(*just) {
	    switch(*just++) {
	    case 'n': yjust = -1; break;
	    case 's': yjust = 0; break;
	    case 'e': xjust = -1; break;
	    case 'w': xjust = 0; break;
	    case 'c': xjust = yjust = -.5; break;
	    }
	}
	at.x[1] += yjust * height;
	if(xjust != 0)
	    at.x[0] += xjust * height * sfStrWidth(str);
    }

    for(s = (const unsigned char *)str; *s != '\0'; s++) {
	fs = (unsigned char *)sfont[ (*s >= ' ' && *s < ' '+sfontchars) ? (*s - ' ') : 0 ];
	if(fs == NULL)
	    continue;
	width = fs[0] + fs[1];
	xoff = -82+fs[0];

	glBegin( GL_LINE_STRIP );
	for(fs += 2; *fs != '\0' && fs[1] != '\0'; fs++) {
	    if(*fs == ' ') {
		glEnd();
		glBegin( GL_LINE_STRIP );
	    } else {
		if(tfm) {
		    Point ip, op;
		    ip.x[0] = at.x[0] + (fs[0]+xoff) * scl;
		    ip.x[1] = at.x[1] + (91-fs[1]) * scl;
		    ip.x[2] = at.x[2];
		    vtfmpoint( &op, &ip, &mytfm );
		    glVertex3fv( op.x );
		} else {
		    glVertex3f(
			at.x[0] + (fs[0]+xoff) * scl,	/* "base" already included */
			at.x[1] + (91-fs[1]) * scl,
			at.x[2] );
		}
		fs++;
	    }
	}
	glEnd();

	at.x[0] += width*scl;
    }
    return at.x[0] - atx0;
}