読者です 読者をやめる 読者になる 読者になる

マルチバイト対応と高速化 - Flexでターミナルエミュレータ

まともな対応方法ではないですが、見た目上はUTF-8EUC-JPがそこそこ通るようになりました。CodeRepos://lang/actoinscript/FxTerm/trunk


エスケープシーケンスの中にカーソルの位置を変更するものが良く出てくるのですが、その指定の方法が、(行, 列)の形式で指定されるのでとても困る。バイト数ではなく見た目上の位置で指定される(全角の文字なら2列分とカウント)。文字が全角なのか半角なのか判断しないといけないし、カーソルの先の文字がバイト列上でどこのバイトになるのか計算しないといけない。
それから、送られてくるバイト列には文字と文字の区切りなんて入っていないから、いつ次の文字に移るのか分からない。UTF-32だったら嬉しいんですけどねぇ。


マルチバイト文字と言えばこのあたりは当たり前なのでしょうが、真面目にやると大変なので、極めていい加減な方法で切り抜けました。
すなわち、全角文字と半角文字の判別は、実際にTextFieldに文字を描画してみて、幅が半角文字の倍くらいなら全角文字と判断。文字と文字の区切りは、ActionScriptのString型はマルチバイト文字でも1文字とカウントしてくれるので、バイト列をマルチバイト文字に変換したときに2文字になったら文字の区切りだと判断。
おまけとして、全角文字の上にカーソルがあるときはカーソルの幅を2倍にするようにしてみました。マルチバイトに対応してるぜー感が味わえます。



マルチバイト対応はAdHocですが、描画周りはしっかり高速化しました。書き換わった行だけを再描画するようになりました。スクロールしなければかなり軽いです。iTermくらい?
背景色はGraphicsクラスに矩形のベクトルグラフィックとして描画していたのですが、どうやらGraphicsクラスは部分的に削除することができないらしいので(知らないだけ?)、代わりにBitmapDataクラスにラスタグラフィックスとして描画するようにしてみました。これで背景色も書き換わった行だけ再描画できます。


ちなみに前回使っているとだんだん重くなってきたのは、Graphicsクラスに描画した背景色を一度も削除していなかったからでした。ベクタグラフィックスであることを忘れていて、図形を上書きしたとしても下になった図形がGCされるわけでもなく、ガツガツとメモリリークしていました。


残る問題点としては…

  • 日本語が入力できない
  • 矢印キーが使えない
  • screen + vimでウィンドウ分割するとおかしくなる
  • Shift_JISは盛大に化ける

思えば日本語を入力できるようにするには、日本語はインプットメソッドから入力されるので、キーイベントを拾う方法ではダメですねぇ。透明なTextAreaを用意して、そのTextAreaのchangeイベントを拾う? BackSpaceとか修飾キーはどうしよう。うーむ。ActionScriptで日本語入力システムを実装すれば完璧だけど…。