From: Marcus Eggenberger Date: Mon, 25 Aug 2008 13:11:19 +0000 (+0200) Subject: Introducing lazy word wrap calc. X-Git-Tag: 0.3.0~13 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=e2953de106e68e72486e294405f4bdcd33c60fba Introducing lazy word wrap calc. - faster message processing - less mem consumption unless you really visit all buffers - slightly slower buffer switch if you visit that buffer the first time --- diff --git a/src/qtui/chatlinemodel.cpp b/src/qtui/chatlinemodel.cpp index 28d77fb5..6b770a82 100644 --- a/src/qtui/chatlinemodel.cpp +++ b/src/qtui/chatlinemodel.cpp @@ -22,20 +22,15 @@ #include "chatlinemodelitem.h" -ChatLineModel::ChatLineModel(QObject *parent) : MessageModel(parent) { +ChatLineModel::ChatLineModel(QObject *parent) + : MessageModel(parent) +{ qRegisterMetaType("ChatLineModel::WrapList"); qRegisterMetaTypeStreamOperators("ChatLineModel::WrapList"); - -} - -ChatLineModel::~ChatLineModel() { - } - MessageModelItem *ChatLineModel::createMessageModelItem(const Message &msg) { return new ChatLineModelItem(msg); - } diff --git a/src/qtui/chatlinemodel.h b/src/qtui/chatlinemodel.h index a1e2c692..0fb92263 100644 --- a/src/qtui/chatlinemodel.h +++ b/src/qtui/chatlinemodel.h @@ -26,25 +26,23 @@ class ChatLineModel : public MessageModel { Q_OBJECT - public: - enum ChatLineRole { - WrapListRole = MessageModel::UserRole - }; - - ChatLineModel(QObject *parent = 0); - virtual ~ChatLineModel(); - - /// Used to store information about words to be used for wrapping - struct Word { - quint16 start; - qreal width; - qreal trailing; - }; - - typedef QVector WrapList; - - protected: - virtual MessageModelItem *createMessageModelItem(const Message &); +public: + enum ChatLineRole { + WrapListRole = MessageModel::UserRole + }; + + ChatLineModel(QObject *parent = 0); + + /// Used to store information about words to be used for wrapping + struct Word { + quint16 start; + qreal width; + qreal trailing; + }; + typedef QVector WrapList; + +protected: + virtual MessageModelItem *createMessageModelItem(const Message &); }; diff --git a/src/qtui/chatlinemodelitem.cpp b/src/qtui/chatlinemodelitem.cpp index 9b9e71c2..1897e3e1 100644 --- a/src/qtui/chatlinemodelitem.cpp +++ b/src/qtui/chatlinemodelitem.cpp @@ -40,8 +40,13 @@ typedef struct { unsigned char *ChatLineModelItem::TextBoundaryFinderBuffer = (unsigned char *)malloc(512 * sizeof(HB_CharAttributes_Dummy)); int ChatLineModelItem::TextBoundaryFinderBufferSize = 512 * (sizeof(HB_CharAttributes_Dummy) / sizeof(unsigned char)); +struct ChatLineModelItemPrivate { + ChatLineModel::WrapList wrapList; +}; + ChatLineModelItem::ChatLineModelItem(const Message &msg) - : MessageModelItem(msg) + : MessageModelItem(msg), + _data(new ChatLineModelItemPrivate) { QtUiStyle::StyledMessage m = QtUi::style()->styleMessage(msg); @@ -52,11 +57,8 @@ ChatLineModelItem::ChatLineModelItem(const Message &msg) _timestamp.formatList = m.timestamp.formatList; _sender.formatList = m.sender.formatList; _contents.formatList = m.contents.formatList; - - computeWrapList(); } - QVariant ChatLineModelItem::data(int column, int role) const { const ChatLinePart *part = 0; @@ -82,19 +84,20 @@ QVariant ChatLineModelItem::data(int column, int role) const { case ChatLineModel::WrapListRole: if(column != ChatLineModel::ContentsColumn) return QVariant(); - return QVariant::fromValue(_wrapList); + if(_data->wrapList.isEmpty()) + computeWrapList(); + return QVariant::fromValue(_data->wrapList); } return MessageModelItem::data(column, role); } -void ChatLineModelItem::computeWrapList() { +void ChatLineModelItem::computeWrapList() const { if(_contents.plainText.isEmpty()) return; enum Mode { SearchStart, SearchEnd }; QList wplist; // use a temp list which we'll later copy into a QVector for efficiency - // QTextBoundaryFinder finder(QTextBoundaryFinder::Word, _contents.plainText); QTextBoundaryFinder finder(QTextBoundaryFinder::Word, _contents.plainText.unicode(), _contents.plainText.length(), TextBoundaryFinderBuffer, TextBoundaryFinderBufferSize); int idx; @@ -153,9 +156,9 @@ void ChatLineModelItem::computeWrapList() { } while(finder.isAtBoundary() || (finder.position() == _contents.plainText.length())); // A QVector needs less space than a QList - _wrapList.resize(wplist.count()); + _data->wrapList.resize(wplist.count()); for(int i = 0; i < wplist.count(); i++) { - _wrapList[i] = wplist.at(i); + _data->wrapList[i] = wplist.at(i); } } diff --git a/src/qtui/chatlinemodelitem.h b/src/qtui/chatlinemodelitem.h index 1e9a8cc4..bc326689 100644 --- a/src/qtui/chatlinemodelitem.h +++ b/src/qtui/chatlinemodelitem.h @@ -26,6 +26,8 @@ #include "chatlinemodel.h" #include "uistyle.h" +class ChatLineModelItemPrivate; + class ChatLineModelItem : public MessageModelItem { public: ChatLineModelItem(const Message &); @@ -34,7 +36,7 @@ public: virtual inline bool setData(int column, const QVariant &value, int role) { Q_UNUSED(column); Q_UNUSED(value); Q_UNUSED(role); return false; } private: - void computeWrapList(); + void computeWrapList() const; struct ChatLinePart { QString plainText; @@ -42,7 +44,7 @@ private: }; ChatLinePart _timestamp, _sender, _contents; - ChatLineModel::WrapList _wrapList; + ChatLineModelItemPrivate *_data; static unsigned char *TextBoundaryFinderBuffer; static int TextBoundaryFinderBufferSize;