QFont: Don't invalidate engine unless request has been changed
This makes QFont do a "light" detach when the font attributes data has been changed. The new test clearly shows that the engine is now shared between two font instances after changing the kerning attribute. Change-Id: I59db822f459f02d111686dba7101b98e361fada9 Reviewed-by: Marc Mutz <marc.mutz@kdab.com> Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
parent
bdc115d969
commit
9690548113
@ -648,6 +648,24 @@ void QFont::detach()
|
|||||||
d.detach();
|
d.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.
|
Constructs a font object that uses the application's default font.
|
||||||
|
|
||||||
@ -1149,7 +1167,7 @@ void QFont::setUnderline(bool enable)
|
|||||||
if ((resolve_mask & QFont::UnderlineResolved) && d->underline == enable)
|
if ((resolve_mask & QFont::UnderlineResolved) && d->underline == enable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
detach();
|
QFontPrivate::detachButKeepEngineData(this);
|
||||||
|
|
||||||
d->underline = enable;
|
d->underline = enable;
|
||||||
resolve_mask |= QFont::UnderlineResolved;
|
resolve_mask |= QFont::UnderlineResolved;
|
||||||
@ -1175,7 +1193,7 @@ void QFont::setOverline(bool enable)
|
|||||||
if ((resolve_mask & QFont::OverlineResolved) && d->overline == enable)
|
if ((resolve_mask & QFont::OverlineResolved) && d->overline == enable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
detach();
|
QFontPrivate::detachButKeepEngineData(this);
|
||||||
|
|
||||||
d->overline = enable;
|
d->overline = enable;
|
||||||
resolve_mask |= QFont::OverlineResolved;
|
resolve_mask |= QFont::OverlineResolved;
|
||||||
@ -1202,7 +1220,7 @@ void QFont::setStrikeOut(bool enable)
|
|||||||
if ((resolve_mask & QFont::StrikeOutResolved) && d->strikeOut == enable)
|
if ((resolve_mask & QFont::StrikeOutResolved) && d->strikeOut == enable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
detach();
|
QFontPrivate::detachButKeepEngineData(this);
|
||||||
|
|
||||||
d->strikeOut = enable;
|
d->strikeOut = enable;
|
||||||
resolve_mask |= QFont::StrikeOutResolved;
|
resolve_mask |= QFont::StrikeOutResolved;
|
||||||
@ -1262,7 +1280,7 @@ void QFont::setKerning(bool enable)
|
|||||||
if ((resolve_mask & QFont::KerningResolved) && d->kerning == enable)
|
if ((resolve_mask & QFont::KerningResolved) && d->kerning == enable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
detach();
|
QFontPrivate::detachButKeepEngineData(this);
|
||||||
|
|
||||||
d->kerning = enable;
|
d->kerning = enable;
|
||||||
resolve_mask |= QFont::KerningResolved;
|
resolve_mask |= QFont::KerningResolved;
|
||||||
@ -1512,7 +1530,7 @@ void QFont::setLetterSpacing(SpacingType type, qreal spacing)
|
|||||||
d->letterSpacing == newSpacing)
|
d->letterSpacing == newSpacing)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
detach();
|
QFontPrivate::detachButKeepEngineData(this);
|
||||||
|
|
||||||
d->letterSpacing = newSpacing;
|
d->letterSpacing = newSpacing;
|
||||||
d->letterSpacingIsAbsolute = absoluteSpacing;
|
d->letterSpacingIsAbsolute = absoluteSpacing;
|
||||||
@ -1562,7 +1580,7 @@ void QFont::setWordSpacing(qreal spacing)
|
|||||||
d->wordSpacing == newSpacing)
|
d->wordSpacing == newSpacing)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
detach();
|
QFontPrivate::detachButKeepEngineData(this);
|
||||||
|
|
||||||
d->wordSpacing = newSpacing;
|
d->wordSpacing = newSpacing;
|
||||||
resolve_mask |= QFont::WordSpacingResolved;
|
resolve_mask |= QFont::WordSpacingResolved;
|
||||||
@ -1596,7 +1614,7 @@ void QFont::setCapitalization(Capitalization caps)
|
|||||||
capitalization() == caps)
|
capitalization() == caps)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
detach();
|
QFontPrivate::detachButKeepEngineData(this);
|
||||||
|
|
||||||
d->capital = caps;
|
d->capital = caps;
|
||||||
resolve_mask |= QFont::CapitalizationResolved;
|
resolve_mask |= QFont::CapitalizationResolved;
|
||||||
@ -1635,6 +1653,7 @@ void QFont::setRawMode(bool enable)
|
|||||||
{
|
{
|
||||||
if ((bool) d->rawMode == enable) return;
|
if ((bool) d->rawMode == enable) return;
|
||||||
|
|
||||||
|
// might change behavior, thus destroy engine data
|
||||||
detach();
|
detach();
|
||||||
|
|
||||||
d->rawMode = enable;
|
d->rawMode = enable;
|
||||||
|
@ -185,6 +185,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void resolve(uint mask, const QFontPrivate *other);
|
void resolve(uint mask, const QFontPrivate *other);
|
||||||
|
|
||||||
|
static void detachButKeepEngineData(QFont *font);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QFontPrivate &operator=(const QFontPrivate &) { return *this; }
|
QFontPrivate &operator=(const QFontPrivate &) { return *this; }
|
||||||
};
|
};
|
||||||
|
@ -2,6 +2,7 @@ CONFIG += testcase
|
|||||||
CONFIG += parallel_test
|
CONFIG += parallel_test
|
||||||
TARGET = tst_qfont
|
TARGET = tst_qfont
|
||||||
QT += testlib
|
QT += testlib
|
||||||
|
QT += core-private gui-private
|
||||||
!contains(QT_CONFIG, no-widgets): QT += widgets
|
!contains(QT_CONFIG, no-widgets): QT += widgets
|
||||||
SOURCES += tst_qfont.cpp
|
SOURCES += tst_qfont.cpp
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <qfont.h>
|
#include <qfont.h>
|
||||||
|
#include <private/qfont_p.h>
|
||||||
#include <qfontdatabase.h>
|
#include <qfontdatabase.h>
|
||||||
#include <qfontinfo.h>
|
#include <qfontinfo.h>
|
||||||
#include <qstringlist.h>
|
#include <qstringlist.h>
|
||||||
@ -81,6 +82,8 @@ private slots:
|
|||||||
void styleName();
|
void styleName();
|
||||||
void defaultFamily_data();
|
void defaultFamily_data();
|
||||||
void defaultFamily();
|
void defaultFamily();
|
||||||
|
|
||||||
|
void sharing();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Testing get/set functions
|
// Testing get/set functions
|
||||||
@ -685,5 +688,45 @@ void tst_QFont::defaultFamily()
|
|||||||
QVERIFY2(isAcceptable, msgNotAcceptableFont(familyForHint, acceptableFamilies));
|
QVERIFY2(isAcceptable, msgNotAcceptableFont(familyForHint, acceptableFamilies));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QFont::sharing()
|
||||||
|
{
|
||||||
|
QFont f;
|
||||||
|
f.setStyleHint(QFont::Serif);
|
||||||
|
f.exactMatch(); // loads engine
|
||||||
|
QCOMPARE(QFontPrivate::get(f)->ref.load(), 1);
|
||||||
|
QVERIFY(QFontPrivate::get(f)->engineData);
|
||||||
|
QCOMPARE(QFontPrivate::get(f)->engineData->ref.load(), 1);
|
||||||
|
|
||||||
|
QFont f2(f);
|
||||||
|
QVERIFY(QFontPrivate::get(f2) == QFontPrivate::get(f));
|
||||||
|
QCOMPARE(QFontPrivate::get(f2)->ref.load(), 2);
|
||||||
|
QVERIFY(QFontPrivate::get(f2)->engineData);
|
||||||
|
QVERIFY(QFontPrivate::get(f2)->engineData == QFontPrivate::get(f)->engineData);
|
||||||
|
QCOMPARE(QFontPrivate::get(f2)->engineData->ref.load(), 1);
|
||||||
|
|
||||||
|
f2.setKerning(!f.kerning());
|
||||||
|
QVERIFY(QFontPrivate::get(f2) != QFontPrivate::get(f));
|
||||||
|
QCOMPARE(QFontPrivate::get(f2)->ref.load(), 1);
|
||||||
|
QVERIFY(QFontPrivate::get(f2)->engineData);
|
||||||
|
QVERIFY(QFontPrivate::get(f2)->engineData == QFontPrivate::get(f)->engineData);
|
||||||
|
QCOMPARE(QFontPrivate::get(f2)->engineData->ref.load(), 2);
|
||||||
|
|
||||||
|
f2 = f;
|
||||||
|
QVERIFY(QFontPrivate::get(f2) == QFontPrivate::get(f));
|
||||||
|
QCOMPARE(QFontPrivate::get(f2)->ref.load(), 2);
|
||||||
|
QVERIFY(QFontPrivate::get(f2)->engineData);
|
||||||
|
QVERIFY(QFontPrivate::get(f2)->engineData == QFontPrivate::get(f)->engineData);
|
||||||
|
QCOMPARE(QFontPrivate::get(f2)->engineData->ref.load(), 1);
|
||||||
|
|
||||||
|
if (f.pointSize() > 0)
|
||||||
|
f2.setPointSize(f.pointSize() * 2 / 3);
|
||||||
|
else
|
||||||
|
f2.setPixelSize(f.pixelSize() * 2 / 3);
|
||||||
|
QVERIFY(QFontPrivate::get(f2) != QFontPrivate::get(f));
|
||||||
|
QCOMPARE(QFontPrivate::get(f2)->ref.load(), 1);
|
||||||
|
QVERIFY(!QFontPrivate::get(f2)->engineData);
|
||||||
|
QVERIFY(QFontPrivate::get(f2)->engineData != QFontPrivate::get(f)->engineData);
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QFont)
|
QTEST_MAIN(tst_QFont)
|
||||||
#include "tst_qfont.moc"
|
#include "tst_qfont.moc"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user