-
Notifications
You must be signed in to change notification settings - Fork 129
/
style.rs
138 lines (127 loc) · 4.1 KB
/
style.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Code based on [https://github.com/defuz/sublimate/blob/master/src/core/syntax/scope.rs](https://github.com/defuz/sublimate/blob/master/src/core/syntax/scope.rs)
// released under the MIT license by @defuz
use bitflags::bitflags;
use serde_derive::{Deserialize, Serialize};
/// Foreground and background colors, with font style
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Style {
/// Foreground color
pub foreground: Color,
/// Background color
pub background: Color,
/// Style of the font
pub font_style: FontStyle,
}
/// A change to a [`Style`] applied incrementally by a theme rule
///
/// Fields left empty (as `None`) will not modify the corresponding field on a `Style`
///
/// [`Style`]: struct.Style.html
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct StyleModifier {
/// Foreground color
pub foreground: Option<Color>,
/// Background color
pub background: Option<Color>,
/// Style of the font
pub font_style: Option<FontStyle>,
}
/// RGBA color, directly from the theme
///
/// Because these numbers come directly from the theme, you might have to do your own color space
/// conversion if you're outputting a different color space from the theme. This can be a problem
/// because some Sublime themes use sRGB and some don't. This is specified in an attribute syntect
/// doesn't parse yet.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Color {
/// Red component
pub r: u8,
/// Green component
pub g: u8,
/// Blue component
pub b: u8,
/// Alpha (transparency) component
pub a: u8,
}
// More compact alternate debug representation by not using a separate line for each color field,
// also adapts the default debug representation to match.
impl std::fmt::Debug for Color {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let Color { r, g, b, a } = self;
if f.alternate() {
// when formatted with "{:#?}"
write!(
f,
"Color {{ r/g/b/a: {: >3}/{: >3}/{: >3}/{: >3} }}",
r, g, b, a
)
} else {
// when formatted with "{:?}"
write!(f, "Color {{ r/g/b/a: {}/{}/{}/{} }}", r, g, b, a)
}
}
}
bitflags! {
/// The color-independent styling of a font - i.e. bold, italicized, and/or underlined
#[derive(Serialize, Deserialize, Debug, Hash, Eq, PartialEq, Clone, Copy)]
pub struct FontStyle: u8 {
/// Bold font style
const BOLD = 1;
/// Underline font style
const UNDERLINE = 2;
/// Italic font style
const ITALIC = 4;
}
}
impl Color {
/// The color black (`#000000`)
pub const BLACK: Color = Color {
r: 0x00,
g: 0x00,
b: 0x00,
a: 0xFF,
};
/// The color white (`#FFFFFF`)
pub const WHITE: Color = Color {
r: 0xFF,
g: 0xFF,
b: 0xFF,
a: 0xFF,
};
}
impl Style {
/// Applies a change to this style, yielding a new changed style
pub fn apply(&self, modifier: StyleModifier) -> Style {
Style {
foreground: modifier.foreground.unwrap_or(self.foreground),
background: modifier.background.unwrap_or(self.background),
font_style: modifier.font_style.unwrap_or(self.font_style),
}
}
}
impl Default for Style {
fn default() -> Style {
Style {
foreground: Color::BLACK,
background: Color::WHITE,
font_style: FontStyle::empty(),
}
}
}
impl StyleModifier {
/// Applies the other modifier to this one, creating a new modifier.
///
/// Values in `other` are preferred.
pub fn apply(&self, other: StyleModifier) -> StyleModifier {
StyleModifier {
foreground: other.foreground.or(self.foreground),
background: other.background.or(self.background),
font_style: other.font_style.or(self.font_style),
}
}
}
impl Default for FontStyle {
fn default() -> FontStyle {
FontStyle::empty()
}
}