# bitmap font system design

This topic is 4500 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

This isn't stricly about games, but since it's about bitmap fonts, I figure that more than a couple of people here would be able to help by giving me a nudge. I'm having a couple of problems attempting to implement a bitmap font system. I have an IVideoDriver class (OGL, DX, although I'm only implementing OGL at the moment) and my bitmap font class seperated into IBitmapFont and COpenGLBitmapFont:
/**
* Class representing the basics of a bitmap font.
*/
class IBitmapFont	:	public IMBase
{
private:

std::string m_name;	///< The name of the font
bool m_bold;		///< If the font is bold
bool m_italic;		///< If the font is italic
bool m_underlined;	///< If the font is underlined

int m_charWidths[96];	///< The widths of each printable character

HDC m_hdc;		///< The hardware device context

public:

/**
* Constructor
* \param hdc The hardware device context
* \param name The font name we want
* \param italic Whether the font is italic
* \param bold Whether the font is bold
* \param underlined Whether the font is underlined
*/
IBitmapFont(HDC hdc, const char* name, bool italic, bool underlined, bool bold)
:	m_hdc(hdc), m_name(name), m_italic(italic), m_bold(bold), m_underlined(underlined)
{
// Get an array of widths for a range of characters
if( !GetCharWidth32(m_hdc, 32, 127, m_charWidths) )
util::Message::print("IBitmapFont:: Unable to load character widths for font \"%s\"", name);
}

/**
* Get the width of a particular character
* \param c The character to get the width of
*/
int getCharWidth(char c)
{
return m_charWidths[c-32];	// because we're not using the first 32 characters (non-printable)
}

};


/**
* Represents a bitmap font in open gl.
*/
class COpenGLBitmapFont	:	public video::IBitmapFont
{
private:

unsigned int m_fontList;	///< The opengl display list id for the bitmap font

public:

/**
* Constructor
* \param hdc The HDC for the window
* \param name The font name we want
* \param italic Whether the font is italic
* \param bold Whether the font is bold
* \param underlined Whether the font is underlined
*/
COpenGLBitmapFont(HDC hdc, const char* name, bool italic, bool underlined, bool bold )
:	IBitmapFont(hdc, name, italic, underlined, bold)
{	}

/**
* Create the font
* \param hdc The hardware device context for creating the font
*/
bool createFont()
{
HFONT font;	// Window font id
HFONT oldfont;	// Used for good house keeping

m_fontList = glGenLists(96);	// Storage for 96 characters

font = CreateFont(	-15,	// Height of font
8,	// Width of font
0,	// Angle of escapement
0,	// Orientation Angle
FW_NORMAL,// Font weight
m_italic,// Italic
m_underlined,// Underline
m_bold,	// Strikeout
ANSI_CHARSET,	// Character set identifier
OUT_TT_PRECIS,	// Output precision
CLIP_DEFAULT_PRECIS,// Clipping precision
ANTIALIASED_QUALITY,// Output quality
FF_DONTCARE|DEFAULT_PITCH,// Family and pitch
"Arial");// Font name

oldfont = (HFONT) SelectObject(hdc, font);	// Selects the font we want
wglUseFontBitmaps(hdc, 32, 96, m_fontList);	// Builds 96 characters starting at character 32
SelectObject(hdc, oldfont);	// Selects the font we want
DeleteObject(font);		// Delete the font
}

};


That's it for the moment, but I'm having a problem with the printing of the text. I initially thought that I could call a function on the bitmap font object, but then I'd have to include the raster position and unless I wanted to always pass a pointer, I'd need a pointer to the VideoDriver inside the bitmap font class. I think that would be going a little too far and too inelegant. I was just stuck with a thought. What if I just kept all of the created bitmap font objects inside the VideoDriver class and whenever I called "createBitmapFont", it would return a handle (integer, whatever). Then, I could just keep with calling the video driver to draw text. I think that I'm more inclined to the latter, but I am looking for any better ideas. Also, just say a have a whole lot of fonts and I'm drawing text with each of them in every rendering frame. I'm using windows, as you could probably tell from the code. When using SelectObject, how quick is it to change fonts? Is it intensive either in time or memory?

##### Share on other sites
Quote:
 Original post by EndarAlso, just say a have a whole lot of fonts and I'm drawing text with each of them in every rendering frame. I'm using windows, as you could probably tell from the code. When using SelectObject, how quick is it to change fonts? Is it intensive either in time or memory?

SelectObject and quickness? Are you calling createFont once per frame or something? Since you're using display lists you don't need to do that.

Also, another thing strange is your calculating widths -> from the constructor even before the font is created and selected into the DC??? That might load the wrong widths.

I also make the font class just a glyph wrapper as well with no rendering support. It's messy if you do it otherwise, especially if you have multiple viewports. The font class would be a friend of the video class and the video class would do the rendering and handle correct placement in whatever viewport your rendering in.

On a personal note, I also don't use wglUseFontBitmaps. I noticed it adds too much spacing to the height of the glyphs for my taste so I make a monochrome bitmap and call glBitmap from a compiled display list myself.

##### Share on other sites
Quote:
 Original post by yadangoSelectObject and quickness? Are you calling createFont once per frame or something? Since you're using display lists you don't need to do that.

I think I made a mistake in my understanding. When I change fonts I don't need to call 'SelectObject' because I've made a display list with the characters in it.

Quote:
 Original post by yadangoAlso, another thing strange is your calculating widths -> from the constructor even before the font is created and selected into the DC??? That might load the wrong widths.

Yeah, I'm still in the middle of writing it and haven't actually run it yet. Thanks.

##### Share on other sites
Quote:
 Original post by EndarAlso, just say a have a whole lot of fonts and I'm drawing text with each of them in every rendering frame. I'm using windows, as you could probably tell from the code. When using SelectObject, how quick is it to change fonts? Is it intensive either in time or memory?

SelectObject itself doesn't really do anything so it's pretty speedy. All the work happens the first time you use a given instance of a font. GDI maintains a cache of glyph metrics and bitmaps so once you get the cache going it's not to bad. It depends on your exact usage pattern of course.

1. 1
2. 2
3. 3
Rutin
16
4. 4
5. 5

• 10
• 14
• 30
• 13
• 11
• ### Forum Statistics

• Total Topics
631788
• Total Posts
3002356
×