Ticket #45483

色パレット 1-7, 9-15 の入れ替え処理のソースにコメントを追加

Open Date: 2022-08-27 20:56 Last Update: 2022-09-10 01:46

Reporter:
Owner:
Type:
Status:
Closed
Component:
MileStone:
Priority:
5 - Medium
Severity:
5 - Medium
Resolution:
Fixed
File:
None
Vote
Score: 0
No votes
0.0% (0/0)
0.0% (0/0)

Details

情報源 ttssh2-devel 810, ttssh2-devel 817

処理の理由を書いておかないと分からなくなってしまうのでソースに書いておきたい。

Ticket History (3/18 Histories)

2022-08-27 20:56 Updated by: nmaya
  • New Ticket "色パレット 1-7, 9-15 の入れ替え処理のソースにコメントを追加" created
2022-08-27 21:58 Updated by: nmaya
Comment

該当すると思われる処理

Tera Term 2.3
void DispSetupDC(TCharAttr Attr, BOOL Reverse)

  else { // full color
	if ((Attr2 & Attr2Fore) != 0)
	{
	  if ((Attr & AttrBold) != 0)
		i = 0;
	  else
		i = 8;
	  j = Attr2 & Attr2ForeMask;
	  if (j==0)
		j = 8 - i + j;
	  else
		j = i + j;
	  TextColor = ANSIColor[j];
	}
	else if ((Attr & AttrBlink) != 0)
	  TextColor = ts.VTBlinkColor[0];
	else if ((Attr & AttrBold) != 0)
	  TextColor = ts.VTBoldColor[0];          
	else
	  TextColor = ts.VTColor[0];

	if ((Attr2 & Attr2Back) != 0)
	{
	  if ((Attr & AttrBlink) != 0)
		i = 0;
	  else
		i = 8;
	  j = (Attr2 & Attr2BackMask) >> SftAttrBack;
	  if (j==0)
		j = 8 - i + j;
	  else
		j = i + j;
	  BackColor = ANSIColor[j];
	}
	else if ((Attr & AttrBlink) != 0)
	  BackColor = ts.VTBlinkColor[1];
	else if ((Attr & AttrBold) != 0)
	  BackColor = ts.VTBoldColor[1];          
	else
	  BackColor = ts.VTColor[1];
  }

https://osdn.net/cvs/view/ttssh2/teraterm/source/teraterm/vtdisp.c?hideattic=0&r1=1.24&r2=1.25

https://osdn.net/cvs/view/ttssh2/teraterm/source/teraterm/vtdisp.c?hideattic=0&r1=1.26&r2=1.27

https://osdn.net/projects/ttssh2/svn/view?view=revision&root=ttssh2&revision=10192

いま
void DispSetupDC(TCharAttr Attr, BOOL Reverse)

	if (Attr2Flag & Attr2Fore) {
		if ((ts.ColorFlag & CF_FULLCOLOR) == 0) {
			// 8色モード
			TextColor = ANSIColor[Attr.Fore];
		}
		else {
			// 16/256色
			if (Attr.Fore < 8 && (ts.ColorFlag & CF_PCBOLD16)) {
				if (((Attr.Attr & AttrBold) != 0) == (Attr.Fore != 0)) {
					TextColor = ANSIColor[Attr.Fore];
				}
				else {
					TextColor = ANSIColor[Attr.Fore ^ 8];
				}
			}
			else if (Attr.Fore < 16 && (Attr.Fore & 7) != 0) {
				TextColor = ANSIColor[Attr.Fore ^ 8];
			}
			else {
				TextColor = ANSIColor[Attr.Fore];
			}
		}
	}

	if (Attr2Flag & Attr2Back) {
		if ((ts.ColorFlag & CF_FULLCOLOR) == 0) {
			// 8色モード
			BackColor = ANSIColor[Attr.Back];
		}
		else {
			// 16/256色
			if (Attr.Back < 8 && (ts.ColorFlag & CF_PCBOLD16)) {
				if (((Attr.Attr & AttrBlink) != 0) == (Attr.Back != 0)) {
					BackColor = ANSIColor[Attr.Back];
				}
				else {
					BackColor = ANSIColor[Attr.Back ^ 8];
				}
			}
			else if (Attr.Back < 16 && (Attr.Back & 7) != 0) {
				BackColor = ANSIColor[Attr.Back ^ 8];
			}
			else {
				BackColor = ANSIColor[Attr.Back];
			}
		}
	}
(Edited, 2022-08-27 23:19 Updated by: nmaya)
2022-08-27 23:14 Updated by: nmaya
Comment

現在の処理を言語化

  • 16/256 色のとき
    • 0-7 で PC-Style が有効
      • Boldで1-7 or Boldではなく0
        • そのまま
      • その他(Boldではなく1-7 or Boldで0)
        • +8 する(XOR)
    • 9-15
      • -8 する(XOR)
    • その他(8, 16以上, aixtermの0-7, xterm256の0-7)
      • そのまま

わからないこと

  • なぜ Bold が条件に入るのか
    • 文字色のときには「Boldのときに」だが、背景色の時は「Blinkのときに」となる
  • 0-7 で PC-Style が有効のときだけ処理が違う(aixterm や xterm256 が有効なだけでは入れ替えられない)のはなぜか
    • aixterm と xterm256 でもこちらの処理をしたら間違いなのか
(Edited, 2022-08-28 00:38 Updated by: nmaya)
2022-08-28 02:42 Updated by: zmatsuo
Comment

r10198, r10199 に修正を入れました。

テスト中に設定(TERATERM.INI)保存時に反転属性の色が保存されていないのを見つけたので修正しました (r10197)。

文字色属性Blod(太字)のときに明るい色が表示される(r10199)ですが、 wikipedia によると、 SGR 1 は "Bold or increased intensity" になっています。

"increased intensity"なので、明るくなるのはokだと思うのですが、 "Bold or" とあるので、Boldにならないのが正解なのかもしれないです。

今のところ、Tera Term 4 と同じ、明るく+Boldとなっています。

r10198のログを書いていて、 ANSIColor[] の参照入れ替え処理を描画時に行うのではなく、 INIファイルからの読み込み/書き込み時に行う、256色をベースにするのが 良いのではないかと思いつきました。 いかがでしょう?

r10198, r10199 は 4-stable に反映させようと思います。

2022-08-28 11:23 Updated by: nmaya
Comment

"Bold or" とあるので、Boldにならないのが正解なのかもしれないです。

今のところ、Tera Term 4 と同じ、明るく+Boldとなっています。

Bold にするかどうかは Setup-Window-Enable bold font で制御できますので、このままでよいと思います。

通常は少し暗い色(8-15)の色が使われる。
Boldのときは文字を強調したいので、文字色に明るい色(1-7)が使われる。背景色は少し暗い色(8-15)のまま。
Blinkのときは背景を強調したいので、背景色に明るい色(1-7)が使われる。文字色は少し暗い色(8-15)のまま。

ということで理解しました。

r10199 により、Bold が文字色も背景色も明るくなりますが、Blink が文字色も背景色も Normal と同じになってしまうので、戻しました。

このようなワンライナーでテストしました。

色指定なし
echo -e "\033[0m0:Normal\033[0m"
echo -e "\033[1m1:Bold\033[0m"
echo -e "\033[4m4:Underline\033[0m"
echo -e "\033[5m5:Blink\033[0m"
echo -e "\033[7m7:Reverse\033[0m"

色指定あり
echo -e "\033[0m\033[36m\033[45m0:Normal 36:Fore Cyan 45:Back Magenta\033[39m\033[49m\033[0m"
echo -e "\033[1m\033[36m\033[45m1:Bold 36:Fore Cyan 42:Back Magenta\033[39m\033[49m\033[0m"
echo -e "\033[4m\033[36m\033[45m4:Underline 36:Fore Cyan 42:Back Magenta\033[39m\033[49m\033[0m"
echo -e "\033[5m\033[36m\033[45m5:Blink 36:Fore Cyan 42:Back Magenta\033[39m\033[49m\033[0m"
echo -e "\033[7m\033[36m\033[45m7:Reverse 36:Fore Cyan 42:Back Magenta\033[39m\033[49m\033[0m"

2022-08-28 11:52 Updated by: nmaya
Comment

CF_PCBOLD16 だけが特別に入れ替えない(Boldの文字が明るくなる・Blinkの背景が明るくなる)のですが、CF_AIXTERM16, CF_XTERM256 でも同じになるようにして問題ないでしょうか?

vtdisp.c のこのコミットから CF_PCBOLD16 を見て処理を分けていますが、同時にコミットされた tttypes.h で CF_XTERM256 まで定義されています。CF_PCBOLD16 だけにこの処理を入れた理由があるのかもしれないのですが、なんでしょうか?

2022-08-28 18:56 Updated by: doda
Comment

wikipedia によると

この部分では大きな問題はありませんがWikipediaは間違いも結構あるので、仕様等を調べる場合はWikipediaではなくECMA-48等の原典をあたるようにして下さい。

2022-08-28 18:57 Updated by: doda
Comment

ECMA-48ではカラーは8色が使えるようになっています。

これに対し、16色(以上)を使いたいという要望が出てきましたが、ECMA-48の仕様では色数を単純に拡張する事はできません。

そこで、

  • カラー属性とBold属性を組み合わせる事で色番号8-15を表す
  • 未使用であるSGR 90-97/100-107を色番号8-15にマップする
  • CCITT Rec. T.416用に予約されていたSGR 38/48を利用する

などの拡張方法が考え出されました。

Tera Termではこれらの拡張すべてに対応しており、それぞれ

  • 16色モード(PC形式) - CF_PCBOLD16
  • 16色モード(aixterm形式) - CF_AIXTERM16
  • 256色モード(xterm形式) - CF_XTERM256

と呼んでいます。

ただし、16色モード(PC形式)で背景色の拡張にBold属性を使ってしまうと文字色15&背景色1のような指定が出来なくなる為、Tera Termでは背景色の拡張にはBlink属性を使うという仕様になっています。

2022-08-28 19:23 Updated by: doda
Comment

CF_PCBOLD16 だけが特別に入れ替えない(Boldの文字が明るくなる・Blinkの背景が明るくなる)のですが、CF_AIXTERM16, CF_XTERM256 でも同じになるようにして問題ないでしょうか?

CF_PCBOLD16はこのBold/Blink属性との組み合わせで色番号8-15を表すという動作のフラグになっています。

CF_AIXTERM16/CF_XTERM256では別の方法で色番号8-15を扱えるので、上記の動作を行うかの条件には含めないでください。

CF_PCBOLD16 だけにこの処理を入れた理由があるのかもしれないのですが、なんでしょうか?

Tera Termでは元々16色モード(PC形式)のみに対応していました。この頃はこの動作をするかの設定を「フルカラー」と呼んでいました。 なので、フルカラーモードの時は常にBold/Blink属性で色番号8-15を使うようになっていました。

後に16色モード(aixterm形式), 256色モード(xterm形式)に対応した時、フルカラーという名称は判りづらいので16色モード(PC形式)に改名しました。 前述したようにCF_AIXTERM16, CF_XTERM256では別の方法で色番号8-15が指定出来る為、Bold/Blink属性と組み合わせる方法は必要ありません。 そこで、これらのモードとは独立にBold/Blink属性との組み合わせを有効にするかを設定出来るようにする為、CF_PCBOLD16のみで動作を決めるようになっています。

2022-08-28 22:23 Updated by: nmaya
Comment

解説ありがとうございます。

カラー属性とBold属性を組み合わせる事で色番号8-15を表す

「文字色属性(31-37)とBold属性を組み合わせることで文字色の色番号8-15を表せる。背景色属性(41-47)とBlink属性を組み合わせることで背景色の色番号8-15を表せる。」と理解しましたが、あっているでしょうか?

Bold(強調)/Blink(点滅)属性が文字/背景色の属性の一部として使用され

マニュアルのこの説明は、2x2=4の組み合わせがあるように読めてしまったのと、ある属性が別の属性の一部になるとはどういうことか分からず、私が正しく読解できませんでした。

CF_AIXTERM16/CF_XTERM256では別の方法で色番号8-15を扱えるので、上記の動作を行うかの条件には含めないでください。

わかりました。

CF_PCBOLD16 の TextColor 出力は、こういう表にすると * の部分の動作結果が非対称に感じられます。Attr.Fore が 9-15 になることはないので考えなくてよい、ということになるでしょうか?

Attr.Fore\Bold false true
1-7 9-15 1-7
9-15 1-7 1-7*



ちなみにですが、

などの拡張方法が考え出され

Bold に関しては「PC-style mapping of bold colors」とのことで、もともとそう扱われるつもりで送ってくるアプリがあるように思えます。

Tera Termでは背景色の拡張にはBlink属性を使う

Blink 属性を背景色に使う(そのように送ってくる)アプリがある、ということでしょうか。それは Tera Term がこのように扱うようになる以前からでしょうか。Tera Term 以外でも同じように扱う端末エミュレータがあるのでしょうか。

2022-08-29 18:35 Updated by: nmaya
Comment

他の方式も有効なら Attr.Fore の 9-15 が来ることがあるので、CF_PCBOLD16 が有効で 9-15 が来てもそれは関係ない、という理解をしました。

現在の理解で r10208 のように修正しました。誤りがありましたらご指摘ください。

2022-08-30 04:33 Updated by: doda
Comment

「文字色属性(31-37)とBold属性を組み合わせることで文字色の色番号8-15を表せる。背景色属性(41-47)とBlink属性を組み合わせることで背景色の色番号8-15を表せる。」と理解しましたが、あっているでしょうか?

対象の属性は正確には30-37, 40-47です。それ以外の部分は合っています。

CF_PCBOLD16 の TextColor 出力は、こういう表にすると * の部分の動作結果が非対称に感じられます。

これは

  • 16色(以上)では色番号1-7と9-15を入れ替える (8色対応を後から16色対応に拡張した事に由来する動作)
  • Bold/Blinkとの組み合わせで色番号0-7を8-15として扱う (CF_PCBOLD16の動作)

を一つの処理で行おうとしている事によって判りづらくなっているのかもしれません。 後者の動作だけに注目すると、

指定色\Bold false true
0-7 0-7 8-15
8-15 8-15 8-15
16-255 16-255 16-255

となり、CF_PCBOLD16は「色番号0-7しか指定できない条件で色番号8-15を使う為の拡張」なので右上の部分だけで変換を行い、 それ以外にはまったく手を付けない機能だというのが判りやすいと思います。

この辺りは、処理を2段階に分けたり、提案が出ているように前者の処理を設定読み込み時に行うようにすると、 コード上でも判りやすくなるかもしれません。

Bold に関しては「PC-style mapping of bold colors」とのことで、もともとそう扱われるつもりで送ってくるアプリがあるように思えます。

これは「そういうつもりで送るアプリが有るから端末が対応する」のではなく、 「そういう動作をする端末がある(例: VT525)があるから、アプリがそれを期待して送る」と考える方がいいでしょう。

Blink 属性を背景色に使う(そのように送ってくる)アプリがある、ということでしょうか。それは Tera Term がこのように扱うようになる以前からでしょうか。

こちらも、まずは「Boldだけで行うと文字/背景色で使えない組合わせができるから、Tera TermではBlinkを使うように拡張した」というのが先で、 アプリは「そのような動作をする端末があるから使う」と考える方がいいでしょう。

その上で実際に使うアプリが有るかですが、TERMINFOで利用している端末エントリのsetabを

setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t5;4%p1%{8}%-%d%e48;5;%p1%d%;m,
のようにしてやればTERMINFOに従って出力するアプリ(ncurses利用アプリ等)ならば背景色にblink属性を併用するようになります。

Tera Term 以外でも同じように扱う端末エミュレータがあるのでしょうか。

他では見た記憶が無いです。

2022-08-31 07:27 Updated by: nmaya
Comment

それ以外の部分は合っています。

ありがとうございます。r10217 のように修正しました。

この辺りは、処理を2段階に分けたり、提案が出ているように前者の処理を設定読み込み時に行うようにすると、 コード上でも判りやすくなるかもしれません。

INI の読み込みや UI から変更されたタイミングで描画時参照用の入れ替え済み配列を作ってしまうと、描画処理が早くなるかもしれませんね。

もしかしたら、if で判定して +8, -8 するのではなく ^ 8 を使っているのが、条件分岐を減らして高速に動作させるためかもしれない、と読んでいて思いました。

アプリは「そのような動作をする端末があるから使う」と考える方がいいでしょう。

他では見た記憶が無いです。

なるほど、わかりました。

2022-09-01 08:58 Updated by: nmaya
Comment

r10221 で 4-stable にマージしました。

2022-09-04 01:38 Updated by: doda
Comment

ANSIColor[] の参照入れ替え処理を描画時に行うのではなく、 INIファイルからの読み込み/書き込み時に行う、256色をベースにするのが 良いのではないかと思いつきました。 いかがでしょう?

読み込みの時点で入れ換えた方が、

  • コード的に単純になるので、分かりやすくなる
  • 普段使う事が多い16色(以上)モードでの処理が減る
  • 入れ換えるという仕様がバグの温床になっていたのが解消される (#45558, #45559)

辺りから良い影響は多いと思います。

ただ、入れ換えてしまうとANSIカラー設定を参照/操作するTTXで互換性の問題が発生します。

これに関しては別チケットにして検討した方がいいかも。

2022-09-04 12:27 Updated by: nmaya
Comment

現状はこうでしょうか。

TERATERM.INI <-> ANSIColor[] -(変換1/2)-> 端末表示
                   ^   ^
                   |   +----------------> カラーパレット変更/カラーパレット設定取得シーケンス
                   +--------------------> 設定UI
変換1: 1-7/9-15
変換2: PC-Style bold/blink

改善案はこういう感じですか?よいと思います。

TERATERM.INI <-(変換1)-> ANSIColor[] -(変換2)-> 端末表示
                           ^   ^
                           |   +----------------> カラーパレット変更/カラーパレット設定取得シーケンス
                           +--------------------> 設定UI
変換1: 1-7/9-15
変換2: PC-Style bold/blink

このへんは制限事項になりますが、仕方ないですね。

  • TERATERM.INI の ANSIColor のインデックス番号が色番号と一致しない ... 現状でもそう
    • UI のほうは改善されるのでよしとする
  • UI から8色ときの色を設定をしようとしたとき色番号と一致しなくなる(9-15を変更せねばならない)
    • マニュアルで対応?
2022-09-10 01:46 Updated by: nmaya
Comment

このチケットはソース内のコメントのことなので、ここまででクローズします。

ANSIColor[] の入れ替え処理の変更については別チケット(#45625)に移行します。

2022-09-10 01:46 Updated by: nmaya
  • Status Update from Open to Closed

Attachment File List

No attachments

Edit

You are not logged in. I you are not logged in, your comment will be treated as an anonymous post. » Login