mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-06 06:09:50 +00:00
Compare commits
1 Commits
dev/migrie
...
dev/lhecke
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d16a3e53a |
@@ -359,6 +359,39 @@ void VtIo::FormatAttributes(std::wstring& target, const TextAttribute& attribute
|
||||
target.append(bufW, len);
|
||||
}
|
||||
|
||||
wchar_t VtIo::SanitizeUCS2(wchar_t ch) noexcept
|
||||
{
|
||||
// If any of the values in the buffer are C0 or C1 controls, we need to
|
||||
// convert them to printable codepoints, otherwise they'll end up being
|
||||
// evaluated as control characters by the receiving terminal. We use the
|
||||
// DOS 437 code page for the C0 controls and DEL, and just a `?` for the
|
||||
// C1 controls, since that's what you would most likely have seen in the
|
||||
// legacy v1 console with raster fonts.
|
||||
if (ch < 0x20)
|
||||
{
|
||||
static constexpr wchar_t lut[] = {
|
||||
// clang-format off
|
||||
L' ', L'☺', L'☻', L'♥', L'♦', L'♣', L'♠', L'•', L'◘', L'○', L'◙', L'♂', L'♀', L'♪', L'♫', L'☼',
|
||||
L'►', L'◄', L'↕', L'‼', L'¶', L'§', L'▬', L'↨', L'↑', L'↓', L'→', L'←', L'∟', L'↔', L'▲', L'▼',
|
||||
// clang-format on
|
||||
};
|
||||
ch = lut[ch];
|
||||
}
|
||||
else if (ch == 0x7F)
|
||||
{
|
||||
ch = L'⌂';
|
||||
}
|
||||
else if (ch > 0x7F && ch < 0xA0)
|
||||
{
|
||||
ch = L'?';
|
||||
}
|
||||
else if (til::is_surrogate(ch))
|
||||
{
|
||||
ch = UNICODE_REPLACEMENT;
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
VtIo::Writer::Writer(VtIo* io) noexcept :
|
||||
_io{ io }
|
||||
{
|
||||
@@ -592,7 +625,7 @@ void VtIo::Writer::WriteUTF16StripControlChars(std::wstring_view str) const
|
||||
|
||||
for (it = begControlChars; it != end && IsControlCharacter(*it); ++it)
|
||||
{
|
||||
WriteUCS2StripControlChars(*it);
|
||||
WriteUCS2(SanitizeUCS2(*it));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -626,36 +659,6 @@ void VtIo::Writer::WriteUCS2(wchar_t ch) const
|
||||
_io->_back.append(buf, len);
|
||||
}
|
||||
|
||||
void VtIo::Writer::WriteUCS2StripControlChars(wchar_t ch) const
|
||||
{
|
||||
// If any of the values in the buffer are C0 or C1 controls, we need to
|
||||
// convert them to printable codepoints, otherwise they'll end up being
|
||||
// evaluated as control characters by the receiving terminal. We use the
|
||||
// DOS 437 code page for the C0 controls and DEL, and just a `?` for the
|
||||
// C1 controls, since that's what you would most likely have seen in the
|
||||
// legacy v1 console with raster fonts.
|
||||
if (ch < 0x20)
|
||||
{
|
||||
static constexpr wchar_t lut[] = {
|
||||
// clang-format off
|
||||
L' ', L'☺', L'☻', L'♥', L'♦', L'♣', L'♠', L'•', L'◘', L'○', L'◙', L'♂', L'♀', L'♪', L'♫', L'☼',
|
||||
L'►', L'◄', L'↕', L'‼', L'¶', L'§', L'▬', L'↨', L'↑', L'↓', L'→', L'←', L'∟', L'↔', L'▲', L'▼',
|
||||
// clang-format on
|
||||
};
|
||||
ch = lut[ch];
|
||||
}
|
||||
else if (ch == 0x7F)
|
||||
{
|
||||
ch = L'⌂';
|
||||
}
|
||||
else if (ch > 0x7F && ch < 0xA0)
|
||||
{
|
||||
ch = L'?';
|
||||
}
|
||||
|
||||
WriteUCS2(ch);
|
||||
}
|
||||
|
||||
// CUP: Cursor Position
|
||||
void VtIo::Writer::WriteCUP(til::point position) const
|
||||
{
|
||||
|
||||
@@ -35,7 +35,6 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
void WriteUTF16TranslateCRLF(std::wstring_view str) const;
|
||||
void WriteUTF16StripControlChars(std::wstring_view str) const;
|
||||
void WriteUCS2(wchar_t ch) const;
|
||||
void WriteUCS2StripControlChars(wchar_t ch) const;
|
||||
void WriteCUP(til::point position) const;
|
||||
void WriteDECTCEM(bool enabled) const;
|
||||
void WriteSGR1006(bool enabled) const;
|
||||
@@ -54,6 +53,7 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
|
||||
static void FormatAttributes(std::string& target, const TextAttribute& attributes);
|
||||
static void FormatAttributes(std::wstring& target, const TextAttribute& attributes);
|
||||
static wchar_t SanitizeUCS2(wchar_t ch) noexcept;
|
||||
|
||||
[[nodiscard]] HRESULT Initialize(const ConsoleArguments* const pArgs);
|
||||
[[nodiscard]] HRESULT CreateAndStartSignalThread() noexcept;
|
||||
|
||||
@@ -316,8 +316,8 @@ void ScrollRegion(SCREEN_INFORMATION& screenInfo,
|
||||
const til::inclusive_rect scrollRectGiven,
|
||||
const std::optional<til::inclusive_rect> clipRectGiven,
|
||||
const til::point destinationOriginGiven,
|
||||
const wchar_t fillCharGiven,
|
||||
const TextAttribute fillAttrsGiven)
|
||||
wchar_t fillCharGiven,
|
||||
TextAttribute fillAttrsGiven)
|
||||
{
|
||||
// ------ 1. PREP SOURCE ------
|
||||
// Set up the source viewport.
|
||||
@@ -357,16 +357,14 @@ void ScrollRegion(SCREEN_INFORMATION& screenInfo,
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine the cell we will use to fill in any revealed/uncovered space.
|
||||
// We generally use exactly what was given to us.
|
||||
OutputCellIterator fillData(fillCharGiven, fillAttrsGiven);
|
||||
|
||||
// However, if the character is null and we were given a null attribute (represented as legacy 0),
|
||||
// then we'll just fill with spaces and whatever the buffer's default colors are.
|
||||
if (fillCharGiven == UNICODE_NULL && fillAttrsGiven == TextAttribute{ 0 })
|
||||
{
|
||||
fillData = OutputCellIterator(UNICODE_SPACE, screenInfo.GetAttributes());
|
||||
}
|
||||
fillAttrsGiven = screenInfo.GetAttributes();
|
||||
}
|
||||
|
||||
fillCharGiven = Microsoft::Console::VirtualTerminal::VtIo::SanitizeUCS2(UNICODE_SPACE);
|
||||
|
||||
// ------ 4. PREP TARGET ------
|
||||
// Now it's time to think about the target. We're only given the origin of the target
|
||||
@@ -422,12 +420,13 @@ void ScrollRegion(SCREEN_INFORMATION& screenInfo,
|
||||
// So use the special subtraction function to get the viewports that fall
|
||||
// within the fill area but outside of the target area.
|
||||
const auto remaining = Viewport::Subtract(fill, target);
|
||||
auto& textBuffer = screenInfo.GetTextBuffer();
|
||||
|
||||
// Apply the fill data to each of the viewports we're given here.
|
||||
for (size_t i = 0; i < remaining.size(); i++)
|
||||
{
|
||||
const auto& view = remaining.at(i);
|
||||
screenInfo.WriteRect(fillData, view);
|
||||
textBuffer.FillRect(view.ToExclusive(), {&fillCharGiven, 1}, fillAttrsGiven);
|
||||
|
||||
// If the region has image content it needs to be erased.
|
||||
ImageSlice::EraseBlock(screenInfo.GetTextBuffer(), view.ToExclusive());
|
||||
|
||||
Reference in New Issue
Block a user