writeString method

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

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

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 < width &&
        currentY >= 0 &&
        currentY < height) {
      // Clear potential wide char we are about to overwrite
      final cell = cells[_index(currentX, currentY)];
      if (cell.char == '') {
        if (currentX - 1 >= 0) {
          final prevCell = cells[_index(currentX - 1, currentY)];
          if (isWideGrapheme(prevCell.char)) {
            prevCell.char = ' ';
          }
        }
      } else if (isWideGrapheme(cell.char)) {
        if (currentX + 1 < width) {
          final nextCell = cells[_index(currentX + 1, currentY)];
          if (nextCell.char == '') {
            nextCell.char = ' ';
          }
        }
      }

      final isWide = isWideGrapheme(char);
      if (isWide && currentX == width - 1) {
        // Can't fit wide character in the last column, write a space instead
        final cell = cells[_index(currentX, currentY)];
        cell.char = ' ';
        cell.style = Style(
          foreground: style.foreground,
          background: style.background ?? cell.style.background,
          modifiers: style.modifiers,
        );
        currentX += 1;
      } else {
        final cell = cells[_index(currentX, currentY)];
        cell.char = char;
        cell.style = Style(
          foreground: style.foreground,
          background: style.background ?? cell.style.background,
          modifiers: style.modifiers,
        );
        if (isWide) {
          if (currentX + 1 < width) {
            // Clear potential wide char we are overwriting in the next cell
            final nextCell = cells[_index(currentX + 1, currentY)];
            if (isWideGrapheme(nextCell.char) && currentX + 2 < width) {
              final nextNextCell = cells[_index(currentX + 2, currentY)];
              if (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;
    }
  }
}