on master help sign in
Allow the area to be bigger than u16 (width and height remain u16) (#4318)
c4d7cdeA-Walrus
helix-tui/src/buffer.rs+7−7
@@ -137,7 +137,7 @@ impl Buffer {
137
137
138 /// Returns a Buffer with all cells initialized with the attributes of the given Cell
138 /// Returns a Buffer with all cells initialized with the attributes of the given Cell
139 pub fn filled(area: Rect, cell: &Cell) -> Buffer {
139 pub fn filled(area: Rect, cell: &Cell) -> Buffer {
140− let size = area.area() as usize;
140+ let size = area.area();
141 let mut content = Vec::with_capacity(size);
141 let mut content = Vec::with_capacity(size);
142 for _ in 0..size {
142 for _ in 0..size {
143 content.push(cell.clone());
143 content.push(cell.clone());
@@ -239,7 +239,7 @@ impl Buffer {
239 y,
239 y,
240 self.area
240 self.area
241 );
241 );
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)
243 }
243 }
244
244
245 /// Returns the index in the Vec<Cell> for the given global (x, y) coordinates,
245 /// Returns the index in the Vec<Cell> for the given global (x, y) coordinates,
@@ -278,8 +278,8 @@ impl Buffer {
278 self.content.len()
278 self.content.len()
279 );
279 );
280 (
280 (
281− self.area.x + i as u16 % self.area.width,
281+ (self.area.x as usize + (i % self.area.width as usize)) as u16,
282− self.area.y + i as u16 / self.area.width,
282+ (self.area.y as usize + (i / self.area.width as usize)) as u16,
283 )
283 )
284 }
284 }
285
285
@@ -480,7 +480,7 @@ impl Buffer {
480 /// Resize the buffer so that the mapped area matches the given area and that the buffer
480 /// Resize the buffer so that the mapped area matches the given area and that the buffer
481 /// length is equal to area.width * area.height
481 /// length is equal to area.width * area.height
482 pub fn resize(&mut self, area: Rect) {
482 pub fn resize(&mut self, area: Rect) {
483− let length = area.area() as usize;
483+ let length = area.area();
484 if self.content.len() > length {
484 if self.content.len() > length {
485 self.content.truncate(length);
485 self.content.truncate(length);
486 } else {
486 } else {
@@ -587,8 +587,8 @@ impl Buffer {
587 let mut to_skip: usize = 0;
587 let mut to_skip: usize = 0;
588 for (i, (current, previous)) in next_buffer.iter().zip(previous_buffer.iter()).enumerate() {
588 for (i, (current, previous)) in next_buffer.iter().zip(previous_buffer.iter()).enumerate() {
589 if (current != previous || invalidated > 0) && to_skip == 0 {
589 if (current != previous || invalidated > 0) && to_skip == 0 {
590− let x = i as u16 % width;
590+ let x = (i % width as usize) as u16;
591− let y = i as u16 / width;
591+ let y = (i / width as usize) as u16;
592 updates.push((x, y, &next_buffer[i]));
592 updates.push((x, y, &next_buffer[i]));
593 }
593 }
594
594
helix-tui/tests/terminal.rs+3−3
@@ -4,12 +4,12 @@ use helix_tui::{
4};
4};
5
5
6#[test]
6#[test]
7−fn terminal_buffer_size_should_be_limited() {
7+fn terminal_buffer_size_should_not_be_limited() {
8 let backend = TestBackend::new(400, 400);
8 let backend = TestBackend::new(400, 400);
9 let terminal = Terminal::new(backend).unwrap();
9 let terminal = Terminal::new(backend).unwrap();
10 let size = terminal.backend().size().unwrap();
10 let size = terminal.backend().size().unwrap();
11− assert_eq!(size.width, 255);
11+ assert_eq!(size.width, 400);
12− assert_eq!(size.height, 255);
12+ assert_eq!(size.height, 400);
13}
13}
14
14
15// #[test]
15// #[test]
helix-view/src/graphics.rs+5−44
@@ -95,31 +95,19 @@ pub struct Rect {
95}
95}
96
96
97impl Rect {
97impl Rect {
98− /// Creates a new rect, with width and height limited to keep the area under max u16.
98+ /// Creates a new rect, with width and height
99− /// If clipped, aspect ratio will be preserved.
100 pub fn new(x: u16, y: u16, width: u16, height: u16) -> Rect {
99 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− };
112 Rect {
100 Rect {
113 x,
101 x,
114 y,
102 y,
115− width: clipped_width,
103+ width,
116− height: clipped_height,
104+ height,
117 }
105 }
118 }
106 }
119
107
120 #[inline]
108 #[inline]
121− pub fn area(self) -> u16 {
109+ pub fn area(self) -> usize {
122− self.width * self.height
110+ (self.width as usize) * (self.height as usize)
123 }
111 }
124
112
125 #[inline]
113 #[inline]
@@ -630,33 +618,6 @@ impl Style {
630mod tests {
618mod tests {
631 use super::*;
619 use super::*;
632
620
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−
660 #[test]
621 #[test]
661 fn test_rect_size_preservation() {
622 fn test_rect_size_preservation() {
662 for width in 0..256u16 {
623 for width in 0..256u16 {