このページは過去に掲載していたものをそのまま使用しています。

[ Home | Index ]

dia-0.84-6で修正された2byte文字対応について

いままでの方法で、どこが悪かったのかについて書いた メモです。

問題点

すべてはテキストウィジェットで文字を入力しないで、Deleteキーを押すと XIMのフォーカスを失なってしまうという問題が始まりでした。その後いろいろ 調べて行くと、"aaa"と文字を打った後に、left arrowキー ('<-'キー)を一回押して さらにDeleteキーを打つとカーソルが正しく移動しないという事がわかりました。

またXIMのフォーカスが失なわれる理由は他にもあるようで、これは まだ不完全な解決に過ぎません。

解決方法

解決方法は主に間違ったmemmove関数の使い方(memmoveを使う時点で嫌なんですが) や2byte毎に操作を行なう事の徹底が行なわれました。

 #ifdef JAPANESE
-  if(text->line[row][text->cursor_pos+1] > 0) {
+  if(text->line[row][text->cursor_pos] > 0) {
     memmove(text->line[row] + text->cursor_pos,
            text->line[row] + text->cursor_pos + 1,
            text->strlen[row] - text->cursor_pos);
 
     text->strlen[row]--;
-    text->cursor_pos --;
   } else {
     memmove(text->line[row] + text->cursor_pos,
-           text->line[row] + text->cursor_pos + 2,
-           text->strlen[row] - text->cursor_pos);
-  text->strlen[row]-=2;
-  text->cursor_pos -=2;
+           text->line[row] + text->cursor_pos + 2,
+           text->strlen[row] - text->cursor_pos - 1);
+
+    text->strlen[row]-=2;
   }

上記のコードではmemmoveを使って一文字を消去しています。 これではあまり良いコードは必然的に書けないので、diaようの マルチバイトサポート関数を作成する必要を感じています。ただ 参考になるものがないので、自前でウィジェットを作成している i18nなものがあれば教えてください。

現在の解決方法は場当たり的な感じがします。 根本的にはgtk+-1.2.7/gtk/gtktext.c辺りを参考にして i18nな処理によって文字の削除や移動を行なわないとダメな気がします。 そもそも文字列に対して色やフォントの属性を決めているので、一文字(GdkWChar)を 構造体に格納して、様々な要素を独立に管理できる(tgifの)ようなものの方が 使えるかもしれません。それも善し悪しですが。

コードでみるDia日本語化

case GDK_Right:
#ifdef JAPANESE
    if(text->line[text->cursor_row][text->cursor_pos+1] > 0) {
      text->cursor_pos++;
    } else {
      text->cursor_pos+=2;
    }
#else
    text->cursor_pos++;
#endif

これは、ある行のcursor_pos番目の文字が負数、つまりEUCであるらしい 場合には普段の2倍だけカーソルの位置を移動させる事を表わしています。ここで 問題になるのは、EUCじゃない(ASCIIでもない)文字の場合にはどうするのか、 という点です。カーソルをn文字進める関数やn文字分文字列を消去する関数などが 必要になるのですが、diaのtext.cの中では定義されていません。

こんなことを全ての場合にやるのは穴ができやすいので、 文字列操作をすべてGdkWCharに変換してから行なうか、あるいはrubyのように EUCであるかどうかの判定を行なって適切なEUC, JISなどのコードに変換する事が 必要になるでしょう。


Yasuhiro Abe <yasu@europa.u-aizu.ac.jp>
Last modified: Mon Apr 17 09:51:18 2000