writeString method

  1. @override
void writeString(
  1. int x,
  2. int y,
  3. String text,
  4. Style style,
)
override

Writes styled text to the buffer starting at (x, y).

Newlines (\n) will wrap to y + 1 at the starting column x. Any characters that fall out of bounds are clipped.

Implementation

@override
void writeString(int x, int y, String text, Style style) {
  final startX = x;
  final chars = text.characters;
  var currentX = x;
  var currentY = y;

  for (final char in chars) {
    if (char == '\n') {
      currentX = startX;
      currentY++;
      continue;
    }
    if (currentX >= 0 &&
        currentX < bounds.width &&
        currentY >= 0 &&
        currentY < bounds.height) {
      // Clear potential wide char we are about to overwrite
      final cell = parent.getCell(bounds.x + currentX, bounds.y + currentY);
      if (cell != null) {
        if (cell.char == '') {
          if (currentX - 1 >= 0) {
            final prevCell = parent.getCell(
              bounds.x + currentX - 1,
              bounds.y + currentY,
            );
            if (prevCell != null && isWideGrapheme(prevCell.char)) {
              prevCell.char = ' ';
            }
          }
        } else if (isWideGrapheme(cell.char)) {
          if (currentX + 1 < bounds.width) {
            final nextCell = parent.getCell(
              bounds.x + currentX + 1,
              bounds.y + currentY,
            );
            if (nextCell != null && nextCell.char == '') {
              nextCell.char = ' ';
            }
          }
        }
      }

      final isWide = isWideGrapheme(char);
      if (isWide && currentX == bounds.width - 1) {
        // Can't fit wide character in the last column, write a space instead
        final cell = parent.getCell(bounds.x + currentX, bounds.y + currentY);
        if (cell != null) {
          cell.char = ' ';
          cell.style = Style(
            foreground: style.foreground,
            background: style.background ?? cell.style.background,
            modifiers: style.modifiers,
          );
        }
        currentX += 1;
      } else {
        final cell = parent.getCell(bounds.x + currentX, bounds.y + currentY);
        if (cell != null) {
          cell.char = char;
          cell.style = Style(
            foreground: style.foreground,
            background: style.background ?? cell.style.background,
            modifiers: style.modifiers,
          );
        }
        if (isWide) {
          if (currentX + 1 < bounds.width) {
            // Clear potential wide char we are overwriting in the next cell
            final nextCell = parent.getCell(
              bounds.x + currentX + 1,
              bounds.y + currentY,
            );
            if (nextCell != null) {
              if (isWideGrapheme(nextCell.char) &&
                  currentX + 2 < bounds.width) {
                final nextNextCell = parent.getCell(
                  bounds.x + currentX + 2,
                  bounds.y + currentY,
                );
                if (nextNextCell != null && nextNextCell.char == '') {
                  nextNextCell.char = ' ';
                }
              }
              nextCell.char = '';
              nextCell.style = Style(
                foreground: style.foreground,
                background: style.background ?? nextCell.style.background,
                modifiers: style.modifiers,
              );
            }
          }
          currentX += 2;
        } else {
          currentX += 1;
        }
      }
    } else {
      currentX += 1;
    }
  }
}