From 153311706cd21d91ba06a7f86228dd575bd9672e Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 30 Nov 2017 15:00:26 +0100 Subject: 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 --- .../fontdatabases/mac/qcoretextfontdatabase.mm | 24 ++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm') diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index 6347d4d231..237e8a89a5 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -416,7 +416,19 @@ extern CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef); template <> QFontEngine *QCoreTextFontDatabaseEngineFactory::fontEngine(const QFontDef &fontDef, void *usrPtr) { - CTFontDescriptorRef descriptor = static_cast(usrPtr); + QCFType descriptor = QCFType::constructFromGet( + static_cast(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 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::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 font = CTFontCreateWithFontDescriptor(descriptor, scaledPointSize, &matrix)) + return new QCoreTextFontEngine(font, fontDef); - return NULL; + return nullptr; } #ifndef QT_NO_FREETYPE -- cgit v1.2.3