[ThemeParser] Extend color formats.

- Support whitespace format.
 - Support deg,rad, grad, turn angle.
 - Add alpha channel support to hwb
This commit is contained in:
Dave Davenport 2017-05-15 15:05:40 +02:00
parent f0ceeb86d8
commit e397c346da
4 changed files with 157 additions and 66 deletions

View File

@ -171,6 +171,13 @@ BOLD "bold"
UNDERLINE "underline"
ITALIC "italic"
/* ANGLES */
ANGLE_DEG "deg"
ANGLE_GRAD "grad"
ANGLE_RAD "rad"
ANGLE_TURN "turn"
/* Color schema */
RGBA "rgba"
RGB "rgb"
@ -180,7 +187,8 @@ HSL hsl[a]?
S_T_PARENT_LEFT \(
S_T_PARENT_RIGHT \)
COMMA ,
COMMA ,
FORWARD_SLASH \/
LS_DASH "dash"
LS_SOLID "solid"
@ -422,6 +430,7 @@ if ( queue == NULL ){
<PROPERTIES>{S_T_PARENT_LEFT} { return T_PARENT_LEFT; }
<PROPERTIES>{S_T_PARENT_RIGHT} { return T_PARENT_RIGHT;}
<PROPERTIES>{COMMA} { return T_COMMA; }
<PROPERTIES>{FORWARD_SLASH} { return T_FORWARD_SLASH; }
/* Position */
<PROPERTIES>{CENTER} { return T_POS_CENTER; }
<PROPERTIES>{EAST} { return T_POS_EAST; }
@ -434,6 +443,10 @@ if ( queue == NULL ){
<PROPERTIES>{ITALIC} { return T_ITALIC; }
<PROPERTIES>{UNDERLINE} { return T_UNDERLINE; }
<PROPERTIES>{ANGLE_DEG} { return T_ANGLE_DEG; }
<PROPERTIES>{ANGLE_RAD} { return T_ANGLE_RAD; }
<PROPERTIES>{ANGLE_GRAD} { return T_ANGLE_GRAD; }
<PROPERTIES>{ANGLE_TURN} { return T_ANGLE_TURN; }
<INITIAL><<EOF>> {
ParseObject *po = g_queue_pop_head ( file_queue );

View File

@ -119,6 +119,17 @@ static ThemeColor hsl_to_rgb ( double h, double s, double l )
return colour;
}
static ThemeColor hwb_to_rgb ( double h, double w, double b)
{
ThemeColor retv = hsl_to_rgb ( h, 1.0, 0.5);
retv.red *= ( 1. - w - b );
retv.red += w;
retv.green *= ( 1. - w - b );
retv.green += w;
retv.blue *= ( 1. - w - b );
retv.blue += w;
return retv;
}
%}
%union {
@ -167,6 +178,11 @@ static ThemeColor hsl_to_rgb ( double h, double s, double l )
%token T_UNIT_EM "em"
%token T_UNIT_PERCENT "%"
%token T_ANGLE_DEG "Degrees"
%token T_ANGLE_GRAD "Gradians"
%token T_ANGLE_RAD "Radians"
%token T_ANGLE_TURN "Turns"
%token T_COL_RGBA "rgba colorscheme"
%token T_COL_RGB "rgb colorscheme"
%token T_COL_HSL "hsl colorscheme"
@ -176,6 +192,8 @@ static ThemeColor hsl_to_rgb ( double h, double s, double l )
%token T_PARENT_LEFT "Parent left ('(')"
%token T_PARENT_RIGHT "Parent right (')')"
%token T_COMMA "comma separator (',')"
%token T_OPTIONAL_COMMA "Optional comma separator (',')"
%token T_FORWARD_SLASH "forward slash ('/')"
%token T_PERCENT "Percent sign ('%')"
%token T_BOPEN "bracket open ('{')"
@ -196,6 +214,10 @@ static ThemeColor hsl_to_rgb ( double h, double s, double l )
%type <property_list> t_property_list_optional
%type <colorval> t_property_color
%type <fval> t_property_color_value
%type <fval> t_property_color_opt_alpha_c
%type <fval> t_property_color_opt_alpha_ws
%type <fval> t_property_color_value_unit
%type <fval> t_property_color_value_angle
%type <sval> t_property_name
%type <distance> t_property_distance
%type <ival> t_property_unit
@ -411,26 +433,24 @@ t_property_line_style
*/
t_property_color
/** rgba ( 0-255 , 0-255, 0-255, 0-1.0 ) */
: T_COL_RGBA T_PARENT_LEFT T_INT T_COMMA T_INT T_COMMA T_INT T_COMMA T_DOUBLE T_PARENT_RIGHT {
: T_COL_RGBA T_PARENT_LEFT T_INT T_COMMA T_INT T_COMMA T_INT T_COMMA t_property_color_value_unit T_PARENT_RIGHT {
if ( ! check_in_range($3,0,255, &(@$)) ) { YYABORT; }
if ( ! check_in_range($5,0,255, &(@$)) ) { YYABORT; }
if ( ! check_in_range($7,0,255, &(@$)) ) { YYABORT; }
if ( ! check_in_range($9,0,1.00, &(@$)) ) { YYABORT; }
$$.alpha = $9;
$$.red = $3/255.0;
$$.green = $5/255.0;
$$.blue = $7/255.0;
}
/** rgba ( 0-255 , 0-255, 0-255, 0-100% ) */
| T_COL_RGBA T_PARENT_LEFT T_INT T_COMMA T_INT T_COMMA T_INT T_COMMA t_property_color_value T_PERCENT T_PARENT_RIGHT {
/** rgba ( 0-255 0-255 0-255 / 0-1.0 ) */
| T_COL_RGBA T_PARENT_LEFT T_INT T_INT T_INT T_FORWARD_SLASH t_property_color_value_unit T_PARENT_RIGHT {
if ( ! check_in_range($3,0,255, &(@$)) ) { YYABORT; }
if ( ! check_in_range($4,0,255, &(@$)) ) { YYABORT; }
if ( ! check_in_range($5,0,255, &(@$)) ) { YYABORT; }
if ( ! check_in_range($7,0,255, &(@$)) ) { YYABORT; }
if ( ! check_in_range($9,0,100, &(@$)) ) { YYABORT; }
$$.alpha = $9/100.0;
$$.alpha = $7;
$$.red = $3/255.0;
$$.green = $5/255.0;
$$.blue = $7/255.0;
$$.green = $4/255.0;
$$.blue = $5/255.0;
}
/** rgb ( 0-255 , 0-255, 0-255 ) */
| T_COL_RGB T_PARENT_LEFT T_INT T_COMMA T_INT T_COMMA T_INT T_PARENT_RIGHT {
@ -442,81 +462,81 @@ t_property_color
$$.green = $5/255.0;
$$.blue = $7/255.0;
}
/** hwb ( 0-360 , 0-100 %, 0 - 100 %) */
| T_COL_HWB T_PARENT_LEFT T_INT T_COMMA t_property_color_value T_PERCENT T_COMMA t_property_color_value T_PERCENT T_PARENT_RIGHT {
if ( ! check_in_range($3,0,360, &(@$)) ) { YYABORT; }
if ( ! check_in_range($5,0,100, &(@$)) ) { YYABORT; }
if ( ! check_in_range($8,0,100, &(@$)) ) { YYABORT; }
double h = $3/360.0;
double w = $5/100.0;
double b = $8/100.0;
$$ = hsl_to_rgb ( h, 1.0, 0.5);
/** rgb ( 0-255 0-255 0-255 ) */
| T_COL_RGB T_PARENT_LEFT T_INT T_INT T_INT T_PARENT_RIGHT {
if ( ! check_in_range($3,0,255, &(@$)) ) { YYABORT; }
if ( ! check_in_range($4,0,255, &(@$)) ) { YYABORT; }
if ( ! check_in_range($5,0,255, &(@$)) ) { YYABORT; }
$$.alpha = 1.0;
$$.red *= ( 1. - w - b );
$$.red += w;
$$.green *= ( 1. - w - b );
$$.green += w;
$$.blue *= ( 1. - w - b );
$$.blue += w;
$$.red = $3/255.0;
$$.green = $4/255.0;
$$.blue = $5/255.0;
}
/** cmyk ( 0-100%, 0-100%, 0-100%, 0-100%) */
| T_COL_CMYK T_PARENT_LEFT t_property_color_value T_PERCENT T_COMMA t_property_color_value T_PERCENT T_COMMA t_property_color_value T_PERCENT T_COMMA t_property_color_value T_PERCENT T_PARENT_RIGHT {
/** hwb with comma */
| T_COL_HWB T_PARENT_LEFT t_property_color_value_angle T_COMMA t_property_color_value_unit T_COMMA t_property_color_value_unit t_property_color_opt_alpha_c T_PARENT_RIGHT {
double h = $3, w = $5, b = $7;
$$ = hwb_to_rgb ( h, w, b );
$$.alpha = $8;
}
/** hwb whitespace */
| T_COL_HWB T_PARENT_LEFT t_property_color_value_angle t_property_color_value_unit t_property_color_value_unit t_property_color_opt_alpha_ws T_PARENT_RIGHT {
double h = $3, w = $4, b = $5;
$$ = hwb_to_rgb ( h, w, b );
$$.alpha = $6;
}
/** cmyk with comma */
| T_COL_CMYK T_PARENT_LEFT t_property_color_value_unit T_COMMA t_property_color_value_unit T_COMMA t_property_color_value_unit T_COMMA t_property_color_value_unit T_PARENT_RIGHT {
$$.alpha = 1.0;
if ( ! check_in_range($3, 0,100, &(@$)) ) { YYABORT; }
if ( ! check_in_range($6, 0,100, &(@$)) ) { YYABORT; }
if ( ! check_in_range($9, 0,100, &(@$)) ) { YYABORT; }
if ( ! check_in_range($12,0,100, &(@$)) ) { YYABORT; }
double c= $3/100.0;
double m= $6/100.0;
double y= $9/100.0;
double k= $12/100.0;
double c= $3, m= $5, y= $7, k= $9;
$$.red = (1.0-c)*(1.0-k);
$$.green = (1.0-m)*(1.0-k);
$$.blue = (1.0-y)*(1.0-k);
}
/** cmyk ( 0-1.0, 0-1.0, 0-1.0, 0-1.0) */
| T_COL_CMYK T_PARENT_LEFT t_property_color_value T_COMMA t_property_color_value T_COMMA t_property_color_value T_COMMA t_property_color_value T_PARENT_RIGHT {
/** cmyk whitespace edition. */
| T_COL_CMYK T_PARENT_LEFT t_property_color_value_unit t_property_color_value_unit t_property_color_value_unit t_property_color_value_unit T_PARENT_RIGHT {
$$.alpha = 1.0;
if ( ! check_in_range($3, 0,1.00, &(@$)) ) { YYABORT; }
if ( ! check_in_range($5, 0,1.00, &(@$)) ) { YYABORT; }
if ( ! check_in_range($7, 0,1.00, &(@$)) ) { YYABORT; }
if ( ! check_in_range($9, 0,1.00, &(@$)) ) { YYABORT; }
double c= $3;
double m= $5;
double y= $7;
double k= $9;
double c= $3, m= $4, y= $5, k= $6;
$$.red = (1.0-c)*(1.0-k);
$$.green = (1.0-m)*(1.0-k);
$$.blue = (1.0-y)*(1.0-k);
}
/** hsl ( 0-360 , 0-100 %, 0 - 100 %) */
| T_COL_HSL T_PARENT_LEFT T_INT T_COMMA t_property_color_value T_PERCENT T_COMMA t_property_color_value T_PERCENT T_PARENT_RIGHT {
if ( ! check_in_range($3, 0,360, &(@$)) ) { YYABORT; }
if ( ! check_in_range($5, 0,100, &(@$)) ) { YYABORT; }
if ( ! check_in_range($8, 0,100, &(@$)) ) { YYABORT; }
gdouble h = $3;
gdouble s = $5;
gdouble l = $8;
$$ = hsl_to_rgb ( h/360.0, s/100.0, l/100.0 );
$$.alpha = 1.0;
/** hsl ( 0-360 0-100 % 0 - 100 % / alpha) */
| T_COL_HSL T_PARENT_LEFT t_property_color_value_angle t_property_color_value_unit t_property_color_value_unit t_property_color_opt_alpha_ws T_PARENT_RIGHT {
double h = $3, s = $4, l = $5;
$$ = hsl_to_rgb ( h, s, l );
$$.alpha = $6;
}
/** hsl ( 0-360 , 0-100 %, 0 - 100 %) */
| T_COL_HSL T_PARENT_LEFT T_INT T_COMMA t_property_color_value T_PERCENT T_COMMA t_property_color_value T_PERCENT T_COMMA t_property_color_value T_PERCENT T_PARENT_RIGHT {
if ( ! check_in_range($3, 0,360, &(@$)) ) { YYABORT; }
if ( ! check_in_range($5, 0,100, &(@$)) ) { YYABORT; }
if ( ! check_in_range($8, 0,100, &(@$)) ) { YYABORT; }
gdouble h = $3;
gdouble s = $5;
gdouble l = $8;
$$ = hsl_to_rgb ( h/360.0, s/100.0, l/100.0 );
$$.alpha = $11/100.0;
| T_COL_HSL T_PARENT_LEFT t_property_color_value_angle T_COMMA t_property_color_value_unit T_COMMA t_property_color_value_unit t_property_color_opt_alpha_c T_PARENT_RIGHT {
double h = $3, s = $5, l = $7;
$$ = hsl_to_rgb ( h, s, l );
$$.alpha = $8;
}
/** Hex colors parsed by lexer. */
| T_COLOR {
$$ = $1;
}
;
t_property_color_opt_alpha_c
: %empty { $$ = 1.0; }
| T_COMMA t_property_color_value_unit { $$ = $2;}
;
t_property_color_opt_alpha_ws
: %empty { $$ = 1.0; }
| T_FORWARD_SLASH t_property_color_value_unit { $$ = $2;}
;
t_property_color_value_angle
: t_property_color_value { $$ = $1/360.0; if ( ! check_in_range ( $1, 0, 360, &(@$))){YYABORT;}}
| t_property_color_value T_ANGLE_DEG { $$ = $1/360.0; if ( ! check_in_range ( $1, 0, 360, &(@$))){YYABORT;}}
| t_property_color_value T_ANGLE_RAD { $$ = $1/(2*G_PI); if ( ! check_in_range ( $1, 0.0, (2*G_PI), &(@$))){YYABORT;}}
| t_property_color_value T_ANGLE_GRAD { $$ = $1/400.0; if ( ! check_in_range ( $1, 0, 400, &(@$))){YYABORT;}}
| t_property_color_value T_ANGLE_TURN { $$ = $1; if ( ! check_in_range ( $1, 0.0, 1.0, &(@$))){YYABORT;}}
;
t_property_color_value_unit
: t_property_color_value T_PERCENT { $$ = $1/100.0; if ( !check_in_range ( $1, 0, 100, &(@$))){YYABORT;}}
| t_property_color_value { $$ = $1; if ( !check_in_range ( $1, 0.0, 1.0, &(@$))){YYABORT;}}
;
/** Color value to be double or integer. */
t_property_color_value
: T_DOUBLE { $$ = $1; }

@ -1 +1 @@
Subproject commit 60e5e71e09e573bd5c7839ce4a892747ea232526
Subproject commit 173f2f5566636a1de559cc57f3154db70c3f2e9f

View File

@ -643,7 +643,7 @@ START_TEST ( test_properties_color_hwb )
widget wid;
wid.name = "blaat";
wid.state = NULL;
rofi_theme_parse_string ( "* { test1: hwb(190,65%,0%); test2: hwb(265, 31%, 29%); }");
rofi_theme_parse_string ( "* { test1: hwb(190,65%,0%); test2: hwb(265, 31%, 29%); testa: hwb(265, 31%, 29%, 40%); }");
ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE );
Property *p = rofi_theme_find_property ( twid, P_COLOR, "test2", FALSE );
@ -658,6 +658,40 @@ START_TEST ( test_properties_color_hwb )
ck_assert_double_eq_tol ( p->value.color.red , 166/255.0, 0.004);
ck_assert_double_eq_tol ( p->value.color.green ,240/255.0, 0.004 );
ck_assert_double_eq_tol ( p->value.color.blue , 255/255.0 , 0.004);
p = rofi_theme_find_property ( twid, P_COLOR, "testa", FALSE );
ck_assert_ptr_nonnull ( p );
ck_assert_double_eq ( p->value.color.alpha , 0.4 );
ck_assert_double_eq_tol ( p->value.color.red , 0x7a/255.0 , 0.004);
ck_assert_double_eq_tol ( p->value.color.green , 0x4f/255.0, 0.004 );
ck_assert_double_eq_tol ( p->value.color.blue , 0xb5/255.0 , 0.004);
}
END_TEST
START_TEST ( test_properties_color_hwb_ws )
{
widget wid;
wid.name = "blaat";
wid.state = NULL;
rofi_theme_parse_string ( "* { test1: hwb(190 deg 65 %0%); test2: hwb(295 grad 31% 29%);testa: hwb(0.736 turn 31% 29% / 40%); }");
ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE );
Property *p = rofi_theme_find_property ( twid, P_COLOR, "test2", FALSE );
ck_assert_ptr_nonnull ( p );
ck_assert_double_eq ( p->value.color.alpha , 1.0 );
ck_assert_double_eq_tol ( p->value.color.red , 0x7a/255.0 , 0.004);
ck_assert_double_eq_tol ( p->value.color.green , 0x4f/255.0, 0.004 );
ck_assert_double_eq_tol ( p->value.color.blue , 0xb5/255.0 , 0.004);
p = rofi_theme_find_property ( twid, P_COLOR, "test1", FALSE );
ck_assert_ptr_nonnull ( p );
ck_assert_double_eq ( p->value.color.alpha , 1.0 );
ck_assert_double_eq_tol ( p->value.color.red , 166/255.0, 0.004);
ck_assert_double_eq_tol ( p->value.color.green ,240/255.0, 0.004 );
ck_assert_double_eq_tol ( p->value.color.blue , 255/255.0 , 0.004);
p = rofi_theme_find_property ( twid, P_COLOR, "testa", FALSE );
ck_assert_ptr_nonnull ( p );
ck_assert_double_eq ( p->value.color.alpha , 0.4 );
ck_assert_double_eq_tol ( p->value.color.red , 0x7a/255.0 , 0.004);
ck_assert_double_eq_tol ( p->value.color.green , 0x4f/255.0, 0.004 );
ck_assert_double_eq_tol ( p->value.color.blue , 0xb5/255.0 , 0.004);
}
END_TEST
START_TEST ( test_properties_color_cmyk )
@ -682,6 +716,28 @@ START_TEST ( test_properties_color_cmyk )
ck_assert_double_eq_tol ( p->value.color.blue , 0 , 0.004);
}
END_TEST
START_TEST ( test_properties_color_cmyk_ws )
{
widget wid;
wid.name = "blaat";
wid.state = NULL;
rofi_theme_parse_string ( "* { test1: cmyk ( 41% 0% 100% 0%); test2: cmyk ( 0 1.0 1.0 0);}");
ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE );
Property *p = rofi_theme_find_property ( twid, P_COLOR, "test1", FALSE );
ck_assert_ptr_nonnull ( p );
ck_assert_double_eq ( p->value.color.alpha , 1.0 );
ck_assert_double_eq_tol ( p->value.color.red , 0x96/255.0 , 0.004);
ck_assert_double_eq_tol ( p->value.color.green , 1.0, 0.004 );
ck_assert_double_eq_tol ( p->value.color.blue , 0.0 , 0.004);
p = rofi_theme_find_property ( twid, P_COLOR, "test2", FALSE );
ck_assert_ptr_nonnull ( p );
ck_assert_double_eq ( p->value.color.alpha , 1.0 );
ck_assert_double_eq_tol ( p->value.color.red , 1 , 0.004);
ck_assert_double_eq_tol ( p->value.color.green , 0, 0.004 );
ck_assert_double_eq_tol ( p->value.color.blue , 0 , 0.004);
}
END_TEST
START_TEST ( test_properties_padding_2 )
{
widget wid;
@ -909,7 +965,9 @@ static Suite * theme_parser_suite (void)
tcase_add_test ( tc_prop_color, test_properties_color_hsl);
tcase_add_test ( tc_prop_color, test_properties_color_hsla);
tcase_add_test ( tc_prop_color, test_properties_color_hwb);
tcase_add_test ( tc_prop_color, test_properties_color_hwb_ws);
tcase_add_test ( tc_prop_color, test_properties_color_cmyk);
tcase_add_test ( tc_prop_color, test_properties_color_cmyk_ws);
suite_add_tcase(s, tc_prop_color );
}
{