@@ -25,46 +25,35 @@ let s:c = s:getXterm2RgbDict()
25
25
26
26
" Given two RGB ojects, gives the difference between the two
27
27
function ! s: colorDiff (rgb1, rgb2)
28
- " The human eye is most sensitive to green light, less to red and least to blue.
29
- let diff_r = 33 * abs (a: rgb1 .r - a: rgb2 .r )
30
- let diff_g = 50 * abs (a: rgb1 .g - a: rgb2 .g )
31
- let diff_b = 16 * abs (a: rgb1 .b - a: rgb2 .b )
32
- let diff = diff_r + diff_g + diff_b
33
- return diff
34
- endfunction
35
-
36
- " Given two RGB ojects, and one is gray, gives the manhattan difference.
37
- function ! s: grayDiff (rgb1, rgb2)
38
28
let diff_r = abs (a: rgb1 .r - a: rgb2 .r )
39
29
let diff_g = abs (a: rgb1 .g - a: rgb2 .g )
40
30
let diff_b = abs (a: rgb1 .b - a: rgb2 .b )
41
- let diff = diff_r + diff_g + diff_b
42
- return diff
31
+ let is_gray_diff = (a: rgb1 .r == a: rgb1 .b ) && (a: rgb1 .b == a: rgb1 .g ) && (a: rgb2 .r == a: rgb2 .b ) && (a: rgb2 .b == a: rgb2 .g )
32
+ if ! is_gray_diff
33
+ " The human eye is most sensitive to green light, less to red and least to blue.
34
+ " In the ratio of about 50 / 33 / 16
35
+ return 16 * diff_r + 33 * diff_g + 50 * diff_b
36
+ else
37
+ " Slightly favour pure gray colors if is gray
38
+ return 32 * diff_r + 32 * diff_g + 32 * diff_b
39
+ endif
43
40
endfunction
44
- let s: rgb_black = capesky#t_hex#toRgb (' #000000' )
45
- let s: rgb_white = capesky#t_hex#toRgb (' #ffffff' )
46
- let s: max_error = s: colorDiff (s: rgb_black , s: rgb_white )
41
+ let s: max_error = s: colorDiff ({' r' :0 , ' g' :0 , ' b' :0 }, {' r' :0xff , ' g' :0xff , ' b' :0xff })
47
42
48
43
" Converts RGB object -> xterm 255 color number
49
44
" Does not use colors 0-15 because they are none standard (customised)
50
- function ! capesky#t_xterm#fromRgb (rgb)
51
- let is_gray = (a: rgb .r == a: rgb .b ) && (a: rgb .b == a: rgb .g )
45
+ " This function is too slow to use to be used to convert all colours on
46
+ " the fly, but used to check capesky#t_xterm#fromRgb (faster version same
47
+ " output)
48
+ function ! capesky#t_xterm#fromRgbSlow (rgb)
52
49
let best = s: max_error
53
50
let e = 0 " Init for scope
54
51
for i in range (16 , 255 )
55
52
let rgb_check = s: c [i ]
56
- if is_gray
57
- let e = s: grayDiff (a: rgb , rgb_check)
58
- else
59
- let e = s: colorDiff (a: rgb , rgb_check)
60
- endif
53
+ let e = s: colorDiff (a: rgb , rgb_check)
61
54
if e <= best
62
55
let best = e
63
56
let n = i
64
- if e <= 8
65
- " I think won't find a closer match
66
- return n
67
- endif
68
57
endif
69
58
endfor
70
59
return n
@@ -75,3 +64,46 @@ function! capesky#t_xterm#toRgb(n)
75
64
return rgb
76
65
endfunction
77
66
67
+ " Colors step at these points
68
+ " let s:steps = [ 0, 95, 135, 175, 215, 255]
69
+ " Thresholds (dec) [ 48, 115, 155, 195, 235 ]
70
+ " Thresholds (hex) [ 30, 73, 9b, c3, eb ]
71
+ function ! s: getClosestColorComponent (n )
72
+ if a: n >= 0x73
73
+ return (a: n - 35 ) / 0x28
74
+ elseif a: n < 0x30
75
+ return 0
76
+ else
77
+ return 1
78
+ endif
79
+ endfunction
80
+ function ! s: getClosestXtermColor16To231 (rgb)
81
+ let r = s: getClosestColorComponent (a: rgb .r )
82
+ let g = s: getClosestColorComponent (a: rgb .g )
83
+ let b = s: getClosestColorComponent (a: rgb .b )
84
+ return 16 + 0x24 * r + 6 * g + b
85
+ endfunction
86
+
87
+ function ! s: getClosestXtermGray232To255 (rgb)
88
+ let l = a: rgb .r
89
+ if l <= 0x03
90
+ return 16 " black
91
+ elseif l >= 0xf7
92
+ return 231 " white
93
+ elseif l >= 0xe9
94
+ return 255 " darkest gray
95
+ else
96
+ " Some gray inbetween
97
+ return (l - 3 )/10 + 232
98
+ endif
99
+ endfunction
100
+
101
+ " Fast implentation of of getting xterm colour from RGB object
102
+ function ! capesky#t_xterm#fromRgb (rgb)
103
+ let color_n = s: getClosestXtermColor16To231 (a: rgb )
104
+ let gray_n = s: getClosestXtermGray232To255 (a: rgb )
105
+ let color_rgb = s: c [color_n]
106
+ let gray_rgb = s: c [gray_n]
107
+ let n = (s: colorDiff (a: rgb , color_rgb) < s: colorDiff (a: rgb , gray_rgb)) ? color_n : gray_n
108
+ return n
109
+ endfunction
0 commit comments