kmiya-culti / RLogin

RLoginは、Windows上で動作するターミナルソフトです
http://nanno.bf1.jp/softlib/man/rlogin/
MIT License
478 stars 17 forks source link

DRCS-SIXElについて #12

Closed arakiken closed 6 years ago

arakiken commented 6 years ago

mlterm (http://mlterm.sf.net/) の開発をしております荒木と申します。 RLogin の豊富な機能については、いつも参考にさせていただいております。

今回、RLogin の DRCS Sixel 拡張を利用し、neovim の terminal 上で Sixel を利用で きるようにしようと考えています。 http://mlterm.sf.net/nvim-mlterm-drcssixel.png のようなイメージです。 これは、neovim の terminal が利用する libvterm を http://bitbucket.org/arakiken/mlterm/src/tip/libvterm/README のようにビルドした ものに置き換えた上で、DRCS-SIXEL に対応した mlterm 上で neovim の terminal を起 動し、Sixelを表示したものです。 neovim からターミナル (RLogin や mlterm) へは、 https://bitbucket.org/arakiken/mlterm/src/tip/libvterm/vterm.c?fileviewer=file-view-default#vterm.c-204 の xterm_get_picture_data() のように、DRCS-SIXEL 関係のシーケンスを出力し、Sixel を表示しています。 DRCS-SIXEL を使えば,neovim 本体は修正せず,libvterm を少し修正するだけで Sixel に対応できるため,非常に便利だと思います。

この中で、現在の RLogin の実装に基づく DRCS-SIXEL の仕様について、主に次の点を解 決したいと考えております。

  1. 画像をセル単位に分割しフォントグリフに割り当てる際に、画像サイズ÷セルサイズ の端数が切り捨てられているため、画像の端が表示できない。 (https://github.com/kmiya-culti/RLogin/blob/master/RLogin/TextRamProc.cpp#L3492 の (i + 1) Pcmh <= pGrapWnd->m_MaxX や (x + 1) Pcmw <= pGrapWnd->m_MaxY の辺り) => [対応案] 端数を切り上げて計算

  2. 一つの文字集合に収まらないサイズの画像の場合、収まらない部分の画像を表示でき ない。 (https://github.com/kmiya-culti/RLogin/blob/master/RLogin/TextRamProc.cpp#L3492 の (Pcn + n) < 0x80 の辺り) => [対応案] 収まらない部分を次の文字集合の0x20から順次割り当て

上記の対応案に基づき、mlterm では、最終的には http://mlterm.sf.net/DRCS-SIXEL-v2 のように実装したいと考えています。 (今のところは、mlterm は、1. はデフォルトでは RLogin と同じ挙動、2. は上記対応案 で実装)

上記 2. は対応しなくても小さい画像は問題なく、大きい画像も途中までは表示できるので、 RLogin と mlterm に処理に違いがあってもそれほど問題はないとは考えております。 一方、1. については、RLogin と mlterm で挙動が違うと、画像の折り返し位置が変わっ てくるため統一しておきたいのですが、画像の端が途切れないよう、できれば、 RLogin の実装を修正いただけないかと思っております。

なお、1. と同様、画像の折り返し位置に関わる問題として、RLogin が認識する Sixel 画像の幅が、img2sixel が出力する画像サイズ ("Pan;Pad;Ph;PvのPh;Pv) よりも1ピクセル 長くなっているように思われます。画像の折り返し位置を判断する上で少し不便なため、 可能であれば、修正を検討いただけるとありがたいです。 (セル幅8ピクセルの場合で http://mlterm.sf.net/rlogin-drcs-sixel-test.png となり、 img2sixel が 31 ピクセル幅で出力しても、RLogin は 32 ピクセル幅と判断しているよ うに思われます。)

また、以上の点について、別の回避策などあればご教示いただけると幸いです。

よろしくお願いいたします。

kmiya-culti commented 6 years ago

ご提案有り難うございます。

1,2どちらもフォント設定では、必要性を感じませんが、画像の表示で使用するには、欲しい機能かもしれませんね。簡単に変更しづらい部分ですが、検討してみようと思います。

画像サイズが違う問題ですがサンプル画像内で実行されているsedの置換でDECSIXELのDCSパラメータ部が残っているのが問題かもしれません。"sed s/\x1b[;0-9]q(.)/"

kmiya-culti commented 6 years ago

次期試作版に色々と実装してみました。

http://nanno.dip.jp/softlib/rlogin/2.23.1/

まず、グリフの切り上げで出来た余白をその時点での背景色で塗りつぶすようにしました。

文字集合のオーバーフローですが、94/96文字集合ともに範囲を0x20-0x7FとしてDscsのインクリメントを行うようにしました。

Dscsのインクリメントは”I I F”としてI=0x20-0x2F,I=0x20-0x2F,F=0x30-0x7Eの範囲で桁上がりするようにしてみました。0x20,0x7E->0x21,0x30

DECSIXELのDCSパラメータの問題は、もし存在する場合は、ちゃんと解釈するように変更しました。

<DRCS mapping rule version 2>のU+10XXZZでZZ=0x00-0x7F=94文字セット(0x00-0x7F)、0x80-0xFF=96文字セット(0x00-0x7F)と解釈するようにしました。

また、U+10XX20を空白として解釈していた部分を表示するように変更しました。

kmiya-culti commented 6 years ago

<DRCS mapping rule version 2>ですがU+10XXZZのXXも拡張したほうがいいかもしれません。

96(0x20-0x7F) * 79(0x30-0x7E)=7584でPcmw=8,Pcmh=16なら約1024x944pixの画像が最大画像サイズになるんじゃないでしょうか・・・

RLoginでの制限では、Dscsの各文字セットで254個なのでそれが先にオーバーしてしまいますが・・・

arakiken commented 6 years ago

 こんなすぐに対応いただき,本当にありがとうございます。  RLogin 上の nvim の :terminal で http://mlterm.sf.net/nvim-terminal-rlogin.png な感じで Sixel を表示できるようになりました。

画像サイズが違う問題ですがサンプル画像内で実行されているsedの置換でDECSIXELのDCSパラメータ部が残っているのが問題かもしれません。"sed s/\x1b[;0-9]q(.)/"

すみません,DECDLDに埋め込むSixelの仕様を勘違いしていました。確かにおっしゃるとおりでした。 ありがとうございます。

Dscsのインクリメントは”I I F”としてI=0x20-0x2F,I=0x20-0x2F,F=0x30-0x7Eの範囲で桁上がりするようにしてみました。0x20,0x7E->0x21,0x30

確かにそのほうが自然だと思います。ただ,UCSにマップしたときに,intermediate は SP 固定なため,intermediate をインクリメントすると UCS で扱えません。 このため,mlterm では 0x20,0x7E の次は 96文字集合の 0x20,0x30になるようにしています。 この辺りは少々挙動が違っても,コンソールアプリケーション側で,1つの画像で 文字集合が 0x7e をまたがないよう気を付ければいいかなと思っています。

<DRCS mapping rule version 2>ですがU+10XXZZのXXも拡張したほうがいいかもしれません。

確かにおっしゃるとおりです。drcsterm のオリジナルの仕様は,下に端末フィルタをかませた場合のことを考えて,conservertiveに設計されているようですので,そういった心配のない端末エミュレータでは,DECDLDで指定できる最大限の文字集合をマップできるようにしたほうがいいですね。 mlterm でも,XX に 0x30-0x3f もマップできるようにしました。 ありがとうございます。

kmiya-culti commented 6 years ago

mlterm では 0x20,0x7E の次は 96文字集合の 0x20,0x30になるようにしています。

あまり欲張って範囲を広げるより一定の制限でオーバーしたのが見て判るのがいいかもしれませんね。RLoginでも94文字セット0x20,0x7E->96文字セット0x20,0x30になるようにしてみます。

arakiken commented 6 years ago

RLoginでも94文字セット0x20,0x7E->96文字セット0x20,0x30となることを確認しました。 そこまで合わせていただき,本当にありがとうございました。