bah I thought i might takle this...I cannot make the bloody thing work, any
ideas?
--
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,16 @@
| 0x02000018 0xffff0000
#reset
+## test HSL
+
+#data
+* { color: hsl(0, 100%, 50%) }
+#errors
+#expected
+| 1 *
+| 0x02000018 0xffff0000
+#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)
@@ -273,9 +273,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 +341,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 +429,161 @@
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;
+ int v;
+
+ /* 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) * 255) /
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(FDIVI(FMULI(num, 255), 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(FDIVI(FMULI(num, 255), 100));
+
+ 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_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 */
+
+ 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 */
+
+
+ if (lit < 128)
+ v = (lit * (256 + sat)) >> 8;
+ else
+ v = (((lit + sat) << 8) - lit * sat) >> 8;
+
+ if (v <= 0) {
+ r = g = b = 0;
+ } else {
+ int m;
+ int sextant;
+ int fract, vsf, mid1, mid2;
+
+ m = lit + lit - v;
+ hue *= 6;
+ sextant = hue >> 8;
+ fract = hue - (sextant << 8);
+ vsf = v * fract * (v - m) / v >> 8;
+ mid1 = m + vsf;
+ mid2 = v - vsf;
+
+ switch (sextant) {
+ case 0: r = v; g = mid1; b = m; break;
+ case 1: r = mid2; g = v; b = m; break;
+ case 2: r = m; g = v; b = mid1; break;
+ case 3: r = m; g = mid2; b = v; break;
+ case 4: r = mid1; g = m; b = v; break;
+ case 5: r = v; g = m; b = mid2; break;
+ }
+ }
+
+ /* apply alpha */
+ if (alpha > 255)
+ a = 255;
+ else if (alpha < 0)
+ a = 0;
+ else
+ a = alpha;
+
+/*
+ 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
+*/
+
+ } else {
goto invalid;
+ }
}
*result = (a << 24) | (r << 16) | (g << 8) | b;