Support arbitrary hex color formats (16/32bits per component)
It's unlikely that string_to_color() is faster, but at least is more flexible. Not sure if 8-digit per channel format is used.
This commit is contained in:
parent
7226ef2c15
commit
1e36a6b4ac
41
src/draw.c
41
src/draw.c
@ -10,6 +10,7 @@
|
|||||||
#include <pango/pango-types.h>
|
#include <pango/pango-types.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include "dunst.h"
|
#include "dunst.h"
|
||||||
#include "icon.h"
|
#include "icon.h"
|
||||||
@ -44,7 +45,7 @@ void draw_setup(void)
|
|||||||
pango_fdesc = pango_font_description_from_string(settings.font);
|
pango_fdesc = pango_font_description_from_string(settings.font);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct color hex_to_color(uint32_t hexValue, int dpc)
|
static struct color hex_to_color(uintmax_t hexValue, int dpc)
|
||||||
{
|
{
|
||||||
const int bpc = 4 * dpc;
|
const int bpc = 4 * dpc;
|
||||||
const unsigned single_max = UINT_MAX_N(bpc);
|
const unsigned single_max = UINT_MAX_N(bpc);
|
||||||
@ -60,20 +61,38 @@ static struct color hex_to_color(uint32_t hexValue, int dpc)
|
|||||||
|
|
||||||
static struct color string_to_color(const char *str)
|
static struct color string_to_color(const char *str)
|
||||||
{
|
{
|
||||||
char *end;
|
uintmax_t val;
|
||||||
uint32_t val = strtoul(str+1, &end, 16);
|
unsigned clen;
|
||||||
if (*end != '\0' && *(end+1) != '\0') {
|
{
|
||||||
LOG_W("Invalid color string: '%s'", str);
|
int cn;
|
||||||
}
|
|
||||||
|
|
||||||
switch (strlen(str+1)) {
|
/* accept 3 or 4 equal components */ {
|
||||||
case 3: return hex_to_color((val << 4) | 0xF, 1);
|
char *end;
|
||||||
case 6: return hex_to_color((val << 8) | 0xFF, 2);
|
val = strtoumax(str+1, &end, 16);
|
||||||
case 4: return hex_to_color(val, 1);
|
if (errno == ERANGE || (end[0] != '\0' && end[1] != '\0'))
|
||||||
case 8: return hex_to_color(val, 2);
|
goto err;
|
||||||
|
|
||||||
|
const int len = (end - (str+1));
|
||||||
|
if (len % 3 == 0) cn = 3;
|
||||||
|
else if (len % 4 == 0) cn = 4;
|
||||||
|
else goto err;
|
||||||
|
clen = len / cn;
|
||||||
|
}
|
||||||
|
/* component length must be 2^n */ {
|
||||||
|
unsigned mask = 1;
|
||||||
|
while(mask < clen) mask <<= 1;
|
||||||
|
if (mask != clen) goto err;
|
||||||
|
}
|
||||||
|
/* turn 3-component to opaque 4-components */ {
|
||||||
|
const unsigned csize = clen * 4;
|
||||||
|
if (cn == 3)
|
||||||
|
val = (val << csize) | UINT_MAX_N(csize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return hex_to_color(val, clen);
|
||||||
|
|
||||||
/* return black on error */
|
/* return black on error */
|
||||||
|
err:
|
||||||
LOG_W("Invalid color string: '%s'", str);
|
LOG_W("Invalid color string: '%s'", str);
|
||||||
return hex_to_color(0xF, 1);
|
return hex_to_color(0xF, 1);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user