From 95ec0633ed4c40f23e49457b1889590e7a569e14 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 2 May 2024 11:33:47 +0400 Subject: [PATCH] Use custom-adjusted font metrics for custom fonts. Fixes #27814. --- Telegram/SourceFiles/core/application.cpp | 4 +- .../media/player/media_player_button.cpp | 5 +- .../media/player/media_player_button.h | 2 + .../media/stories/media_stories_sibling.cpp | 2 +- .../SourceFiles/ui/boxes/choose_font_box.cpp | 158 +++++++----------- Telegram/SourceFiles/ui/chat/chat_style.cpp | 2 +- Telegram/SourceFiles/ui/countryinput.cpp | 48 ------ Telegram/SourceFiles/ui/countryinput.h | 1 - Telegram/codegen | 2 +- Telegram/lib_ui | 2 +- 10 files changed, 77 insertions(+), 149 deletions(-) diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp index 0e67e7179d..5557eb5030 100644 --- a/Telegram/SourceFiles/core/application.cpp +++ b/Telegram/SourceFiles/core/application.cpp @@ -241,7 +241,7 @@ Application::~Application() { _mediaControlsManager = nullptr; Media::Player::finish(_audio.get()); - style::stopManager(); + style::StopManager(); Instance = nullptr; } @@ -278,7 +278,7 @@ void Application::run() { _translator = std::make_unique(); QCoreApplication::instance()->installTranslator(_translator.get()); - style::startManager(cScale()); + style::StartManager(cScale()); Ui::InitTextOptions(); Ui::StartCachedCorners(); Ui::Emoji::Init(); diff --git a/Telegram/SourceFiles/media/player/media_player_button.cpp b/Telegram/SourceFiles/media/player/media_player_button.cpp index 79691a4e7b..0e9ab424a4 100644 --- a/Telegram/SourceFiles/media/player/media_player_button.cpp +++ b/Telegram/SourceFiles/media/player/media_player_button.cpp @@ -269,6 +269,9 @@ SpeedButtonLayout::SpeedButtonLayout( , _text(SpeedText(speed)) , _textWidth(_metrics.horizontalAdvance(_text)) , _callback(std::move(callback)) { + const auto result = style::FindAdjustResult(_st.font->f); + _adjustedAscent = result ? result->ascent : _metrics.ascent(); + _adjustedHeight = result ? result->height : _metrics.height(); } void SpeedButtonLayout::setSpeed(float64 speed) { @@ -292,7 +295,7 @@ void SpeedButtonLayout::paint(QPainter &p, bool over, bool active) { p.drawText( QPointF(inner.topLeft()) + QPointF( (inner.width() - _textWidth) / 2., - (inner.height() - _metrics.height()) / 2. + _metrics.ascent()), + (inner.height() - _adjustedHeight) / 2. + _adjustedAscent), _text); } diff --git a/Telegram/SourceFiles/media/player/media_player_button.h b/Telegram/SourceFiles/media/player/media_player_button.h index ae2b9563d8..750b533eb6 100644 --- a/Telegram/SourceFiles/media/player/media_player_button.h +++ b/Telegram/SourceFiles/media/player/media_player_button.h @@ -69,6 +69,8 @@ private: float64 _speed = 1.; QFontMetricsF _metrics; + float64 _adjustedAscent = 0.; + float64 _adjustedHeight = 0.; QString _text; float64 _textWidth = 0; diff --git a/Telegram/SourceFiles/media/stories/media_stories_sibling.cpp b/Telegram/SourceFiles/media/stories/media_stories_sibling.cpp index e57825ea15..7426398512 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_sibling.cpp +++ b/Telegram/SourceFiles/media/stories/media_stories_sibling.cpp @@ -349,7 +349,7 @@ QImage Sibling::nameImage(const SiblingLayout &layout) { const auto family = 0; // Default font family. const auto font = style::font( _nameFontSize, - style::internal::FontSemibold, + style::FontFlag::Semibold, family); _name.reset(); _nameStyle = std::make_unique(style::TextStyle{ diff --git a/Telegram/SourceFiles/ui/boxes/choose_font_box.cpp b/Telegram/SourceFiles/ui/boxes/choose_font_box.cpp index a5e8fb2032..512e8a6915 100644 --- a/Telegram/SourceFiles/ui/boxes/choose_font_box.cpp +++ b/Telegram/SourceFiles/ui/boxes/choose_font_box.cpp @@ -53,10 +53,10 @@ public: private: void layout(); - void paintBubble(QPainter &p); - void paintContent(QPainter &p); - void paintReply(QPainter &p); - void paintMessage(QPainter &p); + void paintBubble(Painter &p); + void paintContent(Painter &p); + void paintReply(Painter &p); + void paintMessage(Painter &p); void validateBubbleCache(); @@ -64,18 +64,16 @@ private: const style::owned_color _msgBg; const style::owned_color _msgShadow; - QFont _nameFont; - QFontMetricsF _nameMetrics; - int _nameFontHeight = 0; - QFont _textFont; - QFontMetricsF _textMetrics; - int _textFontHeight = 0; + style::owned_font _nameFontOwned; + style::font _nameFont; + style::TextStyle _nameStyle; + style::owned_font _textFontOwned; + style::font _textFont; + style::TextStyle _textStyle; - QString _nameText; - QString _replyText; - QString _messageText; - - int _boundingLimit = 0; + Ui::Text::String _nameText; + Ui::Text::String _replyText; + Ui::Text::String _messageText; QRect _replyRect; QRect _name; @@ -316,18 +314,18 @@ void Selector::validateCache(Entry &row) { } row.paletteVersion = version; row.cache.fill(Qt::transparent); - auto font = style::ResolveFont(row.id, 0, st::boxFontSize); + auto owned = style::owned_font(row.id, 0, st::boxFontSize); + const auto font = owned.font(); auto p = QPainter(&row.cache); p.setFont(font); p.setPen(st::windowFg); const auto textw = width() - _st.padding.left() - _st.padding.right(); - const auto metrics = QFontMetrics(font); - const auto textt = (_rowHeight - metrics.height()) / 2.; + const auto textt = (_rowHeight - font->height) / 2.; p.drawText( _st.padding.left(), - int(base::SafeRound(textt)) + metrics.ascent(), - metrics.elidedText(row.text, Qt::ElideRight, textw)); + textt + font->ascent, + font->elided(row.text, textw)); } bool Selector::searching() const { @@ -576,15 +574,15 @@ PreviewPainter::PreviewPainter(const QImage &bg, PreviewRequest request) : _request(request) , _msgBg(_request.msgBg) , _msgShadow(_request.msgShadow) -, _nameFont(style::ResolveFont( - _request.family, - style::internal::FontSemibold, - st::fsize)) -, _nameMetrics(_nameFont) -, _nameFontHeight(base::SafeRound(_nameMetrics.height())) -, _textFont(style::ResolveFont(_request.family, 0, st::fsize)) -, _textMetrics(_textFont) -, _textFontHeight(base::SafeRound(_textMetrics.height())) { +, _nameFontOwned(_request.family, style::FontFlag::Semibold, st::fsize) +, _nameFont(_nameFontOwned.font()) +, _nameStyle(st::semiboldTextStyle) +, _textFontOwned(_request.family, 0, st::fsize) +, _textFont(_textFontOwned.font()) +, _textStyle(st::defaultTextStyle) { + _nameStyle.font = _nameFont; + _textStyle.font = _textFont; + layout(); const auto ratio = style::DevicePixelRatio(); @@ -593,14 +591,14 @@ PreviewPainter::PreviewPainter(const QImage &bg, PreviewRequest request) QImage::Format_ARGB32_Premultiplied); _result.setDevicePixelRatio(ratio); - auto p = QPainter(&_result); + auto p = Painter(&_result); p.drawImage(0, 0, bg); p.translate(_bubble.topLeft()); paintBubble(p); } -void PreviewPainter::paintBubble(QPainter &p) { +void PreviewPainter::paintBubble(Painter &p) { validateBubbleCache(); const auto bubble = QRect(QPoint(), _bubble.size()); const auto cornerShadow = _bubbleShadowBottomRight.size() @@ -636,7 +634,7 @@ void PreviewPainter::validateBubbleCache() { = Ui::PrepareCornerPixmaps(radius, _msgShadow.color()).p[3]; } -void PreviewPainter::paintContent(QPainter &p) { +void PreviewPainter::paintContent(Painter &p) { paintReply(p); p.translate(_message.topLeft()); @@ -645,7 +643,7 @@ void PreviewPainter::paintContent(QPainter &p) { paintMessage(p); } -void PreviewPainter::paintReply(QPainter &p) { +void PreviewPainter::paintReply(Painter &p) { { auto hq = PainterHighQualityEnabler(p); p.setPen(Qt::NoPen); @@ -672,26 +670,25 @@ void PreviewPainter::paintReply(QPainter &p) { p.setClipping(false); p.setPen(_request.replyNameFg); - p.setFont(_nameFont); - const auto name = _nameMetrics.elidedText( - _nameText, - Qt::ElideRight, - _name.width()); - p.drawText(_name.x(), _name.y() + _nameMetrics.ascent(), name); + _nameText.drawLeftElided( + p, + _name.x(), + _name.y(), + _name.width(), + _outer.width()); p.setPen(_request.textFg); - p.setFont(_textFont); - const auto reply = _textMetrics.elidedText( - _replyText, - Qt::ElideRight, - _reply.width()); - p.drawText(_reply.x(), _reply.y() + _textMetrics.ascent(), reply); + _replyText.drawLeftElided( + p, + _reply.x(), + _reply.y(), + _reply.width(), + _outer.width()); } -void PreviewPainter::paintMessage(QPainter &p) { +void PreviewPainter::paintMessage(Painter &p) { p.setPen(_request.textFg); - p.setFont(_textFont); - p.drawText(QRect(0, 0, _message.width(), _boundingLimit), _messageText); + _messageText.drawLeft(p, 0, 0, _message.width(), _message.width()); } QImage PreviewPainter::takeResult() { @@ -705,79 +702,54 @@ void PreviewPainter::layout() { - 2 * skip - st::msgPadding.left() - st::msgPadding.right(); - _boundingLimit = 100 * maxTextWidth; - const auto textSize = [&]( - const QFontMetricsF &metrics, - const QString &text, - int availableWidth, - bool oneline = false) { - const auto result = metrics.boundingRect( - QRect(0, 0, availableWidth, _boundingLimit), - (Qt::AlignLeft - | Qt::AlignTop - | (oneline ? Qt::TextSingleLine : Qt::TextWordWrap)), - text); - return QSize( - int(std::ceil(result.x() + result.width())), - int(std::ceil(result.y() + result.height()))); - }; - const auto naturalSize = [&]( - const QFontMetricsF &metrics, - const QString &text, - bool oneline = false) { - return textSize(metrics, text, _boundingLimit, oneline); - }; - - _nameText = tr::lng_settings_chat_message_reply_from(tr::now); - _replyText = tr::lng_background_text2(tr::now); - _messageText = tr::lng_background_text1(tr::now); - - const auto nameSize = naturalSize(_nameMetrics, _nameText, true); - const auto nameMaxWidth = nameSize.width(); - const auto replySize = naturalSize(_textMetrics, _replyText, true); - const auto replyMaxWidth = replySize.width(); - const auto messageSize = naturalSize(_textMetrics, _messageText); - const auto messageMaxWidth = messageSize.width(); + _nameText = Ui::Text::String( + _nameStyle, + tr::lng_settings_chat_message_reply_from(tr::now)); + _replyText = Ui::Text::String( + _textStyle, + tr::lng_background_text2(tr::now)); + _messageText = Ui::Text::String( + _textStyle, + tr::lng_background_text1(tr::now), + kDefaultTextOptions, + st::msgMinWidth / 2); const auto namePosition = QPoint( st::historyReplyPadding.left(), st::historyReplyPadding.top()); const auto replyPosition = QPoint( st::historyReplyPadding.left(), - (st::historyReplyPadding.top() + _nameFontHeight)); + (st::historyReplyPadding.top() + _nameFont->height)); const auto paddingRight = st::historyReplyPadding.right(); const auto wantedWidth = std::max({ - namePosition.x() + nameMaxWidth + paddingRight, - replyPosition.x() + replyMaxWidth + paddingRight, - messageMaxWidth + namePosition.x() + _nameText.maxWidth() + paddingRight, + replyPosition.x() + _replyText.maxWidth() + paddingRight, + _messageText.maxWidth() }); const auto messageWidth = std::clamp( wantedWidth, minTextWidth, maxTextWidth); - const auto messageHeight = textSize( - _textMetrics, - _messageText, - maxTextWidth).height(); + const auto messageHeight = _messageText.countHeight(messageWidth); _replyRect = QRect( st::msgReplyBarPos.x(), st::historyReplyTop, messageWidth, (st::historyReplyPadding.top() - + _nameFontHeight - + _textFontHeight + + _nameFont->height + + _textFont->height + st::historyReplyPadding.bottom())); _name = QRect( _replyRect.topLeft() + namePosition, - QSize(messageWidth - namePosition.x(), _nameFontHeight)); + QSize(messageWidth - namePosition.x(), _nameFont->height)); _reply = QRect( _replyRect.topLeft() + replyPosition, - QSize(messageWidth - replyPosition.x(), _textFontHeight)); + QSize(messageWidth - replyPosition.x(), _textFont->height)); _message = QRect(0, 0, messageWidth, messageHeight); const auto replySkip = _replyRect.y() diff --git a/Telegram/SourceFiles/ui/chat/chat_style.cpp b/Telegram/SourceFiles/ui/chat/chat_style.cpp index a532a31805..56f236481f 100644 --- a/Telegram/SourceFiles/ui/chat/chat_style.cpp +++ b/Telegram/SourceFiles/ui/chat/chat_style.cpp @@ -649,7 +649,7 @@ void ChatStyle::clearColorIndexCaches() { void ChatStyle::assignPalette(not_null palette) { *static_cast(this) = *palette; - style::internal::resetIcons(); + style::internal::ResetIcons(); clearColorIndexCaches(); for (auto &style : _messageStyles) { diff --git a/Telegram/SourceFiles/ui/countryinput.cpp b/Telegram/SourceFiles/ui/countryinput.cpp index 0021591009..a9c9e1add1 100644 --- a/Telegram/SourceFiles/ui/countryinput.cpp +++ b/Telegram/SourceFiles/ui/countryinput.cpp @@ -29,18 +29,6 @@ CountryInput::CountryInput( , _st(st) , _text(tr::lng_country_code(tr::now)) { resize(_st.width, _st.heightMin); - - auto placeholderFont = _st.placeholderFont->f; - placeholderFont.setStyleStrategy(QFont::PreferMatch); - //auto metrics = QFontMetrics(placeholderFont); - auto placeholder = QString();// metrics.elidedText(tr::lng_country_fake_ph(tr::now), Qt::ElideRight, availableWidth); - if (!placeholder.isNull()) { - _placeholderPath.addText( - 0, - QFontMetrics(placeholderFont).ascent(), - placeholderFont, - placeholder); - } } void CountryInput::paintEvent(QPaintEvent *e) { @@ -70,42 +58,6 @@ void CountryInput::paintEvent(QPaintEvent *e) { p.setFont(_st.font); p.setPen(_st.textFg); p.drawText(rect().marginsRemoved(_st.textMargins), _text, _st.textAlign); - if (!_placeholderPath.isEmpty()) { - auto placeholderShiftDegree = 1.; - p.save(); - p.setClipRect(r); - - const auto placeholderTop = anim::interpolate( - 0, - _st.placeholderShift, - placeholderShiftDegree); - - auto r = QRect(rect() - (_st.textMargins + _st.placeholderMargins)); - r.moveTop(r.top() + placeholderTop); - if (rtl()) { - r.moveLeft(width() - r.left() - r.width()); - } - - const auto placeholderScale = 1. - - (1. - _st.placeholderScale) * placeholderShiftDegree; - auto placeholderFg = anim::color( - _st.placeholderFg, - _st.placeholderFgActive, - 0.); - placeholderFg = anim::color( - placeholderFg, - _st.placeholderFgError, - 0.); - - PainterHighQualityEnabler hq(p); - p.setPen(Qt::NoPen); - p.setBrush(placeholderFg); - p.translate(r.topLeft()); - p.scale(placeholderScale, placeholderScale); - p.drawPath(_placeholderPath); - - p.restore(); - } } void CountryInput::mouseMoveEvent(QMouseEvent *e) { diff --git a/Telegram/SourceFiles/ui/countryinput.h b/Telegram/SourceFiles/ui/countryinput.h index 7bf3f97966..3ce0f04c6c 100644 --- a/Telegram/SourceFiles/ui/countryinput.h +++ b/Telegram/SourceFiles/ui/countryinput.h @@ -53,7 +53,6 @@ private: bool _active = false; QString _text; QString _chosenIso; - QPainterPath _placeholderPath; rpl::event_stream _codeChanged; diff --git a/Telegram/codegen b/Telegram/codegen index afed06a4c0..6462cda46e 160000 --- a/Telegram/codegen +++ b/Telegram/codegen @@ -1 +1 @@ -Subproject commit afed06a4c04d1a1cf7cfce4faca273e1f574462e +Subproject commit 6462cda46ec5d48a9ae452ba1b6f7dfe1b6d882d diff --git a/Telegram/lib_ui b/Telegram/lib_ui index 4ddff63a9b..86dc01e9bc 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 4ddff63a9b6cd2e2787995611f1ee4b145bdb504 +Subproject commit 86dc01e9bc61db48d33ff253d29bfedd74309278