diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 8a12dd441..fd4bc5610 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -622,7 +622,7 @@ main(int argc, char *argv[]) fprintf(stderr, "Qt: version %s, platform \"%s\"\n", qVersion(), QApplication::platformName().toUtf8().data()); ProgSettings::loadTranslators(&app); #ifdef Q_OS_WINDOWS - QApplication::setFont(QFont(ProgSettings::getFontName(lang_id), 9)); + QApplication::setFont(ProgSettings::getUIFont()); SetCurrentProcessExplicitAppUserModelID(L"86Box.86Box"); #endif diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index f6195389c..1133b26c0 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -2431,7 +2431,7 @@ MainWindow::changeEvent(QEvent *event) #ifdef Q_OS_WINDOWS if (event->type() == QEvent::LanguageChange) { auto size = this->centralWidget()->size(); - QApplication::setFont(QFont(ProgSettings::getFontName(lang_id), 9)); + QApplication::setFont(ProgSettings::getUIFont()); QApplication::processEvents(); main_window->centralWidget()->setFixedSize(size); QApplication::processEvents(); diff --git a/src/qt/qt_progsettings.cpp b/src/qt/qt_progsettings.cpp index 62b63bbcc..d3ebfa9e8 100644 --- a/src/qt/qt_progsettings.cpp +++ b/src/qt/qt_progsettings.cpp @@ -28,6 +28,8 @@ #ifdef Q_OS_WINDOWS # include # include +# define WIN32_LEAN_AND_MEAN +# include #endif extern "C" { @@ -158,26 +160,42 @@ ProgSettings::~ProgSettings() } #ifdef Q_OS_WINDOWS -/* Return the standard font name on Windows, which is overridden per-language - to prevent CJK fonts with embedded bitmaps being chosen as a fallback. */ -QString -ProgSettings::getFontName(int langId) +/* Returns the standard UI font for Windows, which by default varies for different + languages. It can also be changed via external tools, if the user wants that. + + We use the message font here since that is what most Windows components and + other third-party programs use. */ +QFont +ProgSettings::getUIFont() { - QString langCode = languageIdToCode(lang_id); - if (langCode == "ja-JP") { - /* Check for Windows 10 or later to choose the appropriate system font */ - if (QVersionNumber::fromString(QSysInfo::kernelVersion()).majorVersion() >= 10) - return "Yu Gothic UI"; - else - return "Meiryo UI"; - } else if (langCode == "ko-KR") - return "Malgun Gothic"; - else if (langCode == "zh-CN") - return "Microsoft YaHei"; - else if (langCode == "zh-TW") - return "Microsoft JhengHei"; - else - return "Segoe UI"; + // Get the system (primary monitor) DPI. The font returned by + // SystemParametersInfo is scaled according to this and we need + // to get the font size in points to pass into QFont's constructor. + HDC hdc = GetDC(NULL); + int systemDpi = GetDeviceCaps(hdc, LOGPIXELSY); + ReleaseDC(NULL, hdc); + + // Get the font metrics. + NONCLIENTMETRICSW ncm = {}; + ncm.cbSize = sizeof(ncm); + // This should never happen, but just to be safe, return Segoe UI if + // SPI fails. + if (!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0)) + { + return QFont("Segoe UI", 9); + } + + QString fontName = QString::fromWCharArray(ncm.lfMessageFont.lfFaceName); + // Windows' conversion from points to pixels goes as follows: + // + // -MulDiv(PointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72) + // + // (source: https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createfontw) + // + // Let's reverse that calculation to get the point size from the message font. + int fontSize = -MulDiv(ncm.lfMessageFont.lfHeight, 72, systemDpi); + + return QFont(fontName, fontSize); } #endif diff --git a/src/qt/qt_progsettings.hpp b/src/qt/qt_progsettings.hpp index 2ada8c2bf..579c5abf7 100644 --- a/src/qt/qt_progsettings.hpp +++ b/src/qt/qt_progsettings.hpp @@ -15,7 +15,7 @@ public: explicit ProgSettings(QWidget *parent = nullptr); ~ProgSettings(); #ifdef Q_OS_WINDOWS - static QString getFontName(int langId); + static QFont getUIFont(); #endif static int languageCodeToId(QString langCode); static QString languageIdToCode(int id); diff --git a/src/qt/qt_vmmanager_details.cpp b/src/qt/qt_vmmanager_details.cpp index 40d0fb185..300e227e2 100644 --- a/src/qt/qt_vmmanager_details.cpp +++ b/src/qt/qt_vmmanager_details.cpp @@ -165,7 +165,7 @@ VMManagerDetails::VMManagerDetails(QWidget *parent) connect(this, &VMManagerDetails::styleUpdated, portsSection, &VMManagerDetailSection::updateStyle); connect(this, &VMManagerDetails::styleUpdated, otherSection, &VMManagerDetailSection::updateStyle); - QApplication::setFont(QFont(ProgSettings::getFontName(lang_id), 9)); + QApplication::setFont(ProgSettings::getUIFont()); #endif sysconfig = new VMManagerSystem(); diff --git a/src/qt/qt_vmmanager_mainwindow.cpp b/src/qt/qt_vmmanager_mainwindow.cpp index 17bd898bd..a52002653 100644 --- a/src/qt/qt_vmmanager_mainwindow.cpp +++ b/src/qt/qt_vmmanager_mainwindow.cpp @@ -269,7 +269,7 @@ VMManagerMainWindow::changeEvent(QEvent *event) { #ifdef Q_OS_WINDOWS if (event->type() == QEvent::LanguageChange) { - QApplication::setFont(QFont(ProgSettings::getFontName(lang_id), 9)); + QApplication::setFont(QFont(ProgSettings::getUIFont())); } #endif QWidget::changeEvent(event);