From ff2309c1581c025ba8b9f65e6619fe2fe2252827 Mon Sep 17 00:00:00 2001 From: Lev Kropp Date: Wed, 16 Oct 2024 13:17:09 -0400 Subject: [PATCH] Implement line-height snapping and full line rendering --- lib/src/ui/render.dart | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/lib/src/ui/render.dart b/lib/src/ui/render.dart index de2a2f7..3ebaa59 100644 --- a/lib/src/ui/render.dart +++ b/lib/src/ui/render.dart @@ -154,7 +154,8 @@ class RenderTerminal extends RenderBox with RelayoutWhenSystemFontsChangeMixin { var _stickToBottom = true; void _onScroll() { - _stickToBottom = _scrollOffset >= _maxScrollExtent; + final lineHeight = _painter.cellSize.height; + _stickToBottom = (_maxScrollExtent - _offset.pixels).abs() < lineHeight / 2; markNeedsLayout(); _notifyEditableRect(); } @@ -209,12 +210,13 @@ class RenderTerminal extends RenderBox with RelayoutWhenSystemFontsChangeMixin { size = constraints.biggest; _updateViewportSize(); - _updateScrollOffset(); if (_stickToBottom) { - _offset.correctBy(_maxScrollExtent - _scrollOffset); + _offset.correctBy(_maxScrollExtent - _offset.pixels); } + + _notifyEditableRect(); } /// Total height of the terminal in pixels. Includes scrollback buffer. @@ -224,8 +226,9 @@ class RenderTerminal extends RenderBox with RelayoutWhenSystemFontsChangeMixin { /// The distance from the top of the terminal to the top of the viewport. // double get _scrollOffset => _offset.pixels; double get _scrollOffset { - // return _offset.pixels ~/ _painter.cellSize.height * _painter.cellSize.height; - return _offset.pixels; + final lineHeight = _painter.cellSize.height; + // Snap the scroll offset to the nearest multiple of lineHeight + return (_offset.pixels ~/ lineHeight) * lineHeight; } /// The height of a terminal line in pixels. This includes the line spacing. @@ -373,7 +376,15 @@ class RenderTerminal extends RenderBox with RelayoutWhenSystemFontsChangeMixin { } double get _maxScrollExtent { - return max(_terminalHeight - _viewportHeight, 0.0); + final totalLines = _terminal.buffer.lines.length; + final totalHeight = totalLines * _painter.cellSize.height; + final viewportHeight = _viewportHeight; + final maxExtent = totalHeight - viewportHeight; + + final lineHeight = _painter.cellSize.height; + final adjustedMaxExtent = (maxExtent / lineHeight).ceil() * lineHeight; + + return max(0.0, adjustedMaxExtent); } double get _lineOffset { @@ -400,15 +411,14 @@ class RenderTerminal extends RenderBox with RelayoutWhenSystemFontsChangeMixin { void _paint(PaintingContext context, Offset offset) { final canvas = context.canvas; - final lines = _terminal.buffer.lines; final charHeight = _painter.cellSize.height; final firstLineOffset = _scrollOffset - _padding.top; - final lastLineOffset = _scrollOffset + size.height + _padding.bottom; + final lastLineOffset = _scrollOffset + size.height - _padding.bottom; - final firstLine = firstLineOffset ~/ charHeight; - final lastLine = lastLineOffset ~/ charHeight; + final firstLine = (firstLineOffset / charHeight).ceil(); + final lastLine = (lastLineOffset / charHeight).floor() - 1; final effectFirstLine = firstLine.clamp(0, lines.length - 1); final effectLastLine = lastLine.clamp(0, lines.length - 1);