the swine the swine - 7 days ago 6
C++ Question

In Windows, how to detect if a Unicode character renders as square (tofu)?

I'm writing a simple bitmap font renderer for OpenGL and I'd like to render some Unicode as well. However, in many fonts some characters are missing and are rendered as squares. These consequently waste space in my texture and I'd like to get rid of them. Is there a WinAPI function to detect whether a certain character will be rendered as a tofu square using a certain font?

I'm using GDI, I make an offscreen bitmap using

CreateDIBSection
, then get a font using
CreateFontIndirect
and render glyphs using
ExtTextOutW
.

So far I was thinking about detecting the tofu in the rasterized form (by comparing the pixels) which sort of works but I guess it is not very nice. It also requires me to get some Unicode character that the given font for sure does not have, in order to get a "template" to compare to. I guess I would get into trouble sooner or later like that.

Answer

I had to do something similar to implement my own font-linking and font-fallback when building glyph maps for a 3D renderer. I used Uniscribe to convert the string of characters to a string of glyph indexes into the font. Then I used ScriptGetFontProperties to get the wgDefault property for the font and compared the value to each of the glyph indexes.

The pure GDI equivalent would be to use something like GetCharacterPlacement to convert the text to glyph indexes (and then you use ExtTextOut with ETO_GLYPH_INDEX), but I don't think that does all the key shaping and reordering that Uniscribe would do. For starters, I don't think that'll work for anything beyond the BMP.

You don't want to graphically match to the missing symbol glyph because it's not always a square. For example, in some fonts, it's a black diamond with a question mark in it.

Comments