From eadc1c58a2a556ba094facf2824433345f7d96c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 18 Dec 2020 17:32:54 +0100 Subject: [PATCH 01/12] term: fix builds with debug logging enabled DPI_AWARE_ON has been renamed to DPI_AWARE_YES --- terminal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terminal.c b/terminal.c index 489d7e3c..208c8700 100644 --- a/terminal.c +++ b/terminal.c @@ -1710,7 +1710,7 @@ term_font_dpi_changed(struct terminal *term) "DPI: %.2f -> %.2f, scale: %d -> %d, " "sizing font based on monitor's %s", term->conf->dpi_aware == DPI_AWARE_AUTO ? "auto" : - term->conf->dpi_aware == DPI_AWARE_ON ? "yes" : "no", + term->conf->dpi_aware == DPI_AWARE_YES ? "yes" : "no", term->font_dpi, dpi, term->font_scale, scale, will_scale_using_dpi ? "DPI" : "scaling factor"); } From 9e7d108afd8e7ea1c6582269543992184559ed39 Mon Sep 17 00:00:00 2001 From: Craig Barnes Date: Sat, 19 Dec 2020 22:50:18 +0000 Subject: [PATCH 02/12] changelog: fix link to "1.6.0" heading --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85b86d6e..87d2c85a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -* [1.6.0](#1.6.0) +* [1.6.0](#1-6-0) * [1.5.4](#1-5-4) * [1.5.3](#1-5-3) * [1.5.2](#1-5-2) From 18b027f26b4f849cf533bc806368a9ccec3b3975 Mon Sep 17 00:00:00 2001 From: Craig Barnes Date: Sat, 19 Dec 2020 22:09:03 +0000 Subject: [PATCH 03/12] meson: add missing "wl_proto_headers" dependency for pgolib and vtlib Dependency chains: * pgolib -> terminal.c -> terminal.h -> wayland.h * vtlib -> csi.c -> config.h -> wayland.h wayland.h includes , which must be generated by a custom_target() rule *before* any sources that require it are built. Failure to fully specify these dependencies can otherwise result in a race condition, where a dependent source file gets compiled (and fails with a "header not found" error) before the header itself has been generated. --- meson.build | 2 ++ 1 file changed, 2 insertions(+) diff --git a/meson.build b/meson.build index 4370acc0..282f7360 100644 --- a/meson.build +++ b/meson.build @@ -122,6 +122,7 @@ vtlib = static_library( 'osc.c', 'osc.h', 'sixel.c', 'sixel.h', 'vt.c', 'vt.h', + wl_proto_src + wl_proto_headers, version, dependencies: [pixman, fcft, tllist], link_with: misc, @@ -132,6 +133,7 @@ pgolib = static_library( 'grid.c', 'grid.h', 'selection.c', 'selection.h', 'terminal.c', 'terminal.h', + wl_proto_src + wl_proto_headers, dependencies: [pixman, fcft, tllist], link_with: vtlib, ) From b976d10f7dd3bb24a355eee58363376f0a29a9f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 20 Dec 2020 15:46:05 +0100 Subject: [PATCH 04/12] changelog: add 1.6.1 section --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87d2c85a..dfd829df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Changelog +* [1.6.1](#1-6-1) * [1.6.0](#1-6-0) * [1.5.4](#1-5-4) * [1.5.3](#1-5-3) @@ -18,6 +19,16 @@ * [1.2.0](#1-2-0) +## 1.6.1 +### Added +### Changed +### Deprecated +### Removed +### Fixed +### Security +### Contributors5 + + ## 1.6.0 ### For packagers From 3fd60d4975c589242a8083b2323040bb788a5d16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 20 Dec 2020 11:56:18 +0100 Subject: [PATCH 05/12] changelog: mention meson dependency fix --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfd829df..9210188c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,11 @@ ### Deprecated ### Removed ### Fixed + +* Missing dependencies in meson, causing heavily parallelized builds + to fail. + + ### Security ### Contributors5 From 06f84b9aafc14d2e787956c16f6ce32f95e62dd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 20 Dec 2020 12:15:40 +0100 Subject: [PATCH 06/12] meson: add wl_proto_headers to pgo executable This fixes a build failure of pgo.o --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 282f7360..a9ce24b7 100644 --- a/meson.build +++ b/meson.build @@ -141,7 +141,7 @@ pgolib = static_library( executable( 'pgo', 'pgo/pgo.c', - wl_proto_src, + wl_proto_src + wl_proto_headers, dependencies: [math, threads, pixman, wayland_client, fcft, tllist], link_with: pgolib, ) From a2ce0622c5396774c64245bb6cbd6b7dbd0d339d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 20 Dec 2020 12:25:12 +0100 Subject: [PATCH 07/12] render: fix rounding error when calculating background color with alpha MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We use pre-multiplied alpha color channels, but were having bad rounding errors due to the alpha divider being truncated to an integer. The algorithm for pre-multiplying a color channel is: alpha_divider = 0xffff / alpha pre_mult_color = color / alpha_divider In order to fix the rounding errors, we could turn ‘alpha_divider’ into a double. That however would introduce a performance penalty since now we’d need to do floating point math for each cell. The algorithm can be trivially converted to: pre_mult_color = color * alpha / 0xffff Since both color and alpa values are < 65536, the multiplication is “safe”; it will not overflow an uint32_t. Closes #249 --- CHANGELOG.md | 2 ++ render.c | 10 +++------- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9210188c..88d827e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,8 @@ * Missing dependencies in meson, causing heavily parallelized builds to fail. +* Background color when alpha < 1.0 being wrong + (https://codeberg.org/dnkl/foot/issues/249). ### Security diff --git a/render.c b/render.c index df22dd6e..f66e277e 100644 --- a/render.c +++ b/render.c @@ -213,14 +213,10 @@ attrs_to_font(const struct terminal *term, const struct attributes *attrs) static inline pixman_color_t color_hex_to_pixman_with_alpha(uint32_t color, uint16_t alpha) { - if (alpha == 0) - return (pixman_color_t){0, 0, 0, 0}; - - int alpha_div = 0xffff / alpha; return (pixman_color_t){ - .red = ((color >> 16 & 0xff) | (color >> 8 & 0xff00)) / alpha_div, - .green = ((color >> 8 & 0xff) | (color >> 0 & 0xff00)) / alpha_div, - .blue = ((color >> 0 & 0xff) | (color << 8 & 0xff00)) / alpha_div, + .red = ((color >> 16 & 0xff) | (color >> 8 & 0xff00)) * alpha / 0xffff, + .green = ((color >> 8 & 0xff) | (color >> 0 & 0xff00)) * alpha / 0xffff, + .blue = ((color >> 0 & 0xff) | (color << 8 & 0xff00)) * alpha / 0xffff, .alpha = alpha, }; } From d1735ffb6da3b867ceda83fa89648a664a5dafd1 Mon Sep 17 00:00:00 2001 From: sterni Date: Sun, 20 Dec 2020 14:45:09 +0100 Subject: [PATCH 08/12] generate-alt-random-writes: use python random, allow setting a seed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using Python's own PRNG should make the code cleaner and allow for reproducible stimulus files if that is desired via setting --seed (at least for the same versions of the script, changing the kind and/or order of the random calls will of course impact the output in the future). I did the following substitutions: * rand.read(1)[0] % n and struct.unpack('@H', rand.read(2))[0] % n → random.randrange(n) * rand.read(1)[0] → random.randrange(256) * rand.read(n) → [random.randrange(256) for _ in range(n)] (better alternative would have been random.randbytes(n), but is only available for Python >= 3.9, switching to this in the future will impact output) * list[rand.read(1) % len(list)] → random.choice(list) --- scripts/generate-alt-random-writes.py | 200 +++++++++++++------------- 1 file changed, 101 insertions(+), 99 deletions(-) diff --git a/scripts/generate-alt-random-writes.py b/scripts/generate-alt-random-writes.py index 2436b6ff..1f891470 100755 --- a/scripts/generate-alt-random-writes.py +++ b/scripts/generate-alt-random-writes.py @@ -3,6 +3,7 @@ import argparse import enum import fcntl import struct +import random import sys import termios @@ -31,6 +32,7 @@ def main(): parser.add_argument('--attr-italic', action='store_true') parser.add_argument('--attr-underline', action='store_true') parser.add_argument('--sixel', action='store_true') + parser.add_argument('--seed', type=int) opts = parser.parse_args() out = opts.out if opts.out is not None else sys.stdout @@ -61,133 +63,133 @@ def main(): # Enter alt screen out.write('\033[?1049h') - with open('/dev/urandom', 'rb') as rand: - for _ in range(count): - if opts.scroll and rand.read(1)[0] == 0: - out.write('\033[m') + # uses system time or /dev/urandom if available if opt.seed == None + # pin seeding method to make seeding stable across future versions + random.seed(a=opts.seed, version=2) - if opts.scroll_region and rand.read(1)[0] == 0: - top = rand.read(1)[0] % 3 - bottom = rand.read(1)[0] % 3 - out.write(f'\033[{top};{lines - bottom}r') + for _ in range(count): + if opts.scroll and random.randrange(256) == 0: + out.write('\033[m') - lines_to_scroll = rand.read(1)[0] % (lines - 1) - rev = rand.read(1)[0] % 2 - if not rev and rand.read(1)[0] % 2: - out.write(f'\033[{lines};{cols}H') - out.write('\n' * lines_to_scroll) - else: - out.write(f'\033[{lines_to_scroll + 1}{"T" if rev == 1 else "S"}') - continue + if opts.scroll_region and random.randrange(256) == 0: + top = random.randrange(3) + bottom = random.randrange(3) + out.write(f'\033[{top};{lines - bottom}r') - # Generate a random location and a random character - row = rand.read(1)[0] % lines - col = rand.read(1)[0] % cols - c = alphabet[rand.read(1)[0] % len(alphabet)] + lines_to_scroll = random.randrange(lines - 1) + rev = random.randrange(2) + if not rev and random.randrange(2): + out.write(f'\033[{lines};{cols}H') + out.write('\n' * lines_to_scroll) + else: + out.write(f'\033[{lines_to_scroll + 1}{"T" if rev == 1 else "S"}') + continue - repeat = rand.read(1)[0] % (cols - col) + 1 - assert col + repeat <= cols + # Generate a random location and a random character + row = random.randrange(lines) + col = random.randrange(cols) + c = random.choice(alphabet) - color_variant = color_variants[rand.read(1)[0] % len(color_variants)] + repeat = random.randrange((cols - col) + 1) + assert col + repeat <= cols - # Position cursor - out.write(f'\033[{row + 1};{col + 1}H') + color_variant = random.choice(color_variants) - if color_variant in [ColorVariant.REGULAR, ColorVariant.BRIGHT]: - do_bg = rand.read(1)[0] % 2 - base = 40 if do_bg else 30 - base += 60 if color_variant == ColorVariant.BRIGHT else 0 + # Position cursor + out.write(f'\033[{row + 1};{col + 1}H') - idx = rand.read(1)[0] % 8 - out.write(f'\033[{base + idx}m') + if color_variant in [ColorVariant.REGULAR, ColorVariant.BRIGHT]: + do_bg = random.randrange(2) + base = 40 if do_bg else 30 + base += 60 if color_variant == ColorVariant.BRIGHT else 0 - elif color_variant == ColorVariant.CUBE: - do_bg = rand.read(1)[0] % 2 - base = 48 if do_bg else 38 + idx = random.randrange(8) + out.write(f'\033[{base + idx}m') - idx = rand.read(1)[0] % 256 - if rand.read(1)[0] % 2: - # Old-style - out.write(f'\033[{base};5;{idx}m') - else: - # New-style (sub-parameter based) - out.write(f'\033[{base}:2:5:{idx}m') + elif color_variant == ColorVariant.CUBE: + do_bg = random.randrange(2) + base = 48 if do_bg else 38 - elif color_variant == ColorVariant.RGB: - do_bg = rand.read(1)[0] % 2 - base = 48 if do_bg else 38 - rgb = rand.read(3) + idx = random.randrange(256) + if random.randrange(2): + # Old-style + out.write(f'\033[{base};5;{idx}m') + else: + # New-style (sub-parameter based) + out.write(f'\033[{base}:2:5:{idx}m') - if rand.read(1)[0] % 2: - # Old-style - out.write(f'\033[{base};2;{rgb[0]};{rgb[1]};{rgb[2]}m') - else: - # New-style (sub-parameter based) - out.write(f'\033[{base}:2::{rgb[0]}:{rgb[1]}:{rgb[2]}m') + elif color_variant == ColorVariant.RGB: + do_bg = random.randrange(2) + base = 48 if do_bg else 38 - if opts.attr_bold and rand.read(1)[0] % 5 == 0: - out.write('\033[1m') - if opts.attr_italic and rand.read(1)[0] % 5 == 0: - out.write('\033[3m') - if opts.attr_underline and rand.read(1)[0] % 5 == 0: - out.write('\033[4m') + # use list comprehension in favor of randbytes(n) + # which is only available for Python >= 3.9 + rgb = [random.randrange(256) for _ in range(3)] - out.write(c * repeat) + if random.randrange(2): + # Old-style + out.write(f'\033[{base};2;{rgb[0]};{rgb[1]};{rgb[2]}m') + else: + # New-style (sub-parameter based) + out.write(f'\033[{base}:2::{rgb[0]}:{rgb[1]}:{rgb[2]}m') - do_sgr_reset = rand.read(1)[0] % 2 - if do_sgr_reset: - reset_actions = ['\033[m', '\033[39m', '\033[49m'] - idx = rand.read(1)[0] % len(reset_actions) - out.write(reset_actions[idx]) + if opts.attr_bold and random.randrange(5) == 0: + out.write('\033[1m') + if opts.attr_italic and random.randrange(5) == 0: + out.write('\033[3m') + if opts.attr_underline and random.randrange(5) == 0: + out.write('\033[4m') + + out.write(c * repeat) + + do_sgr_reset = random.randrange(2) + if do_sgr_reset: + reset_actions = ['\033[m', '\033[39m', '\033[49m'] + out.write(random.choice(reset_actions)) # Leave alt screen out.write('\033[m\033[r\033[?1049l') - with open('/dev/urandom', 'rb') as rand: - if opts.sixel: - # The sixel 'alphabet' - sixels = '?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~' + if opts.sixel: + # The sixel 'alphabet' + sixels = '?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~' - for _ in range(200): - # Offset image - out.write(' ' * (rand.read(1)[0] % (cols // 2))) + for _ in range(200): + # Offset image + out.write(' ' * (random.randrange(cols // 2))) - # Begin sixel - out.write('\033Pq') + # Begin sixel + out.write('\033Pq') - # Set up 256 random colors - for idx in range(256): - # param 2: 1=HLS, 2=RGB. - # param 3/4/5: HLS/RGB values in range 0-100 - # (except 'hue' which is 0..360) - out.write(f'#{idx};2;{rand.read(1)[0] % 101};{rand.read(1)[0] % 101};{rand.read(1)[0] % 101}') + # Set up 256 random colors + for idx in range(256): + # param 2: 1=HLS, 2=RGB. + # param 3/4/5: HLS/RGB values in range 0-100 + # (except 'hue' which is 0..360) + out.write(f'#{idx};2;{random.randrange(101)};{random.randrange(101)};{random.randrange(101)}') - # Randomize image width/height - six_height = struct.unpack('@H', rand.read(2))[0] % (height // 2) - six_width = struct.unpack('@H', rand.read(2))[0] % (width // 2) + # Randomize image width/height + six_height = random.randrange(height // 2) + six_width = random.randrange(width // 2) - # Sixel size. Without this, sixels will be - # auto-resized on cell-boundaries. We expect programs - # to emit this sequence since otherwise you cannot get - # correctly sized images. - out.write(f'"0;0;{six_width};{six_height}') + # Sixel size. Without this, sixels will be + # auto-resized on cell-boundaries. We expect programs + # to emit this sequence since otherwise you cannot get + # correctly sized images. + out.write(f'"0;0;{six_width};{six_height}') - for row in range(six_height // 6): # Each sixel is 6 pixels - # Choose a random color - out.write(f'#{rand.read(1)[0] % 256}') + for row in range(six_height // 6): # Each sixel is 6 pixels + # Choose a random color + out.write(f'#{random.randrange(256)}') - if rand.read(1)[0] == 999999999999: - assert False - out.write(f'!{six_width}{sixels[rand.read(1)[0] % len(sixels)]}') - else: - for col in range(six_width): - out.write(f'{sixels[rand.read(1)[0] % len(sixels)]}') + for col in range(six_width): + out.write(f'{random.choice(sixels)}') - # Next line - out.write('-') + # Next line + out.write('-') - # End sixel - out.write('\033\\') + # End sixel + out.write('\033\\') if __name__ == '__main__': From 983f474ec8c02e0f50dc84153748445982498411 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 20 Dec 2020 15:27:27 +0100 Subject: [PATCH 09/12] =?UTF-8?q?generate-alt-random:=20fix=20=E2=80=9Cnew?= =?UTF-8?q?=20style=E2=80=9D=20cube=20escape?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It’s “38:5:”, not “38:2:5:”. --- scripts/generate-alt-random-writes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/generate-alt-random-writes.py b/scripts/generate-alt-random-writes.py index 1f891470..e68a00f9 100755 --- a/scripts/generate-alt-random-writes.py +++ b/scripts/generate-alt-random-writes.py @@ -116,7 +116,7 @@ def main(): out.write(f'\033[{base};5;{idx}m') else: # New-style (sub-parameter based) - out.write(f'\033[{base}:2:5:{idx}m') + out.write(f'\033[{base}:5:{idx}m') elif color_variant == ColorVariant.RGB: do_bg = random.randrange(2) From e12a9347dd00ccf49e810667c7b0c0e268dbbfaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 20 Dec 2020 15:36:07 +0100 Subject: [PATCH 10/12] generate-alt-random: override detected width/height when --cols/--rows have been used This ensures we have a valid width and height, that matches what the PGO helper binary expects. --- scripts/generate-alt-random-writes.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/generate-alt-random-writes.py b/scripts/generate-alt-random-writes.py index e68a00f9..202c99c5 100755 --- a/scripts/generate-alt-random-writes.py +++ b/scripts/generate-alt-random-writes.py @@ -45,8 +45,10 @@ def main(): if opts.rows is not None: lines = opts.rows + height = 15 * lines # PGO helper binary hardcodes cell height to 15px if opts.cols is not None: cols = opts.cols + width = 8 * cols # PGO help binary hardcodes cell width to 8px # Number of characters to write to screen count = 256 * 1024**1 From 533db90a94292772002aa417de6e1b856f1ff6e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 20 Dec 2020 15:48:25 +0100 Subject: [PATCH 11/12] =?UTF-8?q?changelog:=20remove=20trailing=20?= =?UTF-8?q?=E2=80=985=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 88d827e7..08129414 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,7 +33,7 @@ ### Security -### Contributors5 +### Contributors ## 1.6.0 From fbe9f54db0d207ee56d926e676ea8584a424ecd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 20 Dec 2020 15:42:32 +0100 Subject: [PATCH 12/12] =?UTF-8?q?changelog:=20update=20=E2=80=98contributo?= =?UTF-8?q?rs=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08129414..ac335fe7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,9 @@ ### Security ### Contributors +* [craigbarnes](https://codeberg.org/craigbarnes) +* [sterni](https://codeberg.org/sterni) + ## 1.6.0