【问题标题】:Does ncurses support TrueColor?ncurses 是否支持真彩色?
【发布时间】:2020-08-27 16:16:49
【问题描述】:

我知道 ncurses 使用 init_pair 函数和朋友支持 16 位颜色。但是是否可以以全 RGB 颜色(又名 True Color)显示字符?

【问题讨论】:

标签: c ncurses


【解决方案1】:

ncurses 常见问题解答Why only 16 (or 256) colors? 详细介绍了此功能的历史,并指出正确的术语是直接颜色(因为它基于标准,而 true color 在其他地方被称为 direct color 的特例)。同样,xterm 常见问题解答Can I set a color by its number? 提供了有关 xterm 中此功能历史的相应详细信息。

ncurses 6.1(2018 年 1 月)引入了对 直接颜色 的支持,如 ncurses versus slang history 的回顾中所示。其中包括一个示例程序 picsmap,它使用 RGB 扩展名(记录在 user_caps(5) 中)。

由于 24 位 RGB 中的颜色数量大于原始(有符号!)16 位数字(参见术语 (5))支持的数字范围,因此有必要提供更大的数字。 ncurses 6.1 通过添加到不透明的 TERMINAL 结构并添加可以操作扩展数字的函数来对现有应用程序进行最小的更改。没有必要更改 ABI(自 2015 年 8 月以来目前为 6 个),因为文档中的功能都没有更改其二进制接口。

要在 ncurses 中使用 RGB 功能,必须有正确的终端描述。 xterm-direct 用于 xterm。此示例设置 RGB 标志并覆盖颜色特征(但保留前 8 种 ANSI 颜色,使其成为可行的混合):

xterm+direct|xterm with direct-color indexing,
        RGB,
        colors#0x1000000, pairs#0x10000, CO#8,
        initc@, op=\E[39;49m,
        setab=\E[%?%p1%{8}%<%t4%p1%d%e48\:2\:\:%p1%{65536}%/%d\:%p1
              %{256}%/%{255}%&%d\:%p1%{255}%&%d%;m,
        setaf=\E[%?%p1%{8}%<%t3%p1%d%e38\:2\:\:%p1%{65536}%/%d\:%p1
              %{256}%/%{255}%&%d\:%p1%{255}%&%d%;m,
        setb@, setf@,

其他终端有其相应的风格。由于该功能已记录在案,并附有示例,因此其他人可以根据需要自定义终端描述。

picsmap 是 ncurses 的测试程序之一,可作为 "ncurses-examples" 单独使用。教程是题外话; source-code 随时可用。

【讨论】:

    【解决方案2】:

    “真彩色”有点用词不当——它不存在。

    Ncurses 允许您重新定义标准 16 种颜色的值,但不支持任意位置的任意 RBG 颜色。幸运的是,如果您想自己做,许多终端确实支持 8 位 RGB(有时称为“真彩色”)——明确地说,这意味着 不使用 ncurses。

    序列是:

    • ESC[ 38;2;⟨r⟩;⟨g⟩;⟨b⟩ m:选择RGB前景色
    • ESC[ 48;2;⟨r⟩;⟨g⟩;⟨b⟩ m:选择RGB背景色

    (来自ANSI Escape Code

    这里,“ESC”只是字符“\x1b”,您将 r、g 和 b 替换为 0-255 之间的值。像这样的:

    printf("\x1b[38;2;%d,%d,%dm", r, g, b);
    

    这不适用于所有终端,但有很多支持它。

    为什么不用 Ncurses?

    为什么 Ncurses 不支持这个?事实证明,Ncurses 不仅只是一个用于设置文本样式并将其放置在终端不同位置的库,而且它还试图变得聪明,并尽量减少在开启时通过 stdout 传输的数据量——屏幕文字变化。 Ncurses 通过在内部保留自己的文本缓冲区并通过标准输出传输增量来做到这一点。

    如果您在 1993 年使用 14.4 kbit/s 调制解调器或慢速串行连接运行,这是一个非常不错的功能,当时 Ncurses 最初是制造的。但是,Ncurses 已在不支持其他颜色的情况下进行了权衡。

    【讨论】:

    • 据我所知,原始转义序列不能在 ncurses 会话中使用...对吗?
    • 我现在看到你的编辑了。哎呀,我想我得做一些颜色减少。
    • @KiedLlaentenn:这是正确的,我已经澄清了答案。我也试图解释为什么 Ncurses 不支持这一点。我会说——如果你只需要显示文本而不需要处理输入,没有 Ncurses 自己做也不会太难。 Ncurses 真正的hard部分是处理用户输入,在大量终端上工作,并计算增量以使界面更快,以应对慢速远程链接。
    • 这是很多有趣的错误信息。 ncurses FAQ 是一个更好的来源。
    • @ThomasDickey 你能详细说明一下吗?