v / vlib / term / ui / color.v
89 lines · 81 sloc · 2.08 KB · 008aaad99981918c51194d7aaaaaccb4c258f244
Raw
1// radare - LGPL - Copyright 2013-2020 - pancake, xarkes
2// ansi 256 color extension for r_cons
3// https://en.wikipedia.org/wiki/ANSI_color
4
5module ui
6
7const value_range = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]!
8
9pub const color_table = init_color_table()
10
11@[direct_array_access]
12fn init_color_table() []u32 {
13 mut color_table_ := []u32{len: 256}
14 // ansi colors
15 color_table_[0] = 0x000000
16 color_table_[1] = 0x800000
17 color_table_[2] = 0x008000
18 color_table_[3] = 0x808000
19 color_table_[4] = 0x000080
20 color_table_[5] = 0x800080
21 color_table_[6] = 0x008080
22 color_table_[7] = 0xc0c0c0
23 color_table_[8] = 0x808080
24 color_table_[9] = 0xff0000
25 color_table_[10] = 0x00ff00
26 color_table_[11] = 0xffff00
27 color_table_[12] = 0x0000ff
28 color_table_[13] = 0xff00ff
29 color_table_[14] = 0x00ffff
30 color_table_[15] = 0xffffff
31 // color palette
32 for i in 0 .. 216 {
33 r := value_range[(i / 36) % 6]
34 g := value_range[(i / 6) % 6]
35 b := value_range[i % 6]
36 color_table_[i + 16] = ((u32(r) << 16) & 0xffffff) + ((u32(g) << 8) & 0xffff) +
37 (u32(b) & 0xff)
38 }
39 // grayscale
40 for i in 0 .. 24 {
41 r := 8 + (i * 10)
42 color_table_[i + 232] = ((u32(r) << 16) & 0xffffff) + ((u32(r) << 8) & 0xffff) +
43 (u32(r) & 0xff)
44 }
45 return color_table_
46}
47
48fn clamp(x int, y int, z int) int {
49 if x < y {
50 return y
51 }
52 if x > z {
53 return z
54 }
55 return x
56}
57
58fn approximate_rgb(r int, g int, b int) int {
59 grey := r > 0 && r < 255 && r == g && r == b
60 if grey {
61 return 232 + int(f64(r) / (255 / 24.1))
62 }
63 k := int(256.0 / 6)
64 r2 := clamp(r / k, 0, 5)
65 g2 := clamp(g / k, 0, 5)
66 b2 := clamp(b / k, 0, 5)
67 return 16 + (r2 * 36) + (g2 * 6) + b2
68}
69
70fn lookup_rgb(r int, g int, b int) int {
71 color := (u32(r) << 16) + (u32(g) << 8) + u32(b)
72 // lookup extended colors only, coz non-extended can be changed by users.
73 for i in 16 .. 256 {
74 if color_table[i] == color {
75 return i
76 }
77 }
78 return -1
79}
80
81// converts an RGB color to an ANSI 256-color, approximating it to the nearest available color
82// if an exact match is not found
83fn rgb2ansi(r int, g int, b int) int {
84 c := lookup_rgb(r, g, b)
85 if c == -1 {
86 return approximate_rgb(r, g, b)
87 }
88 return c
89}
90