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 CHARACTER_H
24#define CHARACTER_H
25
26// Qt
27#include <QHash>
28
29// Local
30#include "CharacterColor.h"
31
32namespace Konsole
33{
34
35typedef unsigned char LineProperty;
36
37static const int LINE_DEFAULT = 0;
38static const int LINE_WRAPPED = (1 << 0);
39static const int LINE_DOUBLEWIDTH = (1 << 1);
40static const int LINE_DOUBLEHEIGHT = (1 << 2);
41
42#define DEFAULT_RENDITION 0
43#define RE_BOLD (1 << 0)
44#define RE_BLINK (1 << 1)
45#define RE_UNDERLINE (1 << 2)
46#define RE_REVERSE (1 << 3) // Screen only
47#define RE_INTENSIVE (1 << 3) // Widget only
48#define RE_ITALIC (1 << 4)
49#define RE_CURSOR (1 << 5)
50#define RE_EXTENDED_CHAR (1 << 6)
51#define RE_FAINT (1 << 7)
52#define RE_STRIKEOUT (1 << 8)
53#define RE_CONCEAL (1 << 9)
54#define RE_OVERLINE (1 << 10)
55
56/**
57 * A single character in the terminal which consists of a unicode character
58 * value, foreground and background colors and a set of rendition attributes
59 * which specify how it should be drawn.
60 */
61class Character
62{
63public:
64 /**
65 * Constructs a new character.
66 *
67 * @param _c The unicode character value of this character.
68 * @param _f The foreground color used to draw the character.
69 * @param _b The color used to draw the character's background.
70 * @param _r A set of rendition flags which specify how this character is to be drawn.
71 */
72 inline Character(quint16 _c = ' ',
73 CharacterColor _f = CharacterColor(COLOR_SPACE_DEFAULT,DEFAULT_FORE_COLOR),
74 CharacterColor _b = CharacterColor(COLOR_SPACE_DEFAULT,DEFAULT_BACK_COLOR),
75 quint8 _r = DEFAULT_RENDITION)
76 : character(_c), rendition(_r), foregroundColor(_f), backgroundColor(_b) {}
77
78 union
79 {
80 /** The unicode character value for this character. */
81 wchar_t character;
82 /**
83 * Experimental addition which allows a single Character instance to contain more than
84 * one unicode character.
85 *
86 * charSequence is a hash code which can be used to look up the unicode
87 * character sequence in the ExtendedCharTable used to create the sequence.
88 */
89 quint16 charSequence;
90 };
91
92 /** A combination of RENDITION flags which specify options for drawing the character. */
93 quint8 rendition;
94
95 /** The foreground color used to draw this character. */
96 CharacterColor foregroundColor;
97 /** The color used to draw this character's background. */
98 CharacterColor backgroundColor;
99
100 /**
101 * Returns true if this character has a transparent background when
102 * it is drawn with the specified @p palette.
103 */
104 bool isTransparent(const ColorEntry* palette) const;
105 /**
106 * Returns true if this character should always be drawn in bold when
107 * it is drawn with the specified @p palette, independent of whether
108 * or not the character has the RE_BOLD rendition flag.
109 */
110 ColorEntry::FontWeight fontWeight(const ColorEntry* base) const;
111
112 /**
113 * returns true if the format (color, rendition flag) of the compared characters is equal
114 */
115 bool equalsFormat(const Character &other) const;
116
117 /**
118 * Compares two characters and returns true if they have the same unicode character value,
119 * rendition and colors.
120 */
121 friend bool operator == (const Character& a, const Character& b);
122 /**
123 * Compares two characters and returns true if they have different unicode character values,
124 * renditions or colors.
125 */
126 friend bool operator != (const Character& a, const Character& b);
127};
128
129inline bool operator == (const Character& a, const Character& b)
130{
131 return a.character == b.character &&
132 a.rendition == b.rendition &&
133 a.foregroundColor == b.foregroundColor &&
134 a.backgroundColor == b.backgroundColor;
135}
136
137inline bool operator != (const Character& a, const Character& b)
138{
139 return a.character != b.character ||
140 a.rendition != b.rendition ||
141 a.foregroundColor != b.foregroundColor ||
142 a.backgroundColor != b.backgroundColor;
143}
144
145inline bool Character::isTransparent(const ColorEntry* base) const
146{
147 return ((backgroundColor._colorSpace == COLOR_SPACE_DEFAULT) &&
148 base[backgroundColor._u+0+(backgroundColor._v?BASE_COLORS:0)].transparent)
149 || ((backgroundColor._colorSpace == COLOR_SPACE_SYSTEM) &&
150 base[backgroundColor._u+2+(backgroundColor._v?BASE_COLORS:0)].transparent);
151}
152
153inline bool Character::equalsFormat(const Character& other) const
154{
155 return
156 backgroundColor==other.backgroundColor &&
157 foregroundColor==other.foregroundColor &&
158 rendition==other.rendition;
159}
160
161inline ColorEntry::FontWeight Character::fontWeight(const ColorEntry* base) const
162{
163 if (backgroundColor._colorSpace == COLOR_SPACE_DEFAULT)
164 return base[backgroundColor._u+0+(backgroundColor._v?BASE_COLORS:0)].fontWeight;
165 else if (backgroundColor._colorSpace == COLOR_SPACE_SYSTEM)
166 return base[backgroundColor._u+2+(backgroundColor._v?BASE_COLORS:0)].fontWeight;
167 else
168 return ColorEntry::UseCurrentFormat;
169}
170
171extern unsigned short vt100_graphics[32];
172
173
174/**
175 * A table which stores sequences of unicode characters, referenced
176 * by hash keys. The hash key itself is the same size as a unicode
177 * character ( ushort ) so that it can occupy the same space in
178 * a structure.
179 */
180class ExtendedCharTable
181{
182public:
183 /** Constructs a new character table. */
184 ExtendedCharTable();
185 ~ExtendedCharTable();
186
187 /**
188 * Adds a sequences of unicode characters to the table and returns
189 * a hash code which can be used later to look up the sequence
190 * using lookupExtendedChar()
191 *
192 * If the same sequence already exists in the table, the hash
193 * of the existing sequence will be returned.
194 *
195 * @param unicodePoints An array of unicode character points
196 * @param length Length of @p unicodePoints
197 */
198 ushort createExtendedChar(ushort* unicodePoints , ushort length);
199 /**
200 * Looks up and returns a pointer to a sequence of unicode characters
201 * which was added to the table using createExtendedChar().
202 *
203 * @param hash The hash key returned by createExtendedChar()
204 * @param length This variable is set to the length of the
205 * character sequence.
206 *
207 * @return A unicode character sequence of size @p length.
208 */
209 ushort* lookupExtendedChar(ushort hash , ushort& length) const;
210
211 /** The global ExtendedCharTable instance. */
212 static ExtendedCharTable instance;
213private:
214 // calculates the hash key of a sequence of unicode points of size 'length'
215 ushort extendedCharHash(ushort* unicodePoints , ushort length) const;
216 // tests whether the entry in the table specified by 'hash' matches the
217 // character sequence 'unicodePoints' of size 'length'
218 bool extendedCharMatch(ushort hash , ushort* unicodePoints , ushort length) const;
219 // internal, maps hash keys to character sequence buffers. The first ushort
220 // in each value is the length of the buffer, followed by the ushorts in the buffer
221 // themselves.
222 QHash<ushort,ushort*> extendedCharTable;
223};
224
225}
226Q_DECLARE_TYPEINFO(Konsole::Character, Q_MOVABLE_TYPE);
227
228#endif // CHARACTER_H
229
230