diff options
Diffstat (limited to 'src/gui/text')
-rw-r--r-- | src/gui/text/qfont.cpp | 33 | ||||
-rw-r--r-- | src/gui/text/qfont_p.h | 3 | ||||
-rw-r--r-- | src/gui/text/qfontengine_qpa.cpp | 1 | ||||
-rw-r--r-- | src/gui/text/qtextengine.cpp | 35 | ||||
-rw-r--r-- | src/gui/text/qtextengine_p.h | 16 |
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; |