有些字符具有模糊的方向性,如空格和标点符号。这可能导致文本布局的情况,在这种情况下,如果不访问额外的数据来解决歧义,似乎就没有一个正确的布局。考虑以下文本:
\u05e9\u05e0\u05d1\u05d2abcd!
这是四个希伯来语字符(从右到左)、四个英语字符(从左到右)和一个标点符号(模棱两可)。如果我在
IDWriteTextLayout
具有
DWRITE_READING_DIRECTION_RIGHT_TO_LEFT
,我得到以下结果:
标点符号似乎被视为一个从右到左的字符,它在英语的左边开始一个新的从右到右的块,这似乎完全合理,尤其是考虑到从右到左边是指定的阅读方向。然而,期望标点符号被视为与嵌入的从左到右英语文本相关的从左至右字符也是完全合理的,这意味着它应该出现在“d”的右侧。
我的应用程序确切地知道它希望如何对待这个角色。如何将数据传递给
ID写入文本布局
要解决这种歧义?
我找到了
SetLocaleName
方法,并认为这一定是答案,但我似乎根本无法让它影响结果。我还发现
localeName
创建时的参数
IDWriteTextFormat
(然后用于创建
ID写入文本布局
).
如果我的目标是让它通常是希伯来语文本和一个嵌入的美式英语字符串,我想我应该使用语言环境
he
上
ID写入文本格式
然后使用
设置区域名称
用locale覆盖
en-US
字符范围[4-9]。然而,这样做没有效果。事实上,无论是将它们限制在子范围还是将它们应用于整个字符串,我都无法得到这些地方使用的任何区域设置组合对布局产生任何影响。
我认为这些API应该达到这个目的,这是错误的吗?如果是,我应该使用什么API?还是真的无从得知
ID写入文本布局
以不同的方式解决这种歧义?我可能用错API了吗?这是我用来创建这个的测试代码
ID写入文本布局
:
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();
}