Per-view ZLTextParagraphCursorCache and ZLTextElementPool
This commit is contained in:
parent
8653f9512d
commit
7565921037
11 changed files with 89 additions and 68 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 ¶graph) {
|
void ZLTextParagraphCursor::processControlParagraph(const ZLTextParagraph ¶graph) {
|
||||||
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 ¶graph() const;
|
const ZLTextParagraph ¶graph() const;
|
||||||
|
ZLTextElementPool *elementPool() const;
|
||||||
|
ZLTextParagraphCursorPtr cursor(size_t index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void processControlParagraph(const ZLTextParagraph ¶graph);
|
void processControlParagraph(const ZLTextParagraph ¶graph);
|
||||||
|
@ -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__ */
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -59,5 +59,5 @@ void ZLTextView::paint() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ZLTextParagraphCursorCache::cleanup();
|
myParagraphCursorCache.cleanup();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue