Skip to content

Commit

Permalink
qt: Fix some font weight related issues (#4131)
Browse files Browse the repository at this point in the history
* qt: Add missing -font-family overridden check

* qt: Add missing `QFont::ExtraBold`

* qt: Remove settings depencency from GUIUtil::loadFonts and load earlier

* qt: Modify supportedWeightToIndex

Return -1 in case of failure

* qt: Add GUIUtil::isSupportedWeight

* qt: Make sure there are always supported weights in the settings

* qt: Add "supported defaults" + store weights based on font family

* qt: Use supported defaults in update weight sliders

* qt: Use supported defaults when updating weight sliders

* qt: Fix tests
  • Loading branch information
xdustinface authored and PastaPastaPasta committed May 14, 2021
1 parent b4a0d01 commit b3c6d09
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 66 deletions.
18 changes: 9 additions & 9 deletions src/qt/appearancewidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ AppearanceWidget::AppearanceWidget(QWidget* parent) :
mapper->setOrientation(Qt::Vertical);

connect(ui->theme, SIGNAL(currentTextChanged(const QString&)), this, SLOT(updateTheme(const QString&)));
connect(ui->fontFamily, SIGNAL(activated(int)), this, SLOT(updateFontFamily(int)));
connect(ui->fontFamily, SIGNAL(currentIndexChanged(int)), this, SLOT(updateFontFamily(int)));
connect(ui->fontScaleSlider, SIGNAL(valueChanged(int)), this, SLOT(updateFontScale(int)));
connect(ui->fontWeightNormalSlider, SIGNAL(valueChanged(int)), this, SLOT(updateFontWeightNormal(int)));
connect(ui->fontWeightBoldSlider, SIGNAL(valueChanged(int)), this, SLOT(updateFontWeightBold(int)));
Expand Down Expand Up @@ -118,7 +118,7 @@ void AppearanceWidget::updateTheme(const QString& theme)
void AppearanceWidget::updateFontFamily(int index)
{
GUIUtil::setFontFamily(static_cast<GUIUtil::FontFamily>(ui->fontFamily->itemData(index).toInt()));
updateWeightSlider();
updateWeightSlider(true);
}

void AppearanceWidget::updateFontScale(int nScale)
Expand Down Expand Up @@ -148,7 +148,7 @@ void AppearanceWidget::updateFontWeightBold(int nValue, bool fForce)
GUIUtil::setFontWeightBold(GUIUtil::supportedWeightFromIndex(ui->fontWeightBoldSlider->value()));
}

void AppearanceWidget::updateWeightSlider()
void AppearanceWidget::updateWeightSlider(const bool fForce)
{
int nMaximum = GUIUtil::getSupportedWeights().size() - 1;

Expand All @@ -158,11 +158,11 @@ void AppearanceWidget::updateWeightSlider()
ui->fontWeightBoldSlider->setMinimum(0);
ui->fontWeightBoldSlider->setMaximum(nMaximum);

if (nMaximum < 4) {
updateFontWeightNormal(0, true);
updateFontWeightBold(nMaximum, true);
} else {
updateFontWeightNormal(1, true);
updateFontWeightBold(4, true);
if (fForce || !GUIUtil::isSupportedWeight(prevWeightNormal) || !GUIUtil::isSupportedWeight(prevWeightBold)) {
int nIndexNormal = GUIUtil::supportedWeightToIndex(GUIUtil::getSupportedFontWeightNormalDefault());
int nIndexBold = GUIUtil::supportedWeightToIndex(GUIUtil::getSupportedFontWeightBoldDefault());
assert(nIndexNormal != -1 && nIndexBold != -1);
updateFontWeightNormal(nIndexNormal, true);
updateFontWeightBold(nIndexBold, true);
}
}
2 changes: 1 addition & 1 deletion src/qt/appearancewidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ private Q_SLOTS:
QFont::Weight prevWeightNormal;
QFont::Weight prevWeightBold;

void updateWeightSlider();
void updateWeightSlider(bool fForce = false);
};

#endif // BITCOIN_QT_APPEARANCEWIDGET_H
4 changes: 2 additions & 2 deletions src/qt/dash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -714,14 +714,14 @@ int main(int argc, char *argv[])
qInstallMessageHandler(DebugMessageHandler);
// Allow parameter interaction before we create the options model
app.parameterSetup();
// Load GUI settings from QSettings
app.createOptionsModel(gArgs.GetBoolArg("-resetguisettings", false));
// Load custom application fonts and setup font management
if (!GUIUtil::loadFonts()) {
QMessageBox::critical(0, QObject::tr(PACKAGE_NAME),
QObject::tr("Error: Failed to load application fonts."));
return EXIT_FAILURE;
}
// Load GUI settings from QSettings
app.createOptionsModel(gArgs.GetBoolArg("-resetguisettings", false));
// Validate/set font family
if (gArgs.IsArgSet("-font-family")) {
GUIUtil::FontFamily family;
Expand Down
137 changes: 89 additions & 48 deletions src/qt/guiutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,9 @@ static const int defaultFontScale = 0;
static FontFamily fontFamily = defaultFontFamily;
// Application font scale value. May be overwritten by -font-scale.
static int fontScale = defaultFontScale;
// Application font weight for normal text. May be overwritten by -font-weight-normal.
static QFont::Weight fontWeightNormal = defaultFontWeightNormal;
// Application font weight for bold text. May be overwritten by -font-weight-bold.
static QFont::Weight fontWeightBold = defaultFontWeightBold;

// Contains the weight settings separated for all available fonts
static std::map<FontFamily, std::pair<QFont::Weight, QFont::Weight>> mapDefaultWeights;
static std::map<FontFamily, std::pair<QFont::Weight, QFont::Weight>> mapWeights;
// Contains all widgets and its font attributes (weight, italic, size) with font changes due to GUIUtil::setFont
static std::map<QPointer<QWidget>, std::tuple<FontWeight, bool, int>> mapFontUpdates;
// Contains a list of supported font weights for all members of GUIUtil::FontFamily
Expand Down Expand Up @@ -290,23 +288,6 @@ void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent, bool fAllow
void setupAppearance(QWidget* parent, OptionsModel* model)
{
if (!QSettings().value("fAppearanceSetupDone", false).toBool()) {
std::vector<QFont::Weight> vecWeights = getSupportedWeights();
// See if the default value for normal weight is available
if (std::find(vecWeights.begin(), vecWeights.end(), defaultFontWeightNormal) == vecWeights.end()) {
// If not, use the lightest available weight as normal weight
fontWeightNormal = vecWeights.front();
}

// See if the default value for bold weight is available
if (std::find(vecWeights.begin(), vecWeights.end(), defaultFontWeightBold) == vecWeights.end()) {
// If not, use the second lightest available weight as bold weight default or also the lightest if there is only one
int nBoldOffset = vecWeights.size() > 1 ? 1 : 0;
fontWeightBold = vecWeights[nBoldOffset];
}

QSettings().setValue("fontWeightNormal", weightToArg(fontWeightNormal));
QSettings().setValue("fontWeightBold", weightToArg(fontWeightBold));

// Create the dialog
QDialog dlg(parent);
dlg.setObjectName("AppearanceSetup");
Expand Down Expand Up @@ -1272,12 +1253,18 @@ QFont::Weight toQFontWeight(FontWeight weight)

QFont::Weight getFontWeightNormal()
{
return fontWeightNormal;
if (!mapWeights.count(fontFamily)) {
return defaultFontWeightNormal;
}
return mapWeights[fontFamily].first;
}

void setFontWeightNormal(QFont::Weight weight)
{
fontWeightNormal = weight;
if (!mapWeights.count(fontFamily)) {
throw std::runtime_error(strprintf("%s: Font family not loaded: %s", __func__, fontFamilyToString(fontFamily).toStdString()));
}
mapWeights[fontFamily].first = weight;
updateFonts();
}

Expand All @@ -1288,12 +1275,18 @@ QFont::Weight getFontWeightBoldDefault()

QFont::Weight getFontWeightBold()
{
return fontWeightBold;
if (!mapWeights.count(fontFamily)) {
return defaultFontWeightBold;
}
return mapWeights[fontFamily].second;
}

void setFontWeightBold(QFont::Weight weight)
{
fontWeightBold = weight;
if (!mapWeights.count(fontFamily)) {
throw std::runtime_error(strprintf("%s: Font family not loaded: %s", __func__, fontFamilyToString(fontFamily).toStdString()));
}
mapWeights[fontFamily].second = weight;
updateFonts();
}

Expand Down Expand Up @@ -1379,26 +1372,6 @@ bool loadFonts()
}
}

// Load font related settings
QSettings settings;
QFont::Weight weight;

if (!gArgs.IsArgSet("-font-family")) {
fontFamily = fontFamilyFromString(settings.value("fontFamily").toString());
}

if (!gArgs.IsArgSet("-font-scale")) {
fontScale = settings.value("fontScale").toInt();
}

if (!gArgs.IsArgSet("-font-weight-normal") && weightFromArg(settings.value("fontWeightNormal").toInt(), weight)) {
fontWeightNormal = weight;
}

if (!gArgs.IsArgSet("-font-weight-bold") && weightFromArg(settings.value("fontWeightBold").toInt(), weight)) {
fontWeightBold = weight;
}

setApplicationFont();

// Initialize supported font weights for all available fonts
Expand All @@ -1410,7 +1383,7 @@ bool loadFonts()
};
std::vector<QFont::Weight> vecWeights{QFont::Thin, QFont::ExtraLight, QFont::Light,
QFont::Normal, QFont::Medium, QFont::DemiBold,
QFont::Bold, QFont::Black};
QFont::Bold, QFont::ExtraBold, QFont::Black};
std::vector<QFont::Weight> vecSupported;
QFont::Weight prevWeight = vecWeights.front();
for (auto weight = vecWeights.begin() + 1; weight != vecWeights.end(); ++weight) {
Expand All @@ -1428,11 +1401,55 @@ bool loadFonts()
mapSupportedWeights.insert(std::make_pair(FontFamily::SystemDefault, supportedWeights(FontFamily::SystemDefault)));
mapSupportedWeights.insert(std::make_pair(FontFamily::Montserrat, supportedWeights(FontFamily::Montserrat)));

auto getBestMatch = [&](FontFamily fontFamily, QFont::Weight targetWeight) {
auto& vecSupported = mapSupportedWeights[fontFamily];
auto it = vecSupported.begin();
QFont::Weight bestWeight = *it;
int nBestDiff = abs(*it - targetWeight);
while (++it != vecSupported.end()) {
int nDiff = abs(*it - targetWeight);
if (nDiff < nBestDiff) {
bestWeight = *it;
nBestDiff = nDiff;
}
}
return bestWeight;
};

auto addBestDefaults = [&](FontFamily family) -> auto {
QFont::Weight normalWeight = getBestMatch(family, defaultFontWeightNormal);
QFont::Weight boldWeight = getBestMatch(family, defaultFontWeightBold);
if (normalWeight == boldWeight) {
// If the results are the same use the next possible weight for bold font
auto& vecSupported = mapSupportedWeights[fontFamily];
auto it = std::find(vecSupported.begin(), vecSupported.end(),normalWeight);
if (++it != vecSupported.end()) {
boldWeight = *it;
}
}
mapDefaultWeights.emplace(family, std::make_pair(normalWeight, boldWeight));
};

addBestDefaults(FontFamily::SystemDefault);
addBestDefaults(FontFamily::Montserrat);

// Load supported defaults. May become overwritten later.
mapWeights = mapDefaultWeights;

return true;
}

bool fontsLoaded()
{
return osDefaultFont != nullptr;
}

void setApplicationFont()
{
if (!fontsLoaded()) {
return;
}

std::unique_ptr<QFont> font;

if (fontFamily == FontFamily::Montserrat) {
Expand Down Expand Up @@ -1581,6 +1598,9 @@ void updateFonts()
QFont getFont(FontFamily family, QFont::Weight qWeight, bool fItalic, int nPointSize)
{
QFont font;
if (!fontsLoaded()) {
return font;
}

if (family == FontFamily::Montserrat) {
static std::map<QFont::Weight, QString> mapMontserratMapping{
Expand Down Expand Up @@ -1657,6 +1677,22 @@ QFont getFontBold()
return getFont(FontWeight::Bold);
}

QFont::Weight getSupportedFontWeightNormalDefault()
{
if (!mapDefaultWeights.count(fontFamily)) {
throw std::runtime_error(strprintf("%s: Font family not loaded: %s", __func__, fontFamilyToString(fontFamily).toStdString()));
}
return mapDefaultWeights[fontFamily].first;
}

QFont::Weight getSupportedFontWeightBoldDefault()
{
if (!mapDefaultWeights.count(fontFamily)) {
throw std::runtime_error(strprintf("%s: Font family not loaded: %s", __func__, fontFamilyToString(fontFamily).toStdString()));
}
return mapDefaultWeights[fontFamily].second;
}

std::vector<QFont::Weight> getSupportedWeights()
{
assert(mapSupportedWeights.count(fontFamily));
Expand All @@ -1678,7 +1714,12 @@ int supportedWeightToIndex(QFont::Weight weight)
return index;
}
}
assert(false);
return -1;
}

bool isSupportedWeight(const QFont::Weight weight)
{
return supportedWeightToIndex(weight) != -1;
}

QString getActiveTheme()
Expand Down
8 changes: 8 additions & 0 deletions src/qt/guiutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,8 @@ namespace GUIUtil

/** Load dash specific appliciation fonts */
bool loadFonts();
/** Check if the fonts have been loaded successfully */
bool fontsLoaded();

/** Set an application wide default font, depends on the selected theme */
void setApplicationFont();
Expand All @@ -348,12 +350,18 @@ namespace GUIUtil
/** Get the default bold QFont */
QFont getFontBold();

/** Return supported normal default for the current font family */
QFont::Weight getSupportedFontWeightNormalDefault();
/** Return supported bold default for the current font family */
QFont::Weight getSupportedFontWeightBoldDefault();
/** Return supported weights for the current font family */
std::vector<QFont::Weight> getSupportedWeights();
/** Convert an index to a weight in the supported weights vector */
QFont::Weight supportedWeightFromIndex(int nIndex);
/** Convert a weight to an index in the supported weights vector */
int supportedWeightToIndex(QFont::Weight weight);
/** Check if a weight is supported by the current font family */
bool isSupportedWeight(QFont::Weight weight);

/** Return the name of the currently active theme.*/
QString getActiveTheme();
Expand Down
Loading

0 comments on commit b3c6d09

Please sign in to comment.