Skip to content

Commit

Permalink
AtlasEngine: Fix a crash when drawing double width rows (#13966)
Browse files Browse the repository at this point in the history
The `TileHashMap` refresh via `makeNewest()` in `StartPaint()` depends
on us filling the entire `cellGlyphMapping` row with valid data.
This commit makes sure to initialize the `cellGlyphMapping` buffer.
Additionally it clears the rest of the row with whitespace
until proper `LineRendition` support is added.

Closes #13962

## Validation Steps Performed
* vttest's "Test of double-sized characters" stops crashing ✅
* No weird leftover characters ✅
  • Loading branch information
lhecker authored Sep 15, 2022
1 parent e2b2d9b commit 16aa79d
Showing 1 changed file with 24 additions and 0 deletions.
24 changes: 24 additions & 0 deletions src/renderer/atlas/AtlasEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,21 @@ void AtlasEngine::_recreateSizeDependentResources()
_api.glyphProps = Buffer<DWRITE_SHAPING_GLYPH_PROPERTIES>{ projectedGlyphSize };
_api.glyphAdvances = Buffer<f32>{ projectedGlyphSize };
_api.glyphOffsets = Buffer<DWRITE_GLYPH_OFFSET>{ projectedGlyphSize };

// Initialize cellGlyphMapping with valid data (whitespace), so that it can be
// safely used by the TileHashMap refresh logic via makeNewest() in StartPaint().
{
u16x2* coords{};
AtlasKey key{ { .cellCount = 1 }, 1, L" " };
AtlasValue value{ CellFlags::None, 1, &coords };

coords[0] = _r.tileAllocator.allocate(_r.glyphs);

const auto it = _r.glyphs.insert(std::move(key), std::move(value));
_r.glyphQueue.emplace_back(it);

std::fill(_r.cellGlyphMapping.begin(), _r.cellGlyphMapping.end(), it);
}
}

if (!_r.d2dMode)
Expand Down Expand Up @@ -1197,6 +1212,15 @@ void AtlasEngine::_flushBufferLine()
// This would seriously blow us up otherwise.
Expects(_api.bufferLineColumn.size() == _api.bufferLine.size() + 1);

// GH#13962: With the lack of proper LineRendition support, just fill
// the remaining columns with whitespace to prevent any weird artifacts.
for (auto lastColumn = _api.bufferLineColumn.back(); lastColumn < _api.cellCount.x;)
{
++lastColumn;
_api.bufferLine.emplace_back(L' ');
_api.bufferLineColumn.emplace_back(lastColumn);
}

// NOTE:
// This entire function is one huge hack to see if it works.

Expand Down

0 comments on commit 16aa79d

Please sign in to comment.