OpenSiv3D
OpenSiv3D copied to clipboard
SimpleGUI::TextBox() で異体字を入力するとカーソルと挿入位置が一致しない
SimpleGUI::TextBox()
や SimpleGUI::TextArea()
などで、入力文字列に異体字セレクタが含まれるとカーソルの位置と挿入・削除される文字の位置がずれることがあります。
異体字セレクタが含まれると UTF-32 での文字数と Glyph
の数が一致しなくなるため、一致することを前提に設計されている SimpleGUI::TextBox()
などの挙動がおかしくなります。
検証用コード
# include <Siv3D.hpp> // Siv3D v0.6.12
void Main()
{
TextEditState textBoxState{ U"竈門禰󠄀豆子" };
TextAreaEditState textAreaState{ U"渡邉󠄂 渡邉󠄃 渡邉󠄄 渡邉󠄅 渡邉󠄆 渡邉󠄇 渡邉󠄈 渡邉󠄉 渡邉󠄊 渡邉󠄋 渡邉󠄌 渡邉󠄍 渡邉󠄎 渡邊󠄁 渡邊󠄂 渡邊󠄃 渡邊󠄄 渡邊󠄅 渡邊󠄆 渡邊󠄇\n" };
while (System::Update())
{
SimpleGUI::TextBoxAt(textBoxState, Vec2{ 400, 150 }, 600);
SimpleGUI::TextAreaAt(textAreaState, Vec2{ 400, 350 }, SizeF{ 600, 250 });
}
}
cursorPos
を String
のインデックスに合わせるのと Array<Glyph>
のインデックスに合わせるの、どちらがいいと思いますか?
TextInput::UpdateText()
や Platform::Web::TextInput::GetCursorIndex()
の実装に合わせて、String
のインデックスに合わせるのがよさそうです。
SimpleGUI::TextBox()
異体字対応の実装案
https://gist.github.com/Raclamusi/1caaacf34a552be9881ba7877223c683/29caa5de8059cbc4c85b4f0c36d36915a321b7b9
Revisions: https://gist.github.com/Raclamusi/1caaacf34a552be9881ba7877223c683/revisions#diff-ff9db3cb6025e343dacac7fe1b565394e85d2b614be4ab7b7fedb99d8e8b762d
Font::getGlyphClusters()
から取得できるグリフに対応する文字のインデックスを利用して、カーソルの移動をグリフ単位で行うようにしました。
グリフ単位での削除については TextInput::UpdateText()
をいじる必要があるため対応しませんでしたが、これはあまり重要ではないと思います。
フォントのフォールバックなしで実装しています。
ありがとうございます。検証してみます。
SimpleGUI::TextArea()
で GlyphCluster
から取った情報を TextAreaEditState
にキャッシュするようにしました。
https://gist.github.com/Raclamusi/1caaacf34a552be9881ba7877223c683/f7cb5131578fdd800107ab46d95f588f4dfd2c9e
Revisions: https://gist.github.com/Raclamusi/1caaacf34a552be9881ba7877223c683/revisions#diff-ff9db3cb6025e343dacac7fe1b565394e85d2b614be4ab7b7fedb99d8e8b762d