cosmic-text/src/attrs.rs

164 lines
3.8 KiB
Rust
Raw Normal View History

2022-10-25 14:42:26 -06:00
// SPDX-License-Identifier: MIT OR Apache-2.0
2022-10-25 14:14:23 -06:00
pub use fontdb::{Family, Stretch, Style, Weight};
2022-10-26 14:16:48 -06:00
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct Color(pub u32);
impl Color {
2022-10-27 09:07:47 -06:00
/// Create new color with red, green, and blue components
#[inline]
2022-10-26 14:16:48 -06:00
pub const fn rgb(r: u8, g: u8, b: u8) -> Self {
Self::rgba(r, g, b, 0xFF)
}
2022-10-27 09:07:47 -06:00
/// Create new color with red, green, blue, and alpha components
#[inline]
2022-10-26 14:16:48 -06:00
pub const fn rgba(r: u8, g: u8, b: u8, a: u8) -> Self {
Self(
((a as u32) << 24) |
((r as u32) << 16) |
((g as u32) << 8) |
(b as u32)
)
}
2022-10-27 09:07:47 -06:00
/// Get the red component
#[inline]
pub fn r(&self) -> u8 {
((self.0 & 0x00FF0000) >> 16) as u8
}
/// Get the green component
#[inline]
pub fn g(&self) -> u8 {
((self.0 & 0x0000FF00) >> 8) as u8
}
/// Get the blue component
#[inline]
pub fn b(&self) -> u8 {
(self.0 & 0x000000FF) as u8
}
/// Get the alpha component
#[inline]
pub fn a(&self) -> u8 {
((self.0 & 0xFF000000) >> 24) as u8
}
2022-10-26 14:16:48 -06:00
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
2022-10-25 14:14:23 -06:00
pub struct Attrs<'a> {
2022-10-26 14:16:48 -06:00
//TODO: should this be an option?
pub color_opt: Option<Color>,
2022-10-25 14:14:23 -06:00
pub family: Family<'a>,
pub monospaced: bool,
pub stretch: Stretch,
pub style: Style,
pub weight: Weight,
}
impl<'a> Attrs<'a> {
pub fn new() -> Self {
Self {
2022-10-26 14:16:48 -06:00
color_opt: None,
2022-10-25 14:14:23 -06:00
family: Family::SansSerif,
monospaced: false,
stretch: Stretch::Normal,
style: Style::Normal,
weight: Weight::NORMAL,
}
}
2022-10-26 14:16:48 -06:00
pub fn color(mut self, color: Color) -> Self {
self.color_opt = Some(color);
self
}
2022-10-25 14:14:23 -06:00
pub fn family(mut self, family: Family<'a>) -> Self {
self.family = family;
self
}
pub fn monospaced(mut self, monospaced: bool) -> Self {
self.monospaced = monospaced;
self
}
pub fn stretch(mut self, stretch: Stretch) -> Self {
self.stretch = stretch;
self
}
pub fn style(mut self, style: Style) -> Self {
self.style = style;
self
}
pub fn weight(mut self, weight: Weight) -> Self {
self.weight = weight;
self
}
2022-10-25 15:51:28 -06:00
pub fn matches(&self, face: &fontdb::FaceInfo) -> bool {
//TODO: smarter way of including emoji
face.post_script_name.contains("Emoji") ||
(
face.style == self.style &&
face.weight == self.weight &&
face.stretch == self.stretch &&
face.monospaced == self.monospaced
)
2022-10-25 15:51:28 -06:00
}
pub fn compatible(&self, other: &Self) -> bool {
self.family == other.family
&& self.monospaced == other.monospaced
&& self.stretch == other.stretch
&& self.style == other.style
&& self.weight == other.weight
}
2022-10-25 14:14:23 -06:00
}
2022-10-26 14:16:48 -06:00
#[derive(Eq, PartialEq)]
pub struct AttrsList<'a> {
defaults: Attrs<'a>,
spans: Vec<(usize, usize, Attrs<'a>)>,
}
impl<'a> AttrsList<'a> {
pub fn new(defaults: Attrs<'a>) -> Self {
Self {
defaults,
spans: Vec::new(),
}
}
pub fn defaults(&self) -> Attrs<'a> {
self.defaults
}
pub fn spans(&self) -> &Vec<(usize, usize, Attrs<'a>)> {
&self.spans
}
pub fn clear_spans(&mut self) {
self.spans.clear();
}
pub fn add_span(&mut self, start: usize, end: usize, attrs: Attrs<'a>) {
self.spans.push((start, end, attrs));
}
pub fn get_span(&self, start: usize, end: usize) -> Attrs<'a> {
let mut attrs = self.defaults;
for span in self.spans.iter() {
if start >= span.0 && end <= span.1 {
attrs = span.2;
}
}
attrs
}
2022-10-26 14:16:48 -06:00
}