summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKonstantin Ritt <ritt.ks@gmail.com>2013-03-18 18:16:40 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-03-19 18:16:41 +0100
commit0654c066d9b67e5c261b708196096311d695adcd (patch)
treed5811e73376305520364c490d7b02458355ba917 /src
parentbd8630763c407f723533e4f29f24647d96a79288 (diff)
Move QTextEngine implementation details from QTextLayout
As of now, we'll have everything related to the additional formats handling just in a single place. Make specialData private to prevent accessing it from outside. This helped in tracking-down several related issues: - in format(const QScriptItem *), the resolvedFormatIndices can not be empty at that point, so the code path is dead; - in resolveAdditionalFormats(), testing if formats has not been indexed yet is not needed since they are indexed just in the setter; - in useRawFont mode, hasFormats() didn't check if QTextEngine really has some formats, which potentially leads to formatting artifacts. Change-Id: Id4b912888fd5a1fa83f01007170134b6386e2879 Reviewed-by: Lars Knoll <lars.knoll@digia.com> Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/gui/text/qtextengine.cpp100
-rw-r--r--src/gui/text/qtextengine_p.h18
-rw-r--r--src/gui/text/qtextlayout.cpp63
3 files changed, 95 insertions, 86 deletions
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<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)
+{
+ 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<QTextLayout::FormatRange> additionalFormats() const;
+ void setAdditionalFormats(const QList<QTextLayout::FormatRange> &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<FormatRange> &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<FormatRange> &formatList)
*/
QList<QTextLayout::FormatRange> QTextLayout::additionalFormats() const
{
- QList<FormatRange> 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();
}
/*!