From aa37892d760496006c129d9811fcd37c2ae739f6 Mon Sep 17 00:00:00 2001 From: Filippo Scognamiglio Date: Sat, 31 May 2014 19:28:35 +0200 Subject: [PATCH] Improved scanlines for all fonts at all font scaling. Now I manually choose the best looking values for every font in any zoom level. Tedious but the effect is awesome. --- app/SettingsWindow.qml | 11 ++-- app/ShaderManager.qml | 33 ++++++----- app/ShaderSettings.qml | 118 +++++++++++++++++++++++++++------------- app/Terminal.qml | 15 ++++- app/app.qmlproject.user | 2 +- 5 files changed, 115 insertions(+), 64 deletions(-) diff --git a/app/SettingsWindow.qml b/app/SettingsWindow.qml index bdedfcf..f0a34d8 100644 --- a/app/SettingsWindow.qml +++ b/app/SettingsWindow.qml @@ -94,14 +94,11 @@ Window { onCurrentIndexChanged: shadersettings.font_index = currentIndex } Text{text: qsTr("Font scaling:")} - SpinBox{ + ComboBox{ Layout.fillWidth: true - decimals: 2 - stepSize: 0.25 - value: shadersettings.font_scaling - minimumValue: 0.5 - maximumValue: 2.0 - onValueChanged: shadersettings.font_scaling = value; + model: shadersettings._font_scalings + currentIndex: shadersettings.font_scaling_index + onCurrentIndexChanged: shadersettings.font_scaling_index = currentIndex } Item{Layout.fillHeight: true} ColorButton{ diff --git a/app/ShaderManager.qml b/app/ShaderManager.qml index 091536d..e6bd16c 100644 --- a/app/ShaderManager.qml +++ b/app/ShaderManager.qml @@ -26,16 +26,18 @@ ShaderEffect { property color background_color: shadersettings.background_color property variant source: theSource property variant bloomSource: bloomSource - property size txt_Size: Qt.size(width, height) + property size txt_Size: Qt.size(frame.sourceRect.width, frame.sourceRect.height) property real bloom: shadersettings.bloom_strength property int rasterization: shadersettings.rasterization property real rasterization_strength: shadersettings.rasterization_strength property real _lines: frame.sourceRect.height / terminal.paintedFontSize.height - property real _columns: frame.sourceRect.width / terminal.paintedFontSize.height - property real verticalPixelDensity: shadersettings.font.verticalPixelDensity - property real horizontalPixelDensity: shadersettings.font.horizontalPixelDensity + property real _columns: frame.sourceRect.width / terminal.paintedFontSize.width + property real verticalPixelDensity: shadersettings.font.virtualResolution.height + shadersettings.font.lineSpacing + property real horizontalPixelDensity: shadersettings.font.virtualResolution.width property size num_scanlines: Qt.size(_columns * horizontalPixelDensity, _lines * verticalPixelDensity) + property real scanlineHeight: frame.sourceRect.height / num_scanlines.height + property real scanlineWidth: frame.sourceRect.width / num_scanlines.width property real noise_strength: shadersettings.noise_strength property real screen_distorsion: shadersettings.screen_distortion @@ -53,6 +55,9 @@ ShaderEffect { property real brightness: shadersettings.brightness * 1.5 + 0.5 + property real deltay: scanlineHeight / (frame.sourceRect.height) + property real deltax: scanlineWidth / (frame.sourceRect.width) + property real time: timetimer.time property variant randomFunctionSource: randfuncsource @@ -91,8 +96,8 @@ ShaderEffect { " void main() { originalCoord = qt_MultiTexCoord0; - qt_TexCoord0.x = -"+disp_left.toFixed(1)+"/txt_Size.x + qt_MultiTexCoord0.x / ((txt_Size.x -("+(disp_left+disp_right).toFixed(1)+")) / txt_Size.x);" + - "qt_TexCoord0.y = -"+disp_top.toFixed(1)+"/txt_Size.y + qt_MultiTexCoord0.y / ((txt_Size.y -("+(disp_top+disp_bottom).toFixed(1)+")) / txt_Size.y);" + + qt_TexCoord0.x = -"+disp_left.toFixed(8)+"/txt_Size.x + qt_MultiTexCoord0.x / ((txt_Size.x -("+(disp_left+disp_right).toFixed(8)+")) / txt_Size.x);" + + "qt_TexCoord0.y = -"+disp_top.toFixed(8)+"/txt_Size.y + qt_MultiTexCoord0.y / ((txt_Size.y -("+(disp_top+disp_bottom).toFixed(8)+")) / txt_Size.y);" + "vec2 coords = vec2(fract(time/(1024.0*2.0)), fract(time/(1024.0*1024.0)));" + (brightness_flickering !== 0.0 ? " brightness = 1.0 + (texture2D(randomFunctionSource, coords).g - 0.5) * "+brightness_flickering.toFixed(2)+";" @@ -132,9 +137,9 @@ ShaderEffect { (rasterization !== shadersettings.no_rasterization ? " float getScanlineIntensity(vec2 coord){ - float result = abs(sin(coord.y * "+(num_scanlines.height * Math.PI).toFixed(2)+"));" + + float result = abs(sin(coord.y * "+(num_scanlines.height * Math.PI).toFixed(8)+"));" + (rasterization === shadersettings.pixel_rasterization ? " - result *= abs(sin(coord.x * "+(num_scanlines.width * Math.PI).toFixed(2)+"));" : "") + + result *= abs(sin(coord.x * "+(num_scanlines.width * Math.PI).toFixed(8)+"));" : "") + "return result; }" : "") + @@ -187,12 +192,12 @@ ShaderEffect { (rasterization !== shadersettings.no_rasterization ? " vec2 txt_coords = coords; - txt_coords.y = floor(coords.y * "+num_scanlines.height.toFixed(1)+") / "+num_scanlines.height.toFixed(1)+";" + + txt_coords.y = floor(coords.y * "+num_scanlines.height.toFixed(8)+") / "+num_scanlines.height.toFixed(8)+";" + (rasterization === shadersettings.pixel_rasterization ? - "txt_coords.x = floor(coords.x * "+num_scanlines.width.toFixed(1)+") / "+num_scanlines.width.toFixed(1)+";" : "") + "txt_coords.x = floor(coords.x * "+num_scanlines.width.toFixed(8)+") / "+num_scanlines.width.toFixed(8)+";" : "") : " vec2 txt_coords = coords;") + - "float color = texture2D(source, txt_coords).r;" + + "float color = texture2D(source, txt_coords + vec2("+(deltax * 0.5).toFixed(8)+", "+(deltay * 0.5).toFixed(8)+")).r;" + (noise_strength !== 0 ? " color += stepNoise(coords) * noise * (1.0 - distance * distance * 2.0);" : "") + @@ -201,11 +206,11 @@ ShaderEffect { color += randomPass(txt_coords) * glowing_line_strength;" : "") + (rasterization !== shadersettings.no_rasterization ? " - color = mix(color, color * getScanlineIntensity(coords), "+ rasterization_strength.toFixed(1) +");" + color = mix(texture2D(source, coords).r, color * getScanlineIntensity(coords), "+ rasterization_strength.toFixed(8) +");" : "") + (bloom !== 0 ? " - color += texture2D(bloomSource, coords).r *" + (2.5 * bloom).toFixed(1) + ";" : "") + + color += texture2D(bloomSource, coords).r *" + (2.5 * bloom).toFixed(8) + ";" : "") + "vec3 finalColor = mix(background_color, font_color, color).rgb;" + "finalColor = mix(finalColor * 1.1, vec3(0.0), 1.2 * distance * distance);" + @@ -213,7 +218,7 @@ ShaderEffect { (brightness_flickering !== 0 ? " finalColor *= brightness;" : "") + - "gl_FragColor = vec4(finalColor *"+brightness.toFixed(1)+", qt_Opacity); + "gl_FragColor = vec4(finalColor *"+brightness.toFixed(8)+", qt_Opacity); }" onStatusChanged: if (log) console.log(log) //Print warning messages diff --git a/app/ShaderSettings.qml b/app/ShaderSettings.qml index 1c36966..66a3359 100644 --- a/app/ShaderSettings.qml +++ b/app/ShaderSettings.qml @@ -75,7 +75,8 @@ Item{ property var frames_list: framelist signal terminalFontChanged - property real font_scaling: 1.0 + + property var _font_scalings: [0.5, 0.75, 1.0, 1.25, 1.50, 1.75, 2.0] property var font: currentfont property int font_index: 0 property var fonts_list: fontlist @@ -88,20 +89,23 @@ Item{ onProfiles_indexChanged: loadProfile(profiles_index); onFont_indexChanged: handleFontChanged(); - onFont_scalingChanged: handleFontChanged(); + onFont_scaling_indexChanged: handleFontChanged(); function handleFontChanged(){ - currentfont.source = fontlist.get(font_index).source; - currentfont.pixelSize = fontlist.get(font_index).pixelSize; - currentfont.lineSpacing = fontlist.get(font_index).lineSpacing; + var f = fontlist.get(font_index); + var metrics = f.metrics.get(font_scaling_index); + currentfont.source = f.source; + currentfont.pixelSize = metrics.px; + currentfont.lineSpacing = f.lineSpacing; + currentfont.virtualResolution = Qt.size(metrics.virtualWidth, + metrics.virtualHeight); terminalFontChanged(); } FontLoader{ - property int pixelSize: fontlist.get(font_index).pixelSize - property real lineSpacing: fontlist.get(font_index).lineSpacing - property real verticalPixelDensity: fontlist.get(font_index).verticalPixelDensity - property real horizontalPixelDensity: fontlist.get(font_index).horizontalPixelDensity + property int pixelSize + property real lineSpacing + property size virtualResolution id: currentfont source: fontlist.get(font_index).source } @@ -113,63 +117,99 @@ Item{ ListElement{text: "Rough black frame"; source: "./frames/BlackRoughFrame.qml"; reflections: true} } + property int font_scaling_index: 0 ListModel{ id: fontlist ListElement{ text: "Terminus (Modern)" source: "fonts/modern-terminus/TerminusTTF-4.38.2.ttf" - pixelSize: 32 - lineSpacing: 0.12 - verticalPixelDensity: 12 - horizontalPixelDensity: 12 + lineSpacing: 1 + metrics: [ + ListElement{px: 18; virtualWidth: 3; virtualHeight: 6}, + ListElement{px: 27; virtualWidth: 5; virtualHeight: 8}, + ListElement{px: 36; virtualWidth: 6; virtualHeight: 11}, + ListElement{px: 44; virtualWidth: 7; virtualHeight: 11}, + ListElement{px: 54; virtualWidth: 7; virtualHeight: 11}, + ListElement{px: 62; virtualWidth: 8; virtualHeight: 13}, + ListElement{px: 71; virtualWidth: 7; virtualHeight: 13}] } ListElement{ text: "Commodore PET (1977)" source: "fonts/1977-commodore-pet/COMMODORE_PET.ttf" - pixelSize: 25 - lineSpacing: 0.1 - verticalPixelDensity: 9 - horizontalPixelDensity: 9 + lineSpacing: 2 + metrics: [ + ListElement{px: 16; virtualWidth: 8; virtualHeight: 6}, + ListElement{px: 20; virtualWidth: 7; virtualHeight: 6}, + ListElement{px: 27; virtualWidth: 8; virtualHeight: 8}, + ListElement{px: 34; virtualWidth: 8; virtualHeight: 8}, + ListElement{px: 40; virtualWidth: 8; virtualHeight: 8}, + ListElement{px: 44; virtualWidth: 8; virtualHeight: 8}, + ListElement{px: 50; virtualWidth: 8; virtualHeight: 8}] } ListElement{ text: "Apple ][ (1977)" source: "fonts/1977-apple2/PrintChar21.ttf" - pixelSize: 25 - lineSpacing: 0.1 - verticalPixelDensity: 9 - horizontalPixelDensity: 10 + lineSpacing: 2 + metrics: [ + ListElement{px: 15; virtualWidth: 6; virtualHeight: 5}, + ListElement{px: 21; virtualWidth: 6; virtualHeight: 7}, + ListElement{px: 27; virtualWidth: 7; virtualHeight: 8}, + ListElement{px: 34; virtualWidth: 7; virtualHeight: 8}, + ListElement{px: 40; virtualWidth: 7; virtualHeight: 8}, + ListElement{px: 47; virtualWidth: 7; virtualHeight: 8}, + ListElement{px: 54; virtualWidth: 7; virtualHeight: 8}] } ListElement{ text: "Atari 400-800 (1979)" source: "fonts/1979-atari-400-800/ATARI400800_original.TTF" - pixelSize: 25 - lineSpacing: 0.22 - verticalPixelDensity: 10 - horizontalPixelDensity: 10 + lineSpacing: 3 + metrics: [ + ListElement{px: 16; virtualWidth: 8; virtualHeight: 8}, + ListElement{px: 20; virtualWidth: 8; virtualHeight: 8}, + ListElement{px: 25; virtualWidth: 8; virtualHeight: 8}, + ListElement{px: 31; virtualWidth: 8; virtualHeight: 8}, + ListElement{px: 38; virtualWidth: 8; virtualHeight: 8}, + ListElement{px: 47; virtualWidth: 8; virtualHeight: 8}, + ListElement{px: 54; virtualWidth: 8; virtualHeight: 8}] } ListElement{ text: "Commodore 64 (1982)" source: "fonts/1982-commodore64/C64_User_Mono_v1.0-STYLE.ttf" - pixelSize: 25 - lineSpacing: 0.22 - verticalPixelDensity: 10 - horizontalPixelDensity: 10 + lineSpacing: 3 + metrics: [ + ListElement{px: 16; virtualWidth: 8; virtualHeight: 8}, + ListElement{px: 20; virtualWidth: 8; virtualHeight: 8}, + ListElement{px: 25; virtualWidth: 8; virtualHeight: 8}, + ListElement{px: 31; virtualWidth: 8; virtualHeight: 8}, + ListElement{px: 38; virtualWidth: 8; virtualHeight: 8}, + ListElement{px: 47; virtualWidth: 8; virtualHeight: 8}, + ListElement{px: 54; virtualWidth: 8; virtualHeight: 8}] } ListElement{ text: "Atari ST (1985)" source: "fonts/1985-atari-st/AtariST8x16SystemFont.ttf" - pixelSize: 26 - lineSpacing: 0.15 - verticalPixelDensity: 11 - horizontalPixelDensity: 12 + lineSpacing: 4 + metrics: [ + ListElement{px: 16; virtualWidth: 3; virtualHeight: 5}, + ListElement{px: 23; virtualWidth: 4; virtualHeight: 7}, + ListElement{px: 30; virtualWidth: 4; virtualHeight: 10}, + ListElement{px: 38; virtualWidth: 6; virtualHeight: 10}, + ListElement{px: 44; virtualWidth: 7; virtualHeight: 14}, + ListElement{px: 53; virtualWidth: 7; virtualHeight: 14}, + ListElement{px: 58; virtualWidth: 7; virtualHeight: 14}] } ListElement{ text: "IBM DOS (1985)" source: "fonts/1985-ibm-pc-vga/Perfect DOS VGA 437.ttf" - pixelSize: 32 - lineSpacing: 0.17 - verticalPixelDensity: 15 - horizontalPixelDensity: 15 + lineSpacing: 2 + metrics: [ + ListElement{px: 18; virtualWidth: 5; virtualHeight: 7}, + ListElement{px: 25; virtualWidth: 5; virtualHeight: 9}, + ListElement{px: 36; virtualWidth: 6; virtualHeight: 12}, + ListElement{px: 45; virtualWidth: 7; virtualHeight: 15}, + ListElement{px: 54; virtualWidth: 8; virtualHeight: 15}, + ListElement{px: 62; virtualWidth: 8; virtualHeight: 15}, + ListElement{px: 74; virtualWidth: 9; virtualHeight: 16}] } } @@ -183,7 +223,7 @@ Item{ brightness: brightness, contrast: contrast, ambient_light: ambient_light, - font_scaling: font_scaling, + font_scaling_index: font_scaling_index, } return JSON.stringify(settings); } @@ -243,7 +283,7 @@ Item{ fps = settings.fps !== undefined ? settings.fps: fps window_scaling = settings.window_scaling ? settings.window_scaling : window_scaling - font_scaling = settings.font_scaling !== undefined ? settings.font_scaling: font_scaling; + font_scaling_index = settings.font_scaling_index !== undefined ? settings.font_scaling_index: font_scaling_index; } function loadProfileString(profileString){ diff --git a/app/Terminal.qml b/app/Terminal.qml index a413c37..750504b 100644 --- a/app/Terminal.qml +++ b/app/Terminal.qml @@ -84,18 +84,27 @@ Item{ } } + Text{id: fontMetrics; text: "B"; visible: false} + function handleFontChange(){ - var scaling_factor = shadersettings.font_scaling * shadersettings.window_scaling; - var font_size = Math.ceil(shadersettings.font.pixelSize * scaling_factor); - var line_spacing = Math.ceil(shadersettings.font.lineSpacing * font_size); + var scaling_factor = shadersettings.window_scaling; + var font_size = shadersettings.font.pixelSize * scaling_factor; font.pixelSize = font_size; font.family = shadersettings.font.name; + + fontMetrics.font = font; + + var scanline_spacing = shadersettings.font.lineSpacing; + var scanline_height = fontMetrics.paintedHeight / shadersettings.font.virtualResolution.height; + + var line_spacing = Math.round(scanline_spacing * scanline_height); setLineSpacing(line_spacing); } onUpdatedImage: {blurredSource.live = true;livetimer.restart();} Component.onCompleted: { shadersettings.terminalFontChanged.connect(handleFontChange); + handleFontChange(); forceActiveFocus(); } } diff --git a/app/app.qmlproject.user b/app/app.qmlproject.user index 802ff8b..fd470c2 100644 --- a/app/app.qmlproject.user +++ b/app/app.qmlproject.user @@ -1,6 +1,6 @@ - + ProjectExplorer.Project.ActiveTarget