/* * 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; }