[PR #2917] [MERGED] Add support for passing through extended text attributes, like… #25142

Open
opened 2026-01-31 09:07:32 +00:00 by claunia · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/microsoft/terminal/pull/2917
Author: @zadjii-msft
Created: 9/26/2019
Status: ✅ Merged
Merged: 10/4/2019
Merged by: @zadjii-msft

Base: master ← Head: dev/migrie/b/2554-_italics_


📝 Commits (10+)

  • 6a39606 store text with extended attributes too
  • bfee5fe Plumb attributes through all the renderers
  • 87dfc88 parse extended attrs, though we're not renderering them right
  • dedb191 Render these states correctly
  • 93aebf6 Add a very extensive test
  • 2c9f539 Cleanup for PR
  • 02d7d0e a block of PR feedback
  • 6aca2ec add 512 test cases
  • e0df256 Merge remote-tracking branch 'origin/master' into dev/migrie/b/2554-italics
  • efe6b3c Fix the build

📊 Changes

36 files changed (+938 additions, -112 deletions)

View changed files

📝 src/buffer/out/TextAttribute.cpp (+7 -7)
📝 src/buffer/out/TextAttribute.hpp (+28 -8)
📝 src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp (+2 -2)
📝 src/host/getset.cpp (+33 -0)
📝 src/host/getset.h (+3 -0)
📝 src/host/outputStream.cpp (+26 -0)
📝 src/host/outputStream.hpp (+2 -0)
📝 src/host/ut_host/ScreenBufferTests.cpp (+333 -0)
📝 src/host/ut_host/VtRendererTests.cpp (+117 -25)
📝 src/inc/conattrs.hpp (+15 -0)
📝 src/interactivity/onecore/BgfxEngine.cpp (+1 -1)
📝 src/interactivity/onecore/BgfxEngine.hpp (+1 -1)
📝 src/renderer/base/renderer.cpp (+2 -2)
📝 src/renderer/dx/DxRenderer.cpp (+2 -2)
📝 src/renderer/dx/DxRenderer.hpp (+1 -1)
📝 src/renderer/gdi/gdirenderer.hpp (+1 -1)
📝 src/renderer/gdi/state.cpp (+2 -2)
📝 src/renderer/inc/IRenderEngine.hpp (+1 -1)
📝 src/renderer/vt/VtSequences.cpp (+88 -0)
📝 src/renderer/vt/WinTelnetEngine.cpp (+7 -2)

...and 16 more files

📄 Description

Summary of the Pull Request

Adds support for Italics, Blinking, Invisible, CrossedOut text, THROUGH CONPTY. This does NOT add support for those styles to conhost or the terminal.

We will store these "Extended Text Attributes" in a TextAttribute. When we go to render a line, we'll see if the state has changed from our previous state, and if so, we'll appropriately toggle that state with VT. Boldness has been moved from a bool to a single bit in these flags.

Technically, now that these are stored in the buffer, we only need to make changes to the renderers to be able to support them. That's not being done as a part of this PR however.

References

See also #2915 and #2916, which are some follow-up tasks from this fix. I thought them too risky for 20H1.

PR Checklist

Validation Steps Performed

  • Replaced the conhost in my system32 and tried running the following script, via WSL interop:
import sys
import time # time.sleep is in seconds
def write(s):
    sys.stdout.write(s)

def csi(seq):
    sys.stdout.write('\x1b[{}'.format(seq))

def sgr(code=0):
    csi('{}m'.format(code))

def cupxy(x=0, y=0):
    cup(y+1, x+1)

def clear_all():
    cupxy(0,0)
    csi('2J')

# $ python ~/vttests/extended-attrs.py
if __name__ == '__main__':
    clear_all()
    print('This is the VT Test template.')

    sgr(0)
    write('[Normal Text]')
    sgr(3)
    write('[Italicized]')
    sgr(0)
    write('\n')

    sgr(0)
    write('[Normal Text]')
    sgr(4)
    write('[Underlined]')
    sgr(0)
    write('[Normal Again]')
    write('\n')

    sgr(0)
    write('[Normal Text]')
    sgr(4)
    write('[Underlined]')
    sgr(3)
    write('[U & I]')
    sgr(0)
    write('[Normal Again]')
    write('\n')

    sgr(0)
    write('[Normal Text]')
    sgr(4)
    write('[Underlined]')
    sgr(3)
    write('[U & I]')
    sgr(23)
    write('[Underlined]')
    sgr(0)
    write('[Normal Again]')
    write('\n')

    sgr(0)
    write('[Normal Text]')
    sgr(4)
    write('[Underlined]')
    sgr(3)
    write('[U & I]')
    sgr(24)
    write('[Italicized]')
    sgr(0)
    write('[Normal Again]')
    write('\n')

    sgr(0)
    write('[Normal Text]')
    sgr(5)
    write('[Blinking]')
    sgr(0)
    write('[Normal Again]')
    write('\n')

    sgr(0)
    write('[Normal Text]')
    sgr(8)
    write('[Invisible]')
    sgr(0)
    write('[Normal Again]')
    write('\n')

    sgr(0)
    write('[Normal Text]')
    sgr(9)
    write('[Crossed-out]')
    sgr(0)
    write('[Normal Again]')
    write('\n')

    ############################################################################


    sgr(0)
    write('[Normal Text]')
    sgr(1)
    write('[Bold]')
    sgr(3)
    write('[B & Italicized]')
    sgr(0)
    write('\n')

    sgr(0)
    write('[Normal Text]')
    sgr(1)
    write('[Bold]')
    sgr(4)
    write('[B & Underlined]')
    sgr(0)
    write('[Normal Again]')
    write('\n')

    sgr(0)
    write('[Normal Text]')
    sgr(1)
    write('[Bold]')
    sgr(4)
    write('[B & Underlined]')
    sgr(3)
    write('[B & U & I]')
    sgr(0)
    write('[Normal Again]')
    write('\n')

    sgr(0)
    write('[Normal Text]')
    sgr(1)
    write('[Bold]')
    sgr(4)
    write('[B & Underlined]')
    sgr(3)
    write('[U & I]')
    sgr(23)
    write('[B & Underlined]')
    sgr(0)
    write('[Normal Again]')
    write('\n')

    sgr(0)
    write('[Normal Text]')
    sgr(1)
    write('[Bold]')
    sgr(4)
    write('[B & Underlined]')
    sgr(3)
    write('[B & U & I]')
    sgr(24)
    write('[B & Italicized]')
    sgr(0)
    write('[Normal Again]')
    write('\n')

    sgr(0)
    write('[Normal Text]')
    sgr(1)
    write('[Bold]')
    sgr(5)
    write('[B & Blinking]')
    sgr(0)
    write('[Normal Again]')
    write('\n')

    sgr(0)
    write('[Normal Text]')
    sgr(1)
    write('[Bold]')
    sgr(8)
    write('[B & Invisible]')
    sgr(0)
    write('[Normal Again]')
    write('\n')

    sgr(0)
    write('[Normal Text]')
    sgr(1)
    write('[Bold]')
    sgr(9)
    write('[B & Crossed-out]')
    sgr(0)
    write('[Normal Again]')
    write('\n')

  • ran tests
  • Using the (added) static assert, ensured that the size of the TextAttribute did not increase.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/microsoft/terminal/pull/2917 **Author:** [@zadjii-msft](https://github.com/zadjii-msft) **Created:** 9/26/2019 **Status:** ✅ Merged **Merged:** 10/4/2019 **Merged by:** [@zadjii-msft](https://github.com/zadjii-msft) **Base:** `master` ← **Head:** `dev/migrie/b/2554-_italics_` --- ### 📝 Commits (10+) - [`6a39606`](https://github.com/microsoft/terminal/commit/6a3960602f107ae609d78667173d6a66c1380037) store text with extended attributes too - [`bfee5fe`](https://github.com/microsoft/terminal/commit/bfee5fe3df96f7db57557c5b3ff67484ddc3dff3) Plumb attributes through all the renderers - [`87dfc88`](https://github.com/microsoft/terminal/commit/87dfc881c513dc79b2e040029db2a9faf64ed31b) parse extended attrs, though we're not renderering them right - [`dedb191`](https://github.com/microsoft/terminal/commit/dedb191e0dc36806825ea530700b861b9e5ca3fb) Render these states correctly - [`93aebf6`](https://github.com/microsoft/terminal/commit/93aebf636a805658f7b2421bc9618a963219f5ae) Add a very extensive test - [`2c9f539`](https://github.com/microsoft/terminal/commit/2c9f539b8ef19bc95867ebd0fc950fb13fdc1491) Cleanup for PR - [`02d7d0e`](https://github.com/microsoft/terminal/commit/02d7d0e396c127cacad4df9a53fc4aaa3796fd5e) a block of PR feedback - [`6aca2ec`](https://github.com/microsoft/terminal/commit/6aca2ecd69e696b43678f47580d401c55e1a03de) add 512 test cases - [`e0df256`](https://github.com/microsoft/terminal/commit/e0df256d3e5a1777086fd84e9405258448734b82) Merge remote-tracking branch 'origin/master' into dev/migrie/b/2554-_italics_ - [`efe6b3c`](https://github.com/microsoft/terminal/commit/efe6b3caff651edcaac61e8d58d16eb3308d4920) Fix the build ### 📊 Changes **36 files changed** (+938 additions, -112 deletions) <details> <summary>View changed files</summary> 📝 `src/buffer/out/TextAttribute.cpp` (+7 -7) 📝 `src/buffer/out/TextAttribute.hpp` (+28 -8) 📝 `src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp` (+2 -2) 📝 `src/host/getset.cpp` (+33 -0) 📝 `src/host/getset.h` (+3 -0) 📝 `src/host/outputStream.cpp` (+26 -0) 📝 `src/host/outputStream.hpp` (+2 -0) 📝 `src/host/ut_host/ScreenBufferTests.cpp` (+333 -0) 📝 `src/host/ut_host/VtRendererTests.cpp` (+117 -25) 📝 `src/inc/conattrs.hpp` (+15 -0) 📝 `src/interactivity/onecore/BgfxEngine.cpp` (+1 -1) 📝 `src/interactivity/onecore/BgfxEngine.hpp` (+1 -1) 📝 `src/renderer/base/renderer.cpp` (+2 -2) 📝 `src/renderer/dx/DxRenderer.cpp` (+2 -2) 📝 `src/renderer/dx/DxRenderer.hpp` (+1 -1) 📝 `src/renderer/gdi/gdirenderer.hpp` (+1 -1) 📝 `src/renderer/gdi/state.cpp` (+2 -2) 📝 `src/renderer/inc/IRenderEngine.hpp` (+1 -1) 📝 `src/renderer/vt/VtSequences.cpp` (+88 -0) 📝 `src/renderer/vt/WinTelnetEngine.cpp` (+7 -2) _...and 16 more files_ </details> ### 📄 Description ## Summary of the Pull Request Adds support for Italics, Blinking, Invisible, CrossedOut text, THROUGH CONPTY. This does **NOT** add support for those styles to conhost or the terminal. We will store these "Extended Text Attributes" in a `TextAttribute`. When we go to render a line, we'll see if the state has changed from our previous state, and if so, we'll appropriately toggle that state with VT. Boldness has been moved from a `bool` to a single bit in these flags. Technically, now that these are stored in the buffer, we only need to make changes to the renderers to be able to support them. That's not being done as a part of this PR however. ## References See also #2915 and #2916, which are some follow-up tasks from this fix. I thought them too risky for 20H1. ## PR Checklist * [x] Closes #2554 * [x] I work here * [x] Tests added/passed * [n/a] Requires documentation to be updated ## Validation Steps Performed * Replaced the conhost in my system32 and tried running the following script, via WSL interop: <details> ```python import sys import time # time.sleep is in seconds def write(s): sys.stdout.write(s) def csi(seq): sys.stdout.write('\x1b[{}'.format(seq)) def sgr(code=0): csi('{}m'.format(code)) def cupxy(x=0, y=0): cup(y+1, x+1) def clear_all(): cupxy(0,0) csi('2J') # $ python ~/vttests/extended-attrs.py if __name__ == '__main__': clear_all() print('This is the VT Test template.') sgr(0) write('[Normal Text]') sgr(3) write('[Italicized]') sgr(0) write('\n') sgr(0) write('[Normal Text]') sgr(4) write('[Underlined]') sgr(0) write('[Normal Again]') write('\n') sgr(0) write('[Normal Text]') sgr(4) write('[Underlined]') sgr(3) write('[U & I]') sgr(0) write('[Normal Again]') write('\n') sgr(0) write('[Normal Text]') sgr(4) write('[Underlined]') sgr(3) write('[U & I]') sgr(23) write('[Underlined]') sgr(0) write('[Normal Again]') write('\n') sgr(0) write('[Normal Text]') sgr(4) write('[Underlined]') sgr(3) write('[U & I]') sgr(24) write('[Italicized]') sgr(0) write('[Normal Again]') write('\n') sgr(0) write('[Normal Text]') sgr(5) write('[Blinking]') sgr(0) write('[Normal Again]') write('\n') sgr(0) write('[Normal Text]') sgr(8) write('[Invisible]') sgr(0) write('[Normal Again]') write('\n') sgr(0) write('[Normal Text]') sgr(9) write('[Crossed-out]') sgr(0) write('[Normal Again]') write('\n') ############################################################################ sgr(0) write('[Normal Text]') sgr(1) write('[Bold]') sgr(3) write('[B & Italicized]') sgr(0) write('\n') sgr(0) write('[Normal Text]') sgr(1) write('[Bold]') sgr(4) write('[B & Underlined]') sgr(0) write('[Normal Again]') write('\n') sgr(0) write('[Normal Text]') sgr(1) write('[Bold]') sgr(4) write('[B & Underlined]') sgr(3) write('[B & U & I]') sgr(0) write('[Normal Again]') write('\n') sgr(0) write('[Normal Text]') sgr(1) write('[Bold]') sgr(4) write('[B & Underlined]') sgr(3) write('[U & I]') sgr(23) write('[B & Underlined]') sgr(0) write('[Normal Again]') write('\n') sgr(0) write('[Normal Text]') sgr(1) write('[Bold]') sgr(4) write('[B & Underlined]') sgr(3) write('[B & U & I]') sgr(24) write('[B & Italicized]') sgr(0) write('[Normal Again]') write('\n') sgr(0) write('[Normal Text]') sgr(1) write('[Bold]') sgr(5) write('[B & Blinking]') sgr(0) write('[Normal Again]') write('\n') sgr(0) write('[Normal Text]') sgr(1) write('[Bold]') sgr(8) write('[B & Invisible]') sgr(0) write('[Normal Again]') write('\n') sgr(0) write('[Normal Text]') sgr(1) write('[Bold]') sgr(9) write('[B & Crossed-out]') sgr(0) write('[Normal Again]') write('\n') ``` </details> * ran tests * Using the (added) static assert, ensured that the size of the TextAttribute did not increase. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
claunia added the pull-request label 2026-01-31 09:07:32 +00:00
Sign in to join this conversation.
No Label pull-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#25142