CoreText: Make sure to keep reference to data when cloning raw font engine

QFontEngine::cloneWithSize() is used by QRawFont internally when switching
a raw-font from one size to another using setPixelSize. For CoreText, we
use a subclass of QCoreTextFontEngine to keep track of the QByteArray data
of a raw-font, but failed to overload cloneWithSize, so we would lose the
data whenever setPixelSize was called, resulting in missing text rendering
in QtWebKit. We now retain the data as we should.

Task-number: QTBUG-65923
Change-Id: I7d4186a3c32a61d48d1e9388e43f2792e8e46081
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
This commit is contained in:
Tor Arne Vestbø 2018-02-05 13:41:37 +01:00
parent fef6b31b99
commit efd5d7a837
3 changed files with 48 additions and 1 deletions

View File

@ -192,6 +192,14 @@ public:
: QCoreTextFontEngine(font, def)
, m_fontData(fontData)
{}
QFontEngine *cloneWithSize(qreal pixelSize) const
{
QFontDef newFontDef = fontDef;
newFontDef.pixelSize = pixelSize;
newFontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi();
return new QCoreTextRawFontEngine(cgFont, newFontDef, m_fontData);
}
QByteArray m_fontData;
};

View File

@ -125,7 +125,7 @@ public:
static QFontEngine::GlyphFormat defaultGlyphFormat;
static QCoreTextFontEngine *create(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
private:
protected:
void init();
QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, bool colorful, const QTransform &m);
CTFontRef ctfont;

View File

@ -93,6 +93,9 @@ private slots:
void fallbackFontsOrder();
void qtbug65923_partal_clone_data();
void qtbug65923_partal_clone();
private:
QString testFont;
QString testFontBoldItalic;
@ -1044,6 +1047,42 @@ void tst_QRawFont::fallbackFontsOrder()
fontDatabase.removeApplicationFont(id);
}
void tst_QRawFont::qtbug65923_partal_clone_data()
{
QTest::addColumn<bool>("shouldClone");
QTest::newRow("Without cloning font engine") << false;
QTest::newRow("Cloning font engine") << true;
}
void tst_QRawFont::qtbug65923_partal_clone()
{
QFile file(testFont);
file.open(QIODevice::ReadOnly);
QByteArray fontData = file.readAll();
QRawFont outerFont;
{
QRawFont innerFont(fontData, 16, QFont::PreferDefaultHinting);
QFETCH(bool, shouldClone);
if (shouldClone) {
// This will trigger QFontEngine::cloneWithSize
innerFont.setPixelSize(innerFont.pixelSize() + 1);
}
outerFont = innerFont;
}
// This will detach if data is shared with the raw font. If the raw font has
// a naked reference to the data, without informing Qt of it via the ref count
// of the byte array, this will result in clearing 'live' data.
fontData.fill('\0');
QVERIFY(!outerFont.boundingRect(42).isEmpty());
}
#endif // QT_NO_RAWFONT
QTEST_MAIN(tst_QRawFont)