From ff0355ca9c6aef91a52622d78047ddd929b08587 Mon Sep 17 00:00:00 2001 From: Andrew Wood Date: Wed, 18 Dec 2024 21:59:17 +0000 Subject: [PATCH] Make the moving indicator more granular on wide displays by calculating its position with floating point rather than integer values. --- configure.ac | 2 ++ src/include/config.h.in | 3 +++ src/pv/format/progressbar.c | 29 ++++++++++++++++++++++------- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index b953953..7ae4d0c 100644 --- a/configure.ac +++ b/configure.ac @@ -44,8 +44,10 @@ AC_CHECK_MEMBERS([struct stat.st_blksize]) AC_CHECK_DECLS([SA_SIGINFO], [], [], [[#include ]]) AC_SEARCH_LIBS([sqrtl],[m]) +AC_SEARCH_LIBS([fmod],[m]) AC_CHECK_HEADERS([math.h]) AC_CHECK_FUNCS([sqrtl]) +AC_CHECK_FUNCS([fmod]) dnl Libraries that may contain key functions. AC_SEARCH_LIBS([clock_gettime],[rt]) diff --git a/src/include/config.h.in b/src/include/config.h.in index acecf5c..15e566e 100644 --- a/src/include/config.h.in +++ b/src/include/config.h.in @@ -44,6 +44,9 @@ /* Define to 1 if you have the `fdatasync' function. */ #undef HAVE_FDATASYNC +/* Define to 1 if you have the `fmod' function. */ +#undef HAVE_FMOD + /* Define to 1 if you have the `fpathconf' function. */ #undef HAVE_FPATHCONF diff --git a/src/pv/format/progressbar.c b/src/pv/format/progressbar.c index 803442e..15d51bc 100644 --- a/src/pv/format/progressbar.c +++ b/src/pv/format/progressbar.c @@ -12,6 +12,10 @@ #include +#if HAVE_MATH_H +#include +#endif + /* Convenience macro for appending a string to the buffer. */ #define append_to_buffer(x) { \ if (buffer_offset < (buffer_size - x.bytes)) { \ @@ -215,7 +219,8 @@ static pvdisplay_bytecount_t pv_formatter_progress_unknownsize(pvformatter_args_ pvdisplay_bytecount_t buffer_size, bool bar_sides) { pvdisplay_bytecount_t buffer_offset; - pvdisplay_width_t bar_area_width, pad_count, indicator_position; + pvdisplay_width_t bar_area_width, pad_count; + double indicator_position, padding_width; pvbarstyle_t style; buffer[0] = '\0'; @@ -242,11 +247,20 @@ static pvdisplay_bytecount_t pv_formatter_progress_unknownsize(pvformatter_args_ * here we make values above 100 send the indicator back down again, * so it moves back and forth. */ - indicator_position = (pvdisplay_width_t) (args->state->calc.percentage); - if (indicator_position > 200) - indicator_position = indicator_position % 200; - if (indicator_position > 100 && indicator_position <= 200) - indicator_position = 200 - indicator_position; + indicator_position = args->state->calc.percentage; + if (indicator_position > 200.0) +#if HAVE_FMOD + indicator_position = fmod(indicator_position, 200.0); +#else + { + while (indicator_position > 200.0) + indicator_position -= 200.0; + } +#endif + if (indicator_position > 100.0) + indicator_position = 200.0 - indicator_position; + if (indicator_position < 0.0) + indicator_position = 0.0; buffer_offset = 0; @@ -257,7 +271,8 @@ static pvdisplay_bytecount_t pv_formatter_progress_unknownsize(pvformatter_args_ /* The spaces before the indicator. */ pad_count = 0; - while (pad_count < bar_area_width && pad_count < ((bar_area_width * indicator_position) / 100)) { + padding_width = (((double) bar_area_width) * indicator_position) / 100.0; + while (pad_count < bar_area_width && pad_count < (pvdisplay_width_t) padding_width) { append_to_buffer(style->filler[0]); pad_count += style->filler[0].width; if (0 == style->filler[0].width)