summaryrefslogtreecommitdiffstats
path: root/src/gui/text/qtextengine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/text/qtextengine.cpp')
-rw-r--r--src/gui/text/qtextengine.cpp125
1 files changed, 61 insertions, 64 deletions
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 67dedca760..c4eb47f708 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -59,10 +59,6 @@
#include <algorithm>
#include <stdlib.h>
-#ifndef QT_NO_RAWFONT
-#include "qfontengine_qpa_p.h"
-#endif
-
QT_BEGIN_NAMESPACE
static const float smallCapsFraction = 0.7f;
@@ -88,7 +84,7 @@ public:
/// The caps parameter is used to choose the algoritm of splitting text and assiging roles to the textitems
void generate(int start, int length, QFont::Capitalization caps)
{
- if ((int)caps == (int)QFont::SmallCaps)
+ if (caps == QFont::SmallCaps)
generateScriptItemsSmallCaps(reinterpret_cast<const ushort *>(m_string.unicode()), start, length);
else if(caps == QFont::Capitalize)
generateScriptItemsCapitalize(start, length);
@@ -122,9 +118,7 @@ private:
return;
const int end = start + length;
for (int i = start + 1; i < end; ++i) {
- if (m_analysis[i].bidiLevel == m_analysis[start].bidiLevel
- && m_analysis[i].flags == m_analysis[start].flags
- && m_analysis[i].script == m_analysis[start].script
+ if (m_analysis[i] == m_analysis[start]
&& m_analysis[i].flags < QScriptAnalysis::SpaceTabOrObject
&& i - start < MaxItemLength)
continue;
@@ -853,7 +847,7 @@ void QTextEngine::shapeLine(const QScriptLine &line)
int item = findItem(line.from);
if (item == -1)
return;
- for (item = findItem(line.from); item <= end; ++item) {
+ for ( ; item <= end; ++item) {
QScriptItem &si = layoutData->items[item];
if (si.analysis.flags == QScriptAnalysis::Tab) {
ensureSpace(1);
@@ -1420,8 +1414,6 @@ void QTextEngine::invalidate()
freeMemory();
minWidth = 0;
maxWidth = 0;
- if (specialData)
- specialData->resolvedFormats.clear();
resetFontEngineCache();
}
@@ -1582,9 +1574,9 @@ void QTextEngine::itemize() const
}
Q_ASSERT(position <= length);
QFont::Capitalization capitalization =
- formats()->charFormat(format).hasProperty(QTextFormat::FontCapitalization)
- ? formats()->charFormat(format).fontCapitalization()
- : formats()->defaultFont().capitalization();
+ formatCollection()->charFormat(format).hasProperty(QTextFormat::FontCapitalization)
+ ? formatCollection()->charFormat(format).fontCapitalization()
+ : formatCollection()->defaultFont().capitalization();
itemizer.generate(prevPosition, position - prevPosition, capitalization);
if (it == end) {
if (position < length)
@@ -1601,8 +1593,8 @@ void QTextEngine::itemize() const
#ifndef QT_NO_RAWFONT
if (useRawFont && specialData) {
int lastIndex = 0;
- for (int i = 0; i < specialData->addFormats.size(); ++i) {
- const QTextLayout::FormatRange &range = specialData->addFormats.at(i);
+ for (int i = 0; i < specialData->formats.size(); ++i) {
+ const QTextLayout::FormatRange &range = specialData->formats.at(i);
const QTextCharFormat &format = range.format;
if (format.hasProperty(QTextFormat::FontCapitalization)) {
itemizer.generate(lastIndex, range.start - lastIndex, QFont::MixedCase);
@@ -1617,7 +1609,7 @@ void QTextEngine::itemize() const
}
addRequiredBoundaries();
- resolveAdditionalFormats();
+ resolveFormats();
}
bool QTextEngine::isRightToLeft() const
@@ -1642,6 +1634,9 @@ bool QTextEngine::isRightToLeft() const
int QTextEngine::findItem(int strPos) const
{
itemize();
+ if (strPos < 0 || strPos >= layoutData->string.size())
+ return -1;
+
int left = 1;
int right = layoutData->items.size()-1;
while(left <= right) {
@@ -1880,7 +1875,7 @@ QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFix
if (feCache.prevFontEngine && feCache.prevFontEngine->type() == QFontEngine::Multi && feCache.prevScript == script) {
engine = feCache.prevFontEngine;
} else {
- engine = QFontEngineMultiQPA::createMultiFontEngine(rawFont.d->fontEngine, script);
+ engine = QFontEngineMultiBasicImpl::createMultiFontEngine(rawFont.d->fontEngine, script);
feCache.prevFontEngine = engine;
feCache.prevScript = script;
engine->ref.ref();
@@ -1889,13 +1884,13 @@ QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFix
feCache.prevScaledFontEngine = 0;
}
}
- if (si.analysis.flags & QFont::SmallCaps) {
+ if (si.analysis.flags == QScriptAnalysis::SmallCaps) {
if (feCache.prevScaledFontEngine) {
scaledEngine = feCache.prevScaledFontEngine;
} else {
QFontEngine *scEngine = rawFont.d->fontEngine->cloneWithSize(smallCapsFraction * rawFont.pixelSize());
scEngine->ref.ref();
- scaledEngine = QFontEngineMultiQPA::createMultiFontEngine(scEngine, script);
+ scaledEngine = QFontEngineMultiBasicImpl::createMultiFontEngine(scEngine, script);
scaledEngine->ref.ref();
feCache.prevScaledFontEngine = scaledEngine;
// If scEngine is not ref'ed by scaledEngine, make sure it is deallocated and not leaked.
@@ -2061,7 +2056,8 @@ void QTextEngine::justify(const QScriptLine &line)
return;
int firstItem = findItem(line.from);
- int nItems = findItem(line.from + line_length - 1) - firstItem + 1;
+ int lastItem = findItem(line.from + line_length - 1);
+ int nItems = (firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0;
QVarLengthArray<QJustificationPoint> justificationPoints;
int nPoints = 0;
@@ -2363,6 +2359,8 @@ void QTextEngine::freeMemory()
layoutData->haveCharAttributes = false;
layoutData->items.clear();
}
+ if (specialData)
+ specialData->resolvedFormats.clear();
for (int i = 0; i < lines.size(); ++i) {
lines[i].justified = 0;
lines[i].gridfitted = 0;
@@ -2372,7 +2370,7 @@ void QTextEngine::freeMemory()
int QTextEngine::formatIndex(const QScriptItem *si) const
{
if (specialData && !specialData->resolvedFormats.isEmpty()) {
- QTextFormatCollection *collection = formats();
+ QTextFormatCollection *collection = formatCollection();
Q_ASSERT(collection);
return collection->indexForFormat(specialData->resolvedFormats.at(si - &layoutData->items[0]));
}
@@ -2394,16 +2392,16 @@ int QTextEngine::formatIndex(const QScriptItem *si) const
QTextCharFormat QTextEngine::format(const QScriptItem *si) const
{
- if (const QTextFormatCollection *formats = this->formats())
- return formats->charFormat(formatIndex(si));
+ if (const QTextFormatCollection *collection = formatCollection())
+ return collection->charFormat(formatIndex(si));
return QTextCharFormat();
}
void QTextEngine::addRequiredBoundaries() const
{
if (specialData) {
- for (int i = 0; i < specialData->addFormats.size(); ++i) {
- const QTextLayout::FormatRange &r = specialData->addFormats.at(i);
+ for (int i = 0; i < specialData->formats.size(); ++i) {
+ const QTextLayout::FormatRange &r = specialData->formats.at(i);
setBoundary(r.start);
setBoundary(r.start + r.length);
//qDebug("adding boundaries %d %d", r.start, r.start+r.length);
@@ -2472,7 +2470,7 @@ void QTextEngine::setPreeditArea(int position, const QString &preeditText)
if (preeditText.isEmpty()) {
if (!specialData)
return;
- if (specialData->addFormats.isEmpty()) {
+ if (specialData->formats.isEmpty()) {
delete specialData;
specialData = 0;
} else {
@@ -2489,41 +2487,41 @@ void QTextEngine::setPreeditArea(int position, const QString &preeditText)
clearLineData();
}
-void QTextEngine::setAdditionalFormats(const QList<QTextLayout::FormatRange> &formatList)
+void QTextEngine::setFormats(const QList<QTextLayout::FormatRange> &formats)
{
- if (formatList.isEmpty()) {
+ if (formats.isEmpty()) {
if (!specialData)
return;
if (specialData->preeditText.isEmpty()) {
delete specialData;
specialData = 0;
} else {
- specialData->addFormats.clear();
+ specialData->formats.clear();
}
} else {
if (!specialData) {
specialData = new SpecialData;
specialData->preeditPosition = -1;
}
- specialData->addFormats = formatList;
- indexAdditionalFormats();
+ specialData->formats = formats;
+ indexFormats();
}
invalidate();
clearLineData();
}
-void QTextEngine::indexAdditionalFormats()
+void QTextEngine::indexFormats()
{
- QTextFormatCollection *collection = formats();
+ QTextFormatCollection *collection = formatCollection();
if (!collection) {
Q_ASSERT(!block.docHandle());
- specialData->formats.reset(new QTextFormatCollection);
- collection = specialData->formats.data();
+ specialData->formatCollection.reset(new QTextFormatCollection);
+ collection = specialData->formatCollection.data();
}
// replace with shared copies
- for (int i = 0; i < specialData->addFormats.count(); ++i) {
- QTextCharFormat &format = specialData->addFormats[i].format;
+ for (int i = 0; i < specialData->formats.size(); ++i) {
+ QTextCharFormat &format = specialData->formats[i].format;
format = collection->charFormat(collection->indexForFormat(format));
}
}
@@ -2928,45 +2926,44 @@ public:
};
}
-void QTextEngine::resolveAdditionalFormats() const
+void QTextEngine::resolveFormats() const
{
- if (!specialData || specialData->addFormats.isEmpty()
- || !specialData->resolvedFormats.isEmpty())
+ if (!specialData || specialData->formats.isEmpty())
return;
+ Q_ASSERT(specialData->resolvedFormats.isEmpty());
- QTextFormatCollection *collection = formats();
+ QTextFormatCollection *collection = formatCollection();
- specialData->resolvedFormats.clear();
QVector<QTextCharFormat> resolvedFormats(layoutData->items.count());
- QVarLengthArray<int, 64> addFormatSortedByStart;
- addFormatSortedByStart.reserve(specialData->addFormats.count());
- for (int i = 0; i < specialData->addFormats.count(); ++i) {
- if (specialData->addFormats.at(i).length >= 0)
- addFormatSortedByStart.append(i);
+ QVarLengthArray<int, 64> formatsSortedByStart;
+ formatsSortedByStart.reserve(specialData->formats.size());
+ for (int i = 0; i < specialData->formats.size(); ++i) {
+ if (specialData->formats.at(i).length >= 0)
+ formatsSortedByStart.append(i);
}
- QVarLengthArray<int, 64> addFormatSortedByEnd = addFormatSortedByStart;
- std::sort(addFormatSortedByStart.begin(), addFormatSortedByStart.end(),
- FormatRangeComparatorByStart(specialData->addFormats));
- std::sort(addFormatSortedByEnd.begin(), addFormatSortedByEnd.end(),
- FormatRangeComparatorByEnd(specialData->addFormats));
+ QVarLengthArray<int, 64> formatsSortedByEnd = formatsSortedByStart;
+ std::sort(formatsSortedByStart.begin(), formatsSortedByStart.end(),
+ FormatRangeComparatorByStart(specialData->formats));
+ std::sort(formatsSortedByEnd.begin(), formatsSortedByEnd.end(),
+ FormatRangeComparatorByEnd(specialData->formats));
QVarLengthArray<int, 16> currentFormats;
- const int *startIt = addFormatSortedByStart.constBegin();
- const int *endIt = addFormatSortedByEnd.constBegin();
+ const int *startIt = formatsSortedByStart.constBegin();
+ const int *endIt = formatsSortedByEnd.constBegin();
for (int i = 0; i < layoutData->items.count(); ++i) {
const QScriptItem *si = &layoutData->items.at(i);
int end = si->position + length(si);
- while (startIt != addFormatSortedByStart.constEnd() &&
- specialData->addFormats.at(*startIt).start <= si->position) {
+ while (startIt != formatsSortedByStart.constEnd() &&
+ specialData->formats.at(*startIt).start <= si->position) {
currentFormats.insert(std::upper_bound(currentFormats.begin(), currentFormats.end(), *startIt),
*startIt);
++startIt;
}
- while (endIt != addFormatSortedByEnd.constEnd() &&
- specialData->addFormats.at(*endIt).start + specialData->addFormats.at(*endIt).length < end) {
+ while (endIt != formatsSortedByEnd.constEnd() &&
+ specialData->formats.at(*endIt).start + specialData->formats.at(*endIt).length < end) {
int *currentFormatIterator = std::lower_bound(currentFormats.begin(), currentFormats.end(), *endIt);
if (*endIt < *currentFormatIterator)
currentFormatIterator = currentFormats.end();
@@ -2982,7 +2979,7 @@ void QTextEngine::resolveAdditionalFormats() const
}
if (!currentFormats.isEmpty()) {
foreach (int cur, currentFormats) {
- const QTextLayout::FormatRange &range = specialData->addFormats.at(cur);
+ const QTextLayout::FormatRange &range = specialData->formats.at(cur);
Q_ASSERT(range.start <= si->position && range.start + range.length >= end);
format.merge(range.format);
}
@@ -3482,15 +3479,15 @@ QTextLineItemIterator::QTextLineItemIterator(QTextEngine *_eng, int _lineNum, co
logicalItem(-1),
item(-1),
visualOrder(nItems),
- levels(nItems),
selection(_selection)
{
- pos_x = x = QFixed::fromReal(pos.x());
+ x = QFixed::fromReal(pos.x());
x += line.x;
x += eng->alignLine(line);
+ QVarLengthArray<uchar> levels(nItems);
for (int i = 0; i < nItems; ++i)
levels[i] = eng->layoutData->items[i+firstItem].analysis.bidiLevel;
QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data());
@@ -3561,7 +3558,7 @@ bool QTextLineItemIterator::getSelectionBounds(QFixed *selectionX, QFixed *selec
return false;
int start_glyph = logClusters[from];
- int end_glyph = (to == eng->length(item)) ? si->num_glyphs : logClusters[to];
+ int end_glyph = (to == itemLength) ? si->num_glyphs : logClusters[to];
QFixed soff;
QFixed swidth;
if (si->analysis.bidiLevel %2) {
@@ -3586,7 +3583,7 @@ bool QTextLineItemIterator::getSelectionBounds(QFixed *selectionX, QFixed *selec
// If the ending character is also part of a ligature, swidth does
// not contain that part yet, we also need to find out the width of
// that left part
- *selectionWidth += eng->offsetInLigature(si, to, eng->length(item), end_glyph);
+ *selectionWidth += eng->offsetInLigature(si, to, itemLength, end_glyph);
}
return true;
}