From 8980eeb363491ef634c8bd322abb535086f7a5a4 Mon Sep 17 00:00:00 2001 From: bi4k8 Date: Thu, 23 Feb 2023 00:31:30 +0000 Subject: [PATCH 1/5] gradient, colours: use 24-bit colour depth internally on Wayland our Colour type assumes this anyway; lower colour depth should be handled by display backends --- src/colours.cc | 12 +++++++++++- src/gradient.cc | 12 +++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/colours.cc b/src/colours.cc index aa62f499f6..0c43e2d9ad 100644 --- a/src/colours.cc +++ b/src/colours.cc @@ -32,6 +32,9 @@ #ifdef BUILD_X11 #include "x11.h" #endif /*BUILD_X11*/ +#ifdef BUILD_WAYLAND +#include "wl.h" +#endif /*BUILD_WAYLAND*/ #include "x11-color.h" /* precalculated: 31/255, and 63/255 */ @@ -42,9 +45,16 @@ short colour_depth = 0; long redmask, greenmask, bluemask; void set_up_gradient() { +#ifdef BUILD_WAYLAND + if (state == nullptr || out_to_wayland.get(*state)) { + colour_depth = 24; + } else +#endif /* BUILD_WAYLAND */ #ifdef BUILD_X11 if (out_to_x.get(*state)) { - colour_depth = DisplayPlanes(display, screen); + if(display != nullptr) { + colour_depth = DisplayPlanes(display, screen); + } } else #endif /* BUILD_X11 */ { diff --git a/src/gradient.cc b/src/gradient.cc index ef8611e342..c98ead87e8 100644 --- a/src/gradient.cc +++ b/src/gradient.cc @@ -34,6 +34,9 @@ #include "gui.h" #include "x11.h" #endif /* BUILD_X11 */ +#ifdef BUILD_WAYLAND +#include "wl.h" +#endif /*BUILD_WAYLAND*/ namespace conky { bool gradient_factory::is_set = false; @@ -77,11 +80,18 @@ void gradient_factory::setup_masks() { } void gradient_factory::setup_colour_depth() { +#ifdef BUILD_WAYLAND + if (state == nullptr || out_to_wayland.get(*state)) { + colour_depth = 24; + } else +#endif /* BUILD_WAYLAND */ #ifdef BUILD_X11 if (state == nullptr) { // testing purposes colour_depth = 24; } else if (out_to_x.get(*state)) { - colour_depth = DisplayPlanes(display, screen); + if(display != nullptr) { + colour_depth = DisplayPlanes(display, screen); + } } else #endif /* BUILD_X11 */ { From 819efaa101f0ccb1414feb392d916bf696bffe5b Mon Sep 17 00:00:00 2001 From: bi4k8 Date: Thu, 23 Feb 2023 00:32:41 +0000 Subject: [PATCH 2/5] core: restore gradient color computation this was mistakenly disabled when moving to a unified Colour representation --- src/conky.cc | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/conky.cc b/src/conky.cc index dfaaef390a..75733ffc06 100644 --- a/src/conky.cc +++ b/src/conky.cc @@ -1019,6 +1019,11 @@ static inline void set_foreground_color(Colour c) { for (auto output : display_outputs()) output->set_foreground_color(c); } +static inline void set_foreground_color_rgb(unsigned long rgb) { + Colour c = Colour::from_argb32(rgb); + set_foreground_color(c); +} + static void draw_string(const char *s) { int i; int i2; @@ -1283,7 +1288,7 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) { case GRAPH: if (display_output() && display_output()->graphical()) { int h, by, i = 0, j = 0; - //int colour_idx = 0; + int colour_idx = 0; Colour last_colour = current_color; if (cur_x - text_start_x > mw && mw > 0) { break; } h = current->height; @@ -1318,18 +1323,18 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) { tmpcolour = factory->create_gradient(); delete factory; } - //colour_idx = 0; + colour_idx = 0; for (i = w - 2; i > -1; i--) { if (current->last_colour != 0 || current->first_colour != 0) { - /*if (current->tempgrad != 0) { - set_foreground_color(tmpcolour[static_cast( + if (current->tempgrad != 0) { + set_foreground_color_rgb(tmpcolour[static_cast( static_cast(w - 2) - current->graph[j] * (w - 2) / std::max(static_cast(current->scale), 1.0F))]); } else { - set_foreground_color(tmpcolour[colour_idx++]); - }*/ + set_foreground_color_rgb(tmpcolour[colour_idx++]); + } } /* this is mugfugly, but it works */ if (display_output()) { From b985ac69eca7304361d13842e599932d1bdde603 Mon Sep 17 00:00:00 2001 From: bi4k8 Date: Thu, 23 Feb 2023 00:50:48 +0000 Subject: [PATCH 3/5] core, gradient: use Colour type --- src/colours.h | 6 ++++++ src/conky.cc | 21 ++++++++------------- src/gradient.cc | 28 +++++++++++++--------------- src/gradient.h | 14 +++++++------- tests/test-gradient.cc | 15 ++------------- 5 files changed, 36 insertions(+), 48 deletions(-) diff --git a/src/colours.h b/src/colours.h index 11df01ad30..b95b446b56 100644 --- a/src/colours.h +++ b/src/colours.h @@ -46,6 +46,12 @@ struct Colour { uint8_t alpha; public: + // Compare two instances. + bool operator==(const Colour &c) const { + return c.red == red && c.green == green && c.blue == blue && + c.alpha == alpha; + } + // Express the color as a 32-bit ARGB integer (alpha in MSB). uint32_t to_argb32(void) { uint32_t out; diff --git a/src/conky.cc b/src/conky.cc index 75733ffc06..9d780f7f95 100644 --- a/src/conky.cc +++ b/src/conky.cc @@ -407,9 +407,8 @@ int dpi_scale(int value) { } #ifdef BUILD_GUI -conky::gradient_factory *create_gradient_factory(int width, - unsigned long first_colour, - unsigned long last_colour) { +conky::gradient_factory *create_gradient_factory(int width, Colour first_colour, + Colour last_colour) { switch (graph_gradient_mode.get(*state)) { case RGB_GRADIENT: return new conky::rgb_gradient_factory(width, first_colour, last_colour); @@ -1019,11 +1018,6 @@ static inline void set_foreground_color(Colour c) { for (auto output : display_outputs()) output->set_foreground_color(c); } -static inline void set_foreground_color_rgb(unsigned long rgb) { - Colour c = Colour::from_argb32(rgb); - set_foreground_color(c); -} - static void draw_string(const char *s) { int i; int i2; @@ -1315,11 +1309,12 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) { /* in case we don't have a graph yet */ if (current->graph != nullptr) { - std::unique_ptr tmpcolour; + std::unique_ptr tmpcolour; if (current->last_colour != 0 || current->first_colour != 0) { - auto factory = create_gradient_factory(w, current->last_colour, - current->first_colour); + auto factory = create_gradient_factory( + w, Colour::from_argb32(current->last_colour), + Colour::from_argb32(current->first_colour)); tmpcolour = factory->create_gradient(); delete factory; } @@ -1327,13 +1322,13 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) { for (i = w - 2; i > -1; i--) { if (current->last_colour != 0 || current->first_colour != 0) { if (current->tempgrad != 0) { - set_foreground_color_rgb(tmpcolour[static_cast( + set_foreground_color(tmpcolour[static_cast( static_cast(w - 2) - current->graph[j] * (w - 2) / std::max(static_cast(current->scale), 1.0F))]); } else { - set_foreground_color_rgb(tmpcolour[colour_idx++]); + set_foreground_color(tmpcolour[colour_idx++]); } } /* this is mugfugly, but it works */ diff --git a/src/gradient.cc b/src/gradient.cc index c98ead87e8..5aa9c10bc9 100644 --- a/src/gradient.cc +++ b/src/gradient.cc @@ -44,8 +44,8 @@ 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) { +gradient_factory::gradient_factory(int width, Colour first_colour, + Colour last_colour) { // Make sure the width is always at least 2 this->width = std::max(2, width); this->first_colour = first_colour; @@ -105,31 +105,29 @@ void gradient_factory::setup_colour_depth() { } } -void gradient_factory::convert_from_rgb(long original, long *array) { +void gradient_factory::convert_from_rgb(Colour original, long *array) { long scaled[3]; - for (int i = 0; i < 3; i++) { - auto value = (original & mask[i]) >> shift[i]; - scaled[i] = value * SCALE; - } + scaled[0] = original.red * SCALE; + scaled[1] = original.green * SCALE; + scaled[2] = original.blue * SCALE; convert_from_scaled_rgb(scaled, array); } -int gradient_factory::convert_to_rgb(long *const array) { +Colour gradient_factory::convert_to_rgb(long *const array) { long scaled_rgb[3]; - int rgb = 0; + Colour c; convert_to_scaled_rgb(array, scaled_rgb); - for (int i = 0; i < 3; i++) { - auto value = scaled_rgb[i] / SCALE; - rgb |= value << shift[i]; - } + c.red = scaled_rgb[0] / SCALE; + c.green = scaled_rgb[1] / SCALE; + c.blue = scaled_rgb[2] / SCALE; - return rgb; + return c; } gradient_factory::colour_array gradient_factory::create_gradient() { - colour_array colours(new unsigned long[width]); + colour_array colours(new Colour[width]); long first_converted[3]; long last_converted[3]; diff --git a/src/gradient.h b/src/gradient.h index ebec330d30..051542c11f 100644 --- a/src/gradient.h +++ b/src/gradient.h @@ -31,11 +31,12 @@ #define _GRADIENT_H #include +#include "colours.h" namespace conky { class gradient_factory { public: - typedef std::unique_ptr colour_array; + typedef std::unique_ptr colour_array; static const long SCALE = 512L; static const long SCALE2 = SCALE * 2; static const long SCALE4 = SCALE * 4; @@ -48,8 +49,7 @@ class gradient_factory { static const long SCALE360 = SCALE * 360; public: - gradient_factory(int width, unsigned long first_colour, - unsigned long last_colour); + gradient_factory(int width, Colour first_colour, Colour last_colour); virtual ~gradient_factory() {} colour_array create_gradient(); @@ -57,8 +57,8 @@ class gradient_factory { 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); + void convert_from_rgb(Colour original, long *array); + Colour convert_to_rgb(long *const array); protected: virtual void fix_diff(long *) {} @@ -72,8 +72,8 @@ class gradient_factory { private: int width; - unsigned long first_colour; - unsigned long last_colour; + Colour first_colour; + Colour last_colour; static bool is_set; static void setup_colour_depth(); diff --git a/tests/test-gradient.cc b/tests/test-gradient.cc index 269e0ef622..72f104fe97 100644 --- a/tests/test-gradient.cc +++ b/tests/test-gradient.cc @@ -28,12 +28,12 @@ #include "catch2/catch.hpp" +#include #include #include const int width = 4; -#ifdef BUILD_X11 // 24-bit color depth -const long colour = 0x996633; // brown +const Colour colour = Colour::from_argb32(0x996633); // brown const long expected_hue = 256; const long expected_value = 0x99; // max(0x99, 0x66, 0x33) const long expected_chroma = 0x66; // (0x99 - 0x33) @@ -42,17 +42,6 @@ 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; From 8aff3a01534df7302eb07460f1f38b463cc4e2de Mon Sep 17 00:00:00 2001 From: bi4k8 Date: Thu, 23 Feb 2023 00:51:45 +0000 Subject: [PATCH 4/5] tests: gradient: always test hsv/hcl colour computations no longer depend on the display backends we compile with, so these can be tested unconditionally now --- tests/test-gradient.cc | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/test-gradient.cc b/tests/test-gradient.cc index 72f104fe97..7b9950f97e 100644 --- a/tests/test-gradient.cc +++ b/tests/test-gradient.cc @@ -103,11 +103,6 @@ TEST_CASE( 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); @@ -129,5 +124,4 @@ TEST_CASE( delete factory; } -#endif } From fbfd90e8bccc603426529626a666c9b5498e45fe Mon Sep 17 00:00:00 2001 From: bi4k8 Date: Thu, 23 Feb 2023 01:26:32 +0000 Subject: [PATCH 5/5] gradients, specials: use Color type this makes specials now accept color names as well as hex codes, and removes all notions of color depth from gradient calculations --- src/colours.cc | 64 ---------------------------------------------- src/colours.h | 2 -- src/conky.cc | 9 +++---- src/gradient.cc | 67 +------------------------------------------------ src/gradient.h | 9 ------- src/specials.cc | 62 +++++++++++++++++++++++++++++---------------- src/specials.h | 7 ++++-- 7 files changed, 51 insertions(+), 169 deletions(-) diff --git a/src/colours.cc b/src/colours.cc index 0c43e2d9ad..ab32a97eae 100644 --- a/src/colours.cc +++ b/src/colours.cc @@ -29,72 +29,8 @@ #include "conky.h" #include "gui.h" #include "logging.h" -#ifdef BUILD_X11 -#include "x11.h" -#endif /*BUILD_X11*/ -#ifdef BUILD_WAYLAND -#include "wl.h" -#endif /*BUILD_WAYLAND*/ #include "x11-color.h" -/* precalculated: 31/255, and 63/255 */ -#define CONST_8_TO_5_BITS 0.12156862745098 -#define CONST_8_TO_6_BITS 0.247058823529412 - -short colour_depth = 0; -long redmask, greenmask, bluemask; - -void set_up_gradient() { -#ifdef BUILD_WAYLAND - if (state == nullptr || out_to_wayland.get(*state)) { - colour_depth = 24; - } else -#endif /* BUILD_WAYLAND */ -#ifdef BUILD_X11 - if (out_to_x.get(*state)) { - if(display != nullptr) { - 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"); - } - - redmask = 0; - greenmask = 0; - bluemask = 0; - for (int i = (colour_depth / 3) - 1; i >= 0; i--) { - redmask |= 1 << i; - greenmask |= 1 << i; - bluemask |= 1 << i; - } - if (colour_depth % 3 == 1) { greenmask |= 1 << (colour_depth / 3); } - redmask = redmask << (2 * colour_depth / 3 + colour_depth % 3); - greenmask = greenmask << (colour_depth / 3); -} - -/* adjust colour values depending on colour depth */ -unsigned int adjust_colours(unsigned int colour) { - double r, g, b; - - if (colour_depth == 0) { set_up_gradient(); } - if (colour_depth == 16) { - r = (colour & 0xff0000) >> 16; - g = (colour & 0xff00) >> 8; - b = colour & 0xff; - colour = static_cast(r * CONST_8_TO_5_BITS) << 11; - colour |= static_cast(g * CONST_8_TO_6_BITS) << 5; - colour |= static_cast(b * CONST_8_TO_5_BITS); - } - return colour; -} - static int hex_nibble_value(char c) { if (c >= '0' && c <= '9') { return c - '0'; diff --git a/src/colours.h b/src/colours.h index b95b446b56..335f8f9f27 100644 --- a/src/colours.h +++ b/src/colours.h @@ -37,8 +37,6 @@ #include "x11.h" #endif /* BUILD_X11 */ -unsigned int adjust_colours(unsigned int); - struct Colour { uint8_t red; uint8_t green; diff --git a/src/conky.cc b/src/conky.cc index 9d780f7f95..1cd5b14b73 100644 --- a/src/conky.cc +++ b/src/conky.cc @@ -1311,16 +1311,15 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) { if (current->graph != nullptr) { std::unique_ptr tmpcolour; - if (current->last_colour != 0 || current->first_colour != 0) { - auto factory = create_gradient_factory( - w, Colour::from_argb32(current->last_colour), - Colour::from_argb32(current->first_colour)); + if (current->colours_set) { + 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--) { - if (current->last_colour != 0 || current->first_colour != 0) { + if (current->colours_set) { if (current->tempgrad != 0) { set_foreground_color(tmpcolour[static_cast( static_cast(w - 2) - diff --git a/src/gradient.cc b/src/gradient.cc index 5aa9c10bc9..2778b6ac61 100644 --- a/src/gradient.cc +++ b/src/gradient.cc @@ -27,82 +27,17 @@ * */ #include "gradient.h" +#include "colours.h" #include "conky.h" #include "logging.h" -#ifdef BUILD_X11 -#include "gui.h" -#include "x11.h" -#endif /* BUILD_X11 */ -#ifdef BUILD_WAYLAND -#include "wl.h" -#endif /*BUILD_WAYLAND*/ - 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, Colour first_colour, Colour 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_WAYLAND - if (state == nullptr || out_to_wayland.get(*state)) { - colour_depth = 24; - } else -#endif /* BUILD_WAYLAND */ -#ifdef BUILD_X11 - if (state == nullptr) { // testing purposes - colour_depth = 24; - } else if (out_to_x.get(*state)) { - if(display != nullptr) { - 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(Colour original, long *array) { diff --git a/src/gradient.h b/src/gradient.h index 051542c11f..8a76d55f1a 100644 --- a/src/gradient.h +++ b/src/gradient.h @@ -66,19 +66,10 @@ class gradient_factory { 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; Colour first_colour; Colour 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 { diff --git a/src/specials.cc b/src/specials.cc index d2ee561fd0..9e61b768eb 100644 --- a/src/specials.cc +++ b/src/specials.cc @@ -102,7 +102,8 @@ struct graph { int id; char flags; int width, height; - unsigned int first_colour, last_colour; + bool colours_set; + Colour first_colour, last_colour; double scale; char tempgrad; }; @@ -191,6 +192,13 @@ void scan_font(struct text_object *obj, const char *args) { } } +void apply_graph_colours(struct graph *g, const char *first_colour_name, + const char *last_colour_name) { + g->first_colour = parse_color(first_colour_name); + g->last_colour = parse_color(last_colour_name); + g->colours_set = true; +} + /** * parses for [height,width] [color1 color2] [scale] [-t] [-l] * @@ -207,6 +215,8 @@ char *scan_graph(struct text_object *obj, const char *args, double defscale) { char quoted_cmd[1024] = {'\0'}; /* double-quoted execgraph command */ char argstr[1024] = {'\0'}; /* args minus quoted_cmd */ char buf[1024] = {'\0'}; /* first unquoted string argument in argstr */ + char first_colour_name[1024] = {'\0'}; + char last_colour_name[1024] = {'\0'}; auto *g = static_cast(malloc(sizeof(struct graph))); memset(g, 0, sizeof(struct graph)); @@ -216,8 +226,9 @@ char *scan_graph(struct text_object *obj, const char *args, double defscale) { g->id = ++graph_count; g->width = default_graph_width.get(*state); g->height = default_graph_height.get(*state); - g->first_colour = 0; - g->last_colour = 0; + g->colours_set = false; + g->first_colour = Colour(); + g->last_colour = Colour(); g->scale = defscale; g->tempgrad = FALSE; if (args != nullptr) { @@ -264,59 +275,67 @@ char *scan_graph(struct text_object *obj, const char *args, double defscale) { /* interpret the beginning(!) of the argument string as: * '[height],[width] [color1] [color2] [scale]' * This means parameters like -t and -l may not be in the beginning */ - if (sscanf(argstr, "%d,%d %x %x %lf", &g->height, &g->width, - &g->first_colour, &g->last_colour, &g->scale) == 5) { + if (sscanf(argstr, "%d,%d %s %s %lf", &g->height, &g->width, + first_colour_name, last_colour_name, &g->scale) == 5) { + apply_graph_colours(g, first_colour_name, last_colour_name); return *quoted_cmd != 0 ? strndup(quoted_cmd, text_buffer_size.get(*state)) : nullptr; } /* [height],[width] [color1] [color2] */ g->scale = defscale; - if (sscanf(argstr, "%d,%d %x %x", &g->height, &g->width, &g->first_colour, - &g->last_colour) == 4) { + if (sscanf(argstr, "%d,%d %s %s", &g->height, &g->width, first_colour_name, + last_colour_name) == 4) { + apply_graph_colours(g, first_colour_name, last_colour_name); return *quoted_cmd != 0 ? strndup(quoted_cmd, text_buffer_size.get(*state)) : nullptr; } /* [command] [height],[width] [color1] [color2] [scale] */ - if (sscanf(argstr, "%1023s %d,%d %x %x %lf", buf, &g->height, &g->width, - &g->first_colour, &g->last_colour, &g->scale) == 6) { + if (sscanf(argstr, "%1023s %d,%d %s %s %lf", buf, &g->height, &g->width, + first_colour_name, last_colour_name, &g->scale) == 6) { + apply_graph_colours(g, first_colour_name, last_colour_name); return strndup(buf, text_buffer_size.get(*state)); } g->scale = defscale; - if (sscanf(argstr, "%1023s %d,%d %x %x", buf, &g->height, &g->width, - &g->first_colour, &g->last_colour) == 5) { + if (sscanf(argstr, "%1023s %d,%d %s %s", buf, &g->height, &g->width, + first_colour_name, last_colour_name) == 5) { + apply_graph_colours(g, first_colour_name, last_colour_name); return strndup(buf, text_buffer_size.get(*state)); } buf[0] = '\0'; g->height = default_graph_height.get(*state); g->width = default_graph_width.get(*state); - if (sscanf(argstr, "%x %x %lf", &g->first_colour, &g->last_colour, + if (sscanf(argstr, "%s %s %lf", first_colour_name, last_colour_name, &g->scale) == 3) { + apply_graph_colours(g, first_colour_name, last_colour_name); return *quoted_cmd != 0 ? strndup(quoted_cmd, text_buffer_size.get(*state)) : nullptr; } g->scale = defscale; - if (sscanf(argstr, "%x %x", &g->first_colour, &g->last_colour) == 2) { + if (sscanf(argstr, "%s %s", first_colour_name, last_colour_name) == 2) { + apply_graph_colours(g, first_colour_name, last_colour_name); return *quoted_cmd != 0 ? strndup(quoted_cmd, text_buffer_size.get(*state)) : nullptr; } - if (sscanf(argstr, "%1023s %x %x %lf", buf, &g->first_colour, - &g->last_colour, &g->scale) == 4) { + if (sscanf(argstr, "%1023s %s %s %lf", buf, first_colour_name, + last_colour_name, &g->scale) == 4) { + apply_graph_colours(g, first_colour_name, last_colour_name); return strndup(buf, text_buffer_size.get(*state)); } g->scale = defscale; - if (sscanf(argstr, "%1023s %x %x", buf, &g->first_colour, - &g->last_colour) == 3) { + if (sscanf(argstr, "%1023s %s %s", buf, first_colour_name, + last_colour_name) == 3) { + apply_graph_colours(g, first_colour_name, last_colour_name); return strndup(buf, text_buffer_size.get(*state)); } buf[0] = '\0'; - g->first_colour = 0; - g->last_colour = 0; + first_colour_name[0] = '\0'; + last_colour_name[0] = '\0'; if (sscanf(argstr, "%d,%d %lf", &g->height, &g->width, &g->scale) == 3) { return *quoted_cmd != 0 ? strndup(quoted_cmd, text_buffer_size.get(*state)) @@ -584,8 +603,9 @@ void new_graph(struct text_object *obj, char *buf, int buf_max_size, graphs[g->id] = graph; } s->height = dpi_scale(g->height); - s->first_colour = adjust_colours(g->first_colour); - s->last_colour = adjust_colours(g->last_colour); + s->colours_set = g->colours_set; + s->first_colour = g->first_colour; + s->last_colour = g->last_colour; if (g->scale != 0) { s->scaled = 0; s->scale = g->scale; diff --git a/src/specials.h b/src/specials.h index f0c96658fd..1ce9292ae3 100644 --- a/src/specials.h +++ b/src/specials.h @@ -29,6 +29,8 @@ #ifndef _SPECIALS_H #define _SPECIALS_H +#include "colours.h" + /* special stuff in text_buffer */ #define SPECIAL_CHAR '\x01' @@ -69,8 +71,9 @@ struct special_t { int graph_allocated; int scaled; /* auto adjust maximum */ int scale_log; - unsigned long first_colour; // for graph gradient - unsigned long last_colour; + bool colours_set; + Colour first_colour; // for graph gradient + Colour last_colour; short font_added; char tempgrad; struct special_t *next;