特殊文字の表示がおかしいときがある

  1. はじめまして。
    Mery 2.6.8 を使っておりますが、特殊文字の表示で不思議な現象に
    出くわしたので、当方の環境の問題かもしれませんが、念のためご報告です。

    症状:
    下記の条件の場合に文字の表示がおかしい
    ・U+2B24 や U+26BF の文字をテキストに入れる
    ・フォントが游ゴシック(メイリオでは発生しない)
    ・当該文字の前後に全角文字が無い
    という条件を満たすと、当該文字が「・」になります。

    環境はWindows10 Home 1803です。

    お手数をおかけしますがよろしくお願いいたします。
    必要であれば、現象が出るファイルを送付することも可能です。
    あるいは、当方で試すことがあればご連絡ください。

     |  taka  |  返信
  2. はじめまして、ご愛用&ご報告ありがとうございます。
    現象、確認いたしました。

    単純に「游ゴシック」で U+2B24 を描画 (TextOut) するだけのテストプログラムを作成して確認してみたところ、同様の現象が発生しました。どうやら GDI で文字を描画していると発生するようです。

    また、秀〇エディタ、E〇Editor、Sublime Text (DirectWrite オフ) で試してみたところ、いずれも同様の現象が発生しました。(メモ帳だと発生しませんでした)

    詳しいことはマイクロソフトに聞かないとわかりませんが (聞いても教えてくれないかも…)、フォントリンクに関係している気がします。

    Mery ですと [ツール] → [オプション] → [表示] タブの中の右下のほうにある [詳細] ボタンから DirectWrite をオンにすれば回避できました。(この現象は Windows の仕様っぽいので Mery 側の修正で対応できるものではなさそうです)

    以下は、調査した内容ですが、非常に根が深いものとなっております。

    --------
    フォントリンクというのは、使用中のフォントに該当の文字が含まれていない場合に代わりのフォントを使用する設定ですが、これはレジストリの下記に記述されています。

    コンピューター\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink

    例えば「メイリオ」なら [Meiryo] という値で [SEGUISYM.TTF,Segoe UI Symbol] というフォントが代替フォントとして設定されているので、フォントに含まれていない U+2B24 という文字は、代わりの Segoe UI Symbol が使用されるため、正常に描画されます。

    Windows 10 では「游ゴシック (Yu Gothic)」はフォントリンクの設定がありませんでした。(Yu Gothic UI は設定されています)

    したがって、游ゴシックの場合、当該文字の前後に全角文字がないと Windows はフォントリンクをたどって代わりのフォントを使おうとしますが、フォントリンクが設定されていないので代わりのフォントが見つからず「・」と表示されてしまいます。

    試しに游ゴシックのフォントリンクに「SEGUISYM.TTF,Segoe UI Symbol」を設定してやると正常に描画されました。

    また、このフォントリンクという機能は GDI (DirectWrite を使用しない) の場合に使用されるものですから、DirectWrite を使用する場合はフォントリンクは使われず、よりイイ感じに不足フォントを補ってくれる仕組みになりますので、本件のような現象が発生しないものと思われます。

    以上が、フォントリンクに起因する現象です。

    で、前後に全角文字があると、なんで正常に表示されるの?という点ですが、これはわかりません。

    さらに詳細に申し上げますと…

    単純に文字を描画するだけの Windows API でも、TextOut と DrawText (どちらも文字を描画するだけの関数) で挙動が異なりました。

    TextOut や ExtTextOut (gdi32 の機能) だと前後に全角文字がないと「・」になりますが、DrawText (user32 の機能) だと前後に全角文字がなくても大丈夫でした。メモ帳だと大丈夫なのはおそらくDrawText が使われているためかと推測します。(もちろん、DrawText だけだと複雑なテキストエディタを作ることはできませんので…)

    さらに TextOut や ExtTextOut でもフォントの CharSet を中国語 (CHINESEBIG5_CHARSET) やタイ語 (THAI_CHARSET) にすると、前後に全角文字がなくても大丈夫という挙動ですので、Windows が前後の文字から自動でロケールを判断してフォントリンクを使うかどうかを決めてるのかも?

    いずれにせよ、このようにフォントリンクは OS のバージョンや API によって仕様や挙動が異なったりしますし、内部でどういう動作をしているのかという情報も公開されていないため知りようがありません。

    根本的な解決には至らずモヤモヤしますが、Windows の仕様ということで諦めるしかなさそうです。

     |  Kuro  |  返信
  3. 早速の詳細な調査ありがとうございました。
    とても根が深い問題だとわかりました。
    また、回避方法も提示していただき助かります。
    ありがとうございました。

     |  taka  |  返信
スポンサーリンク