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 currentChar = parent.getCharacter(
bounds.x + currentX,
bounds.y + currentY,
);
if (currentChar == '') {
if (currentX - 1 >= 0) {
final prevChar = parent.getCharacter(
bounds.x + currentX - 1,
bounds.y + currentY,
);
if (isWideGrapheme(prevChar)) {
parent.setAttributes(
bounds.x + currentX - 1,
bounds.y + currentY,
char: ' ',
);
}
}
} else if (isWideGrapheme(currentChar)) {
if (currentX + 1 < bounds.width) {
final nextChar = parent.getCharacter(
bounds.x + currentX + 1,
bounds.y + currentY,
);
if (nextChar == '') {
parent.setAttributes(
bounds.x + currentX + 1,
bounds.y + currentY,
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 currentBg = parent.getBackground(
bounds.x + currentX,
bounds.y + currentY,
);
parent.setAttributes(
bounds.x + currentX,
bounds.y + currentY,
char: ' ',
fg: style.foreground?.argb ?? 0,
bg: style.background?.argb ?? currentBg,
modifiers: style.modifiers,
);
currentX += 1;
} else {
final currentBg = parent.getBackground(
bounds.x + currentX,
bounds.y + currentY,
);
parent.setAttributes(
bounds.x + currentX,
bounds.y + currentY,
char: char,
fg: style.foreground?.argb ?? 0,
bg: style.background?.argb ?? currentBg,
modifiers: style.modifiers,
);
if (isWide) {
if (currentX + 1 < bounds.width) {
// Clear potential wide char we are overwriting in the next cell
final nextChar = parent.getCharacter(
bounds.x + currentX + 1,
bounds.y + currentY,
);
if (isWideGrapheme(nextChar) && currentX + 2 < bounds.width) {
final nextNextChar = parent.getCharacter(
bounds.x + currentX + 2,
bounds.y + currentY,
);
if (nextNextChar == '') {
parent.setAttributes(
bounds.x + currentX + 2,
bounds.y + currentY,
char: ' ',
);
}
}
final nextBg = parent.getBackground(
bounds.x + currentX + 1,
bounds.y + currentY,
);
parent.setAttributes(
bounds.x + currentX + 1,
bounds.y + currentY,
char: '',
fg: style.foreground?.argb ?? 0,
bg: style.background?.argb ?? nextBg,
modifiers: style.modifiers,
);
}
currentX += 2;
} else {
currentX += 1;
}
}
} else {
currentX += 1;
}
}
}