Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use new Colour type for specials and gradients #1418

Merged
merged 5 commits into from
Feb 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 0 additions & 54 deletions src/colours.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,62 +29,8 @@
#include "conky.h"
#include "gui.h"
#include "logging.h"
#ifdef BUILD_X11
#include "x11.h"
#endif /*BUILD_X11*/
#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_X11
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");
}

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
8 changes: 6 additions & 2 deletions src/colours.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,19 @@
#include "x11.h"
#endif /* BUILD_X11 */

unsigned int adjust_colours(unsigned int);

struct Colour {
uint8_t red;
uint8_t green;
uint8_t blue;
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;
Expand Down
19 changes: 9 additions & 10 deletions src/conky.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -1283,7 +1282,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;
Expand All @@ -1310,26 +1309,26 @@ 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<unsigned long[]> tmpcolour;
std::unique_ptr<Colour[]> tmpcolour;

if (current->last_colour != 0 || current->first_colour != 0) {
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;
colour_idx = 0;
for (i = w - 2; i > -1; i--) {
if (current->last_colour != 0 || current->first_colour != 0) {
/*if (current->tempgrad != 0) {
if (current->colours_set) {
if (current->tempgrad != 0) {
set_foreground_color(tmpcolour[static_cast<int>(
static_cast<float>(w - 2) -
current->graph[j] * (w - 2) /
std::max(static_cast<float>(current->scale),
1.0F))]);
} else {
set_foreground_color(tmpcolour[colour_idx++]);
}*/
}
}
/* this is mugfugly, but it works */
if (display_output()) {
Expand Down
85 changes: 14 additions & 71 deletions src/gradient.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,99 +27,42 @@
*
*/
#include "gradient.h"
#include "colours.h"
#include "conky.h"
#include "logging.h"

#ifdef BUILD_X11
#include "gui.h"
#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) {
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_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) {
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];
Expand Down
23 changes: 7 additions & 16 deletions src/gradient.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@
#define _GRADIENT_H

#include <memory>
#include "colours.h"

namespace conky {
class gradient_factory {
public:
typedef std::unique_ptr<unsigned long[]> colour_array;
typedef std::unique_ptr<Colour[]> colour_array;
static const long SCALE = 512L;
static const long SCALE2 = SCALE * 2;
static const long SCALE4 = SCALE * 4;
Expand All @@ -48,37 +49,27 @@ 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();

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 *) {}

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();
Colour first_colour;
Colour last_colour;
};

class rgb_gradient_factory : public gradient_factory {
Expand Down
Loading