diff --git a/src/terminal/adapter/SixelParser.cpp b/src/terminal/adapter/SixelParser.cpp index 979dd42371c..46407e2a54a 100644 --- a/src/terminal/adapter/SixelParser.cpp +++ b/src/terminal/adapter/SixelParser.cpp @@ -341,6 +341,11 @@ void SixelParser::_initRasterAttributes(const VTInt macroParameter, const Dispat // By default, the filled area will cover the maximum extent allowed. _backgroundSize = { til::CoordTypeMax, til::CoordTypeMax }; + + // If the requested background area can not initially be filled, we'll + // handle the rest of it on demand when the image is resized. But this + // will be determined later in the _fillImageBackground method. + _resizeFillRequired = false; } void SixelParser::_updateRasterAttributes(const VTParameters& rasterAttributes) @@ -647,6 +652,10 @@ void SixelParser::_resizeImageBuffer(const til::CoordType requiredHeight) { static constexpr auto transparentPixel = IndexedPixel{ .transparent = true }; _imageBuffer.resize(requiredSize, transparentPixel); + if (_resizeFillRequired) + { + _fillImageBackground(requiredHeight); + } } } @@ -656,25 +665,30 @@ void SixelParser::_fillImageBackground() { _backgroundFillRequired = false; - const auto backgroundHeight = std::min(_backgroundSize.height, _availablePixelHeight); - const auto backgroundWidth = std::min(_backgroundSize.width, _availablePixelWidth); - _resizeImageBuffer(backgroundHeight); - // When a background fill is requested, we prefill the buffer with the 0 // color index, up to the boundaries set by the raster attributes (or if - // none were given, up to the page boundaries). The actual image output - // isn't limited by the background dimensions though. - static constexpr auto backgroundPixel = IndexedPixel{}; - const auto backgroundOffset = _imageCursor.y * _imageMaxWidth; - auto dst = std::next(_imageBuffer.begin(), backgroundOffset); - for (auto i = 0; i < backgroundHeight; i++) - { - std::fill_n(dst, backgroundWidth, backgroundPixel); - std::advance(dst, _imageMaxWidth); - } + // none were given, up to the page boundaries). If the requested height + // is more than the available height, we'll continue filling the rest of + // it on demand when the image is resized (see above). + const auto backgroundHeight = std::min(_backgroundSize.height, _availablePixelHeight); + _resizeImageBuffer(backgroundHeight); + _fillImageBackground(backgroundHeight); + _resizeFillRequired = _backgroundSize.height > _availablePixelHeight; + } +} - _imageWidth = std::max(_imageWidth, backgroundWidth); +void SixelParser::_fillImageBackground(const int backgroundHeight) +{ + static constexpr auto backgroundPixel = IndexedPixel{}; + const auto backgroundWidth = std::min(_backgroundSize.width, _availablePixelWidth); + const auto backgroundOffset = _imageCursor.y * _imageMaxWidth; + auto dst = std::next(_imageBuffer.begin(), backgroundOffset); + for (auto i = 0; i < backgroundHeight; i++) + { + std::fill_n(dst, backgroundWidth, backgroundPixel); + std::advance(dst, _imageMaxWidth); } + _imageWidth = std::max(_imageWidth, backgroundWidth); } void SixelParser::_writeToImageBuffer(int sixelValue, int repeatCount) diff --git a/src/terminal/adapter/SixelParser.hpp b/src/terminal/adapter/SixelParser.hpp index 1966228d77f..0c9285881e4 100644 --- a/src/terminal/adapter/SixelParser.hpp +++ b/src/terminal/adapter/SixelParser.hpp @@ -89,6 +89,7 @@ namespace Microsoft::Console::VirtualTerminal til::CoordType _pendingTextScrollCount = 0; til::size _backgroundSize; bool _backgroundFillRequired = false; + bool _resizeFillRequired = false; void _initColorMap(const VTParameter backgroundColor); void _defineColor(const VTParameters& colorParameters); @@ -109,6 +110,7 @@ namespace Microsoft::Console::VirtualTerminal void _initImageBuffer(); void _resizeImageBuffer(const til::CoordType requiredHeight); void _fillImageBackground(); + void _fillImageBackground(const int backgroundHeight); void _writeToImageBuffer(const int sixelValue, const int repeatCount); void _eraseImageBufferRows(const int rowCount, const til::CoordType startRow = 0) noexcept; void _maybeFlushImageBuffer(const bool endOfSequence = false);