NeoMutt  2024-11-14-34-g5aaf0d
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
ansi.c File Reference

ANSI Colours. More...

#include "config.h"
#include <stdbool.h>
#include "mutt/lib.h"
#include "gui/lib.h"
#include "ansi.h"
#include "attr.h"
#include "color.h"
#include "curses2.h"
#include "parse_ansi.h"
#include "simple2.h"
+ Include dependency graph for ansi.c:

Go to the source code of this file.

Functions

color_t color_xterm256_to_24bit (const color_t color)
 Convert a xterm color to its RGB value.
 
static void ansi_color_list_add (struct AttrColorList *acl, struct AnsiColor *ansi)
 Add an Ansi colour to the list.
 
int ansi_color_parse (const char *str, struct AnsiColor *ansi, struct AttrColorList *acl, bool dry_run)
 Parse a string of ANSI escape sequence.
 

Detailed Description

ANSI Colours.

Authors
  • Richard Russon

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file ansi.c.

Function Documentation

◆ color_xterm256_to_24bit()

color_t color_xterm256_to_24bit ( const color_t  color)

Convert a xterm color to its RGB value.

Parameters
[in]colorxterm color number to be converted
Return values
numThe color's RGB value as number with value 0xRRGGBB

There are 256 xterm colors numbered 0 to 255.

Caller contract: color must be between 0 and 255.

Xterm Color Codes

Basic and Bright Colors

  • 0-7 correspond to the 8 terminal colours
  • 8-15 are the bright variants of 0-7
0 #000000 1 #800000 2 #008000 3 #808000 4 #000080 5 #800080 6 #008080 7 #c0c0c0
8 #808080 9 #ff0000 10 #00ff00 11 #ffff00 12 #0000ff 13 #ff00ff 14 #00ffff 15 #ffffff

Color palette

16 #000000 17 #00005f 18 #000087 19 #0000af 20 #0000d7 21 #0000ff
22 #005f00 23 #005f5f 24 #005f87 25 #005faf 26 #005fd7 27 #005fff
28 #008700 29 #00875f 30 #008787 31 #0087af 32 #0087d7 33 #0087ff
34 #00af00 35 #00af5f 36 #00af87 37 #00afaf 38 #00afd7 39 #00afff
40 #00d700 41 #00d75f 42 #00d787 43 #00d7af 44 #00d7d7 45 #00d7ff
46 #00ff00 47 #00ff5f 48 #00ff87 49 #00ffaf 50 #00ffd7 51 #00ffff
52 #5f0000 53 #5f005f 54 #5f0087 55 #5f00af 56 #5f00d7 57 #5f00ff
58 #5f5f00 59 #5f5f5f 60 #5f5f87 61 #5f5faf 62 #5f5fd7 63 #5f5fff
64 #5f8700 65 #5f875f 66 #5f8787 67 #5f87af 68 #5f87d7 69 #5f87ff
70 #5faf00 71 #5faf5f 72 #5faf87 73 #5fafaf 74 #5fafd7 75 #5fafff
76 #5fd700 77 #5fd75f 78 #5fd787 79 #5fd7af 80 #5fd7d7 81 #5fd7ff
82 #5fff00 83 #5fff5f 84 #5fff87 85 #5fffaf 86 #5fffd7 87 #5fffff
88 #870000 89 #87005f 90 #870087 91 #8700af 92 #8700d7 93 #8700ff
94 #875f00 95 #875f5f 96 #875f87 97 #875faf 98 #875fd7 99 #875fff
100 #878700 101 #87875f 102 #878787 103 #8787af 104 #8787d7 105 #8787ff
106 #87af00 107 #87af5f 108 #87af87 109 #87afaf 110 #87afd7 111 #87afff
112 #87d700 113 #87d75f 114 #87d787 115 #87d7af 116 #87d7d7 117 #87d7ff
118 #87ff00 119 #87ff5f 120 #87ff87 121 #87ffaf 122 #87ffd7 123 #87ffff
124 #af0000 125 #af005f 126 #af0087 127 #af00af 128 #af00d7 129 #af00ff
130 #af5f00 131 #af5f5f 132 #af5f87 133 #af5faf 134 #af5fd7 135 #af5fff
136 #af8700 137 #af875f 138 #af8787 139 #af87af 140 #af87d7 141 #af87ff
142 #afaf00 143 #afaf5f 144 #afaf87 145 #afafaf 146 #afafd7 147 #afafff
148 #afd700 149 #afd75f 150 #afd787 151 #afd7af 152 #afd7d7 153 #afd7ff
154 #afff00 155 #afff5f 156 #afff87 157 #afffaf 158 #afffd7 159 #afffff
160 #d70000 161 #d7005f 162 #d70087 163 #d700af 164 #d700d7 165 #d700ff
166 #d75f00 167 #d75f5f 168 #d75f87 169 #d75faf 170 #d75fd7 171 #d75fff
172 #d78700 173 #d7875f 174 #d78787 175 #d787af 176 #d787d7 177 #d787ff
178 #d7af00 179 #d7af5f 180 #d7af87 181 #d7afaf 182 #d7afd7 183 #d7afff
184 #d7d700 185 #d7d75f 186 #d7d787 187 #d7d7af 188 #d7d7d7 189 #d7d7ff
190 #d7ff00 191 #d7ff5f 192 #d7ff87 193 #d7ffaf 194 #d7ffd7 195 #d7ffff
196 #ff0000 197 #ff005f 198 #ff0087 199 #ff00af 200 #ff00d7 201 #ff00ff
202 #ff5f00 203 #ff5f5f 204 #ff5f87 205 #ff5faf 206 #ff5fd7 207 #ff5fff
208 #ff8700 209 #ff875f 210 #ff8787 211 #ff87af 212 #ff87d7 213 #ff87ff
214 #ffaf00 215 #ffaf5f 216 #ffaf87 217 #ffafaf 218 #ffafd7 219 #ffafff
220 #ffd700 221 #ffd75f 222 #ffd787 223 #ffd7af 224 #ffd7d7 225 #ffd7ff
226 #ffff00 227 #ffff5f 228 #ffff87 229 #ffffaf 230 #ffffd7 231 #ffffff

Grey Scale Ramp

232 #080808 233 #121212 234 #1c1c1c 235 #262626 236 #303030 237 #3a3a3a 238 #444444 239 #4e4e4e
240 #585858 241 #626262 242 #6c6c6c 243 #767676 244 #808080 245 #8a8a8a 246 #949494 247 #9e9e9e
248 #a8a8a8 249 #b2b2b2 250 #bcbcbc 251 #c6c6c6 252 #d0d0d0 253 #dadada 254 #e4e4e4 255 #eeeeee

Definition at line 320 of file attr.c.

321{
322 static const color_t basic[] = {
323 0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080,
324 0x008080, 0xc0c0c0, 0x808080, 0xff0000, 0x00ff00, 0xffff00,
325 0x0000ff, 0xff00ff, 0x00ffff, 0xffffff,
326 };
327
328 ASSERT(color < 256);
329
330 if (color < 0)
331 return color;
332
333 const bool c_color_directcolor = cs_subset_bool(NeoMutt->sub, "color_directcolor");
334 if (!c_color_directcolor)
335 {
336 return color;
337 }
338
339 if (color < 16)
340 {
341 color_debug(LL_DEBUG5, "Converted color 0-15: %d\n", color);
342 /* The first 16 colours are the "usual" terminal colours */
343 return basic[color];
344 }
345
346 if (color < 232)
347 {
348 /* The Color palette is divided in 6x6x6 colours, i.e. each R, G, B channel
349 * has six values:
350 *
351 * value: 1 2 3 4 5 6
352 * color: 0x00 0x5f 0x87 0xaf 0xd7 0xff
353 *
354 * The steps between the values is 0x28 = 40, the EXCEPT for the first one
355 * where it is 0x5f = 95.
356 *
357 * If we express the xterm color number minus 16 to base 6, i.e.
358 *
359 * color - 16 = (vr * 36) + (vg * 6) + (vb * 1)
360 *
361 * with vr, vg, vb integers between 0 and 5, then vr, vg, vb is the channel
362 * value for red, green, and blue, respectively.
363 */
364
365 color_t normalised_color = color - 16;
366 color_t vr = (normalised_color % 216) / 36; /* 216 = 6*6*6 */
367 color_t vg = (normalised_color % 36) / 6;
368 color_t vb = (normalised_color % 6) / 1;
369
370 /* First step is wider than the other ones, so add the difference if needed */
371 color_t r = (vr * 0x28) + ((vr > 0) ? (0x5f - 0x28) : 0);
372 color_t g = (vg * 0x28) + ((vg > 0) ? (0x5f - 0x28) : 0);
373 color_t b = (vb * 0x28) + ((vb > 0) ? (0x5f - 0x28) : 0);
374
375 color_t rgb = (r << 16) + (g << 8) + (b << 0);
376 color_debug(LL_DEBUG5, "Converted xterm color %d to RGB #%x:\n", color, rgb);
377 return rgb;
378 }
379
380 /* Grey scale starts at 0x08 and adds 0xa = 10 in very step ending in 0xee.
381 * There are a total of 6*4 = 24 grey colors in total. */
382 color_t steps = color - 232;
383 color_t grey = (steps * 0x0a) + 0x08;
384 color_t rgb = (grey << 16) + (grey << 8) + (grey << 0);
385 color_debug(LL_DEBUG5, "Converted xterm color %d to RGB #%x:\n", color, rgb);
386 return rgb;
387}
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:47
int32_t color_t
Type for 24-bit colour value.
Definition: curses2.h:31
static int color_debug(enum LogLevel level, const char *format,...)
Definition: debug.h:52
@ LL_DEBUG5
Log at debug level 5.
Definition: logging2.h:47
#define ASSERT(COND)
Definition: signal2.h:58
Container for Accounts, Notifications.
Definition: neomutt.h:42
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:46
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ansi_color_list_add()

static void ansi_color_list_add ( struct AttrColorList *  acl,
struct AnsiColor ansi 
)
static

Add an Ansi colour to the list.

Parameters
aclList of unique colours
ansiColour to add

Keep track of all the unique ANSI colours in a list.

Definition at line 49 of file ansi.c.

50{
51 if (!acl || !ansi)
52 return;
53
54 if ((ansi->fg.color == COLOR_DEFAULT) && (ansi->bg.color == COLOR_DEFAULT))
55 {
56 switch (ansi->attrs)
57 {
58 case A_NORMAL:
59 return;
60 case A_BOLD:
62 return;
63#ifdef A_ITALIC_DEFINED
64 case A_ITALIC:
66 return;
67#endif
68 case A_UNDERLINE:
70 return;
71 }
72 }
73
74 color_t fg = ansi->fg.color;
75 color_t bg = ansi->bg.color;
76
77#ifdef NEOMUTT_DIRECT_COLORS
78 if ((ansi->fg.type == CT_SIMPLE) || (ansi->fg.type == CT_PALETTE))
80 else if (fg < 8)
81 fg = 8;
82 if ((ansi->bg.type == CT_SIMPLE) || (ansi->bg.type == CT_PALETTE))
84 else if (bg < 8)
85 bg = 8;
86#endif
87
88 struct AttrColor *ac = attr_color_list_find(acl, fg, bg, ansi->attrs);
89 if (ac)
90 {
91 ansi->attr_color = ac;
92 return;
93 }
94
95 ac = attr_color_new();
96 ac->attrs = ansi->attrs;
97 ac->fg = ansi->fg;
98 ac->bg = ansi->bg;
99
100 struct CursesColor *cc = curses_color_new(fg, bg);
101 ac->curses_color = cc;
102 ansi->attr_color = ac;
103
104 TAILQ_INSERT_TAIL(acl, ac, entries);
105}
color_t color_xterm256_to_24bit(const color_t color)
Convert a xterm color to its RGB value.
Definition: attr.c:320
struct AttrColor * attr_color_list_find(struct AttrColorList *acl, color_t fg, color_t bg, int attrs)
Find an AttrColor in a list.
Definition: attr.c:139
struct AttrColor * attr_color_new(void)
Create a new AttrColor.
Definition: attr.c:90
@ CT_SIMPLE
Simple colour, e.g. "Red".
Definition: attr.h:36
@ CT_PALETTE
Palette colour, e.g. "color207".
Definition: attr.h:37
struct AttrColor * simple_color_get(enum ColorId cid)
Get the colour of an object by its ID.
Definition: simple.c:88
#define COLOR_DEFAULT
Definition: color.h:100
@ MT_COLOR_BOLD
Bold text.
Definition: color.h:45
@ MT_COLOR_ITALIC
Italic text.
Definition: color.h:55
@ MT_COLOR_UNDERLINE
Underlined text.
Definition: color.h:80
struct CursesColor * curses_color_new(color_t fg, color_t bg)
Create a new CursesColor.
Definition: curses.c:151
#define A_ITALIC
Definition: mutt_curses.h:49
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:809
int attrs
Text attributes, e.g. A_BOLD.
Definition: ansi.h:38
const struct AttrColor * attr_color
Curses colour of text.
Definition: ansi.h:39
struct ColorElement bg
Background colour.
Definition: ansi.h:37
struct ColorElement fg
Foreground colour.
Definition: ansi.h:36
A curses colour and its attributes.
Definition: attr.h:66
struct ColorElement bg
Background colour.
Definition: attr.h:68
struct ColorElement fg
Foreground colour.
Definition: attr.h:67
int attrs
Text attributes, e.g. A_BOLD.
Definition: attr.h:69
struct CursesColor * curses_color
Underlying Curses colour.
Definition: attr.h:70
enum ColorType type
Type of Colour.
Definition: attr.h:58
color_t color
Colour.
Definition: attr.h:57
Colour in the ncurses palette.
Definition: curses2.h:41
color_t fg
Foreground colour.
Definition: curses2.h:42
color_t bg
Background colour.
Definition: curses2.h:43
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ansi_color_parse()

int ansi_color_parse ( const char *  str,
struct AnsiColor ansi,
struct AttrColorList *  acl,
bool  dry_run 
)

Parse a string of ANSI escape sequence.

Parameters
strString to parse
ansiAnsiColor for the result
aclList to store the unique colours
dry_runIf true, parse but don't save the sequence
Return values
numTotal length of the escape sequences

Parse (multiple) ANSI sequence(s) into ansi. If the colour hasn't been seen before, store the it in acl.

Definition at line 118 of file ansi.c.

120{
121 int seq_len = 0;
122 int total_len = 0;
123
124 while ((seq_len = ansi_color_parse_single(str + total_len, ansi, dry_run)) != 0)
125 {
126 total_len += seq_len;
127 }
128
129 ansi_color_list_add(acl, ansi);
130
131 return total_len;
132}
static void ansi_color_list_add(struct AttrColorList *acl, struct AnsiColor *ansi)
Add an Ansi colour to the list.
Definition: ansi.c:49
int ansi_color_parse_single(const char *buf, struct AnsiColor *ansi, bool dry_run)
Parse a single ANSI escape sequence.
Definition: parse_ansi.c:109
+ Here is the call graph for this function:
+ Here is the caller graph for this function: