1

空白や句読点など、一部の文字は方向性があいまいです。これにより、あいまいさを解決するための追加データにアクセスしないと、単一の正しいレイアウトがないように見えるテキスト レイアウトの状況が発生する可能性があります。次のテキストを検討してください。

\u05e9\u05e0\u05d1\u05d2abcd!

これは、4 つのヘブライ文字 (明確に右から左)、4 つの英語の文字 (明確に左から右)、および 1 つの句読点 (曖昧) です。IDWriteTextLayoutその文字列をwithにレイアウトするとDWRITE_READING_DIRECTION_RIGHT_TO_LEFT、次のようになります。

左端に句読点が表示されているレンダリングされたスクリーン ショット。

句読点は、英語の左側にある新しい右から左のブロックを開始する右から左の文字として扱われるように見えます。これは、特に右から左が指定された読み方であったことを考えると、完全に合理的です。方向。ただし、句読点が、埋め込まれた左から右の英語テキストに関連付けられた左から右の文字として扱われることを期待することも完全に合理的です。つまり、句読点は「d」の右側に表示される必要があります。

私のアプリは、このキャラクターをどのように扱うべきかを正確に知っています。IDWriteTextLayoutこのあいまいさを解決するためにそのデータを渡すにはどうすればよいですか?

メソッドを見つけて、SetLocaleNameそれが答えに違いないと思ったのですが、結果にまったく影響を与えていないようです。localeNameを作成するときにパラメーターも見つけましたIDWriteTextFormat(これは、を作成するために使用されますIDWriteTextLayout)。

私の目標が、一般的に米国英語の文字列が埋め込まれたヘブライ語のテキストになることである場合、 でロケールを使用してから、文字範囲 [4-9]でロケールheをオーバーライドするために使用したいと思います。ただし、これを行っても効果はありません。実際、これらの場所で使用されているロケールの組み合わせがレイアウトにまったく影響を与えることはありません。それらを部分範囲に制限するか、文字列全体に適用するかは関係ありません。IDWriteTextFormatSetLocaleNameen-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 アルゴリズムの観点からは、あいまいさはないと思います。IDWriteTextFormatorに設定された最初の方向IDWriteTextLayoutは重要ですが、その後の実行方向はコードポイントから厳密に導出されます。

ロケールを設定しても方向は変わりませんが、シェーピングに影響を与える可能性があります。最終結果は、フォントが実行する特定の機能に依存します。

テキストのこの部分の周りに LRE/PDF コントロールを使用してabcd!...出力を達成できると思います。

于 2016-01-23T08:51:30.400 に答える