1use crate::schema::{Color, ColorRole};
8
9pub const SYNTAX_ROLES: [ColorRole; 15] = [
11 ColorRole::SyntaxKeyword,
12 ColorRole::SyntaxString,
13 ColorRole::SyntaxComment,
14 ColorRole::SyntaxNumber,
15 ColorRole::SyntaxConstant,
16 ColorRole::SyntaxType,
17 ColorRole::SyntaxFunction,
18 ColorRole::SyntaxVariable,
19 ColorRole::SyntaxProperty,
20 ColorRole::SyntaxOperator,
21 ColorRole::SyntaxPunctuation,
22 ColorRole::SyntaxTag,
23 ColorRole::SyntaxAttribute,
24 ColorRole::SyntaxEscape,
25 ColorRole::SyntaxMacro,
26];
27
28pub const DIFF_ROLES: [(ColorRole, ColorRole, ColorRole); 2] = [
30 (
31 ColorRole::DiffAdded,
32 ColorRole::DiffAddedContainer,
33 ColorRole::DiffAddedEmphasis,
34 ),
35 (
36 ColorRole::DiffRemoved,
37 ColorRole::DiffRemovedContainer,
38 ColorRole::DiffRemovedEmphasis,
39 ),
40];
41
42pub const MIN_SEPARATION: u32 = 24;
45
46fn channel(value: u32) -> f64 {
47 let value = f64::from(value) / 255.0;
48 if value <= 0.040_45 {
49 value / 12.92
50 } else {
51 ((value + 0.055) / 1.055).powf(2.4)
52 }
53}
54
55pub fn luminance(color: Color) -> f64 {
57 let argb = color.to_argb();
58 0.2126 * channel((argb >> 16) & 0xff)
59 + 0.7152 * channel((argb >> 8) & 0xff)
60 + 0.0722 * channel(argb & 0xff)
61}
62
63pub fn contrast(first: Color, second: Color) -> f64 {
65 let (a, b) = (luminance(first), luminance(second));
66 let (high, low) = if a > b { (a, b) } else { (b, a) };
67 (high + 0.05) / (low + 0.05)
68}
69
70pub fn apart(first: Color, second: Color) -> u32 {
72 [16, 8, 0]
73 .into_iter()
74 .map(|shift| {
75 let a = (first.to_argb() >> shift) & 0xff;
76 let b = (second.to_argb() >> shift) & 0xff;
77 a.abs_diff(b)
78 })
79 .sum()
80}