Get rid of SpecialData::addFormatIndices

and rename SpecialData:: resolvedFormatIndices to resolvedFormats.
Instead, resolvedFormats now stores QTextCharFormat shared copies.

Change-Id: I4a22cb3f5679b980ef52d47e4e1935663dd257ea
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
Konstantin Ritt 2014-01-30 01:55:41 +02:00 committed by The Qt Project
parent 903b9d41f7
commit f864bdaf59
3 changed files with 35 additions and 54 deletions

View File

@ -1393,9 +1393,9 @@ void QTextEngine::shape(int item) const
if (layoutData->items[item].analysis.flags == QScriptAnalysis::Object) { if (layoutData->items[item].analysis.flags == QScriptAnalysis::Object) {
ensureSpace(1); ensureSpace(1);
if (block.docHandle()) { if (block.docHandle()) {
QTextFormat format = formats()->format(formatIndex(&layoutData->items[item]));
docLayout()->resizeInlineObject(QTextInlineObject(item, const_cast<QTextEngine *>(this)), docLayout()->resizeInlineObject(QTextInlineObject(item, const_cast<QTextEngine *>(this)),
layoutData->items[item].position + block.position(), format); layoutData->items[item].position + block.position(),
format(&layoutData->items[item]));
} }
} else if (layoutData->items[item].analysis.flags == QScriptAnalysis::Tab) { } else if (layoutData->items[item].analysis.flags == QScriptAnalysis::Tab) {
// set up at least the ascent/descent/leading of the script item for the tab // set up at least the ascent/descent/leading of the script item for the tab
@ -1427,7 +1427,7 @@ void QTextEngine::invalidate()
minWidth = 0; minWidth = 0;
maxWidth = 0; maxWidth = 0;
if (specialData) if (specialData)
specialData->resolvedFormatIndices.clear(); specialData->resolvedFormats.clear();
resetFontEngineCache(); resetFontEngineCache();
} }
@ -1606,10 +1606,9 @@ void QTextEngine::itemize() const
#ifndef QT_NO_RAWFONT #ifndef QT_NO_RAWFONT
if (useRawFont && specialData) { if (useRawFont && specialData) {
int lastIndex = 0; int lastIndex = 0;
const QTextFormatCollection *collection = formats();
for (int i = 0; i < specialData->addFormats.size(); ++i) { for (int i = 0; i < specialData->addFormats.size(); ++i) {
const QTextLayout::FormatRange &range = specialData->addFormats.at(i); const QTextLayout::FormatRange &range = specialData->addFormats.at(i);
const QTextCharFormat format = collection->charFormat(specialData->addFormatIndices.at(i)); const QTextCharFormat &format = range.format;
if (format.hasProperty(QTextFormat::FontCapitalization)) { if (format.hasProperty(QTextFormat::FontCapitalization)) {
itemizer.generate(lastIndex, range.start - lastIndex, QFont::MixedCase); itemizer.generate(lastIndex, range.start - lastIndex, QFont::MixedCase);
itemizer.generate(range.start, range.length, format.fontCapitalization()); itemizer.generate(range.start, range.length, format.fontCapitalization());
@ -2368,8 +2367,12 @@ void QTextEngine::freeMemory()
int QTextEngine::formatIndex(const QScriptItem *si) const int QTextEngine::formatIndex(const QScriptItem *si) const
{ {
if (specialData && !specialData->resolvedFormatIndices.isEmpty()) if (specialData && !specialData->resolvedFormats.isEmpty()) {
return specialData->resolvedFormatIndices.at(si - &layoutData->items[0]); QTextFormatCollection *collection = formats();
Q_ASSERT(collection);
return collection->indexForFormat(specialData->resolvedFormats.at(si - &layoutData->items[0]));
}
QTextDocumentPrivate *p = block.docHandle(); QTextDocumentPrivate *p = block.docHandle();
if (!p) if (!p)
return -1; return -1;
@ -2482,23 +2485,6 @@ void QTextEngine::setPreeditArea(int position, const QString &preeditText)
clearLineData(); clearLineData();
} }
QList<QTextLayout::FormatRange> QTextEngine::additionalFormats() const
{
QList<QTextLayout::FormatRange> formatList;
if (!specialData)
return formatList;
formatList = specialData->addFormats;
if (!specialData->addFormatIndices.isEmpty()) {
const QTextFormatCollection *formats = this->formats();
Q_ASSERT(formats);
for (int i = 0; i < specialData->addFormatIndices.size(); ++i)
formatList[i].format = formats->charFormat(specialData->addFormatIndices.at(i));
}
return formatList;
}
void QTextEngine::setAdditionalFormats(const QList<QTextLayout::FormatRange> &formatList) void QTextEngine::setAdditionalFormats(const QList<QTextLayout::FormatRange> &formatList)
{ {
if (formatList.isEmpty()) { if (formatList.isEmpty()) {
@ -2509,7 +2495,6 @@ void QTextEngine::setAdditionalFormats(const QList<QTextLayout::FormatRange> &fo
specialData = 0; specialData = 0;
} else { } else {
specialData->addFormats.clear(); specialData->addFormats.clear();
specialData->addFormatIndices.clear();
} }
} else { } else {
if (!specialData) { if (!specialData) {
@ -2524,19 +2509,17 @@ void QTextEngine::setAdditionalFormats(const QList<QTextLayout::FormatRange> &fo
void QTextEngine::indexAdditionalFormats() void QTextEngine::indexAdditionalFormats()
{ {
specialData->addFormatIndices.resize(specialData->addFormats.count()); QTextFormatCollection *collection = formats();
if (!collection) {
QTextFormatCollection *formats = this->formats();
if (!formats) {
Q_ASSERT(!block.docHandle()); Q_ASSERT(!block.docHandle());
specialData->formats.reset(new QTextFormatCollection); specialData->formats.reset(new QTextFormatCollection);
formats = specialData->formats.data(); collection = specialData->formats.data();
} }
// replace with shared copies
for (int i = 0; i < specialData->addFormats.count(); ++i) { for (int i = 0; i < specialData->addFormats.count(); ++i) {
specialData->addFormatIndices[i] = formats->indexForFormat(specialData->addFormats.at(i).format); QTextCharFormat &format = specialData->addFormats[i].format;
specialData->addFormats[i].format = QTextCharFormat(); format = collection->charFormat(collection->indexForFormat(format));
} }
} }
@ -2952,14 +2935,12 @@ public:
void QTextEngine::resolveAdditionalFormats() const void QTextEngine::resolveAdditionalFormats() const
{ {
if (!specialData || specialData->addFormats.isEmpty() if (!specialData || specialData->addFormats.isEmpty()
|| !specialData->resolvedFormatIndices.isEmpty()) || !specialData->resolvedFormats.isEmpty())
return; return;
QTextFormatCollection *collection = formats(); QTextFormatCollection *collection = formats();
specialData->resolvedFormatIndices.clear(); specialData->resolvedFormats.resize(layoutData->items.count());
QVector<int> indices(layoutData->items.count());
QVarLengthArray<int, 64> addFormatSortedByStart; QVarLengthArray<int, 64> addFormatSortedByStart;
addFormatSortedByStart.reserve(specialData->addFormats.count()); addFormatSortedByStart.reserve(specialData->addFormats.count());
@ -2995,21 +2976,22 @@ void QTextEngine::resolveAdditionalFormats() const
currentFormats.remove(currentFormatIterator - currentFormats.begin()); currentFormats.remove(currentFormatIterator - currentFormats.begin());
++endIt; ++endIt;
} }
QTextCharFormat format;
QTextCharFormat &format = specialData->resolvedFormats[i];
if (block.docHandle()) { if (block.docHandle()) {
// when we have a docHandle, formatIndex might still return a valid index based // when we have a docHandle, formatIndex might still return a valid index based
// on the preeditPosition. for all other cases, we cleared the resolved format indices // on the preeditPosition. for all other cases, we cleared the resolved format indices
format = collection->charFormat(formatIndex(si)); format = collection->charFormat(formatIndex(si));
} }
if (!currentFormats.isEmpty()) {
foreach (int cur, currentFormats) { foreach (int cur, currentFormats) {
Q_ASSERT(specialData->addFormats.at(cur).start <= si->position const QTextLayout::FormatRange &range = specialData->addFormats.at(cur);
&& specialData->addFormats.at(cur).start + specialData->addFormats.at(cur).length >= end); Q_ASSERT(range.start <= si->position && range.start + range.length >= end);
format.merge(collection->format(specialData->addFormatIndices.at(cur))); format.merge(range.format);
}
format = collection->charFormat(collection->indexForFormat(format)); // get shared copy
} }
indices[i] = collection->indexForFormat(format);
} }
specialData->resolvedFormatIndices = indices;
} }
QFixed QTextEngine::leadingSpaceWidth(const QScriptLine &line) QFixed QTextEngine::leadingSpaceWidth(const QScriptLine &line)

View File

@ -603,7 +603,8 @@ public:
void setPreeditArea(int position, const QString &text); void setPreeditArea(int position, const QString &text);
inline bool hasFormats() const { return block.docHandle() || (specialData && !specialData->addFormats.isEmpty()); } inline bool hasFormats() const { return block.docHandle() || (specialData && !specialData->addFormats.isEmpty()); }
QList<QTextLayout::FormatRange> additionalFormats() const; inline QList<QTextLayout::FormatRange> additionalFormats() const
{ return specialData ? specialData->addFormats : QList<QTextLayout::FormatRange>(); }
void setAdditionalFormats(const QList<QTextLayout::FormatRange> &formatList); void setAdditionalFormats(const QList<QTextLayout::FormatRange> &formatList);
private: private:
@ -613,8 +614,7 @@ private:
int preeditPosition; int preeditPosition;
QString preeditText; QString preeditText;
QList<QTextLayout::FormatRange> addFormats; QList<QTextLayout::FormatRange> addFormats;
QVector<int> addFormatIndices; QVector<QTextCharFormat> resolvedFormats;
QVector<int> resolvedFormatIndices;
// only used when no docHandle is available // only used when no docHandle is available
QScopedPointer<QTextFormatCollection> formats; QScopedPointer<QTextFormatCollection> formats;
}; };

View File

@ -239,9 +239,7 @@ int QTextInlineObject::formatIndex() const
*/ */
QTextFormat QTextInlineObject::format() const QTextFormat QTextInlineObject::format() const
{ {
if (!eng->block.docHandle()) return eng->format(&eng->layoutData->items[itm]);
return QTextFormat();
return eng->formats()->format(eng->formatIndex(&eng->layoutData->items[itm]));
} }
/*! /*!
@ -1812,9 +1810,10 @@ void QTextLine::layout_helper(int maxGlyphs)
lbh.whiteSpaceOrObject = true; lbh.whiteSpaceOrObject = true;
lbh.tmpData.length++; lbh.tmpData.length++;
QTextFormat format = eng->formats()->format(eng->formatIndex(&eng->layoutData->items[item])); if (eng->block.docHandle()) {
if (eng->block.docHandle()) QTextInlineObject inlineObject(item, eng);
eng->docLayout()->positionInlineObject(QTextInlineObject(item, eng), eng->block.position() + current.position, format); eng->docLayout()->positionInlineObject(inlineObject, eng->block.position() + current.position, inlineObject.format());
}
lbh.tmpData.textWidth += current.width; lbh.tmpData.textWidth += current.width;