Color Text, Part II

From last week’s Lesson, I showed how ANSI codes are used to set color text in terminal output. It’s time to go nuts showing the possibilities.

I should write, “go loopy” instead of “go nuts,” as the sample code in this Lesson involves plenty of loops. The goal is to output a spectrum of color values, eight foreground and eight background.

The foreground colors range from 30 through 37. Background colors range from 40 through 47. Rather than explain what each value represents, why not just look at the output? First the foreground codes:

2022_04_09-Lesson-a.c

#include <stdio.h>

int main()
{
    int c;
    const char *colors[] = {
        "BLACK", "RED", "GREEN", "YELLOW",
        "BLUE", "MAGENTA", "CYAN", "WHITE"
    };

    for( c=0 ; c<8; c++ )
    {
        printf("%10s: \x1b[3%cm%s\x1b[m\n",
                colors,
                c+'0',
                colors
              );
    }

    return(0);
}

A const char array colors[] contains the text for the color names corresponding to codes zero through seven. These are output in the for loop at Line 11.

The printf() statement at Line 13 outputs the color text name first in standard terminal colors. (My terminal’s standard colors are orange on black.) Next, the ANSI escape sequence is cobbled together. The value c+'0' sets the ASCII character value for the color code. This value is inserted into the ANSI escape sequence to generate the proper foreground color. Also stuffed into the printf() format string is the “normal” ASNI escape sequence, \x1b[m, which disables the color attribute after the text is output. Figure 1 shows the code’s sample output.

Figure 1. Color text output on my terminal, which uses an orange text foreground and black background.

The first line of output in Figure 1 shows black text on a black background, which makes the text appear invisible though it’s still output. It’s important to properly coordinate foreground and background colors, not only to keep things visible but to ensure that the color pairing doesn’t nauseate the user.

To assist you in choosing the best colors, the following code outputs the entire 64 possible foreground and background color combinations.

2022_04_09-Lesson-b.c

#include <stdio.h>

int main()
{
    int f,b;


    for( f=0 ; f<8; f++ )
    {
        for( b=0; b<8; b++ )
        {
            printf("\x1b[4%c;3%cm %02d:%02d ",
                    f+'0',b+'0',
                    f,b
                  );
        }
        printf("\x1b[m\n");
    }

    return(0);
}

The nested for loops use variables f for the foreground color values and b for the background color values. The printf() statement at Line 12 assembles the proper ASNI escape sequence, setting both values in the sequence, separated by a semicolon. The code pair values are also output.

The printf() statement at Line 17 resets text attributes, ensuring that any “bleed” is removed between lines. Figure 2 shows the sample output on my terminal screen.

Color output grid

Figure 1. The full color grid, foreground and background color combinations.

In Figure 2, the first value in a pair represents the foreground color, which are shown as columns. The second value represents the background, which appear in rows. The diagonal from 00:00 through 07:07 appears invisible as the foreground and background colors are identical.

Other ASNI code values can be mixed with the color values used in this Lesson. In fact, the full slate of colors increases to 16-by-16 when you add the “intensity” value. This ASNI escape sequence is \x1b[1m, with code ‘1’ indicating bold or “intense” text. The bold attribute may not work on all terminals.

For the full list of ASNI codes, refer to this page on Wikipedia. The codes relevant to this post are found in the section titled “SGR (Select Graphic Rendition) parameters.”

Leave a Reply