Per-view ZLTextParagraphCursorCache and ZLTextElementPool

This commit is contained in:
Slava Monich 2015-05-27 00:08:27 +03:00
parent 8653f9512d
commit 7565921037
11 changed files with 89 additions and 68 deletions

View file

@ -28,7 +28,7 @@
#include "ZLTextLineInfo.h" #include "ZLTextLineInfo.h"
#include "ZLTextSelectionModel.h" #include "ZLTextSelectionModel.h"
ZLTextArea::ZLTextArea(ZLPaintContext &context, const Properties &properties) : myContext(context), myProperties(properties), myWidth(0), myHeight(0) { ZLTextArea::ZLTextArea(ZLPaintContext &context, const Properties &properties, ZLTextParagraphCursorCache *cache) : myContext(context), myProperties(properties), myWidth(0), myHeight(0), myParagraphCursorCache(cache) {
} }
ZLTextArea::~ZLTextArea() { ZLTextArea::~ZLTextArea() {
@ -52,7 +52,7 @@ void ZLTextArea::setModel(shared_ptr<ZLTextModel> model) {
} else { } else {
myMirroredContext.reset(); myMirroredContext.reset();
} }
myStartCursor = ZLTextParagraphCursor::cursor(*model); myStartCursor = myParagraphCursorCache->cursor(*model, 0);
myEndCursor = 0; myEndCursor = 0;
} }

View file

@ -27,6 +27,7 @@
#include <ZLTextParagraphCursor.h> #include <ZLTextParagraphCursor.h>
#include <ZLTextRectangle.h> #include <ZLTextRectangle.h>
#include <ZLTextModel.h>
class ZLPaintContext; class ZLPaintContext;
class ZLMirroredPaintContext; class ZLMirroredPaintContext;
@ -53,7 +54,7 @@ public:
}; };
public: public:
ZLTextArea(ZLPaintContext &context, const Properties &properties); ZLTextArea(ZLPaintContext &context, const Properties &properties, ZLTextParagraphCursorCache *cache);
~ZLTextArea(); ~ZLTextArea();
public: public:
@ -124,6 +125,7 @@ private:
ZLTextTreeNodeMap myTreeNodeMap; ZLTextTreeNodeMap myTreeNodeMap;
shared_ptr<ZLTextSelectionModel> mySelectionModel; shared_ptr<ZLTextSelectionModel> mySelectionModel;
ZLTextParagraphCursorCache* myParagraphCursorCache;
friend class ZLTextAreaController; friend class ZLTextAreaController;
friend class ZLTextSelectionModel; friend class ZLTextSelectionModel;

View file

@ -22,7 +22,7 @@
#include "ZLTextAreaStyle.h" #include "ZLTextAreaStyle.h"
#include "ZLTextLineInfo.h" #include "ZLTextLineInfo.h"
ZLTextAreaController::ZLTextAreaController(ZLPaintContext &context, const ZLTextArea::Properties &properties) : myArea(context, properties), myPaintState(NOTHING_TO_PAINT) { ZLTextAreaController::ZLTextAreaController(ZLPaintContext &context, const ZLTextArea::Properties &properties, ZLTextParagraphCursorCache *cache) : myArea(context, properties, cache), myParagraphCursorCache(cache), myPaintState(NOTHING_TO_PAINT) {
} }
ZLTextAreaController::~ZLTextAreaController() { ZLTextAreaController::~ZLTextAreaController() {
@ -38,7 +38,7 @@ void ZLTextAreaController::clear() {
myArea.clear(); myArea.clear();
myPaintState = NOTHING_TO_PAINT; myPaintState = NOTHING_TO_PAINT;
ZLTextParagraphCursorCache::clear(); myParagraphCursorCache->clear();
} }
ZLTextWordCursor ZLTextAreaController::findStart(const ZLTextWordCursor &end, SizeUnit unit, int size) { ZLTextWordCursor ZLTextAreaController::findStart(const ZLTextWordCursor &end, SizeUnit unit, int size) {
@ -229,7 +229,7 @@ void ZLTextAreaController::rebuildPaintInfo(bool strong) {
myArea.myLineInfos.clear(); myArea.myLineInfos.clear();
if (strong) { if (strong) {
ZLTextParagraphCursorCache::clear(); myParagraphCursorCache->clear();
myArea.myLineInfoCache.clear(); myArea.myLineInfoCache.clear();
} }

View file

@ -41,7 +41,7 @@ public:
}; };
public: public:
ZLTextAreaController(ZLPaintContext &context, const ZLTextArea::Properties &properties); ZLTextAreaController(ZLPaintContext &context, const ZLTextArea::Properties &properties, ZLTextParagraphCursorCache *cache);
~ZLTextAreaController(); ~ZLTextAreaController();
const ZLTextArea &area() const; const ZLTextArea &area() const;
@ -77,6 +77,7 @@ private:
private: private:
ZLTextArea myArea; ZLTextArea myArea;
ZLTextParagraphCursorCache *myParagraphCursorCache;
enum { enum {
NOTHING_TO_PAINT, NOTHING_TO_PAINT,

View file

@ -22,7 +22,7 @@
#include <linebreak.h> #include <linebreak.h>
#include <ZLImage.h> #include <ZLImage.h>
#include <ZLTextModel.h>
#include <ZLTextParagraph.h> #include <ZLTextParagraph.h>
#include "ZLTextParagraphCursor.h" #include "ZLTextParagraphCursor.h"
@ -32,6 +32,7 @@
ZLTextParagraphCursor::Builder::Builder(ZLTextParagraphCursor &cursor) : ZLTextParagraphCursor::Builder::Builder(ZLTextParagraphCursor &cursor) :
myParagraph(*cursor.myModel[cursor.myIndex]), myParagraph(*cursor.myModel[cursor.myIndex]),
myElements(cursor.myElements), myElements(cursor.myElements),
myTextElementPool(cursor.myElements.elementPool()),
myLanguage(cursor.myModel.language()), myLanguage(cursor.myModel.language()),
myBaseBidiLevel(cursor.myModel.isRtl() ? 1 : 0) { myBaseBidiLevel(cursor.myModel.isRtl() ? 1 : 0) {
const int paragraphIndex = cursor.myIndex; const int paragraphIndex = cursor.myIndex;
@ -52,16 +53,16 @@ ZLTextParagraphCursor::Builder::Builder(ZLTextParagraphCursor &cursor) :
void ZLTextParagraphCursor::Builder::updateBidiLevel(FriBidiLevel bidiLevel) { void ZLTextParagraphCursor::Builder::updateBidiLevel(FriBidiLevel bidiLevel) {
while (myCurrentBidiLevel > bidiLevel) { while (myCurrentBidiLevel > bidiLevel) {
--myCurrentBidiLevel; --myCurrentBidiLevel;
myElements.push_back(ZLTextElementPool::Pool.EndReversedSequenceElement); myElements.push_back(myTextElementPool.EndReversedSequenceElement);
} }
while (myCurrentBidiLevel < bidiLevel) { while (myCurrentBidiLevel < bidiLevel) {
++myCurrentBidiLevel; ++myCurrentBidiLevel;
myElements.push_back(ZLTextElementPool::Pool.StartReversedSequenceElement); myElements.push_back(myTextElementPool.StartReversedSequenceElement);
} }
} }
void ZLTextParagraphCursor::Builder::addWord(const char *ptr, int offset, int len) { void ZLTextParagraphCursor::Builder::addWord(const char *ptr, int offset, int len) {
ZLTextWord *word = ZLTextElementPool::Pool.getWord(ptr, len, offset, myCurrentBidiLevel); ZLTextWord *word = myTextElementPool.getWord(ptr, len, offset, myCurrentBidiLevel);
for (std::vector<ZLTextMark>::const_iterator mit = myFirstMark; mit != myLastMark; ++mit) { for (std::vector<ZLTextMark>::const_iterator mit = myFirstMark; mit != myLastMark; ++mit) {
ZLTextMark mark = *mit; ZLTextMark mark = *mit;
if ((mark.Offset < offset + len) && (mark.Offset + mark.Length > offset)) { if ((mark.Offset < offset + len) && (mark.Offset + mark.Length > offset)) {
@ -86,7 +87,7 @@ void ZLTextParagraphCursor::Builder::fill() {
break; break;
case ZLTextParagraphEntry::CONTROL_ENTRY: case ZLTextParagraphEntry::CONTROL_ENTRY:
case ZLTextParagraphEntry::HYPERLINK_CONTROL_ENTRY: case ZLTextParagraphEntry::HYPERLINK_CONTROL_ENTRY:
myElements.push_back(ZLTextElementPool::Pool.getControlElement(it.entry())); myElements.push_back(myTextElementPool.getControlElement(it.entry()));
break; break;
case ZLTextParagraphEntry::IMAGE_ENTRY: case ZLTextParagraphEntry::IMAGE_ENTRY:
{ {
@ -173,14 +174,14 @@ void ZLTextParagraphCursor::Builder::processTextEntry(const ZLTextEntry &textEnt
switch (spaceState) { switch (spaceState) {
case SPACE: case SPACE:
if ((myBreaksTable[ptr - start - 1] == LINEBREAK_NOBREAK) || (previousCh == '-')) { if ((myBreaksTable[ptr - start - 1] == LINEBREAK_NOBREAK) || (previousCh == '-')) {
myElements.push_back(ZLTextElementPool::Pool.NBHSpaceElement); myElements.push_back(myTextElementPool.NBHSpaceElement);
} else { } else {
myElements.push_back(ZLTextElementPool::Pool.HSpaceElement); myElements.push_back(myTextElementPool.HSpaceElement);
} }
wordStart = ptr; wordStart = ptr;
break; break;
case NON_BREAKABLE_SPACE: case NON_BREAKABLE_SPACE:
myElements.push_back(ZLTextElementPool::Pool.NBHSpaceElement); myElements.push_back(myTextElementPool.NBHSpaceElement);
wordStart = ptr; wordStart = ptr;
break; break;
case NO_SPACE: case NO_SPACE:
@ -198,10 +199,10 @@ void ZLTextParagraphCursor::Builder::processTextEntry(const ZLTextEntry &textEnt
} }
switch (spaceState) { switch (spaceState) {
case SPACE: case SPACE:
myElements.push_back(ZLTextElementPool::Pool.HSpaceElement); myElements.push_back(myTextElementPool.HSpaceElement);
break; break;
case NON_BREAKABLE_SPACE: case NON_BREAKABLE_SPACE:
myElements.push_back(ZLTextElementPool::Pool.NBHSpaceElement); myElements.push_back(myTextElementPool.NBHSpaceElement);
break; break;
case NO_SPACE: case NO_SPACE:
addWord(wordStart, myOffset + (wordStart - start), end - wordStart); addWord(wordStart, myOffset + (wordStart - start), end - wordStart);

View file

@ -47,6 +47,7 @@ private:
private: private:
const ZLTextParagraph &myParagraph; const ZLTextParagraph &myParagraph;
ZLTextElementVector &myElements; ZLTextElementVector &myElements;
ZLTextElementPool &myTextElementPool;
std::vector<ZLTextMark>::const_iterator myFirstMark; std::vector<ZLTextMark>::const_iterator myFirstMark;
std::vector<ZLTextMark>::const_iterator myLastMark; std::vector<ZLTextMark>::const_iterator myLastMark;

View file

@ -20,24 +20,20 @@
#include <algorithm> #include <algorithm>
#include <ZLTextParagraph.h> #include <ZLTextParagraph.h>
#include <ZLTextModel.h>
#include "ZLTextParagraphCursor.h" #include "ZLTextParagraphCursor.h"
#include "ZLTextWord.h" #include "ZLTextWord.h"
#include "ZLTextParagraphBuilder.h" #include "ZLTextParagraphBuilder.h"
ZLTextElementPool ZLTextElementPool::Pool;
std::map<const ZLTextParagraph*, weak_ptr<ZLTextParagraphCursor> > ZLTextParagraphCursorCache::ourCache;
ZLTextParagraphCursorPtr ZLTextParagraphCursorCache::ourLastAdded;
ZLTextElementVector::~ZLTextElementVector() { ZLTextElementVector::~ZLTextElementVector() {
for (ZLTextElementVector::const_iterator it = begin(); it != end(); ++it) { for (ZLTextElementVector::const_iterator it = begin(); it != end(); ++it) {
switch ((*it)->kind()) { switch ((*it)->kind()) {
case ZLTextElement::WORD_ELEMENT: case ZLTextElement::WORD_ELEMENT:
ZLTextElementPool::Pool.storeWord((ZLTextWord*)*it); myTextElementPool->storeWord((ZLTextWord*)*it);
break; break;
case ZLTextElement::CONTROL_ELEMENT: case ZLTextElement::CONTROL_ELEMENT:
ZLTextElementPool::Pool.storeControlElement((ZLTextControlElement*)*it); myTextElementPool->storeControlElement((ZLTextControlElement*)*it);
break; break;
case ZLTextElement::IMAGE_ELEMENT: case ZLTextElement::IMAGE_ELEMENT:
case ZLTextElement::FORCED_CONTROL_ELEMENT: case ZLTextElement::FORCED_CONTROL_ELEMENT:
@ -77,20 +73,27 @@ ZLTextElementPool::~ZLTextElementPool() {
delete EndReversedSequenceElement; delete EndReversedSequenceElement;
} }
ZLTextParagraphCursorPtr ZLTextParagraphCursor::cursor(const ZLTextModel &model, size_t index) { ZLTextParagraphCursorPtr ZLTextParagraphCursorCache::cursor(const ZLTextModel &model, size_t index) {
ZLTextParagraphCursorPtr result = ZLTextParagraphCursorCache::get(model[index]); const ZLTextParagraph *paragraph = model[index];
ZLTextParagraphCursorPtr result = get(paragraph);
if (result.isNull()) { if (result.isNull()) {
if (model.kind() == ZLTextModel::TREE_MODEL) { if (model.kind() == ZLTextModel::TREE_MODEL) {
result = new ZLTextTreeParagraphCursor((const ZLTextTreeModel&)model, index); result = new ZLTextTreeParagraphCursor((const ZLTextTreeModel&)model, index, this);
} else { } else {
result = new ZLTextPlainParagraphCursor((const ZLTextPlainModel&)model, index); result = new ZLTextPlainParagraphCursor(model, index, this);
} }
ZLTextParagraphCursorCache::put(model[index], result); put(paragraph, result);
} }
return result; return result;
} }
ZLTextParagraphCursor::ZLTextParagraphCursor(const ZLTextModel &model, size_t index) : myModel(model) { ZLTextPlainParagraphCursor::ZLTextPlainParagraphCursor(const ZLTextModel &model, size_t index, ZLTextParagraphCursorCache *cache) : ZLTextParagraphCursor(model, index, cache) {
}
ZLTextTreeParagraphCursor::ZLTextTreeParagraphCursor(const ZLTextTreeModel &model, size_t index, ZLTextParagraphCursorCache *cache) : ZLTextParagraphCursor(model, index, cache) {
}
ZLTextParagraphCursor::ZLTextParagraphCursor(const ZLTextModel &model, size_t index, ZLTextParagraphCursorCache *cache) : myModel(model), myElements(cache->elementPool()), myParagraphCursorCache(cache) {
myIndex = std::min(index, myModel.paragraphsNumber() - 1); myIndex = std::min(index, myModel.paragraphsNumber() - 1);
fill(); fill();
} }
@ -99,7 +102,7 @@ ZLTextParagraphCursor::~ZLTextParagraphCursor() {
} }
ZLTextParagraphCursorPtr ZLTextPlainParagraphCursor::previous() const { ZLTextParagraphCursorPtr ZLTextPlainParagraphCursor::previous() const {
return isFirst() ? 0 : cursor(myModel, myIndex - 1); return isFirst() ? 0 : myParagraphCursorCache->cursor(myModel, myIndex - 1);
} }
ZLTextParagraphCursorPtr ZLTextTreeParagraphCursor::previous() const { ZLTextParagraphCursorPtr ZLTextTreeParagraphCursor::previous() const {
@ -121,11 +124,11 @@ ZLTextParagraphCursorPtr ZLTextTreeParagraphCursor::previous() const {
--index; --index;
} }
} }
return cursor(myModel, index); return myParagraphCursorCache->cursor(myModel, index);
} }
ZLTextParagraphCursorPtr ZLTextPlainParagraphCursor::next() const { ZLTextParagraphCursorPtr ZLTextPlainParagraphCursor::next() const {
return isLast() ? 0 : cursor(myModel, myIndex + 1); return isLast() ? 0 : myParagraphCursorCache->cursor(myModel, myIndex + 1);
} }
ZLTextParagraphCursorPtr ZLTextTreeParagraphCursor::next() const { ZLTextParagraphCursorPtr ZLTextTreeParagraphCursor::next() const {
@ -134,7 +137,7 @@ ZLTextParagraphCursorPtr ZLTextTreeParagraphCursor::next() const {
} }
const ZLTextTreeParagraph *current = (const ZLTextTreeParagraph*)myModel[myIndex]; const ZLTextTreeParagraph *current = (const ZLTextTreeParagraph*)myModel[myIndex];
if (!current->children().empty() && current->isOpen()) { if (!current->children().empty() && current->isOpen()) {
return cursor(myModel, myIndex + 1); return myParagraphCursorCache->cursor(myModel, myIndex + 1);
} }
const ZLTextTreeParagraph *parent = current->parent(); const ZLTextTreeParagraph *parent = current->parent();
@ -147,7 +150,7 @@ ZLTextParagraphCursorPtr ZLTextTreeParagraphCursor::next() const {
while (((const ZLTextTreeParagraph*)myModel[index])->parent() != parent) { while (((const ZLTextTreeParagraph*)myModel[index])->parent() != parent) {
++index; ++index;
} }
return cursor(myModel, index); return myParagraphCursorCache->cursor(myModel, index);
} }
return 0; return 0;
} }
@ -185,6 +188,10 @@ bool ZLTextTreeParagraphCursor::isLast() const {
return true; return true;
} }
const ZLTextParagraph &ZLTextParagraphCursor::paragraph() const {
return *myModel[myIndex];
}
bool ZLTextParagraphCursor::isEndOfSection() const { bool ZLTextParagraphCursor::isEndOfSection() const {
return myModel[myIndex]->kind() == ZLTextParagraph::END_OF_SECTION_PARAGRAPH; return myModel[myIndex]->kind() == ZLTextParagraph::END_OF_SECTION_PARAGRAPH;
} }
@ -207,7 +214,7 @@ ZLTextMark ZLTextWordCursor::position() const {
void ZLTextParagraphCursor::processControlParagraph(const ZLTextParagraph &paragraph) { void ZLTextParagraphCursor::processControlParagraph(const ZLTextParagraph &paragraph) {
for (ZLTextParagraph::Iterator it = paragraph; !it.isEnd(); it.next()) { for (ZLTextParagraph::Iterator it = paragraph; !it.isEnd(); it.next()) {
myElements.push_back(ZLTextElementPool::Pool.getControlElement(it.entry())); myElements.push_back(elementPool()->getControlElement(it.entry()));
} }
} }
@ -223,15 +230,15 @@ void ZLTextParagraphCursor::fill() {
} }
case ZLTextParagraph::EMPTY_LINE_PARAGRAPH: case ZLTextParagraph::EMPTY_LINE_PARAGRAPH:
processControlParagraph(paragraph); processControlParagraph(paragraph);
myElements.push_back(ZLTextElementPool::Pool.EmptyLineElement); myElements.push_back(elementPool()->EmptyLineElement);
break; break;
case ZLTextParagraph::BEFORE_SKIP_PARAGRAPH: case ZLTextParagraph::BEFORE_SKIP_PARAGRAPH:
processControlParagraph(paragraph); processControlParagraph(paragraph);
myElements.push_back(ZLTextElementPool::Pool.BeforeParagraphElement); myElements.push_back(elementPool()->BeforeParagraphElement);
break; break;
case ZLTextParagraph::AFTER_SKIP_PARAGRAPH: case ZLTextParagraph::AFTER_SKIP_PARAGRAPH:
processControlParagraph(paragraph); processControlParagraph(paragraph);
myElements.push_back(ZLTextElementPool::Pool.AfterParagraphElement); myElements.push_back(elementPool()->AfterParagraphElement);
break; break;
case ZLTextParagraph::END_OF_SECTION_PARAGRAPH: case ZLTextParagraph::END_OF_SECTION_PARAGRAPH:
case ZLTextParagraph::END_OF_TEXT_PARAGRAPH: case ZLTextParagraph::END_OF_TEXT_PARAGRAPH:
@ -316,7 +323,7 @@ const ZLTextWordCursor &ZLTextWordCursor::operator = (ZLTextParagraphCursorPtr p
void ZLTextWordCursor::moveToParagraph(int paragraphIndex) { void ZLTextWordCursor::moveToParagraph(int paragraphIndex) {
if (!isNull() && (paragraphIndex != (int)myParagraphCursor->index())) { if (!isNull() && (paragraphIndex != (int)myParagraphCursor->index())) {
myParagraphCursor = ZLTextParagraphCursor::cursor(myParagraphCursor->myModel, paragraphIndex); myParagraphCursor = myParagraphCursor->cursor(paragraphIndex);
moveToParagraphStart(); moveToParagraphStart();
} }
} }

View file

@ -27,26 +27,32 @@
#include <shared_ptr.h> #include <shared_ptr.h>
#include <allocator.h> #include <allocator.h>
#include <ZLTextModel.h> #include <ZLTextMark.h>
#include "ZLTextElement.h" #include "ZLTextElement.h"
#include "ZLTextWord.h" #include "ZLTextWord.h"
class ZLTextParagraph; class ZLTextParagraph;
class ZLTextElementPool;
class ZLTextParagraphCursorCache;
class ZLTextTreeModel;
class ZLTextModel;
class ZLTextElementVector : public std::vector<ZLTextElement*> { class ZLTextElementVector : public std::vector<ZLTextElement*> {
public: public:
ZLTextElementVector(); ZLTextElementVector(ZLTextElementPool *pool);
~ZLTextElementVector(); ~ZLTextElementVector();
ZLTextElementPool &elementPool() const { return *myTextElementPool; }
private:
ZLTextElementPool *myTextElementPool;
}; };
class ZLTextElementPool { class ZLTextElementPool {
public: public:
static ZLTextElementPool Pool;
private:
ZLTextElementPool(); ZLTextElementPool();
~ZLTextElementPool(); ~ZLTextElementPool();
@ -78,10 +84,9 @@ private:
class Builder; class Builder;
protected: protected:
ZLTextParagraphCursor(const ZLTextModel &model, size_t index); ZLTextParagraphCursor(const ZLTextModel &model, size_t index, ZLTextParagraphCursorCache* cache);
public: public:
static ZLTextParagraphCursorPtr cursor(const ZLTextModel &model, size_t index = 0);
virtual ~ZLTextParagraphCursor(); virtual ~ZLTextParagraphCursor();
bool isFirst() const; bool isFirst() const;
@ -96,6 +101,8 @@ public:
const ZLTextElement &operator [] (size_t index) const; const ZLTextElement &operator [] (size_t index) const;
const ZLTextParagraph &paragraph() const; const ZLTextParagraph &paragraph() const;
ZLTextElementPool *elementPool() const;
ZLTextParagraphCursorPtr cursor(size_t index);
private: private:
void processControlParagraph(const ZLTextParagraph &paragraph); void processControlParagraph(const ZLTextParagraph &paragraph);
@ -113,6 +120,7 @@ protected:
const ZLTextModel &myModel; const ZLTextModel &myModel;
size_t myIndex; size_t myIndex;
ZLTextElementVector myElements; ZLTextElementVector myElements;
ZLTextParagraphCursorCache *myParagraphCursorCache;
friend class ZLTextWordCursor; friend class ZLTextWordCursor;
}; };
@ -120,19 +128,21 @@ friend class ZLTextWordCursor;
class ZLTextParagraphCursorCache { class ZLTextParagraphCursorCache {
public: public:
static void put(const ZLTextParagraph *paragraph, ZLTextParagraphCursorPtr cursor); ZLTextParagraphCursorCache() {}
static ZLTextParagraphCursorPtr get(const ZLTextParagraph *paragraph); ~ZLTextParagraphCursorCache() {}
static void clear(); void clear();
static void cleanup(); void cleanup();
void put(const ZLTextParagraph *paragraph, ZLTextParagraphCursorPtr cursor);
ZLTextParagraphCursorPtr get(const ZLTextParagraph *paragraph);
ZLTextParagraphCursorPtr cursor(const ZLTextModel &model, size_t index);
ZLTextElementPool *elementPool() { return &ourElementPool; }
private: private:
static std::map<const ZLTextParagraph*, weak_ptr<ZLTextParagraphCursor> > ourCache; std::map<const ZLTextParagraph*, weak_ptr<ZLTextParagraphCursor> > ourCache;
static ZLTextParagraphCursorPtr ourLastAdded; ZLTextParagraphCursorPtr ourLastAdded;
ZLTextElementPool ourElementPool;
private:
// Instance creation is disabled
ZLTextParagraphCursorCache();
}; };
class ZLTextWordCursor { class ZLTextWordCursor {
@ -179,7 +189,7 @@ private:
class ZLTextPlainParagraphCursor : public ZLTextParagraphCursor { class ZLTextPlainParagraphCursor : public ZLTextParagraphCursor {
private: private:
ZLTextPlainParagraphCursor(const ZLTextModel &model, size_t index); ZLTextPlainParagraphCursor(const ZLTextModel &model, size_t index, ZLTextParagraphCursorCache* cache);
public: public:
~ZLTextPlainParagraphCursor(); ~ZLTextPlainParagraphCursor();
@ -188,13 +198,13 @@ public:
ZLTextParagraphCursorPtr next() const; ZLTextParagraphCursorPtr next() const;
bool isLast() const; bool isLast() const;
friend class ZLTextParagraphCursor; friend class ZLTextParagraphCursorCache;
}; };
class ZLTextTreeParagraphCursor : public ZLTextParagraphCursor { class ZLTextTreeParagraphCursor : public ZLTextParagraphCursor {
private: private:
ZLTextTreeParagraphCursor(const ZLTextTreeModel &model, size_t index); ZLTextTreeParagraphCursor(const ZLTextTreeModel &model, size_t index, ZLTextParagraphCursorCache* cache);
public: public:
~ZLTextTreeParagraphCursor(); ~ZLTextTreeParagraphCursor();
@ -203,10 +213,10 @@ public:
ZLTextParagraphCursorPtr next() const; ZLTextParagraphCursorPtr next() const;
bool isLast() const; bool isLast() const;
friend class ZLTextParagraphCursor; friend class ZLTextParagraphCursorCache;
}; };
inline ZLTextElementVector::ZLTextElementVector() {} inline ZLTextElementVector::ZLTextElementVector(ZLTextElementPool *pool) : myTextElementPool(pool) {}
inline ZLTextWord *ZLTextElementPool::getWord(const char *data, unsigned short length, size_t paragraphOffset, unsigned char bidiLevel) { inline ZLTextWord *ZLTextElementPool::getWord(const char *data, unsigned short length, size_t paragraphOffset, unsigned char bidiLevel) {
return new (myWordAllocator.allocate()) ZLTextWord(data, length, paragraphOffset, bidiLevel); return new (myWordAllocator.allocate()) ZLTextWord(data, length, paragraphOffset, bidiLevel);
@ -225,8 +235,9 @@ inline void ZLTextElementPool::storeControlElement(ZLTextControlElement *element
inline size_t ZLTextParagraphCursor::index() const { return myIndex; } inline size_t ZLTextParagraphCursor::index() const { return myIndex; }
inline const ZLTextElement &ZLTextParagraphCursor::operator [] (size_t index) const { return *myElements[index]; } inline const ZLTextElement &ZLTextParagraphCursor::operator [] (size_t index) const { return *myElements[index]; }
inline const ZLTextParagraph &ZLTextParagraphCursor::paragraph() const { return *myModel[myIndex]; }
inline size_t ZLTextParagraphCursor::paragraphLength() const { return myElements.size(); } inline size_t ZLTextParagraphCursor::paragraphLength() const { return myElements.size(); }
inline ZLTextElementPool *ZLTextParagraphCursor::elementPool() const { return myParagraphCursorCache->elementPool(); }
inline ZLTextParagraphCursorPtr ZLTextParagraphCursor::cursor(size_t index) { return myParagraphCursorCache->cursor(myModel, index); }
inline ZLTextWordCursor::ZLTextWordCursor() : myElementIndex(0), myCharIndex(0) {} inline ZLTextWordCursor::ZLTextWordCursor() : myElementIndex(0), myCharIndex(0) {}
inline ZLTextWordCursor::ZLTextWordCursor(const ZLTextWordCursor &cursor) : myParagraphCursor(cursor.myParagraphCursor), myElementIndex(cursor.myElementIndex), myCharIndex(cursor.myCharIndex) {} inline ZLTextWordCursor::ZLTextWordCursor(const ZLTextWordCursor &cursor) : myParagraphCursor(cursor.myParagraphCursor), myElementIndex(cursor.myElementIndex), myCharIndex(cursor.myCharIndex) {}
@ -268,10 +279,7 @@ inline const ZLTextParagraphCursor &ZLTextWordCursor::paragraphCursor() const {
inline void ZLTextWordCursor::nextWord() { ++myElementIndex; myCharIndex = 0; } inline void ZLTextWordCursor::nextWord() { ++myElementIndex; myCharIndex = 0; }
inline void ZLTextWordCursor::previousWord() { --myElementIndex; myCharIndex = 0; } inline void ZLTextWordCursor::previousWord() { --myElementIndex; myCharIndex = 0; }
inline ZLTextPlainParagraphCursor::ZLTextPlainParagraphCursor(const ZLTextModel &model, size_t index) : ZLTextParagraphCursor(model, index) {}
inline ZLTextPlainParagraphCursor::~ZLTextPlainParagraphCursor() {} inline ZLTextPlainParagraphCursor::~ZLTextPlainParagraphCursor() {}
inline ZLTextTreeParagraphCursor::ZLTextTreeParagraphCursor(const ZLTextTreeModel &model, size_t index) : ZLTextParagraphCursor(model, index) {}
inline ZLTextTreeParagraphCursor::~ZLTextTreeParagraphCursor() {} inline ZLTextTreeParagraphCursor::~ZLTextTreeParagraphCursor() {}
#endif /* __ZLTEXTPARAGRAPHCURSOR_H__ */ #endif /* __ZLTEXTPARAGRAPHCURSOR_H__ */

View file

@ -42,7 +42,7 @@ const ZLTypeId &ZLTextView::typeId() const {
ZLTextView::ZLTextView(ZLPaintContext &context) : ZLTextView::ZLTextView(ZLPaintContext &context) :
ZLView(context), ZLView(context),
myTextAreaController(context, *this), myTextAreaController(context, *this, &myParagraphCursorCache),
myTreeStateIsFrozen(false), myTreeStateIsFrozen(false),
myDoUpdateScrollbar(false), myDoUpdateScrollbar(false),
myDoubleClickInfo(*this) { myDoubleClickInfo(*this) {

View file

@ -127,6 +127,7 @@ private:
void stopSelectionScrolling(); void stopSelectionScrolling();
private: private:
ZLTextParagraphCursorCache myParagraphCursorCache;
ZLTextAreaController myTextAreaController; ZLTextAreaController myTextAreaController;
std::vector<size_t> myTextSize; std::vector<size_t> myTextSize;

View file

@ -59,5 +59,5 @@ void ZLTextView::paint() {
} }
} }
ZLTextParagraphCursorCache::cleanup(); myParagraphCursorCache.cleanup();
} }