Make rusttype optional for vesad
This commit is contained in:
parent
f804ad52e4
commit
ca97b3d2b3
4 changed files with 544 additions and 51 deletions
|
@ -1,39 +1,64 @@
|
|||
#[cfg(feature="rusttype")]
|
||||
extern crate rusttype;
|
||||
|
||||
use std::cmp;
|
||||
|
||||
use primitive::{fast_set32, fast_set64, fast_copy64};
|
||||
use primitive::{fast_set32, fast_set64, fast_copy, fast_copy64};
|
||||
|
||||
#[cfg(feature="rusttype")]
|
||||
use self::rusttype::{Font, FontCollection, Scale, point};
|
||||
|
||||
static FONT: &'static [u8] = include_bytes!("../../../res/fonts/DejaVuSansMono.ttf");
|
||||
static FONT_BOLD: &'static [u8] = include_bytes!("../../../res/fonts/DejaVuSansMono-Bold.ttf");
|
||||
static FONT_BOLD_ITALIC: &'static [u8] = include_bytes!("../../../res/fonts/DejaVuSansMono-BoldOblique.ttf");
|
||||
static FONT_ITALIC: &'static [u8] = include_bytes!("../../../res/fonts/DejaVuSansMono-Oblique.ttf");
|
||||
#[cfg(not(feature="rusttype"))]
|
||||
static FONT: &'static [u8] = include_bytes!("../../../res/fonts/unifont.font");
|
||||
|
||||
/// A display
|
||||
#[cfg(not(feature="rusttype"))]
|
||||
pub struct Display {
|
||||
pub width: usize,
|
||||
pub height: usize,
|
||||
pub onscreen: &'static mut [u32],
|
||||
pub offscreen: &'static mut [u32]
|
||||
}
|
||||
|
||||
/// A display
|
||||
#[cfg(feature="rusttype")]
|
||||
pub struct Display {
|
||||
pub width: usize,
|
||||
pub height: usize,
|
||||
pub onscreen: &'static mut [u32],
|
||||
pub offscreen: &'static mut [u32],
|
||||
#[cfg(feature="rusttype")]
|
||||
pub font: Font<'static>,
|
||||
#[cfg(feature="rusttype")]
|
||||
pub font_bold: Font<'static>,
|
||||
#[cfg(feature="rusttype")]
|
||||
pub font_bold_italic: Font<'static>,
|
||||
#[cfg(feature="rusttype")]
|
||||
pub font_italic: Font<'static>
|
||||
}
|
||||
|
||||
impl Display {
|
||||
#[cfg(not(feature="rusttype"))]
|
||||
pub fn new(width: usize, height: usize, onscreen: &'static mut [u32], offscreen: &'static mut [u32]) -> Display {
|
||||
Display {
|
||||
width: width,
|
||||
height: height,
|
||||
onscreen: onscreen,
|
||||
offscreen: offscreen
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="rusttype")]
|
||||
pub fn new(width: usize, height: usize, onscreen: &'static mut [u32], offscreen: &'static mut [u32]) -> Display {
|
||||
Display {
|
||||
width: width,
|
||||
height: height,
|
||||
onscreen: onscreen,
|
||||
offscreen: offscreen,
|
||||
font: FontCollection::from_bytes(FONT).into_font().unwrap(),
|
||||
font_bold: FontCollection::from_bytes(FONT_BOLD).into_font().unwrap(),
|
||||
font_bold_italic: FontCollection::from_bytes(FONT_BOLD_ITALIC).into_font().unwrap(),
|
||||
font_italic: FontCollection::from_bytes(FONT_ITALIC).into_font().unwrap()
|
||||
font: FontCollection::from_bytes(include_bytes!("../../../res/fonts/DejaVuSansMono.ttf")).into_font().unwrap(),
|
||||
font_bold: FontCollection::from_bytes(include_bytes!("../../../res/fonts/DejaVuSansMono-Bold.ttf")).into_font().unwrap(),
|
||||
font_bold_italic: FontCollection::from_bytes(include_bytes!("../../../res/fonts/DejaVuSansMono-BoldOblique.ttf")).into_font().unwrap(),
|
||||
font_italic: FontCollection::from_bytes(include_bytes!("../../../res/fonts/DejaVuSansMono-Oblique.ttf")).into_font().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,32 +71,49 @@ impl Display {
|
|||
let len = cmp::min(self.width, x + w) - start_x;
|
||||
|
||||
let mut offscreen_ptr = self.offscreen.as_mut_ptr() as usize;
|
||||
let mut onscreen_ptr = self.onscreen.as_mut_ptr() as usize;
|
||||
|
||||
let stride = self.width * 4;
|
||||
|
||||
let offset = y * stride + start_x * 4;
|
||||
offscreen_ptr += offset;
|
||||
onscreen_ptr += offset;
|
||||
|
||||
let mut rows = end_y - start_y;
|
||||
while rows > 0 {
|
||||
unsafe {
|
||||
fast_set32(offscreen_ptr as *mut u32, color, len);
|
||||
fast_set32(onscreen_ptr as *mut u32, color, len);
|
||||
}
|
||||
offscreen_ptr += stride;
|
||||
onscreen_ptr += stride;
|
||||
rows -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw a character
|
||||
#[cfg(not(feature="rusttype"))]
|
||||
pub fn char(&mut self, x: usize, y: usize, character: char, color: u32, _bold: bool, _italic: bool) {
|
||||
if x + 8 <= self.width && y + 16 <= self.height {
|
||||
let mut dst = unsafe { self.offscreen.as_mut_ptr().offset((y * self.width + x) as isize) };
|
||||
|
||||
let font_i = 16 * (character as usize);
|
||||
if font_i + 16 <= FONT.len() {
|
||||
for row in 0..16 {
|
||||
let row_data = FONT[font_i + row];
|
||||
for col in 0..8 {
|
||||
if (row_data >> (7 - col)) & 1 == 1 {
|
||||
unsafe { *dst.offset(col) = color; }
|
||||
}
|
||||
}
|
||||
dst = unsafe { dst.offset(self.width as isize) };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw a character
|
||||
#[cfg(feature="rusttype")]
|
||||
pub fn char(&mut self, x: usize, y: usize, character: char, color: u32, bold: bool, italic: bool) {
|
||||
let width = self.width;
|
||||
let height = self.height;
|
||||
let offscreen = self.offscreen.as_mut_ptr();
|
||||
let onscreen = self.onscreen.as_mut_ptr();
|
||||
let offscreen = self.offscreen.as_mut_ptr() as usize;
|
||||
|
||||
let font = if bold && italic {
|
||||
&self.font_bold_italic
|
||||
|
@ -100,9 +142,9 @@ impl Display {
|
|||
let f_g = (((color >> 8) & 0xFF) * f_a)/255;
|
||||
let f_b = ((color & 0xFF) * f_a)/255;
|
||||
|
||||
let index = (off_y * width + off_x) as isize;
|
||||
let offscreen_ptr = (offscreen + (off_y * width + off_x) * 4) as *mut u32;
|
||||
|
||||
let bg = unsafe { *offscreen.offset(index) };
|
||||
let bg = unsafe { *offscreen_ptr };
|
||||
|
||||
let b_a = 255 - f_a;
|
||||
let b_r = (((bg >> 16) & 0xFF) * b_a)/255;
|
||||
|
@ -111,8 +153,7 @@ impl Display {
|
|||
|
||||
let c = ((f_r + b_r) << 16) | ((f_g + b_g) << 8) | (f_b + b_b);
|
||||
|
||||
unsafe { *offscreen.offset(index) = c; }
|
||||
unsafe { *onscreen.offset(index) = c; }
|
||||
unsafe { *offscreen_ptr = c; }
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -133,9 +174,35 @@ impl Display {
|
|||
let data_ptr = self.offscreen.as_mut_ptr() as *mut u64;
|
||||
fast_copy64(data_ptr, data_ptr.offset(off1 as isize), off2);
|
||||
fast_set64(data_ptr.offset(off2 as isize), data, off1);
|
||||
|
||||
fast_copy64(self.onscreen.as_mut_ptr() as *mut u64, data_ptr, off1 + off2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Copy from offscreen to onscreen
|
||||
pub fn sync(&mut self, x: usize, y: usize, w: usize, h: usize) {
|
||||
let start_y = cmp::min(self.height - 1, y);
|
||||
let end_y = cmp::min(self.height, y + h);
|
||||
|
||||
let start_x = cmp::min(self.width - 1, x);
|
||||
let len = (cmp::min(self.width, x + w) - start_x) * 4;
|
||||
|
||||
let mut offscreen_ptr = self.offscreen.as_mut_ptr() as usize;
|
||||
let mut onscreen_ptr = self.onscreen.as_mut_ptr() as usize;
|
||||
|
||||
let stride = self.width * 4;
|
||||
|
||||
let offset = y * stride + start_x * 4;
|
||||
offscreen_ptr += offset;
|
||||
onscreen_ptr += offset;
|
||||
|
||||
let mut rows = end_y - start_y;
|
||||
while rows > 0 {
|
||||
unsafe {
|
||||
fast_copy(onscreen_ptr as *mut u8, offscreen_ptr as *const u8, len);
|
||||
}
|
||||
offscreen_ptr += stride;
|
||||
onscreen_ptr += stride;
|
||||
rows -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ extern crate ransid;
|
|||
extern crate syscall;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::collections::VecDeque;
|
||||
use std::collections::{BTreeSet, VecDeque};
|
||||
use std::fs::File;
|
||||
use std::io::{Read, Write};
|
||||
use std::{slice, thread};
|
||||
|
@ -26,11 +26,49 @@ pub mod primitive;
|
|||
struct DisplayScheme {
|
||||
console: RefCell<Console>,
|
||||
display: RefCell<Display>,
|
||||
changed: RefCell<BTreeSet<usize>>,
|
||||
input: RefCell<VecDeque<u8>>,
|
||||
cooked: RefCell<VecDeque<u8>>,
|
||||
requested: RefCell<usize>
|
||||
}
|
||||
|
||||
impl DisplayScheme {
|
||||
fn event(&self, event: Event) {
|
||||
let mut display = self.display.borrow_mut();
|
||||
let mut changed = self.changed.borrow_mut();
|
||||
|
||||
match event {
|
||||
Event::Char { x, y, c, color, bold, .. } => {
|
||||
display.char(x * 8, y * 16, c, color.data, bold, false);
|
||||
changed.insert(y);
|
||||
},
|
||||
Event::Rect { x, y, w, h, color } => {
|
||||
display.rect(x * 8, y * 16, w * 8, h * 16, color.data);
|
||||
for y2 in y..y + h {
|
||||
changed.insert(y2);
|
||||
}
|
||||
},
|
||||
Event::Scroll { rows, color } => {
|
||||
display.scroll(rows * 16, color.data);
|
||||
for y in 0..display.height/16 {
|
||||
changed.insert(y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn sync(&self) {
|
||||
let mut display = self.display.borrow_mut();
|
||||
let mut changed = self.changed.borrow_mut();
|
||||
|
||||
let width = display.width;
|
||||
for change in changed.iter() {
|
||||
display.sync(0, change * 16, width, 16);
|
||||
}
|
||||
changed.clear();
|
||||
}
|
||||
}
|
||||
|
||||
impl Scheme for DisplayScheme {
|
||||
fn open(&self, path: &[u8], _flags: usize) -> Result<usize> {
|
||||
if path == b"input" {
|
||||
|
@ -50,7 +88,32 @@ impl Scheme for DisplayScheme {
|
|||
Ok(0)
|
||||
}
|
||||
|
||||
fn fsync(&self, _id: usize) -> Result<usize> {
|
||||
fn fpath(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
let path_str = if id == 1 {
|
||||
format!("display:input")
|
||||
} else {
|
||||
let console = self.console.borrow();
|
||||
format!("display:{}/{}", console.w, console.h)
|
||||
};
|
||||
|
||||
let path = path_str.as_bytes();
|
||||
|
||||
let mut i = 0;
|
||||
while i < buf.len() && i < path.len() {
|
||||
buf[i] = path[i];
|
||||
i += 1;
|
||||
}
|
||||
|
||||
Ok(i)
|
||||
}
|
||||
|
||||
fn fsync(&self, id: usize) -> Result<usize> {
|
||||
if id == 1 {
|
||||
|
||||
} else {
|
||||
self.sync();
|
||||
}
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
|
@ -74,7 +137,7 @@ impl Scheme for DisplayScheme {
|
|||
for &b in buf.iter() {
|
||||
match b {
|
||||
b'\x08' | b'\x7F' => {
|
||||
if let Some(c) = self.cooked.borrow_mut().pop_back() {
|
||||
if let Some(_c) = self.cooked.borrow_mut().pop_back() {
|
||||
self.write(0, b"\x08")?;
|
||||
}
|
||||
},
|
||||
|
@ -94,44 +157,35 @@ impl Scheme for DisplayScheme {
|
|||
}
|
||||
Ok(buf.len())
|
||||
} else {
|
||||
let mut display = self.display.borrow_mut();
|
||||
let mut console = self.console.borrow_mut();
|
||||
if console.cursor && console.x < console.w && console.y < console.h {
|
||||
display.rect(console.x * 8, console.y * 16, 8, 16, 0);
|
||||
self.event(Event::Rect {
|
||||
x: console.x,
|
||||
y: console.y,
|
||||
w: 1,
|
||||
h: 1,
|
||||
color: console.background
|
||||
});
|
||||
}
|
||||
console.write(buf, |event| {
|
||||
match event {
|
||||
Event::Char { x, y, c, color, bold, .. } => display.char(x * 8, y * 16, c, color.data, bold, false),
|
||||
Event::Rect { x, y, w, h, color } => display.rect(x * 8, y * 16, w * 8, h * 16, color.data),
|
||||
Event::Scroll { rows, color } => display.scroll(rows * 16, color.data)
|
||||
}
|
||||
self.event(event);
|
||||
});
|
||||
if console.cursor && console.x < console.w && console.y < console.h {
|
||||
display.rect(console.x * 8, console.y * 16, 8, 16, 0xFFFFFF);
|
||||
self.event(Event::Rect {
|
||||
x: console.x,
|
||||
y: console.y,
|
||||
w: 1,
|
||||
h: 1,
|
||||
color: console.foreground
|
||||
});
|
||||
}
|
||||
if ! console.raw_mode {
|
||||
self.sync();
|
||||
}
|
||||
Ok(buf.len())
|
||||
}
|
||||
}
|
||||
|
||||
fn fpath(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
let path_str = if id == 1 {
|
||||
format!("display:input")
|
||||
} else {
|
||||
let console = self.console.borrow();
|
||||
format!("display:{}/{}", console.w, console.h)
|
||||
};
|
||||
|
||||
let path = path_str.as_bytes();
|
||||
|
||||
let mut i = 0;
|
||||
while i < buf.len() && i < path.len() {
|
||||
buf[i] = path[i];
|
||||
i += 1;
|
||||
}
|
||||
|
||||
Ok(i)
|
||||
}
|
||||
|
||||
fn close(&self, _id: usize) -> Result<usize> {
|
||||
Ok(0)
|
||||
}
|
||||
|
@ -170,6 +224,7 @@ fn main() {
|
|||
unsafe { slice::from_raw_parts_mut(onscreen as *mut u32, size) },
|
||||
unsafe { slice::from_raw_parts_mut(offscreen as *mut u32, size) }
|
||||
)),
|
||||
changed: RefCell::new(BTreeSet::new()),
|
||||
input: RefCell::new(VecDeque::new()),
|
||||
cooked: RefCell::new(VecDeque::new()),
|
||||
requested: RefCell::new(0)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue