Use QFontMetricsF and ceil() the width() results.

This commit is contained in:
John Preston 2023-01-24 12:10:48 +04:00
parent 9cb928b7c4
commit 41ee2fb0f0
4 changed files with 40 additions and 31 deletions

View file

@ -20,7 +20,7 @@ NumbersAnimation::NumbersAnimation(
, _duration(st::slideWrapDuration) , _duration(st::slideWrapDuration)
, _animationCallback(std::move(animationCallback)) { , _animationCallback(std::move(animationCallback)) {
for (auto ch = '0'; ch != '9'; ++ch) { 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.from = digit.to;
digit.fromWidth = digit.toWidth; digit.fromWidth = digit.toWidth;
digit.to = (newSize + i < size) ? QChar(0) : text[newSize + i - size]; 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) { if (digit.from != digit.to) {
animating = true; animating = true;
} }
@ -86,7 +86,7 @@ void NumbersAnimation::realSetText(QString text, int value) {
} }
if (_disabledMonospace) { if (_disabledMonospace) {
_fromWidth = _toWidth; _fromWidth = _toWidth;
_toWidth = _font->m.horizontalAdvance(text); _toWidth = _font->width(text);
} else { } else {
_fromWidth = oldSize * _digitWidth; _fromWidth = oldSize * _digitWidth;
_toWidth = newSize * _digitWidth; _toWidth = newSize * _digitWidth;
@ -141,10 +141,10 @@ void NumbersAnimation::paint(QPainter &p, int x, int y, int outerWidth) {
auto to = digit.to; auto to = digit.to;
const auto toCharWidth = (!_disabledMonospace || to.isDigit()) const auto toCharWidth = (!_disabledMonospace || to.isDigit())
? _digitWidth ? _digitWidth
: _font->m.horizontalAdvance(to); : _font->width(to);
const auto fromCharWidth = (!_disabledMonospace || from.isDigit()) const auto fromCharWidth = (!_disabledMonospace || from.isDigit())
? _digitWidth ? _digitWidth
: _font->m.horizontalAdvance(from); : _font->width(from);
if (from == to) { if (from == to) {
p.setOpacity(1.); p.setOpacity(1.);
singleChar[0] = from; singleChar[0] = from;

View file

@ -17,6 +17,7 @@
#include <QtGui/QFontInfo> #include <QtGui/QFontInfo>
#include <QtGui/QFontDatabase> #include <QtGui/QFontDatabase>
#include <QtWidgets/QApplication> #include <QtWidgets/QApplication>
#include <private/qfontengine_p.h>
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.
@ -292,20 +293,26 @@ int registerFontFamily(const QString &family) {
return result; 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) FontData::FontData(int size, uint32 flags, int family, Font *other)
: f(ResolveFont(flags, size)) : f(ResolveFont(flags, size))
, m(f) , _m(f)
, _size(size) , _size(size)
, _flags(flags) , _flags(flags)
, _family(family) { , _family(family) {
if (other) { if (other) {
memcpy(modified, other, sizeof(modified)); memcpy(_modified, other, sizeof(_modified));
} }
modified[_flags] = Font(this); _modified[_flags] = Font(this);
height = m.height(); height = int(base::SafeRound(_m.height()));
ascent = m.ascent(); ascent = int(base::SafeRound(_m.ascent()));
descent = m.descent(); descent = int(base::SafeRound(_m.descent()));
spacew = width(QLatin1Char(' ')); spacew = width(QLatin1Char(' '));
elidew = width("..."); elidew = width("...");
} }
@ -348,10 +355,10 @@ int FontData::family() const {
Font FontData::otherFlagsFont(uint32 flag, bool set) const { Font FontData::otherFlagsFont(uint32 flag, bool set) const {
int32 newFlags = set ? (_flags | flag) : (_flags & ~flag); int32 newFlags = set ? (_flags | flag) : (_flags & ~flag);
if (!modified[newFlags].v()) { if (!_modified[newFlags].v()) {
modified[newFlags] = Font(_size, newFlags, _family, modified); _modified[newFlags] = Font(_size, newFlags, _family, _modified);
} }
return modified[newFlags]; return _modified[newFlags];
} }
Font::Font(int size, uint32 flags, const QString &family) { Font::Font(int size, uint32 flags, const QString &family) {

View file

@ -66,46 +66,48 @@ enum FontFlags {
FontDifferentFlags = 0x40, FontDifferentFlags = 0x40,
}; };
[[nodiscard]] int CeilTextWidth(const QFont &font, const QString &text);
class FontData { class FontData {
public: public:
int width(const QString &str) const { [[nodiscard]] int width(const QString &text) const {
return m.horizontalAdvance(str); return CeilTextWidth(f, text);
} }
int width(const QString &str, int32 from, int32 to) const { [[nodiscard]] int width(const QString &text, int from, int to) const {
return width(str.mid(from, to)); return width(text.mid(from, to));
} }
int width(QChar ch) const { [[nodiscard]] int width(QChar ch) const {
return m.horizontalAdvance(ch); return int(std::ceil(_m.horizontalAdvance(ch)));
} }
QString elided( [[nodiscard]] QString elided(
const QString &str, const QString &str,
int width, int width,
Qt::TextElideMode mode = Qt::ElideRight) const { Qt::TextElideMode mode = Qt::ElideRight) const {
return m.elidedText(str, mode, width); return _m.elidedText(str, mode, width);
} }
Font bold(bool set = true) const; [[nodiscard]] Font bold(bool set = true) const;
Font italic(bool set = true) const; [[nodiscard]] Font italic(bool set = true) const;
Font underline(bool set = true) const; [[nodiscard]] Font underline(bool set = true) const;
Font strikeout(bool set = true) const; [[nodiscard]] Font strikeout(bool set = true) const;
Font semibold(bool set = true) const; [[nodiscard]] Font semibold(bool set = true) const;
Font monospace(bool set = true) const; [[nodiscard]] Font monospace(bool set = true) const;
int size() const; int size() const;
uint32 flags() const; uint32 flags() const;
int family() const; int family() const;
QFont f; QFont f;
QFontMetrics m;
int32 height, ascent, descent, spacew, elidew; int32 height, ascent, descent, spacew, elidew;
private: private:
mutable Font modified[FontDifferentFlags]; mutable Font _modified[FontDifferentFlags];
Font otherFlagsFont(uint32 flag, bool set) const; Font otherFlagsFont(uint32 flag, bool set) const;
FontData(int size, uint32 flags, int family, Font *other); FontData(int size, uint32 flags, int family, Font *other);
friend class Font; friend class Font;
QFontMetricsF _m;
int _size; int _size;
uint32 _flags; uint32 _flags;
int _family; int _family;

View file

@ -3799,7 +3799,7 @@ void InputField::resizeEvent(QResizeEvent *e) {
} }
void InputField::refreshPlaceholder(const QString &text) { 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.) { if (_st.placeholderScale > 0.) {
auto placeholderFont = _st.placeholderFont->f; auto placeholderFont = _st.placeholderFont->f;
placeholderFont.setStyleStrategy(QFont::PreferMatch); placeholderFont.setStyleStrategy(QFont::PreferMatch);