Skip to content

Commit

Permalink
gradients, specials: use Color type
Browse files Browse the repository at this point in the history
this makes specials now accept color names as well as hex codes, and removes all notions of color depth from gradient calculations
  • Loading branch information
bi4k8 committed Feb 23, 2023
1 parent 8aff3a0 commit fbfd90e
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 169 deletions.
64 changes: 0 additions & 64 deletions src/colours.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<int>(r * CONST_8_TO_5_BITS) << 11;
colour |= static_cast<int>(g * CONST_8_TO_6_BITS) << 5;
colour |= static_cast<int>(b * CONST_8_TO_5_BITS);
}
return colour;
}

static int hex_nibble_value(char c) {
if (c >= '0' && c <= '9') {
return c - '0';
Expand Down
2 changes: 0 additions & 2 deletions src/colours.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@
#include "x11.h"
#endif /* BUILD_X11 */

unsigned int adjust_colours(unsigned int);

struct Colour {
uint8_t red;
uint8_t green;
Expand Down
9 changes: 4 additions & 5 deletions src/conky.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<Colour[]> 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<int>(
static_cast<float>(w - 2) -
Expand Down
67 changes: 1 addition & 66 deletions src/gradient.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
9 changes: 0 additions & 9 deletions src/gradient.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
62 changes: 41 additions & 21 deletions src/specials.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down Expand Up @@ -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]
*
Expand All @@ -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<struct graph *>(malloc(sizeof(struct graph)));
memset(g, 0, sizeof(struct graph));
Expand All @@ -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) {
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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;
Expand Down
7 changes: 5 additions & 2 deletions src/specials.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
#ifndef _SPECIALS_H
#define _SPECIALS_H

#include "colours.h"

/* special stuff in text_buffer */

#define SPECIAL_CHAR '\x01'
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit fbfd90e

Please sign in to comment.