mirror of
https://github.com/kotatogram/kotatogram-desktop
synced 2025-08-31 06:35:14 +00:00
Build fixes
This commit is contained in:
@@ -10,6 +10,7 @@ https://github.com/kotatogram/kotatogram-desktop/blob/dev/LEGAL
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "styles/style_layers.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "core/kotato_settings.h"
|
||||
|
@@ -14,7 +14,7 @@ class Checkbox;
|
||||
class InputField;
|
||||
} // namespace Ui
|
||||
|
||||
class FontsBox : public BoxContent {
|
||||
class FontsBox : public Ui::BoxContent {
|
||||
public:
|
||||
FontsBox(QWidget* parent);
|
||||
|
||||
|
@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "lang/lang_keys.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "styles/style_layers.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "core/kotato_settings.h"
|
||||
|
@@ -15,7 +15,7 @@ class Radiobutton;
|
||||
class FlatLabel;
|
||||
} // namespace Ui
|
||||
|
||||
class NetBoostBox : public BoxContent {
|
||||
class NetBoostBox : public Ui::BoxContent {
|
||||
public:
|
||||
NetBoostBox(QWidget* parent);
|
||||
|
||||
|
@@ -11,6 +11,7 @@ https://github.com/kotatogram/kotatogram-desktop/blob/dev/LEGAL
|
||||
#include "settings/settings_chat.h"
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/continuous_sliders.h"
|
||||
@@ -20,9 +21,7 @@ https://github.com/kotatogram/kotatogram-desktop/blob/dev/LEGAL
|
||||
#include "boxes/net_boost_box.h"
|
||||
#include "boxes/about_box.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "info/profile/info_profile_button.h"
|
||||
#include "platform/platform_specific.h"
|
||||
#include "platform/platform_info.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "core/update_checker.h"
|
||||
|
@@ -1,257 +0,0 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "ui/style/style_core.h"
|
||||
|
||||
#include "ui/effects/animation_value.h"
|
||||
#include "ui/painter.h"
|
||||
#include "styles/style_basic.h"
|
||||
#include "styles/palette.h"
|
||||
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QFontDatabase>
|
||||
|
||||
#include <rpl/event_stream.h>
|
||||
#include <rpl/variable.h>
|
||||
|
||||
namespace style {
|
||||
namespace internal {
|
||||
namespace {
|
||||
|
||||
constexpr auto kMinContrastAlpha = 64;
|
||||
constexpr auto kMinContrastDistance = 64 * 64 * 4;
|
||||
constexpr auto kContrastDeltaL = 64;
|
||||
|
||||
auto PaletteChanges = rpl::event_stream<>();
|
||||
auto ShortAnimationRunning = rpl::variable<bool>(false);
|
||||
auto RunningShortAnimations = 0;
|
||||
auto ResolvedMonospaceFont = style::font();
|
||||
QString CustomMonospaceFont;
|
||||
|
||||
std::vector<internal::ModuleBase*> &StyleModules() {
|
||||
static auto result = std::vector<internal::ModuleBase*>();
|
||||
return result;
|
||||
}
|
||||
|
||||
void startModules(int scale) {
|
||||
for (const auto module : StyleModules()) {
|
||||
module->start(scale);
|
||||
}
|
||||
}
|
||||
|
||||
void ResolveMonospaceFont() {
|
||||
auto family = QString();
|
||||
const auto tryFont = [&](const QString &attempt) {
|
||||
if (family.isEmpty()
|
||||
&& !QFontInfo(QFont(attempt)).family().trimmed().compare(
|
||||
attempt,
|
||||
Qt::CaseInsensitive)) {
|
||||
family = attempt;
|
||||
}
|
||||
};
|
||||
if (!CustomMonospaceFont.isEmpty()) {
|
||||
tryFont(CustomMonospaceFont);
|
||||
}
|
||||
tryFont("Consolas");
|
||||
tryFont("Liberation Mono");
|
||||
tryFont("Menlo");
|
||||
tryFont("Courier");
|
||||
if (family.isEmpty()) {
|
||||
const auto type = QFontDatabase::FixedFont;
|
||||
family = QFontDatabase::systemFont(type).family();
|
||||
}
|
||||
const auto size = st::normalFont->f.pixelSize();
|
||||
ResolvedMonospaceFont = style::font(size, 0, family);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void SetMonospaceFont(const QString &familyName) {
|
||||
CustomMonospaceFont = familyName;
|
||||
}
|
||||
|
||||
void registerModule(ModuleBase *module) {
|
||||
StyleModules().push_back(module);
|
||||
}
|
||||
|
||||
void StartShortAnimation() {
|
||||
if (++RunningShortAnimations == 1) {
|
||||
ShortAnimationRunning = true;
|
||||
}
|
||||
}
|
||||
|
||||
void StopShortAnimation() {
|
||||
if (--RunningShortAnimations == 0) {
|
||||
ShortAnimationRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
void startManager(int scale) {
|
||||
internal::registerFontFamily("Open Sans");
|
||||
internal::startModules(scale);
|
||||
internal::ResolveMonospaceFont();
|
||||
}
|
||||
|
||||
void stopManager() {
|
||||
internal::destroyFonts();
|
||||
internal::destroyIcons();
|
||||
}
|
||||
|
||||
rpl::producer<> PaletteChanged() {
|
||||
return internal::PaletteChanges.events();
|
||||
}
|
||||
|
||||
void NotifyPaletteChanged() {
|
||||
internal::PaletteChanges.fire({});
|
||||
}
|
||||
|
||||
rpl::producer<bool> ShortAnimationPlaying() {
|
||||
return internal::ShortAnimationRunning.value();
|
||||
}
|
||||
|
||||
const style::font &MonospaceFont() {
|
||||
return internal::ResolvedMonospaceFont;
|
||||
}
|
||||
|
||||
void colorizeImage(const QImage &src, QColor c, QImage *outResult, QRect srcRect, QPoint dstPoint) {
|
||||
// In background_box ColorizePattern we use the fact that
|
||||
// colorizeImage takes only first byte of the mask, so it
|
||||
// could be used for wallpaper patterns, which have values
|
||||
// in ranges (0, 0, 0, 0) to (0, 0, 0, 255) (only 'alpha').
|
||||
if (srcRect.isNull()) {
|
||||
srcRect = src.rect();
|
||||
} else {
|
||||
Assert(src.rect().contains(srcRect));
|
||||
}
|
||||
auto width = srcRect.width();
|
||||
auto height = srcRect.height();
|
||||
Assert(outResult && outResult->rect().contains(QRect(dstPoint, srcRect.size())));
|
||||
|
||||
auto pattern = anim::shifted(c);
|
||||
|
||||
auto resultBytesPerPixel = (src.depth() >> 3);
|
||||
constexpr auto resultIntsPerPixel = 1;
|
||||
auto resultIntsPerLine = (outResult->bytesPerLine() >> 2);
|
||||
auto resultIntsAdded = resultIntsPerLine - width * resultIntsPerPixel;
|
||||
auto resultInts = reinterpret_cast<uint32*>(outResult->bits()) + dstPoint.y() * resultIntsPerLine + dstPoint.x() * resultIntsPerPixel;
|
||||
Assert(resultIntsAdded >= 0);
|
||||
Assert(outResult->depth() == static_cast<int>((resultIntsPerPixel * sizeof(uint32)) << 3));
|
||||
Assert(outResult->bytesPerLine() == (resultIntsPerLine << 2));
|
||||
|
||||
auto maskBytesPerPixel = (src.depth() >> 3);
|
||||
auto maskBytesPerLine = src.bytesPerLine();
|
||||
auto maskBytesAdded = maskBytesPerLine - width * maskBytesPerPixel;
|
||||
auto maskBytes = src.constBits() + srcRect.y() * maskBytesPerLine + srcRect.x() * maskBytesPerPixel;
|
||||
Assert(maskBytesAdded >= 0);
|
||||
Assert(src.depth() == (maskBytesPerPixel << 3));
|
||||
for (int y = 0; y != height; ++y) {
|
||||
for (int x = 0; x != width; ++x) {
|
||||
auto maskOpacity = static_cast<anim::ShiftedMultiplier>(*maskBytes) + 1;
|
||||
*resultInts = anim::unshifted(pattern * maskOpacity);
|
||||
maskBytes += maskBytesPerPixel;
|
||||
resultInts += resultIntsPerPixel;
|
||||
}
|
||||
maskBytes += maskBytesAdded;
|
||||
resultInts += resultIntsAdded;
|
||||
}
|
||||
|
||||
outResult->setDevicePixelRatio(src.devicePixelRatio());
|
||||
}
|
||||
|
||||
QBrush transparentPlaceholderBrush() {
|
||||
auto size = st::transparentPlaceholderSize * DevicePixelRatio();
|
||||
auto transparent = QImage(2 * size, 2 * size, QImage::Format_ARGB32_Premultiplied);
|
||||
transparent.fill(st::mediaviewTransparentBg->c);
|
||||
{
|
||||
QPainter p(&transparent);
|
||||
p.fillRect(0, size, size, size, st::mediaviewTransparentFg);
|
||||
p.fillRect(size, 0, size, size, st::mediaviewTransparentFg);
|
||||
}
|
||||
transparent.setDevicePixelRatio(DevicePixelRatio());
|
||||
return QBrush(transparent);
|
||||
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
QImage createCircleMask(int size, QColor bg, QColor fg) {
|
||||
int realSize = size * DevicePixelRatio();
|
||||
#ifndef OS_MAC_OLD
|
||||
auto result = QImage(realSize, realSize, QImage::Format::Format_Grayscale8);
|
||||
#else // OS_MAC_OLD
|
||||
auto result = QImage(realSize, realSize, QImage::Format::Format_RGB32);
|
||||
#endif // OS_MAC_OLD
|
||||
{
|
||||
QPainter p(&result);
|
||||
PainterHighQualityEnabler hq(p);
|
||||
|
||||
p.fillRect(0, 0, realSize, realSize, bg);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(fg);
|
||||
p.drawEllipse(0, 0, realSize, realSize);
|
||||
}
|
||||
result.setDevicePixelRatio(DevicePixelRatio());
|
||||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool GoodForContrast(const QColor &c1, const QColor &c2) {
|
||||
auto r1 = 0;
|
||||
auto g1 = 0;
|
||||
auto b1 = 0;
|
||||
auto r2 = 0;
|
||||
auto g2 = 0;
|
||||
auto b2 = 0;
|
||||
c1.getRgb(&r1, &g1, &b1);
|
||||
c2.getRgb(&r2, &g2, &b2);
|
||||
const auto rMean = (r1 + r2) / 2;
|
||||
const auto r = r1 - r2;
|
||||
const auto g = g1 - g2;
|
||||
const auto b = b1 - b2;
|
||||
const auto distance = (((512 + rMean) * r * r) >> 8)
|
||||
+ (4 * g * g)
|
||||
+ (((767 - rMean) * b * b) >> 8);
|
||||
return (distance > kMinContrastDistance);
|
||||
}
|
||||
|
||||
QColor EnsureContrast(const QColor &over, const QColor &under) {
|
||||
auto overH = 0;
|
||||
auto overS = 0;
|
||||
auto overL = 0;
|
||||
auto overA = 0;
|
||||
auto underH = 0;
|
||||
auto underS = 0;
|
||||
auto underL = 0;
|
||||
over.getHsl(&overH, &overS, &overL, &overA);
|
||||
under.getHsl(&underH, &underS, &underL);
|
||||
const auto good = GoodForContrast(over, under);
|
||||
if (overA >= kMinContrastAlpha && good) {
|
||||
return over;
|
||||
}
|
||||
const auto newA = std::max(overA, kMinContrastAlpha);
|
||||
const auto newL = (overL > underL && overL + kContrastDeltaL <= 255)
|
||||
? (overL + kContrastDeltaL)
|
||||
: (overL < underL && overL - kContrastDeltaL >= 0)
|
||||
? (overL - kContrastDeltaL)
|
||||
: (underL > 128)
|
||||
? (underL - kContrastDeltaL)
|
||||
: (underL + kContrastDeltaL);
|
||||
return QColor::fromHsl(overH, overS, newL, newA).toRgb();
|
||||
}
|
||||
|
||||
void EnsureContrast(ColorData &over, const ColorData &under) {
|
||||
const auto good = EnsureContrast(over.c, under.c);
|
||||
if (over.c != good) {
|
||||
over.c = good;
|
||||
over.p = QPen(good);
|
||||
over.b = QBrush(good);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace style
|
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "ui/style/style_core_scale.h"
|
||||
#include "ui/style/style_core_types.h"
|
||||
#include "ui/style/style_core_direction.h"
|
||||
|
||||
#include <rpl/producer.h>
|
||||
|
||||
namespace style {
|
||||
namespace internal {
|
||||
|
||||
// Objects of derived classes are created in global scope.
|
||||
// They call [un]registerModule() in [de|con]structor.
|
||||
class ModuleBase {
|
||||
public:
|
||||
virtual void start(int scale) = 0;
|
||||
|
||||
virtual ~ModuleBase() = default;
|
||||
|
||||
};
|
||||
|
||||
void SetMonospaceFont(const QString &familyName);
|
||||
|
||||
void registerModule(ModuleBase *module);
|
||||
|
||||
[[nodiscard]] QColor EnsureContrast(const QColor &over, const QColor &under);
|
||||
void EnsureContrast(ColorData &over, const ColorData &under);
|
||||
|
||||
void StartShortAnimation();
|
||||
void StopShortAnimation();
|
||||
|
||||
} // namespace internal
|
||||
|
||||
void startManager(int scale);
|
||||
void stopManager();
|
||||
|
||||
[[nodiscard]] rpl::producer<> PaletteChanged();
|
||||
void NotifyPaletteChanged();
|
||||
|
||||
[[nodiscard]] rpl::producer<bool> ShortAnimationPlaying();
|
||||
|
||||
const style::font &MonospaceFont();
|
||||
|
||||
// *outResult must be r.width() x r.height(), ARGB32_Premultiplied.
|
||||
// QRect(0, 0, src.width(), src.height()) must contain r.
|
||||
void colorizeImage(const QImage &src, QColor c, QImage *outResult, QRect srcRect = QRect(), QPoint dstPoint = QPoint(0, 0));
|
||||
|
||||
inline QImage colorizeImage(const QImage &src, QColor c, QRect srcRect = QRect()) {
|
||||
if (srcRect.isNull()) srcRect = src.rect();
|
||||
auto result = QImage(srcRect.size(), QImage::Format_ARGB32_Premultiplied);
|
||||
colorizeImage(src, c, &result, srcRect);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline QImage colorizeImage(const QImage &src, const color &c, QRect srcRect = QRect()) {
|
||||
return colorizeImage(src, c->c, srcRect);
|
||||
}
|
||||
|
||||
QBrush transparentPlaceholderBrush();
|
||||
|
||||
namespace internal {
|
||||
|
||||
QImage createCircleMask(int size, QColor bg, QColor fg);
|
||||
|
||||
} // namespace internal
|
||||
|
||||
inline QImage createCircleMask(int size) {
|
||||
return internal::createCircleMask(size, QColor(0, 0, 0), QColor(255, 255, 255));
|
||||
}
|
||||
|
||||
inline QImage createInvertedCircleMask(int size) {
|
||||
return internal::createCircleMask(size, QColor(255, 255, 255), QColor(0, 0, 0));
|
||||
}
|
||||
|
||||
} // namespace style
|
@@ -1,273 +0,0 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "ui/style/style_core_font.h"
|
||||
|
||||
#include "base/algorithm.h"
|
||||
#include "ui/ui_log.h"
|
||||
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QVector>
|
||||
#include <QtGui/QFontInfo>
|
||||
#include <QtGui/QFontDatabase>
|
||||
|
||||
namespace style {
|
||||
namespace internal {
|
||||
namespace {
|
||||
|
||||
QMap<QString, int> fontFamilyMap;
|
||||
QVector<QString> fontFamilies;
|
||||
QMap<uint32, FontData*> fontsMap;
|
||||
|
||||
uint32 fontKey(int size, uint32 flags, int family) {
|
||||
return (((uint32(family) << 10) | uint32(size)) << 4) | flags;
|
||||
}
|
||||
|
||||
bool ValidateFont(const QString &familyName, int flags = 0) {
|
||||
QFont checkFont(familyName);
|
||||
checkFont.setPixelSize(13);
|
||||
checkFont.setBold(flags & style::internal::FontBold);
|
||||
checkFont.setItalic(flags & style::internal::FontItalic);
|
||||
checkFont.setUnderline(flags & style::internal::FontUnderline);
|
||||
checkFont.setStyleStrategy(QFont::PreferQuality);
|
||||
auto realFamily = QFontInfo(checkFont).family();
|
||||
if (realFamily.trimmed().compare(familyName, Qt::CaseInsensitive)) {
|
||||
UI_LOG(("Font Error: could not resolve '%1' font, got '%2'.").arg(familyName).arg(realFamily));
|
||||
return false;
|
||||
}
|
||||
|
||||
auto metrics = QFontMetrics(checkFont);
|
||||
if (!metrics.height()) {
|
||||
UI_LOG(("Font Error: got a zero height in '%1'.").arg(familyName));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoadCustomFont(const QString &filePath, const QString &familyName, int flags = 0) {
|
||||
auto regularId = QFontDatabase::addApplicationFont(filePath);
|
||||
if (regularId < 0) {
|
||||
UI_LOG(("Font Error: could not add '%1'.").arg(filePath));
|
||||
return false;
|
||||
}
|
||||
|
||||
auto found = [&familyName, regularId] {
|
||||
for (auto &family : QFontDatabase::applicationFontFamilies(regularId)) {
|
||||
if (!family.trimmed().compare(familyName, Qt::CaseInsensitive)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
if (!found()) {
|
||||
UI_LOG(("Font Error: could not locate '%1' font in '%2'.").arg(familyName).arg(filePath));
|
||||
return false;
|
||||
}
|
||||
|
||||
return ValidateFont(familyName, flags);
|
||||
}
|
||||
|
||||
bool Started = false;
|
||||
QString OpenSansOverride;
|
||||
QString OpenSansSemiboldOverride;
|
||||
|
||||
QString CustomMainFont;
|
||||
QString CustomSemiboldFont;
|
||||
bool CustomSemiboldIsBold = false;
|
||||
|
||||
} // namespace
|
||||
|
||||
void SetMainFont(const QString &familyName) {
|
||||
CustomMainFont = familyName;
|
||||
}
|
||||
|
||||
void SetSemiboldFont(const QString &familyName) {
|
||||
CustomSemiboldFont = familyName;
|
||||
}
|
||||
|
||||
void SetSemiboldIsBold(bool isBold) {
|
||||
CustomSemiboldIsBold = isBold;
|
||||
}
|
||||
|
||||
void StartFonts() {
|
||||
if (Started) {
|
||||
return;
|
||||
}
|
||||
Started = true;
|
||||
|
||||
auto regular = LoadCustomFont(":/gui/fonts/OpenSans-Regular.ttf", "Open Sans");
|
||||
auto bold = LoadCustomFont(":/gui/fonts/OpenSans-Bold.ttf", "Open Sans", style::internal::FontBold);
|
||||
auto semibold = LoadCustomFont(":/gui/fonts/OpenSans-Semibold.ttf", "Open Sans Semibold");
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
// Attempt to workaround a strange font bug with Open Sans Semibold not loading.
|
||||
// See https://github.com/telegramdesktop/tdesktop/issues/3276 for details.
|
||||
// Crash happens on "options.maxh / _t->_st->font->height" with "division by zero".
|
||||
// In that place "_t->_st->font" is "semiboldFont" is "font(13 "Open Sans Semibold").
|
||||
if (!regular || !bold) {
|
||||
if (ValidateFont("Segoe UI") && ValidateFont("Segoe UI", style::internal::FontBold)) {
|
||||
OpenSansOverride = "Segoe UI";
|
||||
UI_LOG(("Fonts Info: Using Segoe UI instead of Open Sans."));
|
||||
}
|
||||
}
|
||||
if (!semibold) {
|
||||
if (ValidateFont("Segoe UI Semibold")) {
|
||||
OpenSansSemiboldOverride = "Segoe UI Semibold";
|
||||
UI_LOG(("Fonts Info: Using Segoe UI Semibold instead of Open Sans Semibold."));
|
||||
}
|
||||
}
|
||||
// Disable default fallbacks to Segoe UI, see:
|
||||
// https://github.com/telegramdesktop/tdesktop/issues/5368
|
||||
//
|
||||
//QFont::insertSubstitution("Open Sans", "Segoe UI");
|
||||
//QFont::insertSubstitution("Open Sans Semibold", "Segoe UI Semibold");
|
||||
#elif defined Q_OS_MAC // Q_OS_WIN
|
||||
auto list = QStringList();
|
||||
list.append(".SF NS Text");
|
||||
list.append("Helvetica Neue");
|
||||
list.append("Lucida Grande");
|
||||
QFont::insertSubstitutions("Open Sans", list);
|
||||
QFont::insertSubstitutions("Open Sans Semibold", list);
|
||||
#endif // Q_OS_WIN || Q_OS_MAC
|
||||
|
||||
if (!CustomMainFont.isEmpty() && ValidateFont(CustomMainFont)) {
|
||||
OpenSansOverride = CustomMainFont;
|
||||
}
|
||||
if (!CustomSemiboldFont.isEmpty() && ValidateFont(CustomSemiboldFont)) {
|
||||
OpenSansSemiboldOverride = CustomSemiboldFont;
|
||||
}
|
||||
}
|
||||
|
||||
QString GetFontOverride(const QString &familyName) {
|
||||
if (familyName == qstr("Open Sans")) {
|
||||
return OpenSansOverride.isEmpty() ? familyName : OpenSansOverride;
|
||||
} else if (familyName == qstr("Open Sans Semibold")) {
|
||||
return OpenSansSemiboldOverride.isEmpty() ? familyName : OpenSansSemiboldOverride;
|
||||
}
|
||||
return familyName;
|
||||
}
|
||||
|
||||
void destroyFonts() {
|
||||
for (auto fontData : fontsMap) {
|
||||
delete fontData;
|
||||
}
|
||||
fontsMap.clear();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
FontData::FontData(int size, uint32 flags, int family, Font *other)
|
||||
: f(GetFontOverride(fontFamilies[family]))
|
||||
, m(f)
|
||||
, _size(size)
|
||||
, _flags(flags)
|
||||
, _family(family) {
|
||||
if (other) {
|
||||
memcpy(modified, other, sizeof(modified));
|
||||
} else {
|
||||
memset(modified, 0, sizeof(modified));
|
||||
}
|
||||
modified[_flags] = Font(this);
|
||||
|
||||
f.setPixelSize(size);
|
||||
if (_flags & FontBold) {
|
||||
f.setBold(true);
|
||||
} else if (fontFamilies[family] == "Open Sans Semibold" && CustomSemiboldIsBold) {
|
||||
f.setBold(true);
|
||||
}
|
||||
f.setItalic(_flags & FontItalic);
|
||||
f.setUnderline(_flags & FontUnderline);
|
||||
f.setStrikeOut(_flags & FontStrikeOut);
|
||||
f.setStyleStrategy(QFont::PreferQuality);
|
||||
|
||||
m = QFontMetrics(f);
|
||||
height = m.height();
|
||||
ascent = m.ascent();
|
||||
descent = m.descent();
|
||||
spacew = width(QLatin1Char(' '));
|
||||
elidew = width("...");
|
||||
}
|
||||
|
||||
Font FontData::bold(bool set) const {
|
||||
return otherFlagsFont(FontBold, set);
|
||||
}
|
||||
|
||||
Font FontData::italic(bool set) const {
|
||||
return otherFlagsFont(FontItalic, set);
|
||||
}
|
||||
|
||||
Font FontData::underline(bool set) const {
|
||||
return otherFlagsFont(FontUnderline, set);
|
||||
}
|
||||
|
||||
Font FontData::strikeout(bool set) const {
|
||||
return otherFlagsFont(FontStrikeOut, set);
|
||||
}
|
||||
|
||||
int FontData::size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
uint32 FontData::flags() const {
|
||||
return _flags;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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, uint32 flags, int family) {
|
||||
init(size, flags, family, 0);
|
||||
}
|
||||
|
||||
Font::Font(int size, uint32 flags, int family, Font *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));
|
||||
}
|
||||
ptr = i.value();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace style
|
@@ -1,130 +0,0 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/basic_types.h"
|
||||
|
||||
#include <QtGui/QFont>
|
||||
#include <QtGui/QFontMetrics>
|
||||
|
||||
namespace style {
|
||||
namespace internal {
|
||||
|
||||
void SetMainFont(const QString &familyName);
|
||||
void SetSemiboldFont(const QString &familyName);
|
||||
void SetSemiboldIsBold(bool isBold);
|
||||
|
||||
void StartFonts();
|
||||
[[nodiscard]] QString GetFontOverride(const QString &familyName);
|
||||
|
||||
void destroyFonts();
|
||||
int registerFontFamily(const QString &family);
|
||||
|
||||
class FontData;
|
||||
class Font {
|
||||
public:
|
||||
Font(Qt::Initialization = Qt::Uninitialized) : ptr(0) {
|
||||
}
|
||||
Font(int size, uint32 flags, const QString &family);
|
||||
Font(int size, uint32 flags, int family);
|
||||
|
||||
Font &operator=(const Font &other) {
|
||||
ptr = other.ptr;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
FontData *operator->() const {
|
||||
return ptr;
|
||||
}
|
||||
FontData *v() const {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
operator bool() const {
|
||||
return !!ptr;
|
||||
}
|
||||
|
||||
operator const QFont &() const;
|
||||
|
||||
private:
|
||||
FontData *ptr;
|
||||
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
enum FontFlags {
|
||||
FontBold = 0x01,
|
||||
FontItalic = 0x02,
|
||||
FontUnderline = 0x04,
|
||||
FontStrikeOut = 0x08,
|
||||
|
||||
FontDifferentFlags = 0x10,
|
||||
};
|
||||
|
||||
class FontData {
|
||||
public:
|
||||
|
||||
int32 width(const QString &str) const {
|
||||
return m.width(str);
|
||||
}
|
||||
int32 width(const QString &str, int32 from, int32 to) const {
|
||||
return width(str.mid(from, to));
|
||||
}
|
||||
int32 width(QChar ch) const {
|
||||
return m.width(ch);
|
||||
}
|
||||
QString elided(const QString &str, int32 width, Qt::TextElideMode mode = Qt::ElideRight) const {
|
||||
return m.elidedText(str, mode, width);
|
||||
}
|
||||
|
||||
Font bold(bool set = true) const;
|
||||
Font italic(bool set = true) const;
|
||||
Font underline(bool set = true) const;
|
||||
Font strikeout(bool set = true) const;
|
||||
|
||||
int size() const;
|
||||
uint32 flags() const;
|
||||
int family() const;
|
||||
|
||||
QFont f;
|
||||
QFontMetrics m;
|
||||
int32 height, ascent, descent, spacew, elidew;
|
||||
|
||||
private:
|
||||
mutable Font modified[FontDifferentFlags];
|
||||
|
||||
Font otherFlagsFont(uint32 flag, bool set) const;
|
||||
FontData(int size, uint32 flags, int family, Font *other);
|
||||
|
||||
friend class Font;
|
||||
int _size;
|
||||
uint32 _flags;
|
||||
int _family;
|
||||
|
||||
};
|
||||
|
||||
inline bool operator==(const Font &a, const Font &b) {
|
||||
return a.v() == b.v();
|
||||
}
|
||||
inline bool operator!=(const Font &a, const Font &b) {
|
||||
return a.v() != b.v();
|
||||
}
|
||||
|
||||
inline Font::operator const QFont &() const {
|
||||
return ptr->f;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace style
|
Reference in New Issue
Block a user