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

Merge pull request #911 from Swordfish90/feature/qt6

Migrate to Qt6
This commit is contained in:
Filippo Scognamiglio
2026-01-19 01:39:05 +01:00
committed by GitHub
230 changed files with 3812 additions and 2181 deletions

View File

@@ -1,98 +0,0 @@
name: "ci"
on:
push:
tags: "**"
workflow_dispatch:
defaults:
run:
shell: bash
jobs:
appimage:
runs-on: ubuntu-18.04
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
submodules: true
- name: Install dependencies
run: |
sudo add-apt-repository -y ppa:beineri/opt-qt-5.15.2-bionic
sudo apt-get update -qq
sudo apt-get install -y \
build-essential make wget libgl1-mesa-dev \
qt515declarative qt515graphicaleffects \
qt515quickcontrols qt515quickcontrols2
- name: Download QT appimage builder
run: |
wget -c -O linuxdeployqt.AppImage \
https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage
chmod a+x linuxdeployqt.AppImage
- name: Build project
run: |
source /opt/qt*/bin/qt*-env.sh && \
qmake -v && \
qmake CONFIG+=release PREFIX=/usr && \
make -j$(nproc)
- name: Install to appdir
run: |
source /opt/qt*/bin/qt*-env.sh && \
make INSTALL_ROOT=appdir -j$(nproc) install
- name: Extract version number
run: |
# Extract version for linuxdeployqt to name the file. Use the tag as
# release name but remove prefix.
echo "VERSION=$(echo '${{ github.ref }}' | sed 's;.*/;;')" >> $GITHUB_ENV
- name: Build appimage directory
run: |
mkdir -p \
appdir/usr/bin \
appdir/usr/lib \
appdir/usr/share/applications \
appdir/usr/share/metainfo \
appdir/usr/share/icons/hicolor/128x128/apps
cp cool-retro-term appdir/usr/bin/
cp cool-retro-term.desktop appdir/usr/share/applications/
cp packaging/appdata/cool-retro-term.appdata.xml appdir/usr/share/metainfo/
cp app/icons/128x128/cool-retro-term.png appdir/usr/share/icons/hicolor/128x128/apps/
cp -r ./app/qml appdir/usr/
# Workaround for https://github.com/probonopd/linuxdeployqt/issues/78
cp -r ./qmltermwidget/QMLTermWidget appdir/usr/qml/
find appdir | sort
- name: Build appimage
run: |
source /opt/qt*/bin/qt*-env.sh && \
./linuxdeployqt.AppImage appdir/usr/share/applications/cool-retro-term.desktop \
-verbose=1 -appimage \
-qmldir=./app/qml/ \
-qmldir=./qmltermwidget/
env:
# Unset environment variables
QTDIR:
QT_PLUGIN_PATH:
LD_LIBRARY_PATH:
- name: Upload release
uses: softprops/action-gh-release@v1
with:
body: appimage release
files: ./**/Cool_Retro_Term-*-x86_64.AppImage
- name: Clean up
if: always()
run: |
find appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq
make clean
rm -rf appdir

54
.github/workflows/build-appimage.yml vendored Normal file
View File

@@ -0,0 +1,54 @@
name: Build AppImage
on:
workflow_dispatch:
push:
branches:
- main
pull_request:
jobs:
build-appimage:
name: Build (Linux, AppImage)
runs-on: ubuntu-22.04
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install build deps
run: |
sudo apt update
sudo apt install -y build-essential rsync wget
- name: Install Qt
uses: jurplel/install-qt-action@v4
with:
version: 6.10.0
dir: ..
modules: qtshadertools
setup-python: false
cache: true
- name: Build AppImage
run: |
./scripts/build-appimage.sh
- name: Collect artifact
run: |
mkdir -p release
mv ./*.AppImage release/
- name: Attestation
uses: actions/attest-build-provenance@v1
with:
subject-path: ./release/*
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: cool-retro-term-appimage
path: ./release/*

50
.github/workflows/build-dmg.yml vendored Normal file
View File

@@ -0,0 +1,50 @@
name: Build DMG
on:
workflow_dispatch:
push:
branches:
- main
pull_request:
jobs:
build-dmg:
name: Build (macOS, DMG)
runs-on: macos-14
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install Qt
uses: jurplel/install-qt-action@v4
with:
version: 6.10.*
modules: qtshadertools
setup-python: true
python-version: '3.11'
cache: true
- name: Build DMG
run: |
JOBS="$(sysctl -n hw.ncpu)"
./scripts/build-dmg.sh
- name: Collect artifact
run: |
mkdir -p release
mv ./*.dmg release/
- name: Attestation
uses: actions/attest-build-provenance@v1
with:
subject-path: ./release/*
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: cool-retro-term-dmg
path: ./release/*

7
.gitignore vendored
View File

@@ -41,10 +41,17 @@ Makefile*
*.json *.json
# Excludes compiled files # Excludes compiled files
imports imports
cool-retro-term cool-retro-term
build
# Linux
*.AppImage
# Mac OSX # Mac OSX
.DS_Store .DS_Store
*.app *.app
*.dmg

3
.gitmodules vendored
View File

@@ -2,3 +2,6 @@
path = qmltermwidget path = qmltermwidget
url = https://github.com/Swordfish90/qmltermwidget url = https://github.com/Swordfish90/qmltermwidget
branch = unstable branch = unstable
[submodule "KDSingleApplication"]
path = KDSingleApplication
url = https://github.com/KDAB/KDSingleApplication.git

View File

@@ -1,37 +0,0 @@
sudo: required
dist: trusty
language: c++
install:
- sudo add-apt-repository -y ppa:beineri/opt-qt58-trusty
- sudo apt-get update -qq
- sudo apt-get -y install build-essential qt58declarative qt58graphicaleffects qt58quickcontrols libgl1-mesa-dev
- source /opt/qt*/bin/qt*-env.sh
script:
- qmake CONFIG+=release PREFIX=/usr
- make -j$(nproc)
- mkdir -p appdir/usr/share/metainfo appdir/usr/bin
- cp packaging/appdata/cool-retro-term.appdata.xml appdir/usr/share/metainfo/
- cp cool-retro-term appdir/usr/bin/
- cp ./cool-retro-term.desktop appdir/
- cp ./app/icons/128x128/cool-retro-term.png appdir/
- cp -r ./app/qml appdir/usr/
- cp -r ./qmltermwidget/QMLTermWidget appdir/usr/qml/ # Workaround for https://github.com/probonopd/linuxdeployqt/issues/78
- wget -c https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage
- chmod a+x linuxdeployqt-*.AppImage
- unset QTDIR; unset QT_PLUGIN_PATH ; unset LD_LIBRARY_PATH
- export VERSION=$(git rev-parse --short HEAD) # linuxdeployqt uses this for naming the file
- ./linuxdeployqt-*.AppImage appdir/usr/bin/cool-retro-term -qmldir=./app/qml/ -qmldir=./qmltermwidget/ # -verbose=3 2>&1 | grep "path:" -C 3
- ./linuxdeployqt-*.AppImage appdir/usr/bin/cool-retro-term -qmldir=./app/qml/ -qmldir=./qmltermwidget/ -verbose=2 -appimage
after_success:
- find appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq
- # curl --upload-file Cool*.AppImage https://transfer.sh/Cool_Retro_Term-git.$(git rev-parse --short HEAD)-x86_64.AppImage
- wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh
- bash upload.sh Cool*.AppImage*
branches:
except:
- # Do not build tags that we create when we upload to GitHub Releases
- /^(?i:continuous)/

1
KDSingleApplication Submodule

Submodule KDSingleApplication added at 1848dd64e8

View File

@@ -10,7 +10,7 @@ It has been designed to be eye-candy, customizable, and reasonably lightweight.
It uses the QML port of qtermwidget (Konsole): https://github.com/Swordfish90/qmltermwidget. It uses the QML port of qtermwidget (Konsole): https://github.com/Swordfish90/qmltermwidget.
This terminal emulator works under Linux and macOS and requires Qt5. It's suggested that you stick to the latest LTS version. This terminal emulator works under Linux and macOS and requires Qt6.
Settings such as colors, fonts, and effects can be accessed via context menu. Settings such as colors, fonts, and effects can be accessed via context menu.

View File

@@ -1,20 +1,99 @@
QT += qml quick widgets sql quickcontrols2 QT += qml quick widgets sql quickcontrols2
TARGET = cool-retro-term TARGET = cool-retro-term
APP_VERSION = $$system(git -C $$PWD/.. describe --tags --always --dirty=-dirty)
isEmpty(APP_VERSION): APP_VERSION = "unknown"
DEFINES += APP_VERSION=\\\"$$APP_VERSION\\\"
# TODO: When migrating to CMake, use KDSingleApplication's CMakeLists.txt instead of these manual sources.
INCLUDEPATH += $$PWD/../KDSingleApplication/src
HEADERS += \
$$PWD/../KDSingleApplication/src/kdsingleapplication.h \
$$PWD/../KDSingleApplication/src/kdsingleapplication_lib.h \
$$PWD/../KDSingleApplication/src/kdsingleapplication_localsocket_p.h
SOURCES += \
$$PWD/../KDSingleApplication/src/kdsingleapplication.cpp \
$$PWD/../KDSingleApplication/src/kdsingleapplication_localsocket.cpp
DEFINES += KDSINGLEAPPLICATION_STATIC_BUILD
DESTDIR = $$OUT_PWD/../ DESTDIR = $$OUT_PWD/../
HEADERS += \ HEADERS += \
fileio.h \ fileio.h \
monospacefontmanager.h fontmanager.h \
fontlistmodel.h
SOURCES = main.cpp \ SOURCES += main.cpp \
fileio.cpp \ fileio.cpp \
monospacefontmanager.cpp fontmanager.cpp \
fontlistmodel.cpp
macx:ICON = icons/crt.icns macx:ICON = icons/crt.icns
RESOURCES += qml/resources.qrc RESOURCES += qml/resources.qrc
# Shader compilation (Qt Shader Baker)
QSB_BIN = $$[QT_HOST_BINS]/qsb
isEmpty(QSB_BIN): QSB_BIN = $$[QT_INSTALL_BINS]/qsb
SHADERS_DIR = $${_PRO_FILE_PWD_}/shaders
SHADERS += $$files($$SHADERS_DIR/*.frag) $$files($$SHADERS_DIR/*.vert)
SHADERS -= $$SHADERS_DIR/terminal_dynamic.frag
SHADERS -= $$SHADERS_DIR/terminal_static.frag
SHADERS -= $$SHADERS_DIR/passthrough.vert
qsb.input = SHADERS
qsb.output = ../../app/shaders/${QMAKE_FILE_NAME}.qsb
qsb.commands = $$QSB_BIN --glsl \"100 es,120,150\" --hlsl 50 --msl 12 --qt6 -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
qsb.clean = $$qsb.output
qsb.name = qsb ${QMAKE_FILE_IN}
qsb.variable_out = QSB_FILES
QMAKE_EXTRA_COMPILERS += qsb
PRE_TARGETDEPS += $$QSB_FILES
OTHER_FILES += $$SHADERS $$QSB_FILES
DYNAMIC_SHADER = $$SHADERS_DIR/terminal_dynamic.frag
STATIC_SHADER = $$SHADERS_DIR/terminal_static.frag
RASTER_MODES = 0 1 2 3 4
BINARY_FLAGS = 0 1
VARIANT_SHADER_DIR = $$relative_path($$PWD/shaders, $$OUT_PWD)
VARIANT_OUTPUTS =
for(raster_mode, RASTER_MODES) {
for(burn_in, BINARY_FLAGS) {
for(display_frame, BINARY_FLAGS) {
for(chroma_on, BINARY_FLAGS) {
dynamic_variant = terminal_dynamic_raster$${raster_mode}_burn$${burn_in}_frame$${display_frame}_chroma$${chroma_on}
dynamic_output = $${VARIANT_SHADER_DIR}/$${dynamic_variant}.frag.qsb
dynamic_target = shader_variant_$${dynamic_variant}
$${dynamic_target}.target = $${dynamic_output}
$${dynamic_target}.depends = $$DYNAMIC_SHADER
$${dynamic_target}.commands = $$QSB_BIN --glsl \"100 es,120,150\" --hlsl 50 --msl 12 --qt6 -DCRT_RASTER_MODE=$${raster_mode} -DCRT_BURN_IN=$${burn_in} -DCRT_DISPLAY_FRAME=$${display_frame} -DCRT_CHROMA=$${chroma_on} -o $${dynamic_output} $$DYNAMIC_SHADER
QMAKE_EXTRA_TARGETS += $${dynamic_target}
VARIANT_OUTPUTS += $${dynamic_output}
}
}
}
}
for(rgb_shift, BINARY_FLAGS) {
for(bloom_on, BINARY_FLAGS) {
for(curve_on, BINARY_FLAGS) {
for(shine_on, BINARY_FLAGS) {
static_variant = terminal_static_rgb$${rgb_shift}_bloom$${bloom_on}_curve$${curve_on}_shine$${shine_on}
static_output = $${VARIANT_SHADER_DIR}/$${static_variant}.frag.qsb
static_target = shader_variant_$${static_variant}
$${static_target}.target = $${static_output}
$${static_target}.depends = $$STATIC_SHADER
$${static_target}.commands = $$QSB_BIN --glsl \"100 es,120,150\" --hlsl 50 --msl 12 --qt6 -DCRT_RGB_SHIFT=$${rgb_shift} -DCRT_BLOOM=$${bloom_on} -DCRT_CURVATURE=$${curve_on} -DCRT_FRAME_SHININESS=$${shine_on} -o $${static_output} $$STATIC_SHADER
QMAKE_EXTRA_TARGETS += $${static_target}
VARIANT_OUTPUTS += $${static_output}
}
}
}
}
PRE_TARGETDEPS += $${VARIANT_OUTPUTS}
######################################### #########################################
## INTALLS ## INTALLS
######################################### #########################################

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

584
app/fontmanager.cpp Normal file
View File

@@ -0,0 +1,584 @@
#include "fontmanager.h"
#include <QFont>
#include <QFontDatabase>
#include <QFontMetricsF>
#include <QtGlobal>
#include <QtMath>
namespace {
constexpr int kModernRasterization = 4;
constexpr int kBaseFontPixelHeight = 32;
constexpr int kSystemFontPixelSize = 32;
}
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(
"TERMINESS_SCALED",
"Terminess",
":/fonts/terminus/TerminessNerdFontMono-Regular.ttf",
1.0,
12,
true);
addBundledFont(
"BIGBLUE_TERMINAL_SCALED",
"BigBlue Terminal",
":/fonts/bigblue-terminal/BigBlueTerm437NerdFontMono-Regular.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(
"GOHU_11_SCALED",
"Gohu 11",
":/fonts/gohu/GohuFont11NerdFontMono-Regular.ttf",
1.0,
11,
true);
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(
"TERMINESS",
"Terminess",
":/fonts/terminus/TerminessNerdFontMono-Regular.ttf",
1.0,
32,
false);
addBundledFont(
"HACK",
"Hack",
":/fonts/hack/HackNerdFontMono-Regular.ttf",
1.0,
32,
false);
addBundledFont(
"FIRA_CODE",
"Fira Code",
":/fonts/fira-code/FiraCodeNerdFontMono-Regular.ttf",
1.0,
32,
false);
addBundledFont(
"IOSEVKA",
"Iosevka",
":/fonts/iosevka/IosevkaTermNerdFontMono-Regular.ttf",
1.0,
32,
false);
addBundledFont(
"JETBRAINS_MONO",
"JetBrains Mono",
":/fonts/jetbrains-mono/JetBrainsMonoNerdFontMono-Regular.ttf",
1.0,
32,
false);
addBundledFont(
"IBM_3278",
"IBM 3278",
":/fonts/ibm-3278/3270NerdFontMono-Regular.ttf",
1.0,
32,
false);
addBundledFont(
"SOURCE_CODE_PRO",
"Source Code Pro",
":/fonts/source-code-pro/SauceCodeProNerdFontMono-Regular.ttf",
1.0,
32,
false);
addBundledFont(
"DEPARTURE_MONO_SCALED",
"Departure Mono",
":/fonts/departure-mono/DepartureMonoNerdFontMono-Regular.otf",
1.0,
11,
true);
addBundledFont(
"OPENDYSLEXIC",
"OpenDyslexic",
":/fonts/opendyslexic/OpenDyslexicMNerdFontMono-Regular.otf",
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.pixelSize = pixelSize;
entry.lowResolutionFont = lowResolutionFont;
entry.isSystemFont = false;
entry.fallbackName = fallbackName;
entry.family = resolveFontFamily(source);
entry.baseWidth = lowResolutionFont
? computeBaseWidth(entry.family, pixelSize, baseWidth)
: baseWidth;
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;
}
qreal FontManager::computeBaseWidth(const QString &family, int pixelSize, qreal fallbackWidth) const
{
if (family.isEmpty()) {
return fallbackWidth;
}
QFont font(family);
font.setPixelSize(pixelSize);
QFontMetricsF metrics(font);
const qreal glyphWidth = metrics.horizontalAdvance(QLatin1String("M"));
const qreal glyphHeight = metrics.height();
if (glyphWidth <= 0.0 || glyphHeight <= 0.0) {
return fallbackWidth;
}
const qreal targetRatio = 0.5;
qreal computedWidth = (targetRatio * glyphHeight) / glyphWidth;
return qBound(0.25, computedWidth, 2.0);
}

111
app/fontmanager.h Normal file
View File

@@ -0,0 +1,111 @@
#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);
qreal computeBaseWidth(const QString &family, int pixelSize, qreal fallbackWidth) const;
FontListModel m_fontListModel;
FontListModel m_filteredFontListModel;
QVector<FontEntry> m_allFonts;
int m_fontSource = 0;
int m_rasterization = 0;
QString m_fontName = QStringLiteral("TERMINESS_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,15 +7,24 @@
#include <QtWidgets/QApplication> #include <QtWidgets/QApplication>
#include <QIcon> #include <QIcon>
#include <QQuickStyle> #include <QQuickStyle>
#include <QtQml/qqml.h>
#include <kdsingleapplication.h>
#include <QDebug> #include <QDebug>
#include <stdlib.h> #include <stdlib.h>
#include <QFontDatabase>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <fileio.h> #include <fileio.h>
#include <monospacefontmanager.h> #include <fontlistmodel.h>
#include <fontmanager.h>
#if defined(Q_OS_MAC)
#include <CoreFoundation/CoreFoundation.h>
#include <QStyleFactory>
#include <QMenu>
#endif
QString getNamedArgument(QStringList args, QString name, QString defaultName) QString getNamedArgument(QStringList args, QString name, QString defaultName)
{ {
@@ -31,60 +40,77 @@ QString getNamedArgument(QStringList args, QString name)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
// Some environmental variable are necessary on certain platforms. // Some environmental variable are necessary on certain platforms.
// This disables QT appmenu under Ubuntu, which is not working with QML apps.
setenv("QT_QPA_PLATFORMTHEME", "", 1);
// Disable Connections slot warnings // Disable Connections slot warnings
QLoggingCategory::setFilterRules("qt.qml.connections.warning=false"); QLoggingCategory::setFilterRules("qt.qml.connections.warning=false");
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Round);
#if defined (Q_OS_LINUX) // #if defined (Q_OS_LINUX)
setenv("QSG_RENDER_LOOP", "threaded", 0); // setenv("QSG_RENDER_LOOP", "threaded", 0);
#endif // #endif
#if defined(Q_OS_MAC) #if defined(Q_OS_MAC)
// This allows UTF-8 characters usage in OSX. // This allows UTF-8 characters usage in OSX.
setenv("LC_CTYPE", "UTF-8", 1); setenv("LC_CTYPE", "UTF-8", 1);
// Ensure key repeat works for letter keys (disable macOS press-and-hold for this app).
CFPreferencesSetAppValue(CFSTR("ApplePressAndHoldEnabled"), kCFBooleanFalse, kCFPreferencesCurrentApplication);
CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
// Qt6 macOS default look is still lacking, so let's force Fusion for now
QQuickStyle::setStyle(QStringLiteral("Fusion"));
#endif #endif
if (argc>1 && (!strcmp(argv[1],"-h") || !strcmp(argv[1],"--help"))) { if (argc>1 && (!strcmp(argv[1],"-h") || !strcmp(argv[1],"--help"))) {
QTextStream cout(stdout, QIODevice::WriteOnly); QTextStream cout(stdout, QIODevice::WriteOnly);
cout << "Usage: " << argv[0] << " [--default-settings] [--workdir <dir>] [--program <prog>] [-p|--profile <prof>] [--fullscreen] [-h|--help]" << endl; cout << "Usage: " << argv[0] << " [--default-settings] [--workdir <dir>] [--program <prog>] [-p|--profile <prof>] [--fullscreen] [-h|--help]" << Qt::endl;
cout << " --default-settings Run cool-retro-term with the default settings" << endl; cout << " --default-settings Run cool-retro-term with the default settings" << Qt::endl;
cout << " --workdir <dir> Change working directory to 'dir'" << endl; cout << " --workdir <dir> Change working directory to 'dir'" << Qt::endl;
cout << " -e <cmd> Command to execute. This option will catch all following arguments, so use it as the last option." << endl; cout << " -e <cmd> Command to execute. This option will catch all following arguments, so use it as the last option." << Qt::endl;
cout << " -T <title> Set window title to 'title'." << endl; cout << " --fullscreen Run cool-retro-term in fullscreen." << Qt::endl;
cout << " --fullscreen Run cool-retro-term in fullscreen." << endl; cout << " -p|--profile <prof> Run cool-retro-term with the given profile." << Qt::endl;
cout << " -p|--profile <prof> Run cool-retro-term with the given profile." << endl; cout << " -h|--help Print this help." << Qt::endl;
cout << " -h|--help Print this help." << endl; cout << " --verbose Print additional information such as profiles and settings." << Qt::endl;
cout << " --verbose Print additional information such as profiles and settings." << endl;
return 0; return 0;
} }
QString appVersion("1.2.0"); QString appVersion(QStringLiteral(APP_VERSION));
if (argc>1 && (!strcmp(argv[1],"-v") || !strcmp(argv[1],"--version"))) { if (argc>1 && (!strcmp(argv[1],"-v") || !strcmp(argv[1],"--version"))) {
QTextStream cout(stdout, QIODevice::WriteOnly); QTextStream cout(stdout, QIODevice::WriteOnly);
cout << "cool-retro-term " << appVersion << endl; cout << "cool-retro-term " << appVersion << Qt::endl;
return 0; return 0;
} }
QApplication app(argc, argv); QApplication app(argc, argv);
app.setAttribute(Qt::AA_MacDontSwapCtrlAndMeta, true); app.setAttribute(Qt::AA_MacDontSwapCtrlAndMeta, true);
app.setApplicationName(QStringLiteral("cool-retro-term"));
app.setOrganizationName(QStringLiteral("cool-retro-term"));
app.setOrganizationDomain(QStringLiteral("cool-retro-term"));
app.setApplicationVersion(appVersion);
KDSingleApplication singleApp(QStringLiteral("cool-retro-term"));
if (!singleApp.isPrimaryInstance()) {
if (singleApp.sendMessage("new-window"))
return 0;
qWarning() << "KDSingleApplication: primary not reachable, continuing as independent instance.";
}
QQmlApplicationEngine engine; QQmlApplicationEngine engine;
FileIO fileIO; 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) #if !defined(Q_OS_MAC)
app.setWindowIcon(QIcon::fromTheme("cool-retro-term", QIcon(":../icons/32x32/cool-retro-term.png"))); app.setWindowIcon(QIcon::fromTheme("cool-retro-term", QIcon(":../icons/32x32/cool-retro-term.png")));
#if defined(Q_OS_LINUX)
QGuiApplication::setDesktopFileName(QStringLiteral("cool-retro-term"));
#endif
#else #else
app.setWindowIcon(QIcon(":../icons/32x32/cool-retro-term.png")); app.setWindowIcon(QIcon(":../icons/32x32/cool-retro-term.png"));
#endif #endif
app.setOrganizationName("cool-retro-term");
app.setOrganizationDomain("cool-retro-term");
// Manage command line arguments from the cpp side // Manage command line arguments from the cpp side
QStringList args = app.arguments(); QStringList args = app.arguments();
@@ -101,15 +127,12 @@ int main(int argc, char *argv[])
engine.rootContext()->setContextProperty("workdir", getNamedArgument(args, "--workdir", "$HOME")); engine.rootContext()->setContextProperty("workdir", getNamedArgument(args, "--workdir", "$HOME"));
engine.rootContext()->setContextProperty("fileIO", &fileIO); engine.rootContext()->setContextProperty("fileIO", &fileIO);
engine.rootContext()->setContextProperty("monospaceSystemFonts", monospaceFontManager.retrieveMonospaceFonts());
engine.rootContext()->setContextProperty("devicePixelRatio", app.devicePixelRatio());
// Manage import paths for Linux and OSX. // Manage import paths for Linux and OSX.
QStringList importPathList = engine.importPathList(); QStringList importPathList = engine.importPathList();
importPathList.prepend(QCoreApplication::applicationDirPath() + "/qmltermwidget"); importPathList.append(QCoreApplication::applicationDirPath() + "/qmltermwidget");
importPathList.prepend(QCoreApplication::applicationDirPath() + "/../PlugIns"); importPathList.append(QCoreApplication::applicationDirPath() + "/../PlugIns");
importPathList.prepend(QCoreApplication::applicationDirPath() + "/../../../qmltermwidget"); importPathList.append(QCoreApplication::applicationDirPath() + "/../../../qmltermwidget");
engine.setImportPathList(importPathList); engine.setImportPathList(importPathList);
engine.load(QUrl(QStringLiteral ("qrc:/main.qml"))); engine.load(QUrl(QStringLiteral ("qrc:/main.qml")));
@@ -122,5 +145,25 @@ int main(int argc, char *argv[])
// Quit the application when the engine closes. // Quit the application when the engine closes.
QObject::connect((QObject*) &engine, SIGNAL(quit()), (QObject*) &app, SLOT(quit())); QObject::connect((QObject*) &engine, SIGNAL(quit()), (QObject*) &app, SLOT(quit()));
auto requestNewWindow = [&engine]() {
if (engine.rootObjects().isEmpty())
return;
QObject *rootObject = engine.rootObjects().constFirst();
QMetaObject::invokeMethod(rootObject, "createWindow", Qt::QueuedConnection);
};
QObject::connect(&singleApp, &KDSingleApplication::messageReceived, &app,
[&requestNewWindow](const QByteArray &message) {
if (message.isEmpty() || message == QByteArray("new-window"))
requestNewWindow();
});
#if defined(Q_OS_MAC)
QMenu *dockMenu = new QMenu(nullptr);
dockMenu->addAction(QObject::tr("New Window"), [&requestNewWindow]() { requestNewWindow(); });
dockMenu->setAsDockMenu();
#endif
return app.exec(); return app.exec();
} }

View File

@@ -1,25 +0,0 @@
#include "monospacefontmanager.h"
#include <QDebug>
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;
}

View File

@@ -1,15 +0,0 @@
#ifndef MONOSPACEFONTMANAGER_H
#define MONOSPACEFONTMANAGER_H
#include <QObject>
#include <QFontDatabase>
class MonospaceFontManager : public QObject
{
Q_OBJECT
public:
explicit MonospaceFontManager(QObject *parent = nullptr);
Q_INVOKABLE QStringList retrieveMonospaceFonts();
};
#endif // MONOSPACEFONTMANAGER_H

View File

@@ -22,14 +22,12 @@ import QtQuick.Controls 2.2
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
import QtQuick.Window 2.0 import QtQuick.Window 2.0
Window { ApplicationWindow {
id: dialogwindow id: dialogwindow
title: qsTr("About") title: qsTr("About")
width: 600 width: 600
height: 400 height: 400
modality: Qt.ApplicationModal
ColumnLayout { ColumnLayout {
anchors.fill: parent anchors.fill: parent
anchors.margins: 15 anchors.margins: 15
@@ -37,6 +35,7 @@ Window {
Text { Text {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
text: "cool-retro-term" text: "cool-retro-term"
color: palette.text
font { font {
bold: true bold: true
pointSize: 18 pointSize: 18
@@ -100,6 +99,7 @@ Window {
Text { Text {
Layout.alignment: Qt.AlignCenter Layout.alignment: Qt.AlignCenter
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
color: palette.text
text: appSettings.version + "\n" + qsTr( text: appSettings.version + "\n" + qsTr(
"Author: ") + "Filippo Scognamiglio\n" + qsTr( "Author: ") + "Filippo Scognamiglio\n" + qsTr(
"Email: ") + "flscogna@gmail.com\n" + qsTr( "Email: ") + "flscogna@gmail.com\n" + qsTr(
@@ -115,7 +115,8 @@ Window {
TextArea { TextArea {
readOnly: true readOnly: true
wrapMode: TextEdit.Wrap wrapMode: TextEdit.Wrap
text: "Copyright (c) 2013-2021 Filippo Scognamiglio <flscogna@gmail.com>\n\n" color: palette.text
text: "Copyright (c) 2013-2025 Filippo Scognamiglio <flscogna@gmail.com>\n\n"
+ "https://github.com/Swordfish90/cool-retro-term\n\n" + + "https://github.com/Swordfish90/cool-retro-term\n\n" +
"cool-retro-term is free software: you can redistribute it and/or modify " "cool-retro-term is free software: you can redistribute it and/or modify "
+ "it under the terms of the GNU General Public License as published by " + "it under the terms of the GNU General Public License as published by "

File diff suppressed because it is too large Load Diff

View File

@@ -24,7 +24,7 @@ import "utils.js" as Utils
Loader { Loader {
id: burnInEffect id: burnInEffect
property ShaderEffectSource source: item ? item.source : null property ShaderEffectSource effectSource: item ? item.source : null
property real lastUpdate: 0 property real lastUpdate: 0
property real prevLastUpdate: 0 property real prevLastUpdate: 0
@@ -81,6 +81,14 @@ Loader {
} }
} }
// Restart blurred source settings change. // Restart blurred source settings change.
Connections {
target: appSettings.fontManager
onTerminalFontChanged: {
burnInEffect.restartBlurSource()
}
}
Connections { Connections {
target: appSettings target: appSettings
@@ -88,10 +96,6 @@ Loader {
burnInEffect.restartBlurSource() burnInEffect.restartBlurSource()
} }
onTerminalFontChanged: {
burnInEffect.restartBlurSource()
}
onRasterizationChanged: { onRasterizationChanged: {
burnInEffect.restartBlurSource() burnInEffect.restartBlurSource()
} }
@@ -102,58 +106,22 @@ Loader {
} }
} }
ShaderLibrary {
id: shaderLibrary
}
ShaderEffect { ShaderEffect {
id: burnInShaderEffect id: burnInShaderEffect
property real time: timeManager.time
property variant txt_source: kterminalSource property variant txt_source: kterminalSource
property variant burnInSource: burnInEffectSource property variant burnInSource: burnInEffectSource
property real burnInTime: burnInFadeTime property real burnInTime: burnInFadeTime
property real lastUpdate: burnInEffect.lastUpdate property real burnInLastUpdate: burnInEffect.lastUpdate
property real prevLastUpdate: burnInEffect.prevLastUpdate property real prevLastUpdate: burnInEffect.prevLastUpdate
anchors.fill: parent anchors.fill: parent
blending: false blending: false
fragmentShader: fragmentShader: "qrc:/shaders/burn_in.frag.qsb"
"#ifdef GL_ES vertexShader: "qrc:/shaders/burn_in.vert.qsb"
precision mediump float;
#endif\n" +
"uniform lowp float qt_Opacity;" +
"uniform lowp sampler2D txt_source;" +
"varying highp vec2 qt_TexCoord0;
uniform lowp sampler2D burnInSource;
uniform highp float burnInTime;
uniform highp float lastUpdate;
uniform highp float prevLastUpdate;" +
shaderLibrary.rgb2grey +
"void main() {
vec2 coords = qt_TexCoord0;
vec3 txtColor = texture2D(txt_source, coords).rgb;
vec4 accColor = texture2D(burnInSource, coords);
float prevMask = accColor.a;
float currMask = rgb2grey(txtColor);
highp float blurDecay = clamp((lastUpdate - prevLastUpdate) * burnInTime, 0.0, 1.0);
blurDecay = max(0.0, blurDecay - prevMask);
vec3 blurColor = accColor.rgb - vec3(blurDecay);
vec3 color = max(blurColor, txtColor);
gl_FragColor = vec4(color, currMask);
}
"
onStatusChanged: if (log) console.log(log) //Print warning messages onStatusChanged: if (log) console.log(log) //Print warning messages
} }

View File

@@ -18,7 +18,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/ *******************************************************************************/
import QtQuick 2.2 import QtQuick 2.2
import QtQuick.Dialogs 1.1 import QtQuick.Dialogs
Item { Item {
id: rootItem id: rootItem
@@ -31,11 +31,13 @@ Item {
id: colorDialog id: colorDialog
title: qsTr("Choose a color") title: qsTr("Choose a color")
modality: Qt.ApplicationModal modality: Qt.ApplicationModal
visible: false selectedColor: rootItem.color
//This is a workaround to a Qt 5.2 bug. onSelectedColorChanged: {
onColorChanged: if (!appSettings.isMacOS) colorSelected(color) if (!appSettings.isMacOS && visible)
onAccepted: if (appSettings.isMacOS) colorSelected(color) colorSelected(selectedColor)
}
onAccepted: colorSelected(selectedColor)
} }
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
@@ -57,6 +59,6 @@ Item {
} }
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
onClicked: colorDialog.visible = true onClicked: colorDialog.open()
} }
} }

View File

@@ -1,107 +0,0 @@
/*******************************************************************************
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term
*
* This file is part of cool-retro-term.
*
* cool-retro-term is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.2
QtObject {
property int selectedFontIndex
property real scaling
property var _font: fontlist.get(selectedFontIndex)
property var source: _font.source
property int pixelSize: _font.pixelSize
property int lineSpacing: _font.lineSpacing
property real screenScaling: scaling * _font.baseScaling
property real defaultFontWidth: fontlist.get(selectedFontIndex).fontWidth
property bool lowResolutionFont: true
property ListModel fontlist: ListModel {
ListElement {
name: "COMMODORE_PET"
text: "Commodore PET (1977)"
source: "fonts/1977-commodore-pet/PetMe.ttf"
lineSpacing: 3
pixelSize: 8
baseScaling: 3.5
fontWidth: 0.8
}
ListElement {
name: "IBM_PC"
text: "IBM PC (1981)"
source: "fonts/1981-ibm-pc/PxPlus_IBM_BIOS.ttf"
lineSpacing: 3
pixelSize: 8
baseScaling: 3.5
fontWidth: 0.8
}
ListElement {
name: "PROGGY_TINY"
text: "Proggy Tiny (Modern)"
source: "fonts/modern-proggy-tiny/ProggyTiny.ttf"
lineSpacing: 1
pixelSize: 16
baseScaling: 3.3
fontWidth: 0.9
}
ListElement {
name: "TERMINUS_SCALED"
text: "Terminus (Modern)"
source: "fonts/modern-terminus/TerminusTTF-4.46.0.ttf"
lineSpacing: 1
pixelSize: 12
baseScaling: 3.0
fontWidth: 1.0
}
ListElement {
name: "PRO_FONT_SCALED"
text: "Pro Font (Modern)"
source: "fonts/modern-pro-font-win-tweaked/ProFontWindows.ttf"
lineSpacing: 1
pixelSize: 12
baseScaling: 3.0
fontWidth: 1.0
}
ListElement {
name: "APPLE_II"
text: "Apple ][ (1977)"
source: "fonts/1977-apple2/PrintChar21.ttf"
lineSpacing: 2
pixelSize: 8
baseScaling: 3.5
fontWidth: 0.9
}
ListElement {
name: "ATARI_400"
text: "Atari 400-800 (1979)"
source: "fonts/1979-atari-400-800/AtariClassic-Regular.ttf"
lineSpacing: 3
pixelSize: 8
baseScaling: 3.5
fontWidth: 0.8
}
ListElement {
name: "COMMODORE_64"
text: "Commodore 64 (1982)"
source: "fonts/1982-commodore64/C64_Pro_Mono-STYLE.ttf"
lineSpacing: 3
pixelSize: 8
baseScaling: 3.5
fontWidth: 0.8
}
}
}

View File

@@ -1,107 +0,0 @@
/*******************************************************************************
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term
*
* This file is part of cool-retro-term.
*
* cool-retro-term is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.2
QtObject {
property int selectedFontIndex
property real scaling
property var _font: fontlist.get(selectedFontIndex)
property var source: _font.source
property int pixelSize: _font.pixelSize
property int lineSpacing: _font.lineSpacing
property real screenScaling: scaling * _font.baseScaling
property real defaultFontWidth: fontlist.get(selectedFontIndex).fontWidth
property bool lowResolutionFont: true
property ListModel fontlist: ListModel {
ListElement {
name: "COMMODORE_PET"
text: "Commodore PET (1977)"
source: "fonts/1977-commodore-pet/PetMe.ttf"
lineSpacing: 3
pixelSize: 8
baseScaling: 3.5
fontWidth: 0.7
}
ListElement {
name: "IBM_PC"
text: "IBM PC (1981)"
source: "fonts/1981-ibm-pc/PxPlus_IBM_BIOS.ttf"
lineSpacing: 3
pixelSize: 8
baseScaling: 3.5
fontWidth: 0.8
}
ListElement {
name: "PROGGY_TINY"
text: "Proggy Tiny (Modern)"
source: "fonts/modern-proggy-tiny/ProggyTiny.ttf"
lineSpacing: 1
pixelSize: 16
baseScaling: 3.3
fontWidth: 0.9
}
ListElement {
name: "TERMINUS_SCALED"
text: "Terminus (Modern)"
source: "fonts/modern-terminus/TerminusTTF-4.46.0.ttf"
lineSpacing: 1
pixelSize: 12
baseScaling: 3.0
fontWidth: 1.0
}
ListElement {
name: "PRO_FONT_SCALED"
text: "Pro Font (Modern)"
source: "fonts/modern-pro-font-win-tweaked/ProFontWindows.ttf"
lineSpacing: 1
pixelSize: 12
baseScaling: 3.0
fontWidth: 1.0
}
ListElement {
name: "APPLE_II"
text: "Apple ][ (1977)"
source: "fonts/1977-apple2/PrintChar21.ttf"
lineSpacing: 3
pixelSize: 8
baseScaling: 3.5
fontWidth: 0.8
}
ListElement {
name: "ATARI_400"
text: "Atari 400-800 (1979)"
source: "fonts/1979-atari-400-800/AtariClassic-Regular.ttf"
lineSpacing: 3
pixelSize: 8
baseScaling: 3.5
fontWidth: 0.7
}
ListElement {
name: "COMMODORE_64"
text: "Commodore 64 (1982)"
source: "fonts/1982-commodore64/C64_Pro_Mono-STYLE.ttf"
lineSpacing: 3
pixelSize: 8
baseScaling: 3.5
fontWidth: 0.7
}
}
}

View File

@@ -1,252 +0,0 @@
/*******************************************************************************
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term
*
* This file is part of cool-retro-term.
*
* cool-retro-term is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.2
QtObject {
property int selectedFontIndex
property real scaling
property var source: fontlist.get(selectedFontIndex).source
property var _font: fontlist.get(selectedFontIndex)
property bool lowResolutionFont: _font.lowResolutionFont
property int pixelSize: lowResolutionFont ? _font.pixelSize : _font.pixelSize * scaling
property int lineSpacing: lowResolutionFont ? _font.lineSpacing : pixelSize * _font.lineSpacing
property real screenScaling: lowResolutionFont ? _font.baseScaling * scaling : 1.0
property real defaultFontWidth: fontlist.get(selectedFontIndex).fontWidth
property string family: fontlist.get(selectedFontIndex).family
property bool isSystemFont: fontlist.get(selectedFontIndex).isSystemFont
// There are two kind of fonts: low resolution and high resolution.
// Low resolution font sets the lowResolutionFont property to true.
// They are rendered at a fixed pixel size and the texture is upscaled
// to fill the screen (they are much faster to render).
// High resolution fonts are instead drawn on a texture which has the
// size of the screen, and the scaling directly controls their pixels size.
// Those are slower to render but are not pixelated.
property ListModel fontlist: ListModel {
ListElement {
name: "TERMINUS_SCALED"
text: "Terminus (Modern)"
source: "fonts/modern-terminus/TerminusTTF-4.46.0.ttf"
lineSpacing: 1
pixelSize: 12
baseScaling: 3.0
fontWidth: 1.0
lowResolutionFont: true
isSystemFont: false
family: ""
}
ListElement {
name: "PRO_FONT_SCALED"
text: "Pro Font (Modern)"
source: "fonts/modern-pro-font-win-tweaked/ProFontWindows.ttf"
lineSpacing: 1
pixelSize: 12
baseScaling: 3.0
fontWidth: 1.0
lowResolutionFont: true
isSystemFont: false
family: ""
}
ListElement {
name: "EXCELSIOR_SCALED"
text: "Fixedsys Excelsior (Modern)"
source: "fonts/modern-fixedsys-excelsior/FSEX301-L2.ttf"
lineSpacing: 0
pixelSize: 16
baseScaling: 2.4
fontWidth: 1.0
lowResolutionFont: true
isSystemFont: false
family: ""
}
ListElement {
name: "COMMODORE_PET_SCALED"
text: "Commodore PET (1977)"
source: "fonts/1977-commodore-pet/PetMe.ttf"
lineSpacing: 3
pixelSize: 8
baseScaling: 3.5
fontWidth: 0.7
lowResolutionFont: true
isSystemFont: false
family: ""
}
ListElement {
name: "PROGGY_TINY_SCALED"
text: "Proggy Tiny (Modern)"
source: "fonts/modern-proggy-tiny/ProggyTiny.ttf"
lineSpacing: 1
pixelSize: 16
baseScaling: 3.3
fontWidth: 0.9
lowResolutionFont: true
isSystemFont: false
family: ""
}
ListElement {
name: "APPLE_II_SCALED"
text: "Apple ][ (1977)"
source: "fonts/1977-apple2/PrintChar21.ttf"
lineSpacing: 3
pixelSize: 8
baseScaling: 3.5
fontWidth: 0.8
lowResolutionFont: true
isSystemFont: false
family: ""
}
ListElement {
name: "ATARI_400_SCALED"
text: "Atari 400-800 (1979)"
source: "fonts/1979-atari-400-800/AtariClassic-Regular.ttf"
lineSpacing: 3
pixelSize: 8
baseScaling: 3.5
fontWidth: 0.7
lowResolutionFont: true
isSystemFont: false
family: ""
}
ListElement {
name: "IBM_PC_SCALED"
text: "IBM PC (1981)"
source: "fonts/1981-ibm-pc/PxPlus_IBM_BIOS.ttf"
lineSpacing: 3
pixelSize: 8
baseScaling: 3.5
fontWidth: 0.8
lowResolutionFont: true
isSystemFont: false
family: ""
}
ListElement {
name: "COMMODORE_64_SCALED"
text: "Commodore 64 (1982)"
source: "fonts/1982-commodore64/C64_Pro_Mono-STYLE.ttf"
lineSpacing: 3
pixelSize: 8
baseScaling: 3.5
fontWidth: 0.7
lowResolutionFont: true
isSystemFont: false
family: ""
}
ListElement {
name: "IBM_DOS"
text: "IBM DOS (1985)"
source: "fonts/1985-ibm-pc-vga/PxPlus_IBM_VGA8.ttf"
lineSpacing: 3
pixelSize: 16
baseScaling: 2.0
fontWidth: 1.0
lowResolutionFont: true
isSystemFont: false
family: ""
}
ListElement {
name: "HERMIT"
text: "HD: Hermit (Modern)"
source: "fonts/modern-hermit/Hermit-medium.otf"
lineSpacing: 0.05
pixelSize: 27
fontWidth: 1.0
lowResolutionFont: false
isSystemFont: false
family: ""
}
ListElement {
name: "TERMINUS"
text: "HD: Terminus (Modern)"
source: "fonts/modern-terminus/TerminusTTF-4.46.0.ttf"
lineSpacing: 0.1
pixelSize: 35
fontWidth: 1.0
lowResolutionFont: false
isSystemFont: false
family: ""
}
ListElement {
name: "PRO_FONT"
text: "HD: Pro Font (Modern)"
source: "fonts/modern-pro-font-win-tweaked/ProFontWindows.ttf"
lineSpacing: 0.1
pixelSize: 35
fontWidth: 1.0
lowResolutionFont: false
isSystemFont: false
family: ""
}
ListElement {
name: "INCONSOLATA"
text: "HD: Inconsolata (Modern)"
source: "fonts/modern-inconsolata/Inconsolata.otf"
lineSpacing: 0.1
pixelSize: 35
fontWidth: 1.0
lowResolutionFont: false
isSystemFont: false
family: ""
}
ListElement {
name: "IBM_3278"
text: "HD: IBM 3278 (1971)"
source: "fonts/1971-ibm-3278/3270-Regular.ttf"
lineSpacing: 0.2
pixelSize: 32
fontWidth: 1.0
lowResolutionFont: false
isSystemFont: false
family: ""
}
}
Component.onCompleted: addSystemFonts()
function addSystemFonts() {
var families = monospaceSystemFonts
for (var i = 0; i < families.length; i++) {
if (verbose) {
console.log("Adding system font: ", families[i])
}
fontlist.append(convertToListElement(families[i]))
}
}
function convertToListElement(family) {
return {
"name": "System: " + family,
"text": qsTr("System: ") + family,
"source": "",
"lineSpacing": 0.1,
"pixelSize": 30,
"fontWidth": 1.0,
"baseScaling": 1.0,
"lowResolutionFont": false,
"isSystemFont": true,
"family": family
}
}
}

View File

@@ -21,7 +21,7 @@ import QtQuick 2.2
import QtQuick.Window 2.0 import QtQuick.Window 2.0
import QtQuick.Controls 2.0 import QtQuick.Controls 2.0
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.1 import QtQuick.Dialogs
Window { Window {
id: insertnamedialog id: insertnamedialog

View File

@@ -20,14 +20,16 @@
import QtQuick 2.2 import QtQuick 2.2
import QtQuick.Controls 2.0 import QtQuick.Controls 2.0
import QtQml
import QMLTermWidget 1.0 import QMLTermWidget 2.0
import "menus" import "menus"
import "utils.js" as Utils import "utils.js" as Utils
Item{ Item {
id: terminalContainer id: preprocessedTerminal
signal sessionFinished()
property size virtualResolution: Qt.size(kterminal.totalWidth, kterminal.totalHeight) property size virtualResolution: Qt.size(kterminal.totalWidth, kterminal.totalHeight)
property alias mainTerminal: kterminal property alias mainTerminal: kterminal
@@ -46,14 +48,14 @@ Item{
// Manage copy and paste // Manage copy and paste
Connections { Connections {
target: copyAction target: copyAction
enabled: terminalContainer.hasFocus
onTriggered: { onTriggered: {
kterminal.copyClipboard() kterminal.copyClipboard()
} }
} }
Connections { Connections {
target: pasteAction target: pasteAction
enabled: terminalContainer.hasFocus
onTriggered: { onTriggered: {
kterminal.pasteClipboard() kterminal.pasteClipboard()
} }
@@ -64,29 +66,22 @@ Item{
target: appSettings target: appSettings
onFontScalingChanged: { onFontScalingChanged: {
terminalContainer.updateSources() preprocessedTerminal.updateSources()
} }
onFontWidthChanged: { onFontWidthChanged: {
terminalContainer.updateSources() preprocessedTerminal.updateSources()
} }
} }
Connections { Connections {
target: terminalContainer target: preprocessedTerminal
onWidthChanged: { onWidthChanged: {
terminalContainer.updateSources() preprocessedTerminal.updateSources()
} }
onHeightChanged: { onHeightChanged: {
terminalContainer.updateSources() preprocessedTerminal.updateSources()
}
}
Connections {
target: terminalWindow
onActiveChanged: {
kterminal.forceActiveFocus()
} }
} }
@@ -97,8 +92,8 @@ Item{
QMLTermWidget { QMLTermWidget {
id: kterminal id: kterminal
property int textureResolutionScale: appSettings.lowResolutionFont ? devicePixelRatio : 1 property int textureResolutionScale: appSettings.lowResolutionFont ? Screen.devicePixelRatio : 1
property int margin: appSettings.totalMargin / screenScaling property int margin: appSettings.margin / screenScaling
property int totalWidth: Math.floor(parent.width / (screenScaling * fontWidth)) property int totalWidth: Math.floor(parent.width / (screenScaling * fontWidth))
property int totalHeight: Math.floor(parent.height / screenScaling) property int totalHeight: Math.floor(parent.height / screenScaling)
@@ -107,26 +102,24 @@ Item{
textureSize: Qt.size(width / textureResolutionScale, height / textureResolutionScale) textureSize: Qt.size(width / textureResolutionScale, height / textureResolutionScale)
width: ensureMultiple(rawWidth, devicePixelRatio) width: ensureMultiple(rawWidth, Screen.devicePixelRatio)
height: ensureMultiple(rawHeight, devicePixelRatio) height: ensureMultiple(rawHeight, Screen.devicePixelRatio)
/** Ensure size is a multiple of factor. This is needed for pixel perfect scaling on highdpi screens. */ /** Ensure size is a multiple of factor. This is needed for pixel perfect scaling on highdpi screens. */
function ensureMultiple(size, factor) { function ensureMultiple(size, factor) {
return Math.round(size / factor) * factor; return Math.round(size / factor) * factor;
} }
colorScheme: "cool-retro-term"
smooth: !appSettings.lowResolutionFont
enableBold: false
fullCursorHeight: true fullCursorHeight: true
blinkingCursor: appSettings.blinkingCursor blinkingCursor: appSettings.blinkingCursor
colorScheme: "cool-retro-term"
session: QMLTermSession { session: QMLTermSession {
id: ksession id: ksession
onFinished: { onFinished: {
Qt.quit() preprocessedTerminal.sessionFinished()
} }
} }
@@ -140,26 +133,36 @@ Item{
anchors.topMargin: 1 anchors.topMargin: 1
anchors.bottomMargin: 1 anchors.bottomMargin: 1
color: "white" color: "white"
radius: width * 0.25
opacity: 0.7 opacity: 0.7
} }
} }
function handleFontChanged(fontFamily, pixelSize, lineSpacing, screenScaling, fontWidth) { function handleFontChanged(fontFamily, pixelSize, lineSpacing, screenScaling, fontWidth, fallbackFontFamily, lowResolutionFont) {
kterminal.antialiasText = !appSettings.lowResolutionFont;
font.pixelSize = pixelSize;
font.family = fontFamily;
terminalContainer.fontWidth = fontWidth;
terminalContainer.screenScaling = screenScaling;
scaleTexture = Math.max(1.0, Math.floor(screenScaling * appSettings.windowScaling));
kterminal.lineSpacing = lineSpacing; kterminal.lineSpacing = lineSpacing;
kterminal.antialiasText = !lowResolutionFont;
kterminal.smooth = !lowResolutionFont;
kterminal.enableBold = !lowResolutionFont;
kterminal.enableItalic = !lowResolutionFont;
kterminal.font = Qt.font({
family: fontFamily,
pixelSize: pixelSize
});
preprocessedTerminal.fontWidth = fontWidth;
preprocessedTerminal.screenScaling = screenScaling;
scaleTexture = Math.max(1.0, Math.floor(screenScaling * appSettings.windowScaling));
}
Connections {
target: appSettings
onWindowScalingChanged: {
scaleTexture = Math.max(1.0, Math.floor(preprocessedTerminal.screenScaling * appSettings.windowScaling));
}
} }
function startSession() { function startSession() {
appSettings.initializedSettings.disconnect(startSession);
// Retrieve the variable set in main.cpp if arguments are passed. // Retrieve the variable set in main.cpp if arguments are passed.
if (defaultCmd) { if (defaultCmd) {
ksession.setShellProgram(defaultCmd); ksession.setShellProgram(defaultCmd);
@@ -180,9 +183,9 @@ Item{
forceActiveFocus(); forceActiveFocus();
} }
Component.onCompleted: { Component.onCompleted: {
appSettings.terminalFontChanged.connect(handleFontChanged); appSettings.fontManager.terminalFontChanged.connect(handleFontChanged);
appSettings.initializedSettings.connect(startSession); appSettings.fontManager.refresh()
appSettings.handleFontChanged() startSession();
} }
} }
@@ -198,51 +201,58 @@ Item{
Loader { Loader {
id: menuLoader id: menuLoader
sourceComponent: (appSettings.isMacOS || appSettings.showMenubar ? shortContextMenu : fullContextMenu) sourceComponent: (appSettings.isMacOS || (appSettings.showMenubar && !terminalWindow.fullscreen) ? shortContextMenu : fullContextMenu)
} }
property alias contextmenu: menuLoader.item property alias contextmenu: menuLoader.item
MouseArea { MouseArea {
property real margin: appSettings.totalMargin property real margin: appSettings.margin
property real frameSize: appSettings.frameSize * terminalWindow.normalizedWindowScale
acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton
anchors.fill: parent anchors.fill: parent
cursorShape: kterminal.terminalUsesMouse ? Qt.ArrowCursor : Qt.IBeamCursor cursorShape: kterminal.terminalUsesMouse ? Qt.ArrowCursor : Qt.IBeamCursor
onWheel:{ onWheel: function(wheel) {
if(wheel.modifiers & Qt.ControlModifier){ if (wheel.modifiers & Qt.ControlModifier) {
wheel.angleDelta.y > 0 ? zoomIn.trigger() : zoomOut.trigger(); wheel.angleDelta.y > 0 ? zoomInAction.trigger() : zoomOutAction.trigger();
} else { } else {
var coord = correctDistortion(wheel.x, wheel.y); var coord = correctDistortion(wheel.x, wheel.y);
kterminal.simulateWheel(coord.x, coord.y, wheel.buttons, wheel.modifiers, wheel.angleDelta); kterminal.simulateWheel(coord.x, coord.y, wheel.buttons, wheel.modifiers, wheel.angleDelta);
} }
} }
onDoubleClicked: { onDoubleClicked: function(mouse) {
var coord = correctDistortion(mouse.x, mouse.y); var coord = correctDistortion(mouse.x, mouse.y);
kterminal.simulateMouseDoubleClick(coord.x, coord.y, mouse.button, mouse.buttons, mouse.modifiers); kterminal.simulateMouseDoubleClick(coord.x, coord.y, mouse.button, mouse.buttons, mouse.modifiers);
} }
onPressed: { onPressed: function(mouse) {
if((!kterminal.terminalUsesMouse || mouse.modifiers & Qt.ShiftModifier) && mouse.button == Qt.RightButton) { kterminal.forceActiveFocus()
if ((!kterminal.terminalUsesMouse || mouse.modifiers & Qt.ShiftModifier) && mouse.button == Qt.RightButton) {
contextmenu.popup(); contextmenu.popup();
} else { } else {
var coord = correctDistortion(mouse.x, mouse.y); var coord = correctDistortion(mouse.x, mouse.y);
kterminal.simulateMousePress(coord.x, coord.y, mouse.button, mouse.buttons, mouse.modifiers) kterminal.simulateMousePress(coord.x, coord.y, mouse.button, mouse.buttons, mouse.modifiers)
} }
} }
onReleased: { onReleased: function(mouse) {
var coord = correctDistortion(mouse.x, mouse.y); var coord = correctDistortion(mouse.x, mouse.y);
kterminal.simulateMouseRelease(coord.x, coord.y, mouse.button, mouse.buttons, mouse.modifiers); kterminal.simulateMouseRelease(coord.x, coord.y, mouse.button, mouse.buttons, mouse.modifiers);
} }
onPositionChanged: { onPositionChanged: function(mouse) {
var coord = correctDistortion(mouse.x, mouse.y); var coord = correctDistortion(mouse.x, mouse.y);
kterminal.simulateMouseMove(coord.x, coord.y, mouse.button, mouse.buttons, mouse.modifiers); kterminal.simulateMouseMove(coord.x, coord.y, mouse.button, mouse.buttons, mouse.modifiers);
} }
function correctDistortion(x, y){ function correctDistortion(x, y) {
x = (x - margin) / width; x = (x - margin) / width;
y = (y - margin) / height; y = (y - margin) / height;
x = x * (1 + frameSize * 2) - frameSize;
y = y * (1 + frameSize * 2) - frameSize;
var cc = Qt.size(0.5 - x, 0.5 - y); var cc = Qt.size(0.5 - x, 0.5 - y);
var distortion = (cc.height * cc.height + cc.width * cc.width) * appSettings.screenCurvature * appSettings.screenCurvatureSize; var distortion = (cc.height * cc.height + cc.width * cc.width)
* appSettings.screenCurvature * appSettings.screenCurvatureSize
* terminalWindow.normalizedWindowScale;
return Qt.point((x - cc.width * (1+distortion) * distortion) * (kterminal.totalWidth), return Qt.point((x - cc.width * (1+distortion) * distortion) * (kterminal.totalWidth),
(y - cc.height * (1+distortion) * distortion) * (kterminal.totalHeight)) (y - cc.height * (1+distortion) * distortion) * (kterminal.totalHeight))

View File

@@ -27,7 +27,9 @@ import "Components"
ColumnLayout { ColumnLayout {
GroupBox { GroupBox {
Layout.fillWidth: true Layout.fillWidth: true
title: qsTr("Command") Layout.fillHeight: true
title: qsTr("Miscellaneous")
padding: appSettings.defaultMargin
ColumnLayout { ColumnLayout {
anchors.fill: parent anchors.fill: parent
@@ -37,12 +39,6 @@ ColumnLayout {
checked: appSettings.useCustomCommand checked: appSettings.useCustomCommand
onCheckedChanged: appSettings.useCustomCommand = checked onCheckedChanged: appSettings.useCustomCommand = checked
} }
// Workaround for QTBUG-31627 for pre 5.3.0
Binding {
target: useCustomCommand
property: "checked"
value: appSettings.useCustomCommand
}
TextField { TextField {
id: customCommand id: customCommand
Layout.fillWidth: true Layout.fillWidth: true
@@ -57,12 +53,27 @@ ColumnLayout {
Component.onCompleted: settings_window.closing.connect( Component.onCompleted: settings_window.closing.connect(
saveSetting) saveSetting)
} }
CheckBox {
id: blinkingCursor
text: qsTr("Blinking Cursor")
checked: appSettings.blinkingCursor
onCheckedChanged: appSettings.blinkingCursor = checked
}
CheckBox {
id: showMenubar
text: qsTr("Show Menubar")
enabled: !appSettings.isMacOS
checked: appSettings.showMenubar
onCheckedChanged: appSettings.showMenubar = checked
}
} }
} }
GroupBox { GroupBox {
title: qsTr("Performance") title: qsTr("Performance")
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true
padding: appSettings.defaultMargin
GridLayout { GridLayout {
anchors.fill: parent anchors.fill: parent
columns: 4 columns: 4
@@ -73,24 +84,17 @@ ColumnLayout {
Slider { Slider {
Layout.fillWidth: true Layout.fillWidth: true
Layout.columnSpan: 2 Layout.columnSpan: 2
id: fpsSlider id: effectsFpsSlider
onValueChanged: { onValueChanged: appSettings.effectsFrameSkip = Math.round(value)
if (enabled) {
appSettings.fps = value !== 60 ? value + 1 : 0
}
}
stepSize: 1 stepSize: 1
enabled: false enabled: true
Component.onCompleted: { from: 5
from = 0 to: 1
to = 60 value: appSettings.effectsFrameSkip
value = appSettings.fps !== 0 ? appSettings.fps - 1 : 60
enabled = true
}
} }
SizedLabel { SizedLabel {
text: appSettings.fps !== 0 ? appSettings.fps : qsTr("Max") text: Math.round(100 / Math.max(1, Math.round(effectsFpsSlider.value))) + "%"
} }
Label { Label {
text: qsTr("Texture Quality") text: qsTr("Texture Quality")
@@ -99,15 +103,11 @@ ColumnLayout {
id: txtslider id: txtslider
Layout.fillWidth: true Layout.fillWidth: true
Layout.columnSpan: 2 Layout.columnSpan: 2
onValueChanged: if (enabled) onValueChanged: appSettings.windowScaling = value
appSettings.windowScaling = value
stepSize: 0.05 stepSize: 0.05
enabled: false enabled: true
Component.onCompleted: { from: 0.25
from = 0.25 //Without this value gets set to 0.5 value: appSettings.windowScaling
value = appSettings.windowScaling
enabled = true
}
} }
SizedLabel { SizedLabel {
text: Math.round(txtslider.value * 100) + "%" text: Math.round(txtslider.value * 100) + "%"
@@ -120,15 +120,11 @@ ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.columnSpan: 2 Layout.columnSpan: 2
id: bloomSlider id: bloomSlider
onValueChanged: if (enabled) onValueChanged: appSettings.bloomQuality = value
appSettings.bloomQuality = value
stepSize: 0.05 stepSize: 0.05
enabled: false enabled: true
Component.onCompleted: { from: 0.25
from = 0.25 value: appSettings.bloomQuality
value = appSettings.bloomQuality
enabled = true
}
} }
SizedLabel { SizedLabel {
text: Math.round(bloomSlider.value * 100) + "%" text: Math.round(bloomSlider.value * 100) + "%"
@@ -141,15 +137,11 @@ ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
id: burnInSlider id: burnInSlider
Layout.columnSpan: 2 Layout.columnSpan: 2
onValueChanged: if (enabled) onValueChanged: appSettings.burnInQuality = value
appSettings.burnInQuality = value
stepSize: 0.05 stepSize: 0.05
enabled: false enabled: true
Component.onCompleted: { from: 0.25
from = 0.25 value: appSettings.burnInQuality
value = appSettings.burnInQuality
enabled = true
}
} }
SizedLabel { SizedLabel {
text: Math.round(burnInSlider.value * 100) + "%" text: Math.round(burnInSlider.value * 100) + "%"

View File

@@ -22,65 +22,74 @@ import QtQuick.Controls 2.0
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
ColumnLayout { ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 2 spacing: 2
GroupBox { GroupBox {
title: qsTr("Effects") title: qsTr("Effects")
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true
padding: appSettings.defaultMargin
ColumnLayout { ColumnLayout {
anchors.fill: parent anchors.fill: parent
CheckableSlider { CheckableSlider {
name: qsTr("Bloom") name: qsTr("Bloom")
onNewValue: appSettings.bloom = newValue onNewValue: function(newValue) { appSettings.bloom = newValue }
value: appSettings.bloom value: appSettings.bloom
} }
CheckableSlider { CheckableSlider {
name: qsTr("BurnIn") name: qsTr("BurnIn")
onNewValue: appSettings.burnIn = newValue onNewValue: function(newValue) { appSettings.burnIn = newValue }
value: appSettings.burnIn value: appSettings.burnIn
} }
CheckableSlider { CheckableSlider {
name: qsTr("Static Noise") name: qsTr("Static Noise")
onNewValue: appSettings.staticNoise = newValue onNewValue: function(newValue) { appSettings.staticNoise = newValue }
value: appSettings.staticNoise value: appSettings.staticNoise
} }
CheckableSlider { CheckableSlider {
name: qsTr("Jitter") name: qsTr("Jitter")
onNewValue: appSettings.jitter = newValue onNewValue: function(newValue) { appSettings.jitter = newValue }
value: appSettings.jitter value: appSettings.jitter
} }
CheckableSlider { CheckableSlider {
name: qsTr("Glow Line") name: qsTr("Glow Line")
onNewValue: appSettings.glowingLine = newValue onNewValue: function(newValue) { appSettings.glowingLine = newValue }
value: appSettings.glowingLine value: appSettings.glowingLine
} }
CheckableSlider { CheckableSlider {
name: qsTr("Screen Curvature") name: qsTr("Screen Curvature")
onNewValue: appSettings.screenCurvature = newValue onNewValue: function(newValue) { appSettings.screenCurvature = newValue }
value: appSettings.screenCurvature value: appSettings.screenCurvature
} }
CheckableSlider { CheckableSlider {
name: qsTr("Ambient Light") name: qsTr("Ambient Light")
onNewValue: appSettings.ambientLight = newValue onNewValue: function(newValue) { appSettings.ambientLight = newValue }
value: appSettings.ambientLight value: appSettings.ambientLight
enabled: appSettings.framesIndex !== 0 enabled: appSettings.framesIndex !== 0
} }
CheckableSlider { CheckableSlider {
name: qsTr("Flickering") name: qsTr("Flickering")
onNewValue: appSettings.flickering = newValue onNewValue: function(newValue) { appSettings.flickering = newValue }
value: appSettings.flickering value: appSettings.flickering
} }
CheckableSlider { CheckableSlider {
name: qsTr("Horizontal Sync") name: qsTr("Horizontal Sync")
onNewValue: appSettings.horizontalSync = newValue onNewValue: function(newValue) { appSettings.horizontalSync = newValue }
value: appSettings.horizontalSync value: appSettings.horizontalSync
} }
CheckableSlider { CheckableSlider {
name: qsTr("RGB Shift") name: qsTr("RGB Shift")
onNewValue: appSettings.rbgShift = newValue onNewValue: function(newValue) { appSettings.rgbShift = newValue }
value: appSettings.rbgShift value: appSettings.rgbShift
}
CheckableSlider {
name: qsTr("Frame Shininess")
onNewValue: function(newValue) { appSettings._frameShininess = newValue }
value: appSettings._frameShininess
} }
} }
} }

View File

@@ -20,12 +20,14 @@
import QtQuick 2.2 import QtQuick 2.2
import QtQuick.Controls 2.4 import QtQuick.Controls 2.4
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.1 import QtQuick.Dialogs
ColumnLayout { ColumnLayout {
GroupBox { GroupBox {
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true
title: qsTr("Profile") title: qsTr("Profile")
padding: appSettings.defaultMargin
RowLayout { RowLayout {
anchors.fill: parent anchors.fill: parent
ListView { ListView {
@@ -183,6 +185,8 @@ ColumnLayout {
GroupBox { GroupBox {
title: qsTr("Screen") title: qsTr("Screen")
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true
padding: appSettings.defaultMargin
GridLayout { GridLayout {
anchors.fill: parent anchors.fill: parent
columns: 2 columns: 2
@@ -207,12 +211,19 @@ ColumnLayout {
onValueChanged: appSettings._margin = value onValueChanged: appSettings._margin = value
value: appSettings._margin value: appSettings._margin
} }
Label {
text: qsTr("Radius")
}
SimpleSlider {
onValueChanged: appSettings._screenRadius = value
value: appSettings._screenRadius
}
Label { Label {
text: qsTr("Frame size") text: qsTr("Frame size")
} }
SimpleSlider { SimpleSlider {
onValueChanged: appSettings._frameMargin = value onValueChanged: appSettings._frameSize = value
value: appSettings._frameMargin value: appSettings._frameSize
} }
Label { Label {
text: qsTr("Opacity") text: qsTr("Opacity")
@@ -237,6 +248,7 @@ ColumnLayout {
MessageDialog { MessageDialog {
id: messageDialog id: messageDialog
title: qsTr("File Error") title: qsTr("File Error")
buttons: MessageDialog.Ok
onAccepted: { onAccepted: {
messageDialog.close() messageDialog.close()
} }
@@ -248,10 +260,8 @@ ColumnLayout {
sourceComponent: FileDialog { sourceComponent: FileDialog {
nameFilters: ["Json files (*.json)"] nameFilters: ["Json files (*.json)"]
selectMultiple: false fileMode: fileDialog.selectExisting ? FileDialog.OpenFile : FileDialog.SaveFile
selectFolder: false onAccepted: callBack(selectedFile)
selectExisting: fileDialog.selectExisting
onAccepted: callBack(fileUrl)
} }
onSelectExistingChanged: reload() onSelectExistingChanged: reload()

View File

@@ -25,27 +25,50 @@ import QtQml 2.0
import "Components" import "Components"
ColumnLayout { ColumnLayout {
GroupBox { GroupBox {
title: qsTr("Font") title: qsTr("Font")
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true
padding: appSettings.defaultMargin
GridLayout { GridLayout {
anchors.fill: parent anchors.fill: parent
columns: 2 columns: 2
Label { Label {
text: qsTr("Rasterization") text: qsTr("Source")
}
RowLayout {
Layout.fillWidth: true
RadioButton {
text: qsTr("Bundled")
checked: appSettings.fontSource === appSettings.bundled_fonts
onClicked: {
appSettings.fontSource = appSettings.bundled_fonts
}
}
RadioButton {
text: qsTr("System")
checked: appSettings.fontSource === appSettings.system_fonts
onClicked: {
appSettings.fontSource = appSettings.system_fonts
}
}
}
Label {
text: qsTr("Rendering")
enabled: appSettings.fontSource === appSettings.bundled_fonts
} }
ComboBox { ComboBox {
id: rasterizationBox id: renderingBox
property string selectedElement: model[currentIndex] property string selectedElement: model[currentIndex]
Layout.fillWidth: true Layout.fillWidth: true
model: [qsTr("Default"), qsTr("Scanlines"), qsTr("Pixels"), qsTr("Sub-Pixels")] model: [qsTr("Default"), qsTr("Scanlines"), qsTr("Pixels"), qsTr("Sub-Pixels"), qsTr("Modern")]
currentIndex: appSettings.rasterization currentIndex: appSettings.rasterization
onCurrentIndexChanged: { onCurrentIndexChanged: {
appSettings.rasterization = currentIndex appSettings.rasterization = currentIndex
} }
enabled: appSettings.fontSource === appSettings.bundled_fonts
} }
Label { Label {
text: qsTr("Name") text: qsTr("Name")
@@ -53,25 +76,43 @@ ColumnLayout {
ComboBox { ComboBox {
id: fontChanger id: fontChanger
Layout.fillWidth: true Layout.fillWidth: true
model: appSettings.fontlist model: appSettings.filteredFontList
textRole: "text" textRole: "text"
onActivated: { onActivated: {
var name = appSettings.fontlist.get(index).name var font = appSettings.filteredFontList.get(currentIndex)
appSettings.fontNames[appSettings.rasterization] = name
appSettings.handleFontChanged() // If selecting a high-res font while not in Modern mode,
// switch to Modern to render at full resolution.
if (!font.lowResolutionFont && appSettings.rasterization !== appSettings.modern_rasterization) {
appSettings.rasterization = appSettings.modern_rasterization
}
// If selecting a low-res font while in Modern mode, switch back to default.
if (font.lowResolutionFont && appSettings.rasterization === appSettings.modern_rasterization) {
appSettings.rasterization = appSettings.no_rasterization
}
appSettings.fontName = font.name
} }
function updateIndex() { function updateIndex() {
var name = appSettings.fontNames[appSettings.rasterization] for (var i = 0; i < appSettings.filteredFontList.count; i++) {
var index = appSettings.getIndexByName(name) var font = appSettings.filteredFontList.get(i)
if (index !== undefined) if (font.name === appSettings.fontName) {
currentIndex = index currentIndex = i
return
}
}
currentIndex = 0
} }
Connections { Connections {
target: appSettings target: appSettings.fontManager
onTerminalFontChanged: { onTerminalFontChanged: {
fontChanger.updateIndex() fontChanger.updateIndex()
} }
onFilteredFontListChanged: {
fontChanger.updateIndex()
}
} }
Component.onCompleted: updateIndex() Component.onCompleted: updateIndex()
} }
@@ -111,41 +152,43 @@ ColumnLayout {
text: Math.round(widthChanger.value * 100) + "%" text: Math.round(widthChanger.value * 100) + "%"
} }
} }
} Label {
} text: qsTr("Line Spacing")
GroupBox {
title: qsTr("Cursor")
Layout.fillWidth: true
ColumnLayout {
anchors.fill: parent
CheckBox {
id: blinkingCursor
text: qsTr("Blinking Cursor")
checked: appSettings.blinkingCursor
onCheckedChanged: appSettings.blinkingCursor = checked
} }
Binding { RowLayout {
target: blinkingCursor Layout.fillWidth: true
property: "checked" Slider {
value: appSettings.blinkingCursor Layout.fillWidth: true
id: lineSpacingChanger
onValueChanged: appSettings.lineSpacing = value
value: appSettings.lineSpacing
stepSize: 0.01
from: 0.0
to: 1.0
}
SizedLabel {
text: Math.round(lineSpacingChanger.value * 100) + "%"
}
} }
} }
} }
GroupBox { GroupBox {
title: qsTr("Colors") title: qsTr("Colors")
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true
padding: appSettings.defaultMargin
ColumnLayout { ColumnLayout {
anchors.fill: parent anchors.fill: parent
ColumnLayout { ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
CheckableSlider { CheckableSlider {
name: qsTr("Chroma Color") name: qsTr("Chroma Color")
onNewValue: appSettings.chromaColor = newValue onNewValue: function(newValue) { appSettings.chromaColor = newValue }
value: appSettings.chromaColor value: appSettings.chromaColor
} }
CheckableSlider { CheckableSlider {
name: qsTr("Saturation Color") name: qsTr("Saturation Color")
onNewValue: appSettings.saturationColor = newValue onNewValue: function(newValue) { appSettings.saturationColor = newValue }
value: appSettings.saturationColor value: appSettings.saturationColor
enabled: appSettings.chromaColor !== 0 enabled: appSettings.chromaColor !== 0
} }
@@ -166,6 +209,13 @@ ColumnLayout {
onColorSelected: appSettings._backgroundColor = color onColorSelected: appSettings._backgroundColor = color
color: appSettings._backgroundColor color: appSettings._backgroundColor
} }
ColorButton {
name: qsTr("Frame")
height: 50
Layout.fillWidth: true
onColorSelected: appSettings._frameColor = color
color: appSettings._frameColor
}
} }
} }
} }

View File

@@ -22,54 +22,55 @@ import QtQuick 2.2
import QtQuick.Controls 2.1 import QtQuick.Controls 2.1
import QtQuick.Window 2.1 import QtQuick.Window 2.1
import QtQuick.Layouts 1.3 import QtQuick.Layouts 1.3
import QtQuick.Dialogs 1.1 import QtQuick.Dialogs
ApplicationWindow {
readonly property real tabButtonPadding: 10
Window {
id: settings_window id: settings_window
title: qsTr("Settings") title: qsTr("Settings")
width: 640 width: 640
height: 640 height: 520
property int tabmargins: 15
Item { Item {
anchors { fill: parent; margins: tabmargins } anchors { fill: parent; }
TabBar { TabBar {
id: bar id: bar
anchors { left: parent.left; right: parent.right; top: parent.top; } anchors { left: parent.left; right: parent.right; top: parent.top; }
TabButton { TabButton {
padding: tabButtonPadding
text: qsTr("General") text: qsTr("General")
} }
TabButton { TabButton {
padding: tabButtonPadding
text: qsTr("Terminal") text: qsTr("Terminal")
} }
TabButton { TabButton {
padding: tabButtonPadding
text: qsTr("Effects") text: qsTr("Effects")
} }
TabButton { TabButton {
padding: tabButtonPadding
text: qsTr("Advanced") text: qsTr("Advanced")
} }
} }
Frame { StackLayout {
anchors { anchors {
top: bar.bottom top: bar.bottom
left: parent.left left: parent.left
right: parent.right right: parent.right
bottom: parent.bottom bottom: parent.bottom
margins: 16
} }
StackLayout { currentIndex: bar.currentIndex
anchors.fill: parent
currentIndex: bar.currentIndex SettingsGeneralTab { }
SettingsTerminalTab { }
SettingsGeneralTab { } SettingsEffectsTab { }
SettingsTerminalTab { } SettingsAdvancedTab { }
SettingsEffectsTab { }
SettingsAdvancedTab { }
}
} }
} }
} }

View File

@@ -1,91 +0,0 @@
import QtQuick 2.0
QtObject {
property string rasterizationShader:
(appSettings.rasterization === appSettings.no_rasterization ? "
lowp vec3 applyRasterization(vec2 screenCoords, lowp vec3 texel, vec2 virtualResolution, float intensity) {
return texel;
}" : "") +
(appSettings.rasterization === appSettings.scanline_rasterization ? "
#define INTENSITY 0.30
#define BRIGHTBOOST 0.30
lowp vec3 applyRasterization(vec2 screenCoords, lowp vec3 texel, vec2 virtualResolution, float intensity) {
lowp vec3 pixelHigh = ((1.0 + BRIGHTBOOST) - (0.2 * texel)) * texel;
lowp vec3 pixelLow = ((1.0 - INTENSITY) + (0.1 * texel)) * texel;
vec2 coords = fract(screenCoords * virtualResolution) * 2.0 - vec2(1.0);
lowp float mask = 1.0 - abs(coords.y);
lowp vec3 rasterizationColor = mix(pixelLow, pixelHigh, mask);
return mix(texel, rasterizationColor, intensity);
}" : "") +
(appSettings.rasterization === appSettings.pixel_rasterization ? "
#define INTENSITY 0.30
#define BRIGHTBOOST 0.30
lowp vec3 applyRasterization(vec2 screenCoords, lowp vec3 texel, vec2 virtualResolution, float intensity) {
lowp vec3 result = texel;
lowp vec3 pixelHigh = ((1.0 + BRIGHTBOOST) - (0.2 * texel)) * texel;
lowp vec3 pixelLow = ((1.0 - INTENSITY) + (0.1 * texel)) * texel;
vec2 coords = fract(screenCoords * virtualResolution) * 2.0 - vec2(1.0);
coords = coords * coords;
lowp float mask = 1.0 - coords.x - coords.y;
lowp vec3 rasterizationColor = mix(pixelLow, pixelHigh, mask);
return mix(texel, rasterizationColor, intensity);
}" : "") +
(appSettings.rasterization === appSettings.subpixel_rasterization ? "
#define INTENSITY 0.30
#define BRIGHTBOOST 0.30
#define SUBPIXELS 3.0
const vec3 offsets = vec3(3.141592654) * vec3(1.0/2.0,1.0/2.0 - 2.0/3.0,1.0/2.0-4.0/3.0);
lowp vec3 applyRasterization(vec2 screenCoords, lowp vec3 texel, vec2 virtualResolution, float intensity) {
vec2 omega = vec2(3.141592654) * vec2(2.0) * virtualResolution;
vec2 angle = screenCoords * omega;
vec3 xfactors = (SUBPIXELS + sin(angle.x + offsets)) / (SUBPIXELS + 1.0);
lowp vec3 result = texel * xfactors;
lowp vec3 pixelHigh = ((1.0 + BRIGHTBOOST) - (0.2 * result)) * result;
lowp vec3 pixelLow = ((1.0 - INTENSITY) + (0.1 * result)) * result;
vec2 coords = fract(screenCoords * virtualResolution) * 2.0 - vec2(1.0);
lowp float mask = 1.0 - abs(coords.y);
lowp vec3 rasterizationColor = mix(pixelLow, pixelHigh, mask);
return mix(texel, rasterizationColor, intensity);
}" : "") +
"\n\n"
property string min2: "
float min2(vec2 v) {
return min(v.x, v.y);
}\n\n"
property string rgb2grey: "
float rgb2grey(vec3 v) {
return dot(v, vec3(0.21, 0.72, 0.04));
}\n\n"
property string max2: "
float max2(vec2 v) {
return max(v.x, v.y);
}\n\n"
property string prod2: "
float prod2(vec2 v) {
return v.x * v.y;
}\n\n"
property string sum2: "
float sum2(vec2 v) {
return v.x + v.y;
}\n\n"
}

View File

@@ -19,11 +19,34 @@
*******************************************************************************/ *******************************************************************************/
import QtQuick 2.2 import QtQuick 2.2
import QtGraphicalEffects 1.0
import "utils.js" as Utils import "utils.js" as Utils
Item { Item {
function dynamicFragmentPath() {
var rasterMode = appSettings.rasterization;
var burnInOn = appSettings.burnIn > 0 ? 1 : 0;
var frameOn = appSettings.frameEnabled ? 1 : 0;
var chromaOn = appSettings.chromaColor > 0 ? 1 : 0;
return "qrc:/shaders/terminal_dynamic_raster" + rasterMode +
"_burn" + burnInOn +
"_frame" + frameOn +
"_chroma" + chromaOn +
".frag.qsb";
}
function staticFragmentPath() {
var rgbShiftOn = appSettings.rgbShift > 0 ? 1 : 0;
var bloomOn = appSettings.bloom > 0 ? 1 : 0;
var curvatureOn = (appSettings.screenCurvature > 0 || appSettings.frameSize > 0) ? 1 : 0;
var shineOn = appSettings.frameShininess > 0 ? 1 : 0;
return "qrc:/shaders/terminal_static_rgb" + rgbShiftOn +
"_bloom" + bloomOn +
"_curve" + curvatureOn +
"_shine" + shineOn +
".frag.qsb";
}
property ShaderEffectSource source property ShaderEffectSource source
property BurnInEffect burnInEffect property BurnInEffect burnInEffect
property ShaderEffectSource bloomSource property ShaderEffectSource bloomSource
@@ -31,7 +54,8 @@ Item {
property color fontColor: appSettings.fontColor property color fontColor: appSettings.fontColor
property color backgroundColor: appSettings.backgroundColor property color backgroundColor: appSettings.backgroundColor
property real screenCurvature: appSettings.screenCurvature * appSettings.screenCurvatureSize property real screenCurvature: appSettings.screenCurvature * appSettings.screenCurvatureSize * terminalWindow.normalizedWindowScale
property real frameSize: appSettings.frameSize * terminalWindow.normalizedWindowScale
property real chromaColor: appSettings.chromaColor property real chromaColor: appSettings.chromaColor
@@ -45,469 +69,132 @@ Item {
screenResolution.height / virtualResolution.height screenResolution.height / virtualResolution.height
) )
ShaderEffect { ShaderEffect {
id: dynamicShader id: dynamicShader
property ShaderEffectSource screenBuffer: frameBuffer
property ShaderEffectSource burnInSource: burnInEffect.effectSource
property ShaderEffectSource frameSource: terminalFrameLoader.item
property ShaderLibrary shaderLibrary: ShaderLibrary { } property color fontColor: parent.fontColor
property color backgroundColor: parent.backgroundColor
property real screenCurvature: parent.screenCurvature
property real chromaColor: parent.chromaColor
property real ambientLight: parent.ambientLight
property ShaderEffectSource screenBuffer: frameBuffer property real flickering: appSettings.flickering
property ShaderEffectSource burnInSource: burnInEffect.source property real horizontalSync: appSettings.horizontalSync
property ShaderEffectSource frameSource: terminalFrameLoader.item property real horizontalSyncStrength: Utils.lint(0.05, 0.35, horizontalSync)
property real glowingLine: appSettings.glowingLine * 0.2
property color fontColor: parent.fontColor // Fast burnin properties
property color backgroundColor: parent.backgroundColor property real burnIn: appSettings.burnIn
property real screenCurvature: parent.screenCurvature property real burnInLastUpdate: burnInEffect.lastUpdate
property real chromaColor: parent.chromaColor property real burnInTime: burnInEffect.burnInFadeTime
property real ambientLight: parent.ambientLight
property real flickering: appSettings.flickering property real jitter: appSettings.jitter
property real horizontalSync: appSettings.horizontalSync property size jitterDisplacement: Qt.size(0.007 * jitter, 0.002 * jitter)
property real horizontalSyncStrength: Utils.lint(0.05, 0.35, horizontalSync) property real staticNoise: appSettings.staticNoise
property real glowingLine: appSettings.glowingLine * 0.2 property size scaleNoiseSize: Qt.size((width * 0.75) / (noiseTexture.width * appSettings.windowScaling * appSettings.totalFontScaling),
(height * 0.75) / (noiseTexture.height * appSettings.windowScaling * appSettings.totalFontScaling))
property size virtualResolution: parent.virtualResolution
// Rasterization might display oversamping issues if virtual resolution is close to physical display resolution.
// We progressively disable rasterization from 4x up to 2x resolution.
property real rasterizationIntensity: Utils.smoothstep(2.0, 4.0, _screenDensity)
property real time: timeManager ? timeManager.time : 0
property ShaderEffectSource noiseSource: noiseShaderSource
property real frameSize: parent.frameSize
property real frameShininess: appSettings.frameShininess
property real bloom: parent.bloomSource ? appSettings.bloom * 2.5 : 0
anchors.fill: parent
blending: false
Image {
id: noiseTexture
source: "images/allNoise512.png"
width: 512
height: 512
fillMode: Image.Tile
visible: false
}
ShaderEffectSource {
id: noiseShaderSource
sourceItem: noiseTexture
wrapMode: ShaderEffectSource.Repeat
visible: false
smooth: true
}
vertexShader: "qrc:/shaders/terminal_dynamic.vert.qsb"
fragmentShader: dynamicFragmentPath()
onStatusChanged: if (log) console.log(log)
}
Loader {
id: terminalFrameLoader
active: appSettings.frameEnabled
width: staticShader.width
height: staticShader.height
sourceComponent: ShaderEffectSource {
sourceItem: terminalFrame
hideSource: true
visible: false
format: ShaderEffectSource.RGBA
TerminalFrame {
id: terminalFrame
blending: false
anchors.fill: parent
}
}
}
ShaderEffect {
id: staticShader
width: parent.width * appSettings.windowScaling
height: parent.height * appSettings.windowScaling
property ShaderEffectSource source: parent.source
property ShaderEffectSource bloomSource: parent.bloomSource
property color fontColor: parent.fontColor
property color backgroundColor: parent.backgroundColor
property real bloom: bloomSource ? appSettings.bloom * 2.5 : 0
// Fast burnin properties property real screenCurvature: parent.screenCurvature
property real burnIn: appSettings.burnIn
property real burnInLastUpdate: burnInEffect.lastUpdate property real chromaColor: appSettings.chromaColor;
property real burnInTime: burnInEffect.burnInFadeTime
property real jitter: appSettings.jitter property real rgbShift: appSettings.rgbShift * (4.0 / width) * appSettings.totalFontScaling
property size jitterDisplacement: Qt.size(0.007 * jitter, 0.002 * jitter)
property real shadowLength: 0.25 * screenCurvature * Utils.lint(0.50, 1.5, ambientLight) property real screen_brightness: Utils.lint(0.5, 1.5, appSettings.brightness)
property real staticNoise: appSettings.staticNoise property real frameShininess: appSettings.frameShininess
property size scaleNoiseSize: Qt.size((width * 0.75) / (noiseTexture.width * appSettings.windowScaling * appSettings.totalFontScaling), property real frameSize: parent.frameSize
(height * 0.75) / (noiseTexture.height * appSettings.windowScaling * appSettings.totalFontScaling))
property size virtualResolution: parent.virtualResolution blending: false
visible: false
// Rasterization might display oversamping issues if virtual resolution is close to physical display resolution. vertexShader: "qrc:/shaders/terminal_static.vert.qsb"
// We progressively disable rasterization from 4x up to 2x resolution. fragmentShader: staticFragmentPath()
property real rasterizationIntensity: Utils.smoothstep(2.0, 4.0, _screenDensity)
property real displayTerminalFrame: appSettings._frameMargin > 0 || appSettings.screenCurvature > 0 onStatusChanged: if (log) console.log(log)
}
property real time: timeManager.time ShaderEffectSource {
property ShaderEffectSource noiseSource: noiseShaderSource id: frameBuffer
visible: false
// If something goes wrong activate the fallback version of the shader. sourceItem: staticShader
property bool fallBack: false hideSource: true
}
anchors.fill: parent
blending: false
//Smooth random texture used for flickering effect.
Image {
id: noiseTexture
source: "images/allNoise512.png"
width: 512
height: 512
fillMode: Image.Tile
visible: false
}
ShaderEffectSource {
id: noiseShaderSource
sourceItem: noiseTexture
wrapMode: ShaderEffectSource.Repeat
visible: false
smooth: true
}
//Print the number with a reasonable precision for the shader.
function str(num){
return num.toFixed(8);
}
vertexShader: "
uniform highp mat4 qt_Matrix;
uniform highp float time;
attribute highp vec4 qt_Vertex;
attribute highp vec2 qt_MultiTexCoord0;
varying highp vec2 qt_TexCoord0;" +
(!fallBack ? "
uniform sampler2D noiseSource;" : "") +
(!fallBack && flickering !== 0.0 ?"
varying lowp float brightness;
uniform lowp float flickering;" : "") +
(!fallBack && horizontalSync !== 0.0 ?"
uniform lowp float horizontalSyncStrength;
varying lowp float distortionScale;
varying lowp float distortionFreq;" : "") +
"
void main() {
qt_TexCoord0 = qt_MultiTexCoord0;
vec2 coords = vec2(fract(time/(1024.0*2.0)), fract(time/(1024.0*1024.0)));" +
(!fallBack && (flickering !== 0.0 || horizontalSync !== 0.0) ?
"vec4 initialNoiseTexel = texture2D(noiseSource, coords);"
: "") +
(!fallBack && flickering !== 0.0 ? "
brightness = 1.0 + (initialNoiseTexel.g - 0.5) * flickering;"
: "") +
(!fallBack && horizontalSync !== 0.0 ? "
float randval = horizontalSyncStrength - initialNoiseTexel.r;
distortionScale = step(0.0, randval) * randval * horizontalSyncStrength;
distortionFreq = mix(4.0, 40.0, initialNoiseTexel.g);"
: "") +
"gl_Position = qt_Matrix * qt_Vertex;
}"
fragmentShader: "
#ifdef GL_ES
precision mediump float;
#endif
uniform sampler2D screenBuffer;
uniform highp float qt_Opacity;
uniform highp float time;
varying highp vec2 qt_TexCoord0;
uniform highp vec4 fontColor;
uniform highp vec4 backgroundColor;
uniform lowp float shadowLength;
uniform highp vec2 virtualResolution;
uniform lowp float rasterizationIntensity;\n" +
(burnIn !== 0 ? "
uniform sampler2D burnInSource;
uniform highp float burnInLastUpdate;
uniform highp float burnInTime;" : "") +
(staticNoise !== 0 ? "
uniform highp float staticNoise;" : "") +
(((staticNoise !== 0 || jitter !== 0) ||(fallBack && (flickering || horizontalSync))) ? "
uniform lowp sampler2D noiseSource;
uniform highp vec2 scaleNoiseSize;" : "") +
(displayTerminalFrame ? "
uniform lowp sampler2D frameSource;" : "") +
(screenCurvature !== 0 ? "
uniform highp float screenCurvature;" : "") +
(glowingLine !== 0 ? "
uniform highp float glowingLine;" : "") +
(chromaColor !== 0 ? "
uniform lowp float chromaColor;" : "") +
(jitter !== 0 ? "
uniform lowp vec2 jitterDisplacement;" : "") +
(ambientLight !== 0 ? "
uniform lowp float ambientLight;" : "") +
(fallBack && horizontalSync !== 0 ? "
uniform lowp float horizontalSyncStrength;" : "") +
(fallBack && flickering !== 0.0 ?"
uniform lowp float flickering;" : "") +
(!fallBack && flickering !== 0 ? "
varying lowp float brightness;"
: "") +
(!fallBack && horizontalSync !== 0 ? "
varying lowp float distortionScale;
varying lowp float distortionFreq;" : "") +
(glowingLine !== 0 ? "
float randomPass(vec2 coords){
return fract(smoothstep(-120.0, 0.0, coords.y - (virtualResolution.y + 120.0) * fract(time * 0.00015)));
}" : "") +
shaderLibrary.min2 +
shaderLibrary.rgb2grey +
shaderLibrary.rasterizationShader +
"
float isInScreen(vec2 v) {
return min2(step(0.0, v) - step(1.0, v));
}
vec2 barrel(vec2 v, vec2 cc) {" +
(screenCurvature !== 0 ? "
float distortion = dot(cc, cc) * screenCurvature;
return (v - cc * (1.0 + distortion) * distortion);"
:
"return v;") +
"}" +
"vec3 convertWithChroma(vec3 inColor) {
vec3 outColor = inColor;" +
(chromaColor !== 0 ?
"outColor = fontColor.rgb * mix(vec3(rgb2grey(inColor)), inColor, chromaColor);"
:
"outColor = fontColor.rgb * rgb2grey(inColor);") +
" return outColor;
}" +
"void main() {" +
"vec2 cc = vec2(0.5) - qt_TexCoord0;" +
"float distance = length(cc);" +
//FallBack if there are problems
(fallBack && (flickering !== 0.0 || horizontalSync !== 0.0) ?
"vec2 initialCoords = vec2(fract(time/(1024.0*2.0)), fract(time/(1024.0*1024.0)));
vec4 initialNoiseTexel = texture2D(noiseSource, initialCoords);"
: "") +
(fallBack && flickering !== 0.0 ? "
float brightness = 1.0 + (initialNoiseTexel.g - 0.5) * flickering;"
: "") +
(fallBack && horizontalSync !== 0.0 ? "
float randval = horizontalSyncStrength - initialNoiseTexel.r;
float distortionScale = step(0.0, randval) * randval * horizontalSyncStrength;
float distortionFreq = mix(4.0, 40.0, initialNoiseTexel.g);"
: "") +
(staticNoise ? "
float noise = staticNoise;" : "") +
(screenCurvature !== 0 ? "
vec2 staticCoords = barrel(qt_TexCoord0, cc);"
:"
vec2 staticCoords = qt_TexCoord0;") +
"vec2 coords = qt_TexCoord0;" +
(horizontalSync !== 0 ? "
float dst = sin((coords.y + time * 0.001) * distortionFreq);
coords.x += dst * distortionScale;" +
(staticNoise ? "
noise += distortionScale * 7.0;" : "")
: "") +
(jitter !== 0 || staticNoise !== 0 ?
"vec4 noiseTexel = texture2D(noiseSource, scaleNoiseSize * coords + vec2(fract(time / 51.0), fract(time / 237.0)));"
: "") +
(jitter !== 0 ? "
vec2 offset = vec2(noiseTexel.b, noiseTexel.a) - vec2(0.5);
vec2 txt_coords = coords + offset * jitterDisplacement;"
: "vec2 txt_coords = coords;") +
"float color = 0.0001;" +
(staticNoise !== 0 ? "
float noiseVal = noiseTexel.a;
color += noiseVal * noise * (1.0 - distance * 1.3);" : "") +
(glowingLine !== 0 ? "
color += randomPass(coords * virtualResolution) * glowingLine;" : "") +
"vec3 txt_color = texture2D(screenBuffer, txt_coords).rgb;" +
(burnIn !== 0 ? "
vec4 txt_blur = texture2D(burnInSource, staticCoords);
float blurDecay = clamp((time - burnInLastUpdate) * burnInTime, 0.0, 1.0);
vec3 burnInColor = 0.65 * (txt_blur.rgb - vec3(blurDecay));
txt_color = max(txt_color, convertWithChroma(burnInColor));"
: "") +
"txt_color += fontColor.rgb * vec3(color);" +
"txt_color = applyRasterization(staticCoords, txt_color, virtualResolution, rasterizationIntensity);\n" +
"vec3 finalColor = txt_color;" +
(flickering !== 0 ? "
finalColor *= brightness;" : "") +
(ambientLight !== 0 ? "
finalColor += vec3(ambientLight) * (1.0 - distance) * (1.0 - distance);" : "") +
(displayTerminalFrame ?
"vec4 frameColor = texture2D(frameSource, qt_TexCoord0);
finalColor = mix(finalColor, frameColor.rgb, frameColor.a);"
: "") +
"gl_FragColor = vec4(finalColor, qt_Opacity);" +
"}"
onStatusChanged: {
// Print warning messages
if (log)
console.log(log);
// Activate fallback mode
if (status == ShaderEffect.Error) {
fallBack = true;
}
}
}
Loader {
id: terminalFrameLoader
active: dynamicShader.displayTerminalFrame
width: staticShader.width
height: staticShader.height
sourceComponent: ShaderEffectSource {
sourceItem: terminalFrame
hideSource: true
visible: false
format: ShaderEffectSource.RGBA
TerminalFrame {
id: terminalFrame
blending: false
anchors.fill: parent
}
}
}
ShaderLibrary {
id: shaderLibrary
}
ShaderEffect {
id: staticShader
width: parent.width * appSettings.windowScaling
height: parent.height * appSettings.windowScaling
property ShaderEffectSource source: parent.source
property ShaderEffectSource bloomSource: parent.bloomSource
property color fontColor: parent.fontColor
property color backgroundColor: parent.backgroundColor
property real bloom: appSettings.bloom * 2.5
property real screenCurvature: parent.screenCurvature
property real chromaColor: appSettings.chromaColor;
property real rbgShift: (appSettings.rbgShift / width) * appSettings.totalFontScaling // TODO FILIPPO width here is wrong.
property int rasterization: appSettings.rasterization
property real screen_brightness: Utils.lint(0.5, 1.5, appSettings.brightness)
property real ambientLight: parent.ambientLight
property size virtualResolution: parent.virtualResolution
blending: false
visible: false
//Print the number with a reasonable precision for the shader.
function str(num){
return num.toFixed(8);
}
fragmentShader: "
#ifdef GL_ES
precision mediump float;
#endif
uniform sampler2D source;
uniform highp float qt_Opacity;
varying highp vec2 qt_TexCoord0;
uniform highp vec4 fontColor;
uniform highp vec4 backgroundColor;
uniform lowp float screen_brightness;
uniform highp vec2 virtualResolution;" +
(bloom !== 0 ? "
uniform highp sampler2D bloomSource;
uniform lowp float bloom;" : "") +
(screenCurvature !== 0 ? "
uniform highp float screenCurvature;" : "") +
(chromaColor !== 0 ? "
uniform lowp float chromaColor;" : "") +
(rbgShift !== 0 ? "
uniform lowp float rbgShift;" : "") +
(ambientLight !== 0 ? "
uniform lowp float ambientLight;" : "") +
shaderLibrary.min2 +
shaderLibrary.sum2 +
shaderLibrary.rgb2grey +
"vec3 convertWithChroma(vec3 inColor) {
vec3 outColor = inColor;" +
(chromaColor !== 0 ?
"outColor = fontColor.rgb * mix(vec3(rgb2grey(inColor)), inColor, chromaColor);"
:
"outColor = fontColor.rgb * rgb2grey(inColor);") +
" return outColor;
}" +
shaderLibrary.rasterizationShader +
"void main() {" +
"vec2 cc = vec2(0.5) - qt_TexCoord0;" +
(screenCurvature !== 0 ? "
float distortion = dot(cc, cc) * screenCurvature;
vec2 curvatureCoords = (qt_TexCoord0 - cc * (1.0 + distortion) * distortion);
vec2 txt_coords = - 2.0 * curvatureCoords + 3.0 * step(vec2(0.0), curvatureCoords) * curvatureCoords - 3.0 * step(vec2(1.0), curvatureCoords) * curvatureCoords;"
:"
vec2 txt_coords = qt_TexCoord0;") +
"vec3 txt_color = texture2D(source, txt_coords).rgb;" +
(rbgShift !== 0 ? "
vec2 displacement = vec2(12.0, 0.0) * rbgShift;
vec3 rightColor = texture2D(source, txt_coords + displacement).rgb;
vec3 leftColor = texture2D(source, txt_coords - displacement).rgb;
txt_color.r = leftColor.r * 0.10 + rightColor.r * 0.30 + txt_color.r * 0.60;
txt_color.g = leftColor.g * 0.20 + rightColor.g * 0.20 + txt_color.g * 0.60;
txt_color.b = leftColor.b * 0.30 + rightColor.b * 0.10 + txt_color.b * 0.60;
" : "") +
"txt_color += vec3(0.0001);" +
"float greyscale_color = rgb2grey(txt_color);" +
(screenCurvature !== 0 ? "
float reflectionMask = sum2(step(vec2(0.0), curvatureCoords) - step(vec2(1.0), curvatureCoords));
reflectionMask = clamp(reflectionMask, 0.0, 1.0);"
:
"float reflectionMask = 1.0;") +
(chromaColor !== 0 ?
"vec3 foregroundColor = mix(fontColor.rgb, txt_color * fontColor.rgb / greyscale_color, chromaColor);
vec3 finalColor = mix(backgroundColor.rgb, foregroundColor, greyscale_color * reflectionMask);"
:
"vec3 finalColor = mix(backgroundColor.rgb, fontColor.rgb, greyscale_color * reflectionMask);") +
(bloom !== 0 ?
"vec4 bloomFullColor = texture2D(bloomSource, txt_coords);
vec3 bloomColor = bloomFullColor.rgb;
float bloomAlpha = bloomFullColor.a;
bloomColor = convertWithChroma(bloomColor);
finalColor += clamp(bloomColor * bloom * bloomAlpha, 0.0, 0.5);"
: "") +
"finalColor *= screen_brightness;" +
"gl_FragColor = vec4(finalColor, qt_Opacity);" +
"}"
onStatusChanged: {
// Print warning messages
if (log) console.log(log);
}
}
ShaderEffectSource {
id: frameBuffer
visible: false
sourceItem: staticShader
hideSource: true
}
} }

View File

@@ -21,15 +21,13 @@ import QtQuick 2.2
Rectangle { Rectangle {
property size terminalSize property size terminalSize
property real topOpacity: 0.6 property real topOpacity: 0.5
width: textSize.width * 2 width: textSize.width * 2
height: textSize.height * 2 height: textSize.height * 2
radius: 5 radius: 5
border.width: 2
border.color: "white"
color: "black" color: "black"
opacity: sizetimer.running ? 0.6 : 0.0 opacity: sizetimer.running ? 0.5 : 0.0
Behavior on opacity { Behavior on opacity {
NumberAnimation { NumberAnimation {

View File

@@ -22,7 +22,7 @@ import QtQuick 2.2
import QtQuick.LocalStorage 2.0 import QtQuick.LocalStorage 2.0
QtObject { QtObject {
readonly property string dbMajorVersion: "1" readonly property string dbMajorVersion: "2"
readonly property string dbMinorVersion: "1.0" readonly property string dbMinorVersion: "1.0"
property bool initialized: false property bool initialized: false

View File

@@ -18,15 +18,23 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/ *******************************************************************************/
import QtQuick 2.2 import QtQuick 2.2
import QtGraphicalEffects 1.0 import Qt5Compat.GraphicalEffects
import "utils.js" as Utils import "utils.js" as Utils
ShaderTerminal { ShaderTerminal {
property alias title: terminal.title property alias title: terminal.title
property alias terminalSize: terminal.terminalSize property alias terminalSize: terminal.terminalSize
signal sessionFinished()
property real devicePixelRatio: terminalWindow.screen.devicePixelRatio property bool loadBloomEffect: appSettings.bloom > 0 || appSettings._frameShininess > 0
property bool hasFocus
onHasFocusChanged: {
if (hasFocus) {
activate()
}
}
id: mainShader id: mainShader
opacity: appSettings.windowOpacity * 0.3 + 0.7 opacity: appSettings.windowOpacity * 0.3 + 0.7
@@ -35,24 +43,25 @@ ShaderTerminal {
burnInEffect: terminal.burnInEffect burnInEffect: terminal.burnInEffect
virtualResolution: terminal.virtualResolution virtualResolution: terminal.virtualResolution
screenResolution: Qt.size( screenResolution: Qt.size(
terminalWindow.width * devicePixelRatio * appSettings.windowScaling, terminalWindow.width * Screen.devicePixelRatio * appSettings.windowScaling,
terminalWindow.height * devicePixelRatio * appSettings.windowScaling terminalWindow.height * Screen.devicePixelRatio * appSettings.windowScaling
) )
bloomSource: bloomSourceLoader.item
TimeManager {
id: timeManager
enableTimer: terminalWindow.visible
}
PreprocessedTerminal { PreprocessedTerminal {
id: terminal id: terminal
anchors.fill: parent anchors.fill: parent
onSessionFinished: mainShader.sessionFinished()
}
function activate() {
terminal.mainTerminal.forceActiveFocus()
} }
// EFFECTS //////////////////////////////////////////////////////////////// // EFFECTS ////////////////////////////////////////////////////////////////
Loader { Loader {
id: bloomEffectLoader id: bloomEffectLoader
active: appSettings.bloom active: loadBloomEffect
asynchronous: true asynchronous: true
width: parent.width * appSettings.bloomQuality width: parent.width * appSettings.bloomQuality
height: parent.height * appSettings.bloomQuality height: parent.height * appSettings.bloomQuality
@@ -65,16 +74,15 @@ ShaderTerminal {
} }
Loader { Loader {
id: bloomSourceLoader id: bloomSourceLoader
active: appSettings.bloom !== 0 active: loadBloomEffect
asynchronous: true asynchronous: true
sourceComponent: ShaderEffectSource { sourceComponent: ShaderEffectSource {
id: _bloomEffectSource id: _bloomEffectSource
sourceItem: bloomEffectLoader.item sourceItem: bloomEffectLoader.item
wrapMode: ShaderEffectSource.Repeat
hideSource: true hideSource: true
smooth: true smooth: true
visible: false visible: false
} }
} }
bloomSource: bloomSourceLoader.item
} }

View File

@@ -22,83 +22,31 @@ import QtQuick 2.0
import "utils.js" as Utils import "utils.js" as Utils
ShaderEffect { ShaderEffect {
property color _staticFrameColor: "#fff" property color _staticFrameColor: Utils.sum(appSettings.frameColor, Qt.rgba(0.1, 0.1, 0.1, 1.0))
property color _backgroundColor: appSettings.backgroundColor property color _backgroundColor: appSettings.backgroundColor
property color _fontColor: appSettings.fontColor property color _fontColor: appSettings.fontColor
property color _lightColor: Utils.mix(_fontColor, _backgroundColor, 0.2) property color _lightColor: Utils.mix(_fontColor, _backgroundColor, 0.2)
property real _ambientLight: Utils.lint(0.2, 0.8, appSettings.ambientLight)
property color frameColor: Utils.mix(_staticFrameColor, _lightColor, _ambientLight) property color frameColor: Utils.mix(
property real screenCurvature: appSettings.screenCurvature * appSettings.screenCurvatureSize Utils.scaleColor(_lightColor, 0.2),
_staticFrameColor,
// Coefficient of the log curve used to approximate shadowing 0.125 + 0.750 * ambientLight
property real screenShadowCoeff: Utils.lint(20.0, 10.0, _ambientLight)
property real frameShadowCoeff: Utils.lint(20.0, 10.0, _ambientLight)
property size margin: Qt.size(
appSettings.frameMargin / width * appSettings.windowScaling,
appSettings.frameMargin / height * appSettings.windowScaling
) )
ShaderLibrary { property real screenCurvature: appSettings.screenCurvature * appSettings.screenCurvatureSize * terminalWindow.normalizedWindowScale
id: shaderLibrary
}
fragmentShader: " property real frameShininess: appSettings.frameShininess
#ifdef GL_ES
precision mediump float;
#endif
uniform lowp float screenCurvature; property real frameSize: appSettings.frameSize * terminalWindow.normalizedWindowScale
uniform lowp float screenShadowCoeff;
uniform lowp float frameShadowCoeff;
uniform highp float qt_Opacity;
uniform lowp vec4 frameColor;
uniform mediump vec2 margin;
varying highp vec2 qt_TexCoord0; property real screenRadius: appSettings.screenRadius
vec2 distortCoordinates(vec2 coords){ property size viewportSize: Qt.size(width / appSettings.windowScaling, height / appSettings.windowScaling)
vec2 cc = (coords - vec2(0.5));
float dist = dot(cc, cc) * screenCurvature;
return (coords + cc * (1.0 + dist) * dist);
}
" +
shaderLibrary.max2 + property real ambientLight: appSettings.ambientLight
shaderLibrary.min2 +
shaderLibrary.prod2 +
shaderLibrary.sum2 +
" vertexShader: "qrc:/shaders/terminal_frame.vert.qsb"
fragmentShader: "qrc:/shaders/terminal_frame.frag.qsb"
vec2 positiveLog(vec2 x) {
return clamp(log(x), vec2(0.0), vec2(100.0));
}
void main() {
vec2 staticCoords = qt_TexCoord0;
vec2 coords = distortCoordinates(staticCoords) * (vec2(1.0) + margin * 2.0) - margin;
vec2 vignetteCoords = staticCoords * (1.0 - staticCoords.yx);
float vignette = pow(prod2(vignetteCoords) * 15.0, 0.25);
vec3 color = frameColor.rgb * vec3(1.0 - vignette);
float alpha = 0.0;
float frameShadow = max2(positiveLog(-coords * frameShadowCoeff + vec2(1.0)) + positiveLog(coords * frameShadowCoeff - (vec2(frameShadowCoeff) - vec2(1.0))));
frameShadow = max(sqrt(frameShadow), 0.0);
color *= frameShadow;
alpha = sum2(1.0 - step(vec2(0.0), coords) + step(vec2(1.0), coords));
alpha = clamp(alpha, 0.0, 1.0);
alpha *= mix(1.0, 0.9, frameShadow);
float screenShadow = 1.0 - prod2(positiveLog(coords * screenShadowCoeff + vec2(1.0)) * positiveLog(-coords * screenShadowCoeff + vec2(screenShadowCoeff + 1.0)));
alpha = max(0.8 * screenShadow, alpha);
gl_FragColor = vec4(color * alpha, alpha);
}
"
onStatusChanged: if (log) console.log(log) //Print warning messages onStatusChanged: if (log) console.log(log) //Print warning messages
} }

153
app/qml/TerminalTabs.qml Normal file
View File

@@ -0,0 +1,153 @@
/*******************************************************************************
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term
*
* This file is part of cool-retro-term.
*
* cool-retro-term is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQml.Models
Item {
id: tabsRoot
readonly property int innerPadding: 6
readonly property string currentTitle: tabsModel.get(currentIndex).title ?? "cool-retro-term"
property alias currentIndex: tabBar.currentIndex
readonly property int count: tabsModel.count
property size terminalSize: Qt.size(0, 0)
function normalizeTitle(rawTitle) {
if (rawTitle === undefined || rawTitle === null) {
return ""
}
return String(rawTitle).trim()
}
function addTab() {
tabsModel.append({ title: "" })
tabBar.currentIndex = tabsModel.count - 1
}
function closeTab(index) {
if (tabsModel.count <= 1) {
terminalWindow.close()
return
}
tabsModel.remove(index)
tabBar.currentIndex = Math.min(tabBar.currentIndex, tabsModel.count - 1)
}
ListModel {
id: tabsModel
}
Component.onCompleted: addTab()
ColumnLayout {
anchors.fill: parent
spacing: 0
Rectangle {
id: tabRow
Layout.fillWidth: true
height: rowLayout.implicitHeight
color: palette.window
visible: tabsModel.count > 1
RowLayout {
id: rowLayout
anchors.fill: parent
spacing: 0
TabBar {
id: tabBar
Layout.fillWidth: true
Layout.fillHeight: true
focusPolicy: Qt.NoFocus
Repeater {
model: tabsModel
TabButton {
id: tabButton
contentItem: RowLayout {
anchors.fill: parent
anchors { leftMargin: innerPadding; rightMargin: innerPadding }
spacing: innerPadding
Label {
text: model.title
elide: Text.ElideRight
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
}
ToolButton {
text: "\u00d7"
focusPolicy: Qt.NoFocus
padding: innerPadding
Layout.alignment: Qt.AlignVCenter
onClicked: tabsRoot.closeTab(index)
}
}
}
}
}
ToolButton {
id: addTabButton
text: "+"
focusPolicy: Qt.NoFocus
Layout.fillHeight: true
padding: innerPadding
Layout.alignment: Qt.AlignVCenter
onClicked: tabsRoot.addTab()
}
}
}
StackLayout {
id: stack
Layout.fillWidth: true
Layout.fillHeight: true
currentIndex: tabBar.currentIndex
Repeater {
model: tabsModel
TerminalContainer {
id: terminalContainer
hasFocus: terminalWindow.active && StackLayout.isCurrentItem
onTerminalSizeChanged: updateTerminalSize()
onTitleChanged: tabsModel.setProperty(index, "title", normalizeTitle(title))
Layout.fillWidth: true
Layout.fillHeight: true
onSessionFinished: tabsRoot.closeTab(index)
function updateTerminalSize() {
// Every tab will have the same size so we can simply take the first one.
if (index == 0) {
tabsRoot.terminalSize = terminalSize
}
}
}
}
}
}
}

View File

@@ -0,0 +1,88 @@
/*******************************************************************************
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
* https://github.com/Swordfish90/cool-retro-term
*
* This file is part of cool-retro-term.
*
* cool-retro-term is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
import QtQuick 2.2
import QtQuick.Window 2.1
import QtQuick.Controls 2.3
import QtQml
import "menus"
ApplicationWindow {
id: terminalWindow
width: 1024
height: 768
// Show the window once it is ready.
Component.onCompleted: {
visible = true
}
minimumWidth: 320
minimumHeight: 240
visible: false
property bool fullscreen: false
onFullscreenChanged: visibility = (fullscreen ? Window.FullScreen : Window.Windowed)
menuBar: qtquickMenuLoader.item
Loader {
id: qtquickMenuLoader
active: !appSettings.isMacOS && (appSettings.showMenubar && !fullscreen)
sourceComponent: WindowMenu { }
}
Connections {
target: newTabAction
enabled: terminalWindow.active
onTriggered: terminalTabs.addTab()
}
Connections {
target: fullscreenAction
enabled: terminalWindow.active
onTriggered: terminalWindow.fullscreen = !terminalWindow.fullscreen
}
property real normalizedWindowScale: 1024 / ((0.5 * width + 0.5 * height))
color: "#00000000"
title: terminalTabs.currentTitle
TerminalTabs {
id: terminalTabs
width: parent.width
height: (parent.height + Math.abs(y))
}
Loader {
anchors.centerIn: parent
active: appSettings.showTerminalSize
sourceComponent: SizeOverlay {
z: 3
terminalSize: terminalTabs.terminalSize
}
}
onClosing: {
appRoot.closeWindow(terminalWindow)
}
}

View File

@@ -17,22 +17,29 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/ *******************************************************************************/
import QtQuick 2.2 import QtQuick
Timer { QtObject {
default property bool enableTimer: false id: timeManager
property real time
NumberAnimation on time { property bool enableTimer: false
from: 0 property real time: 0
to: 100000
running: appSettings.fps === 0 && enableTimer property int framesPerUpdate: Math.max(1, appSettings.effectsFrameSkip)
duration: 100000 property int _frameCounter: 0
loops: Animation.Infinite
property var frameDriver: FrameAnimation {
running: enableTimer
onTriggered: {
timeManager._frameCounter += 1
if (timeManager._frameCounter >= timeManager.framesPerUpdate) {
time = elapsedTime
timeManager._frameCounter = 0
}
}
} }
onTriggered: time += interval onEnableTimerChanged: if (!enableTimer) _frameCounter = 0
running: appSettings.fps !== 0 && enableTimer onFramesPerUpdateChanged: _frameCounter = 0
interval: Math.round(1000 / appSettings.fps)
repeat: true
} }

View File

@@ -1,8 +0,0 @@
Fonts in this package are (c) 2010-2014 Style.
This license is applicable to each font file included in this package in all their variants (ttf, eot, woff, woff2, svg).
You MAY NOT: sell this font; include/redistribute the font in any font collection regardless of pricing; provide the font for direct download from any web site, modify or rename the font. You MAY: link to "http://style64.org/c64-truetype" in order for others to download and install the font; embed the font (without any modification or file renaming) for display on any web site using @font-face rules; use this font in static images and vector art; include this font (without any modification or file renaming) as part of a software package but ONLY if said software package is freely provided to end users. You may also contact us to negotiate a (possibly commercial) license for your use outside of these guidelines at "http://style64.org/contact-style".
At all times the most recent version of this license can be found at "http://style64.org/c64-truetype/license".

Binary file not shown.

View File

@@ -0,0 +1,93 @@
Copyright 20222024 Helena Zhang (helenazhang.com).
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
https://openfontlicense.org
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

View File

@@ -1,94 +1,93 @@
Copyright (c) 2013, Pablo Caro <me AT pcaro DOT es> - http://pcaro.es/ Copyright (c) 2014, The Fira Code Project Authors (https://github.com/tonsky/FiraCode)
with Reserved Font Name Hermit.
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at:
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
http://scripts.sil.org/OFL
-----------------------------------------------------------
----------------------------------------------------------- SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 -----------------------------------------------------------
-----------------------------------------------------------
PREAMBLE
PREAMBLE The goals of the Open Font License (OFL) are to stimulate worldwide
The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation
development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and
efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership
open framework in which fonts may be shared and improved in partnership with others.
with others.
The OFL allows the licensed fonts to be used, studied, modified and
The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The
redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded,
fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved
redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives,
names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The
however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply
requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
to any document created using the fonts or their derivatives.
DEFINITIONS
DEFINITIONS "Font Software" refers to the set of files released by the Copyright
"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may
Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the
or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a
Original Version, by changing formats or by porting the Font Software to a new environment.
new environment.
"Author" refers to any designer, engineer, programmer, technical
"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
PERMISSION & CONDITIONS Permission is hereby granted, free of charge, to any person obtaining
Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify,
a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font
redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy
redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be
contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or
included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or
in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding
Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as
Copyright Holder. This restriction only applies to the primary font name as presented to the users.
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any
Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the
Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written
Copyright Holder(s) and the Author(s) or with their explicit written permission.
permission.
5) The Font Software, modified or unmodified, in part or in whole,
5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be
must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to
distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created
remain under this license does not apply to any document created using the Font Software.
using the Font Software.
TERMINATION
TERMINATION This license becomes null and void if any of the above conditions are
This license becomes null and void if any of the above conditions are not met.
not met.
DISCLAIMER
DISCLAIMER THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
OTHER DEALINGS IN THE FONT SOFTWARE.

Binary file not shown.

View File

@@ -0,0 +1,13 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar
14 rue de Plaisance, 75014 Paris, France
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.

Binary file not shown.

Binary file not shown.

View File

@@ -1,7 +1,7 @@
ProFont
MIT License MIT License
Copyright (c) 2014 Carl Osterwald, Stephen C. Gilardi, Andrew Welch Copyright (c) 2012-2015 Uwe Waldmann
Modified work Copyright 2018 Andy Walker
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -10,13 +10,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in all
all copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
THE SOFTWARE. SOFTWARE.

Binary file not shown.

View File

@@ -0,0 +1,45 @@
The work in the Hack project is Copyright 2018 Source Foundry Authors and licensed under the MIT License
The work in the DejaVu project was committed to the public domain.
Bitstream Vera Sans Mono Copyright 2003 Bitstream Inc. and licensed under the Bitstream Vera License with Reserved Font Names "Bitstream" and "Vera"
### MIT License
Copyright (c) 2018 Source Foundry Authors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
### BITSTREAM VERA LICENSE
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions:
The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces.
The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera".
This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names.
The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself.
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.

Binary file not shown.

View File

@@ -1,4 +1,6 @@
Copyright (c) 2011-2017, Ricardo Banffy. Copyright 2022 The 3270font Authors (https://github.com/rbanffy/3270font)
Copyright (c) 2011-2022, Ricardo Banffy.
Copyright (c) 1993-2011, Paul Mattes. Copyright (c) 1993-2011, Paul Mattes.
Copyright (c) 2004-2005, Don Russell. Copyright (c) 2004-2005, Don Russell.
Copyright (c) 2004, Dick Altenbern. Copyright (c) 2004, Dick Altenbern.
@@ -10,27 +12,27 @@ Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are modification, are permitted provided that the following conditions are
met: met:
* Redistributions of source code must retain the above copyright notice, * Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer. this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, * Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution. and/or other materials provided with the distribution.
* Neither the name of Ricardo Banffy, Paul Mattes, Don Russell, * Neither the name of Ricardo Banffy, Paul Mattes, Don Russell,
Dick Altenbern, Jeff Sparkes, GTRC nor the names of their contributors Dick Altenbern, Jeff Sparkes, GTRC nor the names of their contributors
may be used to endorse or promote products derived from this software may be used to endorse or promote products derived from this software
without specific prior written permission. without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL RICARDO BANFFY, PAUL MATTES, DON RUSSELL, DICK ALTENBERN, JEFF IN NO EVENT SHALL RICARDO BANFFY, PAUL MATTES, DON RUSSELL, DICK ALTENBERN, JEFF
SPARKES OR GTRC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, SPARKES OR GTRC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The Debian Logo glyph is based on the Debian Open Use Logo and is The Debian Logo glyph is based on the Debian Open Use Logo and is

View File

@@ -0,0 +1,110 @@
Copyright (c) 2015-2023, Renzhi Li (aka. Belleve Invis, belleve@typeof.net)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
--------------------------
SIL Open Font License v1.1
====================================================
Preamble
----------
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
Definitions
-------------
`"Font Software"` refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
`"Reserved Font Name"` refers to any names specified as such after the
copyright statement(s).
`"Original Version"` refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
`"Modified Version"` refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
`"Author"` refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
Permission & Conditions
------------------------
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1. Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2. Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3. No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4. The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5. The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
Termination
-----------
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

View File

@@ -0,0 +1,93 @@
Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
https://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

View File

@@ -1,31 +0,0 @@
WHAT IS THIS?
This is ProFont TrueType, converted to Windows TrueType format
by Mike Smith, with some tweaks added by "ardu".
Modifications include:
- A Euro character
- Missing characters from the Latin 1 code page
- Full support for CodePage 850. These are mostly the famous
block/box characters you know from DOS. Very useful if you use
Mightnight Commander through PuTTY.
- Fixed metrics so that point size of 9 works correctly. Until now
you had to select 7 to obtain the native point size of 9.
- Added some quick&dirty hinting for point size of 9. Most characters
now match closely the look of the bitmap version.
Don't expect it to look good on anything else than Windows...
To get the full original Distribution, other ProFont builds
and more information
go to <http://tobiasjung.name/profont/>
DISCLAIMER
See LICENSE file
Tobias Jung
January 2014
profont@tobiasjung.name

View File

@@ -1,7 +0,0 @@
Copyright (c) 2004, 2005 Tristan Grimmer
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,22 @@
License
-------
The license for this font is:
♡ Copying is an act of love. Please copy.
Bitstream License:
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license (“Fonts”) and associated documentation files (the “Font Software”), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions:
The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces.
The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words “Bitstream” or the word “Vera”.
This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the “Bitstream Vera” names.
The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself.
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.

Binary file not shown.

View File

@@ -0,0 +1,93 @@
Copyright 2010-2020 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries.
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

View File

@@ -1,7 +1,7 @@
Copyright (c) 2010 Dimitar Toshkov Zhekov, Copyright (c) 2010 Dimitar Toshkov Zhekov,
with Reserved Font Name "Terminus Font". with Reserved Font Name "Terminus Font".
Copyright (c) 2011 Tilman Blumenbach, Copyright (c) 2011-2021 Tilman Blumenbach,
with Reserved Font Name "Terminus (TTF)". with Reserved Font Name "Terminus (TTF)".
This Font Software is licensed under the SIL Open Font License, Version 1.1. This Font Software is licensed under the SIL Open Font License, Version 1.1.

View File

@@ -0,0 +1 @@
You can consider it Public Domain (or CC-0) except for the files derived from or containing parts of Roman Czyborra's Unifont project (unifont.hex, hex2bdf.pl, unscii-16-full.*) which fall under GPL. See https://savannah.gnu.org/projects/unifont/ for more.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -18,118 +18,92 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/ *******************************************************************************/
import QtQuick 2.2 import QtQuick 2.2
import QtQuick.Window 2.1
import QtQuick.Controls 2.3 import QtQuick.Controls 2.3
import "menus" import "menus"
ApplicationWindow { QtObject {
id: terminalWindow id: appRoot
width: 1024 property ApplicationSettings appSettings: ApplicationSettings {
height: 768 onInitializedSettings: appRoot.createWindow()
// Save window properties automatically
onXChanged: appSettings.x = x
onYChanged: appSettings.y = y
onWidthChanged: appSettings.width = width
onHeightChanged: appSettings.height = height
// Load saved window geometry and show the window
Component.onCompleted: {
x = appSettings.x
y = appSettings.y
width = appSettings.width
height = appSettings.height
visible = true
} }
minimumWidth: 320 property TimeManager timeManager: TimeManager {
minimumHeight: 240 enableTimer: windowsModel.count > 0
visible: false
property bool fullscreen: appSettings.fullscreen
onFullscreenChanged: visibility = (fullscreen ? Window.FullScreen : Window.Windowed)
menuBar: qtquickMenuLoader.item
Loader {
id: qtquickMenuLoader
active: !appSettings.isMacOS && appSettings.showMenubar
sourceComponent: WindowMenu { }
} }
Loader { property SettingsWindow settingsWindow: SettingsWindow {
id: globalMenuLoader visible: false
}
property AboutDialog aboutDialog: AboutDialog {
visible: false
}
property Component windowComponent: Component {
TerminalWindow { }
}
property ListModel windowsModel: ListModel { }
property Loader globalMenuLoader: Loader {
active: appSettings.isMacOS active: appSettings.isMacOS
sourceComponent: OSXMenu { } sourceComponent: OSXMenu { }
} }
property string wintitle: appSettings.wintitle property Action fullscreenAction: Action {
color: "#00000000"
title: terminalContainer.title || qsTr(appSettings.wintitle)
Action {
id: showMenubarAction
text: qsTr("Show Menubar")
enabled: !appSettings.isMacOS
shortcut: "Ctrl+Shift+M"
checkable: true
checked: appSettings.showMenubar
onTriggered: appSettings.showMenubar = !appSettings.showMenubar
}
Action {
id: fullscreenAction
text: qsTr("Fullscreen") text: qsTr("Fullscreen")
enabled: !appSettings.isMacOS enabled: !appSettings.isMacOS
shortcut: "Alt+F11" shortcut: "Alt+F11"
onTriggered: appSettings.fullscreen = !appSettings.fullscreen
checkable: true
checked: appSettings.fullscreen
} }
Action {
id: quitAction property bool initialFullscreenRequested: Qt.application.arguments.indexOf("--fullscreen") !== -1
property Action newWindowAction: Action {
text: qsTr("New Window")
shortcut: "Ctrl+Shift+N"
onTriggered: appRoot.createWindow()
}
property Action quitAction: Action {
text: qsTr("Quit") text: qsTr("Quit")
shortcut: "Ctrl+Shift+Q" shortcut: "Ctrl+Shift+Q"
onTriggered: Qt.quit() onTriggered: appSettings.close()
} }
Action {
id: showsettingsAction property Action showsettingsAction: Action {
text: qsTr("Settings") text: qsTr("Settings")
onTriggered: { onTriggered: {
settingswindow.show() settingsWindow.show()
settingswindow.requestActivate() settingsWindow.requestActivate()
settingswindow.raise() settingsWindow.raise()
} }
} }
Action {
id: copyAction property Action copyAction: Action {
text: qsTr("Copy") text: qsTr("Copy")
shortcut: "Ctrl+Shift+C" shortcut: "Ctrl+Shift+C"
} }
Action {
id: pasteAction property Action pasteAction: Action {
text: qsTr("Paste") text: qsTr("Paste")
shortcut: "Ctrl+Shift+V" shortcut: "Ctrl+Shift+V"
} }
Action {
id: zoomIn property Action zoomInAction: Action {
text: qsTr("Zoom In") text: qsTr("Zoom In")
shortcut: "Ctrl++" shortcut: "Ctrl++"
onTriggered: appSettings.incrementScaling() onTriggered: appSettings.incrementScaling()
} }
Action {
id: zoomOut property Action zoomOutAction: Action {
text: qsTr("Zoom Out") text: qsTr("Zoom Out")
shortcut: "Ctrl+-" shortcut: "Ctrl+-"
onTriggered: appSettings.decrementScaling() onTriggered: appSettings.decrementScaling()
} }
Action {
id: showAboutAction property Action showAboutAction: Action {
text: qsTr("About") text: qsTr("About")
onTriggered: { onTriggered: {
aboutDialog.show() aboutDialog.show()
@@ -137,34 +111,35 @@ ApplicationWindow {
aboutDialog.raise() aboutDialog.raise()
} }
} }
ApplicationSettings {
id: appSettings property Action newTabAction: Action {
text: qsTr("New Tab")
} }
TerminalContainer {
id: terminalContainer function createWindow() {
width: parent.width var useFullscreen = initialFullscreenRequested
height: (parent.height + Math.abs(y)) var window = windowComponent.createObject(null, { fullscreen: useFullscreen })
if (!window)
return
windowsModel.append({ window: window })
initialFullscreenRequested = false
window.show()
window.requestActivate()
} }
SettingsWindow {
id: settingswindow function closeWindow(window) {
visible: false for (var i = 0; i < windowsModel.count; i++) {
} if (windowsModel.get(i).window === window) {
AboutDialog { windowsModel.remove(i)
id: aboutDialog break
visible: false }
} }
Loader {
anchors.centerIn: parent window.destroy()
active: appSettings.showTerminalSize
sourceComponent: SizeOverlay { if (windowsModel.count === 0) {
z: 3 appSettings.close()
terminalSize: terminalContainer.terminalSize
} }
} }
onClosing: {
// OSX Since we are currently supporting only one window
// quit the application when it is closed.
if (appSettings.isMacOS)
Qt.quit()
}
} }

Some files were not shown because too many files have changed in this diff Show More