Stuff

Every once in a while I hear someone say that 2D APIs are old and deprecated and that 3D APIs are the way to go for 2D rendering. This drives me nuts. Sure, in a 3D API like OpenGL or Direct3D, it's easy to render lines and boxes and to blit images. You even get alpha blending and rotation almost for free.

Unfortunately, another essential drawing primitive in a 2D layer, and one that is a pain in the posterior to implement, is drawing text.

By this, I don't mean drawing monospace 8x8 bitmap characters that look like they were extracted using int 10h / AX=1130h and prerendered into a 16x16 grid in a texture. Nor do I mean the ugly line based “vector fonts” that seemed to ship with the graphics library for every C compiler for DOS. I mean hinted, antialiased, properly spaced, proportional text written in a Unicode-supporting font as you'd see in any modern program.

When faced with a problem like this, an appropriate response is to try to get someone else to solve it for you, and that's actually what I would recommend first: the complexity of modern font rendering combined with the scary size of the Unicode standard book should give anyone pause. There are a few readily available libraries for Windows worth calling out here:

D3DXFont: Font rendering path in the Direct3D helper library (D3DX). Works decently well, but has a few major downsides: requires Direct3D, doesn't work with bitmap fonts, and doesn't support subpixel (ClearType) antialiasing. The last point is particularly problematic if you are doing UI with traditionally-sized fonts.

DirectWrite: Accelerated, non-GDI font rendering solution introduced in Windows Vista. Its biggest problem is not being available on XP, and its second biggest problem is that every single program that migrates to it seems to incur a large number of font rendering quality issues. If you use this, I implore you to turn on the whole pixel positioning mode and spare everyone from unusably blurry text.

Uniscribe: Complex script processing library. The rendering path won't be usable in a 3D-based program, but the layout and shaping facilities can still be useful. API looks a bit scary, but I haven't actually tried it yet.

And then, there are a whole bunch of third-party libraries too numerous to list.

When faced with this issue myself, I decided to see how much I could leverage ye olde Graphics Device Interface (GDI), the foundation of 2D graphics in Win32. This approach has a couple of advantages. The first is its universal availability. A much more important one is that by leveraging GDI it's much easier to support any font GDI does and render text the same way as GDI, which I consider important. In particular, many approaches I've seen either don't support bitmap fonts, don't use hinting, or don't do ClearType antialiasing, which I consider showstoppers for rendering UI.

As it turns out, this was a lot more painful than I had expected due to the usual number of quirks in Win32. Here's the story of all the approaches I went through....

VirtualDub 1.10.3 is out. It contains a number of bug fixes along with a couple of small things on the side. Several of the video filters have had additional fixes, a WAVE64 format bug was fixed, a DirectShow capture crash was fixed, a couple of Unicode text problems have been resolved, high DPI aware mode has been enabled, an option has been added to apply edits only to video and not audio, and support for high-performance screen capture on Windows 8 (DXGI 1.2) has been added.