问题
The documentation for CreateTextFormat says nothing about font fallback selection, but if the default (NULL = system) collection is chosen, then DirectWrite clearly implements font fallback. For example, if I add two glyphs not found in the Gabriola font to the test string used by the DirectWrite SDK demo app, then DirectWrite picks the missing glyphs from the Segoe UI Symbol font. This happens with the basic DrawText
call and also with a custom renderer (that does nothing custom for font fallback) as shown below (the only modification is the test string):
The checkmark and wite star come from Segoe UI Symbol, not from Gabriola, even though only Gabriola is specified in the demo app. So, does anyone know how the fallback font(s) is/are selected by DirectWrite (CreateTextFormat)?
Update. I see there is a GetSystemFontFallback that can list the fallback fonts, but it's only available in Windows 8.1 (because it's in IDWriteFactory2). I guess they've noticed the gap in the API with respect to enumerating the fallback fonts. So I'm guessing there's no way to do this before Windows 8.1, but if anyone knows a hack/workaround...
Update2. Quoting a MSFT employee:
DirectWrite has fallback data that is not read from the registry or in any way configurable. In Windows 8.1, though, APIs have been introduced that allow an app to specify its own fallback. (It's similar to the WPF APIs for creating a composite font definition.)
Which still doesn't explain exactly what the hardcoded algorithm/replacement scheme actually is.
回答1:
IDWriteTextLayout
calls IDWriteFontFallback::MapCharacters
to map each Unicode character to an ordered list of font families that are tried until that character is satisfied. Think of a loop reading each character one-by-one, mapping the code point value and language tag to a Unicode range, and stopping at the first font which supports the character in the cmap table. It is somewhat similar to the font fallback algorithm specified by CSS [http://www.w3.org/TR/css3-fonts/#font-matching-algorithm] and fallback used by WPF/XAML/Silverlight. See the IDWriteFontFallbackBuilder::AddMapping
API (Win 8.1+), used to build a custom fallback list, for an idea of the inputs used.
See C:\Windows\Fonts\GlobalUserInterface.CompositeFont for example data (note this file is actually for WPF, not quite the same definition which DWrite uses).
<FontFamilyMap
Unicode = "3000-30FF, 31F0-31FF"
Language = "ja"
Target = "Meiryo UI, Meiryo, Microsoft YaHei UI, Microsoft YaHei, MS Gothic, MingLiu, Arial Unicode MS"
Scale = "1.0" />
来源:https://stackoverflow.com/questions/25693651/how-does-directwrite-createtextformat-pick-the-fallback-fonts