1

一些字符具有不明确的方向性,例如空格和标点符号。这可能会导致文本布局情况,在没有访问附加数据来解决歧义的情况下,似乎没有一个正确的布局。考虑这段文字:

\u05e9\u05e0\u05d1\u05d2abcd!

那是四个希伯来字符(明确从右到左),四个英文字符(明确从左到右)和一个标点符号(不明确)。如果我将该字符串布局在IDWriteTextLayoutwith 中DWRITE_READING_DIRECTION_RIGHT_TO_LEFT,我会得到以下信息:

渲染的屏幕截图显示最左侧的标点符号。

标点符号似乎被视为从右到左的字符,它在英语左侧开始一个新的从右到左的块,这似乎完全合理,特别是考虑到从右到左是指定的阅读方向。但是,将标点符号视为与嵌入的从左到右英文文本相关的从左到右字符也是完全合理的,这意味着它应该出现在“d”的右侧。

我的应用程序确切地知道它希望如何对待这个角色。我如何传递这些数据IDWriteTextLayout来解决这种歧义?

我找到了SetLocaleName方法并认为它一定是答案,但我似乎根本无法让它影响结果。我还在创建一个(然后用于创建)localeName时找到了该参数。IDWriteTextFormatIDWriteTextLayout

如果我的目标通常是带有嵌入美国英语字符串的希伯来语文本,我想我想在 上使用语言环境heIDWriteTextFormat然后用字符范围 [4-9] 上SetLocaleName的语言环境覆盖它。en-US但是,这样做没有任何效果。事实上,无论我将它们限制在一个子范围还是将它们应用于整个字符串,我都无法在这些地方使用任何语言环境组合来对布局产生任何影响。

我认为这些 API 应该服务于这个目的是错误的吗?如果是这样,我应该使用哪些 API?还是真的没有办法告诉IDWriteTextLayout以不同的方式解决这种歧义?我是否可能使用错误的 API?这是我用来创建它的测试代码IDWriteTextLayout

TestTextRenderer::TestTextRenderer(const std::shared_ptr<DX::DeviceResources>& deviceResources) : 
    m_deviceResources(deviceResources),
    m_text(L"\u05e9\u05e0\u05d1\u05d2abcd!"),
    m_readingDirection(DWRITE_READING_DIRECTION_RIGHT_TO_LEFT),
    m_formatLocale(L"en-US"),
    m_layoutLocale(L"en-US")
{
    ComPtr<IDWriteTextFormat> textFormat;
    DX::ThrowIfFailed(
        m_deviceResources->GetDWriteFactory()->CreateTextFormat(
            L"Segoe UI",
            nullptr,
            DWRITE_FONT_WEIGHT_MEDIUM,
            DWRITE_FONT_STYLE_NORMAL,
            DWRITE_FONT_STRETCH_NORMAL,
            24.0f,
            m_formatLocale.c_str(),
            &textFormat
        )
    );
    DX::ThrowIfFailed(textFormat->SetReadingDirection(m_readingDirection));

    DX::ThrowIfFailed(
        m_deviceResources->GetDWriteFactory()->CreateTextLayout(
            m_text.c_str(),
            (uint32) m_text.length(),
            textFormat.Get(),
            250.0f,
            100.0f,
            &m_textLayout
        )
    );

    DWRITE_TEXT_RANGE all{0u, m_text.size()};
    DX::ThrowIfFailed(m_textLayout->SetLocaleName(m_layoutLocale.c_str(), all));

    DX::ThrowIfFailed(m_deviceResources->GetD2DFactory()->CreateDrawingStateBlock(&m_stateBlock));
    CreateDeviceDependentResources();
}
4

1 回答 1

3

从 Unicode BiDi 算法的角度来看,我认为没有任何歧义。初始方向设置为IDWriteTextFormatorIDWriteTextLayout是至关重要的,但之后运行方向将严格从代码点派生。

设置语言环境不会改变方向,但可能会影响造型,最终结果取决于运行字体的特定功能。

我认为您可以在这部分文本周围使用 LRE/PDF 控件完成abcd!...输出。

于 2016-01-23T08:51:30.400 回答