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>
This commit is contained in:
parent
bd8630763c
commit
0654c066d9
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
Loading…
Reference in New Issue
Block a user