Skip to content

Commit c4d7cde

Browse files
authored
Allow the area to be bigger than u16 (width and height remain u16) (#4318)
Now the editor can fill **very** large terminals. Changed/removed tests which check the truncating behaviour.
1 parent ac0fe29 commit c4d7cde

File tree

3 files changed

+15
-54
lines changed

3 files changed

+15
-54
lines changed

helix-tui/src/buffer.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ impl Buffer {
137137

138138
/// Returns a Buffer with all cells initialized with the attributes of the given Cell
139139
pub fn filled(area: Rect, cell: &Cell) -> Buffer {
140-
let size = area.area() as usize;
140+
let size = area.area();
141141
let mut content = Vec::with_capacity(size);
142142
for _ in 0..size {
143143
content.push(cell.clone());
@@ -239,7 +239,7 @@ impl Buffer {
239239
y,
240240
self.area
241241
);
242-
((y - self.area.y) * self.area.width + (x - self.area.x)) as usize
242+
((y - self.area.y) as usize) * (self.area.width as usize) + ((x - self.area.x) as usize)
243243
}
244244

245245
/// Returns the index in the Vec<Cell> for the given global (x, y) coordinates,
@@ -278,8 +278,8 @@ impl Buffer {
278278
self.content.len()
279279
);
280280
(
281-
self.area.x + i as u16 % self.area.width,
282-
self.area.y + i as u16 / self.area.width,
281+
(self.area.x as usize + (i % self.area.width as usize)) as u16,
282+
(self.area.y as usize + (i / self.area.width as usize)) as u16,
283283
)
284284
}
285285

@@ -480,7 +480,7 @@ impl Buffer {
480480
/// Resize the buffer so that the mapped area matches the given area and that the buffer
481481
/// length is equal to area.width * area.height
482482
pub fn resize(&mut self, area: Rect) {
483-
let length = area.area() as usize;
483+
let length = area.area();
484484
if self.content.len() > length {
485485
self.content.truncate(length);
486486
} else {
@@ -587,8 +587,8 @@ impl Buffer {
587587
let mut to_skip: usize = 0;
588588
for (i, (current, previous)) in next_buffer.iter().zip(previous_buffer.iter()).enumerate() {
589589
if (current != previous || invalidated > 0) && to_skip == 0 {
590-
let x = i as u16 % width;
591-
let y = i as u16 / width;
590+
let x = (i % width as usize) as u16;
591+
let y = (i / width as usize) as u16;
592592
updates.push((x, y, &next_buffer[i]));
593593
}
594594

helix-tui/tests/terminal.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ use helix_tui::{
44
};
55

66
#[test]
7-
fn terminal_buffer_size_should_be_limited() {
7+
fn terminal_buffer_size_should_not_be_limited() {
88
let backend = TestBackend::new(400, 400);
99
let terminal = Terminal::new(backend).unwrap();
1010
let size = terminal.backend().size().unwrap();
11-
assert_eq!(size.width, 255);
12-
assert_eq!(size.height, 255);
11+
assert_eq!(size.width, 400);
12+
assert_eq!(size.height, 400);
1313
}
1414

1515
// #[test]

helix-view/src/graphics.rs

Lines changed: 5 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -95,31 +95,19 @@ pub struct Rect {
9595
}
9696

9797
impl Rect {
98-
/// Creates a new rect, with width and height limited to keep the area under max u16.
99-
/// If clipped, aspect ratio will be preserved.
98+
/// Creates a new rect, with width and height
10099
pub fn new(x: u16, y: u16, width: u16, height: u16) -> Rect {
101-
let max_area = u16::max_value();
102-
let (clipped_width, clipped_height) =
103-
if u32::from(width) * u32::from(height) > u32::from(max_area) {
104-
let aspect_ratio = f64::from(width) / f64::from(height);
105-
let max_area_f = f64::from(max_area);
106-
let height_f = (max_area_f / aspect_ratio).sqrt();
107-
let width_f = height_f * aspect_ratio;
108-
(width_f as u16, height_f as u16)
109-
} else {
110-
(width, height)
111-
};
112100
Rect {
113101
x,
114102
y,
115-
width: clipped_width,
116-
height: clipped_height,
103+
width,
104+
height,
117105
}
118106
}
119107

120108
#[inline]
121-
pub fn area(self) -> u16 {
122-
self.width * self.height
109+
pub fn area(self) -> usize {
110+
(self.width as usize) * (self.height as usize)
123111
}
124112

125113
#[inline]
@@ -630,33 +618,6 @@ impl Style {
630618
mod tests {
631619
use super::*;
632620

633-
#[test]
634-
fn test_rect_size_truncation() {
635-
for width in 256u16..300u16 {
636-
for height in 256u16..300u16 {
637-
let rect = Rect::new(0, 0, width, height);
638-
rect.area(); // Should not panic.
639-
assert!(rect.width < width || rect.height < height);
640-
// The target dimensions are rounded down so the math will not be too precise
641-
// but let's make sure the ratios don't diverge crazily.
642-
assert!(
643-
(f64::from(rect.width) / f64::from(rect.height)
644-
- f64::from(width) / f64::from(height))
645-
.abs()
646-
< 1.0
647-
)
648-
}
649-
}
650-
651-
// One dimension below 255, one above. Area above max u16.
652-
let width = 900;
653-
let height = 100;
654-
let rect = Rect::new(0, 0, width, height);
655-
assert_ne!(rect.width, 900);
656-
assert_ne!(rect.height, 100);
657-
assert!(rect.width < width || rect.height < height);
658-
}
659-
660621
#[test]
661622
fn test_rect_size_preservation() {
662623
for width in 0..256u16 {

0 commit comments

Comments
 (0)