1
0
mirror of https://github.com/Swordfish90/cool-retro-term.git synced 2026-02-08 00:32:27 +00:00

Tentative implementation of font handling on cpp side.

This commit is contained in:
Filippo Scognamiglio
2026-01-11 19:28:31 +01:00
parent bd89df3564
commit 60784c47d9
13 changed files with 827 additions and 209 deletions

View File

@@ -16,11 +16,13 @@ DESTDIR = $$OUT_PWD/../
HEADERS += \
fileio.h \
monospacefontmanager.h
fontmanager.h \
fontlistmodel.h
SOURCES += main.cpp \
fileio.cpp \
monospacefontmanager.cpp
fontmanager.cpp \
fontlistmodel.cpp
macx:ICON = icons/crt.icns

94
app/fontlistmodel.cpp Normal file
View File

@@ -0,0 +1,94 @@
#include "fontlistmodel.h"
FontListModel::FontListModel(QObject *parent)
: QAbstractListModel(parent)
{
}
int FontListModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid()) {
return 0;
}
return m_fonts.size();
}
QVariant FontListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() < 0 || index.row() >= m_fonts.size()) {
return QVariant();
}
const FontEntry &font = m_fonts.at(index.row());
switch (role) {
case NameRole:
return font.name;
case TextRole:
return font.text;
case SourceRole:
return font.source;
case BaseWidthRole:
return font.baseWidth;
case PixelSizeRole:
return font.pixelSize;
case LowResolutionRole:
return font.lowResolutionFont;
case IsSystemRole:
return font.isSystemFont;
case FamilyRole:
return font.family;
case FallbackNameRole:
return font.fallbackName;
default:
return QVariant();
}
}
QHash<int, QByteArray> FontListModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[NameRole] = "name";
roles[TextRole] = "text";
roles[SourceRole] = "source";
roles[BaseWidthRole] = "baseWidth";
roles[PixelSizeRole] = "pixelSize";
roles[LowResolutionRole] = "lowResolutionFont";
roles[IsSystemRole] = "isSystemFont";
roles[FamilyRole] = "family";
roles[FallbackNameRole] = "fallbackName";
return roles;
}
void FontListModel::setFonts(const QVector<FontEntry> &fonts)
{
beginResetModel();
m_fonts = fonts;
endResetModel();
emit countChanged();
}
const QVector<FontEntry> &FontListModel::fonts() const
{
return m_fonts;
}
QVariantMap FontListModel::get(int index) const
{
QVariantMap map;
if (index < 0 || index >= m_fonts.size()) {
return map;
}
const FontEntry &font = m_fonts.at(index);
map.insert("name", font.name);
map.insert("text", font.text);
map.insert("source", font.source);
map.insert("baseWidth", font.baseWidth);
map.insert("pixelSize", font.pixelSize);
map.insert("lowResolutionFont", font.lowResolutionFont);
map.insert("isSystemFont", font.isSystemFont);
map.insert("family", font.family);
map.insert("fallbackName", font.fallbackName);
return map;
}

59
app/fontlistmodel.h Normal file
View File

@@ -0,0 +1,59 @@
#ifndef FONTLISTMODEL_H
#define FONTLISTMODEL_H
#include <QAbstractListModel>
#include <QVector>
#include <QVariant>
#include <QVariantMap>
#include <QString>
struct FontEntry
{
QString name;
QString text;
QString source;
qreal baseWidth = 1.0;
int pixelSize = 0;
bool lowResolutionFont = false;
bool isSystemFont = false;
QString family;
QString fallbackName;
};
class FontListModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
public:
explicit FontListModel(QObject *parent = nullptr);
enum Roles {
NameRole = Qt::UserRole + 1,
TextRole,
SourceRole,
BaseWidthRole,
PixelSizeRole,
LowResolutionRole,
IsSystemRole,
FamilyRole,
FallbackNameRole
};
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role) const override;
QHash<int, QByteArray> roleNames() const override;
void setFonts(const QVector<FontEntry> &fonts);
const QVector<FontEntry> &fonts() const;
Q_INVOKABLE QVariantMap get(int index) const;
signals:
void countChanged();
private:
QVector<FontEntry> m_fonts;
};
#endif // FONTLISTMODEL_H

524
app/fontmanager.cpp Normal file
View File

@@ -0,0 +1,524 @@
#include "fontmanager.h"
#include <QFont>
#include <QFontDatabase>
#include <QtMath>
namespace {
constexpr int kModernRasterization = 4;
constexpr int kBaseFontPixelHeight = 32;
constexpr int kSystemFontPixelSize = 30;
}
FontManager::FontManager(QObject *parent)
: QObject(parent)
, m_fontListModel(this)
, m_filteredFontListModel(this)
{
populateBundledFonts();
populateSystemFonts();
m_fontListModel.setFonts(m_allFonts);
updateFilteredFonts();
updateComputedFont();
}
QStringList FontManager::retrieveMonospaceFonts()
{
QStringList result;
QFontDatabase fontDatabase;
const QStringList fontFamilies = fontDatabase.families();
for (const QString &fontFamily : fontFamilies) {
QFont font(fontFamily);
if (fontDatabase.isFixedPitch(font.family())) {
result.append(fontFamily);
}
}
return result;
}
void FontManager::refresh()
{
updateFilteredFonts();
updateComputedFont();
}
FontListModel *FontManager::fontList()
{
return &m_fontListModel;
}
FontListModel *FontManager::filteredFontList()
{
return &m_filteredFontListModel;
}
int FontManager::fontSource() const
{
return m_fontSource;
}
void FontManager::setFontSource(int fontSource)
{
if (m_fontSource == fontSource) {
return;
}
m_fontSource = fontSource;
emit fontSourceChanged();
updateFilteredFonts();
updateComputedFont();
}
int FontManager::rasterization() const
{
return m_rasterization;
}
void FontManager::setRasterization(int rasterization)
{
if (m_rasterization == rasterization) {
return;
}
m_rasterization = rasterization;
emit rasterizationChanged();
updateFilteredFonts();
updateComputedFont();
}
QString FontManager::fontName() const
{
return m_fontName;
}
void FontManager::setFontName(const QString &fontName)
{
if (m_fontName == fontName) {
return;
}
m_fontName = fontName;
emit fontNameChanged();
updateFilteredFonts();
updateComputedFont();
}
qreal FontManager::fontScaling() const
{
return m_fontScaling;
}
void FontManager::setFontScaling(qreal fontScaling)
{
if (qFuzzyCompare(m_fontScaling, fontScaling)) {
return;
}
m_fontScaling = fontScaling;
emit fontScalingChanged();
updateComputedFont();
}
qreal FontManager::fontWidth() const
{
return m_fontWidth;
}
void FontManager::setFontWidth(qreal fontWidth)
{
if (qFuzzyCompare(m_fontWidth, fontWidth)) {
return;
}
m_fontWidth = fontWidth;
emit fontWidthChanged();
updateComputedFont();
}
qreal FontManager::lineSpacing() const
{
return m_lineSpacing;
}
void FontManager::setLineSpacing(qreal lineSpacing)
{
if (qFuzzyCompare(m_lineSpacing, lineSpacing)) {
return;
}
m_lineSpacing = lineSpacing;
emit lineSpacingChanged();
updateComputedFont();
}
qreal FontManager::baseFontScaling() const
{
return m_baseFontScaling;
}
void FontManager::setBaseFontScaling(qreal baseFontScaling)
{
if (qFuzzyCompare(m_baseFontScaling, baseFontScaling)) {
return;
}
m_baseFontScaling = baseFontScaling;
emit baseFontScalingChanged();
updateComputedFont();
}
bool FontManager::lowResolutionFont() const
{
return m_lowResolutionFont;
}
void FontManager::setFontSubstitutions(const QString &family, const QStringList &substitutes)
{
if (family.isEmpty()) {
return;
}
QFont::removeSubstitutions(family);
if (substitutes.isEmpty()) {
return;
}
QFont::insertSubstitutions(family, substitutes);
}
void FontManager::removeFontSubstitution(const QString &family)
{
if (family.isEmpty()) {
return;
}
QFont::removeSubstitutions(family);
}
void FontManager::populateBundledFonts()
{
m_allFonts.clear();
addBundledFont(
"TERMINUS_SCALED",
"Terminus",
":/fonts/terminus/TerminusTTF-4.49.3.ttf",
1.0,
12,
true);
addBundledFont(
"EXCELSIOR_SCALED",
"Fixedsys Excelsior",
":/fonts/fixedsys-excelsior/FSEX301-L2.ttf",
1.0,
16,
true,
"UNSCII_16_SCALED");
addBundledFont(
"GREYBEARD_SCALED",
"Greybeard",
":/fonts/greybeard/Greybeard-16px.ttf",
1.0,
16,
true,
"UNSCII_16_SCALED");
addBundledFont(
"COMMODORE_PET_SCALED",
"Commodore PET",
":/fonts/pet-me/PetMe.ttf",
0.5,
8,
true,
"UNSCII_8_SCALED");
addBundledFont(
"COZETTE_SCALED",
"Cozette",
":/fonts/cozette/CozetteVector.ttf",
1.0,
13,
true);
addBundledFont(
"UNSCII_8_SCALED",
"Unscii 8",
":/fonts/unscii/unscii-8.ttf",
0.5,
8,
true,
"UNSCII_8_SCALED");
addBundledFont(
"UNSCII_8_THIN_SCALED",
"Unscii 8 Thin",
":/fonts/unscii/unscii-8-thin.ttf",
0.5,
8,
true,
"UNSCII_8_SCALED");
addBundledFont(
"UNSCII_16_SCALED",
"Unscii 16",
":/fonts/unscii/unscii-16-full.ttf",
1.0,
16,
true,
"UNSCII_16_SCALED");
addBundledFont(
"APPLE_II_SCALED",
"Apple ][",
":/fonts/apple2/PrintChar21.ttf",
0.5,
8,
true,
"UNSCII_8_SCALED");
addBundledFont(
"ATARI_400_SCALED",
"Atari 400-800",
":/fonts/atari-400-800/AtariClassic-Regular.ttf",
0.5,
8,
true,
"UNSCII_8_SCALED");
addBundledFont(
"COMMODORE_64_SCALED",
"Commodore 64",
":/fonts/pet-me/PetMe64.ttf",
0.5,
8,
true,
"UNSCII_8_SCALED");
addBundledFont(
"IBM_EGA_8x8",
"IBM EGA 8x8",
":/fonts/oldschool-pc-fonts/PxPlus_IBM_EGA_8x8.ttf",
0.5,
8,
true,
"UNSCII_8_SCALED");
addBundledFont(
"IBM_VGA_8x16",
"IBM VGA 8x16",
":/fonts/oldschool-pc-fonts/PxPlus_IBM_VGA_8x16.ttf",
1.0,
16,
true,
"UNSCII_16_SCALED");
addBundledFont(
"TERMINUS",
"Terminus",
":/fonts/terminus/TerminusTTF-4.49.3.ttf",
1.0,
32,
false);
addBundledFont(
"HACK",
"Hack",
":/fonts/hack/Hack-Regular.ttf",
1.0,
32,
false);
addBundledFont(
"FIRA_CODE",
"Fira Code",
":/fonts/fira-code/FiraCode-Medium.ttf",
1.0,
32,
false);
addBundledFont(
"IOSEVKA",
"Iosevka",
":/fonts/iosevka/IosevkaTerm-ExtendedMedium.ttf",
1.0,
32,
false);
addBundledFont(
"JETBRAINS_MONO",
"JetBrains Mono",
":/fonts/jetbrains-mono/JetBrainsMono-Medium.ttf",
1.0,
32,
false);
addBundledFont(
"IBM_3278",
"IBM 3278",
":/fonts/ibm-3278/3270-Regular.ttf",
1.0,
32,
false);
}
void FontManager::addBundledFont(const QString &name,
const QString &text,
const QString &source,
qreal baseWidth,
int pixelSize,
bool lowResolutionFont,
const QString &fallbackName)
{
FontEntry entry;
entry.name = name;
entry.text = text;
entry.source = source;
entry.baseWidth = baseWidth;
entry.pixelSize = pixelSize;
entry.lowResolutionFont = lowResolutionFont;
entry.isSystemFont = false;
entry.fallbackName = fallbackName;
entry.family = resolveFontFamily(source);
m_allFonts.append(entry);
}
void FontManager::populateSystemFonts()
{
const QStringList families = retrieveMonospaceFonts();
for (const QString &family : families) {
if (m_bundledFamilies.contains(family)) {
continue;
}
FontEntry entry;
entry.name = family;
entry.text = family;
entry.source = QString();
entry.baseWidth = 1.0;
entry.pixelSize = kSystemFontPixelSize;
entry.lowResolutionFont = false;
entry.isSystemFont = true;
entry.family = family;
m_allFonts.append(entry);
}
}
void FontManager::updateFilteredFonts()
{
QVector<FontEntry> filtered;
bool fontNameFound = false;
const bool modernMode = (m_rasterization == kModernRasterization);
for (const FontEntry &font : m_allFonts) {
const bool isBundled = !font.isSystemFont;
const bool matchesSource = (m_fontSource == 0 && isBundled)
|| (m_fontSource == 1 && font.isSystemFont);
if (!matchesSource) {
continue;
}
const bool matchesRasterization = font.isSystemFont
|| (modernMode == !font.lowResolutionFont);
if (!matchesRasterization) {
continue;
}
filtered.append(font);
if (font.name == m_fontName) {
fontNameFound = true;
}
}
if (!fontNameFound && !filtered.isEmpty()) {
if (m_fontName != filtered.first().name) {
m_fontName = filtered.first().name;
emit fontNameChanged();
}
}
m_filteredFontListModel.setFonts(filtered);
emit filteredFontListChanged();
}
void FontManager::updateComputedFont()
{
const FontEntry *font = findFontByName(m_fontName);
if (!font) {
const QVector<FontEntry> &filteredFonts = m_filteredFontListModel.fonts();
if (!filteredFonts.isEmpty()) {
font = &filteredFonts.first();
}
}
if (!font) {
return;
}
const qreal totalFontScaling = m_baseFontScaling * m_fontScaling;
const qreal targetPixelHeight = kBaseFontPixelHeight * totalFontScaling;
const qreal lineSpacingFactor = m_lineSpacing;
const int lineSpacing = qRound(targetPixelHeight * lineSpacingFactor);
const int pixelSize = font->lowResolutionFont
? font->pixelSize
: static_cast<int>(targetPixelHeight);
const qreal nativeLineHeight = font->pixelSize + qRound(font->pixelSize * lineSpacingFactor);
const qreal targetLineHeight = targetPixelHeight + lineSpacing;
const qreal screenScaling = font->lowResolutionFont
? (nativeLineHeight > 0 ? targetLineHeight / nativeLineHeight : 1.0)
: 1.0;
const qreal fontWidth = font->baseWidth * m_fontWidth;
QString fontFamily = font->family.isEmpty() ? font->name : font->family;
QString fallbackFontFamily;
if (!font->fallbackName.isEmpty() && font->fallbackName != font->name) {
const FontEntry *fallback = findFontByName(font->fallbackName);
if (fallback) {
fallbackFontFamily = fallback->family.isEmpty() ? fallback->name : fallback->family;
}
}
QStringList fallbackChain;
if (!fallbackFontFamily.isEmpty()) {
fallbackChain.append(fallbackFontFamily);
}
#if defined(Q_OS_MAC)
fallbackChain.append(QStringLiteral("Menlo"));
#else
fallbackChain.append(QStringLiteral("Monospace"));
#endif
setFontSubstitutions(fontFamily, fallbackChain);
if (m_lowResolutionFont != font->lowResolutionFont) {
m_lowResolutionFont = font->lowResolutionFont;
emit lowResolutionFontChanged();
}
emit terminalFontChanged(fontFamily,
pixelSize,
lineSpacing,
screenScaling,
fontWidth,
fallbackFontFamily,
font->lowResolutionFont);
}
const FontEntry *FontManager::findFontByName(const QString &name) const
{
for (const FontEntry &font : m_allFonts) {
if (font.name == name) {
return &font;
}
}
return nullptr;
}
QString FontManager::resolveFontFamily(const QString &sourcePath)
{
const auto cached = m_loadedFamilies.constFind(sourcePath);
if (cached != m_loadedFamilies.constEnd()) {
return cached.value();
}
const int fontId = QFontDatabase::addApplicationFont(sourcePath);
QString family;
if (fontId != -1) {
const QStringList families = QFontDatabase::applicationFontFamilies(fontId);
if (!families.isEmpty()) {
family = families.first();
}
}
if (!family.isEmpty()) {
m_bundledFamilies.insert(family);
}
m_loadedFamilies.insert(sourcePath, family);
return family;
}

110
app/fontmanager.h Normal file
View File

@@ -0,0 +1,110 @@
#ifndef FONTMANAGER_H
#define FONTMANAGER_H
#include <QObject>
#include <QStringList>
#include <QHash>
#include <QSet>
#include "fontlistmodel.h"
class FontManager : public QObject
{
Q_OBJECT
Q_PROPERTY(FontListModel *fontList READ fontList CONSTANT)
Q_PROPERTY(FontListModel *filteredFontList READ filteredFontList NOTIFY filteredFontListChanged)
Q_PROPERTY(int fontSource READ fontSource WRITE setFontSource NOTIFY fontSourceChanged)
Q_PROPERTY(int rasterization READ rasterization WRITE setRasterization NOTIFY rasterizationChanged)
Q_PROPERTY(QString fontName READ fontName WRITE setFontName NOTIFY fontNameChanged)
Q_PROPERTY(qreal fontScaling READ fontScaling WRITE setFontScaling NOTIFY fontScalingChanged)
Q_PROPERTY(qreal fontWidth READ fontWidth WRITE setFontWidth NOTIFY fontWidthChanged)
Q_PROPERTY(qreal lineSpacing READ lineSpacing WRITE setLineSpacing NOTIFY lineSpacingChanged)
Q_PROPERTY(qreal baseFontScaling READ baseFontScaling WRITE setBaseFontScaling NOTIFY baseFontScalingChanged)
Q_PROPERTY(bool lowResolutionFont READ lowResolutionFont NOTIFY lowResolutionFontChanged)
public:
explicit FontManager(QObject *parent = nullptr);
Q_INVOKABLE void refresh();
FontListModel *fontList();
FontListModel *filteredFontList();
int fontSource() const;
void setFontSource(int fontSource);
int rasterization() const;
void setRasterization(int rasterization);
QString fontName() const;
void setFontName(const QString &fontName);
qreal fontScaling() const;
void setFontScaling(qreal fontScaling);
qreal fontWidth() const;
void setFontWidth(qreal fontWidth);
qreal lineSpacing() const;
void setLineSpacing(qreal lineSpacing);
qreal baseFontScaling() const;
void setBaseFontScaling(qreal baseFontScaling);
bool lowResolutionFont() const;
signals:
void fontSourceChanged();
void rasterizationChanged();
void fontNameChanged();
void fontScalingChanged();
void fontWidthChanged();
void lineSpacingChanged();
void baseFontScalingChanged();
void lowResolutionFontChanged();
void filteredFontListChanged();
void terminalFontChanged(QString fontFamily,
int pixelSize,
int lineSpacing,
qreal screenScaling,
qreal fontWidth,
QString fallbackFontFamily,
bool lowResolutionFont);
private:
QStringList retrieveMonospaceFonts();
void populateBundledFonts();
void populateSystemFonts();
void addBundledFont(const QString &name,
const QString &text,
const QString &source,
qreal baseWidth,
int pixelSize,
bool lowResolutionFont,
const QString &fallbackName = QString());
void setFontSubstitutions(const QString &family, const QStringList &substitutes);
void removeFontSubstitution(const QString &family);
void updateFilteredFonts();
void updateComputedFont();
const FontEntry *findFontByName(const QString &name) const;
QString resolveFontFamily(const QString &sourcePath);
FontListModel m_fontListModel;
FontListModel m_filteredFontListModel;
QVector<FontEntry> m_allFonts;
int m_fontSource = 0;
int m_rasterization = 0;
QString m_fontName = QStringLiteral("TERMINUS_SCALED");
qreal m_fontScaling = 1.0;
qreal m_fontWidth = 1.0;
qreal m_lineSpacing = 0.1;
qreal m_baseFontScaling = 0.75;
bool m_lowResolutionFont = false;
QHash<QString, QString> m_loadedFamilies;
QSet<QString> m_bundledFamilies;
};
#endif // FONTMANAGER_H

View File

@@ -7,17 +7,18 @@
#include <QtWidgets/QApplication>
#include <QIcon>
#include <QQuickStyle>
#include <QtQml/qqml.h>
#include <kdsingleapplication.h>
#include <QDebug>
#include <stdlib.h>
#include <QFontDatabase>
#include <QLoggingCategory>
#include <fileio.h>
#include <monospacefontmanager.h>
#include <fontlistmodel.h>
#include <fontmanager.h>
#if defined(Q_OS_MAC)
#include <CoreFoundation/CoreFoundation.h>
@@ -97,7 +98,9 @@ int main(int argc, char *argv[])
QQmlApplicationEngine engine;
FileIO fileIO;
MonospaceFontManager monospaceFontManager;
qmlRegisterType<FontManager>("CoolRetroTerm", 1, 0, "FontManager");
qmlRegisterUncreatableType<FontListModel>("CoolRetroTerm", 1, 0, "FontListModel", "FontListModel is created by FontManager");
#if !defined(Q_OS_MAC)
app.setWindowIcon(QIcon::fromTheme("cool-retro-term", QIcon(":../icons/32x32/cool-retro-term.png")));
@@ -124,8 +127,6 @@ int main(int argc, char *argv[])
engine.rootContext()->setContextProperty("workdir", getNamedArgument(args, "--workdir", "$HOME"));
engine.rootContext()->setContextProperty("fileIO", &fileIO);
engine.rootContext()->setContextProperty("monospaceFontManager", &monospaceFontManager);
engine.rootContext()->setContextProperty("monospaceSystemFonts", monospaceFontManager.retrieveMonospaceFonts());
// Manage import paths for Linux and OSX.
QStringList importPathList = engine.importPathList();

View File

@@ -1,50 +0,0 @@
#include "monospacefontmanager.h"
#include <QDebug>
#include <QFont>
MonospaceFontManager::MonospaceFontManager(QObject *parent) : QObject(parent)
{
}
QStringList MonospaceFontManager::retrieveMonospaceFonts() {
QStringList result;
QFontDatabase fontDatabase;
QStringList fontFamilies = fontDatabase.families();
for (int i = 0; i < fontFamilies.size(); i++) {
QString fontFamily = fontFamilies[i];
QFont font(fontFamily);
if (fontDatabase.isFixedPitch(font.family())) {
result.append(fontFamily);
}
}
return result;
}
void MonospaceFontManager::setFontSubstitutions(const QString &family, const QStringList &substitutes)
{
if (family.isEmpty()) {
return;
}
QFont::removeSubstitutions(family);
if (substitutes.isEmpty()) {
return;
}
QFont::insertSubstitutions(family, substitutes);
}
void MonospaceFontManager::removeFontSubstitution(const QString &family)
{
if (family.isEmpty()) {
return;
}
QFont::removeSubstitutions(family);
}

View File

@@ -1,20 +0,0 @@
#ifndef MONOSPACEFONTMANAGER_H
#define MONOSPACEFONTMANAGER_H
#include <QObject>
#include <QFontDatabase>
#include <QStringList>
class MonospaceFontManager : public QObject
{
Q_OBJECT
public:
explicit MonospaceFontManager(QObject *parent = nullptr);
Q_INVOKABLE QStringList retrieveMonospaceFonts();
public slots:
Q_INVOKABLE void setFontSubstitutions(const QString &family, const QStringList &substitutes);
void removeFontSubstitution(const QString &family);
};
#endif // MONOSPACEFONTMANAGER_H

View File

@@ -19,6 +19,7 @@
*******************************************************************************/
import QtQuick 2.2
import QtQuick.Controls 2.0
import CoolRetroTerm 1.0
import "utils.js" as Utils
@@ -60,7 +61,6 @@ QtObject {
property bool blinkingCursor: false
onWindowScalingChanged: updateFont()
// PROFILE SETTINGS ///////////////////////////////////////////////////////
property real windowOpacity: 1.0
@@ -113,133 +113,33 @@ QtObject {
readonly property int subpixel_rasterization: 3
readonly property int modern_rasterization: 4
property int rasterization: no_rasterization
property alias rasterization: fontManager.rasterization
readonly property int bundled_fonts: 0
readonly property int system_fonts: 1
property int fontSource: bundled_fonts
property alias fontSource: fontManager.fontSource
// FONTS //////////////////////////////////////////////////////////////////
readonly property real baseFontScaling: 0.75
property real fontScaling: 1.0
property alias fontScaling: fontManager.fontScaling
property real totalFontScaling: baseFontScaling * fontScaling
property real fontWidth: 1.0
property real lineSpacing: 0.1
property alias fontWidth: fontManager.fontWidth
property alias lineSpacing: fontManager.lineSpacing
property bool lowResolutionFont: false
property alias lowResolutionFont: fontManager.lowResolutionFont
property string fontName: "TERMINUS_SCALED"
property var fontlist: fontManager.item ? fontManager.item.fontlist : null
property alias fontName: fontManager.fontName
property alias filteredFontList: fontManager.filteredFontList
property var filteredFontList: ListModel {}
function updateFont() {
if (!fontManager.item || !fontlist) return
filteredFontList.clear()
var currentFontInList = false
for (var i = 0; i < fontlist.count; i++) {
var font = fontlist.get(i)
var isBundled = !font.isSystemFont
var isSystem = font.isSystemFont
var matchesSource = (fontSource === bundled_fonts && isBundled) || (fontSource === system_fonts && isSystem)
if (!matchesSource) continue
var modernMode = rasterization === modern_rasterization
var matchesRasterization = font.isSystemFont || (modernMode == !font.lowResolutionFont)
if (matchesRasterization) {
filteredFontList.append(font)
if (font.name === fontName) {
currentFontInList = true
}
}
}
if (!currentFontInList && filteredFontList.count > 0) {
fontName = filteredFontList.get(0).name
}
var index = getIndexByName(fontName)
if (index === undefined) return
fontManager.item.selectedFontIndex = index
fontManager.item.scaling = totalFontScaling
var fontSourcePath = fontManager.item.source
var pixelSize = fontManager.item.pixelSize
var lineSpacing = fontManager.item.lineSpacing
var screenScaling = fontManager.item.screenScaling
var fontWidth = (fontManager.item.baseWidth ?? 1.0) * appSettings.fontWidth
var fontFamily = fontManager.item.family
var isSystemFont = fontManager.item.isSystemFont
var lowResolutionFont = fontManager.item.lowResolutionFont;
var fallbackFontFamily = ""
appSettings.lowResolutionFont = fontManager.item.lowResolutionFont
if (!isSystemFont) {
fontLoader.source = fontSourcePath
fontFamily = fontLoader.name
}
fallbackFontLoader.source = ""
var fallbackName = fontManager.item.fallbackName
if (fallbackName && fallbackName !== fontName) {
var fallbackFont = getFontByName(fallbackName)
if (fallbackFont) {
fallbackFontLoader.source = fallbackFont.source
fallbackFontFamily = fallbackFontLoader.name
}
}
terminalFontChanged(fontFamily, pixelSize, lineSpacing, screenScaling, fontWidth, fallbackFontFamily, lowResolutionFont)
property FontManager fontManager: FontManager {
id: fontManager
baseFontScaling: baseFontScaling
}
onFontSourceChanged: updateFont()
onRasterizationChanged: updateFont()
onFontNameChanged: updateFont()
signal terminalFontChanged(string fontFamily, int pixelSize, int lineSpacing, real screenScaling, real fontWidth, string fallbackFontFamily, bool lowResolutionFont)
signal initializedSettings
property Loader fontManager: Loader {
source: "Fonts.qml"
onLoaded: updateFont()
}
property FontLoader fontLoader: FontLoader {}
property FontLoader fallbackFontLoader: FontLoader {}
onTotalFontScalingChanged: updateFont()
onFontWidthChanged: updateFont()
onLineSpacingChanged: updateFont()
function getIndexByName(name) {
for (var i = 0; i < fontlist.count; i++) {
var requestedName = fontlist.get(i).name
if (name === requestedName)
return i
}
return 0 // If the font is not available default to 0.
}
function getFontByName(name) {
for (var i = 0; i < fontlist.count; i++) {
var font = fontlist.get(i)
if (name === font.name) {
return font
}
}
return null
}
function incrementScaling() {
fontScaling = Math.min(fontScaling + 0.05, maximumFontScaling)
}

View File

@@ -81,6 +81,14 @@ Loader {
}
}
// Restart blurred source settings change.
Connections {
target: appSettings.fontManager
onTerminalFontChanged: {
burnInEffect.restartBlurSource()
}
}
Connections {
target: appSettings
@@ -88,10 +96,6 @@ Loader {
burnInEffect.restartBlurSource()
}
onTerminalFontChanged: {
burnInEffect.restartBlurSource()
}
onRasterizationChanged: {
burnInEffect.restartBlurSource()
}

View File

@@ -148,29 +148,24 @@ Item{
}
function handleFontChanged(fontFamily, pixelSize, lineSpacing, screenScaling, fontWidth, fallbackFontFamily, lowResolutionFont) {
var updatedFont = Qt.font({
kterminal.font = Qt.font({
family: fontFamily,
pixelSize: pixelSize
});
if (!updatedFont) {
return;
}
kterminal.font = updatedFont;
terminalContainer.fontWidth = fontWidth;
terminalContainer.screenScaling = screenScaling;
scaleTexture = Math.max(1.0, Math.floor(screenScaling * appSettings.windowScaling));
kterminal.lineSpacing = lineSpacing;
}
var fallbackChain = [];
if (fallbackFontFamily && fallbackFontFamily.length > 0) {
fallbackChain.push(fallbackFontFamily);
Connections {
target: appSettings
onWindowScalingChanged: {
scaleTexture = Math.max(1.0, Math.floor(terminalContainer.screenScaling * appSettings.windowScaling));
}
fallbackChain.push(appSettings.isMacOS ? "Menlo" : "Monospace");
monospaceFontManager.setFontSubstitutions(fontFamily, fallbackChain);
}
function startSession() {
@@ -194,8 +189,8 @@ Item{
forceActiveFocus();
}
Component.onCompleted: {
appSettings.terminalFontChanged.connect(handleFontChanged);
appSettings.updateFont()
appSettings.fontManager.terminalFontChanged.connect(handleFontChanged);
appSettings.fontManager.refresh()
startSession();
}
}

View File

@@ -104,7 +104,7 @@ ColumnLayout {
currentIndex = 0
}
Connections {
target: appSettings
target: appSettings.fontManager
onTerminalFontChanged: {
fontChanger.updateIndex()

View File

@@ -6,7 +6,6 @@
<file>ApplicationSettings.qml</file>
<file>SettingsWindow.qml</file>
<file>TerminalWindow.qml</file>
<file>Fonts.qml</file>
<file>SettingsGeneralTab.qml</file>
<file>PreprocessedTerminal.qml</file>
<file>TimeManager.qml</file>