mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-25 02:46:17 +04:00
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.
This commit is contained in:
parent
ac0fe29867
commit
c4d7cde6c8
@ -137,7 +137,7 @@ pub fn empty(area: Rect) -> Buffer {
|
||||
|
||||
/// Returns a Buffer with all cells initialized with the attributes of the given Cell
|
||||
pub fn filled(area: Rect, cell: &Cell) -> Buffer {
|
||||
let size = area.area() as usize;
|
||||
let size = area.area();
|
||||
let mut content = Vec::with_capacity(size);
|
||||
for _ in 0..size {
|
||||
content.push(cell.clone());
|
||||
@ -239,7 +239,7 @@ pub fn index_of(&self, x: u16, y: u16) -> usize {
|
||||
y,
|
||||
self.area
|
||||
);
|
||||
((y - self.area.y) * self.area.width + (x - self.area.x)) as usize
|
||||
((y - self.area.y) as usize) * (self.area.width as usize) + ((x - self.area.x) as usize)
|
||||
}
|
||||
|
||||
/// Returns the index in the Vec<Cell> for the given global (x, y) coordinates,
|
||||
@ -278,8 +278,8 @@ pub fn pos_of(&self, i: usize) -> (u16, u16) {
|
||||
self.content.len()
|
||||
);
|
||||
(
|
||||
self.area.x + i as u16 % self.area.width,
|
||||
self.area.y + i as u16 / self.area.width,
|
||||
(self.area.x as usize + (i % self.area.width as usize)) as u16,
|
||||
(self.area.y as usize + (i / self.area.width as usize)) as u16,
|
||||
)
|
||||
}
|
||||
|
||||
@ -480,7 +480,7 @@ pub fn set_style(&mut self, area: Rect, style: Style) {
|
||||
/// Resize the buffer so that the mapped area matches the given area and that the buffer
|
||||
/// length is equal to area.width * area.height
|
||||
pub fn resize(&mut self, area: Rect) {
|
||||
let length = area.area() as usize;
|
||||
let length = area.area();
|
||||
if self.content.len() > length {
|
||||
self.content.truncate(length);
|
||||
} else {
|
||||
@ -587,8 +587,8 @@ pub fn diff<'a>(&self, other: &'a Buffer) -> Vec<(u16, u16, &'a Cell)> {
|
||||
let mut to_skip: usize = 0;
|
||||
for (i, (current, previous)) in next_buffer.iter().zip(previous_buffer.iter()).enumerate() {
|
||||
if (current != previous || invalidated > 0) && to_skip == 0 {
|
||||
let x = i as u16 % width;
|
||||
let y = i as u16 / width;
|
||||
let x = (i % width as usize) as u16;
|
||||
let y = (i / width as usize) as u16;
|
||||
updates.push((x, y, &next_buffer[i]));
|
||||
}
|
||||
|
||||
|
@ -4,12 +4,12 @@
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn terminal_buffer_size_should_be_limited() {
|
||||
fn terminal_buffer_size_should_not_be_limited() {
|
||||
let backend = TestBackend::new(400, 400);
|
||||
let terminal = Terminal::new(backend).unwrap();
|
||||
let size = terminal.backend().size().unwrap();
|
||||
assert_eq!(size.width, 255);
|
||||
assert_eq!(size.height, 255);
|
||||
assert_eq!(size.width, 400);
|
||||
assert_eq!(size.height, 400);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
|
@ -95,31 +95,19 @@ pub struct Rect {
|
||||
}
|
||||
|
||||
impl Rect {
|
||||
/// Creates a new rect, with width and height limited to keep the area under max u16.
|
||||
/// If clipped, aspect ratio will be preserved.
|
||||
/// Creates a new rect, with width and height
|
||||
pub fn new(x: u16, y: u16, width: u16, height: u16) -> Rect {
|
||||
let max_area = u16::max_value();
|
||||
let (clipped_width, clipped_height) =
|
||||
if u32::from(width) * u32::from(height) > u32::from(max_area) {
|
||||
let aspect_ratio = f64::from(width) / f64::from(height);
|
||||
let max_area_f = f64::from(max_area);
|
||||
let height_f = (max_area_f / aspect_ratio).sqrt();
|
||||
let width_f = height_f * aspect_ratio;
|
||||
(width_f as u16, height_f as u16)
|
||||
} else {
|
||||
(width, height)
|
||||
};
|
||||
Rect {
|
||||
x,
|
||||
y,
|
||||
width: clipped_width,
|
||||
height: clipped_height,
|
||||
width,
|
||||
height,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn area(self) -> u16 {
|
||||
self.width * self.height
|
||||
pub fn area(self) -> usize {
|
||||
(self.width as usize) * (self.height as usize)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -630,33 +618,6 @@ pub fn patch(mut self, other: Style) -> Style {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_rect_size_truncation() {
|
||||
for width in 256u16..300u16 {
|
||||
for height in 256u16..300u16 {
|
||||
let rect = Rect::new(0, 0, width, height);
|
||||
rect.area(); // Should not panic.
|
||||
assert!(rect.width < width || rect.height < height);
|
||||
// The target dimensions are rounded down so the math will not be too precise
|
||||
// but let's make sure the ratios don't diverge crazily.
|
||||
assert!(
|
||||
(f64::from(rect.width) / f64::from(rect.height)
|
||||
- f64::from(width) / f64::from(height))
|
||||
.abs()
|
||||
< 1.0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// One dimension below 255, one above. Area above max u16.
|
||||
let width = 900;
|
||||
let height = 100;
|
||||
let rect = Rect::new(0, 0, width, height);
|
||||
assert_ne!(rect.width, 900);
|
||||
assert_ne!(rect.height, 100);
|
||||
assert!(rect.width < width || rect.height < height);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rect_size_preservation() {
|
||||
for width in 0..256u16 {
|
||||
|
Loading…
Reference in New Issue
Block a user