summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirill Chibisov <contact@kchibisov.com>2022-12-09 09:21:28 +0300
committerGitHub <noreply@github.com>2022-12-09 09:21:28 +0300
commit6566dd3defa9f080dabb295740dc1dac06e3b8fb (patch)
treebaf1879dac3a39fda83f80ffe465bfc61596e0a9
parent79860622a7beb8bbff0602e56977be6018f3aa39 (diff)
downloadalacritty-6566dd3defa9f080dabb295740dc1dac06e3b8fb.tar.gz
alacritty-6566dd3defa9f080dabb295740dc1dac06e3b8fb.zip
Fix damage computation on boundaries
Given that the Rect started to use signed integers saturating_sub became irrelevant and no clamp to zero were performed. This commit uses max instead to fix it.
-rw-r--r--Cargo.lock4
-rw-r--r--alacritty/Cargo.toml2
-rw-r--r--alacritty/src/display/damage.rs61
3 files changed, 58 insertions, 9 deletions
diff --git a/Cargo.lock b/Cargo.lock
index c3bb2074..1fedfe18 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -676,9 +676,9 @@ dependencies = [
[[package]]
name = "glutin"
-version = "0.30.2"
+version = "0.30.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0282c380a3adb52ae095e5847cc575c6bf79d296dcbf333e00be4a3fca07235e"
+checksum = "524d807cd49a0c56a53ef9a6738cd15e7c8c4e9d37a3b7fdb3c250c1cd5bf7a3"
dependencies = [
"bitflags",
"cfg_aliases",
diff --git a/alacritty/Cargo.toml b/alacritty/Cargo.toml
index 810f9d33..28529bd1 100644
--- a/alacritty/Cargo.toml
+++ b/alacritty/Cargo.toml
@@ -29,7 +29,7 @@ fnv = "1"
serde = { version = "1", features = ["derive"] }
serde_yaml = "0.8"
serde_json = "1"
-glutin = { version = "0.30.2", default-features = false, features = ["egl", "wgl"] }
+glutin = { version = "0.30.3", default-features = false, features = ["egl", "wgl"] }
winit = { version = "0.27.4", default-features = false, features = ["serde"] }
notify-debouncer-mini = { version = "0.2.1", default-features = false }
parking_lot = "0.12.0"
diff --git a/alacritty/src/display/damage.rs b/alacritty/src/display/damage.rs
index 380a2f63..82230dff 100644
--- a/alacritty/src/display/damage.rs
+++ b/alacritty/src/display/damage.rs
@@ -30,14 +30,13 @@ impl<'a> RenderDamageIterator<'a> {
// Make sure to damage near cells to include wide chars.
#[inline]
- fn overdamage(&self, mut rect: Rect) -> Rect {
- let size_info = &self.size_info;
- rect.x = rect.x.saturating_sub(size_info.cell_width() as i32);
+ fn overdamage(size_info: &SizeInfo<u32>, mut rect: Rect) -> Rect {
+ rect.x = (rect.x - size_info.cell_width() as i32).max(0);
rect.width = cmp::min(
size_info.width() as i32 - rect.x,
rect.width + 2 * size_info.cell_width() as i32,
);
- rect.y = rect.y.saturating_sub(size_info.cell_height() as i32 / 2);
+ rect.y = (rect.y - size_info.cell_height() as i32 / 2).max(0);
rect.height = cmp::min(
size_info.height() as i32 - rect.y,
rect.height + size_info.cell_height() as i32,
@@ -52,11 +51,12 @@ impl<'a> Iterator for RenderDamageIterator<'a> {
fn next(&mut self) -> Option<Rect> {
let line = self.damaged_lines.next()?;
- let mut total_damage_rect = self.overdamage(self.rect_for_line(line));
+ let size_info = &self.size_info;
+ let mut total_damage_rect = Self::overdamage(size_info, self.rect_for_line(line));
// Merge rectangles which overlap with each other.
while let Some(line) = self.damaged_lines.peek().copied() {
- let next_rect = self.overdamage(self.rect_for_line(line));
+ let next_rect = Self::overdamage(size_info, self.rect_for_line(line));
if !rects_overlap(total_damage_rect, next_rect) {
break;
}
@@ -92,3 +92,52 @@ fn merge_rects(lhs: Rect, rhs: Rect) -> Rect {
let y_bottom = cmp::min(lhs.y, rhs.y);
Rect::new(left_x, y_bottom, right_x - left_x, y_top - y_bottom)
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn damage_rect_math() {
+ let rect_side = 10;
+ let cell_size = 4;
+ let bound = 100;
+
+ let size_info: SizeInfo<u32> = SizeInfo::new(
+ bound as f32,
+ bound as f32,
+ cell_size as f32,
+ cell_size as f32,
+ 2.,
+ 2.,
+ true,
+ )
+ .into();
+
+ // Test min clamping.
+ let rect = Rect::new(0, 0, rect_side, rect_side);
+ let rect = RenderDamageIterator::overdamage(&size_info, rect);
+ assert_eq!(Rect::new(0, 0, rect_side + 2 * cell_size, 10 + cell_size), rect);
+
+ // Test max clamping.
+ let rect = Rect::new(bound, bound, rect_side, rect_side);
+ let rect = RenderDamageIterator::overdamage(&size_info, rect);
+ assert_eq!(
+ Rect::new(bound - cell_size, bound - cell_size / 2, cell_size, cell_size / 2),
+ rect
+ );
+
+ // Test no clamping.
+ let rect = Rect::new(bound / 2, bound / 2, rect_side, rect_side);
+ let rect = RenderDamageIterator::overdamage(&size_info, rect);
+ assert_eq!(
+ Rect::new(
+ bound / 2 - cell_size,
+ bound / 2 - cell_size / 2,
+ rect_side + 2 * cell_size,
+ rect_side + cell_size
+ ),
+ rect
+ );
+ }
+}