macOS: Split out font engine creation from QCoreTextFontDatabase
The Core Text font database can produce both Core Text and FreeType font engines. Refactor the code a bit so that the actual factory methods that differ between the two stand out, and do not require a granular runtime check in each method. Change-Id: Ib70f76f4a9001a8108d87c1101a50699a6ea8f55 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>bb10
parent
cd8d2c1743
commit
2b9ecfe69c
|
|
@ -112,12 +112,8 @@ static NSInteger languageMapSort(id obj1, id obj2, void *context)
|
|||
}
|
||||
#endif
|
||||
|
||||
QCoreTextFontDatabase::QCoreTextFontDatabase(bool useFreeType)
|
||||
#ifndef QT_NO_FREETYPE
|
||||
: m_useFreeType(useFreeType)
|
||||
#endif
|
||||
QCoreTextFontDatabase::QCoreTextFontDatabase()
|
||||
{
|
||||
Q_UNUSED(useFreeType)
|
||||
#ifdef Q_OS_MACX
|
||||
QSettings appleSettings(QLatin1String("apple.com"));
|
||||
QVariant appleValue = appleSettings.value(QLatin1String("AppleAntiAliasingThreshold"));
|
||||
|
|
@ -393,35 +389,24 @@ static QByteArray filenameForCFUrl(CFURLRef url)
|
|||
|
||||
extern CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef);
|
||||
|
||||
QFontEngine *QCoreTextFontDatabase::fontEngine(const QFontDef &f, void *usrPtr)
|
||||
template <>
|
||||
QFontEngine *QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine>::fontEngine(const QFontDef &fontDef, void *usrPtr)
|
||||
{
|
||||
CTFontDescriptorRef descriptor = static_cast<CTFontDescriptorRef>(usrPtr);
|
||||
|
||||
#ifndef QT_NO_FREETYPE
|
||||
if (m_useFreeType) {
|
||||
QCFType<CFURLRef> url(static_cast<CFURLRef>(CTFontDescriptorCopyAttribute(descriptor, kCTFontURLAttribute)));
|
||||
|
||||
QByteArray filename;
|
||||
if (url)
|
||||
filename = filenameForCFUrl(url);
|
||||
|
||||
return freeTypeFontEngine(f, filename);
|
||||
}
|
||||
#endif
|
||||
|
||||
// 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
|
||||
// the DPI. The default DPI for the screen is 72, thus the scale factor
|
||||
// is destinationDpi / 72, but since pixelSize = pointSize / 72 * dpi,
|
||||
// the pixelSize is actually the scaled point size for the destination
|
||||
// DPI, and we can use that directly.
|
||||
qreal scaledPointSize = f.pixelSize;
|
||||
qreal scaledPointSize = fontDef.pixelSize;
|
||||
|
||||
CGAffineTransform matrix = qt_transform_from_fontdef(f);
|
||||
CGAffineTransform matrix = qt_transform_from_fontdef(fontDef);
|
||||
CTFontRef font = CTFontCreateWithFontDescriptor(descriptor, scaledPointSize, &matrix);
|
||||
if (font) {
|
||||
QFontEngine *engine = new QCoreTextFontEngine(font, f);
|
||||
engine->fontDef = f;
|
||||
QFontEngine *engine = new QCoreTextFontEngine(font, fontDef);
|
||||
engine->fontDef = fontDef;
|
||||
CFRelease(font);
|
||||
return engine;
|
||||
}
|
||||
|
|
@ -429,6 +414,24 @@ QFontEngine *QCoreTextFontDatabase::fontEngine(const QFontDef &f, void *usrPtr)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_FREETYPE
|
||||
template <>
|
||||
QFontEngine *QCoreTextFontDatabaseEngineFactory<QFontEngineFT>::fontEngine(const QFontDef &fontDef, void *usrPtr)
|
||||
{
|
||||
CTFontDescriptorRef descriptor = static_cast<CTFontDescriptorRef>(usrPtr);
|
||||
|
||||
QCFType<CFURLRef> url(static_cast<CFURLRef>(CTFontDescriptorCopyAttribute(descriptor, kCTFontURLAttribute)));
|
||||
|
||||
QByteArray filename;
|
||||
if (url)
|
||||
filename = filenameForCFUrl(url);
|
||||
|
||||
QFontEngine::FaceId faceId;
|
||||
faceId.filename = filename;
|
||||
return QFontEngineFT::create(fontDef, faceId);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void releaseFontData(void* info, const void* data, size_t size)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
|
|
@ -436,31 +439,9 @@ static void releaseFontData(void* info, const void* data, size_t size)
|
|||
delete (QByteArray*)info;
|
||||
}
|
||||
|
||||
QFontEngine *QCoreTextFontDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference)
|
||||
template <>
|
||||
QFontEngine *QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine>::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference)
|
||||
{
|
||||
#ifndef QT_NO_FREETYPE
|
||||
if (m_useFreeType) {
|
||||
QByteArray *fontDataCopy = new QByteArray(fontData);
|
||||
QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(fontDataCopy,
|
||||
fontDataCopy->constData(), fontDataCopy->size(), releaseFontData);
|
||||
QCFType<CGFontRef> cgFont(CGFontCreateWithDataProvider(dataProvider));
|
||||
|
||||
if (!cgFont) {
|
||||
qWarning("QCoreTextFontDatabase::fontEngine: CGFontCreateWithDataProvider failed");
|
||||
return Q_NULLPTR;
|
||||
}
|
||||
|
||||
QFontDef fontDef;
|
||||
fontDef.pixelSize = pixelSize;
|
||||
fontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi();
|
||||
fontDef.hintingPreference = hintingPreference;
|
||||
CGAffineTransform transform = qt_transform_from_fontdef(fontDef);
|
||||
QCFType<CTFontRef> ctFont(CTFontCreateWithGraphicsFont(cgFont, fontDef.pixelSize, &transform, Q_NULLPTR));
|
||||
QCFType<CFURLRef> url(static_cast<CFURLRef>(CTFontCopyAttribute(ctFont, kCTFontURLAttribute)));
|
||||
return freeTypeFontEngine(fontDef, filenameForCFUrl(url), fontData);
|
||||
}
|
||||
#endif
|
||||
|
||||
Q_UNUSED(hintingPreference);
|
||||
|
||||
QByteArray* fontDataCopy = new QByteArray(fontData);
|
||||
|
|
@ -483,6 +464,34 @@ QFontEngine *QCoreTextFontDatabase::fontEngine(const QByteArray &fontData, qreal
|
|||
return fontEngine;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_FREETYPE
|
||||
template <>
|
||||
QFontEngine *QCoreTextFontDatabaseEngineFactory<QFontEngineFT>::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference)
|
||||
{
|
||||
QByteArray *fontDataCopy = new QByteArray(fontData);
|
||||
QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(fontDataCopy,
|
||||
fontDataCopy->constData(), fontDataCopy->size(), releaseFontData);
|
||||
QCFType<CGFontRef> cgFont(CGFontCreateWithDataProvider(dataProvider));
|
||||
|
||||
if (!cgFont) {
|
||||
qWarning("QCoreTextFontDatabase::fontEngine: CGFontCreateWithDataProvider failed");
|
||||
return Q_NULLPTR;
|
||||
}
|
||||
|
||||
QFontDef fontDef;
|
||||
fontDef.pixelSize = pixelSize;
|
||||
fontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi();
|
||||
fontDef.hintingPreference = hintingPreference;
|
||||
CGAffineTransform transform = qt_transform_from_fontdef(fontDef);
|
||||
QCFType<CTFontRef> ctFont(CTFontCreateWithGraphicsFont(cgFont, fontDef.pixelSize, &transform, Q_NULLPTR));
|
||||
QCFType<CFURLRef> url(static_cast<CFURLRef>(CTFontCopyAttribute(ctFont, kCTFontURLAttribute)));
|
||||
|
||||
QFontEngine::FaceId faceId;
|
||||
faceId.filename = filenameForCFUrl(url);
|
||||
return QFontEngineFT::create(fontDef, faceId, fontData);
|
||||
}
|
||||
#endif
|
||||
|
||||
QFont::StyleHint styleHintFromNSString(NSString *style)
|
||||
{
|
||||
if ([style isEqual: @"sans-serif"])
|
||||
|
|
@ -615,17 +624,27 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo
|
|||
return fallbackLists[styleLookupKey.arg(styleHint)];
|
||||
}
|
||||
|
||||
CFArrayRef QCoreTextFontDatabase::createDescriptorArrayForFont(CTFontRef font, const QString &fileName)
|
||||
template <>
|
||||
CFArrayRef QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine>::createDescriptorArrayForFont(CTFontRef font, const QString &fileName)
|
||||
{
|
||||
Q_UNUSED(fileName)
|
||||
CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
|
||||
QCFType<CTFontDescriptorRef> descriptor = CTFontCopyFontDescriptor(font);
|
||||
CFArrayAppendValue(array, descriptor);
|
||||
return array;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_FREETYPE
|
||||
template <>
|
||||
CFArrayRef QCoreTextFontDatabaseEngineFactory<QFontEngineFT>::createDescriptorArrayForFont(CTFontRef font, const QString &fileName)
|
||||
{
|
||||
CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
|
||||
QCFType<CTFontDescriptorRef> descriptor = CTFontCopyFontDescriptor(font);
|
||||
|
||||
Q_UNUSED(fileName)
|
||||
#ifndef QT_NO_FREETYPE
|
||||
// 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 (m_useFreeType && !fileName.isEmpty()) {
|
||||
if (!fileName.isEmpty()) {
|
||||
QCFType<CFURLRef> fontURL;
|
||||
|
||||
if (fileName.startsWith(QLatin1String(":/"))) {
|
||||
|
|
@ -642,11 +661,11 @@ CFArrayRef QCoreTextFontDatabase::createDescriptorArrayForFont(CTFontRef font, c
|
|||
CFDictionaryAddValue(attributes, kCTFontURLAttribute, fontURL);
|
||||
descriptor = CTFontDescriptorCreateCopyWithAttributes(descriptor, attributes);
|
||||
}
|
||||
#endif
|
||||
|
||||
CFArrayAppendValue(array, descriptor);
|
||||
return array;
|
||||
}
|
||||
#endif
|
||||
|
||||
QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
|
||||
{
|
||||
|
|
@ -884,15 +903,5 @@ void QCoreTextFontDatabase::removeApplicationFonts()
|
|||
m_applicationFonts.clear();
|
||||
}
|
||||
|
||||
#ifndef QT_NO_FREETYPE
|
||||
QFontEngine *QCoreTextFontDatabase::freeTypeFontEngine(const QFontDef &fontDef, const QByteArray &filename,
|
||||
const QByteArray &fontData)
|
||||
{
|
||||
QFontEngine::FaceId faceId;
|
||||
faceId.filename = filename;
|
||||
return QFontEngineFT::create(fontDef, faceId, fontData);
|
||||
}
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
|
|
|||
|
|
@ -72,13 +72,11 @@ QT_BEGIN_NAMESPACE
|
|||
class QCoreTextFontDatabase : public QPlatformFontDatabase
|
||||
{
|
||||
public:
|
||||
QCoreTextFontDatabase(bool useFreeType = false);
|
||||
QCoreTextFontDatabase();
|
||||
~QCoreTextFontDatabase();
|
||||
void populateFontDatabase() Q_DECL_OVERRIDE;
|
||||
void populateFamily(const QString &familyName) Q_DECL_OVERRIDE;
|
||||
|
||||
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) Q_DECL_OVERRIDE;
|
||||
QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) Q_DECL_OVERRIDE;
|
||||
QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const Q_DECL_OVERRIDE;
|
||||
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName) Q_DECL_OVERRIDE;
|
||||
void releaseHandle(void *handle) Q_DECL_OVERRIDE;
|
||||
|
|
@ -93,13 +91,8 @@ public:
|
|||
|
||||
private:
|
||||
void populateFromDescriptor(CTFontDescriptorRef font, const QString &familyName = QString());
|
||||
CFArrayRef createDescriptorArrayForFont(CTFontRef font, const QString &fileName);
|
||||
virtual CFArrayRef createDescriptorArrayForFont(CTFontRef font, const QString &fileName) = 0;
|
||||
|
||||
#ifndef QT_NO_FREETYPE
|
||||
bool m_useFreeType;
|
||||
QFontEngine *freeTypeFontEngine(const QFontDef &fontDef, const QByteArray &filename,
|
||||
const QByteArray &fontData = QByteArray());
|
||||
#endif
|
||||
mutable QString defaultFontName;
|
||||
|
||||
void removeApplicationFonts();
|
||||
|
|
@ -109,6 +102,19 @@ private:
|
|||
mutable QHash<QPlatformTheme::Font, QFont *> m_themeFonts;
|
||||
};
|
||||
|
||||
// Split out into separate template class so that the compiler doesn't have
|
||||
// to generate code for each override in QCoreTextFontDatabase for each T.
|
||||
|
||||
template <class T>
|
||||
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 createDescriptorArrayForFont(CTFontRef font, const QString &fileName) override;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QCORETEXTFONTDATABASE_H
|
||||
|
|
|
|||
|
|
@ -69,6 +69,9 @@ static void initResources()
|
|||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QCoreTextFontEngine;
|
||||
class QFontEngineFT;
|
||||
|
||||
QCocoaScreen::QCocoaScreen(int screenIndex)
|
||||
: QPlatformScreen(), m_screenIndex(screenIndex), m_refreshRate(60.0)
|
||||
{
|
||||
|
|
@ -302,7 +305,7 @@ QCocoaIntegration *QCocoaIntegration::mInstance = 0;
|
|||
|
||||
QCocoaIntegration::QCocoaIntegration(const QStringList ¶mList)
|
||||
: mOptions(parseOptions(paramList))
|
||||
, mFontDb(new QCoreTextFontDatabase(mOptions.testFlag(UseFreeTypeFontEngine)))
|
||||
, mFontDb(0)
|
||||
#ifndef QT_NO_ACCESSIBILITY
|
||||
, mAccessibility(new QCocoaAccessibility)
|
||||
#endif
|
||||
|
|
@ -318,6 +321,13 @@ QCocoaIntegration::QCocoaIntegration(const QStringList ¶mList)
|
|||
qWarning("Creating multiple Cocoa platform integrations is not supported");
|
||||
mInstance = this;
|
||||
|
||||
#ifndef QT_NO_FREETYPE
|
||||
if (mOptions.testFlag(UseFreeTypeFontEngine))
|
||||
mFontDb.reset(new QCoreTextFontDatabaseEngineFactory<QFontEngineFT>);
|
||||
else
|
||||
#endif
|
||||
mFontDb.reset(new QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine>);
|
||||
|
||||
QString icStr = QPlatformInputContextFactory::requested();
|
||||
icStr.isNull() ? mInputContext.reset(new QCocoaInputContext)
|
||||
: mInputContext.reset(QPlatformInputContextFactory::create(icStr));
|
||||
|
|
|
|||
|
|
@ -69,13 +69,15 @@
|
|||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QCoreTextFontEngine;
|
||||
|
||||
QIOSIntegration *QIOSIntegration::instance()
|
||||
{
|
||||
return static_cast<QIOSIntegration *>(QGuiApplicationPrivate::platformIntegration());
|
||||
}
|
||||
|
||||
QIOSIntegration::QIOSIntegration()
|
||||
: m_fontDatabase(new QCoreTextFontDatabase)
|
||||
: m_fontDatabase(new QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine>)
|
||||
#if !defined(Q_OS_TVOS) && !defined(QT_NO_CLIPBOARD)
|
||||
, m_clipboard(new QIOSClipboard)
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@
|
|||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QCoreTextFontEngine;
|
||||
|
||||
static const char debugBackingStoreEnvironmentVariable[] = "QT_DEBUG_BACKINGSTORE";
|
||||
|
||||
static inline unsigned parseOptions(const QStringList ¶mList)
|
||||
|
|
@ -140,7 +142,7 @@ QPlatformFontDatabase *QMinimalIntegration::fontDatabase() const
|
|||
m_fontDatabase = new QWindowsFontDatabase;
|
||||
}
|
||||
#elif defined(Q_OS_DARWIN)
|
||||
m_fontDatabase = new QCoreTextFontDatabase;
|
||||
m_fontDatabase = new QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine>;
|
||||
#else
|
||||
m_fontDatabase = QPlatformIntegration::fontDatabase();
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue