| 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 | |
| 5 | module ui |
| 6 | |
| 7 | const value_range = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]! |
| 8 | |
| 9 | pub const color_table = init_color_table() |
| 10 | |
| 11 | @[direct_array_access] |
| 12 | fn 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 | |
| 48 | fn 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 | |
| 58 | fn 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 | |
| 70 | fn 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 |
| 83 | fn 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 | |