mirror of
https://github.com/wez/wezterm.git
synced 2024-11-26 16:34:23 +03:00
add terminal cell and colors
This commit is contained in:
parent
36a884b872
commit
641e85650d
@ -9,6 +9,7 @@ freetype = "0.3.0"
|
||||
harfbuzz-sys = "0.1.15"
|
||||
resize = "0.3.0"
|
||||
servo-fontconfig = "0.4.0"
|
||||
unicode-segmentation = "1.2.0"
|
||||
unicode-width = "0.1.4"
|
||||
vte = "0.3.2"
|
||||
xcb = "0.8.1"
|
||||
|
@ -1,6 +1,7 @@
|
||||
#[macro_use]
|
||||
extern crate failure;
|
||||
extern crate unicode_width;
|
||||
extern crate unicode_segmentation;
|
||||
extern crate harfbuzz_sys;
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
extern crate fontconfig; // from servo-fontconfig
|
||||
@ -22,6 +23,8 @@ mod xgfx;
|
||||
mod font;
|
||||
use font::{Font, FontPattern, ftwrap};
|
||||
|
||||
mod term;
|
||||
|
||||
struct TerminalWindow<'a> {
|
||||
window: xgfx::Window<'a>,
|
||||
conn: &'a xcb::Connection,
|
||||
@ -127,12 +130,14 @@ impl<'a> TerminalWindow<'a> {
|
||||
self.need_paint = false;
|
||||
|
||||
let message = "x_advance != foo->bar(); ❤ 😍🤢";
|
||||
let cells = term::Line::from_text(message);
|
||||
println!("cells {:?}", cells);
|
||||
|
||||
self.buffer_image.clear(xgfx::Color::rgb(0, 0, 0));
|
||||
|
||||
let mut x = 0 as isize;
|
||||
let mut y = self.cell_height.ceil() as isize;
|
||||
let glyph_info = self.font.shape(0, message)?;
|
||||
let glyph_info = self.font.shape(0, &cells.as_str())?;
|
||||
for info in glyph_info {
|
||||
let has_color = self.font.has_color(info.font_idx)?;
|
||||
let ft_glyph = self.font.load_glyph(info.font_idx, info.glyph_pos)?;
|
||||
|
144
src/term/color.rs
Normal file
144
src/term/color.rs
Normal file
@ -0,0 +1,144 @@
|
||||
//! Colors for attributes
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[repr(u8)]
|
||||
/// These correspond to the classic ANSI color indices and are
|
||||
/// used for convenience/readability here in the code
|
||||
pub enum AnsiColor {
|
||||
Black = 0,
|
||||
Maroon,
|
||||
Green,
|
||||
Olive,
|
||||
Navy,
|
||||
Purple,
|
||||
Teal,
|
||||
Silver,
|
||||
Grey,
|
||||
Red,
|
||||
Lime,
|
||||
Yellow,
|
||||
Blue,
|
||||
Fuschia,
|
||||
Aqua,
|
||||
White,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct RgbColor {
|
||||
pub red: u8,
|
||||
pub green: u8,
|
||||
pub blue: u8,
|
||||
}
|
||||
|
||||
impl RgbColor {}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ColorAttribute {
|
||||
Foreground,
|
||||
Background,
|
||||
PaletteIndex(u8),
|
||||
Rgb(RgbColor),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ColorPalette {
|
||||
colors: [RgbColor; 256],
|
||||
foreground: RgbColor,
|
||||
background: RgbColor,
|
||||
}
|
||||
|
||||
impl ColorPalette {
|
||||
pub fn resolve(&self, color: &ColorAttribute) -> RgbColor {
|
||||
match color {
|
||||
&ColorAttribute::Foreground => self.foreground,
|
||||
&ColorAttribute::Background => self.background,
|
||||
&ColorAttribute::PaletteIndex(idx) => self.colors[idx as usize],
|
||||
&ColorAttribute::Rgb(color) => color,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ColorPalette {
|
||||
/// Construct a default color palette
|
||||
fn default() -> ColorPalette {
|
||||
let mut colors = [RgbColor::default(); 256];
|
||||
|
||||
// The XTerm ansi color set
|
||||
static ANSI: [RgbColor; 16] = [
|
||||
RgbColor{ red: 0x00, green: 0x00, blue: 0x00}, // Black
|
||||
RgbColor{ red: 0x80, green: 0x00, blue: 0x00}, // Maroon
|
||||
RgbColor{ red: 0x00, green: 0x80, blue: 0x00}, // Green
|
||||
RgbColor{ red: 0x80, green: 0x80, blue: 0x00}, // Olive
|
||||
RgbColor{ red: 0x00, green: 0x00, blue: 0x80}, // Navy
|
||||
RgbColor{ red: 0x80, green: 0x00, blue: 0x80}, // Purple
|
||||
RgbColor{ red: 0x00, green: 0x80, blue: 0x80}, // Teal
|
||||
RgbColor{ red: 0xc0, green: 0xc0, blue: 0xc0}, // Silver
|
||||
RgbColor{ red: 0x80, green: 0x80, blue: 0x80}, // Grey
|
||||
RgbColor{ red: 0xff, green: 0x00, blue: 0x00}, // Red
|
||||
RgbColor{ red: 0x00, green: 0xff, blue: 0x00}, // Lime
|
||||
RgbColor{ red: 0xff, green: 0xff, blue: 0x00}, // Yellow
|
||||
RgbColor{ red: 0x00, green: 0x00, blue: 0xff}, // Blue
|
||||
RgbColor{ red: 0xff, green: 0x00, blue: 0xff}, // Fuschia
|
||||
RgbColor{ red: 0x00, green: 0xff, blue: 0xff}, // Aqua
|
||||
RgbColor{ red: 0xff, green: 0xff, blue: 0xff}, // White
|
||||
];
|
||||
|
||||
colors[0..16].copy_from_slice(&ANSI);
|
||||
|
||||
// 216 color cube
|
||||
static RAMP6: [u8; 6] = [0x00, 0x33, 0x66, 0x99, 0xCC, 0xFF];
|
||||
for idx in 0..216 {
|
||||
let red = RAMP6[idx % 6];
|
||||
let green = RAMP6[idx / 6 % 6];
|
||||
let blue = RAMP6[idx / 6 / 6 % 6];
|
||||
|
||||
colors[16 + idx] = RgbColor { red, green, blue };
|
||||
}
|
||||
|
||||
// 24 grey scales
|
||||
static GREYS: [u8; 24] = [
|
||||
0x08,
|
||||
0x12,
|
||||
0x1c,
|
||||
0x26,
|
||||
0x30,
|
||||
0x3a,
|
||||
0x44,
|
||||
0x4e,
|
||||
0x58,
|
||||
0x62,
|
||||
0x6c,
|
||||
0x76,
|
||||
0x80,
|
||||
0x8a,
|
||||
0x94,
|
||||
0x9e,
|
||||
0xa8,
|
||||
0xb2, // Grey70
|
||||
0xbc,
|
||||
0xc6,
|
||||
0xd0,
|
||||
0xda,
|
||||
0xe4,
|
||||
0xee,
|
||||
];
|
||||
|
||||
for idx in 0..24 {
|
||||
let grey = GREYS[idx];
|
||||
colors[232 + idx] = RgbColor {
|
||||
red: grey,
|
||||
green: grey,
|
||||
blue: grey,
|
||||
};
|
||||
}
|
||||
|
||||
let foreground = colors[249]; // Grey70
|
||||
let background = colors[AnsiColor::Black as usize];
|
||||
|
||||
ColorPalette {
|
||||
colors,
|
||||
foreground,
|
||||
background,
|
||||
}
|
||||
}
|
||||
}
|
54
src/term/mod.rs
Normal file
54
src/term/mod.rs
Normal file
@ -0,0 +1,54 @@
|
||||
//! Terminal model
|
||||
|
||||
use std;
|
||||
use unicode_segmentation;
|
||||
|
||||
pub mod color;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Cell {
|
||||
chars: [u8; 8],
|
||||
}
|
||||
|
||||
impl Cell {
|
||||
#[inline]
|
||||
pub fn chars(&self) -> &[u8] {
|
||||
if let Some(len) = self.chars.iter().position(|&c| c == 0) {
|
||||
&self.chars[0..len]
|
||||
} else {
|
||||
&self.chars
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Line {
|
||||
cells: Vec<Cell>,
|
||||
}
|
||||
|
||||
impl Line {
|
||||
/// Recompose line into the corresponding utf8 string.
|
||||
/// In the future, we'll want to decompose into clusters of Cells that share
|
||||
/// the same render attributes
|
||||
pub fn as_str(&self) -> String {
|
||||
let mut s = String::new();
|
||||
for c in self.cells.iter() {
|
||||
s.push_str(std::str::from_utf8(c.chars()).unwrap_or("?"));
|
||||
}
|
||||
s
|
||||
}
|
||||
|
||||
pub fn from_text(s: &str) -> Line {
|
||||
let mut cells = Vec::new();
|
||||
|
||||
for (_, sub) in unicode_segmentation::UnicodeSegmentation::grapheme_indices(s, true) {
|
||||
let mut chars = [0u8; 8];
|
||||
let len = sub.len().min(8);
|
||||
chars[0..len].copy_from_slice(sub.as_bytes());
|
||||
|
||||
cells.push(Cell { chars });
|
||||
}
|
||||
|
||||
Line { cells }
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user