Manual pages: mcmcdiffmceditmcview

root/lib/tty/color-internal.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. parse_hex_digit
  2. parse_256_or_true_color_name
  3. tty_color_get_name_by_index
  4. tty_color_get_index_by_name
  5. tty_attr_get_bits
  6. convert_256color_to_truecolor

   1 /*
   2    Internal stuff of color setup
   3 
   4    Copyright (C) 1994-2025
   5    Free Software Foundation, Inc.
   6 
   7    Written by:
   8    Andrew Borodin <aborodin@vmail.ru>, 2009
   9    Slava Zanko <slavazanko@gmail.com>, 2009, 2013
  10    Egmont Koblinger <egmont@gmail.com>, 2010
  11 
  12    This file is part of the Midnight Commander.
  13 
  14    The Midnight Commander is free software: you can redistribute it
  15    and/or modify it under the terms of the GNU General Public License as
  16    published by the Free Software Foundation, either version 3 of the License,
  17    or (at your option) any later version.
  18 
  19    The Midnight Commander is distributed in the hope that it will be useful,
  20    but WITHOUT ANY WARRANTY; without even the implied warranty of
  21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22    GNU General Public License for more details.
  23 
  24    You should have received a copy of the GNU General Public License
  25    along with this program.  If not, see <https://www.gnu.org/licenses/>.
  26  */
  27 
  28 /** \file color-internal.c
  29  *  \brief Source: Internal stuff of color setup
  30  */
  31 
  32 #include <config.h>
  33 
  34 #include <string.h>  // strcmp
  35 
  36 #include "color.h"  // colors and attributes
  37 #include "color-internal.h"
  38 
  39 /*** global variables ****************************************************************************/
  40 
  41 gboolean mc_tty_color_disable;
  42 
  43 /*** file scope macro definitions ****************************************************************/
  44 
  45 #define COLOR_INTENSITY 8
  46 
  47 /*** file scope type declarations ****************************************************************/
  48 
  49 typedef struct mc_tty_color_table_struct
  50 {
  51     const char *name;
  52     int value;
  53 } mc_tty_color_table_t;
  54 
  55 /*** forward declarations (file scope functions) *************************************************/
  56 
  57 /*** file scope variables ************************************************************************/
  58 
  59 static mc_tty_color_table_t const color_table[] = {
  60     { "black", COLOR_BLACK },
  61     { "gray", COLOR_BLACK + COLOR_INTENSITY },
  62     { "red", COLOR_RED },
  63     { "brightred", COLOR_RED + COLOR_INTENSITY },
  64     { "green", COLOR_GREEN },
  65     { "brightgreen", COLOR_GREEN + COLOR_INTENSITY },
  66     { "brown", COLOR_YELLOW },
  67     { "yellow", COLOR_YELLOW + COLOR_INTENSITY },
  68     { "blue", COLOR_BLUE },
  69     { "brightblue", COLOR_BLUE + COLOR_INTENSITY },
  70     { "magenta", COLOR_MAGENTA },
  71     { "brightmagenta", COLOR_MAGENTA + COLOR_INTENSITY },
  72     { "cyan", COLOR_CYAN },
  73     { "brightcyan", COLOR_CYAN + COLOR_INTENSITY },
  74     { "lightgray", COLOR_WHITE },
  75     { "white", COLOR_WHITE + COLOR_INTENSITY },
  76     { "default", -1 },  // default color of the terminal
  77     // End of list
  78     { NULL, 0 },
  79 };
  80 
  81 static mc_tty_color_table_t const attributes_table[] = {
  82     { "bold", A_BOLD },
  83 #ifdef A_ITALIC  // available since ncurses-5.9-20130831 / slang-pre2.3.0-107
  84     { "italic", A_ITALIC },
  85 #endif
  86     { "underline", A_UNDERLINE },
  87     { "reverse", A_REVERSE },
  88     { "blink", A_BLINK },
  89     // End of list
  90     { NULL, 0 },
  91 };
  92 
  93 /* --------------------------------------------------------------------------------------------- */
  94 /*** file scope functions ************************************************************************/
  95 /* --------------------------------------------------------------------------------------------- */
  96 
  97 static inline int
  98 parse_hex_digit (char c)
     /* [previous][next][first][last][top][bottom][index][help]  */
  99 {
 100     if (c >= '0' && c <= '9')
 101         return c - '0';
 102     c |= 0x20;
 103     if (c >= 'a' && c <= 'f')
 104         return c - 'a' + 10;
 105     return -1;
 106 }
 107 
 108 /* --------------------------------------------------------------------------------------------- */
 109 
 110 static int
 111 parse_256_or_true_color_name (const char *color_name)
     /* [previous][next][first][last][top][bottom][index][help]  */
 112 {
 113     int i;
 114     char dummy;
 115 
 116     if (sscanf (color_name, "color%d%c", &i, &dummy) == 1 && i >= 0 && i < 256)
 117     {
 118         return i;
 119     }
 120     if (sscanf (color_name, "gray%d%c", &i, &dummy) == 1 && i >= 0 && i < 24)
 121     {
 122         return 232 + i;
 123     }
 124     if (strncmp (color_name, "rgb", 3) == 0             //
 125         && color_name[3] >= '0' && color_name[3] < '6'  //
 126         && color_name[4] >= '0' && color_name[4] < '6'  //
 127         && color_name[5] >= '0' && color_name[5] < '6'  //
 128         && color_name[6] == '\0')
 129     {
 130         return 16 + 36 * (color_name[3] - '0') + 6 * (color_name[4] - '0') + (color_name[5] - '0');
 131     }
 132     if (color_name[0] == '#')
 133     {
 134         int len;
 135 
 136         color_name++;
 137         len = (int) strlen (color_name);
 138         if (len == 3 || len == 6)
 139         {
 140             int h[6];
 141 
 142             for (i = 0; i < len; i++)
 143             {
 144                 h[i] = parse_hex_digit (color_name[i]);
 145                 if (h[i] == -1)
 146                     return -1;
 147             }
 148 
 149             if (i == 3)
 150                 i = (h[0] << 20) | (h[0] << 16) | (h[1] << 12) | (h[1] << 8) | (h[2] << 4) | h[2];
 151             else
 152                 i = (h[0] << 20) | (h[1] << 16) | (h[2] << 12) | (h[3] << 8) | (h[4] << 4) | h[5];
 153             return FLAG_TRUECOLOR | i;
 154         }
 155     }
 156 
 157     return -1;
 158 }
 159 
 160 /* --------------------------------------------------------------------------------------------- */
 161 /*** public functions ****************************************************************************/
 162 /* --------------------------------------------------------------------------------------------- */
 163 
 164 const char *
 165 tty_color_get_name_by_index (int idx)
     /* [previous][next][first][last][top][bottom][index][help]  */
 166 {
 167     int i;
 168 
 169     // Find the real English name of the first 16 colors,
 170     // as well as the A_* special values.
 171     for (i = 0; color_table[i].name != NULL; i++)
 172         if (idx == color_table[i].value)
 173             return color_table[i].name;
 174 
 175     // Create and return the strings in "colorNNN" or "#rrggbb" format.
 176     if ((idx >= 16 && idx < 256) || (idx & FLAG_TRUECOLOR) != 0)
 177     {
 178         char name[9];
 179 
 180         if (idx < 256)
 181             g_snprintf (name, sizeof (name), "color%d", idx);
 182         else
 183             g_snprintf (name, sizeof (name), "#%06X", (unsigned int) idx & 0xFFFFFF);
 184         return g_intern_string (name);
 185     }
 186     return "default";
 187 }
 188 
 189 /* --------------------------------------------------------------------------------------------- */
 190 
 191 int
 192 tty_color_get_index_by_name (const char *color_name)
     /* [previous][next][first][last][top][bottom][index][help]  */
 193 {
 194     if (color_name != NULL)
 195     {
 196         size_t i;
 197 
 198         for (i = 0; color_table[i].name != NULL; i++)
 199             if (strcmp (color_name, color_table[i].name) == 0)
 200                 return color_table[i].value;
 201         return parse_256_or_true_color_name (color_name);
 202     }
 203     return -1;
 204 }
 205 
 206 /* --------------------------------------------------------------------------------------------- */
 207 
 208 int
 209 tty_attr_get_bits (const char *attrs)
     /* [previous][next][first][last][top][bottom][index][help]  */
 210 {
 211     int attr_bits = 0;
 212 
 213     if (attrs != NULL)
 214     {
 215         gchar **attr_list;
 216         int i;
 217 
 218         attr_list = g_strsplit (attrs, "+", -1);
 219 
 220         for (i = 0; attr_list[i] != NULL; i++)
 221         {
 222             int j;
 223 
 224             for (j = 0; attributes_table[j].name != NULL; j++)
 225             {
 226                 if (strcmp (attr_list[i], attributes_table[j].name) == 0)
 227                 {
 228                     attr_bits |= attributes_table[j].value;
 229                     break;
 230                 }
 231             }
 232         }
 233         g_strfreev (attr_list);
 234     }
 235     return attr_bits;
 236 }
 237 
 238 /* --------------------------------------------------------------------------------------------- */
 239 
 240 int
 241 convert_256color_to_truecolor (int color)
     /* [previous][next][first][last][top][bottom][index][help]  */
 242 {
 243     int r, g, b;
 244 
 245     // Invalid color
 246     if (color > 255)
 247         return 0;
 248 
 249     if (color >= 232)  // Gray scale
 250         r = g = b = (color - 231) * 10 + 8;
 251     else if (color >= 16)  // 6x6x6 color cube
 252     {
 253         color -= 16;
 254 
 255         r = (color / (6 * 6) % 6);
 256         r = r > 0 ? r * 40 + 55 : 0;
 257 
 258         g = (color / 6 % 6);
 259         g = g > 0 ? g * 40 + 55 : 0;
 260 
 261         b = (color % 6);
 262         b = b > 0 ? b * 40 + 55 : 0;
 263     }
 264     else  // We don't convert basic 16 colors as they are terminal-dependent and user-configurable
 265         return color;
 266 
 267     color = FLAG_TRUECOLOR | (r << 16) | (g << 8) | b;
 268 
 269     return color;
 270 }
 271 
 272 /* --------------------------------------------------------------------------------------------- */

/* [previous][next][first][last][top][bottom][index][help]  */