How does DirectWrite (CreateTextFormat) pick the fallback font(s)?

馋奶兔 提交于 2021-02-07 08:27:00

问题


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):

enter image description here

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!