Friday 30 December 2011

Using Custom Fonts in DirectX

Those of you who work with DirectX know of the ID3DXFont class and its usage.
Its a nice simple to use class which gives good result with little effort.
And since its uses true type fonts, it should be easy to just add in another font right?

ID3DXFont* pFont;
D3DXCreateFont(mpDev,24,0,1,FW_NORMAL,1,false,DEFAULT_CHARSET,
         OUT_DEFAULT_PRECIS,ANTIALIASED_QUALITY,DEFAULT_PITCH|FF_DONTCARE,
         "Arial",&pFont);
...
RECT r={0,0,640,480};
pFont->DrawText(NULL,"hello world",-1,&r,DT_TOP|DT_LEFT,
          D3DCOLOR_XRGB(255,255,0));
...
pFont->Release();

Err not quite.
Well this code works, but if you go off and download a custom font and try:

D3DXCreateFont(mpDev,24,0,1,FW_NORMAL,1,false,DEFAULT_CHARSET,
     OUT_DEFAULT_PRECIS,ANTIALIASED_QUALITY,DEFAULT_PITCH|FF_DONTCARE,
     "Some Custom Font",&pFont);

It doesn't work, UNLESS you have installed the font first which is tedious.

I spent an afternoon hunting about the net looking for the result.  I tried sticking the font all over the place & it just didn't work.

Eventually I found it: http://www.gamedeception.net/archive/index.php?t-18175.html put me on the right track to find AddFontResourceEx.

So now I put my fonts into my 'media/fonts' directory, and do:
AddFontResourceEx("media/fonts/customfont.ttf",FR_PRIVATE,0);
D3DXCreateFont(mpDev,24,0,1,FW_NORMAL,1,false,DEFAULT_CHARSET,
     OUT_DEFAULT_PRECIS,ANTIALIASED_QUALITY,DEFAULT_PITCH|FF_DONTCARE,
     "Some Custom Font",&pFont);

And it works fine. 
The FR_PRIVATE stuff, just tells Windows to only register it for this program (which is fine).
Its a little tedious having to do this for every font, but if I really wanted to I could just write some code to scan the directory for all the ttf's.

Happy Coding:
Mark