How Terminals display color?
Do not miss this exclusive book on Binary Tree Problems. Get it now for free.
NB: I will use the term console and terminal synonymously though there are differences between the two.
Terminals no longer fit the description - 'a dull screen with white text on a black background'.
Perhaps you have noticed some terminal commands returning colored text.
The image above is how the htop program presents the system metrics. It looks elegant and beautiful, isnt it?
History
Video terminal manufacturers added vendor specific escape sequences to perfom operations such as styling, cursor positioning. However this bred a problem of inconsistency.
As a workaround to the inconsistency, libraries suchas termcap and utitlities ie tput were developed to create a uniform API that console programs could use to incoperate color into their functionality.
Besides that, ANSI made a control code character set ie ANSI X3.64. And one of the first video terminals to have supported ANSI escape codes at the time is the VT100. Presently ANSI X3.64 might seem obscure because it merged with ECMA-48 to have ISO 6429 and after then, ANSI withdrew its standard in favor of the International Statndard - ISO 6429.
How terminals display color
Terminals display color using escape sequences (ANSI escape codes for our case).If an escape character(\033) is receded by a byte in the range 0x40-0x5F, then the interpretation of the escape sequence is delegated to the C1 control code.
The C1 control code set defines a Control Sequence Introducer(CSI) that starts most of the sequences. ie ESC [ or Ox9B.
There are various control sequences (a series of charactrers that change the state of the computer rather than being printed as regular bytes) that diverge from the CSI sequence but we shall focus on Select Graphic Rendition (SGR) CSI sequence since its the one responsible for styling and coloring of characters. SGR has a format of: ESC [ n m
Where n represents a series of parameters and m is the terminating character.
SGR defines parameters that are used to set various display attributes and several attributes can be set in the same sequence by separating parameters with a semi colon (;)
An excerpt of the parameters that you can set in the SGR. You can find the full table from this Wikipedia Page.
Try it out
#!/bin/bash
BOLD_RED='\033[1;31;47m'
NO_COLOR='\033[0m'
echo -e "I ${BOLD_RED}love${NO_COLOR} Linux"
When you run that bash script you will have a red bolded love word with a white background.
NB: Running bash scripts is beyond the scope of this article.
The SGR setting of the BOLD_RED is receded by a NO_COLOR reset SGR which implies that the following text afer it will be displayed with the terminal's current setting.
Try out the following variations
- \033[31;47;4;9m
- \x303[32;47;4;3m
- \033[41;4;3m
3bit vs 8 bit vs 24 bit colors
Originally terminals only supported 8 colors (3 bit colors): Black(30), Red(31), Green(32), Yellow(33), Blue(34), Magenta(35), Cyan(36), White(37). Few terminals even implemented the 1 SGR parameter and those that did, used brighter versions of the latter 8 colors and thus this made a total of 16 colors.
Currently, most terminal emulators support the 256 color set and 24 bit colors.
Setting 8 bit colors
- \033[38;5;n m (set foregroung color with 256 color set)
- \033[48;5;n m (set background color with 256 color set)
Where n is the number that corresponds to the color in the 256 color lookup table.
Setting 24 bit colors
- \033[38;2;r;g;b m (set foreground 24 bit color)
- \033[48;2;r;g;b m (set background 24 bit color)
Where r, g, b is the amount of red, green, and blue respectively.
Try it out
#!/bin/bash
DARK_GREEN='\033[38;5;100m'
NO_COLOR='\033[0m'
echo -e "I ${DARK_GREEN}love${NO_COLOR} Linux"
When you run the above bash script, you will have result below.
Try out with the following variations
- \033[38;5;100;4m
- \033[38;5;200;9m
- \033[38;5;220;3m
Thank you for reading this article at OpenGenus.
Sign up for FREE 3 months of Amazon Music. YOU MUST NOT MISS.