From 0bd87483cc75d18500fa2f2dfba246f95da8cc90 Mon Sep 17 00:00:00 2001 From: James Holderness Date: Thu, 25 Jun 2020 03:03:17 +0100 Subject: [PATCH 1/5] Add support for the overline attribute in conhost. --- src/buffer/out/TextAttribute.cpp | 10 ++++++++++ src/buffer/out/TextAttribute.hpp | 2 ++ src/terminal/adapter/DispatchTypes.hpp | 2 ++ src/terminal/adapter/adaptDispatchGraphics.cpp | 6 ++++++ 4 files changed, 20 insertions(+) diff --git a/src/buffer/out/TextAttribute.cpp b/src/buffer/out/TextAttribute.cpp index f9e1426d05a..da92768eef1 100644 --- a/src/buffer/out/TextAttribute.cpp +++ b/src/buffer/out/TextAttribute.cpp @@ -223,6 +223,11 @@ bool TextAttribute::IsUnderlined() const noexcept return WI_IsFlagSet(_wAttrLegacy, COMMON_LVB_UNDERSCORE); } +bool TextAttribute::IsOverlined() const noexcept +{ + return WI_IsFlagSet(_wAttrLegacy, COMMON_LVB_GRID_HORIZONTAL); +} + bool TextAttribute::IsReverseVideo() const noexcept { return WI_IsFlagSet(_wAttrLegacy, COMMON_LVB_REVERSE_VIDEO); @@ -259,6 +264,11 @@ void TextAttribute::SetUnderline(bool isUnderlined) noexcept WI_UpdateFlag(_wAttrLegacy, COMMON_LVB_UNDERSCORE, isUnderlined); } +void TextAttribute::SetOverline(bool isOverlined) noexcept +{ + WI_UpdateFlag(_wAttrLegacy, COMMON_LVB_GRID_HORIZONTAL, isOverlined); +} + void TextAttribute::SetReverseVideo(bool isReversed) noexcept { WI_UpdateFlag(_wAttrLegacy, COMMON_LVB_REVERSE_VIDEO, isReversed); diff --git a/src/buffer/out/TextAttribute.hpp b/src/buffer/out/TextAttribute.hpp index 24f0d85d883..7f645942c0e 100644 --- a/src/buffer/out/TextAttribute.hpp +++ b/src/buffer/out/TextAttribute.hpp @@ -95,6 +95,7 @@ class TextAttribute final bool IsInvisible() const noexcept; bool IsCrossedOut() const noexcept; bool IsUnderlined() const noexcept; + bool IsOverlined() const noexcept; bool IsReverseVideo() const noexcept; void SetBold(bool isBold) noexcept; @@ -103,6 +104,7 @@ class TextAttribute final void SetInvisible(bool isInvisible) noexcept; void SetCrossedOut(bool isCrossedOut) noexcept; void SetUnderline(bool isUnderlined) noexcept; + void SetOverline(bool isOverlined) noexcept; void SetReverseVideo(bool isReversed) noexcept; ExtendedAttributes GetExtendedAttributes() const noexcept; diff --git a/src/terminal/adapter/DispatchTypes.hpp b/src/terminal/adapter/DispatchTypes.hpp index 0c8c9b4fccc..c8ed665c65e 100644 --- a/src/terminal/adapter/DispatchTypes.hpp +++ b/src/terminal/adapter/DispatchTypes.hpp @@ -55,6 +55,8 @@ namespace Microsoft::Console::VirtualTerminal::DispatchTypes BackgroundWhite = 47, BackgroundExtended = 48, BackgroundDefault = 49, + Overline = 53, + NoOverline = 55, BrightForegroundBlack = 90, BrightForegroundRed = 91, BrightForegroundGreen = 92, diff --git a/src/terminal/adapter/adaptDispatchGraphics.cpp b/src/terminal/adapter/adaptDispatchGraphics.cpp index 7cb0d161f65..878f0ed0892 100644 --- a/src/terminal/adapter/adaptDispatchGraphics.cpp +++ b/src/terminal/adapter/adaptDispatchGraphics.cpp @@ -166,6 +166,12 @@ bool AdaptDispatch::SetGraphicsRendition(const std::basic_string_view Date: Thu, 25 Jun 2020 03:25:23 +0100 Subject: [PATCH 2/5] Forward the overline attribute over conpty. --- src/renderer/vt/VtSequences.cpp | 11 +++++++++++ src/renderer/vt/Xterm256Engine.cpp | 6 ++++++ src/renderer/vt/vtrenderer.hpp | 1 + 3 files changed, 18 insertions(+) diff --git a/src/renderer/vt/VtSequences.cpp b/src/renderer/vt/VtSequences.cpp index 32d80c31236..3913a611b79 100644 --- a/src/renderer/vt/VtSequences.cpp +++ b/src/renderer/vt/VtSequences.cpp @@ -355,6 +355,17 @@ using namespace Microsoft::Console::Render; return _Write(isUnderlined ? "\x1b[4m" : "\x1b[24m"); } +// Method Description: +// - Formats and writes a sequence to change the overline of the following text. +// Arguments: +// - isOverlined: If true, we'll overline the text. Otherwise we'll remove the overline. +// Return Value: +// - S_OK if we succeeded, else an appropriate HRESULT for failing to allocate or write. +[[nodiscard]] HRESULT VtEngine::_SetOverline(const bool isOverlined) noexcept +{ + return _Write(isOverlined ? "\x1b[53m" : "\x1b[55m"); +} + // Method Description: // - Formats and writes a sequence to change the italics of the following text. // Arguments: diff --git a/src/renderer/vt/Xterm256Engine.cpp b/src/renderer/vt/Xterm256Engine.cpp index a449d912bba..80408ba8a39 100644 --- a/src/renderer/vt/Xterm256Engine.cpp +++ b/src/renderer/vt/Xterm256Engine.cpp @@ -53,6 +53,12 @@ Xterm256Engine::Xterm256Engine(_In_ wil::unique_hfile hPipe, _lastTextAttributes.SetUnderline(textAttributes.IsUnderlined()); } + if (textAttributes.IsOverlined() != _lastTextAttributes.IsOverlined()) + { + RETURN_IF_FAILED(_SetOverline(textAttributes.IsOverlined())); + _lastTextAttributes.SetOverline(textAttributes.IsOverlined()); + } + if (textAttributes.IsItalic() != _lastTextAttributes.IsItalic()) { RETURN_IF_FAILED(_SetItalics(textAttributes.IsItalic())); diff --git a/src/renderer/vt/vtrenderer.hpp b/src/renderer/vt/vtrenderer.hpp index 0e7db13fe5b..dd0158c2c4c 100644 --- a/src/renderer/vt/vtrenderer.hpp +++ b/src/renderer/vt/vtrenderer.hpp @@ -187,6 +187,7 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT _SetBold(const bool isBold) noexcept; [[nodiscard]] HRESULT _SetUnderline(const bool isUnderlined) noexcept; + [[nodiscard]] HRESULT _SetOverline(const bool isUnderlined) noexcept; [[nodiscard]] HRESULT _SetItalics(const bool isItalic) noexcept; [[nodiscard]] HRESULT _SetBlinking(const bool isBlinking) noexcept; [[nodiscard]] HRESULT _SetInvisible(const bool isInvisible) noexcept; From b74536e6189e74bd085d743649f5b6b5a6c4316d Mon Sep 17 00:00:00 2001 From: James Holderness Date: Thu, 25 Jun 2020 03:37:10 +0100 Subject: [PATCH 3/5] Add support for the overline attribute in the terminal. --- src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp b/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp index 1c777864876..8efa3d859a0 100644 --- a/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp +++ b/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp @@ -157,6 +157,12 @@ bool TerminalDispatch::SetGraphicsRendition(const std::basic_string_view Date: Thu, 25 Jun 2020 12:07:55 +0100 Subject: [PATCH 4/5] Extend various unit tests to cover the overline attribute. --- src/host/ut_host/VtRendererTests.cpp | 6 +++++- src/terminal/adapter/ut_adapter/adapterTest.cpp | 12 +++++++++++- src/terminal/parser/ut_parser/OutputEngineTest.cpp | 11 ++++++++--- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/host/ut_host/VtRendererTests.cpp b/src/host/ut_host/VtRendererTests.cpp index 1bf0cb3e8d3..1a70e5b020e 100644 --- a/src/host/ut_host/VtRendererTests.cpp +++ b/src/host/ut_host/VtRendererTests.cpp @@ -746,7 +746,7 @@ void VtRendererTest::Xterm256TestExtendedAttributes() void VtRendererTest::Xterm256TestAttributesAcrossReset() { BEGIN_TEST_METHOD_PROPERTIES() - TEST_METHOD_PROPERTY(L"Data:renditionAttribute", L"{1, 3, 4, 5, 7, 8, 9}") + TEST_METHOD_PROPERTY(L"Data:renditionAttribute", L"{1, 3, 4, 5, 7, 8, 9, 53}") END_TEST_METHOD_PROPERTIES() int renditionAttribute; @@ -782,6 +782,10 @@ void VtRendererTest::Xterm256TestAttributesAcrossReset() Log::Comment(L"----Set Underline Attribute----"); textAttributes.SetUnderline(true); break; + case GraphicsOptions::Overline: + Log::Comment(L"----Set Overline Attribute----"); + textAttributes.SetOverline(true); + break; case GraphicsOptions::BlinkOrXterm256Index: Log::Comment(L"----Set Blink Attribute----"); textAttributes.SetBlinking(true); diff --git a/src/terminal/adapter/ut_adapter/adapterTest.cpp b/src/terminal/adapter/ut_adapter/adapterTest.cpp index e633b0993c5..2bb64d8b639 100644 --- a/src/terminal/adapter/ut_adapter/adapterTest.cpp +++ b/src/terminal/adapter/ut_adapter/adapterTest.cpp @@ -1261,7 +1261,7 @@ class AdapterTest TEST_METHOD(GraphicsSingleTests) { BEGIN_TEST_METHOD_PROPERTIES() - TEST_METHOD_PROPERTY(L"Data:uiGraphicsOptions", L"{0, 1, 4, 7, 24, 27, 30, 31, 32, 33, 34, 35, 36, 37, 39, 40, 41, 42, 43, 44, 45, 46, 47, 49, 90, 91, 92, 93, 94, 95, 96, 97, 100, 101, 102, 103, 104, 105, 106, 107}") // corresponds to options in DispatchTypes::GraphicsOptions + TEST_METHOD_PROPERTY(L"Data:uiGraphicsOptions", L"{0, 1, 4, 7, 24, 27, 30, 31, 32, 33, 34, 35, 36, 37, 39, 40, 41, 42, 43, 44, 45, 46, 47, 49, 53, 55, 90, 91, 92, 93, 94, 95, 96, 97, 100, 101, 102, 103, 104, 105, 106, 107}") // corresponds to options in DispatchTypes::GraphicsOptions END_TEST_METHOD_PROPERTIES() Log::Comment(L"Starting test..."); @@ -1295,6 +1295,11 @@ class AdapterTest _testGetSet->_attribute = TextAttribute{ 0 }; _testGetSet->_expectedAttribute = TextAttribute{ COMMON_LVB_UNDERSCORE }; break; + case DispatchTypes::GraphicsOptions::Overline: + Log::Comment(L"Testing graphics 'Overline'"); + _testGetSet->_attribute = TextAttribute{ 0 }; + _testGetSet->_expectedAttribute = TextAttribute{ COMMON_LVB_GRID_HORIZONTAL }; + break; case DispatchTypes::GraphicsOptions::Negative: Log::Comment(L"Testing graphics 'Negative'"); _testGetSet->_attribute = TextAttribute{ 0 }; @@ -1305,6 +1310,11 @@ class AdapterTest _testGetSet->_attribute = TextAttribute{ COMMON_LVB_UNDERSCORE }; _testGetSet->_expectedAttribute = TextAttribute{ 0 }; break; + case DispatchTypes::GraphicsOptions::NoOverline: + Log::Comment(L"Testing graphics 'No Overline'"); + _testGetSet->_attribute = TextAttribute{ COMMON_LVB_GRID_HORIZONTAL }; + _testGetSet->_expectedAttribute = TextAttribute{ 0 }; + break; case DispatchTypes::GraphicsOptions::Positive: Log::Comment(L"Testing graphics 'Positive'"); _testGetSet->_attribute = TextAttribute{ COMMON_LVB_REVERSE_VIDEO }; diff --git a/src/terminal/parser/ut_parser/OutputEngineTest.cpp b/src/terminal/parser/ut_parser/OutputEngineTest.cpp index f16ebf1aad5..3f5ea2a25ac 100644 --- a/src/terminal/parser/ut_parser/OutputEngineTest.cpp +++ b/src/terminal/parser/ut_parser/OutputEngineTest.cpp @@ -1602,6 +1602,9 @@ class StateMachineExternalTest final mach.ProcessCharacter(L';'); mach.ProcessCharacter(L'4'); mach.ProcessCharacter(L'5'); + mach.ProcessCharacter(L';'); + mach.ProcessCharacter(L'5'); + mach.ProcessCharacter(L'3'); mach.ProcessCharacter(L'm'); VERIFY_IS_TRUE(pDispatch->_setGraphics); @@ -1610,7 +1613,8 @@ class StateMachineExternalTest final rgExpected[2] = DispatchTypes::GraphicsOptions::Negative; rgExpected[3] = DispatchTypes::GraphicsOptions::ForegroundBlack; rgExpected[4] = DispatchTypes::GraphicsOptions::BackgroundMagenta; - VerifyDispatchTypes({ rgExpected, 5 }, *pDispatch); + rgExpected[5] = DispatchTypes::GraphicsOptions::Overline; + VerifyDispatchTypes({ rgExpected, 6 }, *pDispatch); pDispatch->ClearState(); @@ -1822,7 +1826,7 @@ class StateMachineExternalTest final Log::Comment(L"Test 2: A couple of sequences all in one string"); - mach.ProcessString(L"\x1b[1;4;7;30;45m\x1b[2J"); + mach.ProcessString(L"\x1b[1;4;7;30;45;53m\x1b[2J"); VERIFY_IS_TRUE(pDispatch->_setGraphics); VERIFY_IS_TRUE(pDispatch->_eraseDisplay); @@ -1831,8 +1835,9 @@ class StateMachineExternalTest final rgExpected[2] = DispatchTypes::GraphicsOptions::Negative; rgExpected[3] = DispatchTypes::GraphicsOptions::ForegroundBlack; rgExpected[4] = DispatchTypes::GraphicsOptions::BackgroundMagenta; + rgExpected[5] = DispatchTypes::GraphicsOptions::Overline; expectedDispatchTypes = DispatchTypes::EraseType::All; - VerifyDispatchTypes({ rgExpected, 5 }, *pDispatch); + VerifyDispatchTypes({ rgExpected, 6 }, *pDispatch); VERIFY_ARE_EQUAL(expectedDispatchTypes, pDispatch->_eraseType); pDispatch->ClearState(); From 83f60502c0817bd2981ccbc9c17308ee18ecc68b Mon Sep 17 00:00:00 2001 From: James Holderness Date: Thu, 25 Jun 2020 13:31:52 +0100 Subject: [PATCH 5/5] Add "overlined" to the spell-check dictionary. --- .github/actions/spell-check/dictionary/dictionary.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/spell-check/dictionary/dictionary.txt b/.github/actions/spell-check/dictionary/dictionary.txt index d3590ea587f..c01a75b1927 100644 --- a/.github/actions/spell-check/dictionary/dictionary.txt +++ b/.github/actions/spell-check/dictionary/dictionary.txt @@ -284908,6 +284908,7 @@ overliing overliking overlimit overline +overlined overling overlinger overlinked