macOS: Fix regression with some characters in non-bundle apps
.Noto Sans Univeral is a system-generated font, but for some undiscovered reason, it has different content when the app has a valid Info.plist versus when it does not. When there is no valid Info.plist, the font will act as a last-resort font and return a question mark glyph (index 4) for all characters it does not support. This was discovered with emojis, but I also verified that the font returns index 4 for a random character in the Cherokee range, in order to check if this was specific for emojis or not. This causes the font to take precedence over anything that follows it in the fallback list in apps that do not have a valid Info.plist, so it has to be at the end of the list. Note that in these apps, it will act as a last-resort font, so the glyphs returned for missing characters will be different from in a regular app bundle. But this seems safer than to exclude the font entirely, given that Noto Sans cover a large range of characters and might be needed. This font also refactors the look up of fonts to push to the end to avoid doing lots of unnecessary looping over the list. Fixes: QTBUG-78833 Change-Id: I38bec5d5941681c4b4586072f7811d31561e1051 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
parent
c9eff4aa07
commit
90d94c1c2c
@ -478,6 +478,9 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo
|
||||
if (cascadeList) {
|
||||
QStringList fallbackList;
|
||||
const int numCascades = CFArrayGetCount(cascadeList);
|
||||
|
||||
int symbolIndex = -1;
|
||||
int notoSansUniversalIndex = -1;
|
||||
for (int i = 0; i < numCascades; ++i) {
|
||||
CTFontDescriptorRef fontFallback = (CTFontDescriptorRef) CFArrayGetValueAtIndex(cascadeList, i);
|
||||
QCFString fallbackFamilyName = (CFStringRef) CTFontDescriptorCopyAttribute(fontFallback, kCTFontFamilyNameAttribute);
|
||||
@ -487,15 +490,28 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo
|
||||
|
||||
if (!qt_isFontFamilyPopulated(fallbackName))
|
||||
const_cast<QCoreTextFontDatabase *>(this)->populateFromDescriptor(fontFallback, fallbackName);
|
||||
|
||||
if (fallbackName == QLatin1String(".Apple Symbols Fallback"))
|
||||
symbolIndex = fallbackList.size() - 1;
|
||||
else if (fallbackName == QLatin1String(".Noto Sans Universal"))
|
||||
notoSansUniversalIndex = fallbackList.size() - 1;
|
||||
}
|
||||
|
||||
// .Apple Symbols Fallback will be at the beginning of the list and we will
|
||||
// detect that this has glyphs for Arabic and other writing systems.
|
||||
// Since it is a symbol font, it should be the last resort, so that
|
||||
// the proper fonts for these writing systems are preferred.
|
||||
int symbolIndex = fallbackList.indexOf(QLatin1String(".Apple Symbols Fallback"));
|
||||
if (symbolIndex >= 0)
|
||||
if (symbolIndex >= 0) {
|
||||
fallbackList.move(symbolIndex, fallbackList.size() - 1);
|
||||
if (notoSansUniversalIndex > symbolIndex)
|
||||
--notoSansUniversalIndex;
|
||||
}
|
||||
|
||||
// .Noto Sans Universal appears to have a bug when the application
|
||||
// does not have a valid Info.plist, which causes it to return glyph #4
|
||||
// (a question mark) for any character.
|
||||
if (notoSansUniversalIndex >= 0)
|
||||
fallbackList.move(notoSansUniversalIndex, fallbackList.size() - 1);
|
||||
|
||||
addExtraFallbacks(&fallbackList);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user