LCOV - code coverage report
Current view: top level - src/rendering - color.cc (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 129 129 100.0 %
Date: 2022-06-15 20:16:21 Functions: 20 26 76.9 %
Branches: 1691 1697 99.6 %

           Branch data     Line data    Source code
       1                 :            : #ifdef RUN_TESTS
       2                 :            : # include <gtest/gtest.h>
       3                 :            : #endif
       4                 :            : /** @file rendering/color.cc
       5                 :            :  * @brief Defines conversions between different color formats and parsing colors defined in strings.
       6                 :            :  */
       7                 :            : 
       8                 :            : #include <array>
       9                 :            : #include <string>
      10                 :            : #include <cstdlib>
      11                 :            : #include <cstring>
      12                 :            : #include <utility>
      13                 :            : #include <vector>
      14                 :            : #include <algorithm>
      15                 :            : 
      16                 :            : #include "ctype.hh"
      17                 :            : #include "color.hh"
      18                 :            : 
      19                 :         17 : unsigned ParseColorName(std::u32string_view s)
      20                 :            : {
      21                 :         17 :     return ParseColorName(ToUTF8(s));
      22                 :            : }
      23                 :            : 
      24                 :            : /*
      25                 :            : A simple version of the colors array can be generated with:
      26                 :            : 
      27                 :            : grep -v '!' /usr/share/X11/rgb.txt \
      28                 :            : | perl -pe "s/(\d+)\s+(\d+)\s+(\d+)\s+(.*)/ {\"\\4\", Repack({\\1,\\2,\\3}) },/" \
      29                 :            : | tr A-Z a-z
      30                 :            : 
      31                 :            : The current version is auto-generated code.
      32                 :            : It uses fast hashing that is guaranteed to return correct value
      33                 :            : for all known colors, but undefined value for other strings.
      34                 :            : The hashing is optimized such that the range of different hashes is as short as possible.
      35                 :            : */
      36                 :            : 
      37                 :            : static constexpr unsigned mod = 3832u, mul = 380u;
      38                 :            : // Note: Not using std::string_view, because clang falsely reports it's not a built-in-constant when it is.
      39                 :        771 : static constexpr unsigned hash(const char* s, std::size_t length)
      40                 :            : {
      41                 :        771 :     constexpr std::uint_least64_t lett = 0x927B029ACC77F; // maps a..z into 0..3 
      42                 :        771 :     constexpr std::uint_least64_t map = 0x928CFB571EE207; // maps everything into hex digits
      43                 :        771 :     std::uint_least64_t result = 0x7923C1BDEEE579CE;
      44         [ +  + ]:       7474 :     for(std::size_t p=0; p<length; ++p)
      45                 :            :     {
      46                 :       6703 :         unsigned z = s[p], t;
      47                 :            : 
      48                 :       6703 :         std::uint_least64_t space = -std::uint_least64_t(z != ' ');
      49                 :            :         /* code_lett gets same result for both uppercase and lowercase. */
      50                 :       6703 :         unsigned ch = (2*z - 2*'a');
      51                 :       6703 :         unsigned code_lett = (4*lett) >> (ch&63) /* 0..3 */;
      52                 :       6703 :         unsigned code_dig  = (4*z + 4*4 - 4*'0') /* 4..13 */;
      53                 :            : 
      54                 :            :         // z = (z&64) ? code_lett : code_dig; // Branchful version commented out
      55                 :            :         // Branchless version of the same:
      56                 :            :         // Bit 6 is set for lowercase and uppercase, but not digits
      57                 :            :         // Bit 5 is set for lowercase and digits, but not uppercase
      58                 :            :         // Bit 4 is set for digits and half of letters
      59                 :            :     #ifdef __clang__
      60                 :            :         code_lett &= 3*4;
      61                 :            :         // Clang optimizes this into a cmov
      62                 :            :         t = (z & 64) ? code_lett : code_dig;
      63                 :            :     #else
      64                 :            :         // For GCC, this produces better code, still not very good though.
      65                 :       6703 :         t = (z >> 6) & 1;          // Test bit 6 to detect alphabet
      66                 :       6703 :         t = (code_lett & t*3*4)    // True: want 3*4, false: want 0
      67                 :       6703 :           + (code_dig  & ~-t);     // True: want 0,   false: want 15*4
      68                 :            :     #endif
      69                 :            : 
      70                 :            :         // If the symbol was space, don't update result (skip spaces)
      71                 :            :         // Clang generates branchless cmov from this.
      72                 :            :         // GCC is not quite that smart...
      73                 :       6703 :         result = ((result*mul + ((map >> (t&63)) & 15)) & space) + (result & ~space);
      74                 :            :     }
      75                 :        771 :     return result % mod;
      76                 :            : }
      77                 :            : 
      78                 :            : /* Autogenerated code. This macro defines all the colors and their hashes. */
      79                 :            : #define docolors(o) \
      80                 :            :         o(    1, 0xFFB5C5, "pink1")\
      81                 :            :         o(    5, 0xCD919E, "pink3")\
      82                 :            :         o(    7, 0xEEA9B8, "pink2")\
      83                 :            :         o(   11, 0x8B636C, "pink4")\
      84                 :            :         o(   30, 0x6495ED, "cornflower blue", "CornflowerBlue")\
      85                 :            :         o(   42, 0xFFFAFA, "snow")\
      86                 :            :         o(   65, 0xFFFAFA, "snow1")\
      87                 :            :         o(   66, 0xB03060, "maroon")\
      88                 :            :         o(   69, 0xCDC9C9, "snow3")\
      89                 :            :         o(   70, 0xFFE4B5, "moccasin")\
      90                 :            :         o(   71, 0xEEE9E9, "snow2")\
      91                 :            :         o(   72, 0x000080, "navy")\
      92                 :            :         o(   75, 0x8B8989, "snow4")\
      93                 :            :         o(   78, 0x7B68EE, "medium slate blue", "MediumSlateBlue")\
      94                 :            :         o(   80, 0x2F4F4F, "dark slate gray", "DarkSlateGray", "dark slate grey", "DarkSlateGrey")\
      95                 :            :         o(   94, 0xFDF5E6, "old lace", "OldLace")\
      96                 :            :         o(  104, 0xEEE8AA, "pale goldenrod", "PaleGoldenrod")\
      97                 :            :         o(  120, 0xF5FFFA, "mint cream", "MintCream")\
      98                 :            :         o(  134, 0x0000CD, "medium blue", "MediumBlue")\
      99                 :            :         o(  138, 0xEE82EE, "violet")\
     100                 :            :         o(  176, 0xC71585, "medium violet red", "MediumVioletRed")\
     101                 :            :         o(  189, 0xFFF68F, "khaki1")\
     102                 :            :         o(  193, 0xCDC673, "khaki3")\
     103                 :            :         o(  195, 0xEEE685, "khaki2")\
     104                 :            :         o(  199, 0x8B864E, "khaki4")\
     105                 :            :         o(  209, 0xFF8C69, "salmon1")\
     106                 :            :         o(  213, 0xCD7054, "salmon3")\
     107                 :            :         o(  215, 0xEE8262, "salmon2")\
     108                 :            :         o(  219, 0x8B4C39, "salmon4")\
     109                 :            :         o(  221, 0x696969, "gray41", "grey41")\
     110                 :            :         o(  222, 0x7A7A7A, "gray48", "grey48")\
     111                 :            :         o(  225, 0x6E6E6E, "gray43", "grey43")\
     112                 :            :         o(  227, 0x6B6B6B, "gray42", "grey42")\
     113                 :            :         o(  228, 0x787878, "gray47", "grey47")\
     114                 :            :         o(  229, 0x7D7D7D, "gray49", "grey49")\
     115                 :            :         o(  231, 0x707070, "gray44", "grey44")\
     116                 :            :         o(  232, 0x757575, "gray46", "grey46")\
     117                 :            :         o(  234, 0x666666, "gray40", "grey40")\
     118                 :            :         o(  235, 0x737373, "gray45", "grey45")\
     119                 :            :         o(  240, 0xD70751, "DebianRed")\
     120                 :            :         o(  253, 0x1C1C1C, "gray11", "grey11")\
     121                 :            :         o(  254, 0x2E2E2E, "gray18", "grey18")\
     122                 :            :         o(  257, 0x212121, "gray13", "grey13")\
     123                 :            :         o(  259, 0x1F1F1F, "gray12", "grey12")\
     124                 :            :         o(  260, 0x2B2B2B, "gray17", "grey17")\
     125                 :            :         o(  261, 0x303030, "gray19", "grey19")\
     126                 :            :         o(  263, 0x242424, "gray14", "grey14")\
     127                 :            :         o(  264, 0x292929, "gray16", "grey16")\
     128                 :            :         o(  266, 0x1A1A1A, "gray10", "grey10")\
     129                 :            :         o(  267, 0x262626, "gray15", "grey15")\
     130                 :            :         o(  274, 0x8B4513, "saddle brown", "SaddleBrown")\
     131                 :            :         o(  329, 0xFFEFDB, "AntiqueWhite1")\
     132                 :            :         o(  333, 0xCDC0B0, "AntiqueWhite3")\
     133                 :            :         o(  335, 0xEEDFCC, "AntiqueWhite2")\
     134                 :            :         o(  338, 0x2E8B57, "sea green", "SeaGreen")\
     135                 :            :         o(  339, 0x8B8378, "AntiqueWhite4")\
     136                 :            :         o(  353, 0xFFE4C4, "bisque1")\
     137                 :            :         o(  357, 0xCDB79E, "bisque3")\
     138                 :            :         o(  359, 0xEED5B7, "bisque2")\
     139                 :            :         o(  361, 0x7FFF00, "chartreuse1")\
     140                 :            :         o(  362, 0xA52A2A, "brown")\
     141                 :            :         o(  363, 0x8B7D6B, "bisque4")\
     142                 :            :         o(  365, 0x66CD00, "chartreuse3")\
     143                 :            :         o(  367, 0x76EE00, "chartreuse2")\
     144                 :            :         o(  369, 0xFF0000, "red1")\
     145                 :            :         o(  371, 0x458B00, "chartreuse4")\
     146                 :            :         o(  373, 0xCD0000, "red3")\
     147                 :            :         o(  375, 0xEE0000, "red2")\
     148                 :            :         o(  377, 0xFF83FA, "orchid1")\
     149                 :            :         o(  379, 0x8B0000, "red4")\
     150                 :            :         o(  381, 0xCD69C9, "orchid3")\
     151                 :            :         o(  383, 0xEE7AE9, "orchid2")\
     152                 :            :         o(  387, 0x8B4789, "orchid4")\
     153                 :            :         o(  392, 0xFFD700, "gold")\
     154                 :            :         o(  393, 0x63B8FF, "SteelBlue1")\
     155                 :            :         o(  397, 0x4F94CD, "SteelBlue3")\
     156                 :            :         o(  399, 0x5CACEE, "SteelBlue2")\
     157                 :            :         o(  403, 0x36648B, "SteelBlue4")\
     158                 :            :         o(  426, 0xF08080, "light coral", "LightCoral")\
     159                 :            :         o(  430, 0x00008B, "dark blue", "DarkBlue")\
     160                 :            :         o(  433, 0xFFFACD, "LemonChiffon1")\
     161                 :            :         o(  437, 0xCDC9A5, "LemonChiffon3")\
     162                 :            :         o(  439, 0xEEE9BF, "LemonChiffon2")\
     163                 :            :         o(  443, 0x8B8970, "LemonChiffon4")\
     164                 :            :         o(  490, 0xD2B48C, "tan")\
     165                 :            :         o(  505, 0x00BFFF, "DeepSkyBlue1")\
     166                 :            :         o(  509, 0x009ACD, "DeepSkyBlue3")\
     167                 :            :         o(  510, 0xA020F0, "purple")\
     168                 :            :         o(  511, 0x00B2EE, "DeepSkyBlue2")\
     169                 :            :         o(  515, 0x00688B, "DeepSkyBlue4")\
     170                 :            :         o(  526, 0x40E0D0, "turquoise")\
     171                 :            :         o(  529, 0x836FFF, "SlateBlue1")\
     172                 :            :         o(  533, 0x6959CD, "SlateBlue3")\
     173                 :            :         o(  535, 0x7A67EE, "SlateBlue2")\
     174                 :            :         o(  539, 0x473C8B, "SlateBlue4")\
     175                 :            :         o(  564, 0xDA70D6, "orchid")\
     176                 :            :         o(  569, 0xFFD39B, "burlywood1")\
     177                 :            :         o(  573, 0xCDAA7D, "burlywood3")\
     178                 :            :         o(  574, 0x6A5ACD, "slate blue", "SlateBlue")\
     179                 :            :         o(  575, 0xEEC591, "burlywood2")\
     180                 :            :         o(  579, 0x8B7355, "burlywood4")\
     181                 :            :         o(  601, 0x9C9C9C, "gray61", "grey61")\
     182                 :            :         o(  602, 0xADADAD, "gray68", "grey68")\
     183                 :            :         o(  605, 0xA1A1A1, "gray63", "grey63")\
     184                 :            :         o(  606, 0xF0F8FF, "alice blue", "AliceBlue")\
     185                 :            :         o(  607, 0x9E9E9E, "gray62", "grey62")\
     186                 :            :         o(  608, 0xABABAB, "gray67", "grey67")\
     187                 :            :         o(  609, 0xB0B0B0, "gray69", "grey69")\
     188                 :            :         o(  611, 0xA3A3A3, "gray64", "grey64")\
     189                 :            :         o(  612, 0xA8A8A8, "gray66", "grey66")\
     190                 :            :         o(  614, 0x999999, "gray60", "grey60")\
     191                 :            :         o(  615, 0xA6A6A6, "gray65", "grey65")\
     192                 :            :         o(  617, 0xFF7256, "coral1")\
     193                 :            :         o(  621, 0xCD5B45, "coral3")\
     194                 :            :         o(  623, 0xEE6A50, "coral2")\
     195                 :            :         o(  627, 0x8B3E2F, "coral4")\
     196                 :            :         o(  633, 0xCFCFCF, "gray81", "grey81")\
     197                 :            :         o(  634, 0xE0E0E0, "gray88", "grey88")\
     198                 :            :         o(  637, 0xD4D4D4, "gray83", "grey83")\
     199                 :            :         o(  639, 0xD1D1D1, "gray82", "grey82")\
     200                 :            :         o(  640, 0xDEDEDE, "gray87", "grey87")\
     201                 :            :         o(  641, 0xE3E3E3, "gray89", "grey89")\
     202                 :            :         o(  643, 0xD6D6D6, "gray84", "grey84")\
     203                 :            :         o(  644, 0xDBDBDB, "gray86", "grey86")\
     204                 :            :         o(  646, 0xCCCCCC, "gray80", "grey80")\
     205                 :            :         o(  647, 0xD9D9D9, "gray85", "grey85")\
     206                 :            :         o(  672, 0xD02090, "violet red", "VioletRed")\
     207                 :            :         o(  689, 0xF0FFF0, "honeydew1")\
     208                 :            :         o(  693, 0xC1CDC1, "honeydew3")\
     209                 :            :         o(  695, 0xE0EEE0, "honeydew2")\
     210                 :            :         o(  697, 0xFFB90F, "DarkGoldenrod1")\
     211                 :            :         o(  699, 0x838B83, "honeydew4")\
     212                 :            :         o(  701, 0xCD950C, "DarkGoldenrod3")\
     213                 :            :         o(  703, 0xEEAD0E, "DarkGoldenrod2")\
     214                 :            :         o(  707, 0x8B6508, "DarkGoldenrod4")\
     215                 :            :         o(  722, 0x8A2BE2, "blue violet", "BlueViolet")\
     216                 :            :         o(  737, 0x1E90FF, "DodgerBlue1")\
     217                 :            :         o(  738, 0xFFB6C1, "light pink", "LightPink")\
     218                 :            :         o(  741, 0x1874CD, "DodgerBlue3")\
     219                 :            :         o(  743, 0x1C86EE, "DodgerBlue2")\
     220                 :            :         o(  747, 0x104E8B, "DodgerBlue4")\
     221                 :            :         o(  761, 0xFF7F24, "chocolate1")\
     222                 :            :         o(  765, 0xCD661D, "chocolate3")\
     223                 :            :         o(  767, 0xEE7621, "chocolate2")\
     224                 :            :         o(  769, 0xFF6EB4, "HotPink1")\
     225                 :            :         o(  771, 0x8B4513, "chocolate4")\
     226                 :            :         o(  773, 0xCD6090, "HotPink3")\
     227                 :            :         o(  775, 0xEE6AA7, "HotPink2")\
     228                 :            :         o(  779, 0x8B3A62, "HotPink4")\
     229                 :            :         o(  782, 0x0000FF, "blue")\
     230                 :            :         o(  810, 0xF0FFF0, "honeydew")\
     231                 :            :         o(  824, 0xB8860B, "dark goldenrod", "DarkGoldenrod")\
     232                 :            :         o(  830, 0x191970, "midnight blue", "MidnightBlue")\
     233                 :            :         o(  833, 0xFFA54F, "tan1")\
     234                 :            :         o(  837, 0xCD853F, "tan3")\
     235                 :            :         o(  839, 0xEE9A49, "tan2")\
     236                 :            :         o(  843, 0x8B5A2B, "tan4")\
     237                 :            :         o(  894, 0xA0522D, "sienna")\
     238                 :            :         o(  905, 0xFFFFE0, "LightYellow1")\
     239                 :            :         o(  909, 0xCDCDB4, "LightYellow3")\
     240                 :            :         o(  911, 0xEEEED1, "LightYellow2")\
     241                 :            :         o(  913, 0xBF3EFF, "DarkOrchid1")\
     242                 :            :         o(  915, 0x8B8B7A, "LightYellow4")\
     243                 :            :         o(  917, 0x9A32CD, "DarkOrchid3")\
     244                 :            :         o(  919, 0xB23AEE, "DarkOrchid2")\
     245                 :            :         o(  922, 0xFFF8DC, "cornsilk")\
     246                 :            :         o(  923, 0x68228B, "DarkOrchid4")\
     247                 :            :         o(  934, 0xB0E0E6, "powder blue", "PowderBlue")\
     248                 :            :         o(  937, 0xFF4040, "brown1")\
     249                 :            :         o(  938, 0xBC8F8F, "rosy brown", "RosyBrown")\
     250                 :            :         o(  941, 0xCD3333, "brown3")\
     251                 :            :         o(  943, 0xEE3B3B, "brown2")\
     252                 :            :         o(  946, 0x00FA9A, "medium spring green", "MediumSpringGreen")\
     253                 :            :         o(  947, 0x8B2323, "brown4")\
     254                 :            :         o(  970, 0xFF8C00, "dark orange", "DarkOrange")\
     255                 :            :         o(  990, 0x8470FF, "light slate blue", "LightSlateBlue")\
     256                 :            :         o( 1009, 0xC1FFC1, "DarkSeaGreen1")\
     257                 :            :         o( 1013, 0x9BCD9B, "DarkSeaGreen3")\
     258                 :            :         o( 1015, 0xB4EEB4, "DarkSeaGreen2")\
     259                 :            :         o( 1019, 0x698B69, "DarkSeaGreen4")\
     260                 :            :         o( 1025, 0xFFEC8B, "LightGoldenrod1")\
     261                 :            :         o( 1026, 0xE9967A, "dark salmon", "DarkSalmon")\
     262                 :            :         o( 1029, 0xCDBE70, "LightGoldenrod3")\
     263                 :            :         o( 1031, 0xEEDC82, "LightGoldenrod2")\
     264                 :            :         o( 1035, 0x8B814C, "LightGoldenrod4")\
     265                 :            :         o( 1086, 0xDCDCDC, "gainsboro")\
     266                 :            :         o( 1090, 0xFAFAD2, "light goldenrod yellow", "LightGoldenrodYellow")\
     267                 :            :         o( 1097, 0xFFF8DC, "cornsilk1")\
     268                 :            :         o( 1101, 0xCDC8B1, "cornsilk3")\
     269                 :            :         o( 1103, 0xEEE8CD, "cornsilk2")\
     270                 :            :         o( 1107, 0x8B8878, "cornsilk4")\
     271                 :            :         o( 1120, 0xDDA0DD, "plum")\
     272                 :            :         o( 1137, 0xFFDAB9, "PeachPuff1")\
     273                 :            :         o( 1141, 0xCDAF95, "PeachPuff3")\
     274                 :            :         o( 1143, 0xEECBAD, "PeachPuff2")\
     275                 :            :         o( 1147, 0x8B7765, "PeachPuff4")\
     276                 :            :         o( 1161, 0xE066FF, "MediumOrchid1")\
     277                 :            :         o( 1165, 0xB452CD, "MediumOrchid3")\
     278                 :            :         o( 1167, 0xD15FEE, "MediumOrchid2")\
     279                 :            :         o( 1171, 0x7A378B, "MediumOrchid4")\
     280                 :            :         o( 1216, 0x8B0000, "dark red", "DarkRed")\
     281                 :            :         o( 1222, 0xAFEEEE, "pale turquoise", "PaleTurquoise")\
     282                 :            :         o( 1258, 0xFFFFE0, "light yellow", "LightYellow")\
     283                 :            :         o( 1266, 0x9400D3, "dark violet", "DarkViolet")\
     284                 :            :         o( 1345, 0xFFDEAD, "NavajoWhite1")\
     285                 :            :         o( 1349, 0xCDB38B, "NavajoWhite3")\
     286                 :            :         o( 1351, 0xEECFA1, "NavajoWhite2")\
     287                 :            :         o( 1355, 0x8B795E, "NavajoWhite4")\
     288                 :            :         o( 1368, 0xDB7093, "pale violet red", "PaleVioletRed")\
     289                 :            :         o( 1375, 0xBDB76B, "dark khaki", "DarkKhaki")\
     290                 :            :         o( 1385, 0xFFFF00, "yellow1")\
     291                 :            :         o( 1386, 0xFFA07A, "light salmon", "LightSalmon")\
     292                 :            :         o( 1389, 0xCDCD00, "yellow3")\
     293                 :            :         o( 1391, 0xEEEE00, "yellow2")\
     294                 :            :         o( 1395, 0x8B8B00, "yellow4")\
     295                 :            :         o( 1409, 0xFF3030, "firebrick1")\
     296                 :            :         o( 1413, 0xCD2626, "firebrick3")\
     297                 :            :         o( 1415, 0xEE2C2C, "firebrick2")\
     298                 :            :         o( 1419, 0x8B1A1A, "firebrick4")\
     299                 :            :         o( 1449, 0x00FFFF, "cyan1")\
     300                 :            :         o( 1453, 0x00CDCD, "cyan3")\
     301                 :            :         o( 1455, 0x00EEEE, "cyan2")\
     302                 :            :         o( 1459, 0x008B8B, "cyan4")\
     303                 :            :         o( 1463, 0xE6E6FA, "lavender")\
     304                 :            :         o( 1464, 0xD3D3D3, "light grey", "LightGrey", "light gray", "LightGray")\
     305                 :            :         o( 1466, 0x00FF00, "green")\
     306                 :            :         o( 1478, 0xF8F8FF, "ghost white", "GhostWhite")\
     307                 :            :         o( 1482, 0x8FBC8F, "dark sea green", "DarkSeaGreen")\
     308                 :            :         o( 1494, 0xFFE4E1, "misty rose", "MistyRose")\
     309                 :            :         o( 1506, 0x3CB371, "medium sea green", "MediumSeaGreen")\
     310                 :            :         o( 1513, 0xFF3E96, "VioletRed1")\
     311                 :            :         o( 1514, 0xF4A460, "sandy brown", "SandyBrown")\
     312                 :            :         o( 1517, 0xCD3278, "VioletRed3")\
     313                 :            :         o( 1519, 0xEE3A8C, "VioletRed2")\
     314                 :            :         o( 1523, 0x8B2252, "VioletRed4")\
     315                 :            :         o( 1529, 0x0000FF, "blue1")\
     316                 :            :         o( 1530, 0x000000, "black")\
     317                 :            :         o( 1533, 0x0000CD, "blue3")\
     318                 :            :         o( 1535, 0x0000EE, "blue2")\
     319                 :            :         o( 1539, 0x00008B, "blue4")\
     320                 :            :         o( 1552, 0xFFDAB9, "peach puff", "PeachPuff")\
     321                 :            :         o( 1609, 0x4876FF, "RoyalBlue1")\
     322                 :            :         o( 1613, 0x3A5FCD, "RoyalBlue3")\
     323                 :            :         o( 1615, 0x436EEE, "RoyalBlue2")\
     324                 :            :         o( 1619, 0x27408B, "RoyalBlue4")\
     325                 :            :         o( 1630, 0xFAEBD7, "antique white", "AntiqueWhite")\
     326                 :            :         o( 1638, 0x87CEFA, "light sky blue", "LightSkyBlue")\
     327                 :            :         o( 1692, 0x9932CC, "dark orchid", "DarkOrchid")\
     328                 :            :         o( 1697, 0xFF1493, "DeepPink1")\
     329                 :            :         o( 1701, 0xCD1076, "DeepPink3")\
     330                 :            :         o( 1703, 0xEE1289, "DeepPink2")\
     331                 :            :         o( 1705, 0xFFE1FF, "thistle1")\
     332                 :            :         o( 1707, 0x8B0A50, "DeepPink4")\
     333                 :            :         o( 1709, 0xCDB5CD, "thistle3")\
     334                 :            :         o( 1711, 0xEED2EE, "thistle2")\
     335                 :            :         o( 1715, 0x8B7B8B, "thistle4")\
     336                 :            :         o( 1741, 0x828282, "gray51", "grey51")\
     337                 :            :         o( 1742, 0x949494, "gray58", "grey58")\
     338                 :            :         o( 1745, 0x878787, "gray53", "grey53")\
     339                 :            :         o( 1747, 0x858585, "gray52", "grey52")\
     340                 :            :         o( 1748, 0x919191, "gray57", "grey57")\
     341                 :            :         o( 1749, 0x969696, "gray59", "grey59")\
     342                 :            :         o( 1751, 0x8A8A8A, "gray54", "grey54")\
     343                 :            :         o( 1752, 0x8F8F8F, "gray56", "grey56")\
     344                 :            :         o( 1754, 0x7F7F7F, "gray50", "grey50")\
     345                 :            :         o( 1755, 0x8C8C8C, "gray55", "grey55")\
     346                 :            :         o( 1773, 0x4F4F4F, "gray31", "grey31")\
     347                 :            :         o( 1774, 0x616161, "gray38", "grey38")\
     348                 :            :         o( 1777, 0x545454, "gray33", "grey33")\
     349                 :            :         o( 1779, 0x525252, "gray32", "grey32")\
     350                 :            :         o( 1780, 0x5E5E5E, "gray37", "grey37")\
     351                 :            :         o( 1781, 0x636363, "gray39", "grey39")\
     352                 :            :         o( 1783, 0x575757, "gray34", "grey34")\
     353                 :            :         o( 1784, 0x5C5C5C, "gray36", "grey36")\
     354                 :            :         o( 1786, 0x4D4D4D, "gray30", "grey30")\
     355                 :            :         o( 1787, 0x595959, "gray35", "grey35")\
     356                 :            :         o( 1814, 0x4682B4, "steel blue", "SteelBlue")\
     357                 :            :         o( 1825, 0xFF4500, "OrangeRed1")\
     358                 :            :         o( 1826, 0xFF1493, "deep pink", "DeepPink")\
     359                 :            :         o( 1829, 0xCD3700, "OrangeRed3")\
     360                 :            :         o( 1831, 0xEE4000, "OrangeRed2")\
     361                 :            :         o( 1835, 0x8B2500, "OrangeRed4")\
     362                 :            :         o( 1841, 0xF0FFFF, "azure1")\
     363                 :            :         o( 1845, 0xC1CDCD, "azure3")\
     364                 :            :         o( 1847, 0xE0EEEE, "azure2")\
     365                 :            :         o( 1850, 0xFF6347, "tomato")\
     366                 :            :         o( 1851, 0x838B8B, "azure4")\
     367                 :            :         o( 1870, 0x48D1CC, "medium turquoise", "MediumTurquoise")\
     368                 :            :         o( 1881, 0xFFAEB9, "LightPink1")\
     369                 :            :         o( 1885, 0xCD8C95, "LightPink3")\
     370                 :            :         o( 1886, 0xD8BFD8, "thistle")\
     371                 :            :         o( 1887, 0xEEA2AD, "LightPink2")\
     372                 :            :         o( 1891, 0x8B5F65, "LightPink4")\
     373                 :            :         o( 1897, 0xFFF5EE, "seashell1")\
     374                 :            :         o( 1901, 0xCDC5BF, "seashell3")\
     375                 :            :         o( 1903, 0xEEE5DE, "seashell2")\
     376                 :            :         o( 1907, 0x8B8682, "seashell4")\
     377                 :            :         o( 1921, 0xFFA500, "orange1")\
     378                 :            :         o( 1925, 0xCD8500, "orange3")\
     379                 :            :         o( 1927, 0xEE9A00, "orange2")\
     380                 :            :         o( 1931, 0x8B5A00, "orange4")\
     381                 :            :         o( 1942, 0x00CED1, "dark turquoise", "DarkTurquoise")\
     382                 :            :         o( 1958, 0xFFDEAD, "navajo white", "NavajoWhite")\
     383                 :            :         o( 1962, 0xE0FFFF, "light cyan", "LightCyan")\
     384                 :            :         o( 1978, 0xFFC0CB, "pink")\
     385                 :            :         o( 1990, 0x483D8B, "dark slate blue", "DarkSlateBlue")\
     386                 :            :         o( 1998, 0x66CDAA, "medium aquamarine", "MediumAquamarine")\
     387                 :            :         o( 2006, 0xD2691E, "chocolate")\
     388                 :            :         o( 2022, 0xFFFAF0, "floral white", "FloralWhite")\
     389                 :            :         o( 2042, 0xFFFACD, "lemon chiffon", "LemonChiffon")\
     390                 :            :         o( 2072, 0xFF0000, "red")\
     391                 :            :         o( 2081, 0xFFF0F5, "LavenderBlush1")\
     392                 :            :         o( 2085, 0xCDC1C5, "LavenderBlush3")\
     393                 :            :         o( 2087, 0xEEE0E5, "LavenderBlush2")\
     394                 :            :         o( 2091, 0x8B8386, "LavenderBlush4")\
     395                 :            :         o( 2094, 0x000080, "navy blue", "NavyBlue")\
     396                 :            :         o( 2110, 0xFFFFFF, "gray100", "grey100")\
     397                 :            :         o( 2118, 0x87CEEB, "sky blue", "SkyBlue")\
     398                 :            :         o( 2126, 0x00BFFF, "deep sky blue", "DeepSkyBlue")\
     399                 :            :         o( 2185, 0xFF00FF, "magenta1")\
     400                 :            :         o( 2189, 0xCD00CD, "magenta3")\
     401                 :            :         o( 2191, 0xEE00EE, "magenta2")\
     402                 :            :         o( 2195, 0x8B008B, "magenta4")\
     403                 :            :         o( 2230, 0xB0C4DE, "light steel blue", "LightSteelBlue")\
     404                 :            :         o( 2241, 0x9AFF9A, "PaleGreen1")\
     405                 :            :         o( 2245, 0x7CCD7C, "PaleGreen3")\
     406                 :            :         o( 2247, 0x90EE90, "PaleGreen2")\
     407                 :            :         o( 2251, 0x548B54, "PaleGreen4")\
     408                 :            :         o( 2252, 0xFFFFF0, "ivory")\
     409                 :            :         o( 2265, 0xFFC125, "goldenrod1")\
     410                 :            :         o( 2269, 0xCD9B1D, "goldenrod3")\
     411                 :            :         o( 2271, 0xEEB422, "goldenrod2")\
     412                 :            :         o( 2275, 0x8B6914, "goldenrod4")\
     413                 :            :         o( 2278, 0x9370DB, "medium purple", "MediumPurple")\
     414                 :            :         o( 2304, 0x696969, "dim gray", "DimGray", "dim grey", "DimGrey")\
     415                 :            :         o( 2322, 0xFF69B4, "hot pink", "HotPink")\
     416                 :            :         o( 2332, 0xBA55D3, "medium orchid", "MediumOrchid")\
     417                 :            :         o( 2342, 0x1E90FF, "dodger blue", "DodgerBlue")\
     418                 :            :         o( 2352, 0xA9A9A9, "dark grey", "DarkGrey", "dark gray", "DarkGray")\
     419                 :            :         o( 2378, 0xFF7F50, "coral")\
     420                 :            :         o( 2393, 0xFF6347, "tomato1")\
     421                 :            :         o( 2397, 0xCD4F39, "tomato3")\
     422                 :            :         o( 2399, 0xEE5C42, "tomato2")\
     423                 :            :         o( 2403, 0x8B3626, "tomato4")\
     424                 :            :         o( 2409, 0xFF82AB, "PaleVioletRed1")\
     425                 :            :         o( 2413, 0xCD6889, "PaleVioletRed3")\
     426                 :            :         o( 2415, 0xEE799F, "PaleVioletRed2")\
     427                 :            :         o( 2419, 0x8B475D, "PaleVioletRed4")\
     428                 :            :         o( 2425, 0xB0E2FF, "LightSkyBlue1")\
     429                 :            :         o( 2429, 0x8DB6CD, "LightSkyBlue3")\
     430                 :            :         o( 2431, 0xA4D3EE, "LightSkyBlue2")\
     431                 :            :         o( 2432, 0xFF4500, "orange red", "OrangeRed")\
     432                 :            :         o( 2435, 0x607B8B, "LightSkyBlue4")\
     433                 :            :         o( 2457, 0xFF7F00, "DarkOrange1")\
     434                 :            :         o( 2461, 0xCD6600, "DarkOrange3")\
     435                 :            :         o( 2463, 0xEE7600, "DarkOrange2")\
     436                 :            :         o( 2467, 0x8B4500, "DarkOrange4")\
     437                 :            :         o( 2496, 0x708090, "slate gray", "SlateGray", "slate grey", "SlateGrey")\
     438                 :            :         o( 2533, 0x363636, "gray21", "grey21")\
     439                 :            :         o( 2534, 0x474747, "gray28", "grey28")\
     440                 :            :         o( 2537, 0x3B3B3B, "gray23", "grey23")\
     441                 :            :         o( 2539, 0x383838, "gray22", "grey22")\
     442                 :            :         o( 2540, 0x454545, "gray27", "grey27")\
     443                 :            :         o( 2541, 0x4A4A4A, "gray29", "grey29")\
     444                 :            :         o( 2543, 0x3D3D3D, "gray24", "grey24")\
     445                 :            :         o( 2544, 0x424242, "gray26", "grey26")\
     446                 :            :         o( 2546, 0x333333, "gray20", "grey20")\
     447                 :            :         o( 2547, 0x404040, "gray25", "grey25")\
     448                 :            :         o( 2553, 0xFFFFF0, "ivory1")\
     449                 :            :         o( 2557, 0xCDCDC1, "ivory3")\
     450                 :            :         o( 2559, 0xEEEEE0, "ivory2")\
     451                 :            :         o( 2563, 0x8B8B83, "ivory4")\
     452                 :            :         o( 2569, 0xFF6A6A, "IndianRed1")\
     453                 :            :         o( 2573, 0xCD5555, "IndianRed3")\
     454                 :            :         o( 2575, 0xEE6363, "IndianRed2")\
     455                 :            :         o( 2577, 0xCAFF70, "DarkOliveGreen1")\
     456                 :            :         o( 2579, 0x8B3A3A, "IndianRed4")\
     457                 :            :         o( 2581, 0xA2CD5A, "DarkOliveGreen3")\
     458                 :            :         o( 2583, 0xBCEE68, "DarkOliveGreen2")\
     459                 :            :         o( 2587, 0x6E8B3D, "DarkOliveGreen4")\
     460                 :            :         o( 2617, 0xC0FF3E, "OliveDrab1")\
     461                 :            :         o( 2621, 0x9ACD32, "OliveDrab3")\
     462                 :            :         o( 2623, 0xB3EE3A, "OliveDrab2")\
     463                 :            :         o( 2627, 0x698B22, "OliveDrab4")\
     464                 :            :         o( 2675, 0xFFEFD5, "papaya whip", "PapayaWhip")\
     465                 :            :         o( 2694, 0xFF00FF, "magenta")\
     466                 :            :         o( 2697, 0x00F5FF, "turquoise1")\
     467                 :            :         o( 2701, 0x00C5CD, "turquoise3")\
     468                 :            :         o( 2703, 0x00E5EE, "turquoise2")\
     469                 :            :         o( 2704, 0xBEBEBE, "gray", "grey")\
     470                 :            :         o( 2707, 0x00868B, "turquoise4")\
     471                 :            :         o( 2714, 0xF0FFFF, "azure")\
     472                 :            :         o( 2737, 0xFF34B3, "maroon1")\
     473                 :            :         o( 2741, 0xCD2990, "maroon3")\
     474                 :            :         o( 2743, 0xEE30A7, "maroon2")\
     475                 :            :         o( 2747, 0x8B1C62, "maroon4")\
     476                 :            :         o( 2750, 0x5F9EA0, "cadet blue", "CadetBlue")\
     477                 :            :         o( 2769, 0x00FF00, "green1")\
     478                 :            :         o( 2773, 0x00CD00, "green3")\
     479                 :            :         o( 2775, 0x00EE00, "green2")\
     480                 :            :         o( 2777, 0xFFD700, "gold1")\
     481                 :            :         o( 2779, 0x008B00, "green4")\
     482                 :            :         o( 2781, 0xCDAD00, "gold3")\
     483                 :            :         o( 2783, 0xEEC900, "gold2")\
     484                 :            :         o( 2787, 0x8B7500, "gold4")\
     485                 :            :         o( 2809, 0xC6E2FF, "SlateGray1")\
     486                 :            :         o( 2813, 0x9FB6CD, "SlateGray3")\
     487                 :            :         o( 2815, 0xB9D3EE, "SlateGray2")\
     488                 :            :         o( 2819, 0x6C7B8B, "SlateGray4")\
     489                 :            :         o( 2849, 0x9B30FF, "purple1")\
     490                 :            :         o( 2850, 0x008B8B, "dark cyan", "DarkCyan")\
     491                 :            :         o( 2853, 0x7D26CD, "purple3")\
     492                 :            :         o( 2855, 0x912CEE, "purple2")\
     493                 :            :         o( 2857, 0xFFE7BA, "wheat1")\
     494                 :            :         o( 2859, 0x551A8B, "purple4")\
     495                 :            :         o( 2861, 0xCDBA96, "wheat3")\
     496                 :            :         o( 2863, 0xEED8AE, "wheat2")\
     497                 :            :         o( 2867, 0x8B7E66, "wheat4")\
     498                 :            :         o( 2871, 0xF0E68C, "khaki")\
     499                 :            :         o( 2874, 0x20B2AA, "light sea green", "LightSeaGreen")\
     500                 :            :         o( 2881, 0x00FF7F, "SpringGreen1")\
     501                 :            :         o( 2882, 0x32CD32, "lime green", "LimeGreen")\
     502                 :            :         o( 2885, 0x00CD66, "SpringGreen3")\
     503                 :            :         o( 2886, 0x7FFF00, "chartreuse")\
     504                 :            :         o( 2887, 0x00EE76, "SpringGreen2")\
     505                 :            :         o( 2891, 0x008B45, "SpringGreen4")\
     506                 :            :         o( 2912, 0x778899, "light slate gray", "LightSlateGray", "light slate grey", "LightSlateGrey")\
     507                 :            :         o( 2913, 0xB5B5B5, "gray71", "grey71")\
     508                 :            :         o( 2914, 0xC7C7C7, "gray78", "grey78")\
     509                 :            :         o( 2917, 0xBABABA, "gray73", "grey73")\
     510                 :            :         o( 2919, 0xB8B8B8, "gray72", "grey72")\
     511                 :            :         o( 2920, 0xC4C4C4, "gray77", "grey77")\
     512                 :            :         o( 2921, 0xC9C9C9, "gray79", "grey79")\
     513                 :            :         o( 2923, 0xBDBDBD, "gray74", "grey74")\
     514                 :            :         o( 2924, 0xC2C2C2, "gray76", "grey76")\
     515                 :            :         o( 2926, 0xB3B3B3, "gray70", "grey70")\
     516                 :            :         o( 2927, 0xBFBFBF, "gray75", "grey75")\
     517                 :            :         o( 2966, 0x4169E1, "royal blue", "RoyalBlue")\
     518                 :            :         o( 2985, 0xCAE1FF, "LightSteelBlue1")\
     519                 :            :         o( 2989, 0xA2B5CD, "LightSteelBlue3")\
     520                 :            :         o( 2991, 0xBCD2EE, "LightSteelBlue2")\
     521                 :            :         o( 2995, 0x6E7B8B, "LightSteelBlue4")\
     522                 :            :         o( 3024, 0xDEB887, "burlywood")\
     523                 :            :         o( 3042, 0xCD853F, "peru")\
     524                 :            :         o( 3048, 0xFFEBCD, "blanched almond", "BlanchedAlmond")\
     525                 :            :         o( 3081, 0x97FFFF, "DarkSlateGray1")\
     526                 :            :         o( 3085, 0x79CDCD, "DarkSlateGray3")\
     527                 :            :         o( 3087, 0x8DEEEE, "DarkSlateGray2")\
     528                 :            :         o( 3091, 0x528B8B, "DarkSlateGray4")\
     529                 :            :         o( 3153, 0xFF8247, "sienna1")\
     530                 :            :         o( 3157, 0xCD6839, "sienna3")\
     531                 :            :         o( 3159, 0xEE7942, "sienna2")\
     532                 :            :         o( 3163, 0x8B4726, "sienna4")\
     533                 :            :         o( 3193, 0xFFC1C1, "RosyBrown1")\
     534                 :            :         o( 3197, 0xCD9B9B, "RosyBrown3")\
     535                 :            :         o( 3199, 0xEEB4B4, "RosyBrown2")\
     536                 :            :         o( 3202, 0x00FFFF, "cyan")\
     537                 :            :         o( 3203, 0x8B6969, "RosyBrown4")\
     538                 :            :         o( 3206, 0xFFE4C4, "bisque")\
     539                 :            :         o( 3210, 0xFAF0E6, "linen")\
     540                 :            :         o( 3214, 0x6B8E23, "olive drab", "OliveDrab")\
     541                 :            :         o( 3226, 0x228B22, "forest green", "ForestGreen")\
     542                 :            :         o( 3230, 0x8B008B, "dark magenta", "DarkMagenta")\
     543                 :            :         o( 3240, 0xDAA520, "goldenrod")\
     544                 :            :         o( 3250, 0x556B2F, "dark olive green", "DarkOliveGreen")\
     545                 :            :         o( 3265, 0x7FFFD4, "aquamarine1")\
     546                 :            :         o( 3266, 0x7CFC00, "lawn green", "LawnGreen")\
     547                 :            :         o( 3269, 0x66CDAA, "aquamarine3")\
     548                 :            :         o( 3271, 0x76EEC6, "aquamarine2")\
     549                 :            :         o( 3275, 0x458B74, "aquamarine4")\
     550                 :            :         o( 3293, 0xE8E8E8, "gray91", "grey91")\
     551                 :            :         o( 3294, 0xFAFAFA, "gray98", "grey98")\
     552                 :            :         o( 3297, 0xEDEDED, "gray93", "grey93")\
     553                 :            :         o( 3299, 0xEBEBEB, "gray92", "grey92")\
     554                 :            :         o( 3300, 0xF7F7F7, "gray97", "grey97")\
     555                 :            :         o( 3301, 0xFCFCFC, "gray99", "grey99")\
     556                 :            :         o( 3303, 0xF0F0F0, "gray94", "grey94")\
     557                 :            :         o( 3304, 0xF5F5F5, "gray96", "grey96")\
     558                 :            :         o( 3306, 0xE5E5E5, "gray90", "grey90")\
     559                 :            :         o( 3307, 0xF2F2F2, "gray95", "grey95")\
     560                 :            :         o( 3326, 0xFFF0F5, "lavender blush", "LavenderBlush")\
     561                 :            :         o( 3329, 0xE0FFFF, "LightCyan1")\
     562                 :            :         o( 3333, 0xB4CDCD, "LightCyan3")\
     563                 :            :         o( 3335, 0xD1EEEE, "LightCyan2")\
     564                 :            :         o( 3339, 0x7A8B8B, "LightCyan4")\
     565                 :            :         o( 3346, 0x90EE90, "light green", "LightGreen")\
     566                 :            :         o( 3362, 0x00FF7F, "spring green", "SpringGreen")\
     567                 :            :         o( 3374, 0xADD8E6, "light blue", "LightBlue")\
     568                 :            :         o( 3409, 0xBFEFFF, "LightBlue1")\
     569                 :            :         o( 3413, 0x9AC0CD, "LightBlue3")\
     570                 :            :         o( 3414, 0xF5F5F5, "white smoke", "WhiteSmoke")\
     571                 :            :         o( 3415, 0xB2DFEE, "LightBlue2")\
     572                 :            :         o( 3419, 0x68838B, "LightBlue4")\
     573                 :            :         o( 3425, 0x54FF9F, "SeaGreen1")\
     574                 :            :         o( 3429, 0x43CD80, "SeaGreen3")\
     575                 :            :         o( 3431, 0x4EEE94, "SeaGreen2")\
     576                 :            :         o( 3434, 0xADFF2F, "green yellow", "GreenYellow")\
     577                 :            :         o( 3435, 0x2E8B57, "SeaGreen4")\
     578                 :            :         o( 3450, 0xFFF5EE, "seashell")\
     579                 :            :         o( 3481, 0xFFE4E1, "MistyRose1")\
     580                 :            :         o( 3485, 0xCDB7B5, "MistyRose3")\
     581                 :            :         o( 3487, 0xEED5D2, "MistyRose2")\
     582                 :            :         o( 3491, 0x8B7D7B, "MistyRose4")\
     583                 :            :         o( 3506, 0xF5F5DC, "beige")\
     584                 :            :         o( 3513, 0xFFBBFF, "plum1")\
     585                 :            :         o( 3517, 0xCD96CD, "plum3")\
     586                 :            :         o( 3519, 0xEEAEEE, "plum2")\
     587                 :            :         o( 3523, 0x8B668B, "plum4")\
     588                 :            :         o( 3558, 0x7FFFD4, "aquamarine")\
     589                 :            :         o( 3561, 0xFFA07A, "LightSalmon1")\
     590                 :            :         o( 3565, 0xCD8162, "LightSalmon3")\
     591                 :            :         o( 3567, 0xEE9572, "LightSalmon2")\
     592                 :            :         o( 3571, 0x8B5742, "LightSalmon4")\
     593                 :            :         o( 3593, 0xBBFFFF, "PaleTurquoise1")\
     594                 :            :         o( 3594, 0xF5DEB3, "wheat")\
     595                 :            :         o( 3597, 0x96CDCD, "PaleTurquoise3")\
     596                 :            :         o( 3599, 0xAEEEEE, "PaleTurquoise2")\
     597                 :            :         o( 3602, 0xFFFF00, "yellow")\
     598                 :            :         o( 3603, 0x668B8B, "PaleTurquoise4")\
     599                 :            :         o( 3624, 0xCD5C5C, "indian red", "IndianRed")\
     600                 :            :         o( 3633, 0xAB82FF, "MediumPurple1")\
     601                 :            :         o( 3637, 0x8968CD, "MediumPurple3")\
     602                 :            :         o( 3639, 0x9F79EE, "MediumPurple2")\
     603                 :            :         o( 3643, 0x5D478B, "MediumPurple4")\
     604                 :            :         o( 3656, 0xEEDD82, "light goldenrod", "LightGoldenrod")\
     605                 :            :         o( 3674, 0xFFA500, "orange")\
     606                 :            :         o( 3698, 0x98FB98, "pale green", "PaleGreen")\
     607                 :            :         o( 3721, 0x87CEFF, "SkyBlue1")\
     608                 :            :         o( 3725, 0x6CA6CD, "SkyBlue3")\
     609                 :            :         o( 3726, 0xFFFFFF, "white")\
     610                 :            :         o( 3727, 0x7EC0EE, "SkyBlue2")\
     611                 :            :         o( 3730, 0xFA8072, "salmon")\
     612                 :            :         o( 3731, 0x4A708B, "SkyBlue4")\
     613                 :            :         o( 3745, 0x98F5FF, "CadetBlue1")\
     614                 :            :         o( 3749, 0x7AC5CD, "CadetBlue3")\
     615                 :            :         o( 3751, 0x8EE5EE, "CadetBlue2")\
     616                 :            :         o( 3755, 0x53868B, "CadetBlue4")\
     617                 :            :         o( 3794, 0x9ACD32, "yellow green", "YellowGreen")\
     618                 :            :         o( 3802, 0x006400, "dark green", "DarkGreen")\
     619                 :            :         o( 3809, 0x030303, "gray1", "grey1")\
     620                 :            :         o( 3810, 0x141414, "gray8", "grey8")\
     621                 :            :         o( 3813, 0x080808, "gray3", "grey3")\
     622                 :            :         o( 3815, 0x050505, "gray2", "grey2")\
     623                 :            :         o( 3816, 0x121212, "gray7", "grey7")\
     624                 :            :         o( 3817, 0x171717, "gray9", "grey9")\
     625                 :            :         o( 3818, 0xB22222, "firebrick")\
     626                 :            :         o( 3819, 0x0A0A0A, "gray4", "grey4")\
     627                 :            :         o( 3820, 0x0F0F0F, "gray6", "grey6")\
     628                 :            :         o( 3822, 0x000000, "gray0", "grey0")\
     629                 :            :         o( 3823, 0x0D0D0D, "gray5", "grey5")\
     630                 :            : 
     631                 :            : /** ParseHex: Attempts to read a hexadecimal number from the input.
     632                 :            :  * @returns Pair (result, length). Modifies the input pointer.
     633                 :            :  */
     634                 :         10 : static std::pair<unsigned long long, unsigned> ParseHex(const char*& s)
     635                 :            : {
     636                 :         10 :     unsigned long long result = 0;
     637                 :         10 :     unsigned length           = 0;
     638   [ +  +  +  + ]:         34 :     while(*s != '\0' && *s != '/')
     639                 :            :     {
     640                 :         24 :         result <<= 4;
     641         [ -  + ]:         24 :         if(*s >= 'A' && *s <= 'F')      result += *s - 'A' + 10;
     642         [ -  + ]:         24 :         else if(*s >= 'a' && *s <= 'f') result += *s - 'a' + 10;
     643         [ +  - ]:         24 :         else if(*s >= '0' && *s <= '9') result += *s - '0' +  0;
     644                 :            :         /* Non-hex digits are treated as '0'.             */
     645                 :            :         /* This matches the HTML color parsing algorithm. */
     646                 :         24 :         ++s; ++length;
     647                 :            :     }
     648                 :         10 :     return {result, length};
     649                 :            : }
     650                 :            : /** ParseDbl: Attempts to read a floating point value from the input.
     651                 :            :  * @returns The read number, multiplied by 255.9999 and clamped into 0,255 range.
     652                 :            :  * Modifies the input pointer.
     653                 :            :  */
     654                 :          6 : static unsigned ParseDbl(const char*& s)
     655                 :            : {
     656                 :          6 :     char* endptr = nullptr;
     657                 :          6 :     double result = std::strtod(s, &endptr);
     658                 :          6 :     s = endptr;
     659   [ -  +  -  + ]:          6 :     return unsigned(255.9999 * std::max(std::min(result, 1.), 0.));
     660                 :            : }
     661                 :            : 
     662                 :            : enum { use_separator=1, lsb_first=2, use_dbl=4 };
     663                 :            : /** Attempts to reads a color number from the source using one of the different formats.
     664                 :            :  * @param source String to read. Forward-slashes are ignored.
     665                 :            :  * @param specs Specifications:
     666                 :            :  *              &use_dbl       = Reads floating point values.
     667                 :            :  *              &use_separator = Reads three values.
     668                 :            :  *              &lsb_first     = Places first index to lsb and third index to msb.
     669                 :            :  *                               If unset, the opposite behavior is done.
     670                 :            :  * @returns The read color, as 24-bit integer.
     671                 :            :  */
     672                 :          8 : static unsigned ParseColorNumber(const char* source, unsigned specs)
     673                 :            : {
     674                 :          8 :     unsigned result        = 0;
     675                 :          8 :     unsigned long long val = 0;
     676                 :          8 :     unsigned length        = 0;
     677                 :          8 :     unsigned bits          = 0;
     678                 :            : 
     679         [ +  + ]:         32 :     for(unsigned n=0; n<3; ++n)
     680                 :            :     {
     681         [ +  + ]:         32 :         while(*source == '/') ++source;
     682                 :            : 
     683         [ +  + ]:         24 :         if(specs & use_dbl)
     684                 :            :         {
     685                 :          6 :             val  = ParseDbl(source);
     686                 :          6 :             bits = 8;
     687                 :            :         }
     688   [ +  +  +  + ]:         18 :         else if((specs & use_separator) || n==0)
     689                 :            :         {
     690         [ +  + ]:         10 :             std::tie(val, length) = ParseHex(source);
     691                 :         10 :             bits = length*4;
     692         [ +  + ]:         10 :             if(!(specs & use_separator)) bits /= 3;
     693                 :            :         }
     694                 :            : 
     695                 :         24 :         unsigned mask = ((0x1u << bits)-1);
     696                 :         24 :         unsigned temp = val & mask; val >>= bits;
     697                 :            :         // Scale to 0xFF.
     698                 :         24 :         temp = temp * 0xFF / mask;
     699         [ +  + ]:         24 :         if(specs & lsb_first)
     700                 :            :         {
     701                 :         12 :             result += temp << (8*n);
     702                 :            :             // Place n=0 to LSB and n=2 to MSB.
     703                 :            :         }
     704                 :            :         else
     705                 :            :         {
     706                 :         12 :             result <<= 8;
     707                 :         12 :             result += temp;
     708                 :            :             // Place n=0 to MSB and n=0 to MSB. Reverse of above.
     709                 :            :         }
     710                 :            :     }
     711                 :          8 :     return result;
     712                 :            : }
     713                 :            : /** Attempts reading a color in one of the numberic formats. */
     714                 :        779 : static std::pair<unsigned,bool> TryParseColorNumber(std::string_view lc)
     715                 :            : {
     716                 :        779 :     const char* source = nullptr;
     717                 :        779 :     unsigned    specs  = 0;
     718                 :            : 
     719         [ +  + ]:        779 :     if(lc.size() >= 4)
     720                 :            :     {
     721                 :        777 :         static constexpr const char hextext[]  = {'#'};
     722                 :        777 :         static constexpr const char rgbtext[]  = {'r','g','b',':'};
     723                 :        777 :         static constexpr const char rgbitext[] = {'r','g','b','i',':'};
     724                 :            :         /* Note that these strings are case-sensitive. */
     725         [ +  + ]:        777 :         if(std::memcmp(lc.data(), hextext, sizeof hextext) == 0) // shortest: "#FFF" = 4 characters
     726                 :            :         {
     727                 :          4 :             source = lc.data()+1;
     728                 :          4 :             specs  = lsb_first;
     729                 :            :         }
     730         [ +  + ]:        773 :         else if(std::memcmp(lc.data(), rgbtext, sizeof rgbtext) == 0) // shortest: "rgb:F/F/F" = 9
     731                 :            :         {
     732                 :          2 :             source = lc.data()+4;
     733                 :          2 :             specs  = use_separator;
     734                 :            :         }
     735         [ +  + ]:        771 :         else if(std::memcmp(lc.data(), rgbitext, sizeof rgbitext) == 0) // shortest: "rgbi:1/1/1" = 10
     736                 :            :         {
     737                 :            :             // Note: compares 5 letters while we only checked size >= 4.
     738                 :            :             // If size == 4, there will be a nul, so this comparison is still safe,
     739                 :            :             // assuming that the string view is nul terminated.
     740                 :          2 :             source = lc.data()+5;
     741                 :          2 :             specs  = use_separator | use_dbl;
     742                 :            :         }
     743                 :            :     }
     744                 :          8 :     return source
     745                 :          8 :         ? std::pair{ ParseColorNumber(source, specs), true }
     746         [ +  - ]:        787 :         : std::pair{ 0u, false };
     747                 :            : }
     748                 :            : 
     749                 :            : /** FindColor identifies the hash and returns a color matching it. */
     750                 :        771 : static constexpr unsigned FindColor(unsigned h)
     751                 :            : {
     752                 :            :     #define o(a,b,...) case a: return b; break;
     753   [ +  +  +  +  :        771 :     switch(h) { docolors(o) }
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
                   +  + ]
     754                 :            :     #undef o
     755                 :          8 :     return 0;
     756                 :            : }
     757                 :            : /** Generates an std::array containing colors in an index matching its hash. */
     758                 :            : template <std::size_t... N>
     759                 :            : static consteval auto GetColors(std::index_sequence<N...>)
     760                 :            : {
     761                 :            :     return std::array<unsigned, sizeof...(N)>
     762                 :            :     {
     763                 :            :         // Using a separate function for this rather than
     764                 :            :         // inlining a long ?: chain makes compilation on GCC fast.
     765                 :            :         // While Clang has no trouble with a long ?: chain, GCC would take ages to compile it.
     766                 :            :         FindColor(N) ...
     767                 :            :     };
     768                 :            : }
     769                 :            : 
     770                 :            : 
     771                 :            : /** See explanation in VerifyHash() */
     772                 :            : template<std::size_t N>
     773                 :            : struct fixed_string
     774                 :            : {
     775                 :            :     /** Initializes the string with the given @param s string constant */
     776                 :            :     constexpr fixed_string(const char (&s)[N]) { std::copy_n(s, N, str); }
     777                 :            :     /** @returns a pointer to the string */
     778                 :            :     consteval const char* data() const { return str; }
     779                 :            :     /** @returns the string length */
     780                 :            :     consteval std::size_t size() const { return N-1; }
     781                 :            :     /** Stores the string */
     782                 :            :     char str[N];
     783                 :            : };
     784                 :            : 
     785                 :            : /** VerifyHash()
     786                 :            :  * Purpose:
     787                 :            :  *
     788                 :            :  * Uses static_assert(hash()) to verify that all of the given strings
     789                 :            :  * match to the given hash value.
     790                 :            :  *
     791                 :            :  * Note: fixed_string as a template parameter is
     792                 :            :  * a c++20 feature (class-type in non-type template parameter)
     793                 :            :  * Minimum supported compiler version: GCC 9, Clang 12, MSVC 19.28
     794                 :            :  * Not supported by Apple Clang yet.
     795                 :            :  *
     796                 :            :  * For concepts, you need GCC 10 or Clang 10.
     797                 :            :  *
     798                 :            :  * A fixed_string wrapper must be used, because a character array
     799                 :            :  * is not a valid template parameter. Attempts to use "const char*"
     800                 :            :  * or "char[]" will result in compilation errors.
     801                 :            :  *
     802                 :            :  * Similarly, attempts to pass the strings as parameters will fail,
     803                 :            :  * such as this:
     804                 :            :  *    template<unsigned expected_hash, std::size_t... N>
     805                 :            :  *    static consteval void VerifyHash(const char (&...s)[N])
     806                 :            :  * because the compiler says they are not constant expressions.
     807                 :            :  *
     808                 :            :  * The expected hash number must also be a template parameter.
     809                 :            :  * Otherwise static_assert will fail saying that the number
     810                 :            :  * is not a constant expression.
     811                 :            :  * Even though the function is consteval, passing any of the
     812                 :            :  * function parameters to static_assert() will fail the compilation.
     813                 :            :  *
     814                 :            :  * Then, static_assert is not an expression. It is a statement.
     815                 :            :  * This would not compile:
     816                 :            :  *   (static_assert(hash(s.data(), s.size()) == expected_hash), ...);
     817                 :            :  * We could wrap the static_assert in a lambda, turning it into
     818                 :            :  * an expression, but due to *two* bugs in GCC (PR99893 and PR99895),
     819                 :            :  * it does not compile. Both would work on Clang though.
     820                 :            :  */
     821                 :            : template<unsigned expected_hash, fixed_string... s>
     822                 :            : static constexpr inline void VerifyHash()
     823                 :            : {
     824                 :            :     // Make sure all the hashes are equal and match expected_hash
     825                 :            :     static_assert( ((hash(s.data(), s.size()) == expected_hash) and ...), "Incorrect hash" );
     826                 :            : }
     827                 :            : 
     828                 :        779 : unsigned ParseColorName(std::string_view s)
     829                 :            : {
     830                 :            :     /* First check if it's #ABC, #AABBCC, rgb:aa/bb/cc or rgbi:0.2/0.6/0.8 */
     831         [ +  + ]:        779 :     auto [result,success] = TryParseColorNumber(s);
     832         [ +  + ]:        779 :     if(success) return result;
     833                 :            : 
     834                 :            :     /* Nope? Then look it up in the hardcoded version of Xorg colors database. */
     835                 :            : 
     836                 :            :     /* Verify that all of the hashes in docolors() match the implementation in hash() */
     837                 :            :     #define v(a,b,...) VerifyHash<a, __VA_ARGS__>();
     838                 :        771 :     docolors(v);
     839                 :            :     #undef v
     840                 :            : 
     841                 :            :     /* Begin by reducing the provided color into a small hash that is unique
     842                 :            :      * for all colors in the database.
     843                 :            :      */
     844                 :        771 :     unsigned short h = hash(s.data(), s.size());
     845                 :            : 
     846                 :            : #if defined(__GNUC__) && !defined(__clang__)
     847                 :            :     /* GCC generates pretty optimal code for this. */
     848                 :            :     /* This produces an extra range check compared to what's below, but needs less data. */
     849                 :            :     /* Amount of data: same as below, minus ~100 bytes by average */
     850                 :        771 :     return FindColor(h);
     851                 :            : #elif defined(__clang__) || defined(__GNUC__)
     852                 :            :     /* Clang and GCC compile this well. No comparisons, just a singular data access. */
     853                 :            :     /* Amount of data: mod*4 = ~15 kB */
     854                 :            :     static constinit const auto colorvalues = GetColors(std::make_index_sequence<mod>());
     855                 :            :     return colorvalues[h];
     856                 :            : #else
     857                 :            :     #define o(a,b,...) a,
     858                 :            :     #define q(a,b,...) b,
     859                 :            :     static constinit const unsigned short colorkeys[] { docolors(o) };
     860                 :            :     static constinit const unsigned int colorvalues[] { docolors(q) };
     861                 :            :     #undef q
     862                 :            :     #undef o
     863                 :            :     /* This uses least data, but performs about log2(753) = 10 comparisons. */
     864                 :            :     /* Amount of data: 753*2 + 753*4 = ~4.5 kB */
     865                 :            :     auto i = std::lower_bound(std::begin(colorkeys), std::end(colorkeys), h);
     866                 :            :     if(i != std::end(colorkeys) && *i == h)
     867                 :            :         return colorvalues[ i-std::begin(colorkeys) ];
     868                 :            :     return 0;
     869                 :            : #endif
     870                 :            : }
     871                 :            : 
     872                 :            : #ifdef RUN_TESTS
     873                 :            : /* The word "volatile" is used to ensure that inlining does not foil branch statistics in lcov */
     874                 :          3 : TEST(color, unpack_ok)
     875                 :            : {
     876                 :          1 :     volatile unsigned r = 0x123456;
     877                 :          1 :     EXPECT_EQ(Unpack(r), (std::array{0x12u, 0x34u, 0x56u}));
     878                 :          1 : }
     879                 :          3 : TEST(color, repack_ok)
     880                 :            : {
     881                 :            :     // Basic behavior
     882                 :          1 :     volatile unsigned r = 0x56;
     883                 :          1 :     EXPECT_EQ(Repack({0x12,0x34,r}), 0x123456u);
     884                 :            :     // Clamping
     885                 :          1 :     volatile unsigned q = 256u;
     886                 :          1 :     EXPECT_EQ(Repack({q,q,q}), 0xFFFFFFu);
     887                 :            :     // Desaturating
     888                 :          1 :     volatile unsigned m = 512u;
     889                 :          1 :     EXPECT_EQ(Repack({m,0,0}), 0xFF6E6Eu);
     890                 :          1 : }
     891                 :          3 : TEST(color, mix)
     892                 :            : {
     893                 :          1 :     volatile unsigned a=10;
     894                 :          1 :     EXPECT_EQ(Mix(0x000000, 0xFFFFFF, a,30,40), 0xBFBFBFu);
     895                 :          1 :     EXPECT_EQ(Mix(0x111111, 0xFF0000, a,30,40), 0xC30404u);
     896                 :          1 :     EXPECT_EQ(Mix(0x111111, 0x00FF00, a,30,40), 0x04C304u);
     897                 :          1 :     EXPECT_EQ(Mix(0x111111, 0x0000FF, a,30,40), 0x0404C3u);
     898                 :          1 : }
     899                 :          3 : TEST(color, cmyk)
     900                 :            : {
     901                 :          1 :     volatile unsigned r = 0x123456;
     902                 :          1 :     EXPECT_EQ(cmy2rgb(r),            (0xFFFFFFu - 0x123456u));
     903                 :          1 :     EXPECT_EQ(cmyk2rgb((r<<8)|0x78), 0x7D6B59u);
     904                 :          1 : }
     905                 :          3 : TEST(color, parsecolorname_utf8)
     906                 :            : {
     907                 :          1 :     EXPECT_EQ(ParseColorName("#123456"), 0x123456u);
     908                 :          1 :     EXPECT_EQ(ParseColorName("#123"), 0x112233u);
     909                 :          1 :     EXPECT_EQ(ParseColorName("rgb:1/2/3"), 0x112233u);
     910                 :          1 :     EXPECT_EQ(ParseColorName("rgbi:0.5/0/1"), 0x7F00FFu);
     911                 :          1 :     EXPECT_EQ(ParseColorName("black"), 0x000000u);
     912                 :          1 :     EXPECT_EQ(ParseColorName("white"), 0xFFFFFFu);
     913                 :          1 :     EXPECT_EQ(ParseColorName("blue"), 0x0000FFu);
     914                 :          1 :     EXPECT_EQ(ParseColorName("light coral"), 0xF08080u);
     915                 :          1 :     EXPECT_EQ(ParseColorName("LightCoral"), 0xF08080u);
     916                 :            : 
     917                 :            :     // For coverage, do all colors
     918                 :            :     #define o(hash,color,...) {for(auto s: {__VA_ARGS__})ParseColorName(s); FindColor(hash);}
     919   [ +  +  +  +  :        754 :     docolors(o)
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
                      + ]
     920                 :            :     #undef o
     921                 :          1 : }
     922                 :          3 : TEST(color, parsecolorname_char32)
     923                 :            : {
     924                 :          2 :     EXPECT_EQ(ParseColorName(U"#123456"), 0x123456u);
     925                 :          2 :     EXPECT_EQ(ParseColorName(U"#123"), 0x112233u);
     926                 :          2 :     EXPECT_EQ(ParseColorName(U"rgb:1/2/3"), 0x112233u);
     927                 :          2 :     EXPECT_EQ(ParseColorName(U"rgbi:0.5/0/1"), 0x7F00FFu);
     928                 :          2 :     EXPECT_EQ(ParseColorName(U"black"), 0x000000u);
     929                 :          2 :     EXPECT_EQ(ParseColorName(U"white"), 0xFFFFFFu);
     930                 :          2 :     EXPECT_EQ(ParseColorName(U"blue"), 0x0000FFu);
     931                 :          2 :     EXPECT_EQ(ParseColorName(U"light coral"), 0xF08080u);
     932                 :          2 :     EXPECT_EQ(ParseColorName(U"LightCoral"), 0xF08080u);
     933                 :          1 : }
     934                 :            : #endif

Generated by: LCOV version 1.16