Merge remote-tracking branch 'tdesktop/master' into v2.1.10
This commit is contained in:
commit
5534b37e6f
5 changed files with 205 additions and 104 deletions
|
|
@ -90,6 +90,8 @@ PRIVATE
|
|||
ui/style/style_core.h
|
||||
ui/style/style_core_color.cpp
|
||||
ui/style/style_core_color.h
|
||||
ui/style/style_core_custom_font.cpp
|
||||
ui/style/style_core_custom_font.h
|
||||
ui/style/style_core_direction.cpp
|
||||
ui/style/style_core_direction.h
|
||||
ui/style/style_core_font.cpp
|
||||
|
|
|
|||
93
ui/style/style_core_custom_font.cpp
Normal file
93
ui/style/style_core_custom_font.cpp
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
// This file is part of Desktop App Toolkit,
|
||||
// a set of libraries for developing nice desktop applications.
|
||||
//
|
||||
// For license and copyright information please follow this link:
|
||||
// https://github.com/desktop-app/legal/blob/master/LEGAL
|
||||
//
|
||||
#include "ui/style/style_core_custom_font.h"
|
||||
|
||||
#include "ui/style/style_core_font.h"
|
||||
|
||||
#include <QFontDatabase>
|
||||
|
||||
namespace style {
|
||||
namespace {
|
||||
|
||||
using namespace internal;
|
||||
|
||||
auto RegularFont = CustomFont();
|
||||
auto BoldFont = CustomFont();
|
||||
|
||||
} // namespace
|
||||
|
||||
void SetCustomFonts(const CustomFont ®ular, const CustomFont &bold) {
|
||||
RegularFont = regular;
|
||||
BoldFont = bold;
|
||||
}
|
||||
|
||||
QFont ResolveFont(uint32 flags, int size) {
|
||||
static auto Database = QFontDatabase();
|
||||
|
||||
const auto fontOverride = ParseFamilyName(GetFontOverride(flags));
|
||||
const auto overrideIsEmpty = GetPossibleEmptyOverride(flags).isEmpty();
|
||||
|
||||
const auto bold = ((flags & FontBold) || (flags & FontSemibold));
|
||||
const auto italic = (flags & FontItalic);
|
||||
const auto &custom = bold ? BoldFont : RegularFont;
|
||||
const auto useCustom = !custom.family.isEmpty();
|
||||
|
||||
auto result = QFont();
|
||||
if (flags & FontMonospace) {
|
||||
result.setFamily(MonospaceFont());
|
||||
} else if (useCustom) {
|
||||
const auto sizes = Database.smoothSizes(custom.family, custom.style);
|
||||
const auto good = sizes.isEmpty()
|
||||
? Database.pointSizes(custom.family, custom.style)
|
||||
: sizes;
|
||||
const auto point = good.isEmpty() ? size : good.front();
|
||||
result = Database.font(custom.family, custom.style, point);
|
||||
} else if (!UseSystemFont || !overrideIsEmpty) {
|
||||
result.setFamily(fontOverride);
|
||||
if (bold) {
|
||||
if (CustomSemiboldIsBold) {
|
||||
result.setBold(true);
|
||||
#ifdef DESKTOP_APP_USE_PACKAGED_FONTS
|
||||
} else {
|
||||
result.setWeight(QFont::DemiBold);
|
||||
#else // DESKTOP_APP_USE_PACKAGED_FONTS
|
||||
} else if (UseSystemFont) {
|
||||
result.setWeight(QFont::DemiBold);
|
||||
} else {
|
||||
result.setBold(true);
|
||||
#endif // !DESKTOP_APP_USE_PACKAGED_FONTS
|
||||
}
|
||||
|
||||
if (!CustomSemiboldIsBold) {
|
||||
if (flags & FontItalic) {
|
||||
result.setStyleName("Semibold Italic");
|
||||
} else {
|
||||
result.setStyleName("Semibold");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IsRealSemibold(fontOverride)) {
|
||||
if (_flags & FontItalic) {
|
||||
f.setStyleName("Semibold Italic");
|
||||
} else {
|
||||
f.setStyleName("Semibold");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (italic) {
|
||||
result.setItalic(true);
|
||||
}
|
||||
|
||||
result.setUnderline(flags & FontUnderline);
|
||||
result.setStrikeOut(flags & FontStrikeOut);
|
||||
result.setPixelSize(size);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace style
|
||||
45
ui/style/style_core_custom_font.h
Normal file
45
ui/style/style_core_custom_font.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
// This file is part of Desktop App Toolkit,
|
||||
// a set of libraries for developing nice desktop applications.
|
||||
//
|
||||
// For license and copyright information please follow this link:
|
||||
// https://github.com/desktop-app/legal/blob/master/LEGAL
|
||||
//
|
||||
#pragma once
|
||||
|
||||
namespace style {
|
||||
|
||||
struct CustomFont {
|
||||
QString family;
|
||||
QString style;
|
||||
};
|
||||
|
||||
inline bool operator==(const CustomFont &a, const CustomFont &b) {
|
||||
return (a.family == b.family) && (a.style == b.style);
|
||||
}
|
||||
|
||||
inline bool operator<(const CustomFont &a, const CustomFont &b) {
|
||||
return (a.family < b.family)
|
||||
|| (a.family == b.family && a.style < b.style);
|
||||
}
|
||||
|
||||
inline bool operator!=(const CustomFont &a, const CustomFont &b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
inline bool operator>(const CustomFont &a, const CustomFont &b) {
|
||||
return (b < a);
|
||||
}
|
||||
|
||||
inline bool operator<=(const CustomFont &a, const CustomFont &b) {
|
||||
return !(b < a);
|
||||
}
|
||||
|
||||
inline bool operator>=(const CustomFont &a, const CustomFont &b) {
|
||||
return !(a < b);
|
||||
}
|
||||
|
||||
void SetCustomFonts(const CustomFont ®ular, const CustomFont &bold);
|
||||
|
||||
[[nodiscard]] QFont ResolveFont(uint32 flags, int size);
|
||||
|
||||
} // namespace style
|
||||
|
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
#include "ui/style/style_core_font.h"
|
||||
|
||||
#include "ui/style/style_core_custom_font.h"
|
||||
#include "ui/ui_log.h"
|
||||
#include "base/algorithm.h"
|
||||
#include "ui/integration.h"
|
||||
|
|
@ -47,33 +48,6 @@ QString RemoveSemiboldFromName(const QString &familyName) {
|
|||
return removedSemibold.trimmed();
|
||||
}
|
||||
|
||||
bool IsRealSemibold(const QString &familyName) {
|
||||
const auto removedSemibold = RemoveSemiboldFromName(familyName);
|
||||
|
||||
QFont originalFont(familyName);
|
||||
QFont withoutSemiboldFont(removedSemibold);
|
||||
withoutSemiboldFont.setStyleName("Semibold");
|
||||
|
||||
QFontInfo originalFontInfo(originalFont);
|
||||
QFontInfo withoutSemiboldInfo(withoutSemiboldFont);
|
||||
|
||||
if (originalFontInfo.family().trimmed().compare(familyName, Qt::CaseInsensitive) &&
|
||||
!withoutSemiboldInfo.family().trimmed().compare(removedSemibold, Qt::CaseInsensitive) &&
|
||||
!withoutSemiboldInfo.styleName().trimmed().compare("Semibold", Qt::CaseInsensitive)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QString ParseFamilyName(const QString &familyName) {
|
||||
if (IsRealSemibold(familyName)) {
|
||||
return RemoveSemiboldFromName(familyName);
|
||||
} else {
|
||||
return familyName;
|
||||
}
|
||||
}
|
||||
|
||||
bool ValidateFont(const QString &familyName, int flags = 0) {
|
||||
const auto parsedFamily = ParseFamilyName(familyName);
|
||||
|
||||
|
|
@ -150,30 +124,6 @@ bool TryFont(const QString &attempt) {
|
|||
return QString();
|
||||
}
|
||||
|
||||
QString MonospaceFont() {
|
||||
static const auto family = [&]() -> QString {
|
||||
if (TryFont(CustomMonospaceFont)) {
|
||||
return CustomMonospaceFont;
|
||||
}
|
||||
|
||||
const auto manual = ManualMonospaceFont();
|
||||
const auto system = SystemMonospaceFont();
|
||||
|
||||
#if defined Q_OS_WIN || defined Q_OS_MAC
|
||||
// Prefer our monospace font.
|
||||
const auto useSystem = manual.isEmpty();
|
||||
#else // Q_OS_WIN || Q_OS_MAC
|
||||
// Prefer system monospace font.
|
||||
const auto metrics = QFontMetrics(QFont(system));
|
||||
const auto useSystem = manual.isEmpty()
|
||||
|| (metrics.charWidth("i", 0) == metrics.charWidth("W", 0));
|
||||
#endif // Q_OS_WIN || Q_OS_MAC
|
||||
return (useSystem || UseSystemFont) ? system : manual;
|
||||
}();
|
||||
|
||||
return family;
|
||||
}
|
||||
|
||||
QFontMetrics GetFontMetrics(int size) {
|
||||
#ifdef DESKTOP_APP_USE_PACKAGED_FONTS
|
||||
QFont originalFont("Open Sans");
|
||||
|
|
@ -355,6 +305,57 @@ QString GetFontOverride(int32 flags) {
|
|||
return result.isEmpty() ? "Open Sans" : result;
|
||||
}
|
||||
|
||||
bool IsRealSemibold(const QString &familyName) {
|
||||
const auto removedSemibold = RemoveSemiboldFromName(familyName);
|
||||
|
||||
QFont originalFont(familyName);
|
||||
QFont withoutSemiboldFont(removedSemibold);
|
||||
withoutSemiboldFont.setStyleName("Semibold");
|
||||
|
||||
QFontInfo originalFontInfo(originalFont);
|
||||
QFontInfo withoutSemiboldInfo(withoutSemiboldFont);
|
||||
|
||||
if (originalFontInfo.family().trimmed().compare(familyName, Qt::CaseInsensitive) &&
|
||||
!withoutSemiboldInfo.family().trimmed().compare(removedSemibold, Qt::CaseInsensitive) &&
|
||||
!withoutSemiboldInfo.styleName().trimmed().compare("Semibold", Qt::CaseInsensitive)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QString ParseFamilyName(const QString &familyName) {
|
||||
if (IsRealSemibold(familyName)) {
|
||||
return RemoveSemiboldFromName(familyName);
|
||||
} else {
|
||||
return familyName;
|
||||
}
|
||||
}
|
||||
|
||||
QString MonospaceFont() {
|
||||
static const auto family = [&]() -> QString {
|
||||
if (TryFont(CustomMonospaceFont)) {
|
||||
return CustomMonospaceFont;
|
||||
}
|
||||
|
||||
const auto manual = ManualMonospaceFont();
|
||||
const auto system = SystemMonospaceFont();
|
||||
|
||||
#if defined Q_OS_WIN || defined Q_OS_MAC
|
||||
// Prefer our monospace font.
|
||||
const auto useSystem = manual.isEmpty();
|
||||
#else // Q_OS_WIN || Q_OS_MAC
|
||||
// Prefer system monospace font.
|
||||
const auto metrics = QFontMetrics(QFont(system));
|
||||
const auto useSystem = manual.isEmpty()
|
||||
|| (metrics.charWidth("i", 0) == metrics.charWidth("W", 0));
|
||||
#endif // Q_OS_WIN || Q_OS_MAC
|
||||
return (useSystem || UseSystemFont) ? system : manual;
|
||||
}();
|
||||
|
||||
return family;
|
||||
}
|
||||
|
||||
void destroyFonts() {
|
||||
for (auto fontData : fontsMap) {
|
||||
delete fontData;
|
||||
|
|
@ -373,13 +374,11 @@ int registerFontFamily(const QString &family) {
|
|||
}
|
||||
|
||||
FontData::FontData(int size, uint32 flags, int family, Font *other)
|
||||
: m(f)
|
||||
: f(ResolveFont(flags, size))
|
||||
, m(f)
|
||||
, _size(size)
|
||||
, _flags(flags)
|
||||
, _family(family) {
|
||||
const auto fontOverride = ParseFamilyName(GetFontOverride(flags));
|
||||
const auto overrideIsEmpty = GetPossibleEmptyOverride(flags).isEmpty();
|
||||
|
||||
if (other) {
|
||||
memcpy(modified, other, sizeof(modified));
|
||||
} else {
|
||||
|
|
@ -387,50 +386,6 @@ FontData::FontData(int size, uint32 flags, int family, Font *other)
|
|||
}
|
||||
modified[_flags] = Font(this);
|
||||
|
||||
if (_flags & FontMonospace) {
|
||||
f.setFamily(MonospaceFont());
|
||||
} else if (!UseSystemFont || !overrideIsEmpty) {
|
||||
f.setFamily(fontOverride);
|
||||
}
|
||||
|
||||
f.setPixelSize(size);
|
||||
f.setItalic(_flags & FontItalic);
|
||||
f.setUnderline(_flags & FontUnderline);
|
||||
f.setStrikeOut(_flags & FontStrikeOut);
|
||||
|
||||
if ((_flags & FontBold) || (_flags & FontSemibold)) {
|
||||
if (CustomSemiboldIsBold) {
|
||||
f.setBold(true);
|
||||
#ifdef DESKTOP_APP_USE_PACKAGED_FONTS
|
||||
} else {
|
||||
f.setWeight(QFont::DemiBold);
|
||||
#else // DESKTOP_APP_USE_PACKAGED_FONTS
|
||||
} else if (UseSystemFont) {
|
||||
f.setWeight(QFont::DemiBold);
|
||||
} else {
|
||||
f.setBold(true);
|
||||
#endif // !DESKTOP_APP_USE_PACKAGED_FONTS
|
||||
}
|
||||
|
||||
if (!CustomSemiboldIsBold) {
|
||||
if (_flags & FontItalic) {
|
||||
f.setStyleName("Semibold Italic");
|
||||
} else {
|
||||
f.setStyleName("Semibold");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IsRealSemibold(fontOverride)) {
|
||||
if (_flags & FontItalic) {
|
||||
f.setStyleName("Semibold Italic");
|
||||
} else {
|
||||
f.setStyleName("Semibold");
|
||||
}
|
||||
}
|
||||
|
||||
m = QFontMetrics(f);
|
||||
|
||||
if (UseOriginalMetrics && !(_flags & FontMonospace)) {
|
||||
const auto mOrig = GetFontMetrics(size);
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,11 @@ extern bool UseSystemFont;
|
|||
extern bool UseOriginalMetrics;
|
||||
|
||||
void StartFonts();
|
||||
[[nodiscard]] QString GetPossibleEmptyOverride(int32 flags = 0);
|
||||
[[nodiscard]] QString GetFontOverride(int32 flags = 0);
|
||||
[[nodiscard]] bool IsRealSemibold(const QString &familyName);
|
||||
[[nodiscard]] QString ParseFamilyName(const QString &familyName);
|
||||
[[nodiscard]] QString MonospaceFont();
|
||||
|
||||
void destroyFonts();
|
||||
int registerFontFamily(const QString &family);
|
||||
|
|
@ -74,17 +78,19 @@ enum FontFlags {
|
|||
|
||||
class FontData {
|
||||
public:
|
||||
|
||||
int32 width(const QString &str) const {
|
||||
int width(const QString &str) const {
|
||||
return m.width(str);
|
||||
}
|
||||
int32 width(const QString &str, int32 from, int32 to) const {
|
||||
int width(const QString &str, int32 from, int32 to) const {
|
||||
return width(str.mid(from, to));
|
||||
}
|
||||
int32 width(QChar ch) const {
|
||||
int width(QChar ch) const {
|
||||
return m.width(ch);
|
||||
}
|
||||
QString elided(const QString &str, int32 width, Qt::TextElideMode mode = Qt::ElideRight) const {
|
||||
QString elided(
|
||||
const QString &str,
|
||||
int width,
|
||||
Qt::TextElideMode mode = Qt::ElideRight) const {
|
||||
return m.elidedText(str, mode, width);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue