st/theme-node: Implement extensions for accent color
Add -st-accent-color and -st-fg-accent-color so that these colors can be accessed from CSS. Since they are often transformed in SCSS atm, add st-transparentize(), st-mix(), st-lighten(), st-darken() that work in runtime. Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2715>
This commit is contained in:
parent
1ce6193f4e
commit
c593aecbde
@ -502,6 +502,20 @@ term_is_transparent (CRTerm *term)
|
|||||||
strcmp (term->content.str->stryng->str, "transparent") == 0);
|
strcmp (term->content.str->stryng->str, "transparent") == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
term_is_accent_color (CRTerm *term)
|
||||||
|
{
|
||||||
|
return (term->type == TERM_IDENT &&
|
||||||
|
strcmp (term->content.str->stryng->str, "-st-accent-color") == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
term_is_accent_fg_color (CRTerm *term)
|
||||||
|
{
|
||||||
|
return (term->type == TERM_IDENT &&
|
||||||
|
strcmp (term->content.str->stryng->str, "-st-accent-fg-color") == 0);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
color_component_from_double (double component)
|
color_component_from_double (double component)
|
||||||
{
|
{
|
||||||
@ -594,6 +608,180 @@ get_color_from_rgba_term (CRTerm *term,
|
|||||||
return VALUE_FOUND;
|
return VALUE_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GetFromTermResult get_color_from_term (StThemeNode *node,
|
||||||
|
CRTerm *term,
|
||||||
|
CoglColor *color);
|
||||||
|
|
||||||
|
static GetFromTermResult
|
||||||
|
get_color_from_transparentize_term (StThemeNode *node,
|
||||||
|
CRTerm *term,
|
||||||
|
CoglColor *color)
|
||||||
|
{
|
||||||
|
CRTerm *color_arg = term->ext_content.func_param;
|
||||||
|
CRTerm *amount_arg = color_arg->next;
|
||||||
|
CoglColor base_color;
|
||||||
|
CRNum *amount_num;
|
||||||
|
double amount;
|
||||||
|
|
||||||
|
if (!color_arg || !amount_arg)
|
||||||
|
return VALUE_NOT_FOUND;
|
||||||
|
|
||||||
|
if (get_color_from_term (node, color_arg, &base_color) != VALUE_FOUND)
|
||||||
|
return VALUE_NOT_FOUND;
|
||||||
|
|
||||||
|
if (amount_arg->type != TERM_NUMBER)
|
||||||
|
return VALUE_NOT_FOUND;
|
||||||
|
|
||||||
|
amount_num = amount_arg->content.num;
|
||||||
|
|
||||||
|
if (amount_num->type == NUM_PERCENTAGE)
|
||||||
|
amount = amount_num->val / 100;
|
||||||
|
else if (amount_num->type == NUM_GENERIC)
|
||||||
|
amount = amount_num->val;
|
||||||
|
else
|
||||||
|
return VALUE_NOT_FOUND;
|
||||||
|
|
||||||
|
color->red = base_color.red;
|
||||||
|
color->green = base_color.green;
|
||||||
|
color->blue = base_color.blue;
|
||||||
|
color->alpha = CLAMP (base_color.alpha - amount * 255, 0, 255);
|
||||||
|
|
||||||
|
return VALUE_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LERP(a, b, t) (a + (b - a) * t)
|
||||||
|
|
||||||
|
static GetFromTermResult
|
||||||
|
get_color_from_mix_term (StThemeNode *node,
|
||||||
|
CRTerm *term,
|
||||||
|
CoglColor *color)
|
||||||
|
{
|
||||||
|
CRTerm *color1_arg = term->ext_content.func_param;
|
||||||
|
CRTerm *color2_arg = color1_arg->next;
|
||||||
|
CRTerm *factor_arg = color2_arg->next;
|
||||||
|
CoglColor color1, color2;
|
||||||
|
CRNum *factor_num;
|
||||||
|
double factor;
|
||||||
|
|
||||||
|
if (!color1_arg || !color2_arg || !factor_arg)
|
||||||
|
return VALUE_NOT_FOUND;
|
||||||
|
|
||||||
|
if (get_color_from_term (node, color1_arg, &color1) != VALUE_FOUND ||
|
||||||
|
get_color_from_term (node, color2_arg, &color2) != VALUE_FOUND)
|
||||||
|
return VALUE_NOT_FOUND;
|
||||||
|
|
||||||
|
if (factor_arg->type != TERM_NUMBER)
|
||||||
|
return VALUE_NOT_FOUND;
|
||||||
|
|
||||||
|
factor_num = factor_arg->content.num;
|
||||||
|
|
||||||
|
if (factor_num->type == NUM_PERCENTAGE)
|
||||||
|
factor = factor_num->val / 100;
|
||||||
|
else if (factor_num->type == NUM_GENERIC)
|
||||||
|
factor = factor_num->val;
|
||||||
|
else
|
||||||
|
return VALUE_NOT_FOUND;
|
||||||
|
|
||||||
|
/* SCSS mix() inverts the factor for some reason */
|
||||||
|
factor = 1 - factor;
|
||||||
|
|
||||||
|
color->alpha = CLAMP (LERP (color1.alpha, color2.alpha, factor), 0, 255);
|
||||||
|
|
||||||
|
if (color->alpha == 0)
|
||||||
|
{
|
||||||
|
color->red = color->green = color->blue = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
color->red = CLAMP (LERP (color1.red * color1.alpha, color2.red * color2.alpha, factor) / color->alpha, 0, 255);
|
||||||
|
color->green = CLAMP (LERP (color1.green * color1.alpha, color2.green * color2.alpha, factor) / color->alpha, 0, 255);
|
||||||
|
color->blue = CLAMP (LERP (color1.blue * color1.alpha, color2.blue * color2.alpha, factor) / color->alpha, 0, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
return VALUE_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GetFromTermResult
|
||||||
|
get_color_from_lighten_term (StThemeNode *node,
|
||||||
|
CRTerm *term,
|
||||||
|
CoglColor *color)
|
||||||
|
{
|
||||||
|
CRTerm *color_arg = term->ext_content.func_param;
|
||||||
|
CRTerm *factor_arg = color_arg->next;
|
||||||
|
CoglColor base_color;
|
||||||
|
CRNum *factor_num;
|
||||||
|
double factor;
|
||||||
|
float hue, luminance, saturation;
|
||||||
|
|
||||||
|
if (!color_arg || !factor_arg)
|
||||||
|
return VALUE_NOT_FOUND;
|
||||||
|
|
||||||
|
if (get_color_from_term (node, color_arg, &base_color) != VALUE_FOUND)
|
||||||
|
return VALUE_NOT_FOUND;
|
||||||
|
|
||||||
|
if (factor_arg->type != TERM_NUMBER)
|
||||||
|
return VALUE_NOT_FOUND;
|
||||||
|
|
||||||
|
factor_num = factor_arg->content.num;
|
||||||
|
|
||||||
|
if (factor_num->type == NUM_PERCENTAGE)
|
||||||
|
factor = factor_num->val / 100;
|
||||||
|
else if (factor_num->type == NUM_GENERIC)
|
||||||
|
factor = factor_num->val;
|
||||||
|
else
|
||||||
|
return VALUE_NOT_FOUND;
|
||||||
|
|
||||||
|
cogl_color_to_hsl (&base_color, &hue, &saturation, &luminance);
|
||||||
|
|
||||||
|
luminance = CLAMP (luminance + factor, 0, 1);
|
||||||
|
|
||||||
|
cogl_color_init_from_hsl (color, hue, saturation, luminance);
|
||||||
|
color->alpha = base_color.alpha;
|
||||||
|
|
||||||
|
return VALUE_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GetFromTermResult
|
||||||
|
get_color_from_darken_term (StThemeNode *node,
|
||||||
|
CRTerm *term,
|
||||||
|
CoglColor *color)
|
||||||
|
{
|
||||||
|
CRTerm *color_arg = term->ext_content.func_param;
|
||||||
|
CRTerm *factor_arg = color_arg->next;
|
||||||
|
CoglColor base_color;
|
||||||
|
CRNum *factor_num;
|
||||||
|
double factor;
|
||||||
|
float hue, luminance, saturation;
|
||||||
|
|
||||||
|
if (!color_arg || !factor_arg)
|
||||||
|
return VALUE_NOT_FOUND;
|
||||||
|
|
||||||
|
if (get_color_from_term (node, color_arg, &base_color) != VALUE_FOUND)
|
||||||
|
return VALUE_NOT_FOUND;
|
||||||
|
|
||||||
|
if (factor_arg->type != TERM_NUMBER)
|
||||||
|
return VALUE_NOT_FOUND;
|
||||||
|
|
||||||
|
factor_num = factor_arg->content.num;
|
||||||
|
|
||||||
|
if (factor_num->type == NUM_PERCENTAGE)
|
||||||
|
factor = factor_num->val / 100;
|
||||||
|
else if (factor_num->type == NUM_GENERIC)
|
||||||
|
factor = factor_num->val;
|
||||||
|
else
|
||||||
|
return VALUE_NOT_FOUND;
|
||||||
|
|
||||||
|
cogl_color_to_hsl (&base_color, &hue, &saturation, &luminance);
|
||||||
|
color->alpha = base_color.alpha;
|
||||||
|
|
||||||
|
luminance = CLAMP (luminance - factor, 0, 1);
|
||||||
|
|
||||||
|
cogl_color_init_from_hsl (color, hue, saturation, luminance);
|
||||||
|
color->alpha = base_color.alpha;
|
||||||
|
|
||||||
|
return VALUE_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
static GetFromTermResult
|
static GetFromTermResult
|
||||||
get_color_from_term (StThemeNode *node,
|
get_color_from_term (StThemeNode *node,
|
||||||
CRTerm *term,
|
CRTerm *term,
|
||||||
@ -614,6 +802,18 @@ get_color_from_term (StThemeNode *node,
|
|||||||
*color = TRANSPARENT_COLOR;
|
*color = TRANSPARENT_COLOR;
|
||||||
return VALUE_FOUND;
|
return VALUE_FOUND;
|
||||||
}
|
}
|
||||||
|
/* St-specific extension: -st-accent-color */
|
||||||
|
else if (term_is_accent_color (term))
|
||||||
|
{
|
||||||
|
st_theme_context_get_accent_color (node->context, color, NULL);
|
||||||
|
return VALUE_FOUND;
|
||||||
|
}
|
||||||
|
/* St-specific extension: -st-accent-fg-color */
|
||||||
|
else if (term_is_accent_fg_color (term))
|
||||||
|
{
|
||||||
|
st_theme_context_get_accent_color (node->context, NULL, color);
|
||||||
|
return VALUE_FOUND;
|
||||||
|
}
|
||||||
/* rgba () colors - a CSS3 addition, are not supported by libcroco,
|
/* rgba () colors - a CSS3 addition, are not supported by libcroco,
|
||||||
* but they are parsed as a "function", so we can emulate the
|
* but they are parsed as a "function", so we can emulate the
|
||||||
* functionality.
|
* functionality.
|
||||||
@ -626,6 +826,42 @@ get_color_from_term (StThemeNode *node,
|
|||||||
{
|
{
|
||||||
return get_color_from_rgba_term (term, color);
|
return get_color_from_rgba_term (term, color);
|
||||||
}
|
}
|
||||||
|
/* St-specific extension: st-transparentize() */
|
||||||
|
else if (term->type == TERM_FUNCTION &&
|
||||||
|
term->content.str &&
|
||||||
|
term->content.str->stryng &&
|
||||||
|
term->content.str->stryng->str &&
|
||||||
|
strcmp (term->content.str->stryng->str, "st-transparentize") == 0)
|
||||||
|
{
|
||||||
|
return get_color_from_transparentize_term (node, term, color);
|
||||||
|
}
|
||||||
|
/* St-specific extension: st-mix() */
|
||||||
|
else if (term->type == TERM_FUNCTION &&
|
||||||
|
term->content.str &&
|
||||||
|
term->content.str->stryng &&
|
||||||
|
term->content.str->stryng->str &&
|
||||||
|
strcmp (term->content.str->stryng->str, "st-mix") == 0)
|
||||||
|
{
|
||||||
|
return get_color_from_mix_term (node, term, color);
|
||||||
|
}
|
||||||
|
/* St-specific extension: st-lighten() */
|
||||||
|
else if (term->type == TERM_FUNCTION &&
|
||||||
|
term->content.str &&
|
||||||
|
term->content.str->stryng &&
|
||||||
|
term->content.str->stryng->str &&
|
||||||
|
strcmp (term->content.str->stryng->str, "st-lighten") == 0)
|
||||||
|
{
|
||||||
|
return get_color_from_lighten_term (node, term, color);
|
||||||
|
}
|
||||||
|
/* St-specific extension: st-darken() */
|
||||||
|
else if (term->type == TERM_FUNCTION &&
|
||||||
|
term->content.str &&
|
||||||
|
term->content.str->stryng &&
|
||||||
|
term->content.str->stryng->str &&
|
||||||
|
strcmp (term->content.str->stryng->str, "st-darken") == 0)
|
||||||
|
{
|
||||||
|
return get_color_from_darken_term (node, term, color);
|
||||||
|
}
|
||||||
|
|
||||||
status = cr_rgb_set_from_term (&rgb, term);
|
status = cr_rgb_set_from_term (&rgb, term);
|
||||||
if (status != CR_OK)
|
if (status != CR_OK)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user