Try to make font handling more straightforward
This commit is contained in:
parent
70e61c8ab8
commit
a052b22872
26 changed files with 142 additions and 303 deletions
|
|
@ -139,8 +139,6 @@ PRIVATE
|
||||||
ui/style/style_core.h
|
ui/style/style_core.h
|
||||||
ui/style/style_core_color.cpp
|
ui/style/style_core_color.cpp
|
||||||
ui/style/style_core_color.h
|
ui/style/style_core_color.h
|
||||||
ui/style/style_core_custom_font.cpp
|
|
||||||
ui/style/style_core_custom_font.h
|
|
||||||
ui/style/style_core_direction.cpp
|
ui/style/style_core_direction.cpp
|
||||||
ui/style/style_core_direction.h
|
ui/style/style_core_direction.h
|
||||||
ui/style/style_core_font.cpp
|
ui/style/style_core_font.cpp
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
fonts/OpenSans-Italic.ttf
Normal file
BIN
fonts/OpenSans-Italic.ttf
Normal file
Binary file not shown.
BIN
fonts/OpenSans-Regular.ttf
Normal file
BIN
fonts/OpenSans-Regular.ttf
Normal file
Binary file not shown.
BIN
fonts/OpenSans-SemiBold.ttf
Normal file
BIN
fonts/OpenSans-SemiBold.ttf
Normal file
Binary file not shown.
BIN
fonts/OpenSans-SemiBoldItalic.ttf
Normal file
BIN
fonts/OpenSans-SemiBoldItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/Vazirmatn-UI-NL-Regular.ttf
Normal file
BIN
fonts/Vazirmatn-UI-NL-Regular.ttf
Normal file
Binary file not shown.
BIN
fonts/Vazirmatn-UI-NL-SemiBold.ttf
Normal file
BIN
fonts/Vazirmatn-UI-NL-SemiBold.ttf
Normal file
Binary file not shown.
|
|
@ -1,13 +1,10 @@
|
||||||
<RCC>
|
<RCC>
|
||||||
<qresource prefix="/gui/fonts">
|
<qresource prefix="/gui/fonts">
|
||||||
<file>DAOpenSansRegular.ttf</file>
|
<file>OpenSans-Regular.ttf</file>
|
||||||
<file>DAOpenSansRegularItalic.ttf</file>
|
<file>OpenSans-Italic.ttf</file>
|
||||||
<file>DAOpenSansSemiboldAsBold.ttf</file>
|
<file>OpenSans-SemiBold.ttf</file>
|
||||||
<file>DAOpenSansSemiboldItalicAsBold.ttf</file>
|
<file>OpenSans-SemiBoldItalic.ttf</file>
|
||||||
<file>DAOpenSansSemibold.ttf</file>
|
<file>Vazirmatn-UI-NL-Regular.ttf</file>
|
||||||
<file>DAOpenSansSemiboldItalic.ttf</file>
|
<file>Vazirmatn-UI-NL-SemiBold.ttf</file>
|
||||||
<file>DAVazirRegular.ttf</file>
|
|
||||||
<file>DAVazirMediumAsBold.ttf</file>
|
|
||||||
<file>DAVazirMedium.ttf</file>
|
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
||||||
|
|
@ -1,82 +0,0 @@
|
||||||
// This file is part of Desktop App Toolkit,
|
|
||||||
// a set of libraries for developing nice desktop applications.
|
|
||||||
//
|
|
||||||
// For license and copyright information please follow this link:
|
|
||||||
// https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
||||||
//
|
|
||||||
#include "ui/style/style_core_custom_font.h"
|
|
||||||
|
|
||||||
#include "ui/style/style_core_font.h"
|
|
||||||
|
|
||||||
#include <QGuiApplication>
|
|
||||||
#include <QFontDatabase>
|
|
||||||
|
|
||||||
namespace style {
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
using namespace internal;
|
|
||||||
|
|
||||||
auto RegularFont = CustomFont();
|
|
||||||
auto BoldFont = CustomFont();
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
void SetCustomFonts(const CustomFont ®ular, const CustomFont &bold) {
|
|
||||||
RegularFont = regular;
|
|
||||||
BoldFont = bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFont ResolveFont(const QString &familyOverride, uint32 flags, int size) {
|
|
||||||
static auto Database = QFontDatabase();
|
|
||||||
|
|
||||||
const auto bold = ((flags & FontBold) || (flags & FontSemibold));
|
|
||||||
const auto italic = (flags & FontItalic);
|
|
||||||
const auto &custom = bold ? BoldFont : RegularFont;
|
|
||||||
const auto useCustom = !custom.family.isEmpty();
|
|
||||||
|
|
||||||
auto result = QFont(QGuiApplication::font().family());
|
|
||||||
if (!familyOverride.isEmpty()) {
|
|
||||||
result.setFamily(familyOverride);
|
|
||||||
if (bold) {
|
|
||||||
result.setBold(true);
|
|
||||||
}
|
|
||||||
} else if (flags & FontMonospace) {
|
|
||||||
result.setFamily(MonospaceFont());
|
|
||||||
} else if (useCustom) {
|
|
||||||
const auto sizes = Database.smoothSizes(custom.family, custom.style);
|
|
||||||
const auto good = sizes.isEmpty()
|
|
||||||
? Database.pointSizes(custom.family, custom.style)
|
|
||||||
: sizes;
|
|
||||||
const auto point = good.isEmpty() ? size : good.front();
|
|
||||||
result = Database.font(custom.family, custom.style, point);
|
|
||||||
} else {
|
|
||||||
result.setFamily(GetFontOverride(flags));
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
|
|
||||||
result.setFeature("ss03", true);
|
|
||||||
#endif // Qt >= 6.7.0
|
|
||||||
if (bold) {
|
|
||||||
#ifdef LIB_UI_USE_PACKAGED_FONTS
|
|
||||||
result.setWeight(QFont::DemiBold);
|
|
||||||
#else // LIB_UI_USE_PACKAGED_FONTS
|
|
||||||
result.setBold(true);
|
|
||||||
#endif // !LIB_UI_USE_PACKAGED_FONTS
|
|
||||||
|
|
||||||
if (flags & FontItalic) {
|
|
||||||
result.setStyleName("Semibold Italic");
|
|
||||||
} else {
|
|
||||||
result.setStyleName("Semibold");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (italic) {
|
|
||||||
result.setItalic(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
result.setUnderline(flags & FontUnderline);
|
|
||||||
result.setStrikeOut(flags & FontStrikeOut);
|
|
||||||
result.setPixelSize(size);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace style
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
// This file is part of Desktop App Toolkit,
|
|
||||||
// a set of libraries for developing nice desktop applications.
|
|
||||||
//
|
|
||||||
// For license and copyright information please follow this link:
|
|
||||||
// https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
||||||
//
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace style {
|
|
||||||
|
|
||||||
struct CustomFont {
|
|
||||||
QString family;
|
|
||||||
QString style;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline bool operator==(const CustomFont &a, const CustomFont &b) {
|
|
||||||
return (a.family == b.family) && (a.style == b.style);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator<(const CustomFont &a, const CustomFont &b) {
|
|
||||||
return (a.family < b.family)
|
|
||||||
|| (a.family == b.family && a.style < b.style);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator!=(const CustomFont &a, const CustomFont &b) {
|
|
||||||
return !(a == b);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator>(const CustomFont &a, const CustomFont &b) {
|
|
||||||
return (b < a);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator<=(const CustomFont &a, const CustomFont &b) {
|
|
||||||
return !(b < a);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator>=(const CustomFont &a, const CustomFont &b) {
|
|
||||||
return !(a < b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetCustomFonts(const CustomFont ®ular, const CustomFont &bold);
|
|
||||||
|
|
||||||
[[nodiscard]] QFont ResolveFont(const QString &familyOverride, uint32 flags, int size);
|
|
||||||
|
|
||||||
} // namespace style
|
|
||||||
|
|
@ -8,8 +8,8 @@
|
||||||
|
|
||||||
#include "base/algorithm.h"
|
#include "base/algorithm.h"
|
||||||
#include "base/debug_log.h"
|
#include "base/debug_log.h"
|
||||||
|
#include "base/variant.h"
|
||||||
#include "base/base_file_utilities.h"
|
#include "base/base_file_utilities.h"
|
||||||
#include "ui/style/style_core_custom_font.h"
|
|
||||||
#include "ui/integration.h"
|
#include "ui/integration.h"
|
||||||
|
|
||||||
#include <QtCore/QMap>
|
#include <QtCore/QMap>
|
||||||
|
|
@ -18,10 +18,6 @@
|
||||||
#include <QtGui/QFontDatabase>
|
#include <QtGui/QFontDatabase>
|
||||||
#include <QtWidgets/QApplication>
|
#include <QtWidgets/QApplication>
|
||||||
|
|
||||||
#if __has_include(<glib.h>)
|
|
||||||
#include <glib.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void style_InitFontsResource() {
|
void style_InitFontsResource() {
|
||||||
#ifdef Q_OS_MAC // Use resources from the .app bundle on macOS.
|
#ifdef Q_OS_MAC // Use resources from the .app bundle on macOS.
|
||||||
|
|
||||||
|
|
@ -40,9 +36,35 @@ void style_InitFontsResource() {
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace style {
|
namespace style {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
Font CustomFont;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void SetCustomFont(const Font &font) {
|
||||||
|
CustomFont = font;
|
||||||
|
}
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
#ifndef LIB_UI_USE_PACKAGED_FONTS
|
||||||
|
const auto FontTypes = std::array{
|
||||||
|
std::make_pair(u"OpenSans-Regular"_q, FontFlags()),
|
||||||
|
std::make_pair(u"OpenSans-Italic"_q, FontItalic),
|
||||||
|
std::make_pair(u"OpenSans-SemiBold"_q, FontSemibold),
|
||||||
|
std::make_pair(u"OpenSans-SemiBoldItalic"_q, FontFlags(FontSemibold | FontItalic)),
|
||||||
|
};
|
||||||
|
const auto PersianFontTypes = std::array{
|
||||||
|
std::make_pair(u"Vazirmatn-UI-NL-Regular"_q, FontFlags()),
|
||||||
|
std::make_pair(u"Vazirmatn-UI-NL-SemiBold"_q, FontSemibold),
|
||||||
|
};
|
||||||
|
#endif // !LIB_UI_USE_PACKAGED_FONTS
|
||||||
|
|
||||||
|
bool Started = false;
|
||||||
|
QString FontOverride;
|
||||||
|
|
||||||
QMap<QString, int> fontFamilyMap;
|
QMap<QString, int> fontFamilyMap;
|
||||||
QVector<QString> fontFamilies;
|
QVector<QString> fontFamilies;
|
||||||
QMap<uint32, FontData*> fontsMap;
|
QMap<uint32, FontData*> fontsMap;
|
||||||
|
|
@ -53,11 +75,14 @@ uint32 fontKey(int size, uint32 flags, int family) {
|
||||||
|
|
||||||
bool ValidateFont(const QString &familyName, int flags = 0) {
|
bool ValidateFont(const QString &familyName, int flags = 0) {
|
||||||
QFont checkFont(familyName);
|
QFont checkFont(familyName);
|
||||||
checkFont.setBold(flags & style::internal::FontBold);
|
checkFont.setWeight(((flags & FontBold) || (flags & FontSemibold))
|
||||||
checkFont.setItalic(flags & style::internal::FontItalic);
|
? QFont::DemiBold
|
||||||
checkFont.setUnderline(flags & style::internal::FontUnderline);
|
: QFont::Normal);
|
||||||
|
checkFont.setItalic(flags & FontItalic);
|
||||||
|
checkFont.setUnderline(flags & FontUnderline);
|
||||||
|
checkFont.setStrikeOut(flags & FontStrikeOut);
|
||||||
auto realFamily = QFontInfo(checkFont).family();
|
auto realFamily = QFontInfo(checkFont).family();
|
||||||
if (realFamily.trimmed().compare(familyName, Qt::CaseInsensitive)) {
|
if (!realFamily.trimmed().startsWith(familyName, Qt::CaseInsensitive)) {
|
||||||
LOG(("Font Error: could not resolve '%1' font, got '%2'.").arg(familyName, realFamily));
|
LOG(("Font Error: could not resolve '%1' font, got '%2'.").arg(familyName, realFamily));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -82,7 +107,7 @@ bool LoadCustomFont(const QString &filePath, const QString &familyName, int flag
|
||||||
const auto found = [&] {
|
const auto found = [&] {
|
||||||
for (auto &family : QFontDatabase::applicationFontFamilies(regularId)) {
|
for (auto &family : QFontDatabase::applicationFontFamilies(regularId)) {
|
||||||
LOG(("Font: from '%1' loaded '%2'").arg(filePath, family));
|
LOG(("Font: from '%1' loaded '%2'").arg(filePath, family));
|
||||||
if (!family.trimmed().compare(familyName, Qt::CaseInsensitive)) {
|
if (family.trimmed().startsWith(familyName, Qt::CaseInsensitive)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -104,167 +129,21 @@ bool LoadCustomFont(const QString &filePath, const QString &familyName, int flag
|
||||||
|
|
||||||
[[nodiscard]] QString ManualMonospaceFont() {
|
[[nodiscard]] QString ManualMonospaceFont() {
|
||||||
const auto kTryFirst = std::initializer_list<QString>{
|
const auto kTryFirst = std::initializer_list<QString>{
|
||||||
"Cascadia Mono",
|
u"Cascadia Mono"_q,
|
||||||
"Consolas",
|
u"Consolas"_q,
|
||||||
"Liberation Mono",
|
u"Liberation Mono"_q,
|
||||||
"Menlo",
|
u"Menlo"_q,
|
||||||
"Courier"
|
u"Courier"_q,
|
||||||
};
|
};
|
||||||
for (const auto &family : kTryFirst) {
|
for (const auto &family : kTryFirst) {
|
||||||
const auto resolved = QFontInfo(QFont(family)).family();
|
const auto resolved = QFontInfo(QFont(family)).family();
|
||||||
if (!resolved.trimmed().compare(family, Qt::CaseInsensitive)) {
|
if (resolved.trimmed().startsWith(family, Qt::CaseInsensitive)) {
|
||||||
return family;
|
return family;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
enum {
|
|
||||||
FontTypeRegular = 0,
|
|
||||||
FontTypeRegularItalic,
|
|
||||||
FontTypeBold,
|
|
||||||
FontTypeBoldItalic,
|
|
||||||
FontTypeSemibold,
|
|
||||||
FontTypeSemiboldItalic,
|
|
||||||
|
|
||||||
FontTypesCount,
|
|
||||||
};
|
|
||||||
#ifndef LIB_UI_USE_PACKAGED_FONTS
|
|
||||||
QString FontTypeFiles[FontTypesCount] = {
|
|
||||||
"DAOpenSansRegular",
|
|
||||||
"DAOpenSansRegularItalic",
|
|
||||||
"DAOpenSansSemiboldAsBold",
|
|
||||||
"DAOpenSansSemiboldItalicAsBold",
|
|
||||||
"DAOpenSansSemiboldAsBold",
|
|
||||||
"DAOpenSansSemiboldItalicAsBold",
|
|
||||||
};
|
|
||||||
QString FontTypeNames[FontTypesCount] = {
|
|
||||||
"DAOpenSansRegular",
|
|
||||||
"DAOpenSansRegularItalic",
|
|
||||||
"DAOpenSansSemibold",
|
|
||||||
"DAOpenSansSemiboldItalic",
|
|
||||||
"DAOpenSansSemibold",
|
|
||||||
"DAOpenSansSemiboldItalic",
|
|
||||||
};
|
|
||||||
QString FontTypePersianFallbackFiles[FontTypesCount] = {
|
|
||||||
"DAVazirRegular",
|
|
||||||
"DAVazirRegular",
|
|
||||||
"DAVazirMediumAsBold",
|
|
||||||
"DAVazirMediumAsBold",
|
|
||||||
"DAVazirMediumAsBold",
|
|
||||||
"DAVazirMediumAsBold",
|
|
||||||
};
|
|
||||||
QString FontTypePersianFallback[FontTypesCount] = {
|
|
||||||
"DAVazirRegular",
|
|
||||||
"DAVazirRegular",
|
|
||||||
"DAVazirMedium",
|
|
||||||
"DAVazirMedium",
|
|
||||||
"DAVazirMedium",
|
|
||||||
"DAVazirMedium",
|
|
||||||
};
|
|
||||||
int32 FontTypeFlags[FontTypesCount] = {
|
|
||||||
0,
|
|
||||||
FontItalic,
|
|
||||||
FontBold,
|
|
||||||
FontBold | FontItalic,
|
|
||||||
FontSemibold,
|
|
||||||
FontSemibold | FontItalic,
|
|
||||||
};
|
|
||||||
#endif // !LIB_UI_USE_PACKAGED_FONTS
|
|
||||||
|
|
||||||
bool Started = false;
|
|
||||||
QString Overrides[FontTypesCount];
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
void StartFonts() {
|
|
||||||
if (Started) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Started = true;
|
|
||||||
|
|
||||||
style_InitFontsResource();
|
|
||||||
|
|
||||||
#ifndef LIB_UI_USE_PACKAGED_FONTS
|
|
||||||
[[maybe_unused]] bool areGood[FontTypesCount] = { false };
|
|
||||||
for (auto i = 0; i != FontTypesCount; ++i) {
|
|
||||||
const auto file = FontTypeFiles[i];
|
|
||||||
const auto name = FontTypeNames[i];
|
|
||||||
const auto flags = FontTypeFlags[i];
|
|
||||||
areGood[i] = LoadCustomFont(":/gui/fonts/" + file + ".ttf", name, flags);
|
|
||||||
Overrides[i] = name;
|
|
||||||
|
|
||||||
const auto persianFallbackFile = FontTypePersianFallbackFiles[i];
|
|
||||||
const auto persianFallback = FontTypePersianFallback[i];
|
|
||||||
LoadCustomFont(":/gui/fonts/" + persianFallbackFile + ".ttf", persianFallback, flags);
|
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
// Attempt to workaround a strange font bug with Open Sans Semibold not loading.
|
|
||||||
// See https://github.com/telegramdesktop/tdesktop/issues/3276 for details.
|
|
||||||
// Crash happens on "options.maxh / _t->_st->font->height" with "division by zero".
|
|
||||||
// In that place "_t->_st->font" is "semiboldFont" is "font(13 "Open Sans Semibold").
|
|
||||||
const auto fallback = "Segoe UI";
|
|
||||||
if (!areGood[i]) {
|
|
||||||
if (ValidateFont(fallback, flags)) {
|
|
||||||
Overrides[i] = fallback;
|
|
||||||
LOG(("Fonts Info: Using '%1' instead of '%2'.").arg(fallback).arg(name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Disable default fallbacks to Segoe UI, see:
|
|
||||||
// https://github.com/telegramdesktop/tdesktop/issues/5368
|
|
||||||
//
|
|
||||||
//QFont::insertSubstitution(name, fallback);
|
|
||||||
#endif // Q_OS_WIN
|
|
||||||
|
|
||||||
QFont::insertSubstitution(name, persianFallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
|
||||||
auto list = QStringList();
|
|
||||||
list.append("STIXGeneral");
|
|
||||||
list.append(".SF NS Text");
|
|
||||||
list.append("Helvetica Neue");
|
|
||||||
list.append("Lucida Grande");
|
|
||||||
for (const auto &name : FontTypeNames) {
|
|
||||||
QFont::insertSubstitutions(name, list);
|
|
||||||
}
|
|
||||||
#endif // Q_OS_MAC
|
|
||||||
#elif __has_include(<glib.h>) // !LIB_UI_USE_PACKAGED_FONTS
|
|
||||||
g_warning(
|
|
||||||
"Unable to load patched fonts with Qt workarounds, "
|
|
||||||
"expect font issues.");
|
|
||||||
#endif // LIB_UI_USE_PACKAGED_FONTS
|
|
||||||
|
|
||||||
auto appFont = QApplication::font();
|
|
||||||
appFont.setStyleStrategy(QFont::PreferQuality);
|
|
||||||
QApplication::setFont(appFont);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString GetPossibleEmptyOverride(int32 flags) {
|
|
||||||
flags = flags & (FontBold | FontSemibold | FontItalic);
|
|
||||||
int32 flagsBold = flags & (FontBold | FontItalic);
|
|
||||||
int32 flagsSemibold = flags & (FontSemibold | FontItalic);
|
|
||||||
if (flagsSemibold == (FontSemibold | FontItalic)) {
|
|
||||||
return Overrides[FontTypeSemiboldItalic];
|
|
||||||
} else if (flagsSemibold == FontSemibold) {
|
|
||||||
return Overrides[FontTypeSemibold];
|
|
||||||
} else if (flagsBold == (FontBold | FontItalic)) {
|
|
||||||
return Overrides[FontTypeBoldItalic];
|
|
||||||
} else if (flagsBold == FontBold) {
|
|
||||||
return Overrides[FontTypeBold];
|
|
||||||
} else if (flags == FontItalic) {
|
|
||||||
return Overrides[FontTypeRegularItalic];
|
|
||||||
} else if (flags == 0) {
|
|
||||||
return Overrides[FontTypeRegular];
|
|
||||||
}
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString GetFontOverride(int32 flags) {
|
|
||||||
const auto result = GetPossibleEmptyOverride(flags);
|
|
||||||
return result.isEmpty() ? "Open Sans" : result;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString MonospaceFont() {
|
QString MonospaceFont() {
|
||||||
static const auto family = [&]() -> QString {
|
static const auto family = [&]() -> QString {
|
||||||
const auto manual = ManualMonospaceFont();
|
const auto manual = ManualMonospaceFont();
|
||||||
|
|
@ -285,6 +164,94 @@ QString MonospaceFont() {
|
||||||
return family;
|
return family;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QFont ResolveFont(const QString &familyOverride, uint32 flags, int size) {
|
||||||
|
auto result = QFont();
|
||||||
|
if (!familyOverride.isEmpty()) {
|
||||||
|
result.setFamily(familyOverride);
|
||||||
|
} else if (flags & FontMonospace) {
|
||||||
|
result.setFamily(MonospaceFont());
|
||||||
|
} else if (v::is<QString>(CustomFont)) {
|
||||||
|
result.setFamily(v::get<QString>(CustomFont));
|
||||||
|
} else if (!v::is<SystemFont>(CustomFont)) {
|
||||||
|
result.setFamily(GetFontOverride(flags));
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
|
||||||
|
result.setFeature("ss03", true);
|
||||||
|
#endif // Qt >= 6.7.0
|
||||||
|
}
|
||||||
|
result.setWeight(((flags & FontBold) || (flags & FontSemibold))
|
||||||
|
? QFont::DemiBold
|
||||||
|
: QFont::Normal);
|
||||||
|
result.setItalic(flags & FontItalic);
|
||||||
|
result.setUnderline(flags & FontUnderline);
|
||||||
|
result.setStrikeOut(flags & FontStrikeOut);
|
||||||
|
result.setPixelSize(size);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void StartFonts() {
|
||||||
|
if (Started) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Started = true;
|
||||||
|
|
||||||
|
style_InitFontsResource();
|
||||||
|
|
||||||
|
#ifndef LIB_UI_USE_PACKAGED_FONTS
|
||||||
|
[[maybe_unused]] bool good = true;
|
||||||
|
const auto name = u"Open Sans"_q;
|
||||||
|
const auto persianFallback = u"Vazirmatn UI NL"_q;
|
||||||
|
|
||||||
|
for (const auto &[file, flags] : FontTypes) {
|
||||||
|
if (!LoadCustomFont(u":/gui/fonts/"_q + file + u".ttf"_q, name, flags)) {
|
||||||
|
good = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &[file, flags] : PersianFontTypes) {
|
||||||
|
LoadCustomFont(u":/gui/fonts/"_q + file + u".ttf"_q, persianFallback, flags);
|
||||||
|
}
|
||||||
|
QFont::insertSubstitution(name, persianFallback);
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
// Attempt to workaround a strange font bug with Open Sans Semibold not loading.
|
||||||
|
// See https://github.com/telegramdesktop/tdesktop/issues/3276 for details.
|
||||||
|
// Crash happens on "options.maxh / _t->_st->font->height" with "division by zero".
|
||||||
|
// In that place "_t->_st->font" is "semiboldFont" is "font(13 "Open Sans Semibold").
|
||||||
|
const auto fallback = u"Segoe UI"_q;
|
||||||
|
if (!good) {
|
||||||
|
if (ValidateFont(fallback, flags)) {
|
||||||
|
FontOverride = fallback;
|
||||||
|
LOG(("Fonts Info: Using '%1' instead of '%2'.").arg(fallback, name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Disable default fallbacks to Segoe UI, see:
|
||||||
|
// https://github.com/telegramdesktop/tdesktop/issues/5368
|
||||||
|
//
|
||||||
|
//QFont::insertSubstitution(name, fallback);
|
||||||
|
#endif // Q_OS_WIN
|
||||||
|
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
const auto list = QStringList{
|
||||||
|
u"STIXGeneral"_q,
|
||||||
|
u".SF NS Text"_q,
|
||||||
|
u"Helvetica Neue"_q,
|
||||||
|
u"Lucida Grande"_q,
|
||||||
|
};
|
||||||
|
QFont::insertSubstitutions(name, list);
|
||||||
|
#endif // Q_OS_MAC
|
||||||
|
#endif // !LIB_UI_USE_PACKAGED_FONTS
|
||||||
|
|
||||||
|
auto appFont = QApplication::font();
|
||||||
|
appFont.setStyleStrategy(QFont::PreferQuality);
|
||||||
|
QApplication::setFont(appFont);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString GetFontOverride(int32 flags) {
|
||||||
|
return FontOverride.isEmpty() ? u"Open Sans"_q : FontOverride;
|
||||||
|
}
|
||||||
|
|
||||||
void destroyFonts() {
|
void destroyFonts() {
|
||||||
for (auto fontData : std::as_const(fontsMap)) {
|
for (auto fontData : std::as_const(fontsMap)) {
|
||||||
delete fontData;
|
delete fontData;
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,15 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
namespace style {
|
namespace style {
|
||||||
|
|
||||||
|
struct SystemFont {};
|
||||||
|
using Font = std::variant<std::monostate, SystemFont, QString>;
|
||||||
|
void SetCustomFont(const Font &font);
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
void StartFonts();
|
void StartFonts();
|
||||||
[[nodiscard]] QString GetFontOverride(int32 flags = 0);
|
[[nodiscard]] QString GetFontOverride(int32 flags = 0);
|
||||||
[[nodiscard]] QString MonospaceFont();
|
|
||||||
|
|
||||||
void destroyFonts();
|
void destroyFonts();
|
||||||
int registerFontFamily(const QString &family);
|
int registerFontFamily(const QString &family);
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ constexpr auto kMaxDiacAfterSymbol = 2;
|
||||||
const auto &font = st.font;
|
const auto &font = st.font;
|
||||||
return (font->size() * style::DevicePixelRatio() == 13)
|
return (font->size() * style::DevicePixelRatio() == 13)
|
||||||
&& (font->flags() == 0)
|
&& (font->flags() == 0)
|
||||||
&& (font->f.family() == qstr("DAOpenSansRegular"));
|
&& (font->f.family() == qstr("Open Sans"));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
||||||
|
|
@ -2086,7 +2086,7 @@ bool InputField::isRedoAvailable() const {
|
||||||
void InputField::processFormatting(int insertPosition, int insertEnd) {
|
void InputField::processFormatting(int insertPosition, int insertEnd) {
|
||||||
// Tilde formatting.
|
// Tilde formatting.
|
||||||
const auto tildeFormatting = (_st.font->f.pixelSize() * style::DevicePixelRatio() == 13)
|
const auto tildeFormatting = (_st.font->f.pixelSize() * style::DevicePixelRatio() == 13)
|
||||||
&& (_st.font->f.family() == qstr("DAOpenSansRegular"));
|
&& (_st.font->f.family() == qstr("Open Sans"));
|
||||||
auto isTildeFragment = false;
|
auto isTildeFragment = false;
|
||||||
auto tildeFixedFont = _st.font->semibold()->f;
|
auto tildeFixedFont = _st.font->semibold()->f;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue