summaryrefslogtreecommitdiff
path: root/qtermwidget/Character.h
blob: 0978ce5da0a8145ac42d107cc0edc4b4fa7c9b4c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/*
    This file is part of Konsole, KDE's terminal.
    
    Copyright (C) 2007 by Robert Knight <robertknight@gmail.com>
    Copyright (C) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>

    Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301  USA.
*/

#ifndef CHARACTER_H
#define CHARACTER_H

// Qt
#include <QtCore/QHash>

// Local
#include "CharacterColor.h"

namespace Konsole
{

typedef unsigned char LineProperty;

static const int LINE_DEFAULT		= 0;
static const int LINE_WRAPPED 	 	= (1 << 0);
static const int LINE_DOUBLEWIDTH  	= (1 << 1);
static const int LINE_DOUBLEHEIGHT	= (1 << 2);

#define DEFAULT_RENDITION  0
#define RE_BOLD            (1 << 0)
#define RE_BLINK           (1 << 1)
#define RE_UNDERLINE       (1 << 2)
#define RE_REVERSE         (1 << 3) // Screen only
#define RE_INTENSIVE       (1 << 3) // Widget only
#define RE_CURSOR          (1 << 4)
#define RE_EXTENDED_CHAR   (1 << 5)

/**
 * A single character in the terminal which consists of a unicode character
 * value, foreground and background colors and a set of rendition attributes
 * which specify how it should be drawn.
 */
class Character
{
public:
  /** 
   * Constructs a new character.
   *
   * @param _c The unicode character value of this character.
   * @param _f The foreground color used to draw the character.
   * @param _b The color used to draw the character's background.
   * @param _r A set of rendition flags which specify how this character is to be drawn.
   */
  inline Character(quint16 _c = ' ',
            CharacterColor  _f = CharacterColor(COLOR_SPACE_DEFAULT,DEFAULT_FORE_COLOR),
            CharacterColor  _b = CharacterColor(COLOR_SPACE_DEFAULT,DEFAULT_BACK_COLOR),
            quint8  _r = DEFAULT_RENDITION)
       : character(_c), rendition(_r), foregroundColor(_f), backgroundColor(_b) {}

  union
  {
    /** The unicode character value for this character. */
    quint16 character;
    /** 
     * Experimental addition which allows a single Character instance to contain more than
     * one unicode character.
     *
     * charSequence is a hash code which can be used to look up the unicode
     * character sequence in the ExtendedCharTable used to create the sequence.
     */
    quint16 charSequence; 
  };

  /** A combination of RENDITION flags which specify options for drawing the character. */
  quint8  rendition;

  /** The foreground color used to draw this character. */
  CharacterColor  foregroundColor; 
  /** The color used to draw this character's background. */
  CharacterColor  backgroundColor;

  /** 
   * Returns true if this character has a transparent background when
   * it is drawn with the specified @p palette.
   */
  bool   isTransparent(const ColorEntry* palette) const;
  /**
   * Returns true if this character should always be drawn in bold when
   * it is drawn with the specified @p palette, independent of whether
   * or not the character has the RE_BOLD rendition flag. 
   */
  bool   isBold(const ColorEntry* base) const;
  
  /** 
   * Compares two characters and returns true if they have the same unicode character value,
   * rendition and colors.
   */
  friend bool operator == (const Character& a, const Character& b);
  /**
   * Compares two characters and returns true if they have different unicode character values,
   * renditions or colors.
   */
  friend bool operator != (const Character& a, const Character& b);
};

inline bool operator == (const Character& a, const Character& b)
{ 
  return a.character == b.character && 
         a.rendition == b.rendition && 
         a.foregroundColor == b.foregroundColor && 
         a.backgroundColor == b.backgroundColor;
}

inline bool operator != (const Character& a, const Character& b)
{
  return    a.character != b.character || 
            a.rendition != b.rendition || 
            a.foregroundColor != b.foregroundColor || 
            a.backgroundColor != b.backgroundColor;
}

inline bool Character::isTransparent(const ColorEntry* base) const
{
  return ((backgroundColor._colorSpace == COLOR_SPACE_DEFAULT) && 
          base[backgroundColor._u+0+(backgroundColor._v?BASE_COLORS:0)].transparent)
      || ((backgroundColor._colorSpace == COLOR_SPACE_SYSTEM) && 
          base[backgroundColor._u+2+(backgroundColor._v?BASE_COLORS:0)].transparent);
}

inline bool Character::isBold(const ColorEntry* base) const
{
  return ((backgroundColor._colorSpace == COLOR_SPACE_DEFAULT) &&
            base[backgroundColor._u+0+(backgroundColor._v?BASE_COLORS:0)].bold)
      || ((backgroundColor._colorSpace == COLOR_SPACE_SYSTEM) &&
            base[backgroundColor._u+2+(backgroundColor._v?BASE_COLORS:0)].bold);
}

extern unsigned short vt100_graphics[32];


/**
 * A table which stores sequences of unicode characters, referenced
 * by hash keys.  The hash key itself is the same size as a unicode
 * character ( ushort ) so that it can occupy the same space in
 * a structure.
 */
class ExtendedCharTable
{
public:
    /** Constructs a new character table. */
    ExtendedCharTable();
    ~ExtendedCharTable();

    /**
     * Adds a sequences of unicode characters to the table and returns
     * a hash code which can be used later to look up the sequence
     * using lookupExtendedChar()
     *
     * If the same sequence already exists in the table, the hash
     * of the existing sequence will be returned.
     *
     * @param unicodePoints An array of unicode character points
     * @param length Length of @p unicodePoints
     */
    ushort createExtendedChar(ushort* unicodePoints , ushort length);
    /**
     * Looks up and returns a pointer to a sequence of unicode characters
     * which was added to the table using createExtendedChar().
     *
     * @param hash The hash key returned by createExtendedChar()
     * @param length This variable is set to the length of the 
     * character sequence.
     *
     * @return A unicode character sequence of size @p length.
     */
    ushort* lookupExtendedChar(ushort hash , ushort& length) const;

    /** The global ExtendedCharTable instance. */
    static ExtendedCharTable instance;
private:
    // calculates the hash key of a sequence of unicode points of size 'length'
    ushort extendedCharHash(ushort* unicodePoints , ushort length) const;
    // tests whether the entry in the table specified by 'hash' matches the 
    // character sequence 'unicodePoints' of size 'length'
    bool extendedCharMatch(ushort hash , ushort* unicodePoints , ushort length) const;
    // internal, maps hash keys to character sequence buffers.  The first ushort
    // in each value is the length of the buffer, followed by the ushorts in the buffer
    // themselves.
    QHash<ushort,ushort*> extendedCharTable;
};

}

#endif // CHARACTER_H