File indexing completed on 2024-05-05 05:53:43
0001 /* 0002 SPDX-FileCopyrightText: 2007-2008 Robert Knight <robertknight@gmail.com> 0003 SPDX-FileCopyrightText: 1997, 1998 Lars Doelle <lars.doelle@on-line.de> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #ifndef CHARACTERCOLOR_H 0009 #define CHARACTERCOLOR_H 0010 0011 // Qt 0012 #include <QColor> 0013 0014 namespace Konsole 0015 { 0016 // Attributed Character Representations /////////////////////////////// 0017 0018 // Colors 0019 0020 #define BASE_COLORS (2 + 8) 0021 #define INTENSITIES 3 0022 #define TABLE_COLORS (INTENSITIES * BASE_COLORS) 0023 0024 enum ColorTableIndex { 0025 ColorFgIndex, 0026 ColorBgIndex, 0027 Color0Index, 0028 Color1Index, 0029 Color2Index, 0030 Color3Index, 0031 Color4Index, 0032 Color5Index, 0033 Color6Index, 0034 Color7Index, 0035 0036 ColorFgIntenseIndex, 0037 ColorBgIntenseIndex, 0038 Color0IntenseIndex, 0039 Color1IntenseIndex, 0040 Color2IntenseIndex, 0041 Color3IntenseIndex, 0042 Color4IntenseIndex, 0043 Color5IntenseIndex, 0044 Color6IntenseIndex, 0045 Color7IntenseIndex, 0046 0047 ColorFgFaintIndex, 0048 ColorBgFaintIndex, 0049 Color0FaintIndex, 0050 Color1FaintIndex, 0051 Color2FaintIndex, 0052 Color3FaintIndex, 0053 Color4FaintIndex, 0054 Color5FaintIndex, 0055 Color6FaintIndex, 0056 Color7FaintIndex, 0057 }; 0058 0059 #define DEFAULT_FORE_COLOR 0 0060 #define DEFAULT_BACK_COLOR 1 0061 0062 /* CharacterColor is a union of the various color spaces. 0063 0064 Assignment is as follows: 0065 0066 Type - Space - Values 0067 0068 0 - Undefined - u: 0, v:0 w:0 0069 1 - Default - u: 0..1 v:intense w:0 0070 2 - System - u: 0..7 v:intense w:0 0071 3 - Index(256) - u: 16..255 v:0 w:0 0072 4 - RGB - u: 0..255 v:0..256 w:0..256 0073 0074 ``intense'' is either 0 (normal), 1 (intensive), or 2 (faint) 0075 0076 Default color space has two separate colors, namely 0077 default foreground and default background color. 0078 */ 0079 0080 #define COLOR_SPACE_UNDEFINED 0 0081 #define COLOR_SPACE_DEFAULT 1 0082 #define COLOR_SPACE_SYSTEM 2 0083 #define COLOR_SPACE_256 3 0084 #define COLOR_SPACE_RGB 4 0085 0086 /** 0087 * Describes the color of a single character in the terminal. 0088 */ 0089 class CharacterColor 0090 { 0091 friend class Character; 0092 0093 public: 0094 /** Constructs a new CharacterColor whose color and color space are undefined. */ 0095 constexpr CharacterColor() 0096 : _colorSpace(COLOR_SPACE_UNDEFINED) 0097 , _u(0) 0098 , _v(0) 0099 , _w(0) 0100 { 0101 } 0102 0103 /** 0104 * Constructs a new CharacterColor using the specified @p colorSpace and with 0105 * color value @p co 0106 * 0107 * The meaning of @p co depends on the @p colorSpace used. 0108 * 0109 * TODO : Document how @p co relates to @p colorSpace 0110 * 0111 * TODO : Add documentation about available color spaces. 0112 */ 0113 constexpr CharacterColor(quint8 colorSpace, int co) 0114 : _colorSpace(colorSpace) 0115 , _u(0) 0116 , _v(0) 0117 , _w(0) 0118 { 0119 switch (colorSpace) { 0120 case COLOR_SPACE_DEFAULT: 0121 _u = co & 1; 0122 break; 0123 case COLOR_SPACE_SYSTEM: 0124 _u = co & 7; 0125 _v = (co >> 3) & 3; 0126 break; 0127 case COLOR_SPACE_256: 0128 _u = co & 255; 0129 break; 0130 case COLOR_SPACE_RGB: 0131 _u = co >> 16; 0132 _v = co >> 8; 0133 _w = co; 0134 break; 0135 default: 0136 _colorSpace = COLOR_SPACE_UNDEFINED; 0137 } 0138 } 0139 0140 constexpr quint8 colorSpace() const 0141 { 0142 return _colorSpace; 0143 } 0144 constexpr void termColor(int *u, int *v, int *w) 0145 { 0146 *u = _u; 0147 *v = _v; 0148 *w = _w; 0149 } 0150 0151 /** 0152 * Returns true if this character color entry is valid. 0153 */ 0154 constexpr bool isValid() const 0155 { 0156 return _colorSpace != COLOR_SPACE_UNDEFINED; 0157 } 0158 0159 /** 0160 * Set this color as an intensive system color. 0161 * 0162 * This is only applicable if the color is using the COLOR_SPACE_DEFAULT or COLOR_SPACE_SYSTEM 0163 * color spaces. 0164 */ 0165 void setIntensive(); 0166 0167 /** 0168 * Set this color as a faint system color. 0169 * 0170 * This is only applicable if the color is using the COLOR_SPACE_DEFAULT or COLOR_SPACE_SYSTEM 0171 * color spaces. 0172 */ 0173 void setFaint(); 0174 0175 /** 0176 * Returns the color within the specified color @p base 0177 * 0178 * The @p base is only used if this color is one of the 16 system colors, otherwise 0179 * it is ignored. 0180 */ 0181 constexpr QColor color(const QColor *base) const; 0182 0183 /** 0184 * Compares two colors and returns true if they represent the same color value and 0185 * use the same color space. 0186 */ 0187 friend constexpr bool operator==(const CharacterColor a, const CharacterColor b) 0188 { 0189 return std::tie(a._colorSpace, a._u, a._v, a._w) == std::tie(b._colorSpace, b._u, b._v, b._w); 0190 } 0191 /** 0192 * Compares two colors and returns true if they represent different color values 0193 * or use different color spaces. 0194 */ 0195 friend constexpr bool operator!=(const CharacterColor a, const CharacterColor b) 0196 { 0197 return !operator==(a, b); 0198 } 0199 0200 private: 0201 quint8 _colorSpace; 0202 0203 // bytes storing the character color 0204 quint8 _u; 0205 quint8 _v; 0206 quint8 _w; 0207 }; 0208 0209 constexpr QColor color256(quint8 u, const QColor *base) 0210 { 0211 // 0.. 16: system colors 0212 if (u < 8) { 0213 return base[u + 2]; 0214 } 0215 u -= 8; 0216 if (u < 8) { 0217 return base[u + 2 + BASE_COLORS]; 0218 } 0219 u -= 8; 0220 0221 // 16..231: 6x6x6 rgb color cube 0222 if (u < 216) { 0223 return QColor(((u / 36) % 6) ? (40 * ((u / 36) % 6) + 55) : 0, 0224 ((u / 6) % 6) ? (40 * ((u / 6) % 6) + 55) : 0, 0225 ((u / 1) % 6) ? (40 * ((u / 1) % 6) + 55) : 0); 0226 } 0227 u -= 216; 0228 0229 // 232..255: gray, leaving out black and white 0230 int gray = u * 10 + 8; 0231 0232 return QColor(gray, gray, gray); 0233 } 0234 0235 constexpr QColor CharacterColor::color(const QColor *base) const 0236 { 0237 switch (_colorSpace) { 0238 case COLOR_SPACE_DEFAULT: 0239 return base[_u + 0 + (_v * BASE_COLORS)]; 0240 case COLOR_SPACE_SYSTEM: 0241 return base[_u + 2 + (_v * BASE_COLORS)]; 0242 case COLOR_SPACE_256: 0243 return color256(_u, base); 0244 case COLOR_SPACE_RGB: 0245 return QColor(_u, _v, _w); 0246 case COLOR_SPACE_UNDEFINED: 0247 return QColor(); 0248 } 0249 0250 Q_ASSERT(false); // invalid color space 0251 0252 return QColor(); 0253 } 0254 0255 inline void CharacterColor::setIntensive() 0256 { 0257 if (_colorSpace == COLOR_SPACE_SYSTEM || _colorSpace == COLOR_SPACE_DEFAULT) { 0258 _v = 1; 0259 } 0260 } 0261 0262 inline void CharacterColor::setFaint() 0263 { 0264 if (_colorSpace == COLOR_SPACE_SYSTEM || _colorSpace == COLOR_SPACE_DEFAULT) { 0265 _v = 2; 0266 } 0267 } 0268 } 0269 0270 #endif // CHARACTERCOLOR_H