with the changes from jmb/tlsa and split out...still doesnt work, if
anything its worse than before :-(


-- 
Regards Vincent
http://www.kyllikki.org/
Index: test/data/parse/colours.dat
===================================================================
--- test/data/parse/colours.dat (revision 11426)
+++ test/data/parse/colours.dat (working copy)
@@ -40,6 +40,37 @@
 |   0x02000018 0xffff0000
 #reset
 
+## test HSL 
+
+
+## red
+#data
+* { color: hsl(0, 100%, 50%) }
+#errors
+#expected
+| 1 *
+|   0x02000018 0xffff0000
+#reset
+
+## green
+#data
+* { color: hsl(120, 100%, 50%) }
+#errors
+#expected
+| 1 *
+|   0x02000018 0xff00ff00
+#reset
+
+## blue
+#data
+* { color: hsl(240, 100%, 50%) }
+#errors
+#expected
+| 1 *
+|   0x02000018 0xff0000ff
+#reset
+
+
 ## Out-of-range rgb() parameters
 
 #data
Index: src/parse/propstrings.h
===================================================================
--- src/parse/propstrings.h     (revision 11426)
+++ src/parse/propstrings.h     (working copy)
@@ -84,7 +84,7 @@
        NE_RESIZE, NW_RESIZE, N_RESIZE, SE_RESIZE, SW_RESIZE, S_RESIZE, 
        W_RESIZE, LIBCSS_TEXT, WAIT, HELP, PROGRESS, SERIF, SANS_SERIF, CURSIVE,
        FANTASY, MONOSPACE, MALE, FEMALE, CHILD, MIX, UNDERLINE, OVERLINE, 
-       LINE_THROUGH, BLINK, RGB, RGBA, LIBCSS_LEFT, LIBCSS_CENTER,
+       LINE_THROUGH, BLINK, RGB, RGBA, HSL, HSLA, LIBCSS_LEFT, LIBCSS_CENTER,
        LIBCSS_RIGHT,
 
        /* Named colours */
Index: src/parse/propstrings.c
===================================================================
--- src/parse/propstrings.c     (revision 11426)
+++ src/parse/propstrings.c     (working copy)
@@ -331,6 +331,8 @@
        { "blink", SLEN("blink") },
        { "rgb", SLEN("rgb") },
        { "rgba", SLEN("rgba") },
+       { "hsl", SLEN("hsl") },
+       { "hsla", SLEN("hsla") },
        { "-libcss-left", SLEN("-libcss-left") },
        { "-libcss-center", SLEN("-libcss-center") },
        { "-libcss-right", SLEN("-libcss-right") },
Index: src/parse/properties/utils.c
===================================================================
--- src/parse/properties/utils.c        (revision 11426)
+++ src/parse/properties/utils.c        (working copy)
@@ -248,7 +248,126 @@
        return error;
 }
 
+#define INTEGER_HSL 
+
+#if defined(INTEGER_HSL)
 /**
+ * Convert Hue Sauration Lightness value to RGB integer version
+ *
+ * \param hue Hue in degrees 0..360
+ * \param sat Saturation value in percent 0..100
+ * \param lit Lightness value in percent 0..100
+ * \param r red component
+ * \param g green component
+ * \param b blue component
+ */
+static void HSL_to_RGB(int32_t hue, int32_t sat, int32_t lit, uint8_t *r, 
uint8_t *g, uint8_t *b)
+{
+       int v;
+       int m;
+       int sextant;
+       int fract, vsf, mid1, mid2;
+       int red,green,blue;
+
+       hue = (hue * 1023) / 360;
+       sat = (sat * 1023) / 100;
+       lit = (lit * 1023) / 100;
+
+       if (lit < 511)
+               v = (lit * (512 + sat)) >> 10;
+       else
+               v = (((lit + sat) << 10) - lit * sat) >> 10;
+
+       if (v <= 0) {
+               *r = *g = *b = 0;
+               return;
+       } 
+
+       m = lit + lit - v;
+       hue *= 6;
+       sextant = hue >> 10;
+       fract = hue - (sextant << 10);
+       vsf = v * fract * (v - m) / v >> 10;
+       mid1 = m + vsf;
+       mid2 = v - vsf;
+
+#define ORGB(R,G,B) red = (R)>>2; green = (G)>>2; blue = (B)>>2 
+       switch (sextant) {
+       case 0: ORGB(v, mid1, m); break;
+       case 1: ORGB(mid2, v, m); break;
+       case 2: ORGB(m, v, mid1); break;
+       case 3: ORGB(m, mid2, v); break;
+       case 4: ORGB(mid1, m, v); break;
+       case 5: ORGB(v, m, mid2); break;
+       }
+#undef ORGB
+       *r = red;
+       *g = green;
+       *b = blue;
+}                      
+
+#else
+
+/* CSS standard definition
+
+  HOW TO RETURN hsl.to.rgb(h, s, l): 
+  SELECT: 
+  l<=0.5: PUT l*(s+1) IN m2
+  ELSE: PUT l+s-l*s IN m2
+  PUT l*2-m2 IN m1
+  PUT hue.to.rgb(m1, m2, h+1/3) IN r
+  PUT hue.to.rgb(m1, m2, h    ) IN g
+  PUT hue.to.rgb(m1, m2, h-1/3) IN b
+  RETURN (r, g, b)
+
+  HOW TO RETURN hue.to.rgb(m1, m2, h): 
+  IF h<0: PUT h+1 IN h
+  IF h>1: PUT h-1 IN h
+  IF h*6<1: RETURN m1+(m2-m1)*h*6
+  IF h*2<1: RETURN m2
+  IF h*3<2: RETURN m1+(m2-m1)*(2/3-h)*6
+  RETURN m1
+*/
+static inline int hue_to_RGB(float m1, float m2, float h)
+{
+       h = (h < 0) ? h + 1 : h;
+       h = (h > 1) ? h - 1 : h;
+
+       if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+       if (h * 2 < 1) return m2;
+       if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+       return m1;
+}
+
+/**
+ * Convert Hue Sauration Lightness value to RGB float version from CSS standard
+ *
+ * \param hue Hue in degrees 0..360
+ * \param sat Saturation value in percent 0..100
+ * \param lit Lightness value in percent 0..100
+ * \param r red component
+ * \param g green component
+ * \param b blue component
+ */
+static void HSL_to_RGB(int32_t hue, int32_t sat, int32_t lit, uint8_t *r, 
uint8_t *g, uint8_t *b)
+{
+       float m1, m2;
+       float h, s, l;
+
+       h = hue/360;
+       s = sat/100;
+       l = lit/100;
+
+       m2 = (l <= 0.5) ? l * (s + 1) : l + s - l * s;
+       m1 = l * 2 - m2;
+
+       *r = hue_to_RGB(m1, m2, h + 1/3);
+       *g = hue_to_RGB(m1, m2, h      );
+       *b = hue_to_RGB(m1, m2, h - 1/3);
+}
+#endif
+
+/**
  * Parse a colour specifier
  *
  * \param c       Parsing context
@@ -273,9 +392,12 @@
 
        consumeWhitespace(vector, ctx);
 
-       /* IDENT(<colour name>) | HASH(rgb | rrggbb) |
+       /* IDENT(<colour name>) | 
+        * HASH(rgb | rrggbb) |
         * FUNCTION(rgb) [ [ NUMBER | PERCENTAGE ] ',' ] {3} ')'
         * FUNCTION(rgba) [ [ NUMBER | PERCENTAGE ] ',' ] {4} ')'
+        * FUNCTION(hsl) ANGLE ',' PERCENTAGE ',' PERCENTAGE  ')'
+        * FUNCTION(hsla) ANGLE ',' PERCENTAGE ',' PERCENTAGE ',' NUMBER ')'
         *
         * For quirks, NUMBER | DIMENSION | IDENT, too
         * I.E. "123456" -> NUMBER, "1234f0" -> DIMENSION, "f00000" -> IDENT
@@ -338,6 +460,14 @@
                                token->idata, c->strings[RGBA],
                                &match) == lwc_error_ok && match)) {
                        colour_channels = 4;
+               } if ((lwc_string_caseless_isequal(
+                               token->idata, c->strings[HSL],
+                               &match) == lwc_error_ok && match)) {
+                       colour_channels = 5;
+               } else if ((lwc_string_caseless_isequal(
+                               token->idata, c->strings[HSLA],
+                               &match) == lwc_error_ok && match)) {
+                       colour_channels = 6;
                }
 
                if (colour_channels == 3 || colour_channels == 4) {
@@ -418,8 +548,111 @@
                                        goto invalid;
                                }
                        }
-               } else
+               } else if (colour_channels == 5 || colour_channels == 6) {
+                       /* hue - saturation - lightness */
+                       size_t consumed = 0;
+                       css_fixed num;
+                       int32_t alpha = 255, hue, sat, lit;
+
+                       /* hue is a number without a unit representing an 
+                        * angle (0-360) degrees  
+                        */
+                       consumeWhitespace(vector, ctx);
+
+                       token = parserutils_vector_iterate(vector, ctx);
+                       if ((token == NULL) || (token->type != 
CSS_TOKEN_NUMBER))
+                               goto invalid;
+
+                       num = css__number_from_lwc_string(token->idata, true, 
&consumed);
+                       if (consumed != lwc_string_length(token->idata))
+                               goto invalid; /* failed to consume the whole 
string as a number */
+
+                       hue = (((FIXTOINT(num) % 360) + 360) % 360);
+
+                       consumeWhitespace(vector, ctx);
+
+                       token = parserutils_vector_iterate(vector, ctx);
+                       if (!tokenIsChar(token, ','))
+                               goto invalid;
+
+
+                       /* saturation */
+                       consumeWhitespace(vector, ctx);
+
+                       token = parserutils_vector_iterate(vector, ctx);
+                       if ((token == NULL) || (token->type != 
CSS_TOKEN_PERCENTAGE))
+                               goto invalid;
+
+                       num = css__number_from_lwc_string(token->idata, true, 
&consumed);
+                       if (consumed != lwc_string_length(token->idata))
+                               goto invalid; /* failed to consume the whole 
string as a number */
+                       sat = FIXTOINT(100);
+
+                       consumeWhitespace(vector, ctx);
+
+                       token = parserutils_vector_iterate(vector, ctx);
+                       if (!tokenIsChar(token, ','))
+                               goto invalid;
+
+
+                       /* lightness */
+                       consumeWhitespace(vector, ctx);
+
+                       token = parserutils_vector_iterate(vector, ctx);
+                       if ((token == NULL) || (token->type != 
CSS_TOKEN_PERCENTAGE))
+                               goto invalid;
+
+                       num = css__number_from_lwc_string(token->idata, true, 
&consumed);
+                       if (consumed != lwc_string_length(token->idata))
+                               goto invalid; /* failed to consume the whole 
string as a number */
+
+                       lit = FIXTOINT(num);
+
+                       consumeWhitespace(vector, ctx);
+
+                       token = parserutils_vector_iterate(vector, ctx);
+
+                       if (colour_channels == 6) {
+                               /* alpha */
+
+                               if (!tokenIsChar(token, ','))
+                                       goto invalid;
+                       
+                               consumeWhitespace(vector, ctx);
+
+                               token = parserutils_vector_iterate(vector, ctx);
+                               if ((token == NULL) || (token->type != 
CSS_TOKEN_NUMBER))
+                                       goto invalid;
+
+                               num = css__number_from_lwc_string(token->idata, 
true, &consumed);
+                               if (consumed != lwc_string_length(token->idata))
+                                       goto invalid; /* failed to consume the 
whole string as a number */
+
+                               alpha = FIXTOINT(FMULI(num, 255));
+
+                               consumeWhitespace(vector, ctx);
+
+                               token = parserutils_vector_iterate(vector, ctx);
+
+                       }
+
+                       if (!tokenIsChar(token, ')'))
+                               goto invalid;
+
+                       /* have a valid HSV entry, convert to RGB */
+
+                       HSL_to_RGB(hue, sat, lit, &r, &g, &b);
+                       /* apply alpha */
+                       if (alpha > 255)
+                               a = 255;
+                       else if (alpha < 0)
+                               a = 0;
+                       else
+                               a = alpha;
+
+               } else {
                        goto invalid;
+               }
        }
 
        *result = (a << 24) | (r << 16) | (g << 8) | b;

Reply via email to