File indexing completed on 2025-01-19 04:23:24

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