resize method
void
resize(
- int oldWidth,
- int oldHeight,
- int newWidth,
- int newHeight,
)
Implementation
void resize(int oldWidth, int oldHeight, int newWidth, int newHeight) {
if (newHeight > lines.maxLength) {
lines.maxLength = newHeight;
}
// 1. Adjust the height.
if (newHeight > oldHeight) {
// Grow larger
for (var i = 0; i < newHeight - oldHeight; i++) {
if (newHeight > lines.length) {
lines.push(_newEmptyLine(newWidth));
} else {
_cursorY++;
_savedCursorY++;
}
}
} else {
// Shrink smaller
for (var i = 0; i < oldHeight - newHeight; i++) {
if (_cursorY > newHeight - 1) {
_cursorY--;
} else {
lines.pop();
}
}
}
// Ensure cursor row is within the screen. The column is clamped after
// width handling so reflow can preserve its logical offset.
_cursorY = _cursorY.clamp(0, newHeight - 1);
_savedCursorY = _savedCursorY.clamp(0, newHeight - 1);
// 2. Adjust the width.
if (newWidth != oldWidth) {
if (terminal.reflowEnabled && !isAltBuffer) {
final cursorScrollBack = max(lines.length - newHeight, 0);
final cursorLine = _cursorY + cursorScrollBack;
final cursorPendingWrap = _cursorX >= _rightLimit;
final cursorAnchorX = switch (cursorPendingWrap) {
true => max(0, _cursorX - 1),
false => _cursorX,
};
final cursorAnchor = lines[cursorLine].createAnchor(cursorAnchorX);
final savedCursorLine = _savedCursorY + cursorScrollBack;
final savedCursorAnchorX = switch (_savedPendingWrap) {
true => max(0, _savedCursorX - 1),
false => _savedCursorX,
};
final savedCursorAnchor =
lines[savedCursorLine].createAnchor(savedCursorAnchorX);
final reflowResult = reflow(lines, oldWidth, newWidth);
while (reflowResult.length < newHeight) {
reflowResult.add(_newEmptyLine(newWidth));
}
lines.replaceWith(reflowResult);
if (cursorAnchor.attached) {
final newScrollBack = max(lines.length - newHeight, 0);
_cursorX = _reflowedCursorX(
cursorAnchor,
pendingWrap: cursorPendingWrap,
newWidth: newWidth,
);
_cursorY = (cursorAnchor.y - newScrollBack).clamp(0, newHeight - 1);
}
if (savedCursorAnchor.attached) {
final newScrollBack = max(lines.length - newHeight, 0);
final savedCursorAtRightEdge = savedCursorAnchor.x == newWidth - 1;
_savedCursorX = _reflowedCursorX(
savedCursorAnchor,
pendingWrap: _savedPendingWrap,
newWidth: newWidth,
);
_savedCursorY =
(savedCursorAnchor.y - newScrollBack).clamp(0, newHeight - 1);
_savedPendingWrap = _savedPendingWrap && savedCursorAtRightEdge;
} else {
_savedCursorX = _savedCursorX.clamp(0, newWidth - 1);
_savedPendingWrap = false;
}
cursorAnchor.dispose();
savedCursorAnchor.dispose();
} else {
lines.forEach((item) {
// BufferLine.resize intentionally preserves cell data beyond the
// new length so it can reappear if the line is grown back later
// (see the "preserves hidden cells" resize tests) - it does not
// enforce the width-2/placeholder pairing invariant. If this line
// was shrunk smaller than newWidth in the past and is now being
// grown, the newly exposed last cell may be a stale wide-char
// lead with no room left for its placeholder, so clear it (same
// guard applied by reflow() for the reflow-enabled path).
item.resize(newWidth);
if (newWidth > 0 && item.getWidth(newWidth - 1) == 2) {
item.resetCell(newWidth - 1);
}
});
_cursorX = _cursorX.clamp(0, newWidth - 1);
_savedCursorX = _savedCursorX.clamp(0, newWidth - 1);
_savedPendingWrap = false;
}
}
_cursorX = _cursorX.clamp(0, newWidth);
_marginLeft = 0;
_marginRight = newWidth - 1;
}