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
Fixes: QTBUG-135977
Fixes: QTBUG-135315
Change-Id: I9fd673e7b1061af69cd27049311565a14a145aa4
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
(cherry picked from commit 306e68939cb29151c8333f9940dd48fa686efee7)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Eskil Abrahamsen Blomfeldt 2025-04-25 14:43:31 +02:00 committed by Qt Cherry-pick Bot
parent 4ff2fc9b9d
commit afaef97237
2 changed files with 53 additions and 19 deletions

View File

@ -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);
}
}
}

View File

@ -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