summaryrefslogtreecommitdiff
path: root/alacritty_terminal/src/renderer/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty_terminal/src/renderer/mod.rs')
-rw-r--r--alacritty_terminal/src/renderer/mod.rs122
1 files changed, 68 insertions, 54 deletions
diff --git a/alacritty_terminal/src/renderer/mod.rs b/alacritty_terminal/src/renderer/mod.rs
index 4aae8536..51c0d0f0 100644
--- a/alacritty_terminal/src/renderer/mod.rs
+++ b/alacritty_terminal/src/renderer/mod.rs
@@ -23,10 +23,10 @@ use std::time::Duration;
use fnv::FnvHasher;
use font::{self, FontDesc, FontKey, GlyphKey, Rasterize, RasterizedGlyph, Rasterizer};
-use glutin::dpi::PhysicalSize;
+use log::{error, info};
use notify::{watcher, DebouncedEvent, RecursiveMode, Watcher};
-use crate::config::{self, Config, Delta};
+use crate::config::{self, Config, Delta, Font, StartupMode};
use crate::cursor::{get_cursor_glyph, CursorKey};
use crate::gl;
use crate::gl::types::*;
@@ -34,7 +34,9 @@ use crate::index::{Column, Line};
use crate::renderer::rects::RenderRect;
use crate::term::cell::{self, Flags};
use crate::term::color::Rgb;
+use crate::term::SizeInfo;
use crate::term::{self, RenderableCell, RenderableCellContent};
+use crate::util;
pub mod rects;
@@ -284,12 +286,6 @@ impl GlyphCache {
FontDesc::new(desc.family.clone(), style)
}
- pub fn font_metrics(&self) -> font::Metrics {
- self.rasterizer
- .metrics(self.font_key, self.font_size)
- .expect("metrics load since font is loaded at glyph cache creation")
- }
-
pub fn get<'a, L>(&'a mut self, glyph_key: GlyphKey, loader: &mut L) -> &'a Glyph
where
L: LoadGlyph,
@@ -311,8 +307,7 @@ impl GlyphCache {
pub fn update_font_size<L: LoadGlyph>(
&mut self,
- font: &config::Font,
- size: font::Size,
+ font: config::Font,
dpr: f64,
loader: &mut L,
) -> Result<(), font::Error> {
@@ -325,12 +320,11 @@ impl GlyphCache {
self.rasterizer.update_dpr(dpr as f32);
// Recompute font keys
- let font = font.to_owned().with_size(size);
let (regular, bold, italic, bold_italic) =
Self::compute_font_keys(&font, &mut self.rasterizer)?;
self.rasterizer.get_glyph(GlyphKey { font_key: regular, c: 'm', size: font.size })?;
- let metrics = self.rasterizer.metrics(regular, size)?;
+ let metrics = self.rasterizer.metrics(regular, font.size)?;
info!("Font size changed to {:?} with DPR of {}", font.size, dpr);
@@ -349,13 +343,15 @@ impl GlyphCache {
Ok(())
}
- // Calculate font metrics without access to a glyph cache
- //
- // This should only be used *before* OpenGL is initialized and the glyph cache can be filled.
- pub fn static_metrics(config: &Config, dpr: f32) -> Result<font::Metrics, font::Error> {
- let font = config.font.clone();
+ pub fn font_metrics(&self) -> font::Metrics {
+ self.rasterizer
+ .metrics(self.font_key, self.font_size)
+ .expect("metrics load since font is loaded at glyph cache creation")
+ }
- let mut rasterizer = font::Rasterizer::new(dpr, config.font.use_thin_strokes())?;
+ // Calculate font metrics without access to a glyph cache
+ pub fn static_metrics(font: Font, dpr: f64) -> Result<font::Metrics, font::Error> {
+ let mut rasterizer = font::Rasterizer::new(dpr as f32, font.use_thin_strokes())?;
let regular_desc =
GlyphCache::make_desc(&font.normal(), font::Slant::Normal, font::Weight::Normal);
let regular = rasterizer.load_font(&regular_desc, font.size)?;
@@ -363,6 +359,34 @@ impl GlyphCache {
rasterizer.metrics(regular, font.size)
}
+
+ pub fn calculate_dimensions<C>(
+ config: &Config<C>,
+ dpr: f64,
+ cell_width: f32,
+ cell_height: f32,
+ ) -> Option<(f64, f64)> {
+ let dimensions = config.window.dimensions;
+
+ if dimensions.columns_u32() == 0
+ || dimensions.lines_u32() == 0
+ || config.window.startup_mode() != StartupMode::Windowed
+ {
+ return None;
+ }
+
+ let padding_x = f64::from(config.window.padding.x) * dpr;
+ let padding_y = f64::from(config.window.padding.y) * dpr;
+
+ // Calculate new size based on cols/lines specified in config
+ let grid_width = cell_width as u32 * dimensions.columns_u32();
+ let grid_height = cell_height as u32 * dimensions.lines_u32();
+
+ let width = (f64::from(grid_width) + 2. * padding_x).floor();
+ let height = (f64::from(grid_height) + 2. * padding_y).floor();
+
+ Some((width, height))
+ }
}
#[derive(Debug)]
@@ -411,13 +435,13 @@ pub struct QuadRenderer {
}
#[derive(Debug)]
-pub struct RenderApi<'a> {
+pub struct RenderApi<'a, C> {
active_tex: &'a mut GLuint,
batch: &'a mut Batch,
atlas: &'a mut Vec<Atlas>,
current_atlas: &'a mut usize,
program: &'a mut TextShaderProgram,
- config: &'a Config,
+ config: &'a Config<C>,
}
#[derive(Debug)]
@@ -445,7 +469,7 @@ impl Batch {
Batch { tex: 0, instances: Vec::with_capacity(BATCH_MAX) }
}
- pub fn add_item(&mut self, cell: &RenderableCell, glyph: &Glyph) {
+ pub fn add_item(&mut self, cell: RenderableCell, glyph: &Glyph) {
if self.is_empty() {
self.tex = glyph.tex_id;
}
@@ -639,7 +663,7 @@ impl QuadRenderer {
let (msg_tx, msg_rx) = mpsc::channel();
if cfg!(feature = "live-shader-reload") {
- ::std::thread::spawn(move || {
+ util::thread::spawn_named("live shader reload", move || {
let (tx, rx) = ::std::sync::mpsc::channel();
// The Duration argument is a debouncing period.
let mut watcher =
@@ -691,8 +715,8 @@ impl QuadRenderer {
// Draw all rectangles simultaneously to prevent excessive program swaps
pub fn draw_rects(
&mut self,
- config: &Config,
props: &term::SizeInfo,
+ visual_bell_color: Rgb,
visual_bell_intensity: f64,
cell_line_rects: Vec<RenderRect>,
) {
@@ -724,8 +748,7 @@ impl QuadRenderer {
}
// Draw visual bell
- let color = config.visual_bell.color;
- let rect = RenderRect::new(0., 0., props.width, props.height, color);
+ let rect = RenderRect::new(0., 0., props.width, props.height, visual_bell_color);
self.render_rect(&rect, visual_bell_intensity as f32, props);
// Draw underlines and strikeouts
@@ -753,9 +776,9 @@ impl QuadRenderer {
}
}
- pub fn with_api<F, T>(&mut self, config: &Config, props: &term::SizeInfo, func: F) -> T
+ pub fn with_api<F, T, C>(&mut self, config: &Config<C>, props: &term::SizeInfo, func: F) -> T
where
- F: FnOnce(RenderApi<'_>) -> T,
+ F: FnOnce(RenderApi<'_, C>) -> T,
{
// Flush message queue
if let Ok(Msg::ShaderReload) = self.rx.try_recv() {
@@ -838,25 +861,19 @@ impl QuadRenderer {
self.rect_program = rect_program;
}
- pub fn resize(&mut self, size: PhysicalSize, padding_x: f32, padding_y: f32) {
- let (width, height): (u32, u32) = size.into();
-
+ pub fn resize(&mut self, size: &SizeInfo) {
// viewport
unsafe {
- let width = width as i32;
- let height = height as i32;
- let padding_x = padding_x as i32;
- let padding_y = padding_y as i32;
- gl::Viewport(padding_x, padding_y, width - 2 * padding_x, height - 2 * padding_y);
+ gl::Viewport(
+ size.padding_x as i32,
+ size.padding_y as i32,
+ size.width as i32 - 2 * size.padding_x as i32,
+ size.height as i32 - 2 * size.padding_y as i32,
+ );
// update projection
gl::UseProgram(self.program.id);
- self.program.update_projection(
- width as f32,
- height as f32,
- padding_x as f32,
- padding_y as f32,
- );
+ self.program.update_projection(size.width, size.height, size.padding_x, size.padding_y);
gl::UseProgram(0);
}
}
@@ -899,10 +916,10 @@ impl QuadRenderer {
}
}
-impl<'a> RenderApi<'a> {
+impl<'a, C> RenderApi<'a, C> {
pub fn clear(&self, color: Rgb) {
- let alpha = self.config.background_opacity();
unsafe {
+ let alpha = self.config.background_opacity();
gl::ClearColor(
(f32::from(color.r) / 255.0).min(1.0) * alpha,
(f32::from(color.g) / 255.0).min(1.0) * alpha,
@@ -989,7 +1006,7 @@ impl<'a> RenderApi<'a> {
}
#[inline]
- fn add_render_item(&mut self, cell: &RenderableCell, glyph: &Glyph) {
+ fn add_render_item(&mut self, cell: RenderableCell, glyph: &Glyph) {
// Flush batch if tex changing
if !self.batch.is_empty() && self.batch.tex != glyph.tex_id {
self.render_batch();
@@ -1009,18 +1026,15 @@ impl<'a> RenderApi<'a> {
// Raw cell pixel buffers like cursors don't need to go through font lookup
let metrics = glyph_cache.metrics;
let glyph = glyph_cache.cursor_cache.entry(cursor_key).or_insert_with(|| {
- let offset_x = self.config.font.offset.x;
- let offset_y = self.config.font.offset.y;
-
self.load_glyph(&get_cursor_glyph(
cursor_key.style,
metrics,
- offset_x,
- offset_y,
+ self.config.font.offset.x,
+ self.config.font.offset.y,
cursor_key.is_wide,
))
});
- self.add_render_item(&cell, &glyph);
+ self.add_render_item(cell, &glyph);
return;
},
RenderableCellContent::Chars(chars) => chars,
@@ -1050,7 +1064,7 @@ impl<'a> RenderApi<'a> {
// Add cell to batch
let glyph = glyph_cache.get(glyph_key, self);
- self.add_render_item(&cell, glyph);
+ self.add_render_item(cell, glyph);
// Render zero-width characters
for c in (&chars[1..]).iter().filter(|c| **c != ' ') {
@@ -1064,7 +1078,7 @@ impl<'a> RenderApi<'a> {
// anchor has been moved to the right by one cell.
glyph.left += glyph_cache.metrics.average_advance as f32;
- self.add_render_item(&cell, &glyph);
+ self.add_render_item(cell, &glyph);
}
}
}
@@ -1124,7 +1138,7 @@ impl<'a> LoadGlyph for LoaderApi<'a> {
}
}
-impl<'a> LoadGlyph for RenderApi<'a> {
+impl<'a, C> LoadGlyph for RenderApi<'a, C> {
fn load_glyph(&mut self, rasterized: &RasterizedGlyph) -> Glyph {
load_glyph(self.active_tex, self.atlas, self.current_atlas, rasterized)
}
@@ -1134,7 +1148,7 @@ impl<'a> LoadGlyph for RenderApi<'a> {
}
}
-impl<'a> Drop for RenderApi<'a> {
+impl<'a, C> Drop for RenderApi<'a, C> {
fn drop(&mut self) {
if !self.batch.is_empty() {
self.render_batch();