@@ -22,8 +22,62 @@ let graya v a = rgba v v v a
22
22
23
23
let gray v = graya v 255
24
24
25
- let hsv h s v = failwith " HSV color unimplemented"
25
+ let hsv h s v =
26
+ if h < 0 || h > 360
27
+ then failwith (" hsv h out of range [0, 360]: " ^ string_of_int h) else
28
+ if s < 0 || s > 100
29
+ then failwith (" hsv s out of range [0, 100]: " ^ string_of_int s) else
30
+ if v < 0 || v > 100
31
+ then failwith (" hsv v out of range [0, 100]: " ^ string_of_int v) else
32
+ let open Math in
33
+ let sat = ~. s /. 100. in
34
+ let value = ~. v /. 100. in
35
+ let chroma = value *. sat in
36
+ let h' = ~. h /. 60. in
37
+ let x = chroma *. (1. -. Math. absf ((mod_float h' 2. ) -. 1. )) in
38
+ let r', g', b' =
39
+ if h' > = 0. && h' < 1. then chroma, x, 0. else
40
+ if h' > = 1. && h' < 2. then x, chroma, 0. else
41
+ if h' > = 2. && h' < 3. then 0. , chroma, x else
42
+ if h' > = 3. && h' < 4. then 0. , x, chroma else
43
+ if h' > = 4. && h' < 5. then x, 0. , chroma else
44
+ if h' > = 5. && h' < = 6. then chroma, 0. , x else 0. , 0. , 0. in
45
+ let m = value -. chroma in
46
+ rgb
47
+ ((r' +. m) *. 255. |> Math. round)
48
+ ((g' +. m) *. 255. |> Math. round)
49
+ ((b' +. m) *. 255. |> Math. round)
26
50
27
51
let hsva h s v a = {(hsv h s v) with alpha = a}
28
52
29
- let hex hex = failwith " Hexadecimal color unimplemented"
53
+ let hex hex =
54
+ (* remove leading pound sign *)
55
+ let hex' =
56
+ if String. length hex > 0 && String. get hex 0 = '#'
57
+ then String. sub hex 1 (String. length hex - 1 )
58
+ else hex in
59
+ (* add alpha characters if not present *)
60
+ let hex'' =
61
+ if String. length hex' = 6 then " FF" ^ hex'
62
+ else if String. length hex' = 8 then hex'
63
+ else failwith (" Invalid hex color: " ^ hex) in
64
+ (* convert a hex digit [0-9A-Za-z] to an integer *)
65
+ let int_of_hex_digit c =
66
+ if Char. code c > = Char. code 'a' && Char. code c < = Char. code 'f'
67
+ then Char. code c - Char. code 'a' + 10
68
+ else if Char. code c > = Char. code 'A' && Char. code c < = Char. code 'F'
69
+ then Char. code c - Char. code 'A' + 10
70
+ else if Char. code c > = Char. code '0' && Char. code c < = Char. code '9'
71
+ then Char. code c - Char. code '0'
72
+ else failwith (" Invalid hex char '" ^ (String. make 1 c) ^ " in: " ^ hex) in
73
+ (* convert two hex digits into an integer *)
74
+ let int_of_hex_pair c1 c2 =
75
+ 16 * (int_of_hex_digit c1) + (int_of_hex_digit c2) in
76
+ (* convert two sequential hex digits from [hex] into an integer *)
77
+ let int_of_str_pair_pos i =
78
+ int_of_hex_pair (String. get hex'' i) (String. get hex'' (i + 1 )) in
79
+ let a = int_of_str_pair_pos 0 in
80
+ let r = int_of_str_pair_pos 2 in
81
+ let g = int_of_str_pair_pos 4 in
82
+ let b = int_of_str_pair_pos 6 in
83
+ rgba r g b a
0 commit comments