fix(console): correct CRT scanline alternation (was skipping rows)
The per-line scanline shade alternated on rowIndex = floor((cumulativeY + yOffset) / lineHeight + 0.5), but cumulativeY includes the 2px inter-line gap while the divisor is lineHeight alone. That drifts ~0.14 row per line and, with the rounding, jumps the index by 2 every ~7 rows — so two adjacent rows get the same shade and the alternation visibly breaks in patches. Replace it with a true per-visual-row counter (one increment per drawn sub-row), seeded with the first on-screen line's sub-row ordinal so the shading stays stable while scrolling. Parity now alternates exactly every row. Full-node + lite build clean; source hygiene clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -836,6 +836,14 @@ void ConsoleTab::drawVisibleLines(float padX, float lineHeight, bool hasTextFilt
|
||||
// mid-draw. -1 = none.
|
||||
int pendingFoldToggle = -1;
|
||||
|
||||
// CRT scanline parity is a true per-visual-row counter (each drawn sub-row = one row).
|
||||
// Deriving it from cumulativeY/lineHeight drifted (cumulativeY includes the inter-line
|
||||
// gap) and skipped rows, breaking the alternation. Seed it with the sub-row ordinal of
|
||||
// the first on-screen line so the shading stays stable across scrolling.
|
||||
int scanRowOrdinal = 0;
|
||||
for (int k = 0; k < first_visible && k < static_cast<int>(layout_.segments.size()); k++)
|
||||
scanRowOrdinal += static_cast<int>(layout_.segments[k].size());
|
||||
|
||||
int last_rendered_vi = first_visible - 1;
|
||||
for (int vi = first_visible; vi < visible_count; vi++) {
|
||||
if (vi < static_cast<int>(layout_.cumulativeY.size()) &&
|
||||
@@ -917,9 +925,9 @@ void ConsoleTab::drawVisibleLines(float padX, float lineHeight, bool hasTextFilt
|
||||
const char* segEnd = line.text.c_str() + seg.byteEnd;
|
||||
|
||||
if (s_scanline_enabled && lineHeight > 0.0f) {
|
||||
int rowIndex = static_cast<int>(std::floor((layout_.cumulativeY[vi] + seg.yOffset) / lineHeight + 0.5f));
|
||||
scanline_rows_.push_back({rowY, rowY + seg.height, rowIndex});
|
||||
scanline_rows_.push_back({rowY, rowY + seg.height, scanRowOrdinal});
|
||||
}
|
||||
++scanRowOrdinal; // one per visual sub-row, so parity always alternates
|
||||
|
||||
// Selection highlight for this sub-row
|
||||
if (lineSelected && selByteStart < seg.byteEnd && selByteEnd > seg.byteStart) {
|
||||
|
||||
Reference in New Issue
Block a user