From 17fc188aec5806167d3c6165b0ad299a8d2a6bcf Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 11 Apr 2017 09:35:52 +0200 Subject: Implement maxCharWidth() for DirectWrite engine This is used to create the bounding box in QFontEngine::properties(), which in turn is used for the FontBBox when generating PDFs. The result was that the bounding width in the output was 0 and Adobe Reader complained that the PDF was malformed. We could implement the proper bounding rect in properties() at some point, instead of assuming an origin at x = 0 for instance. The metrics for that are in the head table. But for silencing the warning in Reader, just implementing the maxCharWidth() function is sufficient. [ChangeLog][Windows][PDF] Fixed a bug in PDF output when using high-dpi scaling which was causing the display of warnings when opening the file in Adobe Reader. Task-number: QTBUG-58954 Change-Id: I2540571863d4dd0f85af533b591f75dad3f0d75b Reviewed-by: Simon Hausmann --- .../fontdatabases/windows/qwindowsfontenginedirectwrite.cpp | 12 ++++++++++-- .../fontdatabases/windows/qwindowsfontenginedirectwrite_p.h | 1 + 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'src/platformsupport/fontdatabases') diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp index 683b7f65ad..6f2755a05a 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp @@ -355,6 +355,13 @@ void QWindowsFontEngineDirectWrite::collectMetrics() m_faceId.filename = QFile::encodeName(filenameFromFontFile(fontFile)); fontFile->Release(); } + + QByteArray table = getSfntTable(MAKE_TAG('h', 'h', 'e', 'a')); + const int advanceWidthMaxLocation = 10; + if (table.size() >= advanceWidthMaxLocation + sizeof(quint16)) { + quint16 advanceWidthMax = qFromBigEndian(table.constData() + advanceWidthMaxLocation); + m_maxAdvanceWidth = DESIGN_TO_LOGICAL(advanceWidthMax); + } } QFixed QWindowsFontEngineDirectWrite::underlinePosition() const @@ -607,8 +614,9 @@ QFixed QWindowsFontEngineDirectWrite::xHeight() const qreal QWindowsFontEngineDirectWrite::maxCharWidth() const { - // ### - return 0; + return fontDef.styleStrategy & QFont::ForceIntegerMetrics + ? m_maxAdvanceWidth.round().toReal() + : m_maxAdvanceWidth.toReal(); } QImage QWindowsFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t) diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h index 65b16b9ba7..db4e79e44f 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h @@ -143,6 +143,7 @@ private: QFixed m_descent; QFixed m_xHeight; QFixed m_lineGap; + QFixed m_maxAdvanceWidth; FaceId m_faceId; QString m_uniqueFamilyName; }; -- cgit v1.2.3 From 5ad2e1cea1b2c08950c91174840f542806954d99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 20 Mar 2017 19:31:29 +0100 Subject: Populate application fonts via font descriptors on Apple platforms Instead of registering the font via CTFontManagerRegister we just create a font descriptor for the data/URL and populate that like normal system fonts. This makes the code more similar to how we deal with other fonts, shaves off a ms during font registration due to not registering the font, and fixes an issue on iOS where CTFontManagerRegister would invalidate earlier populated system font descriptors. Task-number: QTBUG-56765 Change-Id: I002a65075b15837c9a2d22573020d4c834111837 Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../fontdatabases/mac/qcoretextfontdatabase.mm | 71 ++++++---------------- .../fontdatabases/mac/qcoretextfontdatabase_p.h | 7 +-- 2 files changed, 22 insertions(+), 56 deletions(-) (limited to 'src/platformsupport/fontdatabases') diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index ce9b61ba4c..d0b28b856b 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -199,10 +199,6 @@ static CFArrayRef availableFamilyNames() void QCoreTextFontDatabase::populateFontDatabase() { - // The caller (QFontDB) expects the db to be populate only with system fonts, so we need - // to make sure that any previously registered app fonts become invisible. - removeApplicationFonts(); - QCFType familyNames = availableFamilyNames(); const int numberOfFamilies = CFArrayGetCount(familyNames); for (int i = 0; i < numberOfFamilies; ++i) { @@ -585,21 +581,19 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo } template <> -CFArrayRef QCoreTextFontDatabaseEngineFactory::createDescriptorArrayForFont(CTFontRef font, const QString &fileName) +CFArrayRef QCoreTextFontDatabaseEngineFactory::createDescriptorArrayForDescriptor(CTFontDescriptorRef descriptor, const QString &fileName) { Q_UNUSED(fileName) CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - QCFType descriptor = CTFontCopyFontDescriptor(font); CFArrayAppendValue(array, descriptor); return array; } #ifndef QT_NO_FREETYPE template <> -CFArrayRef QCoreTextFontDatabaseEngineFactory::createDescriptorArrayForFont(CTFontRef font, const QString &fileName) +CFArrayRef QCoreTextFontDatabaseEngineFactory::createDescriptorArrayForDescriptor(CTFontDescriptorRef descriptor, const QString &fileName) { CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - QCFType descriptor = CTFontCopyFontDescriptor(font); // The physical font source URL (usually a local file or Qt resource) is only required for // FreeType, when using non-system fonts, and needs some hackery to attach in a format @@ -630,44 +624,36 @@ CFArrayRef QCoreTextFontDatabaseEngineFactory::createDescriptorAr QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName) { QCFType fonts; - QStringList families; - CFErrorRef error = 0; if (!fontData.isEmpty()) { QByteArray* fontDataCopy = new QByteArray(fontData); QCFType dataProvider = CGDataProviderCreateWithData(fontDataCopy, fontDataCopy->constData(), fontDataCopy->size(), releaseFontData); - QCFType cgFont = CGFontCreateWithDataProvider(dataProvider); - if (cgFont) { - if (CTFontManagerRegisterGraphicsFont(cgFont, &error)) { - QCFType font = CTFontCreateWithGraphicsFont(cgFont, 0.0, NULL, NULL); - fonts = createDescriptorArrayForFont(font, fileName); - m_applicationFonts.append(QVariant::fromValue(QCFType::constructFromGet(cgFont))); - } + if (QCFType cgFont = CGFontCreateWithDataProvider(dataProvider)) { + QCFType ctFont = CTFontCreateWithGraphicsFont(cgFont, 0.0, NULL, NULL); + QCFType descriptor = CTFontCopyFontDescriptor(ctFont); + fonts = createDescriptorArrayForDescriptor(descriptor, fileName); } } else { - QCFType fontURL = CFURLCreateWithFileSystemPath(NULL, QCFString(fileName), kCFURLPOSIXPathStyle, false); - if (CTFontManagerRegisterFontsForURL(fontURL, kCTFontManagerScopeProcess, &error)) { - fonts = CTFontManagerCreateFontDescriptorsFromURL(fontURL); - m_applicationFonts.append(QVariant::fromValue(QCFType::constructFromGet(fontURL))); - } + QCFType fontURL = QUrl::fromLocalFile(fileName).toCFURL(); + fonts = CTFontManagerCreateFontDescriptorsFromURL(fontURL); } - if (error) { - NSLog(@"Unable to register font: %@", error); - CFRelease(error); - } + if (!fonts) + return QStringList(); - if (fonts) { - const int numFonts = CFArrayGetCount(fonts); - for (int i = 0; i < numFonts; ++i) { - CTFontDescriptorRef fontDescriptor = CTFontDescriptorRef(CFArrayGetValueAtIndex(fonts, i)); - populateFromDescriptor(fontDescriptor); - QCFType familyName = CFStringRef(CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontFamilyNameAttribute)); - families.append(QCFString(familyName)); - } + QStringList families; + const int numFonts = CFArrayGetCount(fonts); + for (int i = 0; i < numFonts; ++i) { + CTFontDescriptorRef fontDescriptor = CTFontDescriptorRef(CFArrayGetValueAtIndex(fonts, i)); + populateFromDescriptor(fontDescriptor); + QCFType familyName = CFStringRef(CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontFamilyNameAttribute)); + families.append(QString::fromCFString(familyName)); } + // Note: We don't do font matching via CoreText for application fonts, so we don't + // need to enable font matching for them via CTFontManagerEnableFontDescriptors. + return families; } @@ -846,22 +832,5 @@ QList QCoreTextFontDatabase::standardSizes() const return ret; } -void QCoreTextFontDatabase::removeApplicationFonts() -{ - if (m_applicationFonts.isEmpty()) - return; - - for (const QVariant &font : qAsConst(m_applicationFonts)) { - CFErrorRef error; - if (font.canConvert(qMetaTypeId >())) { - CTFontManagerUnregisterGraphicsFont(font.value >(), &error); - } else if (font.canConvert(qMetaTypeId >())) { - CTFontManagerUnregisterFontsForURL(font.value >(), kCTFontManagerScopeProcess, &error); - } - } - - m_applicationFonts.clear(); -} - QT_END_NAMESPACE diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h index 8edf60b5fa..11ea0bea02 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h @@ -91,13 +91,10 @@ public: private: void populateFromDescriptor(CTFontDescriptorRef font, const QString &familyName = QString()); - virtual CFArrayRef createDescriptorArrayForFont(CTFontRef font, const QString &fileName) = 0; + virtual CFArrayRef createDescriptorArrayForDescriptor(CTFontDescriptorRef descriptor, const QString &fileName) = 0; mutable QString defaultFontName; - void removeApplicationFonts(); - - QVector m_applicationFonts; mutable QSet m_systemFontDescriptors; mutable QHash m_themeFonts; }; @@ -112,7 +109,7 @@ public: QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override; QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) override; protected: - CFArrayRef createDescriptorArrayForFont(CTFontRef font, const QString &fileName) override; + CFArrayRef createDescriptorArrayForDescriptor(CTFontDescriptorRef descriptor, const QString &fileName) override; }; QT_END_NAMESPACE -- cgit v1.2.3 From 31273f079eb1431a3f51bef5c390a1c15cbe382c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 3 Apr 2017 19:07:43 +0200 Subject: macOS: Don't marshal app font data via URL when using FreeType font engine Font descriptors can have attached attributes of any kind, not just pre- defined constants like kCTFontURLAttribute. We take advantage of this and attach the font data that was passed into addApplicationFont() to the font descriptor, so we can read it out directly when later creating an engine for it. This removes the need to build up a URL to represent the font data, which also didn't work for the memory-font use-case. The FreeType font engine now passes the same tst_QFontDatabase tests on macOS as the native CoreText font engine. This also fixes the leak caused by CTFontCreateWithGraphicsFont never releasing the graphics font, resulting in releaseFontData never being called: http://stackoverflow.com/questions/40805382/ We're now cleaning up the font data in releaseHandle, based on the attribute set on the font descriptor. Change-Id: Iba15222ec919f989e29fd98b263d9fb182c4d710 Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../fontdatabases/mac/qcoretextfontdatabase.mm | 101 +++++++-------------- .../fontdatabases/mac/qcoretextfontdatabase_p.h | 3 - 2 files changed, 33 insertions(+), 71 deletions(-) (limited to 'src/platformsupport/fontdatabases') diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index d0b28b856b..1862900d48 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -354,9 +354,22 @@ void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font, con fd.pixelSize, fd.fixedPitch, fd.writingSystems, (void *) font); } +static NSString * const kQtFontDataAttribute = @"QtFontDataAttribute"; + +template +T *descriptorAttribute(CTFontDescriptorRef descriptor, CFStringRef name) +{ + return [static_cast(CTFontDescriptorCopyAttribute(descriptor, name)) autorelease]; +} + void QCoreTextFontDatabase::releaseHandle(void *handle) { - CFRelease(CTFontDescriptorRef(handle)); + CTFontDescriptorRef descriptor = static_cast(handle); + if (NSValue *fontDataValue = descriptorAttribute(descriptor, (CFStringRef)kQtFontDataAttribute)) { + QByteArray *fontData = static_cast(fontDataValue.pointerValue); + delete fontData; + } + CFRelease(descriptor); } extern CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef); @@ -391,30 +404,21 @@ QFontEngine *QCoreTextFontDatabaseEngineFactory::fontEngine(const { CTFontDescriptorRef descriptor = static_cast(usrPtr); - QByteArray filename; - if (NSURL *url = [static_cast(CTFontDescriptorCopyAttribute(descriptor, kCTFontURLAttribute)) autorelease]) { - if ([url.scheme isEqual:@"qrc"]) - filename = ":"; - else if (!url.fileURL) - qWarning() << "QFontDatabase: Unknown scheme" << url.scheme << "in font descriptor URL"; + if (NSURL *url = descriptorAttribute(descriptor, kCTFontURLAttribute)) { + Q_ASSERT(url.fileURL); + QFontEngine::FaceId faceId; + faceId.filename = QString::fromNSString(url.path).toUtf8(); + return QFontEngineFT::create(fontDef, faceId); - filename += QString::fromNSString(url.path).toUtf8(); + } else if (NSValue *fontDataValue = descriptorAttribute(descriptor, (CFStringRef)kQtFontDataAttribute)) { + QByteArray *fontData = static_cast(fontDataValue.pointerValue); + return QFontEngineFT::create(*fontData, fontDef.pixelSize, + static_cast(fontDef.hintingPreference)); } - Q_ASSERT(!filename.isEmpty()); - - QFontEngine::FaceId faceId; - faceId.filename = filename; - return QFontEngineFT::create(fontDef, faceId); + Q_UNREACHABLE(); } #endif -static void releaseFontData(void* info, const void* data, size_t size) -{ - Q_UNUSED(data); - Q_UNUSED(size); - delete (QByteArray*)info; -} - template <> QFontEngine *QCoreTextFontDatabaseEngineFactory::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) { @@ -580,59 +584,20 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo return fallbackLists[styleLookupKey.arg(styleHint)]; } -template <> -CFArrayRef QCoreTextFontDatabaseEngineFactory::createDescriptorArrayForDescriptor(CTFontDescriptorRef descriptor, const QString &fileName) -{ - Q_UNUSED(fileName) - CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - CFArrayAppendValue(array, descriptor); - return array; -} - -#ifndef QT_NO_FREETYPE -template <> -CFArrayRef QCoreTextFontDatabaseEngineFactory::createDescriptorArrayForDescriptor(CTFontDescriptorRef descriptor, const QString &fileName) -{ - CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - - // The physical font source URL (usually a local file or Qt resource) is only required for - // FreeType, when using non-system fonts, and needs some hackery to attach in a format - // agreeable to OSX. - if (!fileName.isEmpty()) { - QCFType fontURL; - - if (fileName.startsWith(QLatin1String(":/"))) { - // QUrl::fromLocalFile() doesn't accept qrc pseudo-paths like ":/fonts/myfont.ttf". - // Therefore construct from QString with the qrc:// scheme -> "qrc:///fonts/myfont.ttf". - fontURL = QUrl(QStringLiteral("qrc://") + fileName.mid(1)).toCFURL(); - } else { - // At this point we hope that filename is in a format that QUrl can handle. - fontURL = QUrl::fromLocalFile(fileName).toCFURL(); - } - - QCFType attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, - &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFDictionaryAddValue(attributes, kCTFontURLAttribute, fontURL); - descriptor = CTFontDescriptorCreateCopyWithAttributes(descriptor, attributes); - } - - CFArrayAppendValue(array, descriptor); - return array; -} -#endif - QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName) { QCFType fonts; if (!fontData.isEmpty()) { - QByteArray* fontDataCopy = new QByteArray(fontData); - QCFType dataProvider = CGDataProviderCreateWithData(fontDataCopy, - fontDataCopy->constData(), fontDataCopy->size(), releaseFontData); - if (QCFType cgFont = CGFontCreateWithDataProvider(dataProvider)) { - QCFType ctFont = CTFontCreateWithGraphicsFont(cgFont, 0.0, NULL, NULL); - QCFType descriptor = CTFontCopyFontDescriptor(ctFont); - fonts = createDescriptorArrayForDescriptor(descriptor, fileName); + QCFType fontDataReference = fontData.toRawCFData(); + if (QCFType descriptor = CTFontManagerCreateFontDescriptorFromData(fontDataReference)) { + // There's no way to get the data back out of a font descriptor created with + // CTFontManagerCreateFontDescriptorFromData, so we attach the data manually. + NSDictionary *attributes = @{ kQtFontDataAttribute : [NSValue valueWithPointer:new QByteArray(fontData)] }; + descriptor = CTFontDescriptorCreateCopyWithAttributes(descriptor, (CFDictionaryRef)attributes); + CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); + CFArrayAppendValue(array, descriptor); + fonts = array; } } else { QCFType fontURL = QUrl::fromLocalFile(fileName).toCFURL(); diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h index 11ea0bea02..a7529b7fb0 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h @@ -91,7 +91,6 @@ public: private: void populateFromDescriptor(CTFontDescriptorRef font, const QString &familyName = QString()); - virtual CFArrayRef createDescriptorArrayForDescriptor(CTFontDescriptorRef descriptor, const QString &fileName) = 0; mutable QString defaultFontName; @@ -108,8 +107,6 @@ class QCoreTextFontDatabaseEngineFactory : public QCoreTextFontDatabase public: QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override; QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) override; -protected: - CFArrayRef createDescriptorArrayForDescriptor(CTFontDescriptorRef descriptor, const QString &fileName) override; }; QT_END_NAMESPACE -- cgit v1.2.3 From f9226217d1b653e7786f8b920f6b36bfd4bd0512 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 5 Apr 2017 13:35:11 +0200 Subject: macOS: Prevent leaking font data when creating QRawFont from QByteArrays CTFontCreateWithGraphicsFont has a bug causing it to never release the graphics font, which cascades down to the data provider never being released and releaseFontData never being called. Instead of relying on a callback to release the byte array font data, we attach the font data to the engine's lifetime. Note that we are still leaking the CoreFoundation types. Change-Id: I6eda4212638ccc9439b90e004222272d204c707a Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../fontdatabases/mac/qcoretextfontdatabase.mm | 33 ++++--------------- .../fontdatabases/mac/qfontengine_coretext.mm | 37 ++++++++++++++++++++++ .../fontdatabases/mac/qfontengine_coretext_p.h | 2 ++ 3 files changed, 45 insertions(+), 27 deletions(-) (limited to 'src/platformsupport/fontdatabases') diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index 1862900d48..3b9a456be0 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -419,37 +419,16 @@ QFontEngine *QCoreTextFontDatabaseEngineFactory::fontEngine(const } #endif -template <> -QFontEngine *QCoreTextFontDatabaseEngineFactory::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) +template +QFontEngine *QCoreTextFontDatabaseEngineFactory::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) { - Q_UNUSED(hintingPreference); - - QByteArray* fontDataCopy = new QByteArray(fontData); - QCFType dataProvider = CGDataProviderCreateWithData(fontDataCopy, - fontDataCopy->constData(), fontDataCopy->size(), releaseFontData); - - CGFontRef cgFont = CGFontCreateWithDataProvider(dataProvider); - - QFontEngine *fontEngine = NULL; - if (cgFont == NULL) { - qWarning("QCoreTextFontDatabase::fontEngine: CGFontCreateWithDataProvider failed"); - } else { - QFontDef def; - def.pixelSize = pixelSize; - def.pointSize = pixelSize * 72.0 / qt_defaultDpi(); - fontEngine = new QCoreTextFontEngine(cgFont, def); - CFRelease(cgFont); - } - - return fontEngine; + return T::create(fontData, pixelSize, hintingPreference); } +// Explicitly instantiate so that we don't need the plugin to involve FreeType +template class QCoreTextFontDatabaseEngineFactory; #ifndef QT_NO_FREETYPE -template <> -QFontEngine *QCoreTextFontDatabaseEngineFactory::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) -{ - return QFontEngineFT::create(fontData, pixelSize, hintingPreference); -} +template class QCoreTextFontDatabaseEngineFactory; #endif QFont::StyleHint styleHintFromNSString(NSString *style) diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index c8ae342f16..49a6049c4b 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -177,6 +177,43 @@ CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef) return transform; } +// Keeps font data alive until engine is disposed +class QCoreTextRawFontEngine : public QCoreTextFontEngine +{ +public: + QCoreTextRawFontEngine(CGFontRef font, const QFontDef &def, const QByteArray &fontData) + : QCoreTextFontEngine(font, def) + , m_fontData(fontData) + {} + QByteArray m_fontData; +}; + +QCoreTextFontEngine *QCoreTextFontEngine::create(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) +{ + Q_UNUSED(hintingPreference); + + QCFType fontDataReference = fontData.toRawCFData(); + QCFType dataProvider = CGDataProviderCreateWithCFData(fontDataReference); + + // Note: CTFontCreateWithGraphicsFont (which we call from the QCoreTextFontEngine + // constructor) has a bug causing it to retain the CGFontRef but never release it. + // The result is that we are leaking the CGFont, CGDataProvider, and CGData, but + // as the CGData is created from the raw QByteArray data, which we deref in the + // subclass above during destruction, we're at least not leaking the font data, + // (unless CoreText copies it internally). http://stackoverflow.com/questions/40805382/ + QCFType cgFont = CGFontCreateWithDataProvider(dataProvider); + + if (!cgFont) { + qWarning("QCoreTextFontEngine::create: CGFontCreateWithDataProvider failed"); + return nullptr; + } + + QFontDef def; + def.pixelSize = pixelSize; + def.pointSize = pixelSize * 72.0 / qt_defaultDpi(); + return new QCoreTextRawFontEngine(cgFont, def, fontData); +} + QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def) : QFontEngine(Mac) { diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h index 0074790e43..2986f0aaec 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h @@ -123,6 +123,8 @@ public: static int antialiasingThreshold; static QFontEngine::GlyphFormat defaultGlyphFormat; + + static QCoreTextFontEngine *create(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference); private: void init(); QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, bool colorful, const QTransform &m); -- cgit v1.2.3 From 59d4cbca0b232814b736b7543ddecd5e5db40c29 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 12 Apr 2017 09:35:52 +0200 Subject: QWindowsFontEngineDirectWrite: Fix build with MinGW In member function 'void tn::QWindowsFontEngineDirectWrite::collectMetrics()': windows\qwindowsfontenginedirectwrite.cpp:361:22: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare] if (table.size() >= advanceWidthMaxLocation + sizeof(quint16)) { ^ Amends 17fc188aec5806167d3c6165b0ad299a8d2a6bcf. Task-number: QTBUG-58954 Change-Id: Ice2ff135d411b55d32290069b3c85ca0b5ea09af Reviewed-by: Simon Hausmann --- .../fontdatabases/windows/qwindowsfontenginedirectwrite.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/platformsupport/fontdatabases') diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp index 6f2755a05a..f07e711048 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp @@ -358,7 +358,7 @@ void QWindowsFontEngineDirectWrite::collectMetrics() QByteArray table = getSfntTable(MAKE_TAG('h', 'h', 'e', 'a')); const int advanceWidthMaxLocation = 10; - if (table.size() >= advanceWidthMaxLocation + sizeof(quint16)) { + if (table.size() >= advanceWidthMaxLocation + int(sizeof(quint16))) { quint16 advanceWidthMax = qFromBigEndian(table.constData() + advanceWidthMaxLocation); m_maxAdvanceWidth = DESIGN_TO_LOGICAL(advanceWidthMax); } -- cgit v1.2.3 From b727f11c2e4e8d4dd9dbd512f34ce7f95fd077fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Tue, 17 Jan 2017 15:49:07 +0100 Subject: QFontconfigDatabase: properly parse desktop environment variable $XDG_CURRENT_DESKTOP is defined as a colon-separated list of desktop strings, thus we can't check for equality, but split it and check if it contains the desktop environments we care about. Change-Id: Ia9ab0f28654a3e1a68b918794a079f3974f85642 Reviewed-by: Shawn Rutledge Reviewed-by: Dmitry Shachnev --- .../fontdatabases/fontconfig/qfontconfigdatabase.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/platformsupport/fontdatabases') diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp index 2c5ce3e87d..98dce03ae6 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp @@ -900,7 +900,13 @@ void QFontconfigDatabase::setupFontEngine(QFontEngineFT *engine, const QFontDef bool forcedAntialiasSetting = !antialias; const QPlatformServices *services = QGuiApplicationPrivate::platformIntegration()->services(); - bool useXftConf = (services && (services->desktopEnvironment() == "GNOME" || services->desktopEnvironment() == "UNITY")); + bool useXftConf = false; + + if (services) { + const QList desktopEnv = services->desktopEnvironment().split(':'); + useXftConf = desktopEnv.contains("GNOME") || desktopEnv.contains("UNITY"); + } + if (useXftConf && !forcedAntialiasSetting) { void *antialiasResource = QGuiApplication::platformNativeInterface()->nativeResourceForScreen("antialiasingEnabled", -- cgit v1.2.3 From 46976eea1890a0094da421a6dc4ac1276cfccff0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 3 Mar 2017 14:20:42 +0100 Subject: Add debug operators for font database structs for easier debugging Change-Id: Ice1b27ff93de2d369dc6b66c72a64eb05da5639c Reviewed-by: Simon Hausmann --- .../fontdatabases/mac/qcoretextfontdatabase.mm | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src/platformsupport/fontdatabases') diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index 3b9a456be0..d89a81be6b 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -251,6 +251,24 @@ struct FontDescription { QSupportedWritingSystems writingSystems; }; +#ifndef QT_NO_DEBUG_STREAM +Q_DECL_UNUSED static inline QDebug operator<<(QDebug debug, const FontDescription &fd) +{ + QDebugStateSaver saver(debug); + return debug.nospace() << "FontDescription(" + << "familyName=" << QString(fd.familyName) + << ", styleName=" << QString(fd.styleName) + << ", foundry=" << fd.foundryName + << ", weight=" << fd.weight + << ", style=" << fd.style + << ", stretch=" << fd.stretch + << ", pixelSize=" << fd.pixelSize + << ", fixedPitch=" << fd.fixedPitch + << ", writingSystems=" << fd.writingSystems + << ")"; +} +#endif + static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd) { QCFType styles = (CFDictionaryRef) CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute); -- cgit v1.2.3