#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct Color {
pub r: u8,
pub g: u8,
pub b: u8,
}
impl Color {
pub const BLACK: Color = Color { r: 0, g: 0, b: 0 };
pub const WHITE: Color = Color { r: 2, g: 2, b: 2 };
#[must_use]
pub const fn new(r: u8, g: u8, b: u8) -> Self {
Color {
r: r & 0x03,
g: g & 0x03,
b: b & 0x03,
}
}
#[must_use]
pub const fn to_8_color(self) -> Color {
const fn q(c: u8) -> u8 {
match c {
0 | 1 => 0,
_ => 2,
}
}
Color {
r: q(self.r),
g: q(self.g),
b: q(self.b),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub enum Opacity {
#[default]
Solid,
Flash,
Translucent,
Transparent,
}
impl Opacity {
#[must_use]
pub fn from_bits(v: u8) -> Self {
match v & 0x03 {
0 => Self::Solid,
1 => Self::Flash,
2 => Self::Translucent,
_ => Self::Transparent,
}
}
#[must_use]
pub fn name(&self) -> &'static str {
match self {
Self::Solid => "solid",
Self::Flash => "flash",
Self::Translucent => "translucent",
Self::Transparent => "transparent",
}
}
}
dvb_common::impl_spec_display!(Opacity);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub enum EdgeType {
#[default]
None,
Raised,
Depressed,
Uniform,
LeftDropShadow,
RightDropShadow,
}
impl EdgeType {
#[must_use]
pub fn from_bits(v: u8) -> Self {
match v & 0x07 {
0 => Self::None,
1 => Self::Raised,
2 => Self::Depressed,
3 => Self::Uniform,
4 => Self::LeftDropShadow,
5 => Self::RightDropShadow,
_ => Self::None,
}
}
#[must_use]
pub fn name(&self) -> &'static str {
match self {
Self::None => "none",
Self::Raised => "raised",
Self::Depressed => "depressed",
Self::Uniform => "uniform",
Self::LeftDropShadow => "left_drop_shadow",
Self::RightDropShadow => "right_drop_shadow",
}
}
}
dvb_common::impl_spec_display!(EdgeType);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub enum PenSize {
Small,
#[default]
Standard,
Large,
}
impl PenSize {
#[must_use]
pub fn from_bits(v: u8) -> Self {
match v & 0x03 {
0 => Self::Small,
2 => Self::Large,
_ => Self::Standard,
}
}
#[must_use]
pub fn name(&self) -> &'static str {
match self {
Self::Small => "small",
Self::Standard => "standard",
Self::Large => "large",
}
}
}
dvb_common::impl_spec_display!(PenSize);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub enum PenOffset {
Subscript,
#[default]
Normal,
Superscript,
}
impl PenOffset {
#[must_use]
pub fn from_bits(v: u8) -> Self {
match v & 0x03 {
0 => Self::Subscript,
2 => Self::Superscript,
_ => Self::Normal,
}
}
#[must_use]
pub fn name(&self) -> &'static str {
match self {
Self::Subscript => "subscript",
Self::Normal => "normal",
Self::Superscript => "superscript",
}
}
}
dvb_common::impl_spec_display!(PenOffset);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub enum FontStyle {
#[default]
Default,
MonospacedSerif,
ProportionalSerif,
MonospacedSansSerif,
ProportionalSansSerif,
Casual,
Cursive,
SmallCapitals,
}
impl FontStyle {
#[must_use]
pub fn from_bits(v: u8) -> Self {
match v & 0x07 {
0 => Self::Default,
1 => Self::MonospacedSerif,
2 => Self::ProportionalSerif,
3 => Self::MonospacedSansSerif,
4 => Self::ProportionalSansSerif,
5 => Self::Casual,
6 => Self::Cursive,
_ => Self::SmallCapitals,
}
}
#[must_use]
pub fn name(&self) -> &'static str {
match self {
Self::Default => "default",
Self::MonospacedSerif => "monospaced_serif",
Self::ProportionalSerif => "proportional_serif",
Self::MonospacedSansSerif => "monospaced_sans_serif",
Self::ProportionalSansSerif => "proportional_sans_serif",
Self::Casual => "casual",
Self::Cursive => "cursive",
Self::SmallCapitals => "small_capitals",
}
}
}
dvb_common::impl_spec_display!(FontStyle);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub enum Justify {
#[default]
Left,
Right,
Center,
Full,
}
impl Justify {
#[must_use]
pub fn from_bits(v: u8) -> Self {
match v & 0x03 {
0 => Self::Left,
1 => Self::Right,
2 => Self::Center,
_ => Self::Full,
}
}
#[must_use]
pub fn name(&self) -> &'static str {
match self {
Self::Left => "left",
Self::Right => "right",
Self::Center => "center",
Self::Full => "full",
}
}
}
dvb_common::impl_spec_display!(Justify);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub enum PrintDirection {
#[default]
LeftToRight,
RightToLeft,
TopToBottom,
BottomToTop,
}
impl PrintDirection {
#[must_use]
pub fn from_bits(v: u8) -> Self {
match v & 0x03 {
0 => Self::LeftToRight,
1 => Self::RightToLeft,
2 => Self::TopToBottom,
_ => Self::BottomToTop,
}
}
#[must_use]
pub fn name(&self) -> &'static str {
match self {
Self::LeftToRight => "left_to_right",
Self::RightToLeft => "right_to_left",
Self::TopToBottom => "top_to_bottom",
Self::BottomToTop => "bottom_to_top",
}
}
}
dvb_common::impl_spec_display!(PrintDirection);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub enum ScrollDirection {
LeftToRight,
RightToLeft,
TopToBottom,
#[default]
BottomToTop,
}
impl ScrollDirection {
#[must_use]
pub fn from_bits(v: u8) -> Self {
match v & 0x03 {
0 => Self::LeftToRight,
1 => Self::RightToLeft,
2 => Self::TopToBottom,
_ => Self::BottomToTop,
}
}
#[must_use]
pub fn name(&self) -> &'static str {
match self {
Self::LeftToRight => "left_to_right",
Self::RightToLeft => "right_to_left",
Self::TopToBottom => "top_to_bottom",
Self::BottomToTop => "bottom_to_top",
}
}
}
dvb_common::impl_spec_display!(ScrollDirection);
#[cfg(test)]
mod tests {
use super::*;
use alloc::string::ToString;
#[test]
fn color_8_color_mapping() {
assert_eq!(Color::new(1, 2, 3).to_8_color(), Color::new(0, 2, 2));
assert_eq!(Color::new(3, 3, 3).to_8_color(), Color::WHITE);
assert_eq!(Color::new(1, 1, 1).to_8_color(), Color::BLACK);
}
#[test]
fn opacity_bits() {
assert_eq!(Opacity::from_bits(0), Opacity::Solid);
assert_eq!(Opacity::from_bits(3), Opacity::Transparent);
assert_eq!(Opacity::Translucent.to_string(), "translucent");
}
#[test]
fn edge_bits() {
assert_eq!(EdgeType::from_bits(5), EdgeType::RightDropShadow);
assert_eq!(EdgeType::from_bits(7), EdgeType::None);
}
#[test]
fn font_bits() {
assert_eq!(FontStyle::from_bits(7), FontStyle::SmallCapitals);
assert_eq!(FontStyle::from_bits(1).to_string(), "monospaced_serif");
}
}