Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Truecolors (direct RGB colors) support #48

Closed
XVilka opened this issue Feb 16, 2018 · 12 comments
Closed

Truecolors (direct RGB colors) support #48

XVilka opened this issue Feb 16, 2018 · 12 comments
Labels
design Issues regarding Terminal.Gui design (bugs, guidelines, debates, etc...)

Comments

@XVilka
Copy link

XVilka commented Feb 16, 2018

Terminal Colors

There exists common confusion about terminal colors. This is what we have right now:

  • Plain ASCII
  • ANSI escape codes: 16 color codes with bold/italic and background
  • 256 color palette: 216 colors + 16 ANSI + 24 gray (colors are 24-bit)
  • 24-bit true color: "888" colors (aka 16 milion)
printf "\x1b[${bg};2;${red};${green};${blue}m\n"

The 256-color palette is configured at start and is a 666-cube of colors,
each of them defined as a 24-bit (888 rgb) color.

This means that current support can only display 256 different colors in the
terminal while "true color" means that you can display 16 million different
colors at the same time.

Truecolor escape codes do not use a color palette. They just specify the
color itself.

This is a good test case:

printf "\x1b[38;2;255;100;0mTRUECOLOR\x1b[0m\n"
awk 'BEGIN{
    s="/\\/\\/\\/\\/\\"; s=s s s s s s s s;
    for (colnum = 0; colnum<77; colnum++) {
        r = 255-(colnum*255/76);
        g = (colnum*510/76);
        b = (colnum*255/76);
        if (g>255) g = 510-g;
        printf "\033[48;2;%d;%d;%dm", r,g,b;
        printf "\033[38;2;%d;%d;%dm", 255-r,255-g,255-b;
        printf "%s\033[0m", substr(s,colnum+1,1);
    }
    printf "\n";
}'

Keep in mind that it is possible to use both ';' and ':' as Control Sequence
Introducer delimiters.

According to Wikipedia[1], this behavior is only supported by xterm and konsole.

[1] https://en.wikipedia.org/wiki/ANSI_color

Since
ncurses-6.0-20180121,
terminfo began to support the 24-bit True Color capability under the name of
"RGB". You need to use the "setaf" and "setab" commands to set the foreground
and background respectively.

True Color Detection

There will be no reliable way to detect the "RGB" flag until the new release of
terminfo/ncurses. S-Lang author added a check for $COLORTERM containing either
"truecolor" or "24bit" (case sensitive). In addition,
VTE,
Konsole and
iTerm2 set this variable to
"truecolor". It has been in VTE for a while and but is relatively new, being
still git-only in Konsole and iTerm2).

This is obviously not a reliable method, and is not forwarded via sudo, SSH etc.
However, whenever it errs, it errs on the safe side. It does not advertise
support when it is actually unsupported. App developers can freely choose to
check for this same variable, or introduce their own method (e.g. an option in
their config file). They should use whichever method best matches the overall
design of their app. Checking $COLORTERM is recommended though since it will
lead to a more seamless desktop experience where only one variable needs to be
set. This would be system-wide so that the user would not need to set it
separately for each app.

Querying The Terminal

A more reliable method in an interactive program which can read terminal
responses, and one that is transparent to things like sudo, SSH, etc.. is to
simply try setting a truecolor value and then query the terminal to ask what
color it currently has. If the response replies the same color that was set
then it indicates truecolor is supported.

$ (echo -e '\e[48:2:1:2:3m\eP$qm\e\\' ; xxd)

^[P1$r48:2:1:2:3m^[\
00000000: 1b50 3124 7234 383a 323a 313a 323a 336d  .P1$r48:2:1:2:3m

Here we ask to set the background color to RGB(1,2,3) - an unlikely default
choice - and request the value that we just set. The response comes back that
the request was understood (1), and that the color is indeed 48:2:1:2:3.
This tells us also that the terminal supports the colon delimiter. If instead,
the terminal did not support truecolor we might see a response like

^[P1$r40m^[\
00000000: 1b50 3124 7234 306d 1b5c 0a              .P1$r40m.\.

This terminal replied the color is 40 - it has not accepted our request to
set 48:2:1:2:3.

^[P0$r^[\
00000000: 1b50 3024 721b 5c0a                      .P0$r.\.

This terminal did not even understand the DECRQSS request - its response was
0$r. We do not learn if it managed to set the color, but since it doesn't
understand how to reply to our request it is unlikely to support truecolor
either.

Terminals + True Color

Now Supporting True Color

There are a bunch of libvte-based terminals for GTK2, so they are listed in the
another section.

Also, while this one is not a terminal, but a terminal replayer, it is
still worth mentioning:

Improper Support for True Color

Terminals that parse ANSI color sequences, but approximate them to 256 palette

Note about color differences:
a) RGB axes are not orthogonal, so you cannot use
sqrt(R^2+G^2+B^2) formula
b) for color differences there is more correct (but
much more complex)
CIEDE2000 formula
(which may easily blow up performance if used blindly) [2].

[2] neovim/neovim#793 (comment)

Terminal multiplexers

NOT Supporting True Color

Console Programs + True Color

Console Programs Supporting True Color

Console Programs Not Supporting True Color

See the repository https://github.com/termstandard/colors

Or the gist and discussion here: https://gist.github.com/XVilka/8346728

@migueldeicaza
Copy link
Collaborator

Thank you for all this information! This is an amazing source of information, so happy to have it!

Will put something together

@migueldeicaza
Copy link
Collaborator

While I have not yet added TrueColor support to gui.cs, I did use this issue to add TrueColor support to my terminal emulator:

https://github.com/migueldeicaza/SwiftTerm

It should also come soon to XtermSharp:

https://github.com/migueldeicaza/XtermSharp

@AnReZa
Copy link

AnReZa commented Nov 25, 2020

Is there already a way to use more than the default 16 colors? I already tried to add https://github.com/silkfire/Pastel, but that didn't help.

@jmperricone
Copy link
Contributor

jmperricone commented Apr 30, 2021

I was testing on windows with colors.

Now WindowsDriver use writeconsoleoutput.
It only supports 16 colors and underline through attributes (that's why I could add underline without escape sequence).

Microsoft docs:

Our preferred modern solution focuses on virtual terminal sequences for maximum compatibility in cross-platform scenarios.

The preferred solution is to use writeconsole with virtual-terminal-sequences.

Add support FullColor (24bit) for Windows #103 has done this too.

Just for testing I set a random color on every change of Attribute. Psycho alert!!

color.

@BDisp
Copy link
Collaborator

BDisp commented Apr 30, 2021

Fantastic. I like this very much. Thanks.

@tig
Copy link
Collaborator

tig commented May 2, 2021

Does anyone know the status of truecolor support in Windows Terminal?

I'm so happy to see yo working on this @jmperricone !!!

@jmperricone
Copy link
Contributor

that test was with cmd. It works on windows terminal too.

@jmperricone
Copy link
Contributor

I mean, windows terminal with cmd if that was what you were asking.

@BDisp
Copy link
Collaborator

BDisp commented May 6, 2021

Just kidding. With the CursesDriver you don't need to use a random color. With the current bug he already does that :-)

@AnReZa
Copy link

AnReZa commented May 7, 2021

@jmperricone Does that already work with Windows? I tried to modify the current Windows driver, which works, but the refresh rate is far from being optimal and I'm also not a big fan of how I added there features into the current Windows driver.

@BDisp
Copy link
Collaborator

BDisp commented May 7, 2021

Does that already work with Windows?

I didn't tried yet. But it is supposed to work also on Unix, because there are ncurses rgb functions.

@tig
Copy link
Collaborator

tig commented Aug 9, 2023

Closing this as TrueColor is now partially implemented (as of closing #666).

WindowsDriver now supports TrueColor.

These are the new/remaining tracking issues:

#2797
#2798
#2799

@tig tig closed this as completed Aug 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
design Issues regarding Terminal.Gui design (bugs, guidelines, debates, etc...)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants