diff --git a/ui/effects/numbers_animation.cpp b/ui/effects/numbers_animation.cpp index cbe0230..e71b260 100644 --- a/ui/effects/numbers_animation.cpp +++ b/ui/effects/numbers_animation.cpp @@ -20,7 +20,7 @@ NumbersAnimation::NumbersAnimation( , _duration(st::slideWrapDuration) , _animationCallback(std::move(animationCallback)) { for (auto ch = '0'; ch != '9'; ++ch) { - accumulate_max(_digitWidth, _font->m.horizontalAdvance(ch)); + accumulate_max(_digitWidth, _font->width(ch)); } } @@ -76,7 +76,7 @@ void NumbersAnimation::realSetText(QString text, int value) { digit.from = digit.to; digit.fromWidth = digit.toWidth; digit.to = (newSize + i < size) ? QChar(0) : text[newSize + i - size]; - digit.toWidth = digit.to.unicode() ? _font->m.horizontalAdvance(digit.to) : 0; + digit.toWidth = digit.to.unicode() ? _font->width(digit.to) : 0; if (digit.from != digit.to) { animating = true; } @@ -86,7 +86,7 @@ void NumbersAnimation::realSetText(QString text, int value) { } if (_disabledMonospace) { _fromWidth = _toWidth; - _toWidth = _font->m.horizontalAdvance(text); + _toWidth = _font->width(text); } else { _fromWidth = oldSize * _digitWidth; _toWidth = newSize * _digitWidth; @@ -141,10 +141,10 @@ void NumbersAnimation::paint(QPainter &p, int x, int y, int outerWidth) { auto to = digit.to; const auto toCharWidth = (!_disabledMonospace || to.isDigit()) ? _digitWidth - : _font->m.horizontalAdvance(to); + : _font->width(to); const auto fromCharWidth = (!_disabledMonospace || from.isDigit()) ? _digitWidth - : _font->m.horizontalAdvance(from); + : _font->width(from); if (from == to) { p.setOpacity(1.); singleChar[0] = from; diff --git a/ui/style/style_core_font.cpp b/ui/style/style_core_font.cpp index 76f71d8..d87de63 100644 --- a/ui/style/style_core_font.cpp +++ b/ui/style/style_core_font.cpp @@ -17,6 +17,7 @@ #include #include #include +#include void style_InitFontsResource() { #ifdef Q_OS_MAC // Use resources from the .app bundle on macOS. @@ -292,20 +293,26 @@ int registerFontFamily(const QString &family) { return result; } +int CeilTextWidth(const QFont &font, const QString &text) { + return text.isEmpty() + ? 0 + : QStackTextEngine(text, font).width(0, text.size()).ceil().toInt(); +} + FontData::FontData(int size, uint32 flags, int family, Font *other) : f(ResolveFont(flags, size)) -, m(f) +, _m(f) , _size(size) , _flags(flags) , _family(family) { if (other) { - memcpy(modified, other, sizeof(modified)); + memcpy(_modified, other, sizeof(_modified)); } - modified[_flags] = Font(this); + _modified[_flags] = Font(this); - height = m.height(); - ascent = m.ascent(); - descent = m.descent(); + height = int(base::SafeRound(_m.height())); + ascent = int(base::SafeRound(_m.ascent())); + descent = int(base::SafeRound(_m.descent())); spacew = width(QLatin1Char(' ')); elidew = width("..."); } @@ -348,10 +355,10 @@ int FontData::family() const { Font FontData::otherFlagsFont(uint32 flag, bool set) const { int32 newFlags = set ? (_flags | flag) : (_flags & ~flag); - if (!modified[newFlags].v()) { - modified[newFlags] = Font(_size, newFlags, _family, modified); + if (!_modified[newFlags].v()) { + _modified[newFlags] = Font(_size, newFlags, _family, _modified); } - return modified[newFlags]; + return _modified[newFlags]; } Font::Font(int size, uint32 flags, const QString &family) { diff --git a/ui/style/style_core_font.h b/ui/style/style_core_font.h index df98408..e0c85aa 100644 --- a/ui/style/style_core_font.h +++ b/ui/style/style_core_font.h @@ -66,46 +66,48 @@ enum FontFlags { FontDifferentFlags = 0x40, }; +[[nodiscard]] int CeilTextWidth(const QFont &font, const QString &text); + class FontData { public: - int width(const QString &str) const { - return m.horizontalAdvance(str); + [[nodiscard]] int width(const QString &text) const { + return CeilTextWidth(f, text); } - int width(const QString &str, int32 from, int32 to) const { - return width(str.mid(from, to)); + [[nodiscard]] int width(const QString &text, int from, int to) const { + return width(text.mid(from, to)); } - int width(QChar ch) const { - return m.horizontalAdvance(ch); + [[nodiscard]] int width(QChar ch) const { + return int(std::ceil(_m.horizontalAdvance(ch))); } - QString elided( + [[nodiscard]] QString elided( const QString &str, int width, Qt::TextElideMode mode = Qt::ElideRight) const { - return m.elidedText(str, mode, width); + return _m.elidedText(str, mode, width); } - Font bold(bool set = true) const; - 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; + [[nodiscard]] Font bold(bool set = true) const; + [[nodiscard]] Font italic(bool set = true) const; + [[nodiscard]] Font underline(bool set = true) const; + [[nodiscard]] Font strikeout(bool set = true) const; + [[nodiscard]] Font semibold(bool set = true) const; + [[nodiscard]] Font monospace(bool set = true) const; int size() const; uint32 flags() const; int family() const; QFont f; - QFontMetrics m; int32 height, ascent, descent, spacew, elidew; private: - mutable Font modified[FontDifferentFlags]; + mutable Font _modified[FontDifferentFlags]; Font otherFlagsFont(uint32 flag, bool set) const; FontData(int size, uint32 flags, int family, Font *other); friend class Font; + QFontMetricsF _m; int _size; uint32 _flags; int _family; diff --git a/ui/widgets/input_fields.cpp b/ui/widgets/input_fields.cpp index ed7df91..640efdf 100644 --- a/ui/widgets/input_fields.cpp +++ b/ui/widgets/input_fields.cpp @@ -3799,7 +3799,7 @@ void InputField::resizeEvent(QResizeEvent *e) { } void InputField::refreshPlaceholder(const QString &text) { - const auto availableWidth = width() - _st.textMargins.left() - _st.textMargins.right() - _st.placeholderMargins.left() - _st.placeholderMargins.right() - 1; + const auto availableWidth = width() - _st.textMargins.left() - _st.textMargins.right() - _st.placeholderMargins.left() - _st.placeholderMargins.right(); if (_st.placeholderScale > 0.) { auto placeholderFont = _st.placeholderFont->f; placeholderFont.setStyleStrategy(QFont::PreferMatch);