IDWriteTextLayout 使用的默认排版设置是什么?

What are the default typography settings used by IDWriteTextLayout?

我想禁用连字,这似乎是默认启用的,至少在我使用的字体(即 Calibri)中是这样。执行此操作的方法似乎是使用 IDWriteTextLayout::SetTypographyIDWriteTypography 对象设置为布局,其中包含各种与连字相关的字体功能,值为零以禁用它们。这可以禁用连字,但它也会影响(禁用)我不想弄乱的其他排版设置,例如字距调整。

经过一些实验,结果证明我可以通过设置一个空的 IDWriteTypography 对象来禁用连字(一个由 IDWriteFactory 简单地创建然后应用到布局而不改变) .空排版似乎具有将所有可能的字体功能设置为 zero/disable 的效果。所以我真正想做的是检索默认版式设置,覆盖与连字相关的设置,然后将其设置为布局。

很遗憾,我找不到任何地方可以检索默认设置。如果设置了 none,则仅使用 IDWriteTextLayout::GetTypography returns null,但它显然具有各种排版设置,例如在这种情况下启用连字。我也无法在 IDWriteFactory(或其任何较新版本)或任何用于创建 IDWriteTypography 实例的字体相关接口上找到任何其他方法。 IDWriteTextLayout 如何在未设置 IDWriteTypography 时决定使用哪些排版设置?默认设置是否特定于字体?我能否以某种方式检索这些设置,以便我可以调整其中的一些设置并继承其余设置的默认值?

没有办法从 IDWriteTextLayout 或 IDWriteTextAnalyzer 中获取默认功能集,更准确地说,不,它不是 font-specific,它是 script-specific。

如果您对它的总体工作原理感兴趣,可以使用 HarfBuzz 等开源实现,您可以找到在整形期间应用的 script-specific 特征数组。

在 OpenType 文档中记录了 Microsoft 的方法,一个阿拉伯语示例 - https://www.microsoft.com/typography/OpenTypeDev/arabic/intro.htm

It appears that the way to do this is to use IDWriteTextLayout::SetTypography

早在 2015 年 9 月 13 日(您提出此问题的日期),您就能够禁用连字,特别是对于 Calibri 字体,而无需弄乱 IDWriteTypography 对象及其默认设置。

您可能无法以您喜欢的方式禁用连字 "globally",但是当您实际为代码中的一段文本提取字形时,您总是可以选择禁用连字。 IDWriteTextAnalyzer::GetGlyph(...) 方法的第 9、10 和 11('features'、'featureLengths' 和 'featureCount')参数对您有帮助。

例如,要禁用连字,您可以在代码中编写(我从 Windows7 SDK CustomLayout 示例的 FLowLayout::ShapeGlyphRun 方法中借用了这篇文章,并添加了一些功能参数初始化;最初,第 9 到第 11 个参数值为 NULL, NULL, 0):

    DWRITE_FONT_FEATURE fontFeature = { DWRITE_FONT_FEATURE_TAG_STANDARD_LIGATURES, 0 };

    const DWRITE_TYPOGRAPHIC_FEATURES* typoFeatures = 
        new DWRITE_TYPOGRAPHIC_FEATURES{ { &fontFeature } };

    UINT32 featureLengths[1];

    featureLengths[0] = textLength;

    hr = textAnalyzer->GetGlyphs(
            &text_[textStart],
            textLength,
            fontFace_,
            run.isSideways,         // isSideways,
            (run.bidiLevel & 1),    // isRightToLeft
            &run.script,
            localeName_,
            (run.isNumberSubstituted) ? numberSubstitution_ : NULL,
            &typoFeatures,                   // features
            featureLengths,                   // featureLengths
            1,                      // featureCount
            maxGlyphCount,          // maxGlyphCount
            &glyphClusters_[textStart],
            &textProps[0],
            &glyphIndices_[glyphStart],
            &glyphProps[0],
            &actualGlyphCount
            );

    delete typoFeatures;

fontFeature 初始值设定项中的第二个参数 (0) 禁止对文本范围 {textStart, textStart + textLength} 使用连字,无论您在此文本范围内使用什么启用连字的字体。非零参数值将启用此功能,但如您所知,默认情况下启用此功能。

对于下一段文本(从 textStart + textLength 开始,然后继续),您可以重新使用初始化的特征值以继续禁用连字;但是,如果您 return 将 GetGlyph 的第 9 到第 11 个特征参数设为 NULL、NULL、0 值,则在不使用 GetGlyph 中的显式特征设置的情况下启用后一个文本范围的连字。

参见参考资料:https://msdn.microsoft.com/en-us/library/windows/desktop/dd316625(v=vs.85).aspx .

截至目前,新的 DirectWrite 文本引擎可能会提供更方便的方式来控制 typographic/font 功能的使用——我不能肯定地告诉你,但以上信息可能对那些编写代码的人有所帮助兼容 Windows 7.