diff options
Diffstat (limited to 'src/gui/text')
-rw-r--r-- | src/gui/text/qfont.cpp | 60 | ||||
-rw-r--r-- | src/gui/text/qglyphrun.cpp | 10 | ||||
-rw-r--r-- | src/gui/text/qrawfont.cpp | 70 | ||||
-rw-r--r-- | src/gui/text/qrawfont.h | 10 | ||||
-rw-r--r-- | src/gui/text/qtextengine.cpp | 26 | ||||
-rw-r--r-- | src/gui/text/qtextformat.cpp | 4 | ||||
-rw-r--r-- | src/gui/text/qtextobject.cpp | 11 |
7 files changed, 119 insertions, 72 deletions
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 65368fd9d8..995d48d450 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -760,6 +760,9 @@ QString QFont::family() const */ void QFont::setFamily(const QString &family) { + if ((resolve_mask & QFont::FamilyResolved) && d->request.family == family) + return; + detach(); d->request.family = family; @@ -793,6 +796,9 @@ QString QFont::styleName() const */ void QFont::setStyleName(const QString &styleName) { + if ((resolve_mask & QFont::StyleNameResolved) && d->request.styleName == styleName) + return; + detach(); d->request.styleName = styleName; @@ -892,6 +898,9 @@ int QFont::pointSize() const */ void QFont::setHintingPreference(HintingPreference hintingPreference) { + if ((resolve_mask & QFont::HintingPreferenceResolved) && d->request.hintingPreference == hintingPreference) + return; + detach(); d->request.hintingPreference = hintingPreference; @@ -922,6 +931,9 @@ void QFont::setPointSize(int pointSize) return; } + if ((resolve_mask & QFont::SizeResolved) && d->request.pointSize == qreal(pointSize)) + return; + detach(); d->request.pointSize = qreal(pointSize); @@ -944,6 +956,9 @@ void QFont::setPointSizeF(qreal pointSize) return; } + if ((resolve_mask & QFont::SizeResolved) && d->request.pointSize == pointSize) + return; + detach(); d->request.pointSize = pointSize; @@ -979,6 +994,9 @@ void QFont::setPixelSize(int pixelSize) return; } + if ((resolve_mask & QFont::SizeResolved) && d->request.pixelSize == qreal(pixelSize)) + return; + detach(); d->request.pixelSize = pixelSize; @@ -1034,6 +1052,9 @@ QFont::Style QFont::style() const */ void QFont::setStyle(Style style) { + if ((resolve_mask & QFont::StyleResolved) && d->request.style == style) + return; + detach(); d->request.style = style; @@ -1077,6 +1098,9 @@ void QFont::setWeight(int weight) { Q_ASSERT_X(weight >= 0 && weight <= 99, "QFont::setWeight", "Weight must be between 0 and 99"); + if ((resolve_mask & QFont::WeightResolved) && d->request.weight == weight) + return; + detach(); d->request.weight = weight; @@ -1122,6 +1146,9 @@ bool QFont::underline() const */ void QFont::setUnderline(bool enable) { + if ((resolve_mask & QFont::UnderlineResolved) && d->underline == enable) + return; + detach(); d->underline = enable; @@ -1145,6 +1172,9 @@ bool QFont::overline() const */ void QFont::setOverline(bool enable) { + if ((resolve_mask & QFont::OverlineResolved) && d->overline == enable) + return; + detach(); d->overline = enable; @@ -1169,6 +1199,9 @@ bool QFont::strikeOut() const */ void QFont::setStrikeOut(bool enable) { + if ((resolve_mask & QFont::StrikeOutResolved) && d->strikeOut == enable) + return; + detach(); d->strikeOut = enable; @@ -1193,6 +1226,9 @@ bool QFont::fixedPitch() const */ void QFont::setFixedPitch(bool enable) { + if ((resolve_mask & QFont::FixedPitchResolved) && d->request.fixedPitch == enable) + return; + detach(); d->request.fixedPitch = enable; @@ -1223,7 +1259,11 @@ bool QFont::kerning() const */ void QFont::setKerning(bool enable) { + if ((resolve_mask & QFont::KerningResolved) && d->kerning == enable) + return; + detach(); + d->kerning = enable; resolve_mask |= QFont::KerningResolved; } @@ -1339,13 +1379,13 @@ QFont::StyleHint QFont::styleHint() const */ void QFont::setStyleHint(StyleHint hint, StyleStrategy strategy) { - detach(); - if ((resolve_mask & (QFont::StyleHintResolved | QFont::StyleStrategyResolved)) && (StyleHint) d->request.styleHint == hint && (StyleStrategy) d->request.styleStrategy == strategy) return; + detach(); + d->request.styleHint = hint; d->request.styleStrategy = strategy; resolve_mask |= QFont::StyleHintResolved; @@ -1360,12 +1400,12 @@ void QFont::setStyleHint(StyleHint hint, StyleStrategy strategy) */ void QFont::setStyleStrategy(StyleStrategy s) { - detach(); - if ((resolve_mask & QFont::StyleStrategyResolved) && s == (StyleStrategy)d->request.styleStrategy) return; + detach(); + d->request.styleStrategy = s; resolve_mask |= QFont::StyleStrategyResolved; } @@ -1593,10 +1633,10 @@ QFont::Capitalization QFont::capitalization() const */ void QFont::setRawMode(bool enable) { - detach(); - if ((bool) d->rawMode == enable) return; + detach(); + d->rawMode = enable; } @@ -2648,9 +2688,9 @@ void QFontCache::clear() QFontEngineData *QFontCache::findEngineData(const QFontDef &def) const { - EngineDataCache::ConstIterator it = engineDataCache.find(def), - end = engineDataCache.end(); - if (it == end) return 0; + EngineDataCache::ConstIterator it = engineDataCache.constFind(def); + if (it == engineDataCache.constEnd()) + return 0; // found return it.value(); @@ -2768,7 +2808,7 @@ void QFontCache::timerEvent(QTimerEvent *) end = engineDataCache.constEnd(); for (; it != end; ++it) { #ifdef QFONTCACHE_DEBUG - FC_DEBUG(" %p: ref %2d", it.value(), int(it.value()->ref)); + FC_DEBUG(" %p: ref %2d", it.value(), int(it.value()->ref.load())); #endif // QFONTCACHE_DEBUG diff --git a/src/gui/text/qglyphrun.cpp b/src/gui/text/qglyphrun.cpp index 48e0b15c85..f46e86e88c 100644 --- a/src/gui/text/qglyphrun.cpp +++ b/src/gui/text/qglyphrun.cpp @@ -473,15 +473,15 @@ void QGlyphRun::setBoundingRect(const QRectF &boundingRect) */ QRectF QGlyphRun::boundingRect() const { - if (!d->boundingRect.isEmpty()) + if (!d->boundingRect.isEmpty() || !d->rawFont.isValid()) return d->boundingRect; qreal minX, minY, maxX, maxY; minX = minY = maxX = maxY = 0; - for (int i=0; i<qMin(d->glyphPositions.size(), d->glyphIndexes.size()); ++i) { - QRectF glyphRect = d->rawFont.boundingRect(d->glyphIndexes.at(i)); - glyphRect.translate(d->glyphPositions.at(i)); + for (int i = 0, n = qMin(d->glyphIndexDataSize, d->glyphPositionDataSize); i < n; ++i) { + QRectF glyphRect = d->rawFont.boundingRect(d->glyphIndexData[i]); + glyphRect.translate(d->glyphPositionData[i]); if (i == 0) { minX = glyphRect.left(); @@ -506,7 +506,7 @@ QRectF QGlyphRun::boundingRect() const */ bool QGlyphRun::isEmpty() const { - return d->glyphIndexes.isEmpty(); + return d->glyphIndexDataSize == 0; } QT_END_NAMESPACE diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index dee1abcfbc..f1191bc4b9 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -388,10 +388,7 @@ qreal QRawFont::unitsPerEm() const */ qreal QRawFont::lineThickness() const { - if (!isValid()) - return 0.0; - - return d->fontEngine->lineThickness().toReal(); + return d->isValid() ? d->fontEngine->lineThickness().toReal() : 0.0; } /*! @@ -400,10 +397,7 @@ qreal QRawFont::lineThickness() const */ qreal QRawFont::underlinePosition() const { - if (!isValid()) - return 0.0; - - return d->fontEngine->underlinePosition().toReal(); + return d->isValid() ? d->fontEngine->underlinePosition().toReal() : 0.0; } /*! @@ -459,23 +453,28 @@ int QRawFont::weight() const */ QVector<quint32> QRawFont::glyphIndexesForString(const QString &text) const { - if (!d->isValid()) - return QVector<quint32>(); + QVector<quint32> glyphIndexes; + if (!d->isValid() || text.isEmpty()) + return glyphIndexes; + + int numGlyphs = text.size(); + glyphIndexes.resize(numGlyphs); - int nglyphs = text.size(); - QVarLengthGlyphLayoutArray glyphs(nglyphs); - if (!glyphIndexesForChars(text.data(), text.size(), glyphs.glyphs, &nglyphs)) { - glyphs.resize(nglyphs); - if (!glyphIndexesForChars(text.data(), text.size(), glyphs.glyphs, &nglyphs)) { + QGlyphLayout glyphs; + glyphs.numGlyphs = numGlyphs; + glyphs.glyphs = glyphIndexes.data(); + if (!d->fontEngine->stringToCMap(text.data(), text.size(), &glyphs, &numGlyphs, QFontEngine::GlyphIndicesOnly)) { + glyphIndexes.resize(numGlyphs); + + glyphs.numGlyphs = numGlyphs; + glyphs.glyphs = glyphIndexes.data(); + if (!d->fontEngine->stringToCMap(text.data(), text.size(), &glyphs, &numGlyphs, QFontEngine::GlyphIndicesOnly)) { Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice"); return QVector<quint32>(); } } - QVector<quint32> glyphIndexes; - for (int i=0; i<nglyphs; ++i) - glyphIndexes.append(glyphs.glyphs[i]); - + glyphIndexes.resize(numGlyphs); return glyphIndexes; } @@ -491,38 +490,32 @@ QVector<quint32> QRawFont::glyphIndexesForString(const QString &text) const */ bool QRawFont::glyphIndexesForChars(const QChar *chars, int numChars, quint32 *glyphIndexes, int *numGlyphs) const { - if (!d->isValid()) + Q_ASSERT(numGlyphs); + if (!d->isValid() || numChars <= 0) { + *numGlyphs = 0; + return false; + } + + if (*numGlyphs <= 0 || !glyphIndexes) { + *numGlyphs = numChars; return false; + } QGlyphLayout glyphs; + glyphs.numGlyphs = *numGlyphs; glyphs.glyphs = glyphIndexes; return d->fontEngine->stringToCMap(chars, numChars, &glyphs, numGlyphs, QFontEngine::GlyphIndicesOnly); } /*! + \fn QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes) const + Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances give the distance from the position of a given glyph to where the next glyph should be drawn to make it appear as if the two glyphs are unspaced. \sa QTextLine::horizontalAdvance(), QFontMetricsF::width() */ -QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes) const -{ - if (!d->isValid()) - return QVector<QPointF>(); - - int numGlyphs = glyphIndexes.size(); - QVarLengthGlyphLayoutArray glyphs(numGlyphs); - memcpy(glyphs.glyphs, glyphIndexes.data(), numGlyphs * sizeof(quint32)); - - d->fontEngine->recalcAdvances(&glyphs, 0); - - QVector<QPointF> advances; - for (int i=0; i<numGlyphs; ++i) - advances.append(QPointF(glyphs.advances_x[i].toReal(), glyphs.advances_y[i].toReal())); - - return advances; -} /*! Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances @@ -535,7 +528,8 @@ QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyph */ bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs) const { - if (!d->isValid()) + Q_ASSERT(glyphIndexes && advances); + if (!d->isValid() || numGlyphs <= 0) return false; QGlyphLayout glyphs; diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h index 1dbde27c73..98314809e8 100644 --- a/src/gui/text/qrawfont.h +++ b/src/gui/text/qrawfont.h @@ -94,7 +94,7 @@ public: int weight() const; QVector<quint32> glyphIndexesForString(const QString &text) const; - QVector<QPointF> advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes) const; + inline QVector<QPointF> advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes) const; bool glyphIndexesForChars(const QChar *chars, int numChars, quint32 *glyphIndexes, int *numGlyphs) const; bool advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs) const; @@ -147,6 +147,14 @@ private: Q_DECLARE_SHARED(QRawFont) +inline QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes) const +{ + QVector<QPointF> advances(glyphIndexes.size()); + if (advancesForGlyphIndexes(glyphIndexes.constData(), advances.data(), glyphIndexes.size())) + return advances; + return QVector<QPointF>(); +} + QT_END_NAMESPACE QT_END_HEADER diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 8527a85369..38fe2f8140 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -157,27 +157,27 @@ private: m_splitter->setPosition(start); QScriptAnalysis itemAnalysis = m_analysis[start]; - if (m_splitter->boundaryReasons() & QTextBoundaryFinder::StartWord) { + if (m_splitter->boundaryReasons() & QTextBoundaryFinder::StartOfItem) itemAnalysis.flags = QScriptAnalysis::Uppercase; - m_splitter->toNextBoundary(); - } + + m_splitter->toNextBoundary(); const int end = start + length; for (int i = start + 1; i < end; ++i) { - - bool atWordBoundary = false; + bool atWordStart = false; if (i == m_splitter->position()) { - if (m_splitter->boundaryReasons() & QTextBoundaryFinder::StartWord - && m_analysis[i].flags < QScriptAnalysis::TabOrObject) - atWordBoundary = true; + if (m_splitter->boundaryReasons() & QTextBoundaryFinder::StartOfItem) { + Q_ASSERT(m_analysis[i].flags < QScriptAnalysis::TabOrObject); + atWordStart = true; + } m_splitter->toNextBoundary(); } if (m_analysis[i] == itemAnalysis && m_analysis[i].flags < QScriptAnalysis::TabOrObject - && !atWordBoundary + && !atWordStart && i - start < MaxItemLength) continue; @@ -185,7 +185,7 @@ private: start = i; itemAnalysis = m_analysis[start]; - if (atWordBoundary) + if (atWordStart) itemAnalysis.flags = QScriptAnalysis::Uppercase; } m_items.append(QScriptItem(start, itemAnalysis)); @@ -1799,7 +1799,6 @@ struct QJustificationPoint { int type; QFixed kashidaWidth; QGlyphLayout glyph; - QFontEngine *fontEngine; }; Q_DECLARE_TYPEINFO(QJustificationPoint, Q_PRIMITIVE_TYPE); @@ -1808,7 +1807,6 @@ static void set(QJustificationPoint *point, int type, const QGlyphLayout &glyph, { point->type = type; point->glyph = glyph; - point->fontEngine = fe; if (type >= HB_Arabic_Normal) { QChar ch(0x640); // Kashida character @@ -2741,13 +2739,13 @@ void QTextEngine::resolveAdditionalFormats() const const QScriptItem *si = &layoutData->items.at(i); int end = si->position + length(si); - while (startIt != addFormatSortedByStart.end() && + while (startIt != addFormatSortedByStart.constEnd() && specialData->addFormats.at(*startIt).start <= si->position) { currentFormats.insert(std::upper_bound(currentFormats.begin(), currentFormats.end(), *startIt), *startIt); ++startIt; } - while (endIt != addFormatSortedByEnd.end() && + while (endIt != addFormatSortedByEnd.constEnd() && specialData->addFormats.at(*endIt).start + specialData->addFormats.at(*endIt).length < end) { currentFormats.remove(qBinaryFind(currentFormats, *endIt) - currentFormats.begin()); ++endIt; diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index 6607c427f5..90cdd7e072 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -3358,8 +3358,8 @@ int QTextFormatCollection::indexForFormat(const QTextFormat &format) bool QTextFormatCollection::hasFormatCached(const QTextFormat &format) const { uint hash = getHash(format.d, format.format_type); - QMultiHash<uint, int>::const_iterator i = hashes.find(hash); - while (i != hashes.end() && i.key() == hash) { + QMultiHash<uint, int>::const_iterator i = hashes.constFind(hash); + while (i != hashes.constEnd() && i.key() == hash) { if (formats.value(i.value()) == format) { return true; } diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp index abe1035cd1..349f8869fd 100644 --- a/src/gui/text/qtextobject.cpp +++ b/src/gui/text/qtextobject.cpp @@ -1185,8 +1185,15 @@ Qt::LayoutDirection QTextBlock::textDirection() const const QChar *p = buffer.constData() + frag->stringPosition; const QChar * const end = p + frag->size_array[0]; while (p < end) { - switch(QChar::direction(p->unicode())) - { + uint ucs4 = p->unicode(); + if (QChar::isHighSurrogate(ucs4) && p + 1 < end) { + ushort low = p[1].unicode(); + if (QChar::isLowSurrogate(low)) { + ucs4 = QChar::surrogateToUcs4(ucs4, low); + ++p; + } + } + switch (QChar::direction(ucs4)) { case QChar::DirL: return Qt::LeftToRight; case QChar::DirR: |