标签: uniscribe

如何使用DirectWrite平衡面向脚本的OpenType功能与其他OpenType功能?

完全披露:我正在研究我的libui GUI框架的文本API.这包括Windows上的DirectWrite,OS X上的Core Text和其他Unix上的Pango(它使用HarfBuzz进行OpenType整形).我想要指定的文本格式化属性之一是要使用的OpenType功能的集合,这三者都提供了这些功能.DirectWrite是IDWriteTypography.

现在,当您使用这些库绘制一些文本时,默认情况下您将启用一些有用的OpenType功能,例如标准连字(liga),如f + i连字.我认为这是特定于字体的,但事实证明这是特定于正在形成的文本的脚本.Microsoft为OpenType支持的所有脚本提供了指南(在"特定于脚本的开发"下),我可以看到相当复杂的逻辑,可以在HarfBuzz中完成所有这些以确认它.

在Core Text和Pango上,如果我启用其他属性,它们将被添加到这些默认值之上.但是使用DirectWrite,IDWriteTextLayout::SetTypography()这样做会删除默认值:

如果明确指定IDWriteTypography对象,DirectWrite将删除默认的OpenType功能

可以在此处找到生成此输出的程序.

显然我的第一个选择是询问如何获取DirectWrite的默认功能.但是,有人已经在这个网站上这样做了,答案似乎是"不".

我猜测DirectWrite允许我完全控制要应用于某些文本的功能列表.这很好,除了我不能用其他API做到这一点,除非我以某种方式明确禁用默认功能!当然,我不知道这个列表是否会改变,所以硬编码可能不是最好的主意.

即使硬编码是一种选择,我也可以为每个脚本获取HarfBuzz的列表,但是a)它相当复杂 b)脚本有多种可能的整形器,这取决于(我认为)版本兼容性(例如,缅甸).

那么为什么不使用HarfBuzz的列表来重新创建DirectWrite的默认功能列表呢?它似乎想要对其他塑造者准确,所以这应该工作,对吧?好吧,我需要做两件事:找出要使用的脚本,并找出哪些属性用于脚本中字符的位置重要的脚本.

DirectWrite提供了一个接口IDWriteTextAnalyzer,提供执行整形的工具.我可以使用它,但似乎脚本数据在DWRITE_SCRIPT_ANALYSIS结构中返回,并且脚本ID的描述显示"写入系统脚本的从零开始的索引表示.".

这没有用,所以我编写了一个程序来转储我输入的文本的脚本编号.在输入字符串上运行它

????????????????????????? abcd ???? ??? ??????? ????????? ???????? ?????
Run Code Online (Sandbox Code Playgroud)

产生输出

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 …
Run Code Online (Sandbox Code Playgroud)

directx winapi opentype uniscribe directwrite

9
推荐指数
1
解决办法
339
查看次数

如何判断字体是否支持代理对Unicode字符?

我能够找到以下方法来确定Unicode-16字体是否支持某个字符.不幸的是,这对代理对Unicode字符不起作用,因为WCRANGE函数支持的struct GetFontUnicodeRanges只返回WCHAR(16位)参数作为输出.

这是我正在尝试做的一个例子:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static HFONT hFont = NULL;

    switch (message)
    {
        case WM_CREATE:
        {
            LOGFONT lf = {0};
            lf.lfHeight = -64;
            ::StringCchCopy(lf.lfFaceName, _countof(lf.lfFaceName), L"Arial");

            hFont = ::CreateFontIndirect(&lf);
        }
        break;

        case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);

            RECT rcClient = {0};
            ::GetClientRect(hWnd, &rcClient);

            HGDIOBJ hOldFont = ::SelectObject(hdc, hFont);

            LPCTSTR pStr = L">\U0001F609<";
            int nLn = wcslen(pStr); …
Run Code Online (Sandbox Code Playgroud)

c++ winapi gdi uniscribe

8
推荐指数
1
解决办法
289
查看次数

标签 统计

uniscribe ×2

winapi ×2

c++ ×1

directwrite ×1

directx ×1

gdi ×1

opentype ×1