JA's font width calculation is horrible broken, especially when using abnormal (anything but 1.0) scales.
The issue is in the engine, RE_Font_StrLenPixels uses integer precision for the return value, causing visible data loss.
The way I'm currently working around this is by replacing trap_R_Font_StrLenPixels with:
float trap_R_Font_StrLenPixels(const char *text, const int iFontIndex, const float scale)
//Raz: HACK! RE_Font_StrLenPixels only works semi-correctly with 1.0f scale
float width = (float)syscall( CG_R_FONT_STRLENPIXELS, text, iFontIndex, PASSFLOAT(1.0f));
return width * scale;
Note I'm using a float return value - you'll have to adjust function prototypes and usage all around the code to use floats for best results.
I also use a large custom font to help with scaling.
This is not a fix, but it does help tremendously when trying to center-align text in both cgame and ui
Theoretically you could replace all text rendering with your own OpenGL code and use the bmfont library. If you wanted to D: