1 | /* |
2 | This file is part of Konsole, KDE's terminal. |
3 | |
4 | Copyright 2007-2008 by Robert Knight <robertknight@gmail.com> |
5 | Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de> |
6 | |
7 | This program is free software; you can redistribute it and/or modify |
8 | it under the terms of the GNU General Public License as published by |
9 | the Free Software Foundation; either version 2 of the License, or |
10 | (at your option) any later version. |
11 | |
12 | This program is distributed in the hope that it will be useful, |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | GNU General Public License for more details. |
16 | |
17 | You should have received a copy of the GNU General Public License |
18 | along with this program; if not, write to the Free Software |
19 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
20 | 02110-1301 USA. |
21 | */ |
22 | |
23 | #ifndef CHARACTERCOLOR_H |
24 | #define CHARACTERCOLOR_H |
25 | |
26 | // Qt |
27 | #include <QColor> |
28 | |
29 | //#include <kdemacros.h> |
30 | #define KDE_NO_EXPORT |
31 | |
32 | namespace Konsole |
33 | { |
34 | |
35 | /** |
36 | * An entry in a terminal display's color palette. |
37 | * |
38 | * A color palette is an array of 16 ColorEntry instances which map |
39 | * system color indexes (from 0 to 15) into actual colors. |
40 | * |
41 | * Each entry can be set as bold, in which case any text |
42 | * drawn using the color should be drawn in bold. |
43 | * |
44 | * Each entry can also be transparent, in which case the terminal |
45 | * display should avoid drawing the background for any characters |
46 | * using the entry as a background. |
47 | */ |
48 | class ColorEntry |
49 | { |
50 | public: |
51 | /** Specifies the weight to use when drawing text with this color. */ |
52 | enum FontWeight |
53 | { |
54 | /** Always draw text in this color with a bold weight. */ |
55 | Bold, |
56 | /** Always draw text in this color with a normal weight. */ |
57 | Normal, |
58 | /** |
59 | * Use the current font weight set by the terminal application. |
60 | * This is the default behavior. |
61 | */ |
62 | UseCurrentFormat |
63 | }; |
64 | |
65 | /** |
66 | * Constructs a new color palette entry. |
67 | * |
68 | * @param c The color value for this entry. |
69 | * @param tr Specifies that the color should be transparent when used as a background color. |
70 | * @param weight Specifies the font weight to use when drawing text with this color. |
71 | */ |
72 | ColorEntry(QColor c, bool tr, FontWeight weight = UseCurrentFormat) |
73 | : color(c), transparent(tr), fontWeight(weight) {} |
74 | |
75 | /** |
76 | * Constructs a new color palette entry with an undefined color, and |
77 | * with the transparent and bold flags set to false. |
78 | */ |
79 | ColorEntry() : transparent(false), fontWeight(UseCurrentFormat) {} |
80 | |
81 | /** |
82 | * Sets the color, transparency and boldness of this color to those of @p rhs. |
83 | */ |
84 | void operator=(const ColorEntry& rhs) |
85 | { |
86 | color = rhs.color; |
87 | transparent = rhs.transparent; |
88 | fontWeight = rhs.fontWeight; |
89 | } |
90 | |
91 | /** The color value of this entry for display. */ |
92 | QColor color; |
93 | |
94 | /** |
95 | * If true character backgrounds using this color should be transparent. |
96 | * This is not applicable when the color is used to render text. |
97 | */ |
98 | bool transparent; |
99 | /** |
100 | * Specifies the font weight to use when drawing text with this color. |
101 | * This is not applicable when the color is used to draw a character's background. |
102 | */ |
103 | FontWeight fontWeight; |
104 | }; |
105 | |
106 | |
107 | // Attributed Character Representations /////////////////////////////// |
108 | |
109 | // Colors |
110 | |
111 | #define BASE_COLORS (2+8) |
112 | #define INTENSITIES 2 |
113 | #define TABLE_COLORS (INTENSITIES*BASE_COLORS) |
114 | |
115 | #define DEFAULT_FORE_COLOR 0 |
116 | #define DEFAULT_BACK_COLOR 1 |
117 | |
118 | //a standard set of colors using black text on a white background. |
119 | //defined in TerminalDisplay.cpp |
120 | |
121 | extern const ColorEntry base_color_table[TABLE_COLORS] KDE_NO_EXPORT; |
122 | |
123 | /* CharacterColor is a union of the various color spaces. |
124 | |
125 | Assignment is as follows: |
126 | |
127 | Type - Space - Values |
128 | |
129 | 0 - Undefined - u: 0, v:0 w:0 |
130 | 1 - Default - u: 0..1 v:intense w:0 |
131 | 2 - System - u: 0..7 v:intense w:0 |
132 | 3 - Index(256) - u: 16..255 v:0 w:0 |
133 | 4 - RGB - u: 0..255 v:0..256 w:0..256 |
134 | |
135 | Default colour space has two separate colours, namely |
136 | default foreground and default background colour. |
137 | */ |
138 | |
139 | #define COLOR_SPACE_UNDEFINED 0 |
140 | #define COLOR_SPACE_DEFAULT 1 |
141 | #define COLOR_SPACE_SYSTEM 2 |
142 | #define COLOR_SPACE_256 3 |
143 | #define COLOR_SPACE_RGB 4 |
144 | |
145 | /** |
146 | * Describes the color of a single character in the terminal. |
147 | */ |
148 | class CharacterColor |
149 | { |
150 | friend class Character; |
151 | |
152 | public: |
153 | /** Constructs a new CharacterColor whoose color and color space are undefined. */ |
154 | CharacterColor() |
155 | : _colorSpace(COLOR_SPACE_UNDEFINED), |
156 | _u(0), |
157 | _v(0), |
158 | _w(0) |
159 | {} |
160 | |
161 | /** |
162 | * Constructs a new CharacterColor using the specified @p colorSpace and with |
163 | * color value @p co |
164 | * |
165 | * The meaning of @p co depends on the @p colorSpace used. |
166 | * |
167 | * TODO : Document how @p co relates to @p colorSpace |
168 | * |
169 | * TODO : Add documentation about available color spaces. |
170 | */ |
171 | CharacterColor(quint8 colorSpace, int co) |
172 | : _colorSpace(colorSpace), |
173 | _u(0), |
174 | _v(0), |
175 | _w(0) |
176 | { |
177 | switch (colorSpace) |
178 | { |
179 | case COLOR_SPACE_DEFAULT: |
180 | _u = co & 1; |
181 | break; |
182 | case COLOR_SPACE_SYSTEM: |
183 | _u = co & 7; |
184 | _v = (co >> 3) & 1; |
185 | break; |
186 | case COLOR_SPACE_256: |
187 | _u = co & 255; |
188 | break; |
189 | case COLOR_SPACE_RGB: |
190 | _u = co >> 16; |
191 | _v = co >> 8; |
192 | _w = co; |
193 | break; |
194 | default: |
195 | _colorSpace = COLOR_SPACE_UNDEFINED; |
196 | } |
197 | } |
198 | |
199 | /** |
200 | * Returns true if this character color entry is valid. |
201 | */ |
202 | bool isValid() const |
203 | { |
204 | return _colorSpace != COLOR_SPACE_UNDEFINED; |
205 | } |
206 | |
207 | /** |
208 | * Set the value of this color from a normal system color to the corresponding intensive |
209 | * system color if it's not already an intensive system color. |
210 | * |
211 | * This is only applicable if the color is using the COLOR_SPACE_DEFAULT or COLOR_SPACE_SYSTEM |
212 | * color spaces. |
213 | */ |
214 | void setIntensive(); |
215 | |
216 | /** |
217 | * Returns the color within the specified color @p palette |
218 | * |
219 | * The @p palette is only used if this color is one of the 16 system colors, otherwise |
220 | * it is ignored. |
221 | */ |
222 | QColor color(const ColorEntry* palette) const; |
223 | |
224 | /** |
225 | * Compares two colors and returns true if they represent the same color value and |
226 | * use the same color space. |
227 | */ |
228 | friend bool operator == (const CharacterColor& a, const CharacterColor& b); |
229 | /** |
230 | * Compares two colors and returns true if they represent different color values |
231 | * or use different color spaces. |
232 | */ |
233 | friend bool operator != (const CharacterColor& a, const CharacterColor& b); |
234 | |
235 | private: |
236 | quint8 _colorSpace; |
237 | |
238 | // bytes storing the character color |
239 | quint8 _u; |
240 | quint8 _v; |
241 | quint8 _w; |
242 | }; |
243 | |
244 | inline bool operator == (const CharacterColor& a, const CharacterColor& b) |
245 | { |
246 | return a._colorSpace == b._colorSpace && |
247 | a._u == b._u && |
248 | a._v == b._v && |
249 | a._w == b._w; |
250 | } |
251 | inline bool operator != (const CharacterColor& a, const CharacterColor& b) |
252 | { |
253 | return !operator==(a,b); |
254 | } |
255 | |
256 | inline const QColor color256(quint8 u, const ColorEntry* base) |
257 | { |
258 | // 0.. 16: system colors |
259 | if (u < 8) return base[u+2 ].color; |
260 | u -= 8; |
261 | if (u < 8) return base[u+2+BASE_COLORS].color; |
262 | u -= 8; |
263 | |
264 | // 16..231: 6x6x6 rgb color cube |
265 | if (u < 216) return QColor(((u/36)%6) ? (40*((u/36)%6)+55) : 0, |
266 | ((u/ 6)%6) ? (40*((u/ 6)%6)+55) : 0, |
267 | ((u/ 1)%6) ? (40*((u/ 1)%6)+55) : 0); |
268 | u -= 216; |
269 | |
270 | // 232..255: gray, leaving out black and white |
271 | int gray = u*10+8; return QColor(gray,gray,gray); |
272 | } |
273 | |
274 | inline QColor CharacterColor::color(const ColorEntry* base) const |
275 | { |
276 | switch (_colorSpace) |
277 | { |
278 | case COLOR_SPACE_DEFAULT: return base[_u+0+(_v?BASE_COLORS:0)].color; |
279 | case COLOR_SPACE_SYSTEM: return base[_u+2+(_v?BASE_COLORS:0)].color; |
280 | case COLOR_SPACE_256: return color256(_u,base); |
281 | case COLOR_SPACE_RGB: return QColor(_u,_v,_w); |
282 | case COLOR_SPACE_UNDEFINED: return QColor(); |
283 | } |
284 | |
285 | Q_ASSERT(false); // invalid color space |
286 | |
287 | return QColor(); |
288 | } |
289 | |
290 | inline void CharacterColor::setIntensive() |
291 | { |
292 | if (_colorSpace == COLOR_SPACE_SYSTEM || _colorSpace == COLOR_SPACE_DEFAULT) |
293 | { |
294 | _v = 1; |
295 | } |
296 | } |
297 | |
298 | |
299 | } |
300 | |
301 | #endif // CHARACTERCOLOR_H |
302 | |
303 | |