diff options
Diffstat (limited to 'src/gui/text/qtextengine.cpp')
-rw-r--r-- | src/gui/text/qtextengine.cpp | 125 |
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; } |