File indexing completed on 2025-03-16 08:11:24
0001 /* 0002 This file is part of Konsole, KDE's terminal. 0003 0004 SPDX-FileCopyrightText: 2007-2008 Robert Knight <robertknight@gmail.com> 0005 SPDX-FileCopyrightText: 1997, 1998 Lars Doelle <lars.doelle@on-line.de> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 0009 This program is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0012 GNU General Public License for more details. 0013 0014 You should have received a copy of the GNU General Public License 0015 along with this program; if not, write to the Free Software 0016 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 0017 02110-1301 USA. 0018 */ 0019 0020 #ifndef CHARACTERCOLOR_H 0021 #define CHARACTERCOLOR_H 0022 0023 // Qt 0024 #include <QColor> 0025 #include <span> 0026 0027 // #include <kdemacros.h> 0028 #define KDE_NO_EXPORT 0029 0030 namespace Konsole 0031 { 0032 0033 /** 0034 * An entry in a terminal display's color palette. 0035 * 0036 * A color palette is an array of 16 ColorEntry instances which map 0037 * system color indexes (from 0 to 15) into actual colors. 0038 * 0039 * Each entry can be set as bold, in which case any text 0040 * drawn using the color should be drawn in bold. 0041 * 0042 * Each entry can also be transparent, in which case the terminal 0043 * display should avoid drawing the background for any characters 0044 * using the entry as a background. 0045 */ 0046 class ColorEntry 0047 { 0048 public: 0049 /** Specifies the weight to use when drawing text with this color. */ 0050 enum FontWeight { 0051 /** Always draw text in this color with a bold weight. */ 0052 Bold, 0053 /** Always draw text in this color with a normal weight. */ 0054 Normal, 0055 /** 0056 * Use the current font weight set by the terminal application. 0057 * This is the default behavior. 0058 */ 0059 UseCurrentFormat 0060 }; 0061 0062 /** 0063 * Constructs a new color palette entry. 0064 * 0065 * @param c The color value for this entry. 0066 * @param tr Specifies that the color should be transparent when used as a background color. 0067 * @param weight Specifies the font weight to use when drawing text with this color. 0068 */ 0069 constexpr ColorEntry(QColor c, bool tr, FontWeight weight = UseCurrentFormat) 0070 : color(c) 0071 , transparent(tr) 0072 , fontWeight(weight) 0073 { 0074 } 0075 0076 /** 0077 * Constructs a new color palette entry with an undefined color, and 0078 * with the transparent and bold flags set to false. 0079 */ 0080 ColorEntry() 0081 : transparent(false) 0082 , fontWeight(UseCurrentFormat) 0083 { 0084 } 0085 0086 /** The color value of this entry for display. */ 0087 QColor color; 0088 0089 /** 0090 * If true character backgrounds using this color should be transparent. 0091 * This is not applicable when the color is used to render text. 0092 */ 0093 bool transparent; 0094 /** 0095 * Specifies the font weight to use when drawing text with this color. 0096 * This is not applicable when the color is used to draw a character's background. 0097 */ 0098 FontWeight fontWeight; 0099 }; 0100 0101 // Attributed Character Representations /////////////////////////////// 0102 0103 // Colors 0104 0105 constexpr auto BASE_COLORS = (2 + 8); 0106 constexpr auto INTENSITIES = 2; 0107 constexpr auto TABLE_COLORS = (INTENSITIES * BASE_COLORS); 0108 0109 constexpr auto DEFAULT_FORE_COLOR = 0; 0110 constexpr auto DEFAULT_BACK_COLOR = 1; 0111 0112 // a standard set of colors using black text on a white background. 0113 // defined in TerminalDisplay.cpp 0114 0115 /* CharacterColor is a union of the various color spaces. 0116 0117 Assignment is as follows: 0118 0119 Type - Space - Values 0120 0121 0 - Undefined - u: 0, v:0 w:0 0122 1 - Default - u: 0..1 v:intense w:0 0123 2 - System - u: 0..7 v:intense w:0 0124 3 - Index(256) - u: 16..255 v:0 w:0 0125 4 - RGB - u: 0..255 v:0..256 w:0..256 0126 0127 Default colour space has two separate colours, namely 0128 default foreground and default background colour. 0129 */ 0130 0131 #define COLOR_SPACE_UNDEFINED 0 0132 #define COLOR_SPACE_DEFAULT 1 0133 #define COLOR_SPACE_SYSTEM 2 0134 #define COLOR_SPACE_256 3 0135 #define COLOR_SPACE_RGB 4 0136 0137 /** 0138 * Describes the color of a single character in the terminal. 0139 */ 0140 class CharacterColor 0141 { 0142 friend class Character; 0143 0144 public: 0145 /** Constructs a new CharacterColor whoose color and color space are undefined. */ 0146 constexpr CharacterColor() 0147 : _colorSpace(COLOR_SPACE_UNDEFINED) 0148 , _u(0) 0149 , _v(0) 0150 , _w(0) 0151 { 0152 } 0153 0154 /** 0155 * Constructs a new CharacterColor using the specified @p colorSpace and with 0156 * color value @p co 0157 * 0158 * The meaning of @p co depends on the @p colorSpace used. 0159 * 0160 * TODO : Document how @p co relates to @p colorSpace 0161 * 0162 * TODO : Add documentation about available color spaces. 0163 */ 0164 constexpr CharacterColor(quint8 colorSpace, int co) 0165 : _colorSpace(colorSpace) 0166 , _u(0) 0167 , _v(0) 0168 , _w(0) 0169 { 0170 switch (colorSpace) { 0171 case COLOR_SPACE_DEFAULT: 0172 _u = co & 1; 0173 break; 0174 case COLOR_SPACE_SYSTEM: 0175 _u = co & 7; 0176 _v = (co >> 3) & 1; 0177 break; 0178 case COLOR_SPACE_256: 0179 _u = co & 255; 0180 break; 0181 case COLOR_SPACE_RGB: 0182 _u = co >> 16; 0183 _v = co >> 8; 0184 _w = co; 0185 break; 0186 default: 0187 _colorSpace = COLOR_SPACE_UNDEFINED; 0188 } 0189 } 0190 0191 /** 0192 * Returns true if this character color entry is valid. 0193 */ 0194 constexpr bool isValid() const 0195 { 0196 return _colorSpace != COLOR_SPACE_UNDEFINED; 0197 } 0198 0199 /** 0200 * Set the value of this color from a normal system color to the corresponding intensive 0201 * system color if it's not already an intensive system color. 0202 * 0203 * This is only applicable if the color is using the COLOR_SPACE_DEFAULT or COLOR_SPACE_SYSTEM 0204 * color spaces. 0205 */ 0206 void setIntensive(); 0207 0208 /** 0209 * Returns the color within the specified color @p palette 0210 * 0211 * The @p palette is only used if this color is one of the 16 system colors, otherwise 0212 * it is ignored. 0213 */ 0214 constexpr QColor color(std::span<const ColorEntry> palette) const; 0215 0216 /** 0217 * Compares two colors and returns true if they represent the same color value and 0218 * use the same color space. 0219 */ 0220 constexpr friend bool operator==(const CharacterColor &a, const CharacterColor &b); 0221 /** 0222 * Compares two colors and returns true if they represent different color values 0223 * or use different color spaces. 0224 */ 0225 constexpr friend bool operator!=(const CharacterColor &a, const CharacterColor &b); 0226 0227 private: 0228 quint8 _colorSpace; 0229 0230 // bytes storing the character color 0231 quint8 _u; 0232 quint8 _v; 0233 quint8 _w; 0234 }; 0235 0236 constexpr inline bool operator==(const CharacterColor &a, const CharacterColor &b) 0237 { 0238 return a._colorSpace == b._colorSpace && a._u == b._u && a._v == b._v && a._w == b._w; 0239 } 0240 0241 constexpr inline bool operator!=(const CharacterColor &a, const CharacterColor &b) 0242 { 0243 return !operator==(a, b); 0244 } 0245 0246 constexpr inline const QColor color256(quint8 u, std::span<const ColorEntry> base) 0247 { 0248 // 0.. 16: system colors 0249 if (u < 8) 0250 return base[u + 2].color; 0251 u -= 8; 0252 if (u < 8) 0253 return base[u + 2 + BASE_COLORS].color; 0254 u -= 8; 0255 0256 // 16..231: 6x6x6 rgb color cube 0257 if (u < 216) 0258 return QColor(((u / 36) % 6) ? (40 * ((u / 36) % 6) + 55) : 0, 0259 ((u / 6) % 6) ? (40 * ((u / 6) % 6) + 55) : 0, 0260 ((u / 1) % 6) ? (40 * ((u / 1) % 6) + 55) : 0); 0261 u -= 216; 0262 0263 // 232..255: gray, leaving out black and white 0264 int gray = u * 10 + 8; 0265 return QColor(gray, gray, gray); 0266 } 0267 0268 constexpr inline QColor CharacterColor::color(std::span<const ColorEntry> base) const 0269 { 0270 switch (_colorSpace) { 0271 case COLOR_SPACE_DEFAULT: 0272 return base[_u + 0 + (_v ? BASE_COLORS : 0)].color; 0273 case COLOR_SPACE_SYSTEM: 0274 return base[_u + 2 + (_v ? BASE_COLORS : 0)].color; 0275 case COLOR_SPACE_256: 0276 return color256(_u, base); 0277 case COLOR_SPACE_RGB: 0278 return {_u, _v, _w}; 0279 case COLOR_SPACE_UNDEFINED: 0280 return QColor(); 0281 } 0282 0283 Q_ASSERT(false); // invalid color space 0284 0285 return QColor(); 0286 } 0287 0288 inline void CharacterColor::setIntensive() 0289 { 0290 if (_colorSpace == COLOR_SPACE_SYSTEM || _colorSpace == COLOR_SPACE_DEFAULT) { 0291 _v = 1; 0292 } 0293 } 0294 } 0295 0296 #endif // CHARACTERCOLOR_H