Commit f6fa6fc0 authored by Robert Knight's avatar Robert Knight

Hash table to store unicode character sequences with hash keys the same size...

Hash table to store unicode character sequences with hash keys the same size as a unicode character point.  This can be used in future to get around the limitation in Konsole of one unicode point per character space on screen.

svn path=/branches/work/konsole-split-view/; revision=656590
parent 85b03470
......@@ -75,6 +75,7 @@
#include <QApplication>
#include <QClipboard>
#include <QClipboard>
#include <QHashIterator>
#include <QKeyEvent>
#include <QRegExp>
#include <QTextStream>
......@@ -599,4 +600,101 @@ void Emulation::setColumns(int columns)
emit setColumnCount(columns);
}
ushort ExtendedCharTable::extendedCharHash(ushort* unicodePoints , ushort length) const
{
ushort hash = 0;
for ( ushort i = 0 ; i < length ; i++ )
{
hash = 31*hash + unicodePoints[i];
}
return hash;
}
bool ExtendedCharTable::extendedCharMatch(ushort hash , ushort* unicodePoints , ushort length) const
{
ushort* entry = extendedCharTable[hash];
// compare given length with stored sequence length ( given as the first ushort in the
// stored buffer )
if ( entry == 0 || entry[0] != length )
return false;
// if the lengths match, each character must be checked. the stored buffer starts at
// entry[1]
for ( int i = 0 ; i < length ; i++ )
{
if ( entry[i+1] != unicodePoints[i] )
return false;
}
return true;
}
ushort ExtendedCharTable::createExtendedChar(ushort* unicodePoints , ushort length)
{
// look for this sequence of points in the table
ushort hash = extendedCharHash(unicodePoints,length);
// check existing entry for match
while ( extendedCharTable.contains(hash) )
{
if ( extendedCharMatch(hash,unicodePoints,length) )
{
// this sequence already has an entry in the table,
// return its hash
return hash;
}
else
{
// if hash is already used by another, different sequence of unicode character
// points then try next hash
hash++;
}
}
// add the new sequence to the table and
// return that index
ushort* buffer = new ushort[length+1];
buffer[0] = length;
for ( int i = 0 ; i < length ; i++ )
buffer[i+1] = unicodePoints[i];
extendedCharTable.insert(hash,buffer);
return hash;
}
ushort* ExtendedCharTable::lookupExtendedChar(ushort hash , ushort& length) const
{
// lookup index in table and if found, set the length
// argument and return a pointer to the character sequence
ushort* buffer = extendedCharTable[hash];
if ( buffer )
{
length = buffer[0];
return buffer+1;
}
else
{
length = 0;
return 0;
}
}
ExtendedCharTable::ExtendedCharTable()
{
}
ExtendedCharTable::~ExtendedCharTable()
{
// free all allocated character buffers
QHashIterator<ushort,ushort*> iter(extendedCharTable);
while ( iter.hasNext() )
{
iter.next();
delete[] iter.value();
}
}
// global instance
ExtendedCharTable ExtendedCharTable::instance;
#include "Emulation.moc"
......@@ -27,6 +27,7 @@
// Qt
#include <QColor>
#include <QHash>
namespace Konsole
{
......@@ -99,6 +100,58 @@ static const ColorEntry base_color_table[TABLE_COLORS] =
#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 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;
};
typedef unsigned char LineProperty;
......
......@@ -1444,7 +1444,8 @@ void TerminalDisplay::paintContents(QPainter &paint, const QRect &rect)
int rlx = qMin(_usedColumns-1, qMax(0,(rect.right() - tLx - _bX ) / _fontWidth));
int rly = qMin(_usedLines-1, qMax(0,(rect.bottom() - tLy - _bY ) / _fontHeight));
QChar *disstrU = new QChar[_usedColumns];
const int bufferSize = _usedColumns;
QChar *disstrU = new QChar[bufferSize];
for (int y = luy; y <= rly; y++)
{
quint16 c = _image[loc(lux,y)].character;
......@@ -1455,9 +1456,28 @@ void TerminalDisplay::paintContents(QPainter &paint, const QRect &rect)
{
int len = 1;
int p = 0;
c = _image[loc(x,y)].character;
if (c)
disstrU[p++] = c; //fontMap(c);
if ( _image[loc(x,y)].rendition & RE_EXTENDED_CHAR )
{
ushort extendedCharLength;
ushort* chars = ExtendedCharTable::instance
.lookupExtendedChar(_image[loc(x,y)].character,extendedCharLength);
for ( int index = 0 ; index < extendedCharLength ; index++ )
{
Q_ASSERT( p < bufferSize );
disstrU[p++] = chars[index];
}
}
else
{
c = _image[loc(x,y)].character;
if (c)
{
Q_ASSERT( p < bufferSize );
disstrU[p++] = c; //fontMap(c);
}
}
bool lineDraw = isLineChar(c);
bool doubleWidth = (_image[ qMin(loc(x,y)+1,_imageSize) ].character == 0);
CharacterColor cf = _image[loc(x,y)].foregroundColor;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment