OK, the attached patch adds character width support to the fnt library, allowing it to handle glyphs whose logical width (distance along the baseline to the next character) differs from their physical width. Characters like the slash have this property, as do many italic glyphs.
The current antialiased fonts need it because, unlike the bitmap-based .txf fonts, the character glyphs in the texture are not exactly pixel aligned. Thus, I need to "pad" the texture box containing a glyph with whitespace to be sure that the entire glyph is contained in the textured quad. But that padding changes the physical width of the glyph, which means that horizontal padding can't be used without changing the spacing of the characters -- in effect, I have to choose between potentially chopping off parts of a character or achieving the correct character spacing as designed in the font. Anyway, it seems to work. One thing to worry about (and for which I did not test) is the effect this patch will have on older fonts. The code now interprets a value ("step"), which it used to ignore. If older fonts don't set this correctly, they will be misrendered by plib. I did a spot check of the fonts distributed with FlightGear, and they look OK. Hopefully all fonts generated by Mark's tool will be equally fine. I've generated a new set of font files with proper padding and put them back up on my web site (http://plausible.org/glut-fonts -- no, I didn't change the URL to remove the reference to glut). These look much nicer after the patch -- no chopped characters, and proper font metrics for all. FlightGear folks: how do you want to handle this? We can [1] use the new fonts, which won't render well (very W I D E spacing) in unpatched versions of plib, [2] use a slightly hacked new-style font that chops off a few characters but renders with appropriate spacing in all versions of plib, or [3] wait for a new plib release before making a decision. Since we're currently tracking plib CVS pretty closely anyway (the AC3D shading issue), I'd argue for #1. We can always provide a property-based fallback to typewriter.txf for releases. Andy -- Andrew J. Ross NextBus Information Systems Senior Software Engineer Emeryville, CA [EMAIL PROTECTED] http://www.nextbus.com "Men go crazy in conflagrations. They only get better one by one." - Sting (misquoted)
Index: src/fnt/fnt.cxx =================================================================== RCS file: /cvsroot/plib/plib/src/fnt/fnt.cxx,v retrieving revision 1.7 diff -u -r1.7 fnt.cxx --- src/fnt/fnt.cxx 12 Dec 2001 23:49:36 -0000 1.7 +++ src/fnt/fnt.cxx 28 Jun 2002 03:14:11 -0000 @@ -102,14 +102,14 @@ curpos[2] ) ; glEnd () ; - float ww = ( gap + ( fixed_pitch ? width : v_right[cc] ) ) * pointsize ; + float ww = ( gap + ( fixed_pitch ? width : widths[cc] ) ) * pointsize ; curpos[0] += ww ; return ww ; } -void fntTexFont::setGlyph ( char c, +void fntTexFont::setGlyph ( char c, float wid, float tex_left, float tex_right, float tex_bot , float tex_top , float vtx_left, float vtx_right, @@ -119,6 +119,8 @@ exists[cc] = FNT_TRUE ; + widths[cc] = wid; + t_left[cc] = tex_left ; t_right[cc] = tex_right ; t_bot [cc] = tex_bot ; t_top [cc] = tex_top ; @@ -127,7 +129,7 @@ } -int fntTexFont::getGlyph ( char c, +int fntTexFont::getGlyph ( char c, float* wid, float *tex_left, float *tex_right, float *tex_bot , float *tex_top , float *vtx_left, float *vtx_right, @@ -136,6 +138,8 @@ unsigned int cc = (unsigned char) c ; if ( ! exists[cc] ) return FNT_FALSE ; + + if ( wid != NULL ) *wid = widths [cc] ; if ( tex_left != NULL ) *tex_left = t_left [cc] ; if ( tex_right != NULL ) *tex_right = t_right[cc] ; Index: src/fnt/fnt.h =================================================================== RCS file: /cvsroot/plib/plib/src/fnt/fnt.h,v retrieving revision 1.5 diff -u -r1.5 fnt.h --- src/fnt/fnt.h 7 Nov 2001 23:51:09 -0000 1.5 +++ src/fnt/fnt.h 28 Jun 2002 03:14:11 -0000 @@ -90,6 +90,10 @@ v_bot==0.0 and v_top==1.0. */ + /* Nominal baseline widths */ + + float widths [ FNTMAX_CHAR ] ; + /* Texture coordinates */ float t_top [ FNTMAX_CHAR ] ; /* Top edge of each character [0..1] */ @@ -171,19 +175,19 @@ float getGap () const { return gap ; } - void setGlyph ( char c, + void setGlyph ( char c, float wid, float tex_left, float tex_right, float tex_bot , float tex_top , float vtx_left, float vtx_right, float vtx_bot , float vtx_top ) ; - int getGlyph ( char c, + int getGlyph ( char c, float* wid, float *tex_left = NULL, float *tex_right = NULL, float *tex_bot = NULL, float *tex_top = NULL, float *vtx_left = NULL, float *vtx_right = NULL, float *vtx_bot = NULL, float *vtx_top = NULL) ; - int hasGlyph ( char c ) { return getGlyph ( c ) ; } + int hasGlyph ( char c ) { return exists[ c ] ; } void getBBox ( const char *s, float pointsize, float italic, float *left, float *right, Index: src/fnt/fntTXF.cxx =================================================================== RCS file: /cvsroot/plib/plib/src/fnt/fntTXF.cxx,v retrieving revision 1.14 diff -u -r1.14 fntTXF.cxx --- src/fnt/fntTXF.cxx 21 Apr 2002 03:53:15 -0000 1.14 +++ src/fnt/fntTXF.cxx 28 Jun 2002 03:14:11 -0000 @@ -246,6 +246,7 @@ glyph . y = _fnt_readShort () ; setGlyph ( (char) glyph.ch, + (float) glyph.step / (float) max_height, (float) glyph.x / (float) w + xstep, (float)( glyph.x + glyph.w ) / (float) w + xstep, (float) glyph.y / (float) h + ystep,