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 CHARACTER_H
0024 #define CHARACTER_H
0025 
0026 // Qt
0027 #include <QHash>
0028 
0029 // Local
0030 #include "CharacterColor.h"
0031 
0032 namespace Konsole
0033 {
0034 
0035 typedef unsigned char LineProperty;
0036 typedef quint16 RenditionFlags;
0037 
0038 static const int LINE_DEFAULT        = 0;
0039 static const int LINE_WRAPPED          = (1 << 0);
0040 static const int LINE_DOUBLEWIDTH      = (1 << 1);
0041 static const int LINE_DOUBLEHEIGHT    = (1 << 2);
0042 
0043 const RenditionFlags DEFAULT_RENDITION  = 0;
0044 const RenditionFlags RE_BOLD            = (1 << 0);
0045 const RenditionFlags RE_BLINK           = (1 << 1);
0046 const RenditionFlags RE_UNDERLINE       = (1 << 2);
0047 const RenditionFlags RE_REVERSE         = (1 << 3); // Screen only
0048 const RenditionFlags RE_INTENSIVE       = (1 << 3); // Widget only
0049 const RenditionFlags RE_ITALIC          = (1 << 4);
0050 const RenditionFlags RE_CURSOR          = (1 << 5);
0051 const RenditionFlags RE_EXTENDED_CHAR   = (1 << 6);
0052 const RenditionFlags RE_FAINT           = (1 << 7);
0053 const RenditionFlags RE_STRIKEOUT       = (1 << 8);
0054 const RenditionFlags RE_CONCEAL         = (1 << 9);
0055 const RenditionFlags RE_OVERLINE        = (1 << 10);
0056 
0057 /**
0058  * A single character in the terminal which consists of a unicode character
0059  * value, foreground and background colors and a set of rendition attributes
0060  * which specify how it should be drawn.
0061  */
0062 class Character
0063 {
0064 public:
0065   /**
0066    * Constructs a new character.
0067    *
0068    * @param _c The unicode character value of this character.
0069    * @param _f The foreground color used to draw the character.
0070    * @param _b The color used to draw the character's background.
0071    * @param _r A set of rendition flags which specify how this character is to be drawn.
0072    */
0073   inline Character(quint16 _c = ' ',
0074             CharacterColor  _f = CharacterColor(COLOR_SPACE_DEFAULT,DEFAULT_FORE_COLOR),
0075             CharacterColor  _b = CharacterColor(COLOR_SPACE_DEFAULT,DEFAULT_BACK_COLOR),
0076             RenditionFlags  _r = DEFAULT_RENDITION)
0077        : character(_c), rendition(_r), foregroundColor(_f), backgroundColor(_b) {}
0078 
0079   union
0080   {
0081     /** The unicode character value for this character. */
0082     wchar_t character;
0083     /**
0084      * Experimental addition which allows a single Character instance to contain more than
0085      * one unicode character.
0086      *
0087      * charSequence is a hash code which can be used to look up the unicode
0088      * character sequence in the ExtendedCharTable used to create the sequence.
0089      */
0090     quint16 charSequence;
0091   };
0092 
0093   /** A combination of RENDITION flags which specify options for drawing the character. */
0094   RenditionFlags  rendition;
0095 
0096   /** The foreground color used to draw this character. */
0097   CharacterColor  foregroundColor;
0098   /** The color used to draw this character's background. */
0099   CharacterColor  backgroundColor;
0100 
0101   /**
0102    * Returns true if this character has a transparent background when
0103    * it is drawn with the specified @p palette.
0104    */
0105   bool   isTransparent(const ColorEntry* palette) const;
0106   /**
0107    * Returns true if this character should always be drawn in bold when
0108    * it is drawn with the specified @p palette, independent of whether
0109    * or not the character has the RE_BOLD rendition flag.
0110    */
0111   ColorEntry::FontWeight fontWeight(const ColorEntry* base) const;
0112 
0113   /**
0114    * returns true if the format (color, rendition flag) of the compared characters is equal
0115    */
0116   bool equalsFormat(const Character &other) const;
0117 
0118   /**
0119    * Compares two characters and returns true if they have the same unicode character value,
0120    * rendition and colors.
0121    */
0122   friend bool operator == (const Character& a, const Character& b);
0123   /**
0124    * Compares two characters and returns true if they have different unicode character values,
0125    * renditions or colors.
0126    */
0127   friend bool operator != (const Character& a, const Character& b);
0128 };
0129 
0130 inline bool operator == (const Character& a, const Character& b)
0131 {
0132   return a.character == b.character &&
0133          a.rendition == b.rendition &&
0134          a.foregroundColor == b.foregroundColor &&
0135          a.backgroundColor == b.backgroundColor;
0136 }
0137 
0138 inline bool operator != (const Character& a, const Character& b)
0139 {
0140   return    a.character != b.character ||
0141             a.rendition != b.rendition ||
0142             a.foregroundColor != b.foregroundColor ||
0143             a.backgroundColor != b.backgroundColor;
0144 }
0145 
0146 inline bool Character::isTransparent(const ColorEntry* base) const
0147 {
0148   return ((backgroundColor._colorSpace == COLOR_SPACE_DEFAULT) &&
0149           base[backgroundColor._u+0+(backgroundColor._v?BASE_COLORS:0)].transparent)
0150       || ((backgroundColor._colorSpace == COLOR_SPACE_SYSTEM) &&
0151           base[backgroundColor._u+2+(backgroundColor._v?BASE_COLORS:0)].transparent);
0152 }
0153 
0154 inline bool Character::equalsFormat(const Character& other) const
0155 {
0156   return
0157     backgroundColor==other.backgroundColor &&
0158     foregroundColor==other.foregroundColor &&
0159     rendition==other.rendition;
0160 }
0161 
0162 inline ColorEntry::FontWeight Character::fontWeight(const ColorEntry* base) const
0163 {
0164     if (backgroundColor._colorSpace == COLOR_SPACE_DEFAULT)
0165         return base[backgroundColor._u+0+(backgroundColor._v?BASE_COLORS:0)].fontWeight;
0166     else if (backgroundColor._colorSpace == COLOR_SPACE_SYSTEM)
0167         return base[backgroundColor._u+2+(backgroundColor._v?BASE_COLORS:0)].fontWeight;
0168     else
0169         return ColorEntry::UseCurrentFormat;
0170 }
0171 
0172 extern unsigned short vt100_graphics[32];
0173 
0174 
0175 /**
0176  * A table which stores sequences of unicode characters, referenced
0177  * by hash keys.  The hash key itself is the same size as a unicode
0178  * character ( ushort ) so that it can occupy the same space in
0179  * a structure.
0180  */
0181 class ExtendedCharTable
0182 {
0183 public:
0184     /** Constructs a new character table. */
0185     ExtendedCharTable();
0186     ~ExtendedCharTable();
0187 
0188     /**
0189      * Adds a sequences of unicode characters to the table and returns
0190      * a hash code which can be used later to look up the sequence
0191      * using lookupExtendedChar()
0192      *
0193      * If the same sequence already exists in the table, the hash
0194      * of the existing sequence will be returned.
0195      *
0196      * @param unicodePoints An array of unicode character points
0197      * @param length Length of @p unicodePoints
0198      */
0199     ushort createExtendedChar(ushort* unicodePoints , ushort length);
0200     /**
0201      * Looks up and returns a pointer to a sequence of unicode characters
0202      * which was added to the table using createExtendedChar().
0203      *
0204      * @param hash The hash key returned by createExtendedChar()
0205      * @param length This variable is set to the length of the
0206      * character sequence.
0207      *
0208      * @return A unicode character sequence of size @p length.
0209      */
0210     ushort* lookupExtendedChar(ushort hash , ushort& length) const;
0211 
0212     /** The global ExtendedCharTable instance. */
0213     static ExtendedCharTable instance;
0214 private:
0215     // calculates the hash key of a sequence of unicode points of size 'length'
0216     ushort extendedCharHash(ushort* unicodePoints , ushort length) const;
0217     // tests whether the entry in the table specified by 'hash' matches the
0218     // character sequence 'unicodePoints' of size 'length'
0219     bool extendedCharMatch(ushort hash , ushort* unicodePoints , ushort length) const;
0220     // internal, maps hash keys to character sequence buffers.  The first ushort
0221     // in each value is the length of the buffer, followed by the ushorts in the buffer
0222     // themselves.
0223     QHash<ushort,ushort*> extendedCharTable;
0224 };
0225 
0226 }
0227 Q_DECLARE_TYPEINFO(Konsole::Character, Q_MOVABLE_TYPE);
0228 
0229 #endif // CHARACTER_H
0230