diff --git a/cmake/ConkyBuildOptions.cmake b/cmake/ConkyBuildOptions.cmake index 91e7def34..7f53a47c0 100644 --- a/cmake/ConkyBuildOptions.cmake +++ b/cmake/ConkyBuildOptions.cmake @@ -267,8 +267,6 @@ option(BUILD_PULSEAUDIO option(BUILD_INTEL_BACKLIGHT "Enable support for Intel backlight" false) -option(BUILD_HSV_GRADIENT "Enable gradient in HSV colour space" true) - message(STATUS "CMAKE_C_FLAGS: " ${CMAKE_C_FLAGS}) message(STATUS "CMAKE_CXX_FLAGS: " ${CMAKE_CXX_FLAGS}) diff --git a/doc/config_settings.yaml b/doc/config_settings.yaml index cad1056e7..7720daf17 100644 --- a/doc/config_settings.yaml +++ b/doc/config_settings.yaml @@ -148,7 +148,9 @@ values: Substitute N by a number between 0 and 9 inclusive. Use the same format as a font variable. - name: forced_redraw - desc: Boolean value, if true, Conky will redraw everything when you switch the workspace. This may cause delays/flickering on some WMs. + desc: |- + Boolean value, if true, Conky will redraw everything when you switch the + workspace. This may cause delays/flickering on some WMs. - name: format_human_readable desc: |- If enabled, values which are in bytes will be printed in @@ -373,7 +375,8 @@ values: desc: |- If own_window_transparent no, set a specified background colour. Takes either a hex value (e.g. '#ffffff'), - a shorthand hex value (e.g. '#fff'), or a valid RGB name (see `/usr/lib/X11/rgb.txt`). + a shorthand hex value (e.g. '#fff'), or a valid RGB nam + (see `/usr/lib/X11/rgb.txt`). default: black args: - seconds @@ -433,6 +436,13 @@ values: desc: Shows the time range covered by a graph. - name: show_graph_scale desc: Shows the maximum value in scaled graphs. + - name: graph_gradient_mode + desc: |- + Changes the color space used for interpolation. Arguments are hcl, hsv, + and rgb (default). + args: + - (rbg|hcl|hsv) + default: rgb - name: stippled_borders desc: Border stippling (dashing) in pixels. - name: temperature_unit diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c6b5eb8db..1226d08cc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -68,6 +68,8 @@ set(conky_sources exec.h fs.cc fs.h + gradient.cc + gradient.h mail.cc mail.h misc.cc @@ -304,11 +306,6 @@ if(BUILD_INTEL_BACKLIGHT) set(optional_sources ${optional_sources} ${intel_backlight}) endif(BUILD_INTEL_BACKLIGHT) -if(BUILD_HSV_GRADIENT) - set(hsv_gradient hsv_gradient.cc hsv_gradient.h) - set(optional_sources ${optional_sources} ${hsv_gradient}) -endif(BUILD_HSV_GRADIENT) - if(BUILD_TESTS) # Create a library strictly for testing add_library(conky_core ${conky_sources} ${optional_sources}) diff --git a/src/cmus.cc b/src/cmus.cc index 640c43044..1b78d2095 100644 --- a/src/cmus.cc +++ b/src/cmus.cc @@ -99,12 +99,12 @@ void cmus_cb::work() { } else if (strncmp(line, "position ", 9) == 0) { cmus.curtime = line + 9; - cmus.timeleft = - strtol(cmus.totaltime.c_str(), nullptr, 10) - - strtol(cmus.curtime.c_str(), nullptr, 10); + cmus.timeleft = strtol(cmus.totaltime.c_str(), nullptr, 10) - + strtol(cmus.curtime.c_str(), nullptr, 10); if (cmus.curtime.size() > 0) { - cmus.progress = static_cast(strtol(cmus.curtime.c_str(), nullptr, 10)) / - strtol(cmus.totaltime.c_str(), nullptr, 10); + cmus.progress = + static_cast(strtol(cmus.curtime.c_str(), nullptr, 10)) / + strtol(cmus.totaltime.c_str(), nullptr, 10); } else { cmus.progress = 0; } @@ -189,7 +189,8 @@ void print_cmus_totaltime(struct text_object *obj, char *p, lround(music_player_interval.get(*state) / active_update_interval()), 1l); const cmus_result &cmus = conky::register_cb(period)->get_result_copy(); - format_seconds_short(p, p_max_size, strtol(cmus.totaltime.c_str(), nullptr, 10)); + format_seconds_short(p, p_max_size, + strtol(cmus.totaltime.c_str(), nullptr, 10)); } void print_cmus_timeleft(struct text_object *obj, char *p, @@ -209,7 +210,8 @@ void print_cmus_curtime(struct text_object *obj, char *p, lround(music_player_interval.get(*state) / active_update_interval()), 1l); const cmus_result &cmus = conky::register_cb(period)->get_result_copy(); - format_seconds_short(p, p_max_size, strtol(cmus.curtime.c_str(), nullptr, 10)); + format_seconds_short(p, p_max_size, + strtol(cmus.curtime.c_str(), nullptr, 10)); } #undef CMUS_PRINT_GENERATOR diff --git a/src/colours.cc b/src/colours.cc index 4437aa461..ab1a009b7 100644 --- a/src/colours.cc +++ b/src/colours.cc @@ -83,69 +83,6 @@ unsigned int adjust_colours(unsigned int colour) { return colour; } -/* this function returns the next colour between two colours for a gradient */ -std::unique_ptr do_gradient(int width, - unsigned long first_colour, - unsigned long last_colour) { - int red1, green1, blue1; // first colour - int red2, green2, blue2; // last colour - int reddiff, greendiff, bluediff; // difference - short redshift = (2 * colour_depth / 3 + colour_depth % 3); - short greenshift = (colour_depth / 3); - - // Make sure the width is always at least 2 - width = std::max(2, width); - - std::unique_ptr colours(new unsigned long[width]); - - if (colour_depth == 0) { set_up_gradient(); } - red1 = (first_colour & redmask) >> redshift; - green1 = (first_colour & greenmask) >> greenshift; - blue1 = first_colour & bluemask; - red2 = (last_colour & redmask) >> redshift; - green2 = (last_colour & greenmask) >> greenshift; - blue2 = last_colour & bluemask; - reddiff = abs(red1 - red2); - greendiff = abs(green1 - green2); - bluediff = abs(blue1 - blue2); -#ifdef HAVE_OPENMP -#pragma omp parallel for schedule(dynamic, 10) shared(colours) -#endif /* HAVE_OPENMP */ - for (int i = 0; i < width; i++) { - int red3 = 0, green3 = 0, blue3 = 0; // colour components - - float factor = (static_cast(i) / (width - 1)); - - /* the '+ 0.5' bit rounds our floats to ints properly */ - if (red1 >= red2) { - red3 = -(factor * reddiff) - 0.5; - } else if (red1 < red2) { - red3 = factor * reddiff + 0.5; - } - if (green1 >= green2) { - green3 = -(factor * greendiff) - 0.5; - } else if (green1 < green2) { - green3 = factor * greendiff + 0.5; - } - if (blue1 >= blue2) { - blue3 = -(factor * bluediff) - 0.5; - } else if (blue1 < blue2) { - blue3 = factor * bluediff + 0.5; - } - red3 += red1; - green3 += green1; - blue3 += blue1; - if (red3 < 0) { red3 = 0; } - if (green3 < 0) { green3 = 0; } - if (blue3 < 0) { blue3 = 0; } - if (red3 > bluemask) { red3 = bluemask; } - if (green3 > bluemask) { green3 = bluemask; } - if (blue3 > bluemask) { blue3 = bluemask; } - colours[i] = (red3 << redshift) | (green3 << greenshift) | blue3; - } - return colours; -} - #ifdef BUILD_X11 long get_x11_color(const char *name) { XColor color; diff --git a/src/colours.h b/src/colours.h index e943b8a90..e9348369a 100644 --- a/src/colours.h +++ b/src/colours.h @@ -33,7 +33,6 @@ #include unsigned int adjust_colours(unsigned int); -std::unique_ptr do_gradient(int, unsigned long, unsigned long); long get_x11_color(const std::string &colour); // XXX: when everyone uses C++ strings, remove this C version diff --git a/src/common.cc b/src/common.cc index 37d6dd770..3b3da656b 100644 --- a/src/common.cc +++ b/src/common.cc @@ -525,7 +525,8 @@ void print_cached(struct text_object *obj, char *p, unsigned int p_max_size) { p_max_size); } -void print_free_bufcache(struct text_object *obj, char *p, unsigned int p_max_size) { +void print_free_bufcache(struct text_object *obj, char *p, + unsigned int p_max_size) { human_readable(apply_base_multiplier(obj->data.s, info.free_bufcache), p, p_max_size); } diff --git a/src/conky.cc b/src/conky.cc index 07551a184..2b15299d4 100644 --- a/src/conky.cc +++ b/src/conky.cc @@ -133,9 +133,7 @@ #include "openbsd.h" #endif /* __OpenBSD__ */ -#ifdef BUILD_HSV_GRADIENT -#include "hsv_gradient.h" -#endif /* BUILD_HSV_GRADIENT */ +#include "gradient.h" #ifdef BUILD_OLD_CONFIG #include "convertconf.h" @@ -294,12 +292,19 @@ conky::range_config_setting diskio_avg_samples("diskio_avg_samples", 1, 14, 2, true); #ifdef BUILD_GUI - +/* graph */ conky::simple_config_setting show_graph_scale("show_graph_scale", false, false); conky::simple_config_setting show_graph_range("show_graph_range", false, false); +enum gradient_state { RGB_GRADIENT = 0, HSV_GRADIENT, HCL_GRADIENT }; +template <> +conky::lua_traits::Map conky::lua_traits::map = + {{"rgb", RGB_GRADIENT}, {"hsv", HSV_GRADIENT}, {"hcl", HCL_GRADIENT}}; +static conky::simple_config_setting graph_gradient_mode( + "graph_gradient_mode", RGB_GRADIENT, false); + /* Position on the screen */ conky::simple_config_setting gap_x("gap_x", 5, true); conky::simple_config_setting gap_y("gap_y", 60, true); @@ -401,6 +406,22 @@ int dpi_scale(int value) { #endif /* BUILD_GUI */ } +#ifdef BUILD_GUI +conky::gradient_factory *create_gradient_factory(int width, + unsigned long first_colour, + unsigned long last_colour) { + switch (graph_gradient_mode.get(*state)) { + case RGB_GRADIENT: + return new conky::rgb_gradient_factory(width, first_colour, last_colour); + case HSV_GRADIENT: + return new conky::hsv_gradient_factory(width, first_colour, last_colour); + case HCL_GRADIENT: + return new conky::hcl_gradient_factory(width, first_colour, last_colour); + } + return nullptr; +} +#endif /* BUILD_GUI */ + /* formatted text to render on screen, generated in generate_text(), * drawn in draw_stuff() */ @@ -1294,13 +1315,10 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) { std::unique_ptr tmpcolour; if (current->last_colour != 0 || current->first_colour != 0) { -#ifdef BUILD_HSV_GRADIENT - tmpcolour = do_hsv_gradient(w - 1, current->last_colour, - current->first_colour); -#else /* BUILD_HSV_GRADIENT */ - tmpcolour = do_gradient(w - 1, current->last_colour, - current->first_colour); -#endif /* BUILD_HSV_GRADIENT */ + auto factory = create_gradient_factory(w, current->last_colour, + current->first_colour); + tmpcolour = factory->create_gradient(); + delete factory; } colour_idx = 0; for (i = w - 2; i > -1; i--) { diff --git a/src/core.cc b/src/core.cc index 7b1a3f790..4bdea21b3 100644 --- a/src/core.cc +++ b/src/core.cc @@ -434,7 +434,8 @@ struct text_object *construct_text_object(char *s, const char *arg, long line, END OBJ(freq, nullptr) get_cpu_count(); if ((arg == nullptr) || strlen(arg) >= 3 || strtol(&arg[0], nullptr, 10) == 0 || - static_cast(strtol(&arg[0], nullptr, 10)) > info.cpu_count) { + static_cast(strtol(&arg[0], nullptr, 10)) > + info.cpu_count) { obj->data.i = 1; /* NORM_ERR("freq: Invalid CPU number or you don't have that many CPUs! " "Displaying the clock for CPU 1."); */ @@ -445,7 +446,8 @@ struct text_object *construct_text_object(char *s, const char *arg, long line, END OBJ(freq_g, nullptr) get_cpu_count(); if ((arg == nullptr) || strlen(arg) >= 3 || strtol(&arg[0], nullptr, 10) == 0 || - static_cast(strtol(&arg[0], nullptr, 10)) > info.cpu_count) { + static_cast(strtol(&arg[0], nullptr, 10)) > + info.cpu_count) { obj->data.i = 1; /* NORM_ERR("freq_g: Invalid CPU number or you don't have that many " "CPUs! Displaying the clock for CPU 1."); */ @@ -457,7 +459,8 @@ struct text_object *construct_text_object(char *s, const char *arg, long line, END OBJ(cpugovernor, nullptr) get_cpu_count(); if ((arg == nullptr) || strlen(arg) >= 3 || strtol(&arg[0], nullptr, 10) == 0 || - static_cast(strtol(&arg[0], nullptr, 10)) > info.cpu_count) { + static_cast(strtol(&arg[0], nullptr, 10)) > + info.cpu_count) { obj->data.i = 1; /* NORM_ERR("cpugovernor: Invalid CPU number or you don't have that " "many CPUs! Displaying the scaling governor for CPU 1."); */ @@ -484,7 +487,7 @@ struct text_object *construct_text_object(char *s, const char *arg, long line, #if defined(__linux__) END OBJ(voltage_mv, 0) get_cpu_count(); if (!arg || strlen(arg) >= 3 || strtol(&arg[0], nullptr, 10) == 0 || - (unsigned int)strtol(&arg[0], nullptr, 10) > info.cpu_count) { + (unsigned int)strtol(&arg[0], nullptr, 10) > info.cpu_count) { obj->data.i = 1; /* NORM_ERR("voltage_mv: Invalid CPU number or you don't have that many " "CPUs! Displaying voltage for CPU 1."); */ @@ -494,7 +497,7 @@ struct text_object *construct_text_object(char *s, const char *arg, long line, obj->callbacks.print = &print_voltage_mv; END OBJ(voltage_v, 0) get_cpu_count(); if (!arg || strlen(arg) >= 3 || strtol(&arg[0], nullptr, 10) == 0 || - (unsigned int)strtol(&arg[0], nullptr, 10) > info.cpu_count) { + (unsigned int)strtol(&arg[0], nullptr, 10) > info.cpu_count) { obj->data.i = 1; /* NORM_ERR("voltage_v: Invalid CPU number or you don't have that many " "CPUs! Displaying voltage for CPU 1."); */ @@ -1029,20 +1032,24 @@ struct text_object *construct_text_object(char *s, const char *arg, long line, END OBJ(fs_used, &update_fs_stats) init_fs(obj, arg); obj->callbacks.print = &print_fs_used; #ifdef BUILD_GUI - END OBJ(hr, nullptr) obj->data.l = arg != nullptr ? strtol(arg, nullptr, 10) : 1; + END OBJ(hr, nullptr) obj->data.l = + arg != nullptr ? strtol(arg, nullptr, 10) : 1; obj->callbacks.print = &new_hr; #endif /* BUILD_GUI */ END OBJ(nameserver, &update_dns_data) parse_nameserver_arg(obj, arg); obj->callbacks.print = &print_nameserver; obj->callbacks.free = &free_dns_data; - END OBJ(offset, nullptr) obj->data.l = arg != nullptr ? strtol(arg, nullptr, 10) : 1; + END OBJ(offset, nullptr) obj->data.l = + arg != nullptr ? strtol(arg, nullptr, 10) : 1; obj->callbacks.print = &new_offset; - END OBJ(voffset, nullptr) obj->data.l = arg != nullptr ? strtol(arg, nullptr, 10) : 1; + END OBJ(voffset, nullptr) obj->data.l = + arg != nullptr ? strtol(arg, nullptr, 10) : 1; obj->callbacks.print = &new_voffset; END OBJ(save_coordinates, nullptr) obj->data.l = arg != nullptr ? strtol(arg, nullptr, 10) : 0; obj->callbacks.print = &new_save_coordinates; - END OBJ_ARG(goto, nullptr, "goto needs arguments") obj->data.l = strtol(arg, nullptr, 10); + END OBJ_ARG(goto, nullptr, "goto needs arguments") obj->data.l = + strtol(arg, nullptr, 10); obj->callbacks.print = &new_goto; #ifdef BUILD_GUI END OBJ(tab, nullptr) scan_tab(obj, arg); @@ -1505,7 +1512,8 @@ struct text_object *construct_text_object(char *s, const char *arg, long line, parse_net_stat_arg(obj, arg, free_at_crash); obj->callbacks.print = &print_totalup; END OBJ(updates, nullptr) obj->callbacks.print = &print_updates; - END OBJ_IF(if_updatenr, nullptr) obj->data.i = arg != nullptr ? strtol(arg, nullptr, 10) : 0; + END OBJ_IF(if_updatenr, nullptr) obj->data.i = + arg != nullptr ? strtol(arg, nullptr, 10) : 0; if (obj->data.i == 0) { CRIT_ERR(obj, free_at_crash, "if_updatenr needs a number above 0 as argument"); @@ -1513,9 +1521,11 @@ struct text_object *construct_text_object(char *s, const char *arg, long line, set_updatereset(obj->data.i > get_updatereset() ? obj->data.i : get_updatereset()); obj->callbacks.iftest = &updatenr_iftest; - END OBJ(alignr, nullptr) obj->data.l = arg != nullptr ? strtol(arg, nullptr, 10) : 1; + END OBJ(alignr, nullptr) obj->data.l = + arg != nullptr ? strtol(arg, nullptr, 10) : 1; obj->callbacks.print = &new_alignr; - END OBJ(alignc, nullptr) obj->data.l = arg != nullptr ? strtol(arg, nullptr, 10) : 0; + END OBJ(alignc, nullptr) obj->data.l = + arg != nullptr ? strtol(arg, nullptr, 10) : 0; obj->callbacks.print = &new_alignc; END OBJ(upspeed, &update_net_stats) parse_net_stat_arg(obj, arg, free_at_crash); diff --git a/src/gradient.cc b/src/gradient.cc new file mode 100644 index 000000000..77d9a09ea --- /dev/null +++ b/src/gradient.cc @@ -0,0 +1,335 @@ +/* + * + * Conky, a system monitor, based on torsmo + * + * Any original torsmo code is licensed under the BSD license + * + * All code written since the fork of torsmo is licensed under the GPL + * + * Please see COPYING for details + * + * Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen + * Copyright (c) 2005-2021 Brenden Matthews, Philip Kovacs, et. al. + * (see AUTHORS) + * All rights reserved. + * + * This program 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 . + * + */ +#include "gradient.h" +#include "conky.h" +#include "logging.h" + +#ifdef BUILD_X11 +#include "x11.h" +#endif /* BUILD_X11 */ + +namespace conky { +bool gradient_factory::is_set = false; +short gradient_factory::colour_depth = 0; +long gradient_factory::mask[3]; +short gradient_factory::shift[3]; + +gradient_factory::gradient_factory(int width, unsigned long first_colour, + unsigned long last_colour) { + // Make sure the width is always at least 2 + this->width = std::max(2, width); + this->first_colour = first_colour; + this->last_colour = last_colour; + + if (!is_set) { + setup_colour_depth(); + setup_shifts(); + setup_masks(); + is_set = true; + } +} + +void gradient_factory::setup_shifts() { + shift[0] = (2 * colour_depth / 3 + colour_depth % 3); + shift[1] = (colour_depth / 3); + shift[2] = 0; +} + +void gradient_factory::setup_masks() { + mask[0] = mask[1] = mask[2] = 0; + + for (int i = (colour_depth / 3) - 1; i >= 0; i--) { + mask[0] |= 1 << i; + mask[1] |= 1 << i; + mask[2] |= 1 << i; + } + + if (colour_depth % 3 == 1) { + mask[1] |= 1 << (colour_depth / 3); + } + + for (int i = 0; i < 3; i++) { + mask[i] = mask[i] << shift[i]; + } +} + +void gradient_factory::setup_colour_depth() { +#ifdef BUILD_X11 + if (state == nullptr) { // testing purposes + colour_depth = 24; + } else if (out_to_x.get(*state)) { + colour_depth = DisplayPlanes(display, screen); + } else +#endif /* BUILD_X11 */ + { + colour_depth = 16; + } + + if (colour_depth != 24 && colour_depth != 16) { + NORM_ERR( + "using non-standard colour depth, " + "gradients may look like a lolly-pop"); + } +} + +void gradient_factory::convert_from_rgb(long original, long *array) { + long scaled[3]; + + for (int i = 0; i < 3; i++) { + auto value = (original & mask[i]) >> shift[i]; + scaled[i] = value * SCALE; + } + convert_from_scaled_rgb(scaled, array); +} + +int gradient_factory::convert_to_rgb(long *const array) { + long scaled_rgb[3]; + int rgb = 0; + + convert_to_scaled_rgb(array, scaled_rgb); + for (int i = 0; i < 3; i++) { + auto value = scaled_rgb[i] / SCALE; + rgb |= value << shift[i]; + } + + return rgb; +} + +gradient_factory::colour_array gradient_factory::create_gradient() { + colour_array colours(new unsigned long[width]); + + long first_converted[3]; + long last_converted[3]; + long diff[3], delta[3]; + + colours[0] = first_colour; + colours[width - 1] = last_colour; + + convert_from_rgb(first_colour, first_converted); + convert_from_rgb(last_colour, last_converted); + + for (int i = 0; i < 3; i++) { + diff[i] = last_converted[i] - first_converted[i]; + } + fix_diff(diff); + for (int i = 0; i < 3; i++) { delta[i] = diff[i] / (width - 1); } + for (int i = 1; i < width - 1; i++) { + for (int k = 0; k < 3; k++) { first_converted[k] += delta[k]; } + colours[i] = convert_to_rgb(first_converted); + } + + return colours; +} + +long gradient_factory::get_hue(long *const rgb, long chroma, long value) { + if (chroma == 0) { return 0; } + + long diff, offset; + + if (rgb[0] == value) { + diff = rgb[1] - rgb[2]; + offset = 0; + } else if (rgb[1] == value) { + diff = rgb[2] - rgb[0]; + offset = SCALE2; + } else { + diff = rgb[0] - rgb[1]; + offset = SCALE4; + } + long h = (SCALE * diff) / chroma + offset; + + return 60L * ((SCALE6 + h) % SCALE6); +} + +long gradient_factory::get_intermediate(long hue, long chroma) { + long h = hue / 60L; + long multiplier = SCALE - std::abs(h % SCALE2 - SCALE); + + return (chroma * multiplier) / SCALE; +} + +/* rgb_gradient_factory */ +void rgb_gradient_factory::convert_from_scaled_rgb(long *const scaled, + long *target) { + target[0] = scaled[0] * 360L; + target[1] = scaled[1] * 360L; + target[2] = scaled[2] * 360L; +} + +void rgb_gradient_factory::convert_to_scaled_rgb(long *const target, + long *scaled) { + scaled[0] = target[0] / 360L; + scaled[1] = target[1] / 360L; + scaled[2] = target[2] / 360L; +} +/* rgb_gradient_factory */ + +namespace { +long get_value(long *const rgb) { + if (rgb[0] > rgb[1]) { return std::max(rgb[0], rgb[2]); } + return std::max(rgb[1], rgb[2]); +} + +long get_minimum(long *const rgb) { + if (rgb[0] < rgb[1]) { return std::min(rgb[0], rgb[2]); } + return std::min(rgb[1], rgb[2]); +} +} // namespace + +/* hsv_gradient_factory */ +void hsv_gradient_factory::fix_diff(long *diff) { + if (diff[0] > SCALE180) { + diff[0] -= SCALE360; + } else if (diff[0] < -SCALE180) { + diff[0] += SCALE360; + } +} + +void hsv_gradient_factory::convert_from_scaled_rgb(long *const scaled, + long *target) { + auto value = get_value(scaled); + auto minimum = get_minimum(scaled); + auto chroma = value - minimum; + auto saturation = (SCALE360 * chroma) / value; + + target[0] = get_hue(scaled, chroma, value); + target[1] = saturation; + target[2] = value * 360L; +} + +void hsv_gradient_factory::convert_to_scaled_rgb(long *const target, + long *scaled) { + auto hue = target[0] % SCALE360; + auto saturation = target[1] / 360L; + auto value = target[2] / 360L; + auto chroma = (saturation * value) / SCALE; + auto x = get_intermediate(hue, chroma); + + scaled[0] = scaled[1] = scaled[2] = (value - chroma); + + if (hue < SCALE60) { + scaled[0] += chroma; + scaled[1] += x; + } else if (hue < SCALE120) { + scaled[0] += x; + scaled[1] += chroma; + } else if (hue < SCALE180) { + scaled[1] += chroma; + scaled[2] += x; + } else if (hue < SCALE240) { + scaled[1] += x; + scaled[2] += chroma; + } else if (hue < SCALE300) { + scaled[2] += chroma; + scaled[0] += x; + } else { + scaled[2] += x; + scaled[0] += chroma; + } +} +/* hsv_gradient_factory */ + +namespace { +// Using Rec.2020 color space +// Y' = 0.2627 x R + 0.6780 x G + 0.0593 x B +long get_luma(long *const rgb) { + return 360L * (2627L * rgb[0] + 6780L * rgb[1] + 593L * rgb[2]) / 10000L; +} + +// Using Rec.2020 color space +// m = Y' - (0.2627 x R + 0.6780 x G + 0.0593 x B) +long get_minimum_from_luma(long luma, long r, long g, long b) { + return luma - (2627L * r + 6780L * g + 593L * b) / 10000L; +} +} // namespace + +/* hcl_gradient_factory */ +void hcl_gradient_factory::fix_diff(long *diff) { + if (diff[0] > SCALE180) { + diff[0] -= SCALE360; + } else if (diff[0] < -SCALE180) { + diff[0] += SCALE360; + } +} + +void hcl_gradient_factory::convert_from_scaled_rgb(long *const scaled, + long *target) { + auto value = get_value(scaled); + auto minimum = get_minimum(scaled); + auto luma = get_luma(scaled); + auto chroma = value - minimum; + + target[0] = get_hue(scaled, chroma, value); + target[1] = chroma * 360L; + target[2] = luma; +} + +void hcl_gradient_factory::convert_to_scaled_rgb(long *const target, + long *scaled) { + auto hue = target[0] % SCALE360; + auto chroma = target[1] / 360L; + auto luma = target[2] / 360L; + + auto x = get_intermediate(hue, chroma); + long m; + + if (hue < SCALE60) { + m = get_minimum_from_luma(luma, chroma, x, 0); + scaled[0] = scaled[1] = scaled[2] = m; + scaled[0] += chroma; + scaled[1] += x; + } else if (hue < SCALE120) { + m = get_minimum_from_luma(luma, x, chroma, 0); + scaled[0] = scaled[1] = scaled[2] = m; + scaled[0] += x; + scaled[1] += chroma; + } else if (hue < SCALE180) { + m = get_minimum_from_luma(luma, 0, chroma, x); + scaled[0] = scaled[1] = scaled[2] = m; + scaled[1] += chroma; + scaled[2] += x; + } else if (hue < SCALE240) { + m = get_minimum_from_luma(luma, 0, x, chroma); + scaled[0] = scaled[1] = scaled[2] = m; + scaled[1] += x; + scaled[2] += chroma; + } else if (hue < SCALE300) { + m = get_minimum_from_luma(luma, x, 0, chroma); + scaled[0] = scaled[1] = scaled[2] = m; + scaled[2] += chroma; + scaled[0] += x; + } else { + m = get_minimum_from_luma(luma, chroma, 0, x); + scaled[0] = scaled[1] = scaled[2] = m; + scaled[2] += x; + scaled[0] += chroma; + } +} +/* hcl_gradient_factory */ +} // namespace conky diff --git a/src/gradient.h b/src/gradient.h new file mode 100644 index 000000000..b46db9a6b --- /dev/null +++ b/src/gradient.h @@ -0,0 +1,111 @@ +/* + * + * Conky, a system monitor, based on torsmo + * + * Any original torsmo code is licensed under the BSD license + * + * All code written since the fork of torsmo is licensed under the GPL + * + * Please see COPYING for details + * + * Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen + * Copyright (c) 2005-2021 Brenden Matthews, Philip Kovacs, et. al. + * (see AUTHORS) + * All rights reserved. + * + * This program 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 . + * + */ + +#ifndef _GRADIENT_H +#define _GRADIENT_H + +#include + +namespace conky { +class gradient_factory { + public: + typedef std::unique_ptr colour_array; + static const long SCALE = 512L; + static const long SCALE2 = SCALE * 2; + static const long SCALE4 = SCALE * 4; + static const long SCALE6 = SCALE * 6; + static const long SCALE60 = SCALE * 60; + static const long SCALE120 = SCALE * 120; + static const long SCALE180 = SCALE * 180; + static const long SCALE240 = SCALE * 240; + static const long SCALE300 = SCALE * 300; + static const long SCALE360 = SCALE * 360; + + public: + gradient_factory(int width, unsigned long first_colour, + unsigned long last_colour); + virtual ~gradient_factory() { } + + colour_array create_gradient(); + + virtual void convert_from_scaled_rgb(long *const scaled, long *target) = 0; + virtual void convert_to_scaled_rgb(long *const target, long *scaled) = 0; + + void convert_from_rgb(long original, long *array); + int convert_to_rgb(long *const array); + + protected: + virtual void fix_diff(long *) {} + + static long get_hue(long *const scaled, long chroma, long value); + static long get_intermediate(long hue, long chroma); + + static short colour_depth; + static long mask[3]; + static short shift[3]; + + private: + int width; + unsigned long first_colour; + unsigned long last_colour; + + static bool is_set; + static void setup_colour_depth(); + static void setup_masks(); + static void setup_shifts(); +}; + +class rgb_gradient_factory : public gradient_factory { + using gradient_factory::gradient_factory; + + public: + void convert_from_scaled_rgb(long *const scaled, long *target); + void convert_to_scaled_rgb(long *const target, long *scaled); +}; + +class hsv_gradient_factory : public gradient_factory { + using gradient_factory::gradient_factory; + + public: + void fix_diff(long *diff); + void convert_from_scaled_rgb(long *const scaled, long *target); + void convert_to_scaled_rgb(long *const target, long *scaled); +}; + +class hcl_gradient_factory : public gradient_factory { + using gradient_factory::gradient_factory; + + public: + void fix_diff(long *diff); + void convert_from_scaled_rgb(long *const scaled, long *target); + void convert_to_scaled_rgb(long *const target, long *scaled); +}; +} // namespace conky + +#endif /* _GRADIENT_H */ diff --git a/src/hsv_gradient.cc b/src/hsv_gradient.cc deleted file mode 100644 index 0962e0c33..000000000 --- a/src/hsv_gradient.cc +++ /dev/null @@ -1,221 +0,0 @@ -/* - * - * Conky, a system monitor, based on torsmo - * - * Any original torsmo code is licensed under the BSD license - * - * All code written since the fork of torsmo is licensed under the GPL - * - * Please see COPYING for details - * - * Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen - * Copyright (c) 2005-2021 Brenden Matthews, Philip Kovacs, et. al. - * (see AUTHORS) - * All rights reserved. - * - * This program 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 . - * - */ -#include "hsv_gradient.h" -#include "colours.h" -#include "conky.h" -#include "logging.h" - -#ifdef BUILD_X11 -#include "x11.h" -#endif /* BUILD_X11 */ - -#define CONST_SCALE 512L -#define CONST_SCALE_HALF (CONST_SCALE / 2) -#define CONST_SCALE2 (CONST_SCALE * 2L) -#define CONST_SCALE4 (CONST_SCALE * 4L) -#define CONST_SCALE6 (CONST_SCALE * 6L) -#define CONST_SCALE60 (CONST_SCALE * 60L) -#define CONST_SCALE120 (CONST_SCALE * 120L) -#define CONST_SCALE180 (CONST_SCALE * 180L) -#define CONST_SCALE240 (CONST_SCALE * 240L) -#define CONST_SCALE300 (CONST_SCALE * 300L) -#define CONST_SCALE360 (CONST_SCALE * 360L) - -long to_decimal_scale(long value, long max_value) { - if (value == 0) { - return 0; - } else if (value > 0) { - return (value * CONST_SCALE + max_value - 1) / max_value; - } - return -((std::abs(value) * CONST_SCALE + max_value - 1) / max_value); -} - -long from_decimal_scale(long value, long max_value) { - if (value == 0) { - return 0; - } else if (value > 0) { - return (value * max_value + CONST_SCALE_HALF) / CONST_SCALE; - } - return -((std::abs(value) * max_value + CONST_SCALE_HALF) / CONST_SCALE); -} - -void scaled_rgb_to_scaled_hsv(long *const rgb, long *hsv) { - long val = - rgb[0] > rgb[1] ? std::max(rgb[0], rgb[2]) : std::max(rgb[1], rgb[2]); - long cmin = - rgb[0] < rgb[1] ? std::min(rgb[0], rgb[2]) : std::min(rgb[1], rgb[2]); - long delta = val - cmin; - - long hue; - - if (delta == 0) { - hue = 0; - } else { - long d; - long offset; - - if (rgb[0] == val) { - d = rgb[1] - rgb[2]; - offset = 0; - } else if (rgb[1] == val) { - d = rgb[2] - rgb[0]; - offset = CONST_SCALE2; - } else { - d = rgb[0] - rgb[1]; - offset = CONST_SCALE4; - } - long h = (CONST_SCALE * d + delta / 2) / delta + offset; - hue = 60L * ((CONST_SCALE6 + h) % CONST_SCALE6); - } - - long sat; - if (val == 0) { - sat = 0; - } else { - sat = (CONST_SCALE * delta + val / 2) / val; - } - - hsv[0] = hue; - hsv[1] = sat; - hsv[2] = val; -} - -void scaled_hsv_to_scaled_rgb(long *const hsv, long *rgb) { - long c = (hsv[2] * hsv[1] + CONST_SCALE_HALF) / CONST_SCALE; - - long hue = hsv[0] % CONST_SCALE360; - long x = (c * (CONST_SCALE - - std::abs(((hue + 30L) / 60L) % CONST_SCALE2 - CONST_SCALE)) + - CONST_SCALE_HALF) / - CONST_SCALE; - long m = hsv[2] - c; - - rgb[0] = m; - rgb[1] = m; - rgb[2] = m; - - if (hue < CONST_SCALE60) { - rgb[0] += c; - rgb[1] += x; - } else if (hue < CONST_SCALE120) { - rgb[0] += x; - rgb[1] += c; - } else if (hue < CONST_SCALE180) { - rgb[1] += c; - rgb[2] += x; - } else if (hue < CONST_SCALE240) { - rgb[1] += x; - rgb[2] += c; - } else if (hue < CONST_SCALE300) { - rgb[2] += c; - rgb[0] += x; - } else { - rgb[2] += x; - rgb[0] += c; - } -} - -/* this function returns the next colour between two colours in hsv space for a - * gradient */ -std::unique_ptr do_hsv_gradient(int width, - unsigned long first_colour, - unsigned long last_colour) { - long rgb1[3], rgb2[3], rgb3[3]; - long hsv1[3], hsv2[3]; - long hueDiff, satDiff, valDiff; - - int redshift = (2 * colour_depth / 3 + colour_depth % 3); - int greenshift = (colour_depth / 3); - - // Make sure the width is always at least 2 - width = std::max(2, width); - - std::unique_ptr colours(new unsigned long[width]); - - if (colour_depth == 0) { set_up_gradient(); } - - rgb1[0] = to_decimal_scale((first_colour & redmask) >> redshift, - redmask >> redshift); - rgb1[1] = to_decimal_scale((first_colour & greenmask) >> greenshift, - greenmask >> greenshift); - rgb1[2] = to_decimal_scale(first_colour & bluemask, bluemask); - rgb2[0] = to_decimal_scale((last_colour & redmask) >> redshift, - redmask >> redshift); - rgb2[1] = to_decimal_scale((last_colour & greenmask) >> greenshift, - greenmask >> greenshift); - rgb2[2] = to_decimal_scale(last_colour & bluemask, bluemask); - - scaled_rgb_to_scaled_hsv(rgb1, hsv1); - scaled_rgb_to_scaled_hsv(rgb2, hsv2); - - hueDiff = hsv2[0] - hsv1[0]; - // use shortest hue path - if (hueDiff > CONST_SCALE180) { - hueDiff = hueDiff - CONST_SCALE360; - } else if (hueDiff < -CONST_SCALE180) { - hueDiff = hueDiff + CONST_SCALE360; - } - satDiff = hsv2[1] - hsv1[1]; - valDiff = hsv2[2] - hsv1[2]; - - colours[0] = first_colour; - colours[width - 1] = last_colour; - - for (int i = 1; i < (width - 1); i++) { - long k; - - long divisor = width - i; - k = (hueDiff + divisor / 2) / divisor; - hueDiff -= k; - long h = hsv1[0] + k; - if (h < 0) { - hsv1[0] = CONST_SCALE360 + h; - } else { - hsv1[0] = h; - } - - k = (satDiff + divisor / 2) / divisor; - satDiff -= k; - hsv1[1] += k; - - k = (valDiff + divisor / 2) / divisor; - valDiff -= k; - hsv1[2] += k; - - scaled_hsv_to_scaled_rgb(hsv1, rgb3); - - long red3 = from_decimal_scale(rgb3[0], bluemask); - long green3 = from_decimal_scale(rgb3[1], bluemask); - long blue3 = from_decimal_scale(rgb3[2], bluemask); - - colours[i] = (red3 << redshift) | (green3 << greenshift) | blue3; - } - - return colours; -} diff --git a/src/hsv_gradient.h b/src/hsv_gradient.h deleted file mode 100644 index 9c624538d..000000000 --- a/src/hsv_gradient.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * Conky, a system monitor, based on torsmo - * - * Any original torsmo code is licensed under the BSD license - * - * All code written since the fork of torsmo is licensed under the GPL - * - * Please see COPYING for details - * - * Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen - * Copyright (c) 2005-2021 Brenden Matthews, Philip Kovacs, et. al. - * (see AUTHORS) - * All rights reserved. - * - * This program 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 . - * - */ -#ifndef _HSV_GRADIENT_H -#define _HSV_GRADIENT_H - -#include - -// needed by hsv_gradient -extern short colour_depth; -extern long redmask, greenmask, bluemask; -extern void set_up_gradient(); - -std::unique_ptr do_hsv_gradient(int, unsigned long, - unsigned long); - -long to_decimal_scale(long value, long max_value); -long from_decimal_scale(long value, long max_value); -void scaled_rgb_to_scaled_hsv(long *const rgb, long *hsv); -void scaled_hsv_to_scaled_rgb(long *const hsv, long *rgb); - -#endif /* _COLOURS_H */ diff --git a/src/linux.cc b/src/linux.cc index 6f0be1ea5..27ed293b7 100644 --- a/src/linux.cc +++ b/src/linux.cc @@ -192,7 +192,7 @@ int update_meminfo(void) { info.memmax = info.memdirty = info.swap = info.swapfree = info.swapmax = info.memwithbuffers = info.buffers = info.cached = info.memfree = info.memeasyfree = info.legacymem = info.shmem = info.memavail = - info.free_bufcache = 0; + info.free_bufcache = 0; if (!(meminfo_fp = open_file("/proc/meminfo", &reported))) { return 0; } @@ -1583,9 +1583,9 @@ char get_freq(char *p_client_buffer, size_t client_buffer_size, #define CPUFREQ_GOVERNOR "cpufreq/scaling_governor" -/* print the CPU scaling governor */ +/* print the CPU scaling governor */ void print_cpugovernor(struct text_object *obj, char *p, - unsigned int p_max_size) { + unsigned int p_max_size) { FILE *fp; char buf[64]; unsigned int cpu = obj->data.i; diff --git a/src/main.cc b/src/main.cc index 65d375aae..aad918427 100644 --- a/src/main.cc +++ b/src/main.cc @@ -182,9 +182,6 @@ static void print_version() { << _(" * Own window\n") #endif #endif /* BUILD_X11 */ -#ifdef BUILD_HSV_GRADIENT - << _(" * HSV Gradient\n") -#endif /* BUILD_HSV_GRADIENT */ #if defined BUILD_AUDACIOUS || defined BUILD_CMUS || defined BUILD_MPD || \ defined BUILD_MOC || defined BUILD_XMMS2 << _("\n Music detection:\n") diff --git a/src/nvidia.cc b/src/nvidia.cc index 7ddd92868..3d8fb68ee 100644 --- a/src/nvidia.cc +++ b/src/nvidia.cc @@ -1032,8 +1032,7 @@ void print_nvidia_value(struct text_object *obj, char *p, if (value != -1) { if (nvs->is_percentage) { percent_print(p, p_max_size, value); - } - else { + } else { snprintf(p, p_max_size, "%d", value); } } else if (str != nullptr) { diff --git a/src/specials.cc b/src/specials.cc index 93e423c0c..047403480 100644 --- a/src/specials.cc +++ b/src/specials.cc @@ -419,7 +419,7 @@ void new_gauge(struct text_object *obj, char *p, unsigned int p_max_size, if (out_to_stdout.get(*state)) { new_gauge_in_shell(obj, p, p_max_size, usage); } -#else /* BUILD_GUI */ +#else /* BUILD_GUI */ new_gauge_in_shell(obj, p, p_max_size, usage); #endif /* BUILD_GUI */ } @@ -728,7 +728,7 @@ void new_bar(struct text_object *obj, char *p, unsigned int p_max_size, if (out_to_stdout.get(*state)) { new_bar_in_shell(obj, p, p_max_size, usage); } -#else /* BUILD_GUI */ +#else /* BUILD_GUI */ new_bar_in_shell(obj, p, p_max_size, usage); #endif /* BUILD_GUI */ } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2db5f75af..0d8552ec6 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -17,9 +17,7 @@ endif() set(test_srcs ${test_srcs} test-core.cc) set(test_srcs ${test_srcs} test-diskio.cc) set(test_srcs ${test_srcs} test-fs.cc) -if(BUILD_HSV_GRADIENT) - set(test_srcs ${test_srcs} test-hsv.cc) -endif(BUILD_HSV_GRADIENT) +set(test_srcs ${test_srcs} test-gradient.cc) add_executable(test-conky test-common.cc ${test_srcs}) target_link_libraries(test-conky conky_core) diff --git a/tests/test-gradient.cc b/tests/test-gradient.cc new file mode 100644 index 000000000..de52fed92 --- /dev/null +++ b/tests/test-gradient.cc @@ -0,0 +1,163 @@ +/* + * + * Conky, a system monitor, based on torsmo + * + * Any original torsmo code is licensed under the BSD license + * + * All code written since the fork of torsmo is licensed under the GPL + * + * Please see COPYING for details + * + * Copyright (c) 2005-2021 Brenden Matthews, Philip Kovacs, et. al. + * (see AUTHORS) + * All rights reserved. + * + * This program 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 . + * + */ + +#include "catch2/catch.hpp" + +#include +#include + +const int width = 4; +#ifdef BUILD_X11 // 24-bit color depth +const long colour = 0x996633; // brown +const long expected_hue = 256; +const long expected_value = 0x99; // max(0x99, 0x66, 0x33) +const long expected_chroma = 0x66; // (0x99 - 0x33) +const long expected_luma = 20712665L; +const long expected_saturation = 122880L; +const long expected_red = 0x99; +const long expected_green = 0x66; +const long expected_blue = 0x33; +#else // 16-bit color depth +const long colour = 0x99A6; // brown +const long expected_hue = 275; +const long expected_value = 0x13; // max(0x13, 0x0d, 0x06) +const long expected_chroma = 0x0d; // (0x1a - 0x06) +const long expected_luma = 2610173L; +const long expected_saturation = 126113L; +const long expected_red = 0x13; +const long expected_green = 0x0d; +const long expected_blue = 0x06; +#endif + +const long full_scale = conky::gradient_factory::SCALE360; + +TEST_CASE("gradient_factory::convert_from_rgb returns correct value") { +#ifdef BUILD_X11 + state = nullptr; +#endif + SECTION("rgb_gradient_factory") { + auto factory = new conky::rgb_gradient_factory(width, colour, colour); + long result[3]; + + factory->convert_from_rgb(colour, result); + + SECTION("red") { + REQUIRE(result[0] == expected_red * full_scale); + } + SECTION("green") { + REQUIRE(result[1] == expected_green * full_scale); + } + SECTION("blue") { + REQUIRE(result[2] == expected_blue * full_scale); + } + + delete factory; + } + + SECTION("hsv_gradient_factory") { + auto factory = new conky::hsv_gradient_factory(width, colour, colour); + long result[3]; + + factory->convert_from_rgb(colour, result); + + SECTION("hue") { + REQUIRE(result[0] == expected_hue * 60); + } + SECTION("saturation") { + REQUIRE(result[1] == expected_saturation); + } + SECTION("value") { + REQUIRE(result[2] == expected_value * full_scale); + } + + delete factory; + } + + SECTION("hcl_gradient_factory") { + auto factory = new conky::hcl_gradient_factory(width, colour, colour); + long result[3]; + + factory->convert_from_rgb(colour, result); + + SECTION("hue") { + REQUIRE(result[0] == expected_hue * 60); + } + SECTION("chroma") { + REQUIRE(result[1] == expected_chroma * full_scale); + } + SECTION("luma") { + REQUIRE(result[2] == expected_luma); + } + + delete factory; + } +} + +TEST_CASE( + "gradient_factory should convert to and from rgb " + "and get the initial value") { + + SECTION("rgb_gradient_factory") { + long tmp[3]; + auto factory = new conky::rgb_gradient_factory(width, colour, colour); + factory->convert_from_rgb(colour, tmp); + auto result = factory->convert_to_rgb(tmp); + + REQUIRE(result == colour); + + delete factory; + } + +/* + * Due to lack of precision, the HSV and HCL functions are not reversible + * if color depth is less than 24-bit + */ +#ifdef BUILD_X11 + SECTION("hsv_gradient_factory") { + long tmp[3]; + auto factory = new conky::hsv_gradient_factory(width, colour, colour); + factory->convert_from_rgb(colour, tmp); + auto result = factory->convert_to_rgb(tmp); + + REQUIRE(result == colour); + + delete factory; + } + + SECTION("hcl_gradient_factory") { + long tmp[3]; + auto factory = new conky::hcl_gradient_factory(width, colour, colour); + factory->convert_from_rgb(colour, tmp); + auto result = factory->convert_to_rgb(tmp); + + REQUIRE(result == colour); + + delete factory; + } +#endif +} diff --git a/tests/test-hsv.cc b/tests/test-hsv.cc deleted file mode 100644 index b46052a97..000000000 --- a/tests/test-hsv.cc +++ /dev/null @@ -1,72 +0,0 @@ -/* - * - * Conky, a system monitor, based on torsmo - * - * Any original torsmo code is licensed under the BSD license - * - * All code written since the fork of torsmo is licensed under the GPL - * - * Please see COPYING for details - * - * Copyright (c) 2005-2021 Brenden Matthews, Philip Kovacs, et. al. - * (see AUTHORS) - * All rights reserved. - * - * This program 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 . - * - */ - -#include "catch2/catch.hpp" - -#include -#include -#include - -int testColor(long *rgb, int scale) { - long hsv[3]; - long rgb1[3]; - long rgb2[3]; - long rgb3[3]; - - rgb1[0] = to_decimal_scale(rgb[0], scale); - rgb1[1] = to_decimal_scale(rgb[1], scale); - rgb1[2] = to_decimal_scale(rgb[2], scale); - - scaled_rgb_to_scaled_hsv(rgb1, hsv); - scaled_hsv_to_scaled_rgb(hsv, rgb2); - - rgb3[0] = from_decimal_scale(rgb2[0], scale); - rgb3[1] = from_decimal_scale(rgb2[1], scale); - rgb3[2] = from_decimal_scale(rgb2[2], scale); - - return (rgb[0] != rgb3[0] || rgb[1] != rgb3[1] || rgb[2] != rgb3[2]); -} - -TEST_CASE("hsv gradient tests") { - SECTION("rgb -> hsv -> rgb should returns original value") { - int failedCount = 0; - long rgb1[3]; - - for (int i = 0; i < 256 && failedCount < 10; i++) { - for (int j = 0; j < 256 && failedCount < 10; j++) { - for (int k = 0; k < 256 && failedCount < 10; k++) { - rgb1[0] = i; - rgb1[1] = j; - rgb1[2] = k; - failedCount += testColor(rgb1, 255); - } - } - } - REQUIRE(failedCount == 0); - } -}