From 3106a3474b4185217bbb230c605565f127d2a3a1 Mon Sep 17 00:00:00 2001 From: ilya-fedin Date: Thu, 30 Jan 2020 11:43:51 +0400 Subject: [PATCH] add possiblity to use system font (#2) --- ui/style/style_core.cpp | 15 ++++--- ui/style/style_core_font.cpp | 87 +++++++++++++++++++++++------------- ui/style/style_core_font.h | 5 ++- ui/text/text.cpp | 14 +++--- ui/text/text_block.cpp | 14 +++--- ui/widgets/input_fields.cpp | 5 +-- 6 files changed, 90 insertions(+), 50 deletions(-) diff --git a/ui/style/style_core.cpp b/ui/style/style_core.cpp index 3f9b003..4232be6 100644 --- a/ui/style/style_core.cpp +++ b/ui/style/style_core.cpp @@ -19,6 +19,9 @@ namespace style { namespace internal { + +bool GetUseSystemFont(); + namespace { constexpr auto kMinContrastAlpha = 64; @@ -55,16 +58,18 @@ void ResolveMonospaceFont() { if (!CustomMonospaceFont.isEmpty()) { tryFont(CustomMonospaceFont); } - tryFont("Consolas"); - tryFont("Liberation Mono"); - tryFont("Menlo"); - tryFont("Courier"); + if (!GetUseSystemFont()) { + tryFont("Consolas"); + tryFont("Liberation Mono"); + tryFont("Menlo"); + tryFont("Courier"); + } if (family.isEmpty()) { const auto type = QFontDatabase::FixedFont; family = QFontDatabase::systemFont(type).family(); } const auto size = st::normalFont->f.pixelSize(); - ResolvedMonospaceFont = style::font(size, 0, family); + ResolvedMonospaceFont = style::font(size, 0, family)->monospace(); } } // namespace diff --git a/ui/style/style_core_font.cpp b/ui/style/style_core_font.cpp index 6295331..8ea3ed9 100644 --- a/ui/style/style_core_font.cpp +++ b/ui/style/style_core_font.cpp @@ -36,7 +36,7 @@ QVector fontFamilies; QMap fontsMap; uint32 fontKey(int size, uint32 flags, int family) { - return (((uint32(family) << 10) | uint32(size)) << 4) | flags; + return (((uint32(family) << 12) | uint32(size)) << 6) | flags; } QString RemoveSemiboldFromName(const QString &familyName) { @@ -170,9 +170,14 @@ QString Overrides[FontTypesCount]; QString CustomMainFont; QString CustomSemiboldFont; bool CustomSemiboldIsBold = false; +bool UseSystemFont = false; } // namespace +bool GetUseSystemFont() { + return UseSystemFont; +} + void SetMainFont(const QString &familyName) { CustomMainFont = familyName; } @@ -185,6 +190,10 @@ void SetSemiboldIsBold(bool isBold) { CustomSemiboldIsBold = isBold; } +void SetUseSystemFont(bool isSystemFont) { + UseSystemFont = isSystemFont; +} + void StartFonts() { if (Started) { return; @@ -193,41 +202,43 @@ void StartFonts() { style_InitFontsResource(); + if (!UseSystemFont) { #ifndef DESKTOP_APP_USE_PACKAGED_FONTS - bool areGood[FontTypesCount] = { false }; - for (auto i = 0; i != FontTypesCount; ++i) { - const auto name = FontTypeNames[i]; - const auto flags = FontTypeFlags[i]; - areGood[i] = LoadCustomFont(":/gui/fonts/" + name + ".ttf", name, flags); - Overrides[i] = name; + bool areGood[FontTypesCount] = { false }; + for (auto i = 0; i != FontTypesCount; ++i) { + const auto name = FontTypeNames[i]; + const auto flags = FontTypeFlags[i]; + areGood[i] = LoadCustomFont(":/gui/fonts/" + name + ".ttf", name, flags); + Overrides[i] = name; #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 = FontTypeWindowsFallback[i]; - if (!areGood[i]) { - if (ValidateFont(fallback, flags)) { - Overrides[i] = fallback; - UI_LOG(("Fonts Info: Using '%1' instead of '%2'.").arg(fallback).arg(name)); + // 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 = FontTypeWindowsFallback[i]; + if (!areGood[i]) { + if (ValidateFont(fallback, flags)) { + Overrides[i] = fallback; + UI_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); + // Disable default fallbacks to Segoe UI, see: + // https://github.com/telegramdesktop/tdesktop/issues/5368 + // + //QFont::insertSubstitution(name, fallback); #endif // Q_OS_WIN - } + } #endif // !DESKTOP_APP_USE_PACKAGED_FONTS #ifdef Q_OS_MAC - auto list = QStringList(); - list.append(".SF NS Text"); - list.append("Helvetica Neue"); - list.append("Lucida Grande"); - for (const auto &name : FontTypeNames) { - QFont::insertSubstitutions(name, list); - } + auto list = QStringList(); + 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 + } if (!CustomMainFont.isEmpty() && ValidateFont(CustomMainFont)) { Overrides[FontTypeRegular] = CustomMainFont; @@ -286,11 +297,14 @@ int registerFontFamily(const QString &family) { } FontData::FontData(int size, uint32 flags, int family, Font *other) -: f(ParseFamilyName(GetFontOverride(fontFamilies[family], flags))) +: f() , m(f) , _size(size) , _flags(flags) , _family(family) { + const auto fontOverride = GetFontOverride(fontFamilies[family], flags); + const auto possibleEmptyOverride = GetPossibleEmptyOverride(fontFamilies[family], flags); + if (other) { memcpy(modified, other, sizeof(modified)); } else { @@ -298,11 +312,18 @@ FontData::FontData(int size, uint32 flags, int family, Font *other) } modified[_flags] = Font(this); + if (!UseSystemFont || !possibleEmptyOverride.isEmpty() || (_flags & FontMonospace)) { + f.setFamily(fontOverride); + } + f.setPixelSize(size); if (_flags & FontBold) { f.setBold(true); } else if (fontFamilies[family] == "Open Sans Semibold" && CustomSemiboldIsBold) { f.setBold(true); + } else if (fontFamilies[family] == "Open Sans Semibold" && UseSystemFont + && possibleEmptyOverride.isEmpty()) { + f.setWeight(QFont::DemiBold); #ifdef DESKTOP_APP_USE_PACKAGED_FONTS } else if (fontFamilies[family] == "Open Sans Semibold") { f.setWeight(QFont::DemiBold); @@ -313,7 +334,7 @@ FontData::FontData(int size, uint32 flags, int family, Font *other) f.setStrikeOut(_flags & FontStrikeOut); f.setStyleStrategy(QFont::PreferQuality); - if (IsRealSemibold(GetFontOverride(fontFamilies[family], flags))) { + if (IsRealSemibold(fontOverride)) { f.setStyleName("Semibold"); } @@ -341,6 +362,10 @@ Font FontData::strikeout(bool set) const { return otherFlagsFont(FontStrikeOut, set); } +Font FontData::monospace(bool set) const { + return otherFlagsFont(FontMonospace, set); +} + int FontData::size() const { return _size; } diff --git a/ui/style/style_core_font.h b/ui/style/style_core_font.h index 6ea22c0..d9cd9b1 100644 --- a/ui/style/style_core_font.h +++ b/ui/style/style_core_font.h @@ -17,6 +17,7 @@ namespace internal { void SetMainFont(const QString &familyName); void SetSemiboldFont(const QString &familyName); void SetSemiboldIsBold(bool isBold); +void SetUseSystemFont(bool isSystemFont); void StartFonts(); [[nodiscard]] QString GetFontOverride(const QString &familyName, int32 flags = 0); @@ -63,8 +64,9 @@ enum FontFlags { FontItalic = 0x02, FontUnderline = 0x04, FontStrikeOut = 0x08, + FontMonospace = 0x10, - FontDifferentFlags = 0x10, + FontDifferentFlags = 0x20, }; class FontData { @@ -87,6 +89,7 @@ public: Font italic(bool set = true) const; Font underline(bool set = true) const; Font strikeout(bool set = true) const; + Font monospace(bool set = true) const; int size() const; uint32 flags() const; diff --git a/ui/text/text.cpp b/ui/text/text.cpp index 90f9f8e..faa1dc4 100644 --- a/ui/text/text.cpp +++ b/ui/text/text.cpp @@ -2015,8 +2015,8 @@ private: auto result = f; if ((flags & TextBlockFPre) || (flags & TextBlockFCode)) { result = style::MonospaceFont(); - if (result->size() != f->size() || result->flags() != f->flags()) { - result = style::font(f->size(), f->flags(), result->family()); + if (result->size() != f->size()) { + result = style::font(f->size(), result->flags(), result->family()); } } else { if (flags & TextBlockFBold) { @@ -2027,9 +2027,13 @@ private: result = style::font(f->size(), f->flags(), result->family()); } } - if (flags & TextBlockFItalic) result = result->italic(); - if (flags & TextBlockFUnderline) result = result->underline(); - if (flags & TextBlockFStrikeOut) result = result->strikeout(); + } + + if (flags & TextBlockFItalic) result = result->italic(); + if (flags & TextBlockFUnderline) result = result->underline(); + if (flags & TextBlockFStrikeOut) result = result->strikeout(); + + if (flags & TextBlockFSemibold) { if (flags & TextBlockFTilde) { // tilde fix in OpenSans result = st::semiboldFont; } diff --git a/ui/text/text_block.cpp b/ui/text/text_block.cpp index ffa378f..da9a3cb 100644 --- a/ui/text/text_block.cpp +++ b/ui/text/text_block.cpp @@ -323,8 +323,8 @@ TextBlock::TextBlock(const style::font &font, const QString &str, QFixed minResi if ((flags & TextBlockFPre) || (flags & TextBlockFCode)) { blockFont = style::MonospaceFont(); - if (blockFont->size() != font->size() || blockFont->flags() != font->flags()) { - blockFont = style::font(font->size(), font->flags(), blockFont->family()); + if (blockFont->size() != font->size()) { + blockFont = style::font(font->size(), blockFont->flags(), blockFont->family()); } } else { if (flags & TextBlockFBold) { @@ -335,9 +335,13 @@ TextBlock::TextBlock(const style::font &font, const QString &str, QFixed minResi blockFont = style::font(font->size(), font->flags(), blockFont->family()); } } - if (flags & TextBlockFItalic) blockFont = blockFont->italic(); - if (flags & TextBlockFUnderline) blockFont = blockFont->underline(); - if (flags & TextBlockFStrikeOut) blockFont = blockFont->strikeout(); + } + + if (flags & TextBlockFItalic) blockFont = blockFont->italic(); + if (flags & TextBlockFUnderline) blockFont = blockFont->underline(); + if (flags & TextBlockFStrikeOut) blockFont = blockFont->strikeout(); + + if (flags & TextBlockFSemibold) { if (flags & TextBlockFTilde) { // tilde fix in OpenSans blockFont = st::semiboldFont; } diff --git a/ui/widgets/input_fields.cpp b/ui/widgets/input_fields.cpp index ded3b52..5ff4e2d 100644 --- a/ui/widgets/input_fields.cpp +++ b/ui/widgets/input_fields.cpp @@ -657,9 +657,8 @@ void RemoveDocumentTags( style::font AdjustFont( const style::font &font, const style::font &original) { - return (font->size() != original->size() - || font->flags() != original->flags()) - ? style::font(original->size(), original->flags(), font->family()) + return (font->size() != original->size()) + ? style::font(original->size(), font->flags(), font->family()) : font; }