Krita Source Code Documentation
Loading...
Searching...
No Matches
KisUiFont.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2016 The Qt Company Ltd.
3 * SPDX-FileCopyrightText: 2020 Halla Rempt <halla@valdyas.org>
4 * SPDX-FileCopyrightText: 2021 Alvin Wong <alvin@alvinhc.com>
5 *
6 * SPDX-License-Identifier: GPL-3.0-or-later
7 *
8 *
9 * This file contains code that was borrowed and modified from the Qt Project,
10 * originally licensed under LGPL-3.0-or-later or GPL-2.0-or-later.
11 */
12
13#include "KisUiFont.h"
14
15#include <kis_config.h>
16
17#include <boost/optional.hpp>
18
19#include <QtGlobal>
20#include <QFontDatabase>
21
22#if defined(Q_OS_WIN) && QT_VERSION < 0x060000
23# include <qt_windows.h>
24#endif
25
26namespace KisUiFont
27{
28
29static const QString useCustomSystemFontCfgName = QStringLiteral("use_custom_system_font");
30static const QString customSystemFontCfgName = QStringLiteral("custom_system_font");
31static const QString customFontSizeCfgName = QStringLiteral("custom_font_size");
32
37static QFont systemDefaultUiFont();
38
43static boost::optional<QFont> userCfgUiFont();
44
45#if defined(Q_OS_WIN) && QT_VERSION < 0x060000
46static QFont windowsSystemUiFont();
47#endif
48
50{
51#if defined(Q_OS_WIN) && QT_VERSION < 0x060000
52 return windowsSystemUiFont();
53#else
54 return QFontDatabase::systemFont(QFontDatabase::GeneralFont);
55#endif
56}
57
58boost::optional<QFont> userCfgUiFont()
59{
60 KisConfig cfg(true);
61 if (cfg.readEntry<bool>(useCustomSystemFontCfgName, false)) {
62 QString fontName = cfg.readEntry<QString>(customSystemFontCfgName, QString());
63 if (fontName.isEmpty()) {
64 return boost::none;
65 }
66 int fontSize = cfg.readEntry<int>(customFontSizeCfgName, -1);
67 if (fontSize <= 6) {
68 // Font size may be in pixels (on Android) or points (everywhere else.)
69 QFont systemFont = systemDefaultUiFont();
70 fontSize = systemFont.pointSize();
71 if (fontSize == -1) {
72 fontSize = systemFont.pixelSize();
73 }
74 }
75 return QFont(fontName, fontSize);
76 } else {
77 return boost::none;
78 }
79}
80
82{
83 QFont font;
84 if (boost::optional<QFont> userFont = userCfgUiFont()) {
85 font = *userFont;
86 } else {
87 font = systemDefaultUiFont();
88 }
89#ifdef Q_OS_WIN
90 // XXX: Forces Qt to use full hinting for UI text, otherwise the default
91 // will cause Qt to do vertical hinting only when High-DPI is active,
92 // which makes some UI text extremely blurry on CJK systems.
93 font.setHintingPreference(QFont::PreferFullHinting);
94#endif
95 return font;
96}
97
98QFont dockFont()
99{
100 QFont font = normalFont();
101 // Font size may be in pixels (on Android) or points (everywhere else.)
102 qreal ratio = 0.9;
103 if (font.pixelSize() == -1) {
104 font.setPointSizeF(font.pointSizeF() * ratio);
105 } else {
106 font.setPixelSize(qRound(font.pixelSize() * ratio));
107 }
108 return font;
109}
110
111#if defined(Q_OS_WIN) && QT_VERSION < 0x060000
112
113// From qtbase/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
114static int defaultVerticalDPI()
115{
116 static int vDPI = -1;
117 if (vDPI == -1) {
118 if (HDC defaultDC = GetDC(0)) {
119 vDPI = GetDeviceCaps(defaultDC, LOGPIXELSY);
120 ReleaseDC(0, defaultDC);
121 } else {
122 // FIXME: Resolve now or return 96 and keep unresolved?
123 vDPI = 96;
124 }
125 }
126 return vDPI;
127}
128
129// From qtbase/src/gui/text/qplatformfontdatabase.cpp
130QFont::Weight weightFromInteger(int weight)
131{
132 if (weight < 150) {
133 return QFont::Thin;
134 }
135 if (weight < 250) {
136 return QFont::ExtraLight;
137 }
138 if (weight < 350) {
139 return QFont::Light;
140 }
141 if (weight < 450) {
142 return QFont::Normal;
143 }
144 if (weight < 550) {
145 return QFont::Medium;
146 }
147 if (weight < 650) {
148 return QFont::DemiBold;
149 }
150 if (weight < 750) {
151 return QFont::Bold;
152 }
153 if (weight < 850) {
154 return QFont::ExtraBold;
155 }
156 return QFont::Black;
157}
158
159// From qtbase/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
160static QFont LOGFONT_to_QFont(const LOGFONTW& logFont)
161{
162 const int verticalDPI_In = defaultVerticalDPI();
163 QFont qFont(QString::fromWCharArray(logFont.lfFaceName));
164 qFont.setItalic(logFont.lfItalic);
165 if (logFont.lfWeight != FW_DONTCARE) {
166 qFont.setWeight(weightFromInteger(logFont.lfWeight));
167 }
168 const qreal logFontHeight = qAbs(logFont.lfHeight);
169 qFont.setPointSizeF(logFontHeight * 72.0 / qreal(verticalDPI_In));
170 qFont.setUnderline(logFont.lfUnderline);
171 qFont.setOverline(false);
172 qFont.setStrikeOut(logFont.lfStrikeOut);
173 return qFont;
174}
175
176// From qtbase/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
177static QFont windowsSystemUiFont()
178{
179 // Qt 6: Obtain default GUI font (typically "Segoe UI, 9pt", see QTBUG-58610)
180 NONCLIENTMETRICSW ncm;
181 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSW, lfMessageFont) + sizeof(LOGFONTW);
182 SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, ncm.cbSize , &ncm, 0);
183 const QFont systemFont = LOGFONT_to_QFont(ncm.lfMessageFont);
184 return systemFont;
185}
186#endif
187
188} // namespace KisUiFont
T readEntry(const QString &name, const T &defaultValue=T())
Definition kis_config.h:832
QFont normalFont()
Gets a font for normal UI widgets to use.
Definition KisUiFont.cpp:81
static const QString customFontSizeCfgName
Definition KisUiFont.cpp:31
QFont dockFont()
Gets a font with a smallish font size for dock widgets to use.
Definition KisUiFont.cpp:98
static QFont systemDefaultUiFont()
Gets the system default UI font.
Definition KisUiFont.cpp:49
static boost::optional< QFont > userCfgUiFont()
Returns the font the user has configured.
Definition KisUiFont.cpp:58
static const QString customSystemFontCfgName
Definition KisUiFont.cpp:30
static const QString useCustomSystemFontCfgName
Definition KisUiFont.cpp:29