touchLine method
Implementation
void touchLine(int x, int y, int width) {
if (y < 0 || y >= lines.length) return;
if (width <= 0) return;
if (y >= touched.length) {
touched = [
...touched,
...List<LineData?>.filled(y - touched.length + 1, null),
];
}
if (y >= dirtyRows.length) {
dirtyRows = [
...dirtyRows,
...List<bool>.filled(y - dirtyRows.length + 1, false),
];
}
if (y >= dirtyBits.length) {
final width = this.width();
dirtyBits = [
...dirtyBits,
...List<Uint32List>.generate(
y - dirtyBits.length + 1,
(_) => Uint32List(_dirtyWordCount(width)),
),
];
}
final ch = touched[y];
final first = x;
final last = x + width;
dirtyRows[y] = true;
_markDirtyBits(y, first, last);
if (ch == null) {
touched[y] = LineData(
firstCell: first,
lastCell: last,
spans: <DirtySpan>[DirtySpan(start: first, end: last)],
);
} else {
final prevFirst = ch.firstCell == -1 ? first : ch.firstCell;
final prevLast = ch.lastCell == -1 ? last : ch.lastCell;
if (ch.overflowed) {
final mergedFirst = first < prevFirst ? first : prevFirst;
final mergedLast = last > prevLast ? last : prevLast;
touched[y] = LineData(
firstCell: mergedFirst,
lastCell: mergedLast,
spans: <DirtySpan>[DirtySpan(start: mergedFirst, end: mergedLast)],
overflowed: true,
);
return;
}
if (ch.spans.isNotEmpty) {
final lastSpan = ch.spans.last;
if (first <= lastSpan.end && first >= lastSpan.start) {
final mergedSpans = List<DirtySpan>.from(ch.spans, growable: false);
mergedSpans[mergedSpans.length - 1] = DirtySpan(
start: lastSpan.start,
end: last > lastSpan.end ? last : lastSpan.end,
);
touched[y] = LineData(
firstCell: first < prevFirst ? first : prevFirst,
lastCell: last > prevLast ? last : prevLast,
spans: mergedSpans,
overflowed: false,
);
return;
}
}
final spans = _mergeDirtySpans(
ch.spans,
DirtySpan(start: first, end: last),
);
touched[y] = LineData(
firstCell: first < prevFirst ? first : prevFirst,
lastCell: last > prevLast ? last : prevLast,
spans: spans.spans,
overflowed: spans.overflowed || ch.overflowed,
);
}
}