Use custom-adjusted font metrics.
This commit is contained in:
parent
4ddff63a9b
commit
86dc01e9bc
16 changed files with 362 additions and 202 deletions
|
|
@ -23,12 +23,16 @@ public:
|
||||||
void drawTextLeft(int x, int y, int outerw, const QString &text, int textWidth = -1) {
|
void drawTextLeft(int x, int y, int outerw, const QString &text, int textWidth = -1) {
|
||||||
QFontMetrics m(fontMetrics());
|
QFontMetrics m(fontMetrics());
|
||||||
if (style::RightToLeft() && textWidth < 0) textWidth = m.horizontalAdvance(text);
|
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) {
|
void drawTextRight(int x, int y, int outerw, const QString &text, int textWidth = -1) {
|
||||||
QFontMetrics m(fontMetrics());
|
QFontMetrics m(fontMetrics());
|
||||||
if (!style::RightToLeft() && textWidth < 0) textWidth = m.horizontalAdvance(text);
|
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) {
|
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);
|
drawPixmap(QPoint(style::RightToLeft() ? (outerw - x - (from.width() / pix.devicePixelRatio())) : x, y), pix, from);
|
||||||
|
|
|
||||||
|
|
@ -107,13 +107,13 @@ void TitleWidget::init(int height) {
|
||||||
const auto apple = (family == u".AppleSystemUIFont"_q);
|
const auto apple = (family == u".AppleSystemUIFont"_q);
|
||||||
setFromFont(style::font(
|
setFromFont(style::font(
|
||||||
apple ? 13 : (height * 15) / 24,
|
apple ? 13 : (height * 15) / 24,
|
||||||
apple ? style::internal::FontBold : 0,
|
apple ? style::FontFlag::Bold : 0,
|
||||||
family));
|
family));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!_textStyle) {
|
if (!_textStyle) {
|
||||||
setFromFont(style::font(13, style::internal::FontSemibold, 0));
|
setFromFont(style::font(13, style::FontFlag::Semibold, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,12 +29,12 @@ auto PaletteVersion = 0;
|
||||||
auto ShortAnimationRunning = rpl::variable<bool>(false);
|
auto ShortAnimationRunning = rpl::variable<bool>(false);
|
||||||
auto RunningShortAnimations = 0;
|
auto RunningShortAnimations = 0;
|
||||||
|
|
||||||
std::vector<internal::ModuleBase*> &StyleModules() {
|
[[nodiscard]] std::vector<internal::ModuleBase*> &StyleModules() {
|
||||||
static auto result = std::vector<internal::ModuleBase*>();
|
static auto result = std::vector<internal::ModuleBase*>();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void startModules(int scale) {
|
void StartModules(int scale) {
|
||||||
for (const auto module : StyleModules()) {
|
for (const auto module : StyleModules()) {
|
||||||
module->start(scale);
|
module->start(scale);
|
||||||
}
|
}
|
||||||
|
|
@ -60,14 +60,14 @@ void StopShortAnimation() {
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
void startManager(int scale) {
|
void StartManager(int scale) {
|
||||||
internal::registerFontFamily("Open Sans");
|
internal::RegisterFontFamily("Open Sans");
|
||||||
internal::startModules(scale);
|
internal::StartModules(scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
void stopManager() {
|
void StopManager() {
|
||||||
internal::destroyFonts();
|
internal::DestroyFonts();
|
||||||
internal::destroyIcons();
|
internal::DestroyIcons();
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<> PaletteChanged() {
|
rpl::producer<> PaletteChanged() {
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,8 @@ void StopShortAnimation();
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
void startManager(int scale);
|
void StartManager(int scale);
|
||||||
void stopManager();
|
void StopManager();
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<> PaletteChanged();
|
[[nodiscard]] rpl::producer<> PaletteChanged();
|
||||||
[[nodiscard]] int PaletteVersion();
|
[[nodiscard]] int PaletteVersion();
|
||||||
|
|
|
||||||
|
|
@ -57,27 +57,28 @@ public:
|
||||||
_data->set(r, g, b, a);
|
_data->set(r, g, b, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
operator const QBrush &() const {
|
[[nodiscard]] operator const QBrush &() const {
|
||||||
return _data->b;
|
return _data->b;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator const QPen &() const {
|
[[nodiscard]] operator const QPen &() const {
|
||||||
return _data->p;
|
return _data->p;
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorData *operator->() const {
|
[[nodiscard]] ColorData *operator->() const {
|
||||||
return _data;
|
return _data;
|
||||||
}
|
}
|
||||||
ColorData *v() const {
|
[[nodiscard]] ColorData *get() const {
|
||||||
return _data;
|
return _data;
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit operator bool() const {
|
[[nodiscard]] explicit operator bool() const {
|
||||||
return !!_data;
|
return !!_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Proxy;
|
class Proxy;
|
||||||
Proxy operator[](const style::palette &paletteOverride) const;
|
[[nodiscard]] Proxy operator[](
|
||||||
|
const style::palette &paletteOverride) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class OwnedColor;
|
friend class OwnedColor;
|
||||||
|
|
@ -164,12 +165,12 @@ public:
|
||||||
}
|
}
|
||||||
Proxy(const Proxy &other) = default;
|
Proxy(const Proxy &other) = default;
|
||||||
|
|
||||||
operator const QBrush &() const { return _color; }
|
[[nodiscard]] operator const QBrush &() const { return _color; }
|
||||||
operator const QPen &() const { return _color; }
|
[[nodiscard]] operator const QPen &() const { return _color; }
|
||||||
ColorData *operator->() const { return _color.v(); }
|
[[nodiscard]] ColorData *operator->() const { return _color.get(); }
|
||||||
ColorData *v() const { return _color.v(); }
|
[[nodiscard]] ColorData *get() const { return _color.get(); }
|
||||||
explicit operator bool() const { return _color ? true : false; }
|
[[nodiscard]] explicit operator bool() const { return !!_color; }
|
||||||
Color clone() const { return _color; }
|
[[nodiscard]] Color clone() const { return _color; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Color _color;
|
Color _color;
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,19 @@ void SetCustomFont(const QString &font) {
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace internal {
|
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 {
|
namespace {
|
||||||
|
|
||||||
#ifndef LIB_UI_USE_PACKAGED_FONTS
|
#ifndef LIB_UI_USE_PACKAGED_FONTS
|
||||||
|
|
@ -69,12 +82,33 @@ const auto PersianFontTypes = std::array{
|
||||||
|
|
||||||
bool Started = false;
|
bool Started = false;
|
||||||
|
|
||||||
QMap<QString, int> fontFamilyMap;
|
base::flat_map<QString, int> FontFamilyIndices;
|
||||||
QVector<QString> fontFamilies;
|
std::vector<QString> FontFamilies;
|
||||||
QMap<uint32, FontData*> fontsMap;
|
base::flat_map<uint32, std::unique_ptr<ResolvedFont>> FontsByKey;
|
||||||
|
base::flat_map<uint64, uint32> QtFontsKeys;
|
||||||
|
|
||||||
uint32 fontKey(int size, uint32 flags, int family) {
|
[[nodiscard]] uint32 FontKey(int size, FontFlags flags, int family) {
|
||||||
return (((uint32(family) << 12) | uint32(size)) << 6) | flags;
|
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
|
#ifndef LIB_UI_USE_PACKAGED_FONTS
|
||||||
|
|
@ -135,106 +169,161 @@ bool LoadCustomFont(const QString &filePath) {
|
||||||
return family;
|
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;
|
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 family = font.family();
|
||||||
const auto basic = u"Open Sans"_q;
|
const auto basic = u"Open Sans"_q;
|
||||||
if (family == basic) {
|
if (family == basic) {
|
||||||
return size;
|
return simple();
|
||||||
}
|
}
|
||||||
font.setPixelSize(size);
|
|
||||||
|
|
||||||
auto copy = font;
|
auto copy = font;
|
||||||
copy.setFamily(basic);
|
copy.setFamily(basic);
|
||||||
const auto basicMetrics = QFontMetricsF(copy);
|
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;
|
static const auto Test = u"acemnorsuvwxz"_q;
|
||||||
|
|
||||||
const auto desired = basicMetrics.tightBoundingRect(Test).height();
|
const auto desired = basicMetrics.tightBoundingRect(Test).height();
|
||||||
//const auto tightAscent = -tightRect.y();
|
const auto desiredFull = basicMetrics.tightBoundingRect(Full);
|
||||||
//const auto tightDescent = tightRect.y() + tightRect.height();
|
if (desired < 1. || desiredFull.height() < desired) {
|
||||||
|
return simple();
|
||||||
if (desired < 1.) {
|
|
||||||
return size;
|
|
||||||
}
|
}
|
||||||
const auto currentMetrics = QFontMetricsF(font);
|
|
||||||
|
|
||||||
auto current = currentMetrics.tightBoundingRect(Test).height();
|
const auto adjusted = [&](int size, const QFontMetricsF &metrics) {
|
||||||
//const auto tightAscent = -tightRect.y();
|
const auto full = metrics.tightBoundingRect(Full);
|
||||||
//const auto tightDescent = tightRect.y() + tightRect.height();
|
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);
|
auto current = metrics.tightBoundingRect(Test).height();
|
||||||
if (current < 1. || std::abs(current - desired) < 0.2) {
|
if (current < 1.) {
|
||||||
return size;
|
return simple();
|
||||||
} else if (current < desired) {
|
} 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) {
|
for (auto i = 0; i != max; ++i) {
|
||||||
const auto shift = i + 1;
|
const auto shift = i + 1;
|
||||||
font.setPixelSize(size + shift);
|
font.setPixelSize(startSize + shift);
|
||||||
const auto metrics = QFontMetricsF(font);
|
const auto metrics = QFontMetricsF(font);
|
||||||
const auto now = metrics.tightBoundingRect(Test).height();
|
const auto now = metrics.tightBoundingRect(Test).height();
|
||||||
if (now > desired) {
|
if (now > desired) {
|
||||||
const auto better = (now - desired) < (desired - current);
|
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;
|
current = now;
|
||||||
}
|
}
|
||||||
return size + max;
|
font.setPixelSize(startSize + max);
|
||||||
|
return adjustedByFont(font);
|
||||||
} else {
|
} else {
|
||||||
for (auto i = 0; i != max; ++i) {
|
for (auto i = 0; i != max; ++i) {
|
||||||
const auto shift = i + 1;
|
const auto shift = i + 1;
|
||||||
font.setPixelSize(size - shift);
|
font.setPixelSize(startSize - shift);
|
||||||
const auto metrics = QFontMetricsF(font);
|
const auto metrics = QFontMetricsF(font);
|
||||||
const auto now = metrics.tightBoundingRect(Test).height();
|
const auto now = metrics.tightBoundingRect(Test).height();
|
||||||
if (now < desired) {
|
if (now < desired) {
|
||||||
const auto better = (desired - now) < (current - 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;
|
current = now;
|
||||||
}
|
}
|
||||||
return size - max;
|
font.setPixelSize(startSize - max);
|
||||||
|
return adjustedByFont(font);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] QFont ResolveFont(
|
[[nodiscard]] FontResolveResult ResolveFont(
|
||||||
const QString &family,
|
const QString &family,
|
||||||
uint32 flags,
|
FontFlags flags,
|
||||||
int size,
|
int size,
|
||||||
bool skipSizeAdjustment) {
|
bool skipSizeAdjustment) {
|
||||||
auto result = QFont();
|
auto font = QFont();
|
||||||
const auto monospace = (flags & FontMonospace) != 0;
|
|
||||||
|
const auto monospace = (flags & FontFlag::Monospace) != 0;
|
||||||
const auto system = !monospace && (family == SystemFontTag());
|
const auto system = !monospace && (family == SystemFontTag());
|
||||||
const auto overriden = !monospace && !system && !family.isEmpty();
|
const auto overriden = !monospace && !system && !family.isEmpty();
|
||||||
if (monospace) {
|
if (monospace) {
|
||||||
result.setFamily(MonospaceFont());
|
font.setFamily(MonospaceFont());
|
||||||
} else if (system) {
|
} else if (system) {
|
||||||
} else if (overriden) {
|
} else if (overriden) {
|
||||||
result.setFamily(family);
|
font.setFamily(family);
|
||||||
} else {
|
} else {
|
||||||
result.setFamily("Open Sans"_q);
|
font.setFamily("Open Sans"_q);
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
|
||||||
result.setFeature("ss03", true);
|
font.setFeature("ss03", true);
|
||||||
#endif // Qt >= 6.7.0
|
#endif // Qt >= 6.7.0
|
||||||
}
|
}
|
||||||
result.setWeight(((flags & FontBold) || (flags & FontSemibold))
|
font.setPixelSize(size);
|
||||||
|
|
||||||
|
font.setWeight((flags & (FontFlag::Bold | FontFlag::Semibold))
|
||||||
? QFont::DemiBold
|
? QFont::DemiBold
|
||||||
: QFont::Normal);
|
: QFont::Normal);
|
||||||
if (result.bold()) {
|
if (font.bold()) {
|
||||||
const auto style = QFontInfo(result).styleName();
|
const auto style = QFontInfo(font).styleName();
|
||||||
if (!style.isEmpty() && !style.startsWith(
|
if (!style.isEmpty() && !style.startsWith(
|
||||||
"Semibold",
|
"Semibold",
|
||||||
Qt::CaseInsensitive)) {
|
Qt::CaseInsensitive)) {
|
||||||
result.setBold(true);
|
font.setBold(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.setItalic(flags & FontItalic);
|
|
||||||
result.setUnderline(flags & FontUnderline);
|
font.setItalic(flags & FontFlag::Italic);
|
||||||
result.setStrikeOut(flags & FontStrikeOut);
|
font.setUnderline(flags & FontFlag::Underline);
|
||||||
result.setPixelSize((monospace || !overriden || skipSizeAdjustment)
|
font.setStrikeOut(flags & FontFlag::StrikeOut);
|
||||||
? size
|
|
||||||
: ComputePixelSize(result, flags, size));
|
const auto adjust = (overriden && !skipSizeAdjustment);
|
||||||
return result;
|
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
|
} // namespace
|
||||||
|
|
@ -276,74 +365,66 @@ void StartFonts() {
|
||||||
QApplication::setFont(appFont);
|
QApplication::setFont(appFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroyFonts() {
|
void DestroyFonts() {
|
||||||
for (auto fontData : std::as_const(fontsMap)) {
|
base::take(FontsByKey);
|
||||||
delete fontData;
|
|
||||||
}
|
|
||||||
fontsMap.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int registerFontFamily(const QString &family) {
|
int RegisterFontFamily(const QString &family) {
|
||||||
auto result = fontFamilyMap.value(family, -1);
|
auto i = FontFamilyIndices.find(family);
|
||||||
if (result < 0) {
|
if (i == end(FontFamilyIndices)) {
|
||||||
result = fontFamilies.size();
|
i = FontFamilyIndices.emplace(family, FontFamilies.size()).first;
|
||||||
fontFamilyMap.insert(family, result);
|
FontFamilies.push_back(family);
|
||||||
fontFamilies.push_back(family);
|
|
||||||
}
|
}
|
||||||
return result;
|
return i->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
FontData::FontData(int size, uint32 flags, int family, Font *other)
|
FontData::FontData(const FontResolveResult &result, FontVariants *modified)
|
||||||
: f(ResolveFont(
|
: f(result.font)
|
||||||
family ? fontFamilies[family] : Custom,
|
|
||||||
flags,
|
|
||||||
size,
|
|
||||||
family != 0))
|
|
||||||
, _m(f)
|
, _m(f)
|
||||||
, _size(size)
|
, _size(result.requestedSize)
|
||||||
, _flags(flags)
|
, _family(result.requestedFamily)
|
||||||
, _family(family) {
|
, _flags(result.requestedFlags) {
|
||||||
if (other) {
|
if (modified) {
|
||||||
memcpy(_modified, other, sizeof(_modified));
|
memcpy(&_modified, modified, sizeof(_modified));
|
||||||
}
|
}
|
||||||
_modified[_flags] = Font(this);
|
_modified[int(_flags)] = Font(this);
|
||||||
|
|
||||||
height = int(base::SafeRound(_m.height()));
|
height = int(base::SafeRound(result.height));
|
||||||
ascent = int(base::SafeRound(_m.ascent()));
|
ascent = int(base::SafeRound(result.ascent));
|
||||||
descent = int(base::SafeRound(_m.descent()));
|
descent = height - ascent;
|
||||||
spacew = width(QLatin1Char(' '));
|
spacew = width(QLatin1Char(' '));
|
||||||
elidew = width(u"..."_q);
|
elidew = width(u"..."_q);
|
||||||
}
|
}
|
||||||
|
|
||||||
Font FontData::bold(bool set) const {
|
Font FontData::bold(bool set) const {
|
||||||
return otherFlagsFont(FontBold, set);
|
return otherFlagsFont(FontFlag::Bold, set);
|
||||||
}
|
}
|
||||||
|
|
||||||
Font FontData::italic(bool set) const {
|
Font FontData::italic(bool set) const {
|
||||||
return otherFlagsFont(FontItalic, set);
|
return otherFlagsFont(FontFlag::Italic, set);
|
||||||
}
|
}
|
||||||
|
|
||||||
Font FontData::underline(bool set) const {
|
Font FontData::underline(bool set) const {
|
||||||
return otherFlagsFont(FontUnderline, set);
|
return otherFlagsFont(FontFlag::Underline, set);
|
||||||
}
|
}
|
||||||
|
|
||||||
Font FontData::strikeout(bool set) const {
|
Font FontData::strikeout(bool set) const {
|
||||||
return otherFlagsFont(FontStrikeOut, set);
|
return otherFlagsFont(FontFlag::StrikeOut, set);
|
||||||
}
|
}
|
||||||
|
|
||||||
Font FontData::semibold(bool set) const {
|
Font FontData::semibold(bool set) const {
|
||||||
return otherFlagsFont(FontSemibold, set);
|
return otherFlagsFont(FontFlag::Semibold, set);
|
||||||
}
|
}
|
||||||
|
|
||||||
Font FontData::monospace(bool set) const {
|
Font FontData::monospace(bool set) const {
|
||||||
return otherFlagsFont(FontMonospace, set);
|
return otherFlagsFont(FontFlag::Monospace, set);
|
||||||
}
|
}
|
||||||
|
|
||||||
int FontData::size() const {
|
int FontData::size() const {
|
||||||
return _size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 FontData::flags() const {
|
FontFlags FontData::flags() const {
|
||||||
return _flags;
|
return _flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -351,50 +432,61 @@ int FontData::family() const {
|
||||||
return _family;
|
return _family;
|
||||||
}
|
}
|
||||||
|
|
||||||
Font FontData::otherFlagsFont(uint32 flag, bool set) const {
|
Font FontData::otherFlagsFont(FontFlag flag, bool set) const {
|
||||||
int32 newFlags = set ? (_flags | flag) : (_flags & ~flag);
|
const auto newFlags = set ? (_flags | flag) : (_flags & ~flag);
|
||||||
if (!_modified[newFlags].v()) {
|
if (!_modified[newFlags]) {
|
||||||
_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, FontFlags flags, const QString &family) {
|
||||||
if (fontFamilyMap.isEmpty()) {
|
init(size, flags, RegisterFontFamily(family), 0);
|
||||||
for (uint32 i = 0, s = fontFamilies.size(); i != s; ++i) {
|
|
||||||
fontFamilyMap.insert(fontFamilies.at(i), i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto i = fontFamilyMap.constFind(family);
|
Font::Font(int size, FontFlags flags, int 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, uint32 flags, int family) {
|
|
||||||
init(size, flags, family, 0);
|
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);
|
init(size, flags, family, modified);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Font::init(int size, uint32 flags, int family, Font *modified) {
|
void Font::init(
|
||||||
uint32 key = fontKey(size, flags, family);
|
int size,
|
||||||
auto i = fontsMap.constFind(key);
|
FontFlags flags,
|
||||||
if (i == fontsMap.cend()) {
|
int family,
|
||||||
i = fontsMap.insert(key, new FontData(size, flags, family, modified));
|
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
|
} // namespace internal
|
||||||
|
|
||||||
QFont ResolveFont(const QString &custom, uint32 flags, int size) {
|
const FontResolveResult *FindAdjustResult(const QFont &font) {
|
||||||
return internal::ResolveFont(custom, flags, size, false);
|
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
|
} // namespace style
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "base/basic_types.h"
|
#include "base/basic_types.h"
|
||||||
|
#include "base/flags.h"
|
||||||
|
|
||||||
#include <QtGui/QFont>
|
#include <QtGui/QFont>
|
||||||
#include <QtGui/QFontMetrics>
|
#include <QtGui/QFontMetrics>
|
||||||
|
|
@ -18,61 +19,75 @@ namespace style {
|
||||||
[[nodiscard]] const QString &SystemFontTag();
|
[[nodiscard]] const QString &SystemFontTag();
|
||||||
void SetCustomFont(const QString &font);
|
void SetCustomFont(const QString &font);
|
||||||
|
|
||||||
[[nodiscard]] QFont ResolveFont(
|
enum class FontFlag : uchar {
|
||||||
const QString &custom,
|
Bold = 0x01,
|
||||||
uint32 flags,
|
Italic = 0x02,
|
||||||
int size);
|
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 {
|
namespace internal {
|
||||||
|
|
||||||
void StartFonts();
|
void StartFonts();
|
||||||
|
|
||||||
void destroyFonts();
|
void DestroyFonts();
|
||||||
int registerFontFamily(const QString &family);
|
int RegisterFontFamily(const QString &family);
|
||||||
|
|
||||||
|
inline constexpr auto kFontVariants = 0x40;
|
||||||
|
|
||||||
|
class Font;
|
||||||
|
using FontVariants = std::array<Font, kFontVariants>;
|
||||||
|
|
||||||
class FontData;
|
class FontData;
|
||||||
class Font {
|
class Font final {
|
||||||
public:
|
public:
|
||||||
Font(Qt::Initialization = Qt::Uninitialized) {
|
Font(Qt::Initialization = Qt::Uninitialized) {
|
||||||
}
|
}
|
||||||
Font(int size, uint32 flags, const QString &family);
|
Font(int size, FontFlags flags, const QString &family);
|
||||||
Font(int size, uint32 flags, int family);
|
Font(int size, FontFlags flags, int family);
|
||||||
|
|
||||||
FontData *operator->() const {
|
[[nodiscard]] FontData *operator->() const {
|
||||||
return ptr;
|
return _data;
|
||||||
}
|
}
|
||||||
FontData *v() const {
|
[[nodiscard]] FontData *get() const {
|
||||||
return ptr;
|
return _data;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator bool() const {
|
[[nodiscard]] operator bool() const {
|
||||||
return !!ptr;
|
return _data != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator const QFont &() const;
|
[[nodiscard]] operator const QFont &() const;
|
||||||
|
|
||||||
private:
|
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 FontData;
|
||||||
|
friend class OwnedFont;
|
||||||
|
|
||||||
};
|
FontData *_data = nullptr;
|
||||||
|
|
||||||
enum FontFlags {
|
void init(int size, FontFlags flags, int family, FontVariants *modified);
|
||||||
FontBold = 0x01,
|
friend void StartManager();
|
||||||
FontItalic = 0x02,
|
|
||||||
FontUnderline = 0x04,
|
explicit Font(FontData *data) : _data(data) {
|
||||||
FontStrikeOut = 0x08,
|
}
|
||||||
FontSemibold = 0x10,
|
Font(int size, FontFlags flags, int family, FontVariants *modified);
|
||||||
FontMonospace = 0x20,
|
|
||||||
|
|
||||||
FontDifferentFlags = 0x40,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FontData {
|
class FontData {
|
||||||
|
|
@ -100,37 +115,74 @@ public:
|
||||||
[[nodiscard]] Font semibold(bool set = true) const;
|
[[nodiscard]] Font semibold(bool set = true) const;
|
||||||
[[nodiscard]] Font monospace(bool set = true) const;
|
[[nodiscard]] Font monospace(bool set = true) const;
|
||||||
|
|
||||||
int size() const;
|
[[nodiscard]] int size() const;
|
||||||
uint32 flags() const;
|
[[nodiscard]] FontFlags flags() const;
|
||||||
int family() const;
|
[[nodiscard]] int family() const;
|
||||||
|
|
||||||
QFont f;
|
QFont f;
|
||||||
int32 height, ascent, descent, spacew, elidew;
|
int height = 0;
|
||||||
|
int ascent = 0;
|
||||||
|
int descent = 0;
|
||||||
|
int spacew = 0;
|
||||||
|
int elidew = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable Font _modified[FontDifferentFlags];
|
friend class OwnedFont;
|
||||||
|
friend struct ResolvedFont;
|
||||||
|
|
||||||
Font otherFlagsFont(uint32 flag, bool set) const;
|
mutable FontVariants _modified;
|
||||||
FontData(int size, uint32 flags, int family, Font *other);
|
|
||||||
|
[[nodiscard]] Font otherFlagsFont(FontFlag flag, bool set) const;
|
||||||
|
FontData(const FontResolveResult &data, FontVariants *modified);
|
||||||
|
|
||||||
friend class Font;
|
|
||||||
QFontMetricsF _m;
|
QFontMetricsF _m;
|
||||||
int _size;
|
int _size = 0;
|
||||||
uint32 _flags;
|
int _family = 0;
|
||||||
int _family;
|
FontFlags _flags = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool operator==(const Font &a, const Font &b) {
|
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) {
|
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 {
|
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 internal
|
||||||
} // namespace style
|
} // namespace style
|
||||||
|
|
|
||||||
|
|
@ -393,14 +393,14 @@ Icon Icon::withPalette(const style::palette &palette) const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetIcons() {
|
void ResetIcons() {
|
||||||
iconPixmaps.clear();
|
iconPixmaps.clear();
|
||||||
for (const auto data : iconData) {
|
for (const auto data : iconData) {
|
||||||
data->reset();
|
data->reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroyIcons() {
|
void DestroyIcons() {
|
||||||
iconData.clear();
|
iconData.clear();
|
||||||
iconPixmaps.clear();
|
iconPixmaps.clear();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -295,8 +295,8 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void resetIcons();
|
void ResetIcons();
|
||||||
void destroyIcons();
|
void DestroyIcons();
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace style
|
} // namespace style
|
||||||
|
|
|
||||||
|
|
@ -226,7 +226,7 @@ QByteArray save() {
|
||||||
|
|
||||||
bool load(const QByteArray &cache) {
|
bool load(const QByteArray &cache) {
|
||||||
if (GetMutable().load(cache)) {
|
if (GetMutable().load(cache)) {
|
||||||
style::internal::resetIcons();
|
style::internal::ResetIcons();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -242,17 +242,17 @@ palette::SetResult setColor(QLatin1String name, QLatin1String from) {
|
||||||
|
|
||||||
void apply(const palette &other) {
|
void apply(const palette &other) {
|
||||||
GetMutable() = other;
|
GetMutable() = other;
|
||||||
style::internal::resetIcons();
|
style::internal::ResetIcons();
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
GetMutable().reset();
|
GetMutable().reset();
|
||||||
style::internal::resetIcons();
|
style::internal::ResetIcons();
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset(const colorizer &with) {
|
void reset(const colorizer &with) {
|
||||||
GetMutable().reset(with);
|
GetMutable().reset(with);
|
||||||
style::internal::resetIcons();
|
style::internal::ResetIcons();
|
||||||
}
|
}
|
||||||
|
|
||||||
int indexOfColor(color c) {
|
int indexOfColor(color c) {
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ using cursor = Qt::CursorShape;
|
||||||
using align = Qt::Alignment;
|
using align = Qt::Alignment;
|
||||||
using margins = QMargins;
|
using margins = QMargins;
|
||||||
using font = internal::Font;
|
using font = internal::Font;
|
||||||
|
using owned_font = internal::OwnedFont;
|
||||||
using color = internal::Color;
|
using color = internal::Color;
|
||||||
using owned_color = internal::OwnedColor;
|
using owned_color = internal::OwnedColor;
|
||||||
using complex_color = internal::ComplexColor;
|
using complex_color = internal::ComplexColor;
|
||||||
|
|
|
||||||
|
|
@ -373,28 +373,31 @@ bool BlockParser::isSpaceBreak(
|
||||||
style::font WithFlags(
|
style::font WithFlags(
|
||||||
const style::font &font,
|
const style::font &font,
|
||||||
TextBlockFlags flags,
|
TextBlockFlags flags,
|
||||||
uint32 fontFlags) {
|
style::FontFlags fontFlags) {
|
||||||
using namespace style::internal;
|
using namespace style::internal;
|
||||||
|
|
||||||
|
using Flag = style::FontFlag;
|
||||||
if (!flags && !fontFlags) {
|
if (!flags && !fontFlags) {
|
||||||
return font;
|
return font;
|
||||||
} else if (IsMono(flags) || (fontFlags & FontMonospace)) {
|
} else if (IsMono(flags) || (fontFlags & Flag::Monospace)) {
|
||||||
return font->monospace();
|
return font->monospace();
|
||||||
}
|
}
|
||||||
auto result = font;
|
auto result = font;
|
||||||
if ((flags & TextBlockFlag::Bold) || (fontFlags & FontBold)) {
|
if ((flags & TextBlockFlag::Bold) || (fontFlags & Flag::Bold)) {
|
||||||
result = result->bold();
|
result = result->bold();
|
||||||
} else if ((flags & TextBlockFlag::Semibold)
|
} else if ((flags & TextBlockFlag::Semibold)
|
||||||
|| (fontFlags & FontSemibold)) {
|
|| (fontFlags & Flag::Semibold)) {
|
||||||
result = result->semibold();
|
result = result->semibold();
|
||||||
}
|
}
|
||||||
if ((flags & TextBlockFlag::Italic) || (fontFlags & FontItalic)) {
|
if ((flags & TextBlockFlag::Italic) || (fontFlags & Flag::Italic)) {
|
||||||
result = result->italic();
|
result = result->italic();
|
||||||
}
|
}
|
||||||
if ((flags & TextBlockFlag::Underline) || (fontFlags & FontUnderline)) {
|
if ((flags & TextBlockFlag::Underline)
|
||||||
|
|| (fontFlags & Flag::Underline)) {
|
||||||
result = result->underline();
|
result = result->underline();
|
||||||
}
|
}
|
||||||
if ((flags & TextBlockFlag::StrikeOut) || (fontFlags & FontStrikeOut)) {
|
if ((flags & TextBlockFlag::StrikeOut)
|
||||||
|
|| (fontFlags & Flag::StrikeOut)) {
|
||||||
result = result->strikeout();
|
result = result->strikeout();
|
||||||
}
|
}
|
||||||
if (flags & TextBlockFlag::Tilde) { // Tilde fix in OpenSans.
|
if (flags & TextBlockFlag::Tilde) { // Tilde fix in OpenSans.
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ using TextBlockFlags = base::flags<TextBlockFlag>;
|
||||||
[[nodiscard]] style::font WithFlags(
|
[[nodiscard]] style::font WithFlags(
|
||||||
const style::font &font,
|
const style::font &font,
|
||||||
TextBlockFlags flags,
|
TextBlockFlags flags,
|
||||||
uint32 fontFlags = 0);
|
style::FontFlags fontFlags = 0);
|
||||||
|
|
||||||
[[nodiscard]] Qt::LayoutDirection UnpackParagraphDirection(
|
[[nodiscard]] Qt::LayoutDirection UnpackParagraphDirection(
|
||||||
bool ltr,
|
bool ltr,
|
||||||
|
|
|
||||||
|
|
@ -3912,7 +3912,9 @@ void InputField::refreshPlaceholder(const QString &text) {
|
||||||
_placeholder = metrics.elidedText(text, Qt::ElideRight, availableWidth);
|
_placeholder = metrics.elidedText(text, Qt::ElideRight, availableWidth);
|
||||||
_placeholderPath = QPainterPath();
|
_placeholderPath = QPainterPath();
|
||||||
if (!_placeholder.isEmpty()) {
|
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 {
|
} else {
|
||||||
_placeholder = _st.placeholderFont->elided(text, availableWidth);
|
_placeholder = _st.placeholderFont->elided(text, availableWidth);
|
||||||
|
|
|
||||||
|
|
@ -390,7 +390,9 @@ void MaskedInputField::refreshPlaceholder(const QString &text) {
|
||||||
_placeholder = metrics.elidedText(text, Qt::ElideRight, availableWidth);
|
_placeholder = metrics.elidedText(text, Qt::ElideRight, availableWidth);
|
||||||
_placeholderPath = QPainterPath();
|
_placeholderPath = QPainterPath();
|
||||||
if (!_placeholder.isEmpty()) {
|
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 {
|
} else {
|
||||||
_placeholder = _st.placeholderFont->elided(text, availableWidth);
|
_placeholder = _st.placeholderFont->elided(text, availableWidth);
|
||||||
|
|
|
||||||
|
|
@ -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
|
// 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);
|
setVisible(false);
|
||||||
Assert(_st != nullptr);
|
|
||||||
Assert(_st->shColor.v() != nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScrollShadow::paintEvent(QPaintEvent *e) {
|
void ScrollShadow::paintEvent(QPaintEvent *e) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue