Question

I have a MFC application that displays annotated maps, which can include a large amount of text. While the size and font of the text does not tend to change much, the rotation of the text varies considerably, in order to be aligned with the surrounding line work. This basically means that I have to do create and select a new font into the display context each time the rotation changes. Something like;

if (TextRotationChanges)
{
    m_pFont = new CFont;
    m_lf.lfEscapement = NewRotation;
    m_pFont->CreateFontIndirect(&m_lf);
}
CFont *OldFont = m_pDC->SelectObject(m_pFont);
m_pDC->TextOut(x,y,text,strlen(text));
m_pDC->SelectObject(OldFont);

This is obviously slow when dealing with large amounts of text. Is there any way of speeding this up without going to a different display engine such as D3D or OpenGL? Put another way, can I change the text rotation in the existing selected font?

n.b. I'm already carrying out other obvious optimizations, like ensuring text is on screen at a visible size prior to attempting to draw it.

Was it helpful?

Solution

Creating and destroying many GDI object can be slow. What you can do is create 360 fonts at the startup of your program so that you can SelectObject() from a lookup table with pre-made fonts at the correct rotation, rather than creating them on-demand. Or you can rotate your text by not using lfEscapement but by using SetWorldTransform() with the appropriate rotation matrix (again, you could cache rotation matrices for speed). You'd have to test if it will actually give you a speed gain.

See my question here SetWorldTransform() and font rotation for an issue I had/have with that approach, though (haven't had time to go back and look into it).

OTHER TIPS

Are you sure that the problem is the font and not the TextOut?
Oleg's idea of using a back buffer isn't bad if you want to avoid flickering.

If I was going to use a graphic engine I'd try Cairo because it's designed specifically for that kind of jobs.
(it can render directly on win32 DC surfaces)

You should first draw it on the invisible DC and than copy to your DC.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top