macOS/iOS: Fix garbled text under some conditions
There seems to be an issue in CoreText which may cause an existing font descriptor to give unreliable results if it refers to one of the system theme fonts. Since we do not know all function calls or events that may trigger this bug, the safe route is to always create fresh font descriptors when creating fonts for these descriptors. The impact on performance should be small, as Qt has its own internal caches. [ChangeLog][macOS/iOS][Text] Fixed an issue where text using one of the system theme fonts would under certain circumstances display random glyphs. Task-number: QTBUG-63476 Change-Id: I9e9b253018c63976345eec1439a6b78de2cab869 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>bb10
parent
8dfcc3b023
commit
153311706c
|
|
@ -416,7 +416,19 @@ extern CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef);
|
|||
template <>
|
||||
QFontEngine *QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine>::fontEngine(const QFontDef &fontDef, void *usrPtr)
|
||||
{
|
||||
CTFontDescriptorRef descriptor = static_cast<CTFontDescriptorRef>(usrPtr);
|
||||
QCFType<CTFontDescriptorRef> descriptor = QCFType<CTFontDescriptorRef>::constructFromGet(
|
||||
static_cast<CTFontDescriptorRef>(usrPtr));
|
||||
|
||||
// CoreText will sometimes invalidate information in font descriptors that refer
|
||||
// to system fonts in certain function calls or application states. While the descriptor
|
||||
// looks the same from the outside, some internal plumbing is different, causing the results
|
||||
// of creating CTFonts from those descriptors unreliable. The work-around for this
|
||||
// is to copy the attributes of those descriptors each time we make a new CTFont
|
||||
// from them instead of referring to the original, as that may trigger the CoreText bug.
|
||||
if (m_systemFontDescriptors.contains(descriptor)) {
|
||||
QCFType<CFDictionaryRef> attributes = CTFontDescriptorCopyAttributes(descriptor);
|
||||
descriptor = CTFontDescriptorCreateWithAttributes(attributes);
|
||||
}
|
||||
|
||||
// Since we do not pass in the destination DPI to CoreText when making
|
||||
// the font, we need to pass in a point size which is scaled to include
|
||||
|
|
@ -427,14 +439,10 @@ QFontEngine *QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine>::fontEngine
|
|||
qreal scaledPointSize = fontDef.pixelSize;
|
||||
|
||||
CGAffineTransform matrix = qt_transform_from_fontdef(fontDef);
|
||||
CTFontRef font = CTFontCreateWithFontDescriptor(descriptor, scaledPointSize, &matrix);
|
||||
if (font) {
|
||||
QFontEngine *engine = new QCoreTextFontEngine(font, fontDef);
|
||||
CFRelease(font);
|
||||
return engine;
|
||||
}
|
||||
if (QCFType<CTFontRef> font = CTFontCreateWithFontDescriptor(descriptor, scaledPointSize, &matrix))
|
||||
return new QCoreTextFontEngine(font, fontDef);
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_FREETYPE
|
||||
|
|
|
|||
|
|
@ -91,12 +91,14 @@ public:
|
|||
QFont *themeFont(QPlatformTheme::Font) const;
|
||||
const QHash<QPlatformTheme::Font, QFont *> &themeFonts() const;
|
||||
|
||||
protected:
|
||||
mutable QSet<CTFontDescriptorRef> m_systemFontDescriptors;
|
||||
|
||||
private:
|
||||
void populateFromDescriptor(CTFontDescriptorRef font, const QString &familyName = QString());
|
||||
|
||||
mutable QString defaultFontName;
|
||||
|
||||
mutable QSet<CTFontDescriptorRef> m_systemFontDescriptors;
|
||||
mutable QHash<QPlatformTheme::Font, QFont *> m_themeFonts;
|
||||
bool m_hasPopulatedAliases;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue