From e397c346da38f71c8b8f6e5e4cf57f7ee01b2404 Mon Sep 17 00:00:00 2001 From: Dave Davenport Date: Mon, 15 May 2017 15:05:40 +0200 Subject: [PATCH] [ThemeParser] Extend color formats. - Support whitespace format. - Support deg,rad, grad, turn angle. - Add alpha channel support to hwb --- lexer/theme-lexer.l | 15 +++- lexer/theme-parser.y | 146 ++++++++++++++++++++++----------------- libgwater | 2 +- test/theme-parser-test.c | 60 +++++++++++++++- 4 files changed, 157 insertions(+), 66 deletions(-) diff --git a/lexer/theme-lexer.l b/lexer/theme-lexer.l index a43323f5..a35a5044 100644 --- a/lexer/theme-lexer.l +++ b/lexer/theme-lexer.l @@ -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 ){ {S_T_PARENT_LEFT} { return T_PARENT_LEFT; } {S_T_PARENT_RIGHT} { return T_PARENT_RIGHT;} {COMMA} { return T_COMMA; } +{FORWARD_SLASH} { return T_FORWARD_SLASH; } /* Position */ {CENTER} { return T_POS_CENTER; } {EAST} { return T_POS_EAST; } @@ -434,6 +443,10 @@ if ( queue == NULL ){ {ITALIC} { return T_ITALIC; } {UNDERLINE} { return T_UNDERLINE; } +{ANGLE_DEG} { return T_ANGLE_DEG; } +{ANGLE_RAD} { return T_ANGLE_RAD; } +{ANGLE_GRAD} { return T_ANGLE_GRAD; } +{ANGLE_TURN} { return T_ANGLE_TURN; } <> { ParseObject *po = g_queue_pop_head ( file_queue ); diff --git a/lexer/theme-parser.y b/lexer/theme-parser.y index 1ccc551e..7ba81ae6 100644 --- a/lexer/theme-parser.y +++ b/lexer/theme-parser.y @@ -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 t_property_list_optional %type t_property_color %type t_property_color_value +%type t_property_color_opt_alpha_c +%type t_property_color_opt_alpha_ws +%type t_property_color_value_unit +%type t_property_color_value_angle %type t_property_name %type t_property_distance %type 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; } diff --git a/libgwater b/libgwater index 60e5e71e..173f2f55 160000 --- a/libgwater +++ b/libgwater @@ -1 +1 @@ -Subproject commit 60e5e71e09e573bd5c7839ce4a892747ea232526 +Subproject commit 173f2f5566636a1de559cc57f3154db70c3f2e9f diff --git a/test/theme-parser-test.c b/test/theme-parser-test.c index 5aa0b298..488aa203 100644 --- a/test/theme-parser-test.c +++ b/test/theme-parser-test.c @@ -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 ); } {