WinMergeで[空白を表示]をONにすると、キャレットの位置がズレる
udaken opened this issue · 7 comments
WinMerge でフォントにHackGenを指定し、メニューの[表示] - [空白を表示]をONにすると、タブ文字を含んだ行のキャレットが誤った位置に表示されます。
ちょっと画像だと分かりにくいかもしれませんが、下記画像のbの前にキャレットがあるのですが、タブ文字の途中に表示されます。
break
WinMerge側の問題かHackGen側の問題かわからないのですが、HackGen以外のフォントでは起きなかったので報告させてもらいます。
環境:
- Windows 10 21H2
- WinMerge 日本語版 2.16.18+-jp-3
不具合が発生するフォント:
- HackGen v2.6.1
不具合が発生しなかったフォント:
- HackGen Console v2.6.1
- Hack v3.003
- PlemolJP
- UDEV Gothic
- UDEV Gothic JPDOC
- MS Gothic
- UD デジタル 教科書体 N-R
- Cascadia Mono
- Consolas
WinMerge、HackGen共に少し古いバージョンでも発生していましたが、細かいバージョンは控えてませんでした。
メモ: U+00BB の扱われ方を調べる。
@udaken
ご報告ありがとうございます。
こちらでも同じ状況が確認できました。どういう理由なのかは分かりませんが、WinMergeではタブ文字可視化に使っている記号 » (U+00BB)
が、HackGenだと全角として扱われてしまうようです。それにより、キャレットの位置ずれが引き起こされていたようです。
またご認識の通り、HackGen Consoleではちゃんと半角として扱われていました。通常版とConsole版での差は、当該記号が源柔ゴシック由来かHack由来かの違いしかなく、いずれにしても半角幅の記号であり、WinMerge以外のエディタでは正しい幅で表示されていました。WinMerge固有の問題であるようには思えますが、ひとまずHack由来の » (U+00BB)
を適用することで正常になったので、この方法で対応しようと思います。
以下に、修正済みのフォントをプレリリースで出しました。お試しください。
早々に対応いただいてありがとうございます。
プレリリース版で解消されていることを確認し出来ました!
この問題、WinMerge側の問題だと思うようになりました。
[オプション(エディター > 一般)]でレンダリングモードをGDIからDirectWriteに変えると不具合は発生しませんでした。
以前に試していたんですが、ウィンドウを開きなおさないと反映されない様で、確認が不足してしまいました。
仮に» (U+00BB)
を全角で表示することがWinMerge側の想定動作だとしても、
レンダリングモードで変わるのはおかしいので、WinMergeに何らかの問題があるはずです。
WinMerge側にも報告しました。
WinMergeへのご報告ありがとうございます🙇♂️
GDIとDirectWriteで表示が変わってしまうというのは、フォント合成をしているとよくあることで(ほとんどの場合、私の理解不足が原因で引き起こすのですが…)、今回もそれかなと思ったのですが、GDI描画のサクラエディタやMery(DirectWrite OFF状態)で表示しても想定の半角幅になることから、今回はちょっとお手上げでした。
たまたまHackGen Consoleでは正常に表示されることから予測して今回の対症療法に至ったわけですが、結局なぜ解消されたのかは分からずです…。ともあれ、解消できてよかったです。
WinMergeメンテナコメントより抜粋
再現できず、しばらく悩んでいたのですが、HackGen-Regular.ttf だけインストールすると問題なく、HackGen-Bold.ttf もインストールすると問題が再現するようでした。
WinMergeでは、日本語ターミナルソフトのように漢字等の全角文字を半角2文字分の幅で表示しています。 全角文字判定は、それぞれの文字のフォントの幅をGetCharWidth32() Win32APIを使用して取得し、半角文字の幅よりも1.5倍以上であれば、全角文字とみなすようにしています。
レンダリングモードがGDIの場合、フォントの幅を計算する際、フォントを太文字かつ斜体に設定しているのですが、HackGenフォントでは、 タブを表す文字(U+00BB)がなぜか全角相当の幅で取得されていました。(フォントを太文字かつ斜体でなければ半角相当の幅となっていました)
カレット位置を計算する際はタブを表す文字は半角幅とみなして計算しますが、実際に表示する際は、タブを表す文字を全角幅で表示するため、このずれが発生していました。
レンダリングモードをDirectWriteに変えると問題なかったのは、フォント幅を計算する際、フォントを太文字かつ斜体に設定しなければならなかったのですが、そうしておらず、タブを表す文字の幅が半角幅で取得できたためでした。
HackGenで » (U+00BB)
の幅が、Regular: 半角, Bold: 全角というように、食い違っていることが原因だった模様。この状態は、合成元の源柔ゴシックのRegular/Boldで幅が食い違っていることが原因。(以下図参照)
Hackの記号を適用することで事象が発生しなくなったのは、このRegular/Boldにおける幅の違いが無くなったためと見られる。