From df328c13903d5a0e595d27b14f79e2a61f66f8fc Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Wed, 27 Apr 2016 02:36:30 -0400 Subject: implement fgcolor and bgcolor for cells --- src/cell.rs | 31 ++++++++++++++++++++++++++++++- src/color.rs | 23 +++++++++++++++++++++++ src/lib.rs | 2 ++ src/types.rs | 1 + tests/basic.rs | 24 ++++++++++++++++++++++++ 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 src/color.rs diff --git a/src/cell.rs b/src/cell.rs index 7590e98..4c0d6fb 100644 --- a/src/cell.rs +++ b/src/cell.rs @@ -1,14 +1,23 @@ use libc; use std; +use color; use types; pub struct Cell(*mut types::CellImpl); +#[repr(C)] +struct CellAttrs { + fgcolor: types::ColorImpl, + bgcolor: types::ColorImpl, + attrs: libc::c_uchar, +} + #[repr(C)] struct CellPrefix { pub contents: [libc::c_char; 8], pub len: libc::size_t, + pub attrs: CellAttrs, } impl Cell { @@ -18,8 +27,10 @@ impl Cell { pub fn contents(&self) -> &str { let Cell(cell_impl) = *self; + let prefix: *mut CellPrefix = unsafe { + std::mem::transmute(cell_impl) + }; let contents: &[u8] = unsafe { - let prefix: *mut CellPrefix = std::mem::transmute(cell_impl); std::slice::from_raw_parts( &(*prefix).contents as *const i8 as *const u8, (*prefix).len @@ -27,4 +38,22 @@ impl Cell { }; std::str::from_utf8(contents).unwrap() } + + pub fn fgcolor(&self) -> color::Color { + let Cell(cell_impl) = *self; + let prefix: *mut CellPrefix = unsafe { + std::mem::transmute(cell_impl) + }; + let attrs = unsafe { &(*prefix).attrs }; + color::Color::new(&attrs.fgcolor) + } + + pub fn bgcolor(&self) -> color::Color { + let Cell(cell_impl) = *self; + let prefix: *mut CellPrefix = unsafe { + std::mem::transmute(cell_impl) + }; + let attrs = unsafe { &(*prefix).attrs }; + color::Color::new(&attrs.bgcolor) + } } diff --git a/src/color.rs b/src/color.rs new file mode 100644 index 0000000..52d9d61 --- /dev/null +++ b/src/color.rs @@ -0,0 +1,23 @@ +use std; + +use types; + +#[derive(Eq,PartialEq,Debug)] +pub enum Color { + ColorDefault, + ColorIdx(u8), + ColorRgb(u8, u8, u8), +} + +impl Color { + pub fn new(color_impl: &types::ColorImpl) -> Color { + let &types::ColorImpl(color_repr) = color_impl; + let bytes: [u8; 4] = unsafe { std::mem::transmute(color_repr) }; + match bytes[3] { + 0 => Color::ColorDefault, + 1 => Color::ColorIdx(bytes[0]), + 2 => Color::ColorRgb(bytes[0], bytes[1], bytes[2]), + _ => panic!("invalid color type"), + } + } +} diff --git a/src/lib.rs b/src/lib.rs index aa7d488..58d9b2c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,11 @@ extern crate libc; mod cell; +mod color; mod ffi; mod screen; mod types; pub use screen::Screen; pub use cell::Cell; +pub use color::Color; diff --git a/src/types.rs b/src/types.rs index fca7f97..6e82779 100644 --- a/src/types.rs +++ b/src/types.rs @@ -2,6 +2,7 @@ use libc; pub enum ScreenImpl {} pub enum CellImpl {} +pub struct ColorImpl(pub libc::uint32_t); #[repr(C)] pub struct Loc { diff --git a/tests/basic.rs b/tests/basic.rs index 4828ea9..7af33f0 100644 --- a/tests/basic.rs +++ b/tests/basic.rs @@ -43,4 +43,28 @@ mod tests { assert_eq!(screen.cell(0, 5).unwrap().contents(), "r"); assert_eq!(screen.cell(0, 6).unwrap().contents(), ""); } + + #[test] + fn cell_colors() { + let mut screen = vt100::Screen::new(24, 80); + let input = b"foo\x1b[31m\x1b[32mb\x1b[3;7;42ma\x1b[23mr"; + screen.process(input); + + assert_eq!( + screen.cell(0, 0).unwrap().fgcolor(), + vt100::Color::ColorDefault + ); + assert_eq!( + screen.cell(0, 3).unwrap().fgcolor(), + vt100::Color::ColorIdx(2) + ); + assert_eq!( + screen.cell(0, 4).unwrap().fgcolor(), + vt100::Color::ColorIdx(2) + ); + assert_eq!( + screen.cell(0, 4).unwrap().bgcolor(), + vt100::Color::ColorIdx(2) + ); + } } -- cgit v1.2.3