Каковы типографские настройки по умолчанию, используемые IDWriteTextLayout?
Я хотел бы отключить лигатуры, которые, по-видимому, включены по умолчанию, по крайней мере, в шрифтах, которые я использую (например, Calibri). Похоже, что способ сделать это заключается в использовании IDWriteTextLayout::SetTypography
установить IDWriteTypography
Объект для макета, который содержит различные функции шрифта, связанные с лигатурой, со значением ноль, чтобы отключить их. Это работает для отключения лигатур, но также влияет (отключает) другие параметры типографии, с которыми я не хочу связываться, например, кернинг.
После некоторых экспериментов выясняется, что я могу отключить лигатуры, просто установив пустой IDWriteTypography
объект (тот, который был просто создан IDWriteFactory
а затем применяется к макету без переделки). Пустая типографика, кажется, имеет эффект установки всех возможных функций шрифта на ноль / отключение. Итак, что я на самом деле хочу сделать, это получить настройки типографии по умолчанию, переопределить те, которые связаны с лигатурами, а затем установить их в макет.
К сожалению, я нигде не могу найти настройки по умолчанию. С помощью IDWriteTextLayout::GetTypography
просто возвращает ноль, если ни один не был установлен, но он явно имеет различные настройки типографии, такие как лигатуры в этом случае. Я также не могу найти другие методы на IDWriteFactory
(или любой из его более новых версий) или любой из связанных со шрифтом интерфейсов для создания IDWriteTypography
пример. Как работает IDWriteTextLayout
решить, какие настройки типографии использовать, когда нет IDWriteTypography
был установлен? Настройки по умолчанию зависят от шрифта? Могу ли я каким-то образом получить эти настройки, чтобы настроить некоторые из них и унаследовать значения по умолчанию для остальных?
2 ответа
Нет способа получить набор функций по умолчанию из IDWriteTextLayout или IDWriteTextAnalyzer, чтобы быть более точным, и нет, это не специфично для шрифта, это специфично для скрипта.
Если вам интересно, как это работает в целом, вы можете использовать реализации с открытым исходным кодом, такие как HarfBuzz, вы можете найти массивы специфичных для сценариев функций, которые применяются во время формирования.
Подход Microsoft к этому задокументирован в документации OpenType, пример для арабского - https://www.microsoft.com/typography/OpenTypeDev/arabic/intro.htm.
Похоже, что способ сделать это состоит в том, чтобы использовать IDWriteTextLayout::SetTypography
Уже 13 сентября 2015 г. (дата, когда вы задали этот вопрос), вы были в состоянии отключить лигатуры, в частности, для шрифта Calibri, БЕЗ взаимодействия с объектом IDWriteTypography и его настройками по умолчанию.
Возможно, вам не удастся отключить лигатуры "глобально" так, как вам нравится, но у вас всегда есть возможность отключить лигатуры, когда вы фактически извлекаете глифы для фрагмента текста в вашем коде. 9-й, 10-й и 11-й ('features', 'featureLengths' и 'featureCount') параметры метода IDWriteTextAnalyzer::GetGlyph(...) вам помогут.
Например, чтобы отключить лигатуры, вы пишете в своем коде (я позаимствовал этот кусок из метода FLowLayout::ShapeGlyphRun образца Windows7 SDK CustomLayout и добавил некоторые инициализации параметров функций; первоначально значения параметров с 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;
Второй параметр (0) в инициализаторе fontFeature ОТКЛЮЧАЕТ использование лигатур для текстового диапазона {textStart, textStart + textLength}, независимо от того, какой шрифт с поддержкой лигатуры используется в этом текстовом диапазоне. Ненулевое значение параметра активирует эту функцию, но эта функция, как вы знаете, включена по умолчанию.
Для следующего фрагмента текста (начиная с textStart + textLength и далее) вы можете повторно использовать значения инициализированных объектов, чтобы продолжать отключать лигатуры; но если вы вернете значения NULL, NULL, 0 для 9-го и 11-го функциональных параметров GetGlyph, лигатуры для этого последнего текстового диапазона будут включены без использования явных настроек функции в GetGlyph.
См. Ссылку: https://msdn.microsoft.com/en-us/library/windows/desktop/dd316625(v=vs.85).aspx.
На данный момент новый текстовый движок DirectWrite может предлагать более удобные способы управления использованием функций шрифтов и шрифтов - я не могу вам точно сказать, но приведенная выше информация может оказаться полезной для тех, кто пишет код, совместимый с Windows 7.