UIKit: Improve handling of private system fonts / fallback fonts
Commit2bc7a40048
taught the CoreText font database to populate the families lazily, and in the process added a guard to ensure that we didn't populate internal fonts (prefixed with a '.'), as these fonts would then show up in font selection dialogs. Commit909d3f5c7
then added support for private fonts, by making it possible to filter out any private fonts from font selection daialogs. But the guard was not removed, so we were still not populating these fonts. This guard has been removed, and the filtering function has been updated to include the conditions of the guard. Next, commite5e93345c5
used [UIFont fontNamesForFamilyName:] to verify that each family that we registered with the font database would also have matching fonts when finally populated. This is not the right approach, as [UIFont fontNamesForFamilyName:] does not handle internal fonts. Instead we trust what CTFontDescriptorCreateMatchingFontDescriptors() gives us, but make sure to register the resulting font descriptors with the original/originating font family, instead of the one we pull out of the font descriptor. Finally, as of iOS 10, we can use CTFontManagerCopyAvailableFontFamilyNames instead of [UIFont familyNames], which gives us all of the internal font families like on macOS, instead of just the user-visible families. For earlier iOS versions we manually add '.PhoneFallback', as we know it will be available even if not listed in [UIFont familyNames]. The end result is that we register and populate families like '.PhoneFallback', which is critical to supporting more esoteric writing systems. The check in tst_QFont that styles for a given family is not empty has been removed, as we can't guarantee that on all platforms, which is also documented for QFontDatabase::styles(). Task-number: QTBUG-45746 Task-number: QTBUG-50624 Change-Id: I04674dcb2bb36b4cdf5646d540c35727ff3daaad Reviewed-by: Jake Petroules <jake.petroules@qt.io>
This commit is contained in:
parent
2488f34ecf
commit
50cb2687b2
@ -189,11 +189,16 @@ QCoreTextFontDatabase::~QCoreTextFontDatabase()
|
||||
|
||||
static CFArrayRef availableFamilyNames()
|
||||
{
|
||||
#if defined(Q_OS_OSX)
|
||||
return CTFontManagerCopyAvailableFontFamilyNames();
|
||||
#elif defined(QT_PLATFORM_UIKIT)
|
||||
return (CFArrayRef) [[UIFont familyNames] retain];
|
||||
#if QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(1060, 100000, 100000, 30000)
|
||||
if (&CTFontManagerCopyAvailableFontFamilyNames)
|
||||
return CTFontManagerCopyAvailableFontFamilyNames();
|
||||
#endif
|
||||
#if defined(QT_PLATFORM_UIKIT)
|
||||
CFMutableArrayRef familyNames = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, (CFArrayRef)[UIFont familyNames]);
|
||||
CFArrayAppendValue(familyNames, CFSTR(".PhoneFallback"));
|
||||
return familyNames;
|
||||
#endif
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
void QCoreTextFontDatabase::populateFontDatabase()
|
||||
@ -207,17 +212,6 @@ void QCoreTextFontDatabase::populateFontDatabase()
|
||||
for (int i = 0; i < numberOfFamilies; ++i) {
|
||||
CFStringRef familyNameRef = (CFStringRef) CFArrayGetValueAtIndex(familyNames, i);
|
||||
QString familyName = QString::fromCFString(familyNameRef);
|
||||
|
||||
// Don't populate internal fonts
|
||||
if (familyName.startsWith(QLatin1Char('.')) || familyName == QLatin1String("LastResort"))
|
||||
continue;
|
||||
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
// Skip font families with no corresponding fonts
|
||||
if (![UIFont fontNamesForFamilyName:(NSString*)familyNameRef].count)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
QPlatformFontDatabase::registerFontFamily(familyName);
|
||||
|
||||
#if defined(Q_OS_OSX)
|
||||
@ -250,7 +244,7 @@ void QCoreTextFontDatabase::populateFamily(const QString &familyName)
|
||||
|
||||
const int numFonts = CFArrayGetCount(matchingFonts);
|
||||
for (int i = 0; i < numFonts; ++i)
|
||||
populateFromDescriptor(CTFontDescriptorRef(CFArrayGetValueAtIndex(matchingFonts, i)));
|
||||
populateFromDescriptor(CTFontDescriptorRef(CFArrayGetValueAtIndex(matchingFonts, i)), familyName);
|
||||
}
|
||||
|
||||
struct FontDescription {
|
||||
@ -352,13 +346,18 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
|
||||
}
|
||||
}
|
||||
|
||||
void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font)
|
||||
void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font, const QString &familyName)
|
||||
{
|
||||
FontDescription fd;
|
||||
getFontDescription(font, &fd);
|
||||
|
||||
// Note: The familyName we are registering, and the family name of the font descriptor, may not
|
||||
// match, as CTFontDescriptorCreateMatchingFontDescriptors will return descriptors for replacement
|
||||
// fonts if a font family does not have any fonts available on the system.
|
||||
QString family = !familyName.isNull() ? familyName : static_cast<QString>(fd.familyName);
|
||||
|
||||
CFRetain(font);
|
||||
QPlatformFontDatabase::registerFont(fd.familyName, fd.styleName, fd.foundryName, fd.weight, fd.style, fd.stretch,
|
||||
QPlatformFontDatabase::registerFont(family, fd.styleName, fd.foundryName, fd.weight, fd.style, fd.stretch,
|
||||
true /* antialiased */, true /* scalable */,
|
||||
fd.pixelSize, fd.fixedPitch, fd.writingSystems, (void *) font);
|
||||
}
|
||||
@ -699,7 +698,7 @@ QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData
|
||||
|
||||
bool QCoreTextFontDatabase::isPrivateFontFamily(const QString &family) const
|
||||
{
|
||||
if (family.startsWith(QLatin1Char('.')))
|
||||
if (family.startsWith(QLatin1Char('.')) || family == QLatin1String("LastResort"))
|
||||
return true;
|
||||
|
||||
return QPlatformFontDatabase::isPrivateFontFamily(family);
|
||||
|
@ -92,7 +92,7 @@ public:
|
||||
const QHash<QPlatformTheme::Font, QFont *> &themeFonts() const;
|
||||
|
||||
private:
|
||||
void populateFromDescriptor(CTFontDescriptorRef font);
|
||||
void populateFromDescriptor(CTFontDescriptorRef font, const QString &familyName = QString());
|
||||
|
||||
#ifndef QT_NO_FREETYPE
|
||||
bool m_useFreeType;
|
||||
|
@ -130,7 +130,6 @@ void tst_QFont::italicOblique()
|
||||
|
||||
QString family = *f_it;
|
||||
QStringList styles = fdb.styles(family);
|
||||
QVERIFY(!styles.isEmpty());
|
||||
QStringList::ConstIterator s_it, s_end = styles.end();
|
||||
for (s_it = styles.begin(); s_it != s_end; ++s_it) {
|
||||
QString style = *s_it;
|
||||
|
Loading…
Reference in New Issue
Block a user