Windows のコンソール端末と Unicode の相性

その他
[ Windows のコンソール端末と Unicode の相性 ]

Windows のコンソール端末環境と Unicode の相性はかなりイマイチです。先日発表された Windows Terminal も含めて、その一端を紹介したいと思います。

追加多言語面を上手く扱えない

U+0000 ~ U+FFFF の 基本多言語面 (BMP) に続く、U+10000 ~ U+10FFFF の 追加多言語面 (SMP) を上手く扱えないケースが少なくありません。

日本語で言うと、JIS X 0213 の第3水準漢字・第4水準漢字や絵文字などにあたります。

UTF-16 でサロゲートペアに対応していないアプリや、UTF-8 で3バイトまでしか対応していないアプリは、共に基本多言語面 (BMP) しか扱えず、表示や入力は期待通りになりません。

文字化け

コマンド プロンプトPowerShellWSL の Ubuntu など、Windows の既定のコンソール ウィンドウ ホスト conhost.exe を利用して表示すると文字化けします。

echo "☃㋿あ漢🙂𠮟𠮷" で試してみます。

フォントは MS ゴシック に揃えてみました。

文字UnicodeJIS X 0213CP932備考
U+26031-06-75なしJIS X 0213 の雪だるま
U+32FFなしなしJIS X 0208, 0212, 0213 にない合字
U+30421-04-0282A0非漢字
U+6F221-20-338ABF第1水準漢字
🙂U+1F642なしなしサロゲートペアの絵文字
𠮟U+20B9F1-47-52なし第3水準漢字
𠮷U+20BB9なしなしJIS X 0208, 0212, 0213 にない漢字

サロゲートペアの文字化け

MacType が効いている MSYS2 の mintty は、雪だるまと令和合字の字送りの幅が半角扱いなことを除けば、概ね合格です。

サロゲートペアを扱えないのは、マルチバイトの文字コードを扱えない、シングルバイト圏のソフトウェアのような話です。

FontLink

レジストリの FontLink で欧文フォント等に和文フォント結び付けていると、意図しない形で FontLink と異なるフォントになることがあります。メモ帳で先ほど同様に試してみると、次のように。

FontLink

どうやらコードポイントによって、FontLink のフォントでなく、システムの他のフォントで描画されてしまうようです。

  • ☃ U+2603 が Segoe UI Emoji
  • 𠮟 U+20B9F や 𠮷 U+20BB7 が 游明朝

しかも、混入した 游明朝 の文字は、なぜか一回り大きな文字サイズです。標準の Segoe UITahoma でも見られる現象なので、Consolas + MeiryoKe_Gothic がアレだというのとは別の話です。

同じ「漢字」なのに、コードポイントによって書体と文字サイズが異なる……、怪文書のような表現です。

ちなみに MS ゴシック でのツチヨシは、フォントのビットマップのデータそのものが、明らかに統一感に欠けるおかしな具合です。深読みすると、JIS X 0213 に登録されていない文字である警告を込めての、デザインなのかも知れません。

MS Gothic U+20BB7

絵文字を上手く扱えない

macOS と Linux ではそれなりに扱えているようですが、Windows のコンソール端末にその時代は未だ来ていません。

カラー絵文字

Windows でカラー絵文字に対応する文字描画 API は限られていて、正攻法は DirectWrite だけのようです。

MacType の最新ベータ版で ColorFont を使う方法もありますが、こちらは GDI でアプリとの相性にも依ります。

FontLink with MacType

カラー絵文字のフォント形式も4種類ほど乱立していて、それぞれ使える OS や環境が異なるという、戦国時代まっただ中な感じです。

シーケンスと字形選択子

Emoji Presentation Sequences の対応は大幅に欠けています。アプリによっては、異体字セレクタの一種の字形選択子 U+FE0E や U+FE0F などが文字化けして描画されます。

Emoji Default Style (text) の冒頭を出力させると、この様に。

emoji mintty

emoji Rlogin

絵文字アイコンで分かり易いつもりが、きちんと伝わらず逆効果になるのは、かつての機種依存文字に関するリテラシーと、良く似ています。

幅化け

先ほどの画像にあるとおり、円形や正方形の絵文字が半角の幅に縮小されたり、左右の文字と半分被ったりしています。

絵文字は半角で何文字分かという想定とは別に、そもそも Segoe UI Emoji は、ラテン文字にマッチするデザインのプロポーショナルフォントです。FontForge での画面を切り貼りして 游ゴシック と並べると、この通り。

Segoe UI Emoji

コンソール端末とのミスマッチは一目瞭然です。

Unicode を上手く入力できない

conhost.exe と OpenSSH for Windows

コンソール ウィンドウ ホスト conhost.exe の中から C:\Windows\System32\OpenSSH\ssh.exe を使ってリモートホストに繋ぐと、Shift_JIS な CP932 で表現できない文字が入力できません。

サーバに繋いで echo "☃㋿あ漢🙂𠮟𠮷" | hexdump -C とすると、単に手元の描画が上手く行かないだけでなく、, 以外が届いていません。

入力表示端末シェルssh
××conhostcmdWindows
×conhostcmdMSYS2
××conhostPowerShellWindows
×conhostWSL / bashWSL
××conhostWSL / bashWindows
×ConEmuPowerShellWindows
PuTTY
minttyMSYS2 / bashMSYS2
minttyMSYS2 / bashWindows (winpty 経由)

conhost.exe と OpenSSH for Windows の組み合わせに限って、内部で CP_ACP を介してしてしまうのでしょうか。

(ちなみに PuTTY は、最新の 0.71 + MacType でもカラー絵文字になりません)

Tera Term

CP932 ≒ Shift_JIS (JIS X 0201 + JIS X 0208) の範囲の意識が必要な Unicode 環境というのは、Tera TermUnicode設定 の説明が分かりやすいと思います。

現状のTera Termは内部設計がUnicode対応になっておらず、以下に示すように文字コードは二段変換になっています。

UTF-8 <-----> Unicode(UTF-16LE) <-----> MBCS
        (1)                       (2)

(1)において、UTF-8は3バイトまでしか変換していないため、サロゲートペア(surrogate pair)や結合文字(combining character)などには対応していません。
(2)において、UnicodeとMBCS(Multiple Byte Character Set)の相互変換を行うために、ロケール(言語指定)を正しく設定する必要があります。

このことを Tera Term は令和合字 U+32FF を扱えない と表現すると、衝撃的かも知れません。

問題なく Unicode 対応と思って利用してきたツールが、実は UCS-2 や CP932 の範囲でしか動いてくれない仕様だった、というケースは山のようにありそうです。

使うかどうかは別として、Unicode 対応なのに令和合字を扱えないのは、……令和時代の日本人に相応しい環境なのか疑問を感じるところです。

Windows Terminal

さて、Microsoft は先日、旧来との互換性との兼ね合いで改善が難しい conhost.exe とは別に、新しいコンソール端末 Windows Terminal を発表しました。

The new Windows Terminal

宣伝動画 での画面は とても美しい文字描画 で、心を奪われそう になります。

文字描画は DirectWrite

公式ブログ のスクリーンショットを良く見てみましょう。

Windows Terminal Emojis

通常の 200% の文字サイズ(4Kモニタ用)での DirectWrite です。ガワもフラットデザインで、動画のような 3D ルックスではありません。

ビルドして動かしてみた方の 記事 のスクリーンショットを見ると、とても見慣れた感じの、ごく普通の DirectWrite です。

……そう。悲しいことに、動画での画面は、3DCG で作り込んだイメージ(想像図)なのだと、見破らなくてはならないのです。

動画に映る C:\Users\Administrator というパスも、何かやらかした感があります。

conhost.exe での問題点を解決できているのか

ものは試しです。Windows 10 Insider Preview で プレビュー版の野良ビルド を動かしてみました。

Windows Terminal は FontLink が効かない
日本語表示と FontLink
Windows Terminal の ConsolasIPAゴシック を FontLink で設定。
メモ帳は参考までに、上が FontLink させた Consolas、下は素の IPAゴシック
  • 日本語部分は Meiryo UI が等幅に配置される
  • FontLink は効かない(ごく普通の DirectWrite の動作)
  • フォントは1つしか指定できない("fontFace": "Conosolas, MS Gothic""fontFace": ["Consolas", "MS Gothic"] はエラー扱いなのか動かない)
Windows Terminal で プロポーショナルフォント, IME, 絵文字, サロゲートペア
プロポーショナルフォント, IME, 絵文字, サロゲートペア
  • Segoe UI などプロポーショナルフォントも等幅として配置される(読みにくい)、更に漢字と仮名が異なる文字サイズに(Meiryo UI の文字毎の字幅から文字サイズを逆算?)
  • IME に未対応(デスクトップの左上に IME 入力ウィンドウが出る)
  • 素早く文字の入力や消去(バックスペース等)を行うと、最後の変化が再描画される(echoechecho のように)
  • chcp 65001 で UTF-8 で保存したファイル内容の表示 → サロゲートペアを含めて一応できる?
  • chcp 65001 で BMP の入力と表示 → できる
  • chcp 65001 で絵文字のシーケンス・字形選択子の表示 → シーケンスによって豆腐あり、表示中に固まる
  • chcp 65001 で サロゲートペアの入力 → できない(エラーなのか動かなくなる)
Windows Terminal で Shift_JIS / CP932
CP932 (Shift_JIS) と曖昧文字の幅
  • chcp 932 で CP932 にない BMP の入力と表示 → なぜかできる
  • chcp 932 で CP932 にない BMP をファイルにリダイレクト → ?(半角疑問符)に文字化けする
  • chcp 932 で 曖昧文字 の入力と表示 → MS Gothic 等なら全角表示
  • chcp 932 で 曖昧文字 の入力後の BS やカーソル移動 → ズレたり、小さな文字サイズのゴミが描画される

あまりにも早すぎるプレビュー版のようです。

夏にプレビューリリース、冬に一般リリースを目指しているそうなので、改めて試してみたいですね。

ただ、大抵のことは既に mintty と MacType で解決できてしまっています。残っているのは、

  • Windows で使える等幅絵文字フォントの普及
  • FontLink とシステムの絵文字フォントに関する OS での扱い方
  • Unicode 文字列にホストが期待する幅のエスケープシーケンス化と端末の対応みたいなコト

といった話になる気がします……。

タブ化は、別窓で動いている画面が完全非表示になるのと同じなので、透過表示やオーバーレイのモニタリングが無いなら、個人的には興味ないです。

What’s new with the Windows Command Line – BDL2029

少し長めの動画ですが、デモの内容がラテン文字圏と大きな文字サイズに偏っています。先ずそこから、というステップは理解できますが、先行きが不安になります。6:15 辺りの、コーディング向けのリガチャ(合字)に関するやり取りは、見物かもしれません。

悪い予感がする、というのは、外れればそれに越したことはなく、むしろ外れることを願いつつ、口にするものです。

そういう意味で、宣伝動画の内容は今のところ、絵に描いた餅 です。

万全の動作によって、同種のコンソール端末アプリへの良い影響(または淘汰)が広がる事を願ってやみません。

終わりに

Windows のコンソール端末と Unicode の相性は、今のところご覧の有様です。絵文字は兎も角、JIS X 0213 が完全に使えないのは問題でしょう。

VirtualBox で Ubuntu Desktop 辺りを動かすのが、手堅い代替案かもしれません。

それでは、改めて Windows Terminal の今後に期待したいと思います。ビバ!

コメント

  1. masao より:

    「Tera Term は令和合字 U+32FF を扱えない」の部分、サロゲートペアでも結合文字でもなく、ただの合字なのだからTeraTermでも扱えるのではないかと思うのですが、自分の勘違いでしょうか? これがダメなら「㍻」もダメではないかと思うのですが…。

    • ともにく より:

      Tera Term 4.102 で試したところ、「㍻」は OK で、「㋿」は「?」に文字化けします。

      日本語での入出力に、MBCS(CP932) ←→ Unicode (UTF-16LE) ←→ UTF-8 の変換が行われているので、単純に、「㍻」は CP932 で表現可能で、「㋿」は CP932 で表現できないことが、直接の原因だと思われます。

タイトルとURLをコピーしました