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.h
|
||||||
ui/style/style_core_color.cpp
|
ui/style/style_core_color.cpp
|
||||||
ui/style/style_core_color.h
|
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.cpp
|
||||||
ui/style/style_core_direction.h
|
ui/style/style_core_direction.h
|
||||||
ui/style/style_core_font.cpp
|
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_font.h"
|
||||||
|
|
||||||
|
#include "ui/style/style_core_custom_font.h"
|
||||||
#include "ui/ui_log.h"
|
#include "ui/ui_log.h"
|
||||||
#include "base/algorithm.h"
|
#include "base/algorithm.h"
|
||||||
#include "ui/integration.h"
|
#include "ui/integration.h"
|
||||||
|
|
@ -47,33 +48,6 @@ QString RemoveSemiboldFromName(const QString &familyName) {
|
||||||
return removedSemibold.trimmed();
|
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) {
|
bool ValidateFont(const QString &familyName, int flags = 0) {
|
||||||
const auto parsedFamily = ParseFamilyName(familyName);
|
const auto parsedFamily = ParseFamilyName(familyName);
|
||||||
|
|
||||||
|
|
@ -150,30 +124,6 @@ bool TryFont(const QString &attempt) {
|
||||||
return QString();
|
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) {
|
QFontMetrics GetFontMetrics(int size) {
|
||||||
#ifdef DESKTOP_APP_USE_PACKAGED_FONTS
|
#ifdef DESKTOP_APP_USE_PACKAGED_FONTS
|
||||||
QFont originalFont("Open Sans");
|
QFont originalFont("Open Sans");
|
||||||
|
|
@ -355,6 +305,57 @@ QString GetFontOverride(int32 flags) {
|
||||||
return result.isEmpty() ? "Open Sans" : result;
|
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() {
|
void destroyFonts() {
|
||||||
for (auto fontData : fontsMap) {
|
for (auto fontData : fontsMap) {
|
||||||
delete fontData;
|
delete fontData;
|
||||||
|
|
@ -373,13 +374,11 @@ int registerFontFamily(const QString &family) {
|
||||||
}
|
}
|
||||||
|
|
||||||
FontData::FontData(int size, uint32 flags, int family, Font *other)
|
FontData::FontData(int size, uint32 flags, int family, Font *other)
|
||||||
: m(f)
|
: f(ResolveFont(flags, size))
|
||||||
|
, m(f)
|
||||||
, _size(size)
|
, _size(size)
|
||||||
, _flags(flags)
|
, _flags(flags)
|
||||||
, _family(family) {
|
, _family(family) {
|
||||||
const auto fontOverride = ParseFamilyName(GetFontOverride(flags));
|
|
||||||
const auto overrideIsEmpty = GetPossibleEmptyOverride(flags).isEmpty();
|
|
||||||
|
|
||||||
if (other) {
|
if (other) {
|
||||||
memcpy(modified, other, sizeof(modified));
|
memcpy(modified, other, sizeof(modified));
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -387,50 +386,6 @@ FontData::FontData(int size, uint32 flags, int family, Font *other)
|
||||||
}
|
}
|
||||||
modified[_flags] = Font(this);
|
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)) {
|
if (UseOriginalMetrics && !(_flags & FontMonospace)) {
|
||||||
const auto mOrig = GetFontMetrics(size);
|
const auto mOrig = GetFontMetrics(size);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,11 @@ extern bool UseSystemFont;
|
||||||
extern bool UseOriginalMetrics;
|
extern bool UseOriginalMetrics;
|
||||||
|
|
||||||
void StartFonts();
|
void StartFonts();
|
||||||
|
[[nodiscard]] QString GetPossibleEmptyOverride(int32 flags = 0);
|
||||||
[[nodiscard]] QString GetFontOverride(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();
|
void destroyFonts();
|
||||||
int registerFontFamily(const QString &family);
|
int registerFontFamily(const QString &family);
|
||||||
|
|
@ -74,17 +78,19 @@ enum FontFlags {
|
||||||
|
|
||||||
class FontData {
|
class FontData {
|
||||||
public:
|
public:
|
||||||
|
int width(const QString &str) const {
|
||||||
int32 width(const QString &str) const {
|
|
||||||
return m.width(str);
|
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));
|
return width(str.mid(from, to));
|
||||||
}
|
}
|
||||||
int32 width(QChar ch) const {
|
int width(QChar ch) const {
|
||||||
return m.width(ch);
|
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);
|
return m.elidedText(str, mode, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue