Use custom-adjusted font metrics.

This commit is contained in:
John Preston 2024-05-02 11:32:44 +04:00
parent 4ddff63a9b
commit 86dc01e9bc
16 changed files with 362 additions and 202 deletions

View file

@ -23,12 +23,16 @@ public:
void drawTextLeft(int x, int y, int outerw, const QString &text, int textWidth = -1) {
QFontMetrics m(fontMetrics());
if (style::RightToLeft() && textWidth < 0) textWidth = m.horizontalAdvance(text);
drawText(style::RightToLeft() ? (outerw - x - textWidth) : x, y + m.ascent(), text);
const auto result = style::FindAdjustResult(font());
const auto ascent = result ? result->iascent : m.ascent();
drawText(style::RightToLeft() ? (outerw - x - textWidth) : x, y + ascent, text);
}
void drawTextRight(int x, int y, int outerw, const QString &text, int textWidth = -1) {
QFontMetrics m(fontMetrics());
if (!style::RightToLeft() && textWidth < 0) textWidth = m.horizontalAdvance(text);
drawText(style::RightToLeft() ? x : (outerw - x - textWidth), y + m.ascent(), text);
const auto result = style::FindAdjustResult(font());
const auto ascent = result ? result->iascent : m.ascent();
drawText(style::RightToLeft() ? x : (outerw - x - textWidth), y + ascent, text);
}
void drawPixmapLeft(int x, int y, int outerw, const QPixmap &pix, const QRect &from) {
drawPixmap(QPoint(style::RightToLeft() ? (outerw - x - (from.width() / pix.devicePixelRatio())) : x, y), pix, from);

View file

@ -107,13 +107,13 @@ void TitleWidget::init(int height) {
const auto apple = (family == u".AppleSystemUIFont"_q);
setFromFont(style::font(
apple ? 13 : (height * 15) / 24,
apple ? style::internal::FontBold : 0,
apple ? style::FontFlag::Bold : 0,
family));
break;
}
}
if (!_textStyle) {
setFromFont(style::font(13, style::internal::FontSemibold, 0));
setFromFont(style::font(13, style::FontFlag::Semibold, 0));
}
}

View file

@ -29,12 +29,12 @@ auto PaletteVersion = 0;
auto ShortAnimationRunning = rpl::variable<bool>(false);
auto RunningShortAnimations = 0;
std::vector<internal::ModuleBase*> &StyleModules() {
[[nodiscard]] std::vector<internal::ModuleBase*> &StyleModules() {
static auto result = std::vector<internal::ModuleBase*>();
return result;
}
void startModules(int scale) {
void StartModules(int scale) {
for (const auto module : StyleModules()) {
module->start(scale);
}
@ -60,14 +60,14 @@ void StopShortAnimation() {
} // namespace internal
void startManager(int scale) {
internal::registerFontFamily("Open Sans");
internal::startModules(scale);
void StartManager(int scale) {
internal::RegisterFontFamily("Open Sans");
internal::StartModules(scale);
}
void stopManager() {
internal::destroyFonts();
internal::destroyIcons();
void StopManager() {
internal::DestroyFonts();
internal::DestroyIcons();
}
rpl::producer<> PaletteChanged() {

View file

@ -35,8 +35,8 @@ void StopShortAnimation();
} // namespace internal
void startManager(int scale);
void stopManager();
void StartManager(int scale);
void StopManager();
[[nodiscard]] rpl::producer<> PaletteChanged();
[[nodiscard]] int PaletteVersion();

View file

@ -57,27 +57,28 @@ public:
_data->set(r, g, b, a);
}
operator const QBrush &() const {
[[nodiscard]] operator const QBrush &() const {
return _data->b;
}
operator const QPen &() const {
[[nodiscard]] operator const QPen &() const {
return _data->p;
}
ColorData *operator->() const {
[[nodiscard]] ColorData *operator->() const {
return _data;
}
ColorData *v() const {
[[nodiscard]] ColorData *get() const {
return _data;
}
explicit operator bool() const {
[[nodiscard]] explicit operator bool() const {
return !!_data;
}
class Proxy;
Proxy operator[](const style::palette &paletteOverride) const;
[[nodiscard]] Proxy operator[](
const style::palette &paletteOverride) const;
private:
friend class OwnedColor;
@ -164,12 +165,12 @@ public:
}
Proxy(const Proxy &other) = default;
operator const QBrush &() const { return _color; }
operator const QPen &() const { return _color; }
ColorData *operator->() const { return _color.v(); }
ColorData *v() const { return _color.v(); }
explicit operator bool() const { return _color ? true : false; }
Color clone() const { return _color; }
[[nodiscard]] operator const QBrush &() const { return _color; }
[[nodiscard]] operator const QPen &() const { return _color; }
[[nodiscard]] ColorData *operator->() const { return _color.get(); }
[[nodiscard]] ColorData *get() const { return _color.get(); }
[[nodiscard]] explicit operator bool() const { return !!_color; }
[[nodiscard]] Color clone() const { return _color; }
private:
Color _color;

View file

@ -52,6 +52,19 @@ void SetCustomFont(const QString &font) {
}
namespace internal {
struct ResolvedFont {
ResolvedFont(FontResolveResult result, FontVariants *modified);
FontResolveResult result;
FontData data;
};
ResolvedFont::ResolvedFont(FontResolveResult result, FontVariants *modified)
: result(std::move(result))
, data(this->result, modified) {
}
namespace {
#ifndef LIB_UI_USE_PACKAGED_FONTS
@ -69,12 +82,33 @@ const auto PersianFontTypes = std::array{
bool Started = false;
QMap<QString, int> fontFamilyMap;
QVector<QString> fontFamilies;
QMap<uint32, FontData*> fontsMap;
base::flat_map<QString, int> FontFamilyIndices;
std::vector<QString> FontFamilies;
base::flat_map<uint32, std::unique_ptr<ResolvedFont>> FontsByKey;
base::flat_map<uint64, uint32> QtFontsKeys;
uint32 fontKey(int size, uint32 flags, int family) {
return (((uint32(family) << 12) | uint32(size)) << 6) | flags;
[[nodiscard]] uint32 FontKey(int size, FontFlags flags, int family) {
return (uint32(family) << 18)
| (uint32(size) << 6)
| uint32(flags.value());
}
[[nodiscard]] uint64 QtFontKey(const QFont &font) {
static auto Families = base::flat_map<QString, int>();
const auto pixelSize = font.pixelSize();
const auto family = font.family();
auto i = Families.find(family);
if (i == end(Families)) {
i = Families.emplace(family, Families.size()).first;
}
return (uint64(i->second) << 24)
| (uint64(font.weight()) << 16)
| (uint64(font.bold() ? 1 : 0) << 15)
| (uint64(font.italic() ? 1 : 0) << 14)
| (uint64(font.underline() ? 1 : 0) << 13)
| (uint64(font.strikeOut() ? 1 : 0) << 12)
| (uint64(font.pixelSize()));
}
#ifndef LIB_UI_USE_PACKAGED_FONTS
@ -135,106 +169,161 @@ bool LoadCustomFont(const QString &filePath) {
return family;
}
[[nodiscard]] int ComputePixelSize(QFont font, uint32 flags, int size) {
struct Metrics {
int pixelSize = 0;
float64 ascent = 0.;
float64 height = 0.;
};
[[nodiscard]] Metrics ComputeMetrics(QFont font, bool adjust) {
constexpr auto kMaxSizeShift = 8;
const auto startSize = font.pixelSize();
const auto metrics = QFontMetricsF(font);
const auto simple = [&] {
return Metrics{
.pixelSize = startSize,
.ascent = metrics.ascent(),
.height = metrics.height(),
};
};
const auto family = font.family();
const auto basic = u"Open Sans"_q;
if (family == basic) {
return size;
return simple();
}
font.setPixelSize(size);
auto copy = font;
copy.setFamily(basic);
const auto basicMetrics = QFontMetricsF(copy);
//static const auto Test = u"bdfghijklpqtyBDFGHIJKLPQTY1234567890[]{}()"_q;
static const auto Full = u"bdfghijklpqtyBDFGHIJKLPQTY1234567890[]{}()"_q;
static const auto Test = u"acemnorsuvwxz"_q;
const auto desired = basicMetrics.tightBoundingRect(Test).height();
//const auto tightAscent = -tightRect.y();
//const auto tightDescent = tightRect.y() + tightRect.height();
if (desired < 1.) {
return size;
const auto desiredFull = basicMetrics.tightBoundingRect(Full);
if (desired < 1. || desiredFull.height() < desired) {
return simple();
}
const auto currentMetrics = QFontMetricsF(font);
auto current = currentMetrics.tightBoundingRect(Test).height();
//const auto tightAscent = -tightRect.y();
//const auto tightDescent = tightRect.y() + tightRect.height();
const auto adjusted = [&](int size, const QFontMetricsF &metrics) {
const auto full = metrics.tightBoundingRect(Full);
const auto desiredTightAscent = -desiredFull.y();
const auto desiredTightHeight = desiredFull.height();
const auto ascentAdd = basicMetrics.ascent() - desiredTightAscent;
const auto heightAdd = basicMetrics.height() - desiredTightHeight;
const auto tightAscent = -full.y();
const auto tightHeight = full.height();
return Metrics{
.pixelSize = size,
.ascent = tightAscent + ascentAdd,
.height = tightHeight + heightAdd,
};
};
const auto max = std::min(kMaxSizeShift, size - 1);
if (current < 1. || std::abs(current - desired) < 0.2) {
return size;
} else if (current < desired) {
auto current = metrics.tightBoundingRect(Test).height();
if (current < 1.) {
return simple();
} else if (std::abs(current - desired) < 0.2) {
return adjusted(startSize, metrics);
}
const auto adjustedByFont = [&](const QFont &font) {
return adjusted(font.pixelSize(), QFontMetricsF(font));
};
const auto max = std::min(kMaxSizeShift, startSize - 1);
if (current < desired) {
for (auto i = 0; i != max; ++i) {
const auto shift = i + 1;
font.setPixelSize(size + shift);
font.setPixelSize(startSize + shift);
const auto metrics = QFontMetricsF(font);
const auto now = metrics.tightBoundingRect(Test).height();
if (now > desired) {
const auto better = (now - desired) < (desired - current);
return better ? (size + shift) : (size + shift - 1);
if (better) {
return adjusted(startSize + shift, metrics);
}
font.setPixelSize(startSize + shift - 1);
return adjustedByFont(font);
}
current = now;
}
return size + max;
font.setPixelSize(startSize + max);
return adjustedByFont(font);
} else {
for (auto i = 0; i != max; ++i) {
const auto shift = i + 1;
font.setPixelSize(size - shift);
font.setPixelSize(startSize - shift);
const auto metrics = QFontMetricsF(font);
const auto now = metrics.tightBoundingRect(Test).height();
if (now < desired) {
const auto better = (desired - now) < (current - desired);
return better ? (size - shift) : (size - shift + 1);
if (better) {
return adjusted(startSize - shift, metrics);
}
font.setPixelSize(startSize - shift + 1);
return adjustedByFont(font);
}
current = now;
}
return size - max;
font.setPixelSize(startSize - max);
return adjustedByFont(font);
}
}
[[nodiscard]] QFont ResolveFont(
[[nodiscard]] FontResolveResult ResolveFont(
const QString &family,
uint32 flags,
FontFlags flags,
int size,
bool skipSizeAdjustment) {
auto result = QFont();
const auto monospace = (flags & FontMonospace) != 0;
auto font = QFont();
const auto monospace = (flags & FontFlag::Monospace) != 0;
const auto system = !monospace && (family == SystemFontTag());
const auto overriden = !monospace && !system && !family.isEmpty();
if (monospace) {
result.setFamily(MonospaceFont());
font.setFamily(MonospaceFont());
} else if (system) {
} else if (overriden) {
result.setFamily(family);
font.setFamily(family);
} else {
result.setFamily("Open Sans"_q);
font.setFamily("Open Sans"_q);
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
result.setFeature("ss03", true);
font.setFeature("ss03", true);
#endif // Qt >= 6.7.0
}
result.setWeight(((flags & FontBold) || (flags & FontSemibold))
font.setPixelSize(size);
font.setWeight((flags & (FontFlag::Bold | FontFlag::Semibold))
? QFont::DemiBold
: QFont::Normal);
if (result.bold()) {
const auto style = QFontInfo(result).styleName();
if (font.bold()) {
const auto style = QFontInfo(font).styleName();
if (!style.isEmpty() && !style.startsWith(
"Semibold",
Qt::CaseInsensitive)) {
result.setBold(true);
font.setBold(true);
}
}
result.setItalic(flags & FontItalic);
result.setUnderline(flags & FontUnderline);
result.setStrikeOut(flags & FontStrikeOut);
result.setPixelSize((monospace || !overriden || skipSizeAdjustment)
? size
: ComputePixelSize(result, flags, size));
return result;
font.setItalic(flags & FontFlag::Italic);
font.setUnderline(flags & FontFlag::Underline);
font.setStrikeOut(flags & FontFlag::StrikeOut);
const auto adjust = (overriden && !skipSizeAdjustment);
const auto metrics = ComputeMetrics(font, adjust);
font.setPixelSize(metrics.pixelSize);
return {
.font = font,
.ascent = metrics.ascent,
.height = metrics.height,
.iascent = int(base::SafeRound(metrics.ascent)),
.iheight = int(base::SafeRound(metrics.height)),
.requestedFamily = RegisterFontFamily(family),
.requestedSize = size,
.requestedFlags = flags,
};
}
} // namespace
@ -276,74 +365,66 @@ void StartFonts() {
QApplication::setFont(appFont);
}
void destroyFonts() {
for (auto fontData : std::as_const(fontsMap)) {
delete fontData;
}
fontsMap.clear();
void DestroyFonts() {
base::take(FontsByKey);
}
int registerFontFamily(const QString &family) {
auto result = fontFamilyMap.value(family, -1);
if (result < 0) {
result = fontFamilies.size();
fontFamilyMap.insert(family, result);
fontFamilies.push_back(family);
int RegisterFontFamily(const QString &family) {
auto i = FontFamilyIndices.find(family);
if (i == end(FontFamilyIndices)) {
i = FontFamilyIndices.emplace(family, FontFamilies.size()).first;
FontFamilies.push_back(family);
}
return result;
return i->second;
}
FontData::FontData(int size, uint32 flags, int family, Font *other)
: f(ResolveFont(
family ? fontFamilies[family] : Custom,
flags,
size,
family != 0))
FontData::FontData(const FontResolveResult &result, FontVariants *modified)
: f(result.font)
, _m(f)
, _size(size)
, _flags(flags)
, _family(family) {
if (other) {
memcpy(_modified, other, sizeof(_modified));
, _size(result.requestedSize)
, _family(result.requestedFamily)
, _flags(result.requestedFlags) {
if (modified) {
memcpy(&_modified, modified, sizeof(_modified));
}
_modified[_flags] = Font(this);
_modified[int(_flags)] = Font(this);
height = int(base::SafeRound(_m.height()));
ascent = int(base::SafeRound(_m.ascent()));
descent = int(base::SafeRound(_m.descent()));
height = int(base::SafeRound(result.height));
ascent = int(base::SafeRound(result.ascent));
descent = height - ascent;
spacew = width(QLatin1Char(' '));
elidew = width(u"..."_q);
}
Font FontData::bold(bool set) const {
return otherFlagsFont(FontBold, set);
return otherFlagsFont(FontFlag::Bold, set);
}
Font FontData::italic(bool set) const {
return otherFlagsFont(FontItalic, set);
return otherFlagsFont(FontFlag::Italic, set);
}
Font FontData::underline(bool set) const {
return otherFlagsFont(FontUnderline, set);
return otherFlagsFont(FontFlag::Underline, set);
}
Font FontData::strikeout(bool set) const {
return otherFlagsFont(FontStrikeOut, set);
return otherFlagsFont(FontFlag::StrikeOut, set);
}
Font FontData::semibold(bool set) const {
return otherFlagsFont(FontSemibold, set);
return otherFlagsFont(FontFlag::Semibold, set);
}
Font FontData::monospace(bool set) const {
return otherFlagsFont(FontMonospace, set);
return otherFlagsFont(FontFlag::Monospace, set);
}
int FontData::size() const {
return _size;
}
uint32 FontData::flags() const {
FontFlags FontData::flags() const {
return _flags;
}
@ -351,50 +432,61 @@ int FontData::family() const {
return _family;
}
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);
Font FontData::otherFlagsFont(FontFlag flag, bool set) const {
const auto newFlags = set ? (_flags | flag) : (_flags & ~flag);
if (!_modified[newFlags]) {
_modified[newFlags] = Font(_size, newFlags, _family, &_modified);
}
return _modified[newFlags];
}
Font::Font(int size, uint32 flags, const QString &family) {
if (fontFamilyMap.isEmpty()) {
for (uint32 i = 0, s = fontFamilies.size(); i != s; ++i) {
fontFamilyMap.insert(fontFamilies.at(i), i);
}
}
auto i = fontFamilyMap.constFind(family);
if (i == fontFamilyMap.cend()) {
fontFamilies.push_back(family);
i = fontFamilyMap.insert(family, fontFamilies.size() - 1);
}
init(size, flags, i.value(), 0);
Font::Font(int size, FontFlags flags, const QString &family) {
init(size, flags, RegisterFontFamily(family), 0);
}
Font::Font(int size, uint32 flags, int family) {
Font::Font(int size, FontFlags flags, int family) {
init(size, flags, family, 0);
}
Font::Font(int size, uint32 flags, int family, Font *modified) {
Font::Font(int size, FontFlags flags, int family, FontVariants *modified) {
init(size, flags, family, modified);
}
void Font::init(int size, uint32 flags, int family, Font *modified) {
uint32 key = fontKey(size, flags, family);
auto i = fontsMap.constFind(key);
if (i == fontsMap.cend()) {
i = fontsMap.insert(key, new FontData(size, flags, family, modified));
void Font::init(
int size,
FontFlags flags,
int family,
FontVariants *modified) {
const auto key = FontKey(size, flags, family);
auto i = FontsByKey.find(key);
if (i == end(FontsByKey)) {
i = FontsByKey.emplace(
key,
std::make_unique<ResolvedFont>(
ResolveFont(
family ? FontFamilies[family] : Custom,
flags,
size,
family != 0),
modified)).first;
QtFontsKeys.emplace(QtFontKey(i->second->data.f), key);
}
ptr = i.value();
_data = &i->second->data;
}
OwnedFont::OwnedFont(const QString &custom, FontFlags flags, int size)
: _data(ResolveFont(custom, flags, size, false), nullptr) {
_font._data = &_data;
}
} // namespace internal
QFont ResolveFont(const QString &custom, uint32 flags, int size) {
return internal::ResolveFont(custom, flags, size, false);
const FontResolveResult *FindAdjustResult(const QFont &font) {
const auto key = internal::QtFontKey(font);
const auto i = internal::QtFontsKeys.find(key);
return (i != end(internal::QtFontsKeys))
? &internal::FontsByKey[i->second]->result
: nullptr;
}
} // namespace style

View file

@ -7,6 +7,7 @@
#pragma once
#include "base/basic_types.h"
#include "base/flags.h"
#include <QtGui/QFont>
#include <QtGui/QFontMetrics>
@ -18,61 +19,75 @@ namespace style {
[[nodiscard]] const QString &SystemFontTag();
void SetCustomFont(const QString &font);
[[nodiscard]] QFont ResolveFont(
const QString &custom,
uint32 flags,
int size);
enum class FontFlag : uchar {
Bold = 0x01,
Italic = 0x02,
Underline = 0x04,
StrikeOut = 0x08,
Semibold = 0x10,
Monospace = 0x20,
};
inline constexpr bool is_flag_type(FontFlag) { return true; }
using FontFlags = base::flags<FontFlag>;
struct FontResolveResult {
QFont font;
float64 ascent = 0.;
float64 height = 0.;
int iascent = 0;
int iheight = 0;
int requestedFamily = 0;
int requestedSize = 0;
FontFlags requestedFlags;
};
[[nodiscard]] const FontResolveResult *FindAdjustResult(const QFont &font);
namespace internal {
void StartFonts();
void destroyFonts();
int registerFontFamily(const QString &family);
void DestroyFonts();
int RegisterFontFamily(const QString &family);
inline constexpr auto kFontVariants = 0x40;
class Font;
using FontVariants = std::array<Font, kFontVariants>;
class FontData;
class Font {
class Font final {
public:
Font(Qt::Initialization = Qt::Uninitialized) {
}
Font(int size, uint32 flags, const QString &family);
Font(int size, uint32 flags, int family);
Font(int size, FontFlags flags, const QString &family);
Font(int size, FontFlags flags, int family);
FontData *operator->() const {
return ptr;
[[nodiscard]] FontData *operator->() const {
return _data;
}
FontData *v() const {
return ptr;
[[nodiscard]] FontData *get() const {
return _data;
}
operator bool() const {
return !!ptr;
[[nodiscard]] operator bool() const {
return _data != nullptr;
}
operator const QFont &() const;
[[nodiscard]] operator const QFont &() const;
private:
FontData *ptr = nullptr;
void init(int size, uint32 flags, int family, Font *modified);
friend void startManager();
Font(FontData *p) : ptr(p) {
}
Font(int size, uint32 flags, int family, Font *modified);
friend class FontData;
friend class OwnedFont;
};
FontData *_data = nullptr;
enum FontFlags {
FontBold = 0x01,
FontItalic = 0x02,
FontUnderline = 0x04,
FontStrikeOut = 0x08,
FontSemibold = 0x10,
FontMonospace = 0x20,
void init(int size, FontFlags flags, int family, FontVariants *modified);
friend void StartManager();
explicit Font(FontData *data) : _data(data) {
}
Font(int size, FontFlags flags, int family, FontVariants *modified);
FontDifferentFlags = 0x40,
};
class FontData {
@ -100,37 +115,74 @@ public:
[[nodiscard]] Font semibold(bool set = true) const;
[[nodiscard]] Font monospace(bool set = true) const;
int size() const;
uint32 flags() const;
int family() const;
[[nodiscard]] int size() const;
[[nodiscard]] FontFlags flags() const;
[[nodiscard]] int family() const;
QFont f;
int32 height, ascent, descent, spacew, elidew;
int height = 0;
int ascent = 0;
int descent = 0;
int spacew = 0;
int elidew = 0;
private:
mutable Font _modified[FontDifferentFlags];
friend class OwnedFont;
friend struct ResolvedFont;
Font otherFlagsFont(uint32 flag, bool set) const;
FontData(int size, uint32 flags, int family, Font *other);
mutable FontVariants _modified;
[[nodiscard]] Font otherFlagsFont(FontFlag flag, bool set) const;
FontData(const FontResolveResult &data, FontVariants *modified);
friend class Font;
QFontMetricsF _m;
int _size;
uint32 _flags;
int _family;
int _size = 0;
int _family = 0;
FontFlags _flags = 0;
};
inline bool operator==(const Font &a, const Font &b) {
return a.v() == b.v();
return a.get() == b.get();
}
inline bool operator!=(const Font &a, const Font &b) {
return a.v() != b.v();
return a.get() != b.get();
}
inline Font::operator const QFont &() const {
return ptr->f;
Expects(_data != nullptr);
return _data->f;
}
class OwnedFont final {
public:
OwnedFont(const QString &custom, FontFlags flags, int size);
OwnedFont(const OwnedFont &other)
: _data(other._data) {
_font._data = &_data;
}
OwnedFont &operator=(const OwnedFont &other) {
_data = other._data;
return *this;
}
[[nodiscard]] const Font &font() const {
return _font;
}
[[nodiscard]] FontData *operator->() const {
return _font.get();
}
[[nodiscard]] FontData *get() const {
return _font.get();
}
private:
FontData _data;
Font _font;
};
} // namespace internal
} // namespace style

View file

@ -393,14 +393,14 @@ Icon Icon::withPalette(const style::palette &palette) const {
return result;
}
void resetIcons() {
void ResetIcons() {
iconPixmaps.clear();
for (const auto data : iconData) {
data->reset();
}
}
void destroyIcons() {
void DestroyIcons() {
iconData.clear();
iconPixmaps.clear();

View file

@ -295,8 +295,8 @@ private:
};
void resetIcons();
void destroyIcons();
void ResetIcons();
void DestroyIcons();
} // namespace internal
} // namespace style

View file

@ -226,7 +226,7 @@ QByteArray save() {
bool load(const QByteArray &cache) {
if (GetMutable().load(cache)) {
style::internal::resetIcons();
style::internal::ResetIcons();
return true;
}
return false;
@ -242,17 +242,17 @@ palette::SetResult setColor(QLatin1String name, QLatin1String from) {
void apply(const palette &other) {
GetMutable() = other;
style::internal::resetIcons();
style::internal::ResetIcons();
}
void reset() {
GetMutable().reset();
style::internal::resetIcons();
style::internal::ResetIcons();
}
void reset(const colorizer &with) {
GetMutable().reset(with);
style::internal::resetIcons();
style::internal::ResetIcons();
}
int indexOfColor(color c) {

View file

@ -27,6 +27,7 @@ using cursor = Qt::CursorShape;
using align = Qt::Alignment;
using margins = QMargins;
using font = internal::Font;
using owned_font = internal::OwnedFont;
using color = internal::Color;
using owned_color = internal::OwnedColor;
using complex_color = internal::ComplexColor;

View file

@ -373,28 +373,31 @@ bool BlockParser::isSpaceBreak(
style::font WithFlags(
const style::font &font,
TextBlockFlags flags,
uint32 fontFlags) {
style::FontFlags fontFlags) {
using namespace style::internal;
using Flag = style::FontFlag;
if (!flags && !fontFlags) {
return font;
} else if (IsMono(flags) || (fontFlags & FontMonospace)) {
} else if (IsMono(flags) || (fontFlags & Flag::Monospace)) {
return font->monospace();
}
auto result = font;
if ((flags & TextBlockFlag::Bold) || (fontFlags & FontBold)) {
if ((flags & TextBlockFlag::Bold) || (fontFlags & Flag::Bold)) {
result = result->bold();
} else if ((flags & TextBlockFlag::Semibold)
|| (fontFlags & FontSemibold)) {
|| (fontFlags & Flag::Semibold)) {
result = result->semibold();
}
if ((flags & TextBlockFlag::Italic) || (fontFlags & FontItalic)) {
if ((flags & TextBlockFlag::Italic) || (fontFlags & Flag::Italic)) {
result = result->italic();
}
if ((flags & TextBlockFlag::Underline) || (fontFlags & FontUnderline)) {
if ((flags & TextBlockFlag::Underline)
|| (fontFlags & Flag::Underline)) {
result = result->underline();
}
if ((flags & TextBlockFlag::StrikeOut) || (fontFlags & FontStrikeOut)) {
if ((flags & TextBlockFlag::StrikeOut)
|| (fontFlags & Flag::StrikeOut)) {
result = result->strikeout();
}
if (flags & TextBlockFlag::Tilde) { // Tilde fix in OpenSans.

View file

@ -47,7 +47,7 @@ using TextBlockFlags = base::flags<TextBlockFlag>;
[[nodiscard]] style::font WithFlags(
const style::font &font,
TextBlockFlags flags,
uint32 fontFlags = 0);
style::FontFlags fontFlags = 0);
[[nodiscard]] Qt::LayoutDirection UnpackParagraphDirection(
bool ltr,

View file

@ -3912,7 +3912,9 @@ void InputField::refreshPlaceholder(const QString &text) {
_placeholder = metrics.elidedText(text, Qt::ElideRight, availableWidth);
_placeholderPath = QPainterPath();
if (!_placeholder.isEmpty()) {
_placeholderPath.addText(0, QFontMetrics(placeholderFont).ascent(), placeholderFont, _placeholder);
const auto result = style::FindAdjustResult(placeholderFont);
const auto ascent = result ? result->iascent : metrics.ascent();
_placeholderPath.addText(0, ascent, placeholderFont, _placeholder);
}
} else {
_placeholder = _st.placeholderFont->elided(text, availableWidth);

View file

@ -390,7 +390,9 @@ void MaskedInputField::refreshPlaceholder(const QString &text) {
_placeholder = metrics.elidedText(text, Qt::ElideRight, availableWidth);
_placeholderPath = QPainterPath();
if (!_placeholder.isEmpty()) {
_placeholderPath.addText(0, QFontMetrics(placeholderFont).ascent(), placeholderFont, _placeholder);
const auto result = style::FindAdjustResult(placeholderFont);
const auto ascent = result ? result->iascent : metrics.ascent();
_placeholderPath.addText(0, ascent, placeholderFont, _placeholder);
}
} else {
_placeholder = _st.placeholderFont->elided(text, availableWidth);

View file

@ -20,10 +20,13 @@ namespace Ui {
// flick scroll taken from http://qt-project.org/doc/qt-4.8/demos-embedded-anomaly-src-flickcharm-cpp.html
ScrollShadow::ScrollShadow(ScrollArea *parent, const style::ScrollArea *st) : QWidget(parent), _st(st) {
ScrollShadow::ScrollShadow(ScrollArea *parent, const style::ScrollArea *st)
: QWidget(parent)
, _st(st) {
Expects(_st != nullptr);
Expects(_st->shColor.get() != nullptr);
setVisible(false);
Assert(_st != nullptr);
Assert(_st->shColor.v() != nullptr);
}
void ScrollShadow::paintEvent(QPaintEvent *e) {