From 306e68939cb29151c8333f9940dd48fa686efee7 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 25 Apr 2025 14:43:31 +0200 Subject: [PATCH] Fix regression when selecting special font styles The fix for QTBUG-131574 aimed to make it possible to have multiple fonts in the same family with the same style name. It, however, inadvertedly made it impossible to have multiple styles of a font for which the typical font properties did not differ. This was especially bad for variable fonts. So in the case of e.g. Roboto Flex, where the "Italic" is not recognized as an italic font, as it does not set the "ital" axis, we would overwrite the default subfamily (Regular) with the Italic, because these would be seen as the same. This was not intentional, and this patch fixes it so that when we enter fonts into the database, they have to match both on style name and properties, otherwise we will register them as a new font. So identical subfamilies will still be supported. Pick-to: 6.8 6.9 Fixes: QTBUG-135977 Fixes: QTBUG-135315 Change-Id: I9fd673e7b1061af69cd27049311565a14a145aa4 Reviewed-by: Lars Knoll --- src/gui/text/qfontdatabase.cpp | 60 ++++++++++++++++++++++++---------- src/gui/text/qfontdatabase_p.h | 12 ++++++- 2 files changed, 53 insertions(+), 19 deletions(-) diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index cef3af226bb..5d455219359 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -194,20 +194,29 @@ QtFontSize *QtFontStyle::pixelSize(unsigned short size, bool add) return pixelSizes + (count++); } -QtFontStyle *QtFontFoundry::style(const QtFontStyle::Key &key, const QString &styleName, bool create) +QtFontStyle *QtFontFoundry::style(const QtFontStyle::Key &key, const QString &styleName, StyleRetrievalFlags flags) { int pos = 0; for (; pos < count; pos++) { - bool hasStyleName = !styleName.isEmpty(); // search styleName first if available - if (hasStyleName && !styles[pos]->styleName.isEmpty()) { - if (styles[pos]->styleName == styleName) + bool hasStyleName = !styleName.isEmpty() && !styles[pos]->styleName.isEmpty(); + bool hasStyleNameMatch = styles[pos]->styleName == styleName; + bool hasKeyMatch = styles[pos]->key == key; + + // If MatchAllProperties are set, then both the key and style name have to match, otherwise + // we consider it a different font. If it is not set, then we prefer matches on the style + // name if there is one. If no style name is part of the request (or the font does not + // have one) we match on the key. + if (flags & MatchAllProperties) { + if (hasStyleNameMatch && hasKeyMatch) return styles[pos]; - } else { - if (styles[pos]->key == key) + } else if (hasStyleName) { + if (hasStyleNameMatch) return styles[pos]; + } else if (hasKeyMatch) { + return styles[pos]; } } - if (!create) + if (!(flags & AddWhenMissing)) return nullptr; // qDebug("adding key (weight=%d, style=%d, oblique=%d stretch=%d) at %d", key.weight, key.style, key.oblique, key.stretch, pos); @@ -559,8 +568,9 @@ void qt_registerFont(const QString &familyName, const QString &stylename, } QtFontFoundry *foundry = f->foundry(foundryname, true); - QtFontStyle *fontStyle = foundry->style(styleKey, QString{}, true); - fontStyle->styleName = stylename; + QtFontStyle *fontStyle = foundry->style(styleKey, + stylename, + QtFontFoundry::StyleRetrievalFlags::AllRetrievalFlags); fontStyle->smoothScalable = scalable; fontStyle->antialiased = antialiased; QtFontSize *size = fontStyle->pixelSize(pixelSize ? pixelSize : SMOOTH_SCALABLE, true); @@ -1510,7 +1520,9 @@ QStringList QFontDatabase::styles(const QString &family) for (int k = 0; k < foundry->count; k++) { QtFontStyle::Key ke(foundry->styles[k]->key); ke.stretch = 0; - allStyles.style(ke, foundry->styles[k]->styleName, true); + allStyles.style(ke, + foundry->styles[k]->styleName, + QtFontFoundry::AddWhenMissing); } } } @@ -1733,8 +1745,11 @@ QFont QFontDatabase::font(const QString &family, const QString &style, for (int j = 0; j < f->count; j++) { QtFontFoundry *foundry = f->foundries[j]; if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) { - for (int k = 0; k < foundry->count; k++) - allStyles.style(foundry->styles[k]->key, foundry->styles[k]->styleName, true); + for (int k = 0; k < foundry->count; k++) { + allStyles.style(foundry->styles[k]->key, + foundry->styles[k]->styleName, + QtFontFoundry::AddWhenMissing); + } } } @@ -1844,8 +1859,11 @@ bool QFontDatabase::italic(const QString &family, const QString &style) for (int j = 0; j < f->count; j++) { QtFontFoundry *foundry = f->foundries[j]; if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) { - for (int k = 0; k < foundry->count; k++) - allStyles.style(foundry->styles[k]->key, foundry->styles[k]->styleName, true); + for (int k = 0; k < foundry->count; k++) { + allStyles.style(foundry->styles[k]->key, + foundry->styles[k]->styleName, + QtFontFoundry::AddWhenMissing); + } } } @@ -1878,8 +1896,11 @@ bool QFontDatabase::bold(const QString &family, QtFontFoundry *foundry = f->foundries[j]; if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) { - for (int k = 0; k < foundry->count; k++) - allStyles.style(foundry->styles[k]->key, foundry->styles[k]->styleName, true); + for (int k = 0; k < foundry->count; k++) { + allStyles.style(foundry->styles[k]->key, + foundry->styles[k]->styleName, + QtFontFoundry::AddWhenMissing); + } } } @@ -1913,8 +1934,11 @@ int QFontDatabase::weight(const QString &family, QtFontFoundry *foundry = f->foundries[j]; if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) { - for (int k = 0; k < foundry->count; k++) - allStyles.style(foundry->styles[k]->key, foundry->styles[k]->styleName, true); + for (int k = 0; k < foundry->count; k++) { + allStyles.style(foundry->styles[k]->key, + foundry->styles[k]->styleName, + QtFontFoundry::AddWhenMissing); + } } } diff --git a/src/gui/text/qfontdatabase_p.h b/src/gui/text/qfontdatabase_p.h index cbfa02b2b7c..4cd6996aab8 100644 --- a/src/gui/text/qfontdatabase_p.h +++ b/src/gui/text/qfontdatabase_p.h @@ -139,7 +139,17 @@ struct Q_GUI_EXPORT QtFontFoundry QString name; int count; QtFontStyle **styles; - QtFontStyle *style(const QtFontStyle::Key &, const QString & = QString(), bool = false); + + enum StyleRetrievalFlags : quint8 { + NoRetrievalFlags = 0, + AddWhenMissing = 1, + MatchAllProperties = 2, + AllRetrievalFlags = 3, + }; + + QtFontStyle *style(const QtFontStyle::Key &, + const QString & = QString(), + StyleRetrievalFlags flags = NoRetrievalFlags); }; struct Q_GUI_EXPORT QtFontFamily