gpt4 book ai didi

winapi - 如何使用DirectWrite在面向脚本的OpenType功能与其他OpenType功能之间取得平衡?

转载 作者:行者123 更新时间:2023-12-04 04:20:38 24 4
gpt4 key购买 nike

全面披露:我正在使用libui GUI框架的文本API。这将在Windows上包装DirectWrite,在OS X上包装Core Text,在其他Unix上包装Pango(使用HarfBuzz进行OpenType成形)。我要指定的文本格式属性之一是要使用的OpenType功能的集合,这三个功能都可以提供; DirectWrite的是IDWriteTypography

现在,当您使用这些库绘制一些文本时,默认情况下会启用一些有用的OpenType功能,例如像f + i连字之类的标准连字(liga)。我以为这是特定于字体的,但事实证明,这是特定于所成形文本的脚本的。 Microsoft provides guidelines for all the scripts supported by OpenType(在“特定于脚本的开发”下),我可以在HarfBuzz本身中看到相当复杂的逻辑来进行确认。

在Core Text和Pango上,如果启用其他属性,则会将它们添加到这些默认值的顶部。但是,使用DirectWrite尤其是IDWriteTextLayout::SetTypography()可以删除默认值:

产生此输出的程序可以在here中找到。

显然,我的第一个选择是询问如何在DirectWrite上获取默认功能。 Someone did so already on this site, though, and the answer seems to be "no".

我猜想DirectWrite允许我完全控制要应用于某些文本的功能列表。很好,除了我不能用其他API做到这一点,除非我以某种方式显式禁用了默认功能!当然,我不知道此列表是否会更改,因此对其进行硬编码可能不是最好的主意。

即使可以使用硬编码,我也可以只获取每个脚本的HarfBuzz列表,但是a)it's rather complicated b)脚本可能有多种成形器,具体取决于(我认为)版本兼容性(例如,缅甸)。

那么,为什么不使用HarfBuzz的列表来重新创建DirectWrite的默认功能列表呢?无论如何,它似乎仍想对其他成型者精确,所以这应该可行,对吗?好吧,我需要做两件事:找出要使用的脚本,并找出要在脚本的哪些字符上使用哪些属性,其中字符在单词中的位置很重要。

DirectWrite提供了一个IDWriteTextAnalyzer接口(interface),该接口(interface)提供了执行整形的工具。我可以使用它,但是似乎脚本数据是在 DWRITE_SCRIPT_ANALYSIS structure中返回的,并且脚本ID的描述为“编写系统脚本的从零开始的索引表示形式”。

这没有帮助,所以我写了a program to just dump the script numbers for text I type in。在输入字符串上运行它

لللللللللللللاااااااااالا abcd محمد ابن بطوطة‎‎ Отложения датского яруса

产生输出
0 - 26 script 3 shapes 0
26 - 5 script 49 shapes 0
31 - 14 script 3 shapes 0
45 - 2 script 1 shapes 1
47 - 25 script 22 shapes 0

我无法将这些脚本编号与任何Windows header 中的任何内容进行匹配:如果在任何API中都为阿拉伯文,拉丁文或西里尔文定义了编号,则它们不匹配。即使我确实获得了脚本和脚本编号之间的映射,也仍然无法获得应用字内功能的数据。

那Uniscribe呢?好吧, the equivalent SCRIPT_ANALYSIS type的文档说它的脚本ID是一个“[不透明]值”,其“该成员的值未定义,应用程序不应依赖于它的值在一个发行版与下一个发行版中相同”。尽管可以获取语言代码来标识脚本,但“西方”(拉丁文)脚本的 LANG_ENGLISH仍然没有定义的值。 DirectWrite值与Uniscribe值相同吗?看来我至少可以通过查看 fLinkBeforefLinkAfter字段来了解单词的初始状态和最终状态,但这足以正确地按脚本应用属性吗?

HarfBuzz确实有一个实验性的DirectWrite后端 isn't intended to be used by real programs;我尚不确定它是否具有与上面指定的功能相同的功能。如果发现,我将在这里更新此部分。

最后,如果我以类似kaxaml的方式输入与上述第一个相同的以下测试用例:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<FlowDocumentPageViewer>
<FlowDocument FontFamily="Constantia" FontSize="48">
<Paragraph>
afford afire aflight 1/4<LineBreak/>
<Run Typography.Fraction="1">afford afire aflight 1/4</Run>
</Paragraph>
</FlowDocument>
</FlowDocumentPageViewer>
</Grid>
</Page>

我看到连字正确应用,即使在后一种情况下:

(最后的部分只是为了证明该属性已被应用。)如果我假设XAML使用DirectWrite,那么这证明了我的第一个选择(将我的自定义属性覆盖在默认值之上)应该是可能的...(我基于XAML提供了与Direct2D极其相似的API来绘制2D图形的想法,并填补了很多空白,在这些地方我不得不手动编写大量胶水代码以使用 Vanilla Direct2D做相同的事情,因此,我假设Direct2D可以实现XAML中的所有功能,并且通过扩展DirectWrite可以实现,因为它们是在技术上一起引入的...)

在这一点上我已经完全迷路了。我至少希望跨平台可预测,而且我不确定程序应如何直接使用OpenType功能,更不用说如何使用OpenType功能了。我对文本布局API的期望不高吗?如果需要,我是否必须删除IDWriteTextLayout并自行完成所有文本的成形和布局?

还是我必须放弃对Windows 7的原始支持并升级到Platform Update DirectWrite功能集?甚至完全是Windows 7?

最佳答案

与Peter Sikking和Ebrahim Byagowi进行了一些讨论之后,我去调试了我快速构建的通用程序来测试事物,并弄清楚了内部发生了什么。

但是,首先,我要说这同样适用于Uniscribe和DirectWrite

事实证明,无论我使用哪种功能,DirectWrite始终提供一组默认的OpenType功能!情况是,所提供的默认功能的列表会有所不同,具体取决于我是否加载自己的功能以及整形引擎。对于水平书写模式下的latn脚本和英语而言,这是通过“通用引擎”完成的。

如果我不提供任何功能,则通用引擎将加载特定于脚本的功能。对于水平latn,此列表为

locl
ccmp
rlig
rclt
calt
liga
clig

如果我提供功能,则通用引擎将对所有脚本使用相同的默认列表:
locl
ccmp
rclt
rlig
mark
mkmk
dist

所以我不知道该怎么办。我可能可以在libui代码中自己提供 liga和其他一些代码(当然也标记为 HACK),但这仍然很奇怪。我不确定动机是什么。无论哪种方式,这都可以解释我所看到的行为。

关于winapi - 如何使用DirectWrite在面向脚本的OpenType功能与其他OpenType功能之间取得平衡?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44611592/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com