diff --git a/ui/basic.style b/ui/basic.style index 25f086a..9d0a66a 100644 --- a/ui/basic.style +++ b/ui/basic.style @@ -23,8 +23,6 @@ TextStyle { lineHeight: pixels; } -semibold: "Open Sans Semibold"; - fsize: 13px; normalFont: font(fsize); semiboldFont: font(fsize semibold); diff --git a/ui/style/style_core.cpp b/ui/style/style_core.cpp index 18a5bbb..171b390 100644 --- a/ui/style/style_core.cpp +++ b/ui/style/style_core.cpp @@ -12,7 +12,6 @@ #include "styles/palette.h" #include -#include #include #include @@ -28,7 +27,6 @@ constexpr auto kContrastDeltaL = 64; auto PaletteChanges = rpl::event_stream<>(); auto ShortAnimationRunning = rpl::variable(false); auto RunningShortAnimations = 0; -auto ResolvedMonospaceFont = style::font(); std::vector &StyleModules() { static auto result = std::vector(); @@ -41,28 +39,6 @@ void startModules(int scale) { } } -void ResolveMonospaceFont() { - auto family = QString(); - const auto tryFont = [&](const QString &attempt) { - if (family.isEmpty() - && !QFontInfo(QFont(attempt)).family().trimmed().compare( - attempt, - Qt::CaseInsensitive)) { - family = attempt; - } - }; - 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); -} - } // namespace void registerModule(ModuleBase *module) { @@ -86,7 +62,6 @@ void StopShortAnimation() { void startManager(int scale) { internal::registerFontFamily("Open Sans"); internal::startModules(scale); - internal::ResolveMonospaceFont(); } void stopManager() { @@ -106,10 +81,6 @@ rpl::producer ShortAnimationPlaying() { return internal::ShortAnimationRunning.value(); } -const style::font &MonospaceFont() { - return internal::ResolvedMonospaceFont; -} - void colorizeImage(const QImage &src, QColor c, QImage *outResult, QRect srcRect, QPoint dstPoint) { // In background_box ColorizePattern we use the fact that // colorizeImage takes only first byte of the mask, so it diff --git a/ui/style/style_core.h b/ui/style/style_core.h index 62da03c..d996342 100644 --- a/ui/style/style_core.h +++ b/ui/style/style_core.h @@ -43,8 +43,6 @@ void NotifyPaletteChanged(); [[nodiscard]] rpl::producer ShortAnimationPlaying(); -const style::font &MonospaceFont(); - // *outResult must be r.width() x r.height(), ARGB32_Premultiplied. // QRect(0, 0, src.width(), src.height()) must contain r. void colorizeImage(const QImage &src, QColor c, QImage *outResult, QRect srcRect = QRect(), QPoint dstPoint = QPoint(0, 0)); diff --git a/ui/style/style_core_font.cpp b/ui/style/style_core_font.cpp index 318783b..08bb43b 100644 --- a/ui/style/style_core_font.cpp +++ b/ui/style/style_core_font.cpp @@ -14,6 +14,7 @@ #include #include #include +#include void style_InitFontsResource() { #ifndef DESKTOP_APP_USE_PACKAGED_FONTS @@ -37,16 +38,14 @@ 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; } bool ValidateFont(const QString &familyName, int flags = 0) { QFont checkFont(familyName); - checkFont.setPixelSize(13); checkFont.setBold(flags & style::internal::FontBold); checkFont.setItalic(flags & style::internal::FontItalic); checkFont.setUnderline(flags & style::internal::FontUnderline); - checkFont.setStyleStrategy(QFont::PreferQuality); auto realFamily = QFontInfo(checkFont).family(); if (realFamily.trimmed().compare(familyName, Qt::CaseInsensitive)) { UI_LOG(("Font Error: could not resolve '%1' font, got '%2'.").arg(familyName).arg(realFamily)); @@ -86,6 +85,39 @@ bool LoadCustomFont(const QString &filePath, const QString &familyName, int flag return ValidateFont(familyName, flags); } +QString MonospaceFont() { + static const auto family = [&]() -> QString { +#ifdef Q_OS_WIN + const auto tryFont = [&](const QString &attempt) { + return !QFontInfo(QFont(attempt)).family().trimmed().compare( + attempt, + Qt::CaseInsensitive); + }; + + if (tryFont("Consolas")) { + return "Consolas"; + } + + if (tryFont("Liberation Mono")) { + return "Liberation Mono"; + } + + if (tryFont("Menlo")) { + return "Menlo"; + } + + if (tryFont("Courier")) { + return "Courier"; + } +#endif // Q_OS_WIN + + const auto type = QFontDatabase::FixedFont; + return QFontDatabase::systemFont(type).family(); + }(); + + return family; +} + enum { FontTypeRegular = 0, FontTypeRegularItalic, @@ -111,8 +143,8 @@ int32 FontTypeFlags[FontTypesCount] = { FontItalic, FontBold, FontBold | FontItalic, - 0, - FontItalic, + FontSemibold, + FontSemibold | FontItalic, }; #ifdef Q_OS_WIN QString FontTypeWindowsFallback[FontTypesCount] = { @@ -168,7 +200,18 @@ void StartFonts() { //QFont::insertSubstitution(name, fallback); #endif // Q_OS_WIN } -#endif // !DESKTOP_APP_USE_PACKAGED_FONTS + +#ifdef Q_OS_WIN + auto list = QStringList(); + list.append("Microsoft YaHei"); + list.append("Microsoft JhengHei UI"); + list.append("Yu Gothic UI"); + list.append("\xEB\xA7\x91\xEC\x9D\x80 \xEA\xB3\xA0\xEB\x94\x95"); + for (const auto &name : FontTypeNames) { + QFont::insertSubstitutions(name, list); + } +#endif // Q_OS_WIN + #ifdef Q_OS_MAC auto list = QStringList(); list.append("STIXGeneral"); @@ -179,36 +222,44 @@ void StartFonts() { QFont::insertSubstitutions(name, list); } #endif // Q_OS_MAC +#endif // !DESKTOP_APP_USE_PACKAGED_FONTS + + auto appFont = QFont(GetFontOverride()); + appFont.setPixelSize(13); + appFont.setStyleStrategy(QFont::PreferQuality); + QApplication::setFont(appFont); if (integrationExists) { Ui::Integration::Instance().startFontsEnd(); } } -QString GetPossibleEmptyOverride(const QString &familyName, int32 flags) { - flags = flags & (FontBold | FontItalic); - if (familyName == qstr("Open Sans")) { - if (flags == (FontBold | FontItalic)) { - return Overrides[FontTypeBoldItalic]; - } else if (flags == FontBold) { - return Overrides[FontTypeBold]; - } else if (flags == FontItalic) { - return Overrides[FontTypeRegularItalic]; - } else if (flags == 0) { - return Overrides[FontTypeRegular]; - } - } else if (familyName == qstr("Open Sans Semibold")) { - if (flags == FontItalic) { - return Overrides[FontTypeSemiboldItalic]; - } else if (flags == 0) { - return Overrides[FontTypeSemibold]; - } +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(const QString &familyName, int32 flags) { - const auto result = GetPossibleEmptyOverride(familyName, flags); +QString GetFontOverride(int32 flags) { + const auto familyName = (flags & FontSemibold) + ? "Open Sans Semibold" + : "Open Sans"; + + const auto result = GetPossibleEmptyOverride(flags); return result.isEmpty() ? familyName : result; } @@ -230,8 +281,7 @@ int registerFontFamily(const QString &family) { } FontData::FontData(int size, uint32 flags, int family, Font *other) -: f(GetFontOverride(fontFamilies[family], flags)) -, m(f) +: m(f) , _size(size) , _flags(flags) , _family(family) { @@ -242,18 +292,23 @@ FontData::FontData(int size, uint32 flags, int family, Font *other) } modified[_flags] = Font(this); - f.setPixelSize(size); - if (_flags & FontBold) { - f.setBold(true); -#ifdef DESKTOP_APP_USE_PACKAGED_FONTS - } else if (fontFamilies[family] == "Open Sans Semibold") { - f.setWeight(QFont::DemiBold); -#endif + if (_flags & FontMonospace) { + f.setFamily(MonospaceFont()); + } else { + f.setFamily(GetFontOverride(flags)); } + +#ifdef DESKTOP_APP_USE_PACKAGED_FONTS + if (_flags & FontSemibold) { + f.setWeight(QFont::DemiBold); + } +#endif // DESKTOP_APP_USE_PACKAGED_FONTS + + f.setPixelSize(size); + f.setBold(_flags & FontBold); f.setItalic(_flags & FontItalic); f.setUnderline(_flags & FontUnderline); f.setStrikeOut(_flags & FontStrikeOut); - f.setStyleStrategy(QFont::PreferQuality); m = QFontMetrics(f); height = m.height(); @@ -279,6 +334,14 @@ Font FontData::strikeout(bool set) const { return otherFlagsFont(FontStrikeOut, set); } +Font FontData::semibold(bool set) const { + return otherFlagsFont(FontSemibold, 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 31b5962..29e5299 100644 --- a/ui/style/style_core_font.h +++ b/ui/style/style_core_font.h @@ -15,7 +15,7 @@ namespace style { namespace internal { void StartFonts(); -[[nodiscard]] QString GetFontOverride(const QString &familyName, int32 flags = 0); +[[nodiscard]] QString GetFontOverride(int32 flags = 0); void destroyFonts(); int registerFontFamily(const QString &family); @@ -59,8 +59,10 @@ enum FontFlags { FontItalic = 0x02, FontUnderline = 0x04, FontStrikeOut = 0x08, + FontSemibold = 0x10, + FontMonospace = 0x20, - FontDifferentFlags = 0x10, + FontDifferentFlags = 0x40, }; class FontData { @@ -83,6 +85,8 @@ public: Font italic(bool set = true) const; Font underline(bool set = true) const; Font strikeout(bool set = true) const; + Font semibold(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 a48abae..b4c61cd 100644 --- a/ui/text/text.cpp +++ b/ui/text/text.cpp @@ -2014,24 +2014,18 @@ 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()); - } + result = result->monospace(); } else { if (flags & TextBlockFBold) { result = result->bold(); } else if (flags & TextBlockFSemibold) { - result = st::semiboldFont; - if (result->size() != f->size() || result->flags() != f->flags()) { - result = style::font(f->size(), f->flags(), result->family()); - } + result = result->semibold(); } if (flags & TextBlockFItalic) result = result->italic(); if (flags & TextBlockFUnderline) result = result->underline(); if (flags & TextBlockFStrikeOut) result = result->strikeout(); if (flags & TextBlockFTilde) { // tilde fix in OpenSans - result = st::semiboldFont; + result = result->semibold(); } } return result; diff --git a/ui/text/text_block.cpp b/ui/text/text_block.cpp index ffa378f..c2a3f11 100644 --- a/ui/text/text_block.cpp +++ b/ui/text/text_block.cpp @@ -322,24 +322,18 @@ 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()); - } + blockFont = blockFont->monospace(); } else { if (flags & TextBlockFBold) { blockFont = blockFont->bold(); } else if (flags & TextBlockFSemibold) { - blockFont = st::semiboldFont; - if (blockFont->size() != font->size() || blockFont->flags() != font->flags()) { - blockFont = style::font(font->size(), font->flags(), blockFont->family()); - } + blockFont = blockFont->semibold(); } if (flags & TextBlockFItalic) blockFont = blockFont->italic(); if (flags & TextBlockFUnderline) blockFont = blockFont->underline(); if (flags & TextBlockFStrikeOut) blockFont = blockFont->strikeout(); if (flags & TextBlockFTilde) { // tilde fix in OpenSans - blockFont = st::semiboldFont; + blockFont = blockFont->semibold(); } } diff --git a/ui/widgets/input_fields.cpp b/ui/widgets/input_fields.cpp index db17e0c..e37a125 100644 --- a/ui/widgets/input_fields.cpp +++ b/ui/widgets/input_fields.cpp @@ -651,15 +651,6 @@ void RemoveDocumentTags( cursor.mergeCharFormat(format); } -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()) - : font; -} - bool IsValidMarkdownLink(const QString &link) { return (link.indexOf('.') >= 0) || (link.indexOf(':') >= 0); } @@ -672,16 +663,8 @@ QTextCharFormat PrepareTagFormat( result.setForeground(st::defaultTextPalette.linkFg); result.setFont(st.font); } else if (tag == kTagBold) { - auto semibold = st::semiboldFont; - if (semibold->size() != st.font->size() - || semibold->flags() != st.font->flags()) { - semibold = style::font( - st.font->size(), - st.font->flags(), - semibold->family()); - } result.setForeground(st.textFg); - result.setFont(AdjustFont(st::semiboldFont, st.font)); + result.setFont(st.font->semibold()); } else if (tag == kTagItalic) { result.setForeground(st.textFg); result.setFont(st.font->italic()); @@ -693,7 +676,7 @@ QTextCharFormat PrepareTagFormat( result.setFont(st.font->strikeout()); } else if (tag == kTagCode || tag == kTagPre) { result.setForeground(st::defaultTextPalette.monoFg); - result.setFont(AdjustFont(style::MonospaceFont(), st.font)); + result.setFont(st.font->monospace()); } else { result.setForeground(st.textFg); result.setFont(st.font); @@ -1985,7 +1968,7 @@ void InputField::processFormatting(int insertPosition, int insertEnd) { const auto tildeFormatting = (_st.font->f.pixelSize() * style::DevicePixelRatio() == 13) && (_st.font->f.family() == qstr("DAOpenSansRegular")); auto isTildeFragment = false; - const auto tildeFixedFont = AdjustFont(st::semiboldFont, _st.font); + const auto tildeFixedFont = _st.font->semibold(); // First tag handling (the one we inserted text to). bool startTagFound = false;