diff options
Diffstat (limited to 'src/gui/text/coretext/qcoretextfontdatabase.mm')
-rw-r--r-- | src/gui/text/coretext/qcoretextfontdatabase.mm | 79 |
1 files changed, 58 insertions, 21 deletions
diff --git a/src/gui/text/coretext/qcoretextfontdatabase.mm b/src/gui/text/coretext/qcoretextfontdatabase.mm index 61c662cd45..2197c83f29 100644 --- a/src/gui/text/coretext/qcoretextfontdatabase.mm +++ b/src/gui/text/coretext/qcoretextfontdatabase.mm @@ -361,7 +361,7 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd) fd->fixedPitch = false; if (QCFType<CTFontRef> tempFont = CTFontCreateWithFontDescriptor(font, 0.0, 0)) { - uint tag = MAKE_TAG('O', 'S', '/', '2'); + uint tag = QFont::Tag("OS/2").value(); CTFontRef tempFontRef = tempFont; void *userData = reinterpret_cast<void *>(&tempFontRef); uint length = 128; @@ -489,6 +489,31 @@ QFontEngine *QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine>::fontEngine qreal scaledPointSize = fontDef.pixelSize; CGAffineTransform matrix = qt_transform_from_fontdef(fontDef); + + if (!fontDef.variableAxisValues.isEmpty()) { + QCFType<CFMutableDictionaryRef> variations = CFDictionaryCreateMutable(nullptr, + fontDef.variableAxisValues.size(), + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + for (auto it = fontDef.variableAxisValues.constBegin(); + it != fontDef.variableAxisValues.constEnd(); + ++it) { + const quint32 tag = it.key().value(); + const float value = it.value(); + QCFType<CFNumberRef> tagRef = CFNumberCreate(nullptr, kCFNumberIntType, &tag); + QCFType<CFNumberRef> valueRef = CFNumberCreate(nullptr, kCFNumberFloatType, &value); + + CFDictionarySetValue(variations, tagRef, valueRef); + } + QCFType<CFDictionaryRef> attributes = CFDictionaryCreate(nullptr, + (const void **) &kCTFontVariationAttribute, + (const void **) &variations, + 1, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + descriptor = CTFontDescriptorCreateCopyWithAttributes(descriptor, attributes); + } + if (QCFType<CTFontRef> font = CTFontCreateWithFontDescriptor(descriptor, scaledPointSize, &matrix)) return new QCoreTextFontEngine(font, fontDef); @@ -504,7 +529,7 @@ QFontEngine *QCoreTextFontDatabaseEngineFactory<QFontEngineFT>::fontEngine(const if (NSValue *fontDataValue = descriptorAttribute<NSValue>(descriptor, (CFStringRef)kQtFontDataAttribute)) { QByteArray *fontData = static_cast<QByteArray *>(fontDataValue.pointerValue); return QFontEngineFT::create(*fontData, fontDef.pixelSize, - static_cast<QFont::HintingPreference>(fontDef.hintingPreference)); + static_cast<QFont::HintingPreference>(fontDef.hintingPreference), fontDef.variableAxisValues); } else if (NSURL *url = descriptorAttribute<NSURL>(descriptor, kCTFontURLAttribute)) { QFontEngine::FaceId faceId; @@ -515,6 +540,8 @@ QFontEngine *QCoreTextFontDatabaseEngineFactory<QFontEngineFT>::fontEngine(const QString styleName = QCFString(CTFontDescriptorCopyAttribute(descriptor, kCTFontStyleNameAttribute)); faceId.index = QFreetypeFace::getFaceIndexByStyleName(faceFileName, styleName); + faceId.variableAxes = fontDef.variableAxisValues; + return QFontEngineFT::create(fontDef, faceId); } // We end up here with a descriptor does not contain Qt font data or kCTFontURLAttribute. @@ -527,7 +554,7 @@ QFontEngine *QCoreTextFontDatabaseEngineFactory<QFontEngineFT>::fontEngine(const template <class T> QFontEngine *QCoreTextFontDatabaseEngineFactory<T>::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) { - return T::create(fontData, pixelSize, hintingPreference); + return T::create(fontData, pixelSize, hintingPreference, {}); } // Explicitly instantiate so that we don't need the plugin to involve FreeType @@ -545,7 +572,7 @@ CFArrayRef fallbacksForDescriptor(CTFontDescriptorRef descriptor) } CFArrayRef cascadeList = CFArrayRef(CTFontCopyDefaultCascadeListForLanguages(font, - (CFArrayRef)[NSUserDefaults.standardUserDefaults stringArrayForKey:@"AppleLanguages"])); + (CFArrayRef)NSLocale.preferredLanguages)); if (!cascadeList) { qCWarning(lcQpaFonts) << "Failed to create fallback cascade list for" << descriptor; @@ -714,13 +741,20 @@ QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData if (!fontData.isEmpty()) { QCFType<CFDataRef> fontDataReference = fontData.toRawCFData(); - if (QCFType<CTFontDescriptorRef> 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); + if (QCFType<CFArrayRef> descriptors = CTFontManagerCreateFontDescriptorsFromData(fontDataReference)) { CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - CFArrayAppendValue(array, descriptor); + const int count = CFArrayGetCount(descriptors); + + for (int i = 0; i < count; ++i) { + CTFontDescriptorRef descriptor = CTFontDescriptorRef(CFArrayGetValueAtIndex(descriptors, i)); + + // 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); + CFArrayAppendValue(array, descriptor); + } + fonts = array; } } else { @@ -862,7 +896,7 @@ static CTFontDescriptorRef fontDescriptorFromTheme(QPlatformTheme::Font f) UIFontDescriptor *desc = [UIFontDescriptor preferredFontDescriptorWithTextStyle:textStyle]; return static_cast<CTFontDescriptorRef>(CFBridgingRetain(desc)); } -#endif // Q_OS_IOS, Q_OS_TVOS, Q_OS_WATCHOS +#endif // QT_PLATFORM_UIKIT // macOS default case and iOS fallback case return descriptorForFontType(fontTypeFromTheme(f)); @@ -905,7 +939,7 @@ void QCoreTextFontDatabase::populateThemeFonts() auto addFontVariants = [&](CTFontDescriptorRef descriptor) { QCFType<CFArrayRef> matchingDescriptors = CTFontDescriptorCreateMatchingFontDescriptors(descriptor, nullptr); - const int matchingDescriptorsCount = CFArrayGetCount(matchingDescriptors); + const int matchingDescriptorsCount = matchingDescriptors ? CFArrayGetCount(matchingDescriptors) : 0; qCDebug(lcQpaFonts) << "Enumerating font variants based on" << id(descriptor) << "resulted in" << matchingDescriptorsCount << "matching descriptors" << matchingDescriptors.as<NSArray*>(); @@ -917,15 +951,13 @@ void QCoreTextFontDatabase::populateThemeFonts() }; // Try populating the font variants based on its UI design trait, if available - if (@available(macos 10.15, ios 13.0, *)) { - auto fontTraits = QCFType<CFDictionaryRef>(CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontTraitsAttribute)); - static const NSString *kUIFontDesignTrait = @"NSCTFontUIFontDesignTrait"; - if (id uiFontDesignTrait = fontTraits.as<NSDictionary*>()[kUIFontDesignTrait]) { - QCFType<CTFontDescriptorRef> designTraitDescriptor = CTFontDescriptorCreateWithAttributes( - CFDictionaryRef(@{ (id)kCTFontTraitsAttribute: @{ kUIFontDesignTrait: uiFontDesignTrait } - })); - addFontVariants(designTraitDescriptor); - } + auto fontTraits = QCFType<CFDictionaryRef>(CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontTraitsAttribute)); + static const NSString *kUIFontDesignTrait = @"NSCTFontUIFontDesignTrait"; + if (id uiFontDesignTrait = fontTraits.as<NSDictionary*>()[kUIFontDesignTrait]) { + QCFType<CTFontDescriptorRef> designTraitDescriptor = CTFontDescriptorCreateWithAttributes( + CFDictionaryRef(@{ (id)kCTFontTraitsAttribute: @{ kUIFontDesignTrait: uiFontDesignTrait } + })); + addFontVariants(designTraitDescriptor); } if (themeFontVariants.isEmpty()) { @@ -980,5 +1012,10 @@ QList<int> QCoreTextFontDatabase::standardSizes() const return ret; } +bool QCoreTextFontDatabase::supportsVariableApplicationFonts() const +{ + return true; +} + QT_END_NAMESPACE |