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 QFont font = QFontDatabase::systemFont(QFontDatabase::GeneralFont);
55 // On Android, font size may be in pixels, but we expect it to be in points
56 if (font.pointSizeF() == -1) {
57 font.setPointSizeF(font.pixelSize());
58 }
59 return font;
60#endif
61}
62
63boost::optional<QFont> userCfgUiFont()
64{
65 KisConfig cfg(true);
66 if (cfg.readEntry<bool>(useCustomSystemFontCfgName, false)) {
67 QString fontName = cfg.readEntry<QString>(customSystemFontCfgName, QString());
68 if (fontName.isEmpty()) {
69 return boost::none;
70 }
71 int fontSize = cfg.readEntry<int>(customFontSizeCfgName, -1);
72 if (fontSize <= 6) {
73 fontSize = systemDefaultUiFont().pointSize();
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.setPointSizeF(font.pointSizeF() * 0.9);
102 return font;
103}
104
105#if defined(Q_OS_WIN) && QT_VERSION < 0x060000
106
107// From qtbase/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
108static int defaultVerticalDPI()
109{
110 static int vDPI = -1;
111 if (vDPI == -1) {
112 if (HDC defaultDC = GetDC(0)) {
113 vDPI = GetDeviceCaps(defaultDC, LOGPIXELSY);
114 ReleaseDC(0, defaultDC);
115 } else {
116 // FIXME: Resolve now or return 96 and keep unresolved?
117 vDPI = 96;
118 }
119 }
120 return vDPI;
121}
122
123// From qtbase/src/gui/text/qplatformfontdatabase.cpp
124QFont::Weight weightFromInteger(int weight)
125{
126 if (weight < 150) {
127 return QFont::Thin;
128 }
129 if (weight < 250) {
130 return QFont::ExtraLight;
131 }
132 if (weight < 350) {
133 return QFont::Light;
134 }
135 if (weight < 450) {
136 return QFont::Normal;
137 }
138 if (weight < 550) {
139 return QFont::Medium;
140 }
141 if (weight < 650) {
142 return QFont::DemiBold;
143 }
144 if (weight < 750) {
145 return QFont::Bold;
146 }
147 if (weight < 850) {
148 return QFont::ExtraBold;
149 }
150 return QFont::Black;
151}
152
153// From qtbase/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
154static QFont LOGFONT_to_QFont(const LOGFONTW& logFont)
155{
156 const int verticalDPI_In = defaultVerticalDPI();
157 QFont qFont(QString::fromWCharArray(logFont.lfFaceName));
158 qFont.setItalic(logFont.lfItalic);
159 if (logFont.lfWeight != FW_DONTCARE) {
160 qFont.setWeight(weightFromInteger(logFont.lfWeight));
161 }
162 const qreal logFontHeight = qAbs(logFont.lfHeight);
163 qFont.setPointSizeF(logFontHeight * 72.0 / qreal(verticalDPI_In));
164 qFont.setUnderline(logFont.lfUnderline);
165 qFont.setOverline(false);
166 qFont.setStrikeOut(logFont.lfStrikeOut);
167 return qFont;
168}
169
170// From qtbase/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
171static QFont windowsSystemUiFont()
172{
173 // Qt 6: Obtain default GUI font (typically "Segoe UI, 9pt", see QTBUG-58610)
174 NONCLIENTMETRICSW ncm;
175 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSW, lfMessageFont) + sizeof(LOGFONTW);
176 SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, ncm.cbSize , &ncm, 0);
177 const QFont systemFont = LOGFONT_to_QFont(ncm.lfMessageFont);
178 return systemFont;
179}
180#endif
181
182} // namespace KisUiFont
T readEntry(const QString &name, const T &defaultValue=T())
Definition kis_config.h:789
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:63
static const QString customSystemFontCfgName
Definition KisUiFont.cpp:30
static const QString useCustomSystemFontCfgName
Definition KisUiFont.cpp:29