summaryrefslogtreecommitdiffstats
path: root/src/gui/text
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/text')
-rw-r--r--src/gui/text/qfont.cpp33
-rw-r--r--src/gui/text/qfont_p.h3
-rw-r--r--src/gui/text/qfontengine_qpa.cpp1
-rw-r--r--src/gui/text/qtextengine.cpp35
-rw-r--r--src/gui/text/qtextengine_p.h16
5 files changed, 61 insertions, 27 deletions
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index 995d48d450..2bc63cbd10 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -649,6 +649,24 @@ void QFont::detach()
}
/*!
+ \internal
+ Detaches the font object from common font attributes data.
+ Call this instead of QFont::detach() if the only font attributes data
+ has been changed (underline, letterSpacing, kerning, etc.).
+*/
+void QFontPrivate::detachButKeepEngineData(QFont *font)
+{
+ if (font->d->ref.load() == 1)
+ return;
+
+ QFontEngineData *engineData = font->d->engineData;
+ if (engineData)
+ engineData->ref.ref();
+ font->d.detach();
+ font->d->engineData = engineData;
+}
+
+/*!
Constructs a font object that uses the application's default font.
\sa QGuiApplication::setFont(), QGuiApplication::font()
@@ -1149,7 +1167,7 @@ void QFont::setUnderline(bool enable)
if ((resolve_mask & QFont::UnderlineResolved) && d->underline == enable)
return;
- detach();
+ QFontPrivate::detachButKeepEngineData(this);
d->underline = enable;
resolve_mask |= QFont::UnderlineResolved;
@@ -1175,7 +1193,7 @@ void QFont::setOverline(bool enable)
if ((resolve_mask & QFont::OverlineResolved) && d->overline == enable)
return;
- detach();
+ QFontPrivate::detachButKeepEngineData(this);
d->overline = enable;
resolve_mask |= QFont::OverlineResolved;
@@ -1202,7 +1220,7 @@ void QFont::setStrikeOut(bool enable)
if ((resolve_mask & QFont::StrikeOutResolved) && d->strikeOut == enable)
return;
- detach();
+ QFontPrivate::detachButKeepEngineData(this);
d->strikeOut = enable;
resolve_mask |= QFont::StrikeOutResolved;
@@ -1262,7 +1280,7 @@ void QFont::setKerning(bool enable)
if ((resolve_mask & QFont::KerningResolved) && d->kerning == enable)
return;
- detach();
+ QFontPrivate::detachButKeepEngineData(this);
d->kerning = enable;
resolve_mask |= QFont::KerningResolved;
@@ -1512,7 +1530,7 @@ void QFont::setLetterSpacing(SpacingType type, qreal spacing)
d->letterSpacing == newSpacing)
return;
- detach();
+ QFontPrivate::detachButKeepEngineData(this);
d->letterSpacing = newSpacing;
d->letterSpacingIsAbsolute = absoluteSpacing;
@@ -1562,7 +1580,7 @@ void QFont::setWordSpacing(qreal spacing)
d->wordSpacing == newSpacing)
return;
- detach();
+ QFontPrivate::detachButKeepEngineData(this);
d->wordSpacing = newSpacing;
resolve_mask |= QFont::WordSpacingResolved;
@@ -1596,7 +1614,7 @@ void QFont::setCapitalization(Capitalization caps)
capitalization() == caps)
return;
- detach();
+ QFontPrivate::detachButKeepEngineData(this);
d->capital = caps;
resolve_mask |= QFont::CapitalizationResolved;
@@ -1635,6 +1653,7 @@ void QFont::setRawMode(bool enable)
{
if ((bool) d->rawMode == enable) return;
+ // might change behavior, thus destroy engine data
detach();
d->rawMode = enable;
diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h
index f32b6e72a4..2a37b56d87 100644
--- a/src/gui/text/qfont_p.h
+++ b/src/gui/text/qfont_p.h
@@ -185,6 +185,9 @@ public:
}
void resolve(uint mask, const QFontPrivate *other);
+
+ static void detachButKeepEngineData(QFont *font);
+
private:
QFontPrivate &operator=(const QFontPrivate &) { return *this; }
};
diff --git a/src/gui/text/qfontengine_qpa.cpp b/src/gui/text/qfontengine_qpa.cpp
index 37195d5f61..c6e8a53284 100644
--- a/src/gui/text/qfontengine_qpa.cpp
+++ b/src/gui/text/qfontengine_qpa.cpp
@@ -726,6 +726,7 @@ void QFontEngineMultiQPA::setFallbackFamiliesList(const QStringList &fallbacks)
// Turns out we lied about having any fallback at all.
fallbackFamilies << fe->fontDef.family;
engines[1] = fe;
+ fe->ref.ref();
}
fallbacksQueried = true;
}
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 38fe2f8140..82cff6a043 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -1015,10 +1015,22 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
casedString.resize(entire_shaper_item.item.length);
HB_UChar16 *uc = casedString.data();
for (uint i = 0; i < entire_shaper_item.item.length; ++i) {
- if(si.analysis.flags == QScriptAnalysis::Lowercase)
- uc[i] = QChar::toLower(entire_shaper_item.string[si.position + i]);
- else
- uc[i] = QChar::toUpper(entire_shaper_item.string[si.position + i]);
+ uint ucs4 = entire_shaper_item.string[si.position + i];
+ if (QChar::isHighSurrogate(ucs4)) {
+ uc[i] = ucs4; // high part never changes in simple casing
+ if (i + 1 < entire_shaper_item.item.length) {
+ ushort low = entire_shaper_item.string[si.position + i + 1];
+ if (QChar::isLowSurrogate(low)) {
+ ucs4 = QChar::surrogateToUcs4(ucs4, low);
+ ucs4 = si.analysis.flags == QScriptAnalysis::Lowercase ? QChar::toLower(ucs4)
+ : QChar::toUpper(ucs4);
+ uc[++i] = QChar::lowSurrogate(ucs4);
+ }
+ }
+ } else {
+ uc[i] = si.analysis.flags == QScriptAnalysis::Lowercase ? QChar::toLower(ucs4)
+ : QChar::toUpper(ucs4);
+ }
}
entire_shaper_item.item.pos = 0;
entire_shaper_item.string = uc;
@@ -3060,8 +3072,7 @@ void QTextEngine::drawItemDecorationList(QPainter *painter, const ItemDecoration
foreach (const ItemDecoration &decoration, decorationList) {
painter->setPen(decoration.pen);
- QLineF line(decoration.x1, decoration.y, decoration.x2, decoration.y);
- painter->drawLine(line);
+ painter->drawLine(QLineF(decoration.x1, decoration.y, decoration.x2, decoration.y));
}
}
@@ -3069,13 +3080,23 @@ void QTextEngine::drawDecorations(QPainter *painter)
{
QPen oldPen = painter->pen();
+ bool wasCompatiblePainting = painter->renderHints()
+ & QPainter::Qt4CompatiblePainting;
+
+ if (wasCompatiblePainting)
+ painter->setRenderHint(QPainter::Qt4CompatiblePainting, false);
+
adjustUnderlines();
drawItemDecorationList(painter, underlineList);
drawItemDecorationList(painter, strikeOutList);
drawItemDecorationList(painter, overlineList);
- painter->setPen(oldPen);
clearDecorations();
+
+ if (wasCompatiblePainting)
+ painter->setRenderHint(QPainter::Qt4CompatiblePainting);
+
+ painter->setPen(oldPen);
}
void QTextEngine::clearDecorations()
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index bef461f448..aff5e1cb7f 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -390,7 +390,7 @@ struct Q_AUTOTEST_EXPORT QScriptLine
mutable uint gridfitted : 1;
uint hasTrailingSpaces : 1;
uint leadingIncluded : 1;
- QFixed height() const { return (ascent + descent).ceil()
+ QFixed height() const { return ascent + descent
+ (leadingIncluded? qMax(QFixed(),leading) : QFixed()); }
QFixed base() const { return ascent
+ (leadingIncluded ? qMax(QFixed(),leading) : QFixed()); }
@@ -540,24 +540,14 @@ public:
int findItem(int strPos) const;
inline QTextFormatCollection *formats() const {
-#ifdef QT_BUILD_COMPAT_LIB
- return 0; // Compat should never reference this symbol
-#else
if (block.docHandle())
return block.docHandle()->formatCollection();
- else if (specialData)
- return specialData->formats.data();
-
- return 0;
-#endif
+ return specialData ? specialData->formats.data() : 0;
}
QTextCharFormat format(const QScriptItem *si) const;
inline QAbstractTextDocumentLayout *docLayout() const {
-#ifdef QT_BUILD_COMPAT_LIB
- return 0; // Compat should never reference this symbol
-#else
+ Q_ASSERT(block.docHandle());
return block.docHandle()->document()->documentLayout();
-#endif
}
int formatIndex(const QScriptItem *si) const;