tags:

views:

152

answers:

1

WPF has the Typography.Variants attached property that lets you do superscript and subscript. However, it only works for some fonts. For other fonts, the variant is utterly ignored, and the text is shown normally. (Code sample and screenshot here)

Since it silently falls back to a no-op, I have no idea that anything went wrong; but my user will see lousy behavior.

Is there any way that I can programmatically detect whether a given font supports Typography.Variants? If so, I could provide more meaningful behavior if the user selected a non-variant-supporting font for something that needs superscripts/subscripts.

I looked at GlyphTypeface, since it's the one you use to query whether a font can be embedded, but I didn't see anything there about variants. I also didn't see anything obvious on FontFamily, and the only thing I could find on Typography was the Variants attached property itself (and its getters and setters).

+1  A: 

As far as I can tell, WPF provides no information about the available GSUB tables (which tell you this information). Everything is hidden deep within private classes of PresentationCore.

One way would be to use the advanced text services of WPF to create a TextFormatter, and then retrieve the GlyphRuns created by a piece of text with the variants on, and one with the variants off, and then compare the glyph indexes used.

Another way would be to physically examine a font's data through GlyphTypeFace.GetFontStream(). The TrueType font format is not very complicated, so you'll probably find some information on the net on how to parse the binary font data to find information on the GSUB tables.

Note that simply asking wither a variant is supported is also a little ambiguous. A font can say it supports a variant, but nothing requires it to actually provide any meaningful substitutions. Most Adobe fonts provide only a few alphabetical lowercase characters for things like superscript and subscript (not even the entire Latin alphabet, mind you). Which is pretty useless, IMHO, since you can't ask WPF to fake subscripts or superscripts like Word and other word processors do.

Still, it would have been nice if you could simply ask TypeFace.GetSupportedOpenTypeFeatures().

Ruben
Wow. So the variant actually causes my "2" (or "th" or whatever else) to be replaced by different characters from the same font? The documentation doesn't even hint about how it works.
Joe White
Yep, that's OpenType for you. It's an incredibly complicated piece of work to get all the (contextual!) substitutions to work. Subscript usually works by substituting the normal letters with hand designed super/subscript ones, which are hidden somewhere in the font's glyph table. (If you open the font with a font editor you'll see them, and some fonts also allocate them to the Private Use Area of the font, which is at the high end of the Unicode spectrum.)
Ruben