From 3bcf11264befd1501873e0e539a20d4df14d3353 Mon Sep 17 00:00:00 2001 From: Filippo Scognamiglio Date: Sun, 14 Dec 2025 13:31:01 +0100 Subject: [PATCH] Simplify and clarify fonts handling. --- app/qml/ApplicationSettings.qml | 171 +++++++++++++++++------------- app/qml/FontPixels.qml | 107 ------------------- app/qml/FontScanlines.qml | 107 ------------------- app/qml/Fonts.qml | 4 +- app/qml/PreprocessedTerminal.qml | 4 +- app/qml/SettingsTerminalTab.qml | 56 ++++++++-- app/qml/menus/FullContextMenu.qml | 1 - app/qml/menus/OSXMenu.qml | 1 - app/qml/menus/WindowMenu.qml | 1 - app/qml/resources.qrc | 2 - 10 files changed, 145 insertions(+), 309 deletions(-) delete mode 100644 app/qml/FontPixels.qml delete mode 100644 app/qml/FontScanlines.qml diff --git a/app/qml/ApplicationSettings.qml b/app/qml/ApplicationSettings.qml index 83df78f..9bed01f 100644 --- a/app/qml/ApplicationSettings.qml +++ b/app/qml/ApplicationSettings.qml @@ -58,7 +58,7 @@ QtObject { property bool blinkingCursor: false - onWindowScalingChanged: handleFontChanged() + onWindowScalingChanged: updateFont() // PROFILE SETTINGS /////////////////////////////////////////////////////// property real windowOpacity: 1.0 @@ -113,6 +113,11 @@ QtObject { property int rasterization: no_rasterization + readonly property int bundled_fonts: 0 + readonly property int system_fonts: 1 + + property int fontSource: bundled_fonts + // FONTS ////////////////////////////////////////////////////////////////// readonly property real baseFontScaling: 0.75 property real fontScaling: 1.0 @@ -122,52 +127,88 @@ QtObject { property bool lowResolutionFont: false - property var fontNames: ["TERMINUS_SCALED", "COMMODORE_PET", "COMMODORE_PET"] - property var fontlist: fontManager.item.fontlist + property string fontName: "TERMINUS_SCALED" + property var fontlist: fontManager.item ? fontManager.item.fontlist : null + + property var filteredFontList: ListModel {} + + // Single method that updates the font list and applies changes to terminal + function updateFont() { + if (!fontManager.item || !fontlist) return + + // Step 1: Update filtered font list + filteredFontList.clear() + var currentFontInList = false + + for (var i = 0; i < fontlist.count; i++) { + var font = fontlist.get(i) + var isBundled = !font.isSystemFont + var isSystem = font.isSystemFont + + // Filter by font source (bundled vs system) + var matchesSource = (fontSource === bundled_fonts && isBundled) || + (fontSource === system_fonts && isSystem) + + if (!matchesSource) continue + + // For non-default rasterization, only show low-resolution fonts + var matchesRasterization = (rasterization === no_rasterization) || font.lowResolutionFont + + if (matchesRasterization) { + filteredFontList.append(font) + if (font.name === fontName) { + currentFontInList = true + } + } + } + + // Step 2: If current font is not in the filtered list, select the first available font + if (!currentFontInList && filteredFontList.count > 0) { + fontName = filteredFontList.get(0).name + } + + // Step 3: Apply font to terminal + var index = getIndexByName(fontName) + if (index === undefined) return + + fontManager.item.selectedFontIndex = index + fontManager.item.scaling = totalFontScaling + + var fontSourcePath = fontManager.item.source + var pixelSize = fontManager.item.pixelSize + var lineSpacing = fontManager.item.lineSpacing + var screenScaling = fontManager.item.screenScaling + var fontWidth = fontManager.item.defaultFontWidth * appSettings.fontWidth + var fontFamily = fontManager.item.family + var isSystemFont = fontManager.item.isSystemFont + + lowResolutionFont = fontManager.item.lowResolutionFont + + if (!isSystemFont) { + fontLoader.source = fontSourcePath + fontFamily = fontLoader.name + } + + terminalFontChanged(fontFamily, pixelSize, lineSpacing, screenScaling, fontWidth) + } + + onFontSourceChanged: updateFont() + onRasterizationChanged: updateFont() + onFontNameChanged: updateFont() signal terminalFontChanged(string fontFamily, int pixelSize, int lineSpacing, real screenScaling, real fontWidth) signal initializedSettings property Loader fontManager: Loader { - states: [ - State { - when: rasterization == no_rasterization - PropertyChanges { - target: fontManager - source: "Fonts.qml" - } - }, - State { - when: rasterization == scanline_rasterization - PropertyChanges { - target: fontManager - source: "FontScanlines.qml" - } - }, - State { - when: rasterization == pixel_rasterization - PropertyChanges { - target: fontManager - source: "FontPixels.qml" - } - }, - State { - when: rasterization == subpixel_rasterization - PropertyChanges { - target: fontManager - source: "FontPixels.qml" - } - } - ] - - onLoaded: handleFontChanged() + source: "Fonts.qml" + onLoaded: updateFont() } property FontLoader fontLoader: FontLoader {} - onTotalFontScalingChanged: handleFontChanged() - onFontWidthChanged: handleFontChanged() + onTotalFontScalingChanged: updateFont() + onFontWidthChanged: updateFont() function getIndexByName(name) { for (var i = 0; i < fontlist.count; i++) { @@ -180,42 +221,10 @@ QtObject { function incrementScaling() { fontScaling = Math.min(fontScaling + 0.05, maximumFontScaling) - handleFontChanged() } function decrementScaling() { fontScaling = Math.max(fontScaling - 0.05, minimumFontScaling) - handleFontChanged() - } - - function handleFontChanged() { - if (!fontManager.item) - return - - var index = getIndexByName(fontNames[rasterization]) - if (index === undefined) - return - - fontManager.item.selectedFontIndex = index - fontManager.item.scaling = totalFontScaling - - var fontSource = fontManager.item.source - var pixelSize = fontManager.item.pixelSize - var lineSpacing = fontManager.item.lineSpacing - var screenScaling = fontManager.item.screenScaling - var fontWidth = fontManager.item.defaultFontWidth * appSettings.fontWidth - var fontFamily = fontManager.item.family - var isSystemFont = fontManager.item.isSystemFont - - lowResolutionFont = fontManager.item.lowResolutionFont - - if (!isSystemFont) { - fontLoader.source = fontSource - fontFamily = fontLoader.name - } - - terminalFontChanged(fontFamily, pixelSize, lineSpacing, screenScaling, - fontWidth) } property Storage storage: Storage {} @@ -237,7 +246,8 @@ QtObject { "windowScaling": windowScaling, "showTerminalSize": showTerminalSize, "fontScaling": fontScaling, - "fontNames": fontNames, + "fontName": fontName, + "fontSource": fontSource, "showMenubar": showMenubar, "bloomQuality": bloomQuality, "burnInQuality": burnInQuality, @@ -267,7 +277,8 @@ QtObject { "contrast": contrast, "ambientLight": ambientLight, "windowOpacity": windowOpacity, - "fontName": fontNames[rasterization], + "fontName": fontName, + "fontSource": fontSource, "fontWidth": fontWidth, "margin": _margin, "blinkingCursor": blinkingCursor, @@ -324,8 +335,9 @@ QtObject { width = settings.width !== undefined ? settings.width : width height = settings.height !== undefined ? settings.height : height - fontNames = settings.fontNames !== undefined ? settings.fontNames : fontNames + fontName = settings.fontName !== undefined ? settings.fontName : fontName fontScaling = settings.fontScaling !== undefined ? settings.fontScaling : fontScaling + fontSource = settings.fontSource !== undefined ? settings.fontSource : fontSource showMenubar = settings.showMenubar !== undefined ? settings.showMenubar : showMenubar @@ -373,16 +385,14 @@ QtObject { windowOpacity = settings.windowOpacity !== undefined ? settings.windowOpacity : windowOpacity - fontNames[rasterization] = settings.fontName - !== undefined ? settings.fontName : fontNames[rasterization] + fontName = settings.fontName !== undefined ? settings.fontName : fontName + fontSource = settings.fontSource !== undefined ? settings.fontSource : fontSource fontWidth = settings.fontWidth !== undefined ? settings.fontWidth : fontWidth _margin = settings.margin !== undefined ? settings.margin : _margin _frameMargin = settings.frameMargin !== undefined ? settings.frameMargin : _frameMargin blinkingCursor = settings.blinkingCursor !== undefined ? settings.blinkingCursor : blinkingCursor - - handleFontChanged() } function storeCustomProfiles() { @@ -451,6 +461,7 @@ QtObject { "flickering": 0.1, "fontColor": "#ff8100", "fontName": "TERMINUS_SCALED", + "fontSource": 0, "fontWidth": 1, "glowingLine": 0.2, "horizontalSync": 0.08, @@ -480,6 +491,7 @@ QtObject { "flickering": 0.1, "fontColor": "#0ccc68", "fontName": "TERMINUS_SCALED", + "fontSource": 0, "fontWidth": 1, "glowingLine": 0.2, "horizontalSync": 0.08, @@ -509,6 +521,7 @@ QtObject { "flickering": 0.1, "fontColor": "#7cff4f", "fontName": "PRO_FONT_SCALED", + "fontSource": 0, "fontWidth": 1, "glowingLine": 0.2, "horizontalSync": 0.151, @@ -538,6 +551,7 @@ QtObject { "flickering": 0.1962, "fontColor": "#ffffff", "fontName": "COMMODORE_PET", + "fontSource": 0, "fontWidth": 1, "glowingLine": 0.2, "horizontalSync": 0.151, @@ -567,6 +581,7 @@ QtObject { "flickering": 0.2, "fontColor": "#00d56d", "fontName": "APPLE_II", + "fontSource": 0, "fontWidth": 1, "glowingLine": 0.22, "horizontalSync": 0.16, @@ -596,6 +611,7 @@ QtObject { "flickering": 0.9, "fontColor": "#00ff3e", "fontName": "COMMODORE_PET", + "fontSource": 0, "fontWidth": 1, "glowingLine": 0.3, "horizontalSync": 0.42, @@ -625,6 +641,7 @@ QtObject { "flickering": 0.0955, "fontColor": "#ffffff", "fontName": "IBM_DOS", + "fontSource": 0, "fontWidth": 1, "glowingLine": 0.1545, "horizontalSync": 0, @@ -654,6 +671,7 @@ QtObject { "flickering": 0, "fontColor": "#0ccc68", "fontName": "IBM_3278", + "fontSource": 0, "fontWidth": 1, "glowingLine": 0, "horizontalSync": 0, @@ -683,6 +701,7 @@ QtObject { "flickering": 0.2, "fontColor": "#729fcf", "fontName": "TERMINUS", + "fontSource": 0, "fontWidth": 1, "glowingLine": 0.1476, "horizontalSync": 0, diff --git a/app/qml/FontPixels.qml b/app/qml/FontPixels.qml deleted file mode 100644 index 0978480..0000000 --- a/app/qml/FontPixels.qml +++ /dev/null @@ -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 . -*******************************************************************************/ -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 - } - } -} diff --git a/app/qml/FontScanlines.qml b/app/qml/FontScanlines.qml deleted file mode 100644 index 37003ed..0000000 --- a/app/qml/FontScanlines.qml +++ /dev/null @@ -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 . -*******************************************************************************/ -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 - } - } -} diff --git a/app/qml/Fonts.qml b/app/qml/Fonts.qml index 1dc15aa..7b5c458 100644 --- a/app/qml/Fonts.qml +++ b/app/qml/Fonts.qml @@ -237,8 +237,8 @@ QtObject { function convertToListElement(family) { return { - "name": "System: " + family, - "text": qsTr("System: ") + family, + "name": family, + "text": family, "source": "", "lineSpacing": 0.1, "pixelSize": 30, diff --git a/app/qml/PreprocessedTerminal.qml b/app/qml/PreprocessedTerminal.qml index 97eec92..c4683e5 100644 --- a/app/qml/PreprocessedTerminal.qml +++ b/app/qml/PreprocessedTerminal.qml @@ -157,7 +157,7 @@ Item{ kterminal.lineSpacing = lineSpacing; // Set up font fallback based on platform - var fallbackFont = appSettings.isMacOS ? "Menlo" : "monospace"; + var fallbackFont = appSettings.isMacOS ? "Menlo" : "Monospace"; monospaceFontManager.setFontSubstitution(fontFamily, fallbackFont); } @@ -186,7 +186,7 @@ Item{ Component.onCompleted: { appSettings.terminalFontChanged.connect(handleFontChanged); appSettings.initializedSettings.connect(startSession); - appSettings.handleFontChanged() + appSettings.updateFont() } } diff --git a/app/qml/SettingsTerminalTab.qml b/app/qml/SettingsTerminalTab.qml index d80cfb4..dc1e129 100644 --- a/app/qml/SettingsTerminalTab.qml +++ b/app/qml/SettingsTerminalTab.qml @@ -33,10 +33,31 @@ ColumnLayout { anchors.fill: parent columns: 2 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 { - id: rasterizationBox + id: renderingBox property string selectedElement: model[currentIndex] @@ -46,6 +67,7 @@ ColumnLayout { onCurrentIndexChanged: { appSettings.rasterization = currentIndex } + enabled: appSettings.fontSource === appSettings.bundled_fonts } Label { text: qsTr("Name") @@ -53,18 +75,28 @@ ColumnLayout { ComboBox { id: fontChanger Layout.fillWidth: true - model: appSettings.fontlist + model: appSettings.filteredFontList textRole: "text" onActivated: { - var name = appSettings.fontlist.get(index).name - appSettings.fontNames[appSettings.rasterization] = name - appSettings.handleFontChanged() + var font = appSettings.filteredFontList.get(index) + + // If selecting a high-res font while in non-default rasterization, + // switch to default rasterization + if (!font.lowResolutionFont && appSettings.rasterization !== appSettings.no_rasterization) { + appSettings.rasterization = appSettings.no_rasterization + } + + appSettings.fontName = font.name } function updateIndex() { - var name = appSettings.fontNames[appSettings.rasterization] - var index = appSettings.getIndexByName(name) - if (index !== undefined) - currentIndex = index + for (var i = 0; i < appSettings.filteredFontList.count; i++) { + var font = appSettings.filteredFontList.get(i) + if (font.name === appSettings.fontName) { + currentIndex = i + return + } + } + currentIndex = 0 } Connections { target: appSettings @@ -72,6 +104,10 @@ ColumnLayout { onTerminalFontChanged: { fontChanger.updateIndex() } + + onFilteredFontListChanged: { + fontChanger.updateIndex() + } } Component.onCompleted: updateIndex() } diff --git a/app/qml/menus/FullContextMenu.qml b/app/qml/menus/FullContextMenu.qml index 33992b8..2be1639 100644 --- a/app/qml/menus/FullContextMenu.qml +++ b/app/qml/menus/FullContextMenu.qml @@ -79,7 +79,6 @@ Menu { text: model.text onTriggered: { appSettings.loadProfileString(obj_string) - appSettings.handleFontChanged() } } onObjectAdded: function(index, object) { profilesMenu.insertItem(index, object) } diff --git a/app/qml/menus/OSXMenu.qml b/app/qml/menus/OSXMenu.qml index 02447a3..37844b4 100644 --- a/app/qml/menus/OSXMenu.qml +++ b/app/qml/menus/OSXMenu.qml @@ -72,7 +72,6 @@ MenuBar { text: model.text onTriggered: { appSettings.loadProfileString(obj_string) - appSettings.handleFontChanged() } } onObjectAdded: function(index, object) { profilesMenu.insertItem(index, object) } diff --git a/app/qml/menus/WindowMenu.qml b/app/qml/menus/WindowMenu.qml index d62ac41..74610fb 100644 --- a/app/qml/menus/WindowMenu.qml +++ b/app/qml/menus/WindowMenu.qml @@ -69,7 +69,6 @@ MenuBar { text: model.text onTriggered: { appSettings.loadProfileString(obj_string) - appSettings.handleFontChanged() } } onObjectAdded: function(index, object) { profilesMenu.insertItem(index, object) } diff --git a/app/qml/resources.qrc b/app/qml/resources.qrc index b5009de..16fd035 100644 --- a/app/qml/resources.qrc +++ b/app/qml/resources.qrc @@ -6,7 +6,6 @@ ApplicationSettings.qml SettingsWindow.qml Fonts.qml - FontPixels.qml SettingsGeneralTab.qml PreprocessedTerminal.qml TimeManager.qml @@ -17,7 +16,6 @@ SettingsEffectsTab.qml main.qml SettingsTerminalTab.qml - FontScanlines.qml fonts/1977-apple2/PrintChar21.ttf fonts/1971-ibm-3278/3270-Regular.ttf Storage.qml