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)
, _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;

View file

@ -17,6 +17,7 @@
#include <QtGui/QFontInfo>
#include <QtGui/QFontDatabase>
#include <QtWidgets/QApplication>
#include <private/qfontengine_p.h>
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) {

View file

@ -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;

View file

@ -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);