From 9c75ea795dec316cfa2c33c237ec5bb44c813f6f Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 17 Jul 2024 17:41:47 +0530 Subject: [PATCH] Recognize more linear bezier curves --- kitty/animation.c | 12 +++++++++++- kitty_tests/options.py | 13 +++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/kitty/animation.c b/kitty/animation.c index 8f8a40e26..f90775b80 100644 --- a/kitty/animation.c +++ b/kitty/animation.c @@ -194,10 +194,20 @@ init_function(Animation *a, double y_at_start, double y_at_end, easing_curve cur return f; } +static bool +is_bezier_linear(double p1x, double p1y, double p2x, double p2y) { + return ( + (p1x == 0 && p1y == 0 && p2x == 1 && p2y == 1) || + (p1x == 0 && p1y == 0 && p2x == 0 && p2y == 0) || + (p1x == 1 && p1y == 1 && p2x == 1 && p2y == 1) || + (p1x != 0 && p2x != 0 && p1y != 0 && p2y != 0 && p1y / p1x == p2y / p2x) + ); +} + void add_cubic_bezier_animation(Animation *a, double y_at_start, double y_at_end, double p1x, double p1y, double p2x, double p2y) { p1x = unit_value(p1x); p2x = unit_value(p2x); - if (p1x == 0 && p1y == 0 && p2x == 1 && p2y == 1) { + if (is_bezier_linear(p1x, p1y, p2x, p2y)) { init_function(a, y_at_start, y_at_end, identity_easing_curve); return; } diff --git a/kitty_tests/options.py b/kitty_tests/options.py index 5a7700cce..43a5bd206 100644 --- a/kitty_tests/options.py +++ b/kitty_tests/options.py @@ -157,16 +157,21 @@ class TestConfParsing(BaseTest): cb('linear(0, 0.25 25% 75%, 1)', first=EasingFunction('linear', linear_x=(0.0, 0.25, 0.75, 1.0), linear_y=(0, 0.25, 0.25, 1.0))) # test that easing functions give expected values - def ef(spec, tests, duration=0.5): + def ef(spec, tests, duration=0.5, accuracy=0): cfv = p('cursor_blink_interval ' + spec).cursor_blink_interval self.set_options({'cursor_blink_interval': cfv}) for t, expected in tests.items(): actual = test_cursor_blink_easing_function(t, duration) - self.ae(expected, actual, f'Failed for {spec=} with {t=}: {expected} != {actual}') + if abs(actual - expected) > accuracy: + self.ae(expected, actual, f'Failed for {spec=} with {t=}: {expected} != {actual}') ef('linear(0, 0.25 25% 75%, 1)', {0: 0, 0.25: 0.25, 0.3: 0.25, 0.75: 0.25, 1:1}) - for spec in ('linear', 'linear(0, 1)'): - ef(spec, {0: 0, 1: 1, 0.1234: 0.1234, 0.6453: 0.6453}) + linear_vals = {0: 0, 1: 1, 0.1234: 0.1234, 0.6453: 0.6453} + for spec in ('linear', 'linear(0, 1)', 'cubic-bezier(0, 0, 1, 1)', 'cubic-bezier(0.2, 0.2, 0.7, 0.7)'): + ef(spec, linear_vals) + # test an almost linear function to test cubic bezier implementation + ef('cubic-bezier(0.2, 0.2, 0.7, 0.71)', linear_vals, accuracy=0.01) + ef('cubic-bezier(0.23, 0.2, 0.7, 0.71)', linear_vals, accuracy=0.01) ef('steps(5)', {0: 0, 0.1: 0, 0.3: 0.2, 0.9:0.8}) ef('steps(5, start)', {0: 0.2, 0.1: 0.2, 0.3: 0.4, 0.9:1})