2020-10-19 19:22:02 +03:00
|
|
|
use super::glyphcache::GlyphCache;
|
2019-12-24 06:13:15 +03:00
|
|
|
use super::quad::*;
|
2019-10-27 02:59:53 +03:00
|
|
|
use super::utilsprites::{RenderMetrics, UtilSprites};
|
2020-10-26 02:09:47 +03:00
|
|
|
use ::window::bitmaps::atlas::OutOfTextureSpace;
|
2019-10-27 02:59:53 +03:00
|
|
|
use ::window::glium::backend::Context as GliumContext;
|
|
|
|
use ::window::glium::texture::SrgbTexture2d;
|
|
|
|
use ::window::glium::{IndexBuffer, VertexBuffer};
|
|
|
|
use ::window::*;
|
add `window-resized` event
This is to support <https://github.com/wez/wezterm/issues/291>.
The window resized event happens asynchronously wrt. processing
a window resize, triggering at the end of the normal window
resize handling.
This commit introduces the notion of whether we are in full screen
mode or not in the underlying event callback, which is useful to
gate the desired feature, which is: when in full screen mode,
increase the padding for the window to center its content.
While poking around at this, I noticed that we weren't passing
the per-window config down to the code that computes the quad
locations for the window.
This commit also changes the font size increase/decrease behavior
so that in full screen mode it doesn't try to resize the window.
```lua
local wezterm = require 'wezterm';
wezterm.on("window-resized", function(window, pane)
local window_dims = window:get_dimensions();
local pane_dims = pane:get_dimensions();
local overrides = window:get_config_overrides() or {}
if not window_dims.is_full_screen then
if not overrides.window_padding then
-- not changing anything
return;
end
overrides.window_padding = nil;
else
-- Use only the middle 33%
local third = math.floor(window_dims.pixel_width / 3)
local new_padding = {
left = third,
right = third,
top = 0,
bottom = 0
};
if overrides.window_padding and new_padding.left == overrides.window_padding.left then
-- padding is same, avoid triggering further changes
return
end
overrides.window_padding = new_padding
end
window:set_config_overrides(overrides)
end);
return {
}
```
2021-03-07 22:54:15 +03:00
|
|
|
use config::ConfigHandle;
|
2019-10-27 02:59:53 +03:00
|
|
|
use std::cell::RefCell;
|
|
|
|
use std::rc::Rc;
|
2020-10-25 02:40:15 +03:00
|
|
|
use wezterm_font::FontConfiguration;
|
2019-10-27 02:59:53 +03:00
|
|
|
|
2021-03-21 22:01:30 +03:00
|
|
|
pub struct TripleVertexBuffer {
|
|
|
|
pub index: usize,
|
|
|
|
pub bufs: [VertexBuffer<Vertex>; 3],
|
|
|
|
}
|
|
|
|
|
2021-01-16 19:00:17 +03:00
|
|
|
pub struct RenderState {
|
2019-10-27 02:59:53 +03:00
|
|
|
pub context: Rc<GliumContext>,
|
|
|
|
pub glyph_cache: RefCell<GlyphCache<SrgbTexture2d>>,
|
|
|
|
pub util_sprites: UtilSprites<SrgbTexture2d>,
|
2021-02-21 04:02:21 +03:00
|
|
|
pub background_prog: glium::Program,
|
|
|
|
pub line_prog: glium::Program,
|
|
|
|
pub glyph_prog: glium::Program,
|
2021-07-22 19:46:08 +03:00
|
|
|
pub img_prog: glium::Program,
|
2021-03-21 22:01:30 +03:00
|
|
|
pub glyph_vertex_buffer: RefCell<TripleVertexBuffer>,
|
2019-10-27 02:59:53 +03:00
|
|
|
pub glyph_index_buffer: IndexBuffer<u32>,
|
2019-12-24 06:13:15 +03:00
|
|
|
pub quads: Quads,
|
2019-10-27 02:59:53 +03:00
|
|
|
}
|
|
|
|
|
2021-01-16 19:00:17 +03:00
|
|
|
impl RenderState {
|
2019-10-27 02:59:53 +03:00
|
|
|
pub fn new(
|
add `window-resized` event
This is to support <https://github.com/wez/wezterm/issues/291>.
The window resized event happens asynchronously wrt. processing
a window resize, triggering at the end of the normal window
resize handling.
This commit introduces the notion of whether we are in full screen
mode or not in the underlying event callback, which is useful to
gate the desired feature, which is: when in full screen mode,
increase the padding for the window to center its content.
While poking around at this, I noticed that we weren't passing
the per-window config down to the code that computes the quad
locations for the window.
This commit also changes the font size increase/decrease behavior
so that in full screen mode it doesn't try to resize the window.
```lua
local wezterm = require 'wezterm';
wezterm.on("window-resized", function(window, pane)
local window_dims = window:get_dimensions();
local pane_dims = pane:get_dimensions();
local overrides = window:get_config_overrides() or {}
if not window_dims.is_full_screen then
if not overrides.window_padding then
-- not changing anything
return;
end
overrides.window_padding = nil;
else
-- Use only the middle 33%
local third = math.floor(window_dims.pixel_width / 3)
local new_padding = {
left = third,
right = third,
top = 0,
bottom = 0
};
if overrides.window_padding and new_padding.left == overrides.window_padding.left then
-- padding is same, avoid triggering further changes
return
end
overrides.window_padding = new_padding
end
window:set_config_overrides(overrides)
end);
return {
}
```
2021-03-07 22:54:15 +03:00
|
|
|
config: &ConfigHandle,
|
2019-10-27 02:59:53 +03:00
|
|
|
context: Rc<GliumContext>,
|
|
|
|
fonts: &Rc<FontConfiguration>,
|
|
|
|
metrics: &RenderMetrics,
|
2020-10-26 02:09:47 +03:00
|
|
|
mut atlas_size: usize,
|
2019-10-27 02:59:53 +03:00
|
|
|
pixel_width: usize,
|
|
|
|
pixel_height: usize,
|
2019-12-15 08:43:05 +03:00
|
|
|
) -> anyhow::Result<Self> {
|
2020-10-26 02:09:47 +03:00
|
|
|
loop {
|
2021-01-06 01:16:21 +03:00
|
|
|
let glyph_cache =
|
|
|
|
RefCell::new(GlyphCache::new_gl(&context, fonts, atlas_size, metrics)?);
|
2020-10-26 02:09:47 +03:00
|
|
|
let result = UtilSprites::new(&mut *glyph_cache.borrow_mut(), metrics);
|
|
|
|
match result {
|
|
|
|
Ok(util_sprites) => {
|
2021-07-22 19:46:08 +03:00
|
|
|
let do_gamma = cfg!(target_os = "macos");
|
|
|
|
|
|
|
|
let background_prog =
|
|
|
|
Self::compile_prog(&context, do_gamma, Self::background_shader)?;
|
|
|
|
let line_prog = Self::compile_prog(&context, do_gamma, Self::line_shader)?;
|
2019-10-27 02:59:53 +03:00
|
|
|
|
2021-07-22 19:46:08 +03:00
|
|
|
let glyph_prog = Self::compile_prog(&context, do_gamma, Self::glyph_shader)?;
|
2021-02-21 04:02:21 +03:00
|
|
|
// Last prog outputs srgb for gamma correction
|
2021-07-22 19:46:08 +03:00
|
|
|
let img_prog = Self::compile_prog(&context, true, Self::img_shader)?;
|
2020-10-26 02:09:47 +03:00
|
|
|
|
|
|
|
let (glyph_vertex_buffer, glyph_index_buffer, quads) = Self::compute_vertices(
|
add `window-resized` event
This is to support <https://github.com/wez/wezterm/issues/291>.
The window resized event happens asynchronously wrt. processing
a window resize, triggering at the end of the normal window
resize handling.
This commit introduces the notion of whether we are in full screen
mode or not in the underlying event callback, which is useful to
gate the desired feature, which is: when in full screen mode,
increase the padding for the window to center its content.
While poking around at this, I noticed that we weren't passing
the per-window config down to the code that computes the quad
locations for the window.
This commit also changes the font size increase/decrease behavior
so that in full screen mode it doesn't try to resize the window.
```lua
local wezterm = require 'wezterm';
wezterm.on("window-resized", function(window, pane)
local window_dims = window:get_dimensions();
local pane_dims = pane:get_dimensions();
local overrides = window:get_config_overrides() or {}
if not window_dims.is_full_screen then
if not overrides.window_padding then
-- not changing anything
return;
end
overrides.window_padding = nil;
else
-- Use only the middle 33%
local third = math.floor(window_dims.pixel_width / 3)
local new_padding = {
left = third,
right = third,
top = 0,
bottom = 0
};
if overrides.window_padding and new_padding.left == overrides.window_padding.left then
-- padding is same, avoid triggering further changes
return
end
overrides.window_padding = new_padding
end
window:set_config_overrides(overrides)
end);
return {
}
```
2021-03-07 22:54:15 +03:00
|
|
|
config,
|
2020-10-26 02:09:47 +03:00
|
|
|
&context,
|
|
|
|
metrics,
|
|
|
|
pixel_width as f32,
|
|
|
|
pixel_height as f32,
|
|
|
|
)?;
|
|
|
|
|
|
|
|
return Ok(Self {
|
|
|
|
context,
|
|
|
|
glyph_cache,
|
|
|
|
util_sprites,
|
2021-02-21 04:02:21 +03:00
|
|
|
background_prog,
|
|
|
|
line_prog,
|
|
|
|
glyph_prog,
|
2021-07-22 19:46:08 +03:00
|
|
|
img_prog,
|
2020-10-26 02:09:47 +03:00
|
|
|
glyph_vertex_buffer: RefCell::new(glyph_vertex_buffer),
|
|
|
|
glyph_index_buffer,
|
|
|
|
quads,
|
|
|
|
});
|
|
|
|
}
|
2021-03-14 10:18:15 +03:00
|
|
|
Err(OutOfTextureSpace {
|
|
|
|
size: Some(size), ..
|
|
|
|
}) => {
|
2020-10-26 02:09:47 +03:00
|
|
|
atlas_size = size;
|
|
|
|
}
|
2021-03-14 10:18:15 +03:00
|
|
|
Err(OutOfTextureSpace { size: None, .. }) => {
|
2020-10-26 02:09:47 +03:00
|
|
|
anyhow::bail!("requested texture size is impossible!?")
|
2019-10-27 02:59:53 +03:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-21 04:02:21 +03:00
|
|
|
fn compile_prog(
|
|
|
|
context: &Rc<GliumContext>,
|
|
|
|
outputs_srgb: bool,
|
|
|
|
fragment_shader: fn(&str) -> (String, String),
|
|
|
|
) -> anyhow::Result<glium::Program> {
|
|
|
|
let mut errors = vec![];
|
|
|
|
for version in &["330", "300 es"] {
|
|
|
|
let (vertex_shader, fragment_shader) = fragment_shader(version);
|
|
|
|
let source = glium::program::ProgramCreationInput::SourceCode {
|
|
|
|
vertex_shader: &vertex_shader,
|
|
|
|
fragment_shader: &fragment_shader,
|
|
|
|
outputs_srgb,
|
|
|
|
tessellation_control_shader: None,
|
|
|
|
tessellation_evaluation_shader: None,
|
|
|
|
transform_feedback_varyings: None,
|
|
|
|
uses_point_size: false,
|
|
|
|
geometry_shader: None,
|
|
|
|
};
|
|
|
|
log::trace!("compiling a prog with version {}", version);
|
|
|
|
match glium::Program::new(context, source) {
|
|
|
|
Ok(prog) => {
|
|
|
|
return Ok(prog);
|
|
|
|
}
|
|
|
|
Err(err) => errors.push(err.to_string()),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
anyhow::bail!("Failed to compile shaders: {}", errors.join("\n"))
|
|
|
|
}
|
|
|
|
|
2019-10-27 02:59:53 +03:00
|
|
|
pub fn advise_of_window_size_change(
|
|
|
|
&mut self,
|
add `window-resized` event
This is to support <https://github.com/wez/wezterm/issues/291>.
The window resized event happens asynchronously wrt. processing
a window resize, triggering at the end of the normal window
resize handling.
This commit introduces the notion of whether we are in full screen
mode or not in the underlying event callback, which is useful to
gate the desired feature, which is: when in full screen mode,
increase the padding for the window to center its content.
While poking around at this, I noticed that we weren't passing
the per-window config down to the code that computes the quad
locations for the window.
This commit also changes the font size increase/decrease behavior
so that in full screen mode it doesn't try to resize the window.
```lua
local wezterm = require 'wezterm';
wezterm.on("window-resized", function(window, pane)
local window_dims = window:get_dimensions();
local pane_dims = pane:get_dimensions();
local overrides = window:get_config_overrides() or {}
if not window_dims.is_full_screen then
if not overrides.window_padding then
-- not changing anything
return;
end
overrides.window_padding = nil;
else
-- Use only the middle 33%
local third = math.floor(window_dims.pixel_width / 3)
local new_padding = {
left = third,
right = third,
top = 0,
bottom = 0
};
if overrides.window_padding and new_padding.left == overrides.window_padding.left then
-- padding is same, avoid triggering further changes
return
end
overrides.window_padding = new_padding
end
window:set_config_overrides(overrides)
end);
return {
}
```
2021-03-07 22:54:15 +03:00
|
|
|
config: &ConfigHandle,
|
2019-10-27 02:59:53 +03:00
|
|
|
metrics: &RenderMetrics,
|
|
|
|
pixel_width: usize,
|
|
|
|
pixel_height: usize,
|
2019-12-15 08:43:05 +03:00
|
|
|
) -> anyhow::Result<()> {
|
2019-12-24 06:13:15 +03:00
|
|
|
let (glyph_vertex_buffer, glyph_index_buffer, quads) = Self::compute_vertices(
|
add `window-resized` event
This is to support <https://github.com/wez/wezterm/issues/291>.
The window resized event happens asynchronously wrt. processing
a window resize, triggering at the end of the normal window
resize handling.
This commit introduces the notion of whether we are in full screen
mode or not in the underlying event callback, which is useful to
gate the desired feature, which is: when in full screen mode,
increase the padding for the window to center its content.
While poking around at this, I noticed that we weren't passing
the per-window config down to the code that computes the quad
locations for the window.
This commit also changes the font size increase/decrease behavior
so that in full screen mode it doesn't try to resize the window.
```lua
local wezterm = require 'wezterm';
wezterm.on("window-resized", function(window, pane)
local window_dims = window:get_dimensions();
local pane_dims = pane:get_dimensions();
local overrides = window:get_config_overrides() or {}
if not window_dims.is_full_screen then
if not overrides.window_padding then
-- not changing anything
return;
end
overrides.window_padding = nil;
else
-- Use only the middle 33%
local third = math.floor(window_dims.pixel_width / 3)
local new_padding = {
left = third,
right = third,
top = 0,
bottom = 0
};
if overrides.window_padding and new_padding.left == overrides.window_padding.left then
-- padding is same, avoid triggering further changes
return
end
overrides.window_padding = new_padding
end
window:set_config_overrides(overrides)
end);
return {
}
```
2021-03-07 22:54:15 +03:00
|
|
|
config,
|
2019-10-27 02:59:53 +03:00
|
|
|
&self.context,
|
|
|
|
metrics,
|
|
|
|
pixel_width as f32,
|
|
|
|
pixel_height as f32,
|
|
|
|
)?;
|
|
|
|
|
|
|
|
*self.glyph_vertex_buffer.borrow_mut() = glyph_vertex_buffer;
|
|
|
|
self.glyph_index_buffer = glyph_index_buffer;
|
2019-12-24 06:13:15 +03:00
|
|
|
self.quads = quads;
|
2019-10-27 02:59:53 +03:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2021-02-21 04:02:21 +03:00
|
|
|
fn glyph_shader(version: &str) -> (String, String) {
|
|
|
|
(
|
|
|
|
format!(
|
|
|
|
"#version {}\n{}\n{}",
|
|
|
|
version,
|
|
|
|
include_str!("vertex-common.glsl"),
|
|
|
|
include_str!("glyph-vertex.glsl")
|
|
|
|
),
|
|
|
|
format!(
|
|
|
|
"#version {}\n{}\n{}",
|
|
|
|
version,
|
|
|
|
include_str!("fragment-common.glsl"),
|
|
|
|
include_str!("glyph-frag.glsl")
|
|
|
|
),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-07-22 19:46:08 +03:00
|
|
|
fn img_shader(version: &str) -> (String, String) {
|
|
|
|
(
|
|
|
|
format!(
|
|
|
|
"#version {}\n{}\n{}",
|
|
|
|
version,
|
|
|
|
include_str!("vertex-common.glsl"),
|
|
|
|
include_str!("img-vertex.glsl")
|
|
|
|
),
|
|
|
|
format!(
|
|
|
|
"#version {}\n{}\n{}",
|
|
|
|
version,
|
|
|
|
include_str!("fragment-common.glsl"),
|
|
|
|
include_str!("img-frag.glsl")
|
|
|
|
),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-02-21 04:02:21 +03:00
|
|
|
fn line_shader(version: &str) -> (String, String) {
|
|
|
|
(
|
|
|
|
format!(
|
|
|
|
"#version {}\n{}\n{}",
|
|
|
|
version,
|
|
|
|
include_str!("vertex-common.glsl"),
|
|
|
|
include_str!("line-vertex.glsl")
|
|
|
|
),
|
|
|
|
format!(
|
|
|
|
"#version {}\n{}\n{}",
|
|
|
|
version,
|
|
|
|
include_str!("fragment-common.glsl"),
|
|
|
|
include_str!("line-frag.glsl")
|
|
|
|
),
|
|
|
|
)
|
2019-10-27 02:59:53 +03:00
|
|
|
}
|
|
|
|
|
2021-02-21 04:02:21 +03:00
|
|
|
fn background_shader(version: &str) -> (String, String) {
|
|
|
|
(
|
|
|
|
format!(
|
|
|
|
"#version {}\n{}\n{}",
|
|
|
|
version,
|
|
|
|
include_str!("vertex-common.glsl"),
|
|
|
|
include_str!("background-vertex.glsl")
|
|
|
|
),
|
|
|
|
format!(
|
|
|
|
"#version {}\n{}\n{}",
|
|
|
|
version,
|
|
|
|
include_str!("fragment-common.glsl"),
|
|
|
|
include_str!("background-frag.glsl")
|
|
|
|
),
|
|
|
|
)
|
2019-10-27 02:59:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Compute a vertex buffer to hold the quads that comprise the visible
|
|
|
|
/// portion of the screen. We recreate this when the screen is resized.
|
2019-12-22 01:17:50 +03:00
|
|
|
/// The idea is that we want to minimize any heavy lifting and computation
|
2019-10-27 02:59:53 +03:00
|
|
|
/// and instead just poke some attributes into the offset that corresponds
|
|
|
|
/// to a changed cell when we need to repaint the screen, and then just
|
|
|
|
/// let the GPU figure out the rest.
|
|
|
|
fn compute_vertices(
|
add `window-resized` event
This is to support <https://github.com/wez/wezterm/issues/291>.
The window resized event happens asynchronously wrt. processing
a window resize, triggering at the end of the normal window
resize handling.
This commit introduces the notion of whether we are in full screen
mode or not in the underlying event callback, which is useful to
gate the desired feature, which is: when in full screen mode,
increase the padding for the window to center its content.
While poking around at this, I noticed that we weren't passing
the per-window config down to the code that computes the quad
locations for the window.
This commit also changes the font size increase/decrease behavior
so that in full screen mode it doesn't try to resize the window.
```lua
local wezterm = require 'wezterm';
wezterm.on("window-resized", function(window, pane)
local window_dims = window:get_dimensions();
local pane_dims = pane:get_dimensions();
local overrides = window:get_config_overrides() or {}
if not window_dims.is_full_screen then
if not overrides.window_padding then
-- not changing anything
return;
end
overrides.window_padding = nil;
else
-- Use only the middle 33%
local third = math.floor(window_dims.pixel_width / 3)
local new_padding = {
left = third,
right = third,
top = 0,
bottom = 0
};
if overrides.window_padding and new_padding.left == overrides.window_padding.left then
-- padding is same, avoid triggering further changes
return
end
overrides.window_padding = new_padding
end
window:set_config_overrides(overrides)
end);
return {
}
```
2021-03-07 22:54:15 +03:00
|
|
|
config: &ConfigHandle,
|
2019-10-27 02:59:53 +03:00
|
|
|
context: &Rc<GliumContext>,
|
|
|
|
metrics: &RenderMetrics,
|
|
|
|
width: f32,
|
|
|
|
height: f32,
|
2021-03-21 22:01:30 +03:00
|
|
|
) -> anyhow::Result<(TripleVertexBuffer, IndexBuffer<u32>, Quads)> {
|
2019-10-27 02:59:53 +03:00
|
|
|
let cell_width = metrics.cell_size.width as f32;
|
|
|
|
let cell_height = metrics.cell_size.height as f32;
|
|
|
|
let mut verts = Vec::new();
|
|
|
|
let mut indices = Vec::new();
|
|
|
|
|
2021-02-28 05:40:04 +03:00
|
|
|
let padding_right = super::termwindow::resize::effective_right_padding(&config, metrics);
|
2019-12-23 05:57:54 +03:00
|
|
|
let avail_width =
|
|
|
|
(width as usize).saturating_sub((config.window_padding.left + padding_right) as usize);
|
2019-12-22 01:17:50 +03:00
|
|
|
let avail_height = (height as usize)
|
|
|
|
.saturating_sub((config.window_padding.top + config.window_padding.bottom) as usize);
|
|
|
|
|
|
|
|
let num_cols = avail_width as usize / cell_width as usize;
|
|
|
|
let num_rows = avail_height as usize / cell_height as usize;
|
|
|
|
|
|
|
|
let padding_left = config.window_padding.left as f32;
|
|
|
|
let padding_top = config.window_padding.top as f32;
|
2019-10-27 02:59:53 +03:00
|
|
|
|
2019-12-01 22:43:22 +03:00
|
|
|
log::debug!(
|
2019-12-22 01:17:50 +03:00
|
|
|
"compute_vertices {}x{} {}x{} padding={} {}",
|
2019-12-01 10:22:37 +03:00
|
|
|
num_cols,
|
|
|
|
num_rows,
|
|
|
|
width,
|
2019-12-22 01:17:50 +03:00
|
|
|
height,
|
|
|
|
padding_left,
|
|
|
|
padding_top
|
2019-12-01 10:22:37 +03:00
|
|
|
);
|
|
|
|
|
2019-12-24 06:13:15 +03:00
|
|
|
let mut quads = Quads::default();
|
|
|
|
quads.cols = num_cols;
|
2019-12-23 05:57:54 +03:00
|
|
|
|
2019-12-24 06:13:15 +03:00
|
|
|
let mut define_quad = |left, top, right, bottom| -> u32 {
|
2019-12-23 05:57:54 +03:00
|
|
|
// Remember starting index for this position
|
|
|
|
let idx = verts.len() as u32;
|
2019-12-24 06:13:15 +03:00
|
|
|
|
2019-12-23 05:57:54 +03:00
|
|
|
verts.push(Vertex {
|
|
|
|
// Top left
|
2019-12-24 06:13:15 +03:00
|
|
|
position: (left, top),
|
2019-12-23 05:57:54 +03:00
|
|
|
..Default::default()
|
|
|
|
});
|
|
|
|
verts.push(Vertex {
|
|
|
|
// Top Right
|
2019-12-24 06:13:15 +03:00
|
|
|
position: (right, top),
|
2019-12-23 05:57:54 +03:00
|
|
|
..Default::default()
|
|
|
|
});
|
|
|
|
verts.push(Vertex {
|
|
|
|
// Bottom Left
|
2019-12-24 06:13:15 +03:00
|
|
|
position: (left, bottom),
|
2019-12-23 05:57:54 +03:00
|
|
|
..Default::default()
|
|
|
|
});
|
|
|
|
verts.push(Vertex {
|
|
|
|
// Bottom Right
|
2019-12-24 06:13:15 +03:00
|
|
|
position: (right, bottom),
|
2019-12-23 05:57:54 +03:00
|
|
|
..Default::default()
|
|
|
|
});
|
|
|
|
|
|
|
|
// Emit two triangles to form the glyph quad
|
|
|
|
indices.push(idx + V_TOP_LEFT as u32);
|
|
|
|
indices.push(idx + V_TOP_RIGHT as u32);
|
|
|
|
indices.push(idx + V_BOT_LEFT as u32);
|
|
|
|
|
|
|
|
indices.push(idx + V_TOP_RIGHT as u32);
|
|
|
|
indices.push(idx + V_BOT_LEFT as u32);
|
|
|
|
indices.push(idx + V_BOT_RIGHT as u32);
|
2019-12-24 06:13:15 +03:00
|
|
|
|
|
|
|
idx
|
|
|
|
};
|
|
|
|
|
2020-10-18 19:47:55 +03:00
|
|
|
// Background image fills the entire window background
|
|
|
|
quads.background_image =
|
|
|
|
define_quad(width / -2.0, height / -2.0, width / 2.0, height / 2.0) as usize;
|
|
|
|
|
2020-10-19 03:50:49 +03:00
|
|
|
for y in 0..=num_rows {
|
2019-12-24 06:13:15 +03:00
|
|
|
let y_pos = (height / -2.0) + (y as f32 * cell_height) + padding_top;
|
|
|
|
|
|
|
|
for x in 0..num_cols {
|
|
|
|
let x_pos = (width / -2.0) + (x as f32 * cell_width) + padding_left;
|
|
|
|
|
|
|
|
let idx = define_quad(x_pos, y_pos, x_pos + cell_width, y_pos + cell_height);
|
|
|
|
if x == 0 {
|
|
|
|
// build row -> vertex mapping
|
|
|
|
quads.row_starts.push(idx as usize);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-20 06:59:22 +03:00
|
|
|
// And a quad for the scrollbar thumb
|
|
|
|
quads.scroll_thumb = define_quad(0.0, 0.0, 0.0, 0.0) as usize;
|
2019-12-23 05:57:54 +03:00
|
|
|
|
2021-03-21 22:01:30 +03:00
|
|
|
let buffer = TripleVertexBuffer {
|
|
|
|
index: 0,
|
|
|
|
bufs: [
|
2021-03-22 06:51:02 +03:00
|
|
|
VertexBuffer::dynamic(context, &verts)?,
|
|
|
|
VertexBuffer::dynamic(context, &verts)?,
|
|
|
|
VertexBuffer::dynamic(context, &verts)?,
|
2021-03-21 22:01:30 +03:00
|
|
|
],
|
|
|
|
};
|
|
|
|
|
2019-10-27 02:59:53 +03:00
|
|
|
Ok((
|
2021-03-21 22:01:30 +03:00
|
|
|
buffer,
|
2019-10-27 02:59:53 +03:00
|
|
|
IndexBuffer::new(
|
|
|
|
context,
|
|
|
|
glium::index::PrimitiveType::TrianglesList,
|
|
|
|
&indices,
|
|
|
|
)?,
|
2019-12-24 06:13:15 +03:00
|
|
|
quads,
|
2019-10-27 02:59:53 +03:00
|
|
|
))
|
|
|
|
}
|
|
|
|
|
2020-10-23 23:57:58 +03:00
|
|
|
pub fn clear_texture_atlas(&mut self, metrics: &RenderMetrics) -> anyhow::Result<()> {
|
2021-01-16 19:00:17 +03:00
|
|
|
let mut glyph_cache = self.glyph_cache.borrow_mut();
|
|
|
|
glyph_cache.clear();
|
|
|
|
self.util_sprites = UtilSprites::new(&mut glyph_cache, metrics)?;
|
2020-10-23 23:57:58 +03:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2019-10-27 02:59:53 +03:00
|
|
|
pub fn recreate_texture_atlas(
|
|
|
|
&mut self,
|
|
|
|
fonts: &Rc<FontConfiguration>,
|
|
|
|
metrics: &RenderMetrics,
|
|
|
|
size: Option<usize>,
|
2021-01-16 19:12:45 +03:00
|
|
|
) -> anyhow::Result<()> {
|
|
|
|
// We make a a couple of passes at resizing; if the user has selected a large
|
|
|
|
// font size (or a large scaling factor) then the `size==None` case will not
|
|
|
|
// be able to fit the initial utility glyphs and apply_scale_change won't
|
|
|
|
// be able to deal with that error situation. Rather than make every
|
|
|
|
// caller know how to deal with OutOfTextureSpace we try to absorb
|
|
|
|
// and accomodate that here.
|
|
|
|
let mut size = size;
|
|
|
|
let mut attempt = 10;
|
|
|
|
loop {
|
|
|
|
match self.recreate_texture_atlas_impl(fonts, metrics, size) {
|
|
|
|
Ok(_) => return Ok(()),
|
|
|
|
Err(err) => {
|
|
|
|
attempt -= 1;
|
|
|
|
if attempt == 0 {
|
|
|
|
return Err(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(&OutOfTextureSpace {
|
|
|
|
size: Some(needed_size),
|
2021-03-14 10:18:15 +03:00
|
|
|
..
|
2021-01-16 19:12:45 +03:00
|
|
|
}) = err.downcast_ref::<OutOfTextureSpace>()
|
|
|
|
{
|
|
|
|
size.replace(needed_size);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Err(err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn recreate_texture_atlas_impl(
|
|
|
|
&mut self,
|
|
|
|
fonts: &Rc<FontConfiguration>,
|
|
|
|
metrics: &RenderMetrics,
|
|
|
|
size: Option<usize>,
|
2019-12-15 08:43:05 +03:00
|
|
|
) -> anyhow::Result<()> {
|
2021-01-16 19:00:17 +03:00
|
|
|
let size = size.unwrap_or_else(|| self.glyph_cache.borrow().atlas.size());
|
2021-03-14 20:29:02 +03:00
|
|
|
let mut new_glyph_cache = GlyphCache::new_gl(&self.context, fonts, size, metrics)?;
|
|
|
|
self.util_sprites = UtilSprites::new(&mut new_glyph_cache, metrics)?;
|
|
|
|
|
|
|
|
let mut glyph_cache = self.glyph_cache.borrow_mut();
|
|
|
|
|
|
|
|
// Steal the decoded image cache; without this, any animating gifs
|
|
|
|
// would reset back to frame 0 each time we filled the texture
|
|
|
|
std::mem::swap(
|
|
|
|
&mut glyph_cache.image_cache,
|
|
|
|
&mut new_glyph_cache.image_cache,
|
|
|
|
);
|
|
|
|
|
|
|
|
*glyph_cache = new_glyph_cache;
|
2019-10-27 02:59:53 +03:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|