reflow_strategy_wider.dart 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import 'dart:math';
  2. import 'package:xterm/buffer/buffer.dart';
  3. import 'package:xterm/buffer/buffer_line.dart';
  4. import 'package:xterm/buffer/reflow_strategy.dart';
  5. class ReflowStrategyWider extends ReflowStrategy {
  6. ReflowStrategyWider(Buffer buffer) : super(buffer);
  7. @override
  8. void reflow(int newCols, int newRows, int oldCols, int oldRows) {
  9. final linesAfterReflow = <BufferLine>[];
  10. for (var i = 0; i < buffer.lines.length; i++) {
  11. final line = buffer.lines[i];
  12. line.ensure(newCols);
  13. linesAfterReflow.add(line);
  14. var linesToSkip = 0;
  15. for (var offset = 1; i + offset < buffer.lines.length; offset++) {
  16. final nextLine = buffer.lines[i + offset];
  17. if (!nextLine.isWrapped) {
  18. break;
  19. }
  20. // when we are reflowing wider we can be sure that this line and the next all have equal to or less than
  21. // 'newCols' length => we can pass newCols as the upper limit
  22. final lineLength = line.getTrimmedLength(newCols);
  23. var copyDestIndex = lineLength;
  24. if (copyDestIndex >= 1 &&
  25. line.cellGetWidth(copyDestIndex - 1) == 2 &&
  26. line.cellGetContent(copyDestIndex) == 0) {
  27. //we would override a wide char placeholder => move index one to the right
  28. copyDestIndex += 1;
  29. }
  30. final spaceOnLine = newCols - copyDestIndex;
  31. if (spaceOnLine <= 0) {
  32. // no more space to unwrap
  33. break;
  34. }
  35. // when we are reflowing wider we can be sure that this line and the next all have equal to or less than
  36. // 'newCols' length => we can pass newCols as the upper limit
  37. final nextLineLength = nextLine.getTrimmedLength(newCols);
  38. var moveCount = min(spaceOnLine, nextLineLength);
  39. if (moveCount <= 0) {
  40. break;
  41. }
  42. // when we are about to copy a double width character
  43. // to the end of the line then we just ignore it as the target width
  44. // would be too much
  45. if (nextLine.cellGetWidth(moveCount - 1) == 2) {
  46. moveCount -= 1;
  47. }
  48. line.copyCellsFrom(nextLine, 0, copyDestIndex, moveCount);
  49. if (moveCount >= nextLineLength) {
  50. // if we unwrapped all cells off the next line, skip it
  51. linesToSkip++;
  52. } else {
  53. // otherwise just remove the characters we moved up a line
  54. nextLine.removeN(0, moveCount);
  55. }
  56. }
  57. // skip empty lines.
  58. i += linesToSkip;
  59. }
  60. //buffer doesn't have enough lines
  61. while (linesAfterReflow.length < buffer.terminal.viewHeight) {
  62. linesAfterReflow.add(BufferLine(length: buffer.terminal.viewWidth));
  63. }
  64. buffer.lines.replaceWith(linesAfterReflow);
  65. }
  66. }