summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonstantin Ritt <ritt.ks@gmail.com>2012-10-17 14:31:33 +0300
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-10-19 18:04:36 +0200
commit9690548113e03614c770cec44a527e6c1edce6ab (patch)
tree98f30932311f463468d5095bd9669843fb794476
parentbdc115d9698d4f3cf5ce089dbddca75e425d3eeb (diff)
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>
-rw-r--r--src/gui/text/qfont.cpp33
-rw-r--r--src/gui/text/qfont_p.h3
-rw-r--r--tests/auto/gui/text/qfont/qfont.pro1
-rw-r--r--tests/auto/gui/text/qfont/tst_qfont.cpp43
4 files changed, 73 insertions, 7 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/tests/auto/gui/text/qfont/qfont.pro b/tests/auto/gui/text/qfont/qfont.pro
index 86178f3fa6..562294dd66 100644
--- a/tests/auto/gui/text/qfont/qfont.pro
+++ b/tests/auto/gui/text/qfont/qfont.pro
@@ -2,6 +2,7 @@ CONFIG += testcase
CONFIG += parallel_test
TARGET = tst_qfont
QT += testlib
+QT += core-private gui-private
!contains(QT_CONFIG, no-widgets): QT += widgets
SOURCES += tst_qfont.cpp
diff --git a/tests/auto/gui/text/qfont/tst_qfont.cpp b/tests/auto/gui/text/qfont/tst_qfont.cpp
index 287fd728ff..3fe23bf1ff 100644
--- a/tests/auto/gui/text/qfont/tst_qfont.cpp
+++ b/tests/auto/gui/text/qfont/tst_qfont.cpp
@@ -44,6 +44,7 @@
#include <qfont.h>
+#include <private/qfont_p.h>
#include <qfontdatabase.h>
#include <qfontinfo.h>
#include <qstringlist.h>
@@ -81,6 +82,8 @@ private slots:
void styleName();
void defaultFamily_data();
void defaultFamily();
+
+ void sharing();
};
// Testing get/set functions
@@ -685,5 +688,45 @@ void tst_QFont::defaultFamily()
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)
#include "tst_qfont.moc"