diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index f1a0804e68..ad85fedcd0 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1164,7 +1164,7 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const layoutData->used += si.num_glyphs; } -static void init(QTextEngine *e) +void QTextEngine::init(QTextEngine *e) { e->ignoreBidi = false; e->cacheGlyphs = false; @@ -1433,10 +1433,11 @@ void QTextEngine::itemize() const #ifndef QT_NO_RAWFONT if (useRawFont && specialData) { int lastIndex = 0; + const QTextFormatCollection *collection = formats(); for (int i = 0; i < specialData->addFormats.size(); ++i) { const QTextLayout::FormatRange &range = specialData->addFormats.at(i); - QTextCharFormat format = formats()->charFormat(specialData->addFormatIndices.at(i)); - if (format.fontCapitalization()) { + const QTextCharFormat format = collection->charFormat(specialData->addFormatIndices.at(i)); + if (format.hasProperty(QTextFormat::FontCapitalization)) { itemizer.generate(lastIndex, range.start - lastIndex, QFont::MixedCase); itemizer.generate(range.start, range.length, format.fontCapitalization()); lastIndex = range.start + range.length; @@ -2209,25 +2210,9 @@ int QTextEngine::formatIndex(const QScriptItem *si) const QTextCharFormat QTextEngine::format(const QScriptItem *si) const { - QTextCharFormat format; - const QTextFormatCollection *formats = this->formats(); - - if (formats) - format = formats->charFormat(formatIndex(si)); - - if (specialData && specialData->resolvedFormatIndices.isEmpty()) { - int end = si->position + length(si); - for (int i = 0; i < specialData->addFormats.size(); ++i) { - const QTextLayout::FormatRange &r = specialData->addFormats.at(i); - if (r.start <= si->position && r.start + r.length >= end) { - if (!specialData->addFormatIndices.isEmpty()) - format.merge(formats->format(specialData->addFormatIndices.at(i))); - else - format.merge(r.format); - } - } - } - return format; + if (const QTextFormatCollection *formats = this->formats()) + return formats->charFormat(formatIndex(si)); + return QTextCharFormat(); } void QTextEngine::addRequiredBoundaries() const @@ -2298,6 +2283,67 @@ bool QTextEngine::atSpace(int position) const return false; } +void QTextEngine::setPreeditArea(int position, const QString &preeditText) +{ + if (preeditText.isEmpty()) { + if (!specialData) + return; + if (specialData->addFormats.isEmpty()) { + delete specialData; + specialData = 0; + } else { + specialData->preeditText = QString(); + specialData->preeditPosition = -1; + } + } else { + if (!specialData) + specialData = new SpecialData; + specialData->preeditPosition = position; + specialData->preeditText = preeditText; + } + invalidate(); + clearLineData(); +} + +QList QTextEngine::additionalFormats() const +{ + QList 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 &formatList) +{ + if (formatList.isEmpty()) { + if (!specialData) + return; + if (specialData->preeditText.isEmpty()) { + delete specialData; + specialData = 0; + } else { + specialData->addFormats.clear(); + specialData->addFormatIndices.clear(); + } + } else { + if (!specialData) { + specialData = new SpecialData; + specialData->preeditPosition = -1; + } + specialData->addFormats = formatList; + indexAdditionalFormats(); + } + resetFontEngineCache(); +} void QTextEngine::indexAdditionalFormats() { @@ -2775,13 +2821,9 @@ void QTextEngine::resolveAdditionalFormats() const } foreach (int cur, currentFormats) { - const QTextLayout::FormatRange &r = specialData->addFormats.at(cur); - Q_ASSERT (r.start <= si->position && r.start + r.length >= end); - if (!specialData->addFormatIndices.isEmpty()) { - format.merge(collection->format(specialData->addFormatIndices.at(cur))); - } else { - format.merge(r.format); - } + Q_ASSERT(specialData->addFormats.at(cur).start <= si->position + && specialData->addFormats.at(cur).start + specialData->addFormats.at(cur).length >= end); + format.merge(collection->format(specialData->addFormatIndices.at(cur))); } indices[i] = collection->indexForFormat(format); } diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index 88bc5dcc4c..ec7f7407b2 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -617,13 +617,23 @@ public: ItemDecorationList strikeOutList; ItemDecorationList overlineList; - inline bool hasFormats() const { return (block.docHandle() || specialData); } inline bool visualCursorMovement() const { return (visualMovement || (block.docHandle() ? block.docHandle()->defaultCursorMoveStyle == Qt::VisualMoveStyle : false)); } + inline int preeditAreaPosition() const { return specialData ? specialData->preeditPosition : -1; } + inline QString preeditAreaText() const { return specialData ? specialData->preeditText : QString(); } + void setPreeditArea(int position, const QString &text); + + inline bool hasFormats() const { return block.docHandle() || (specialData && !specialData->addFormats.isEmpty()); } + QList additionalFormats() const; + void setAdditionalFormats(const QList &formatList); + +private: + static void init(QTextEngine *e); + struct SpecialData { int preeditPosition; QString preeditText; @@ -635,9 +645,12 @@ public: }; SpecialData *specialData; + void indexAdditionalFormats(); + void resolveAdditionalFormats() const; + +public: bool atWordSeparator(int position) const; bool atSpace(int position) const; - void indexAdditionalFormats(); QString elidedText(Qt::TextElideMode mode, const QFixed &width, int flags = 0, int from = 0, int count = -1) const; @@ -675,7 +688,6 @@ private: void shapeTextWithHarfbuzz(int item) const; void splitItem(int item, int pos) const; - void resolveAdditionalFormats() const; int endOfLine(int lineNum); int beginningOfLine(int lineNum); int getClusterLength(unsigned short *logClusters, const QCharAttributes *attributes, int from, int to, int glyph_pos, int *start); diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 50908f9908..eed6758cc9 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -463,24 +463,10 @@ const QTextOption &QTextLayout::textOption() const */ void QTextLayout::setPreeditArea(int position, const QString &text) { - if (text.isEmpty()) { - if (!d->specialData) - return; - if (d->specialData->addFormats.isEmpty()) { - delete d->specialData; - d->specialData = 0; - } else { - d->specialData->preeditText = QString(); - d->specialData->preeditPosition = -1; - } - } else { - if (!d->specialData) - d->specialData = new QTextEngine::SpecialData; - d->specialData->preeditPosition = position; - d->specialData->preeditText = text; - } - d->invalidate(); - d->clearLineData(); + if (d->preeditAreaPosition() == position && d->preeditAreaText() == text) + return; + d->setPreeditArea(position, text); + if (d->block.docHandle()) d->block.docHandle()->documentChange(d->block.position(), d->block.length()); } @@ -493,7 +479,7 @@ void QTextLayout::setPreeditArea(int position, const QString &text) */ int QTextLayout::preeditAreaPosition() const { - return d->specialData ? d->specialData->preeditPosition : -1; + return d->preeditAreaPosition(); } /*! @@ -503,7 +489,7 @@ int QTextLayout::preeditAreaPosition() const */ QString QTextLayout::preeditAreaText() const { - return d->specialData ? d->specialData->preeditText : QString(); + return d->preeditAreaText(); } @@ -515,27 +501,10 @@ QString QTextLayout::preeditAreaText() const */ void QTextLayout::setAdditionalFormats(const QList &formatList) { - if (formatList.isEmpty()) { - if (!d->specialData) - return; - if (d->specialData->preeditText.isEmpty()) { - delete d->specialData; - d->specialData = 0; - } else { - d->specialData->addFormats = formatList; - d->specialData->addFormatIndices.clear(); - } - } else { - if (!d->specialData) { - d->specialData = new QTextEngine::SpecialData; - d->specialData->preeditPosition = -1; - } - d->specialData->addFormats = formatList; - d->indexAdditionalFormats(); - } + d->setAdditionalFormats(formatList); + if (d->block.docHandle()) d->block.docHandle()->documentChange(d->block.position(), d->block.length()); - d->resetFontEngineCache(); } /*! @@ -545,21 +514,7 @@ void QTextLayout::setAdditionalFormats(const QList &formatList) */ QList QTextLayout::additionalFormats() const { - QList formats; - if (!d->specialData) - return formats; - - formats = d->specialData->addFormats; - - if (d->specialData->addFormatIndices.isEmpty()) - return formats; - - const QTextFormatCollection *collection = d->formats(); - - for (int i = 0; i < d->specialData->addFormatIndices.count(); ++i) - formats[i].format = collection->charFormat(d->specialData->addFormatIndices.at(i)); - - return formats; + return d->additionalFormats(); } /*!