writeString method
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;
}
}
}