summaryrefslogtreecommitdiffstats
path: root/src/gui/text
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/text')
-rw-r--r--src/gui/text/qfont.cpp60
-rw-r--r--src/gui/text/qglyphrun.cpp10
-rw-r--r--src/gui/text/qrawfont.cpp70
-rw-r--r--src/gui/text/qrawfont.h10
-rw-r--r--src/gui/text/qtextengine.cpp26
-rw-r--r--src/gui/text/qtextformat.cpp4
-rw-r--r--src/gui/text/qtextobject.cpp11
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: