SDL2 でテキスト入力ボックスを作る 2

 ASCII文字(1 バイト文字)は、キャレットの移動や、文字削除はうまく行きましたが、UTF8 文字は判定しないといけないので処理が複雑になります。

 まず、UTF8 の 1 バイト目の上位 4 ビットでバイト数がわかります。1100 なら 2 バイト、1110 なら 3 バイト、1111 なら 4 バイトです。このバイト数には、自分自身が含まれます。残りの 4 ビットは無視してもいいようです。そして、後続バイトの先頭 2 ビットは必ず 10 になるようです。例えば次のビット列で それぞれ 1 文字になります。

1110 xxxx 10xx xxxx 10xx xxxx
1100 xxxx 10xx xxxx

 つまり、最上位ビットが 1 であれば UTF8 であり、次のビットが 0 でなければ、そのバイトから文字が始まります。C 言語で書けば次のようになります。

char c[];

if( (c[i] & 0xc0) == 0xc0 ) {
    /* UTF8 文字の開始 */
} else if( (c[i] & 0xc0) == 0x80 ) {
    /* UTF8 文字の 2 バイト目以降 */
} else {
    /* ASCII 文字 */
}

 この判別で UTF8 文字を識別できました。

 文字列の処理は、キャレットより前の文字列、変換中の文字列、キャレットの後の文字列と 3 つの部分に分けて処理していかなければなりません。変換中の文字列は、背景に色を付けて視覚的にわかるようにしました。

 なんとかテキストボックスっぽくなりました。ただ、変換中はキーイベントが IME に取られてしまうようで、文節の調整とかを表示させることができません。イベントがないので対処ができません。

テキスト入力

 入力中の文字の選択はできません。また、カット&ペーストもできません。1文字削除とキャレットの移動しかできませんが、本格的な編集機能を望むのであれば、他の便利なライブラリを使ったほうがいいでしょう。あくまで、SDL2 のみで GUI を実現してみたかったので、これ以上の編集機能を作っていくつもりはありません。例えば、他のライブラリが使えない不自由な環境の中で、GUI を使いたい場合を想定しています。

 次は、確認ダイアログを作ってみたいと思います。

SDL2

Posted by sirius