parent
2738969f29
commit
a86dfd1a11
|
@ -30,6 +30,52 @@ use term::{Term, SizeInfo};
|
||||||
|
|
||||||
use window::{self, Size, Pixels, Window, SetInnerSize};
|
use window::{self, Size, Pixels, Window, SetInnerSize};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
/// Error with window management
|
||||||
|
Window(window::Error),
|
||||||
|
|
||||||
|
/// Error dealing with fonts
|
||||||
|
Font(font::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::std::error::Error for Error {
|
||||||
|
fn cause(&self) -> Option<&::std::error::Error> {
|
||||||
|
match *self {
|
||||||
|
Error::Window(ref err) => Some(err),
|
||||||
|
Error::Font(ref err) => Some(err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn description(&self) -> &str {
|
||||||
|
match *self {
|
||||||
|
Error::Window(ref err) => err.description(),
|
||||||
|
Error::Font(ref err) => err.description(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::std::fmt::Display for Error {
|
||||||
|
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||||
|
match *self {
|
||||||
|
Error::Window(ref err) => err.fmt(f),
|
||||||
|
Error::Font(ref err) => err.fmt(f),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<window::Error> for Error {
|
||||||
|
fn from(val: window::Error) -> Error {
|
||||||
|
Error::Window(val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<font::Error> for Error {
|
||||||
|
fn from(val: font::Error) -> Error {
|
||||||
|
Error::Font(val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The display wraps a window, font rasterizer, and GPU renderer
|
/// The display wraps a window, font rasterizer, and GPU renderer
|
||||||
pub struct Display {
|
pub struct Display {
|
||||||
window: Window,
|
window: Window,
|
||||||
|
@ -74,26 +120,23 @@ impl Display {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
options: &cli::Options,
|
options: &cli::Options,
|
||||||
) -> Result<Display, window::Error> {
|
) -> Result<Display, Error> {
|
||||||
// Extract some properties from config
|
// Extract some properties from config
|
||||||
let font = config.font();
|
let font = config.font();
|
||||||
let dpi = config.dpi();
|
let dpi = config.dpi();
|
||||||
let render_timer = config.render_timer();
|
let render_timer = config.render_timer();
|
||||||
|
|
||||||
// Create the window where Alacritty will be displayed
|
// Create the window where Alacritty will be displayed
|
||||||
let mut window = match Window::new() {
|
let mut window = Window::new()?;
|
||||||
Ok(window) => window,
|
|
||||||
Err(err) => die!("{}", err)
|
|
||||||
};
|
|
||||||
|
|
||||||
// get window properties for initializing the other subsytems
|
// get window properties for initializing the other subsytems
|
||||||
let size = window.inner_size_pixels().unwrap();
|
let size = window.inner_size_pixels()
|
||||||
|
.expect("glutin returns window size");
|
||||||
let dpr = window.hidpi_factor();
|
let dpr = window.hidpi_factor();
|
||||||
|
|
||||||
println!("device_pixel_ratio: {}", dpr);
|
println!("device_pixel_ratio: {}", dpr);
|
||||||
|
|
||||||
// TODO ERROR HANDLING
|
let rasterizer = font::Rasterizer::new(dpi.x(), dpi.y(), dpr)?;
|
||||||
let rasterizer = font::Rasterizer::new(dpi.x(), dpi.y(), dpr).unwrap();
|
|
||||||
|
|
||||||
// Create renderer
|
// Create renderer
|
||||||
let mut renderer = QuadRenderer::new(config, size);
|
let mut renderer = QuadRenderer::new(config, size);
|
||||||
|
@ -105,7 +148,7 @@ impl Display {
|
||||||
|
|
||||||
let cache = renderer.with_loader(|mut api| {
|
let cache = renderer.with_loader(|mut api| {
|
||||||
GlyphCache::new(rasterizer, config, &mut api)
|
GlyphCache::new(rasterizer, config, &mut api)
|
||||||
});
|
})?;
|
||||||
|
|
||||||
let stop = init_start.elapsed();
|
let stop = init_start.elapsed();
|
||||||
let stop_f = stop.as_secs() as f64 + stop.subsec_nanos() as f64 / 1_000_000_000f64;
|
let stop_f = stop.as_secs() as f64 + stop.subsec_nanos() as f64 / 1_000_000_000f64;
|
||||||
|
@ -247,8 +290,10 @@ impl Display {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unlock the terminal mutex
|
// Unlock the terminal mutex; following call to swap_buffers() may block
|
||||||
drop(terminal);
|
drop(terminal);
|
||||||
self.window.swap_buffers().unwrap();
|
self.window
|
||||||
|
.swap_buffers()
|
||||||
|
.expect("swap buffers");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
10
src/main.rs
10
src/main.rs
|
@ -52,12 +52,20 @@ fn main() {
|
||||||
|
|
||||||
// Run alacritty
|
// Run alacritty
|
||||||
if let Err(err) = run(config, options) {
|
if let Err(err) = run(config, options) {
|
||||||
die!("{}", err);
|
die!("Alacritty encountered an unrecoverable error:\n\n\t{}\n", Red(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Goodbye");
|
println!("Goodbye");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
struct Red<T>(T);
|
||||||
|
impl<T: fmt::Display> fmt::Display for Red<T> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "\x1b[31m{}\x1b[0m", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Run Alacritty
|
/// Run Alacritty
|
||||||
///
|
///
|
||||||
/// Creates a window, the terminal state, pty, I/O event loop, input processor,
|
/// Creates a window, the terminal state, pty, I/O event loop, input processor,
|
||||||
|
|
|
@ -119,7 +119,11 @@ pub struct GlyphCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GlyphCache {
|
impl GlyphCache {
|
||||||
pub fn new<L>(mut rasterizer: Rasterizer, config: &Config, loader: &mut L) -> GlyphCache
|
pub fn new<L>(
|
||||||
|
mut rasterizer: Rasterizer,
|
||||||
|
config: &Config,
|
||||||
|
loader: &mut L
|
||||||
|
) -> Result<GlyphCache, font::Error>
|
||||||
where L: LoadGlyph
|
where L: LoadGlyph
|
||||||
{
|
{
|
||||||
let font = config.font();
|
let font = config.font();
|
||||||
|
@ -128,8 +132,7 @@ impl GlyphCache {
|
||||||
// Load regular font
|
// Load regular font
|
||||||
let regular_desc = FontDesc::new(font.family(), font.style());
|
let regular_desc = FontDesc::new(font.family(), font.style());
|
||||||
let regular = rasterizer
|
let regular = rasterizer
|
||||||
.load_font(®ular_desc, size)
|
.load_font(®ular_desc, size)?;
|
||||||
.expect("regular font load ok");
|
|
||||||
|
|
||||||
// Load bold font
|
// Load bold font
|
||||||
let bold_style = font.bold_style().unwrap_or("Bold");
|
let bold_style = font.bold_style().unwrap_or("Bold");
|
||||||
|
@ -177,21 +180,22 @@ impl GlyphCache {
|
||||||
load_glyphs_for_font!(bold);
|
load_glyphs_for_font!(bold);
|
||||||
load_glyphs_for_font!(italic);
|
load_glyphs_for_font!(italic);
|
||||||
|
|
||||||
cache
|
Ok(cache)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn font_metrics(&self) -> font::Metrics {
|
pub fn font_metrics(&self) -> font::Metrics {
|
||||||
// TODO ERROR HANDLING
|
self.rasterizer
|
||||||
self.rasterizer.metrics(self.font_key, self.font_size).unwrap()
|
.metrics(self.font_key, self.font_size)
|
||||||
|
.expect("metrics load since font is loaded at glyph cache creation")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_and_cache_glyph<L>(&mut self, glyph_key: GlyphKey, loader: &mut L)
|
fn load_and_cache_glyph<L>(&mut self, glyph_key: GlyphKey, loader: &mut L)
|
||||||
where L: LoadGlyph
|
where L: LoadGlyph
|
||||||
{
|
{
|
||||||
// TODO ERROR HANDLING
|
if let Ok(rasterized) = self.rasterizer.get_glyph(&glyph_key) {
|
||||||
let rasterized = self.rasterizer.get_glyph(&glyph_key).unwrap();
|
let glyph = loader.load_glyph(&rasterized);
|
||||||
let glyph = loader.load_glyph(&rasterized);
|
self.cache.insert(glyph_key, glyph);
|
||||||
self.cache.insert(glyph_key, glyph);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get<L>(&mut self, glyph_key: &GlyphKey, loader: &mut L) -> Option<&Glyph>
|
pub fn get<L>(&mut self, glyph_key: &GlyphKey, loader: &mut L) -> Option<&Glyph>
|
||||||
|
@ -783,7 +787,8 @@ impl<'a> LoadGlyph for LoaderApi<'a> {
|
||||||
///
|
///
|
||||||
/// If the current atlas is full, a new one will be created.
|
/// If the current atlas is full, a new one will be created.
|
||||||
fn load_glyph(&mut self, rasterized: &RasterizedGlyph) -> Glyph {
|
fn load_glyph(&mut self, rasterized: &RasterizedGlyph) -> Glyph {
|
||||||
// At least one atlas is guaranteed to be in the `self.atlas` list; thus the unwrap.
|
// At least one atlas is guaranteed to be in the `self.atlas` list; thus
|
||||||
|
// the unwrap should always be ok.
|
||||||
match self.atlas.last_mut().unwrap().insert(rasterized, &mut self.active_tex) {
|
match self.atlas.last_mut().unwrap().insert(rasterized, &mut self.active_tex) {
|
||||||
Ok(glyph) => glyph,
|
Ok(glyph) => glyph,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
|
@ -801,7 +806,8 @@ impl<'a> LoadGlyph for RenderApi<'a> {
|
||||||
///
|
///
|
||||||
/// If the current atlas is full, a new one will be created.
|
/// If the current atlas is full, a new one will be created.
|
||||||
fn load_glyph(&mut self, rasterized: &RasterizedGlyph) -> Glyph {
|
fn load_glyph(&mut self, rasterized: &RasterizedGlyph) -> Glyph {
|
||||||
// At least one atlas is guaranteed to be in the `self.atlas` list; thus the unwrap.
|
// At least one atlas is guaranteed to be in the `self.atlas` list; thus
|
||||||
|
// the unwrap.
|
||||||
match self.atlas.last_mut().unwrap().insert(rasterized, &mut self.active_tex) {
|
match self.atlas.last_mut().unwrap().insert(rasterized, &mut self.active_tex) {
|
||||||
Ok(glyph) => glyph,
|
Ok(glyph) => glyph,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
|
|
Loading…
Reference in New Issue