Lies, damned lies, and font metrics

At work this week, we had a bug report where text was being placed with too large an offset from the feature. It was quite easy to reproduce; here is a river label using the Cambria font:

Cambria

And here it is using Cambria Math:

Cambria Math

The grey line is the baseline of the label, which we can draw on screen to show where the label engine thinks it is being placed. In this case, we’re actually placing the label with the correct offset, but there is something odd going on with the font itself.

We’re not the only application that has problems with this font, as the Windows font viewer shows:

CambriaCambria Math

It appears that the line spacing is much larger with Cambria Math, although there is no mention of this in the font vendor’s catalogue.

I queried the font metrics [1], and, while most fonts return a height of around 25 [2] (average ascent is around 20, descent 5), Cambria Math is 117 (ascent is 65, descent is 52). Also, the internal leading is 96, compared to an average of 4 [3]. It appears that this font is actually designed to have large spaces around each line of text; as the name suggests, it is intended for Maths and Engineering use. If you are writing equations or drawing matrices, you will need extra line spacing for everything to fit in. If you are trying to label geographic features though, I would suggest using a different font!

This isn’t the first time we’ve had problems with fonts returning bad information. Arial Unicode MS is very useful for internationalisation – it contains thousands of glyphs from a wide range of languages – but it often returns dodgy metrics.

Another problem is when users customise fonts to insert their own symbols. When the label engine requests details of the text height, it would adversely affect performance to return the height of every character in the font, so for a long time, the engine just used the height of the capital M, without any problems. If this character has been removed, however, the height will come back as zero, so all the text in the label will be zero-height, i.e. invisible. Now, the maximum height of A, M, and Z is used, so labels should still be placed, even if the font information is incomplete. In this example, ESRI Cartography has a small symbol in place of M and the ESRI Mil2525C Modifiers font has no letter M at all, but both are still placed with a label of the correct height (label is ‘McKenzie River’, as above).

ESRI Cartography ESRI Mil2525C Modifiers

The bottom line is: be aware that sometimes fonts don’t give the answer you’re expecting.

[1] Using GetTextMetrics and GetGlyphOutline methods of gdi32.dll.
[2] According to Microsoft, this is in “font design units”, not points or pixels.
[3] Average of the 387 fonts installed on my machine.