From 8f1fc339152f59048c12ed9621e653ea457af716 Mon Sep 17 00:00:00 2001
From: Error-String-Expected-Got-Nil
<103805191+Error-String-Expected-Got-Nil@users.noreply.github.com>
Date: Tue, 6 May 2025 21:03:05 -0500
Subject: [PATCH 01/12] TextStyle enum
---
Terminal.Gui/Drawing/TextStyle.cs | 66 +++++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
create mode 100644 Terminal.Gui/Drawing/TextStyle.cs
diff --git a/Terminal.Gui/Drawing/TextStyle.cs b/Terminal.Gui/Drawing/TextStyle.cs
new file mode 100644
index 0000000000..3ca296620b
--- /dev/null
+++ b/Terminal.Gui/Drawing/TextStyle.cs
@@ -0,0 +1,66 @@
+namespace Terminal.Gui;
+
+///
+/// Defines non-color text style flags for an .
+///
+///
+///
+/// Only a subset of ANSI SGR (Select Graphic Rendition) styles are represented.
+/// Styles that are poorly supported, non-visual, or redundant with other APIs are omitted.
+///
+///
+/// Multiple styles can be combined using bitwise operations. Use
+/// to get or set these styles on an .
+///
+///
+[Flags]
+public enum TextStyle : byte
+{
+ ///
+ /// No text style.
+ ///
+ /// Corresponds to no active SGR styles.
+ None = 0b_0000_0000,
+
+ ///
+ /// Bold text.
+ ///
+ /// SGR code: 1 (Bold).
+ Bold = 0b_0000_0001,
+
+ ///
+ /// Faint (dim) text.
+ ///
+ /// SGR code: 2 (Faint). Not widely supported on all terminals.
+ Faint = 0b_0000_0010,
+
+ ///
+ /// Italic text.
+ ///
+ /// SGR code: 3 (Italic). Some terminals may not support italic rendering.
+ Italic = 0b_0000_0100,
+
+ ///
+ /// Underlined text.
+ ///
+ /// SGR code: 4 (Underline).
+ Underline = 0b_0000_1000,
+
+ ///
+ /// Slow blinking text.
+ ///
+ /// SGR code: 5 (Slow Blink). Support varies; blinking is often disabled in modern terminals.
+ Blink = 0b_0001_0000,
+
+ ///
+ /// Reverse video (swaps foreground and background colors).
+ ///
+ /// SGR code: 7 (Reverse Video).
+ Reverse = 0b_0010_0000,
+
+ ///
+ /// Strikethrough (crossed-out) text.
+ ///
+ /// SGR code: 9 (Crossed-out / Strikethrough).
+ Strikethrough = 0b_0100_0000
+}
From 89033fc91be8178793e2d307de5a15b2086a5967 Mon Sep 17 00:00:00 2001
From: Error-String-Expected-Got-Nil
<103805191+Error-String-Expected-Got-Nil@users.noreply.github.com>
Date: Tue, 6 May 2025 21:03:31 -0500
Subject: [PATCH 02/12] CSI_AppendTextStyleChange
---
.../ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs | 111 ++++++++++++++++++
1 file changed, 111 insertions(+)
diff --git a/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs b/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs
index adc463cc2c..835235b6bd 100644
--- a/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs
+++ b/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs
@@ -1849,6 +1849,117 @@ public static void CSI_AppendBackgroundColorRGB (StringBuilder builder, int r, i
#endregion
+ #region Text Styles
+
+ ///
+ /// Appends an ANSI SGR (Select Graphic Rendition) escape sequence to switch printed text from one to another.
+ ///
+ /// to add escape sequence to.
+ /// Previous to change away from.
+ /// Next to change to.
+ ///
+ ///
+ /// Unlike colors, most text styling options are not mutually exclusive with each other, and can be applied independently. This creates a problem when
+ /// switching from one style to another: For instance, if your previous style is just bold, and your next style is just italic, then simply adding the
+ /// sequence to enable italic text would cause the text to remain bold. This method automatically handles this problem, enabling and disabling styles as
+ /// necessary to apply exactly the next style.
+ ///
+ ///
+ internal static void CSI_AppendTextStyleChange (StringBuilder output, TextStyle prev, TextStyle next)
+ {
+ // Do nothing if styles are the same, as no changes are necessary.
+ if (prev == next)
+ {
+ return;
+ }
+
+ // Bitwise operations to determine flag changes. A ^ B are the flags different between two flag sets. These different flags that exist in the next flag
+ // set (diff & next) are the ones that were enabled in the switch, those that exist in the previous flag set (diff & prev) are the ones that were
+ // disabled.
+ var diff = prev ^ next;
+ var enabled = diff & next;
+ var disabled = diff & prev;
+
+ // List of escape codes to apply.
+ var sgr = new List ();
+
+ if (disabled != TextStyle.None)
+ {
+ // Special case: Unlike other styles, bold and faint text are mutually exclusive. They also both have the same disable code: ^[[22m
+ // This also means disabling codes must be put before enabling codes, so that you can disable bold/faint text and enable the other at the same time.
+ if (disabled.HasFlag (TextStyle.Bold | TextStyle.Faint))
+ {
+ sgr.Add (22);
+ }
+
+ if (disabled.HasFlag (TextStyle.Italic))
+ {
+ sgr.Add (23);
+ }
+
+ if (disabled.HasFlag (TextStyle.Underline))
+ {
+ sgr.Add (24);
+ }
+
+ if (disabled.HasFlag (TextStyle.Blink))
+ {
+ sgr.Add (25);
+ }
+
+ if (disabled.HasFlag (TextStyle.Reverse))
+ {
+ sgr.Add (27);
+ }
+
+ if (disabled.HasFlag (TextStyle.Strikethrough))
+ {
+ sgr.Add (29);
+ }
+ }
+
+ if (enabled != TextStyle.None)
+ {
+ // Special case: As before, bold and faint are mutually exclusive. Activating both will leave it up to the terminal to decide which to actually
+ // apply. So that behavior is always consistent, we'll enforce precedence of bold over faint, since bold is more commonly used.
+ if (enabled.HasFlag (TextStyle.Bold | TextStyle.Faint))
+ {
+ sgr.Add (enabled.HasFlag (TextStyle.Bold) ? 1 : 2);
+ }
+
+ if (enabled.HasFlag (TextStyle.Italic))
+ {
+ sgr.Add (3);
+ }
+
+ if (enabled.HasFlag (TextStyle.Underline))
+ {
+ sgr.Add (4);
+ }
+
+ if (enabled.HasFlag (TextStyle.Blink))
+ {
+ sgr.Add (5);
+ }
+
+ if (enabled.HasFlag (TextStyle.Reverse))
+ {
+ sgr.Add (7);
+ }
+
+ if (enabled.HasFlag (TextStyle.Strikethrough))
+ {
+ sgr.Add (9);
+ }
+ }
+
+ output.Append ("\x1b[");
+ output.Append (string.Join (';', sgr));
+ output.Append ('m');
+ }
+
+ #endregion Text Styles
+
#region Requests
///
From 0ca2fc0cbaa777771dade17a8c7691668c17a85d Mon Sep 17 00:00:00 2001
From: Error-String-Expected-Got-Nil
<103805191+Error-String-Expected-Got-Nil@users.noreply.github.com>
Date: Tue, 6 May 2025 21:08:54 -0500
Subject: [PATCH 03/12] Add TextStyle to Attribute
---
Terminal.Gui/Drawing/Attribute.cs | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Terminal.Gui/Drawing/Attribute.cs b/Terminal.Gui/Drawing/Attribute.cs
index 28097f3774..c2547b62be 100644
--- a/Terminal.Gui/Drawing/Attribute.cs
+++ b/Terminal.Gui/Drawing/Attribute.cs
@@ -34,6 +34,10 @@ namespace Terminal.Gui;
[JsonConverter (typeof (ColorJsonConverter))]
public Color Background { get; }
+ // TODO: Add constructors which permit including a TextStyle.
+ /// The text style (bold, italic, underlined, etc.).
+ public TextStyle TextStyle { get; } = TextStyle.None;
+
/// Initializes a new instance with default values.
public Attribute ()
{
@@ -103,6 +107,7 @@ public Attribute (in Color color) : this (color, color) { }
///
public override int GetHashCode () { return HashCode.Combine (PlatformColor, Foreground, Background); }
+ // TODO: Add TextStyle to Attribute.ToString(), modify unit tests to account
///
public override string ToString ()
{
From 9636e9cec32b8e02e6d1bc4ba0079727bc4d9319 Mon Sep 17 00:00:00 2001
From: Error-String-Expected-Got-Nil
<103805191+Error-String-Expected-Got-Nil@users.noreply.github.com>
Date: Tue, 6 May 2025 21:16:40 -0500
Subject: [PATCH 04/12] Apply text style in NetOutput.Write()
---
Terminal.Gui/ConsoleDrivers/V2/NetOutput.cs | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/Terminal.Gui/ConsoleDrivers/V2/NetOutput.cs b/Terminal.Gui/ConsoleDrivers/V2/NetOutput.cs
index 69defb82e5..4579b6efc2 100644
--- a/Terminal.Gui/ConsoleDrivers/V2/NetOutput.cs
+++ b/Terminal.Gui/ConsoleDrivers/V2/NetOutput.cs
@@ -12,6 +12,9 @@ public class NetOutput : IConsoleOutput
private CursorVisibility? _cachedCursorVisibility;
+ // Last text style used, for updating style with EscSeqUtils.CSI_AppendTextStyleChange().
+ private TextStyle _redrawTextStyle = TextStyle.None;
+
///
/// Creates a new instance of the class.
///
@@ -117,7 +120,7 @@ public void Write (IOutputBuffer buffer)
Attribute attr = buffer.Contents [row, col].Attribute.Value;
// Performance: Only send the escape sequence if the attribute has changed.
- if (attr != redrawAttr)
+ if (attr != redrawAttr || attr.TextStyle != _redrawTextStyle)
{
redrawAttr = attr;
@@ -134,6 +137,10 @@ public void Write (IOutputBuffer buffer)
attr.Background.G,
attr.Background.B
);
+
+ EscSeqUtils.CSI_AppendTextStyleChange (output, _redrawTextStyle, attr.TextStyle);
+
+ _redrawTextStyle = attr.TextStyle;
}
outputWidth++;
From 74e0ece0a60f9fb5679f08eaa3745f505fdec66a Mon Sep 17 00:00:00 2001
From: Error-String-Expected-Got-Nil
<103805191+Error-String-Expected-Got-Nil@users.noreply.github.com>
Date: Tue, 6 May 2025 21:19:59 -0500
Subject: [PATCH 05/12] Don't append escape code if nothing to change
---
Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs b/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs
index 835235b6bd..5d6aab73e1 100644
--- a/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs
+++ b/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs
@@ -1953,6 +1953,11 @@ internal static void CSI_AppendTextStyleChange (StringBuilder output, TextStyle
}
}
+ if (sgr.Count == 0)
+ {
+ return;
+ }
+
output.Append ("\x1b[");
output.Append (string.Join (';', sgr));
output.Append ('m');
From 6b24734e8e3e52def590e28449fc50cb8a36b888 Mon Sep 17 00:00:00 2001
From: Error-String-Expected-Got-Nil
<103805191+Error-String-Expected-Got-Nil@users.noreply.github.com>
Date: Tue, 6 May 2025 21:27:42 -0500
Subject: [PATCH 06/12] Make TextStyle an init property
---
Terminal.Gui/Drawing/Attribute.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Terminal.Gui/Drawing/Attribute.cs b/Terminal.Gui/Drawing/Attribute.cs
index c2547b62be..cba89e682b 100644
--- a/Terminal.Gui/Drawing/Attribute.cs
+++ b/Terminal.Gui/Drawing/Attribute.cs
@@ -36,7 +36,7 @@ namespace Terminal.Gui;
// TODO: Add constructors which permit including a TextStyle.
/// The text style (bold, italic, underlined, etc.).
- public TextStyle TextStyle { get; } = TextStyle.None;
+ public TextStyle TextStyle { get; init; } = TextStyle.None;
/// Initializes a new instance with default values.
public Attribute ()
From 5a0fd0b12d40efd8fc8b00812d9792283321c5c1 Mon Sep 17 00:00:00 2001
From: Error-String-Expected-Got-Nil
<103805191+Error-String-Expected-Got-Nil@users.noreply.github.com>
Date: Tue, 6 May 2025 22:35:14 -0500
Subject: [PATCH 07/12] Apply TextStyle to OutputBuffer attributes
---
Terminal.Gui/ConsoleDrivers/V2/OutputBuffer.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Terminal.Gui/ConsoleDrivers/V2/OutputBuffer.cs b/Terminal.Gui/ConsoleDrivers/V2/OutputBuffer.cs
index 248c266fa0..1b62959858 100644
--- a/Terminal.Gui/ConsoleDrivers/V2/OutputBuffer.cs
+++ b/Terminal.Gui/ConsoleDrivers/V2/OutputBuffer.cs
@@ -33,7 +33,8 @@ public Attribute CurrentAttribute
// TODO: This makes IConsoleDriver dependent on Application, which is not ideal. Once Attribute.PlatformColor is removed, this can be fixed.
if (Application.Driver is { })
{
- _currentAttribute = new (value.Foreground, value.Background);
+ // TODO: Update this when attributes can include TextStyle in the constructor
+ _currentAttribute = new (value.Foreground, value.Background) { TextStyle = value.TextStyle };
return;
}
From aa660eb2cf57e825b74b9c5498f0ee535c906f40 Mon Sep 17 00:00:00 2001
From: Error-String-Expected-Got-Nil
<103805191+Error-String-Expected-Got-Nil@users.noreply.github.com>
Date: Tue, 6 May 2025 23:32:53 -0500
Subject: [PATCH 08/12] Fix flag checking
Misunderstood how Enum.HasFlag worked, fixed now
---
Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs b/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs
index 5d6aab73e1..b1ae9f0671 100644
--- a/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs
+++ b/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs
@@ -1887,7 +1887,7 @@ internal static void CSI_AppendTextStyleChange (StringBuilder output, TextStyle
{
// Special case: Unlike other styles, bold and faint text are mutually exclusive. They also both have the same disable code: ^[[22m
// This also means disabling codes must be put before enabling codes, so that you can disable bold/faint text and enable the other at the same time.
- if (disabled.HasFlag (TextStyle.Bold | TextStyle.Faint))
+ if (disabled.HasFlag (TextStyle.Bold) || disabled.HasFlag (TextStyle.Faint))
{
sgr.Add (22);
}
@@ -1922,7 +1922,7 @@ internal static void CSI_AppendTextStyleChange (StringBuilder output, TextStyle
{
// Special case: As before, bold and faint are mutually exclusive. Activating both will leave it up to the terminal to decide which to actually
// apply. So that behavior is always consistent, we'll enforce precedence of bold over faint, since bold is more commonly used.
- if (enabled.HasFlag (TextStyle.Bold | TextStyle.Faint))
+ if (enabled.HasFlag (TextStyle.Bold) || enabled.HasFlag(TextStyle.Faint))
{
sgr.Add (enabled.HasFlag (TextStyle.Bold) ? 1 : 2);
}
From 9bf39fd9710f1e34e21cf1ba8a3ec024bced1626 Mon Sep 17 00:00:00 2001
From: Error-String-Expected-Got-Nil
<103805191+Error-String-Expected-Got-Nil@users.noreply.github.com>
Date: Wed, 7 May 2025 09:26:23 -0500
Subject: [PATCH 09/12] Allow bold-faint text
Also adds remarks to TextStyle noting that they may be incompatible depending on terminal settings.
---
.../ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs | 33 +++++++++++++++----
Terminal.Gui/Drawing/TextStyle.cs | 17 ++++++++--
2 files changed, 41 insertions(+), 9 deletions(-)
diff --git a/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs b/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs
index b1ae9f0671..98997b5266 100644
--- a/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs
+++ b/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs
@@ -1885,11 +1885,27 @@ internal static void CSI_AppendTextStyleChange (StringBuilder output, TextStyle
if (disabled != TextStyle.None)
{
- // Special case: Unlike other styles, bold and faint text are mutually exclusive. They also both have the same disable code: ^[[22m
- // This also means disabling codes must be put before enabling codes, so that you can disable bold/faint text and enable the other at the same time.
- if (disabled.HasFlag (TextStyle.Bold) || disabled.HasFlag (TextStyle.Faint))
+ // Special case: Both bold and faint have the same disabling code. While unusual, it can be valid to have both enabled at the same time, so when
+ // one and only one of them is being disabled, we need to re-enable the other afterward. We can check what flags remain enabled by taking
+ // prev & next, as this is the set of flags both have.
+ if (disabled.HasFlag (TextStyle.Bold))
{
sgr.Add (22);
+
+ if ((prev & next).HasFlag (TextStyle.Faint))
+ {
+ sgr.Add (2);
+ }
+ }
+
+ if (disabled.HasFlag (TextStyle.Faint))
+ {
+ sgr.Add (22);
+
+ if ((prev & next).HasFlag (TextStyle.Bold))
+ {
+ sgr.Add (1);
+ }
}
if (disabled.HasFlag (TextStyle.Italic))
@@ -1920,11 +1936,14 @@ internal static void CSI_AppendTextStyleChange (StringBuilder output, TextStyle
if (enabled != TextStyle.None)
{
- // Special case: As before, bold and faint are mutually exclusive. Activating both will leave it up to the terminal to decide which to actually
- // apply. So that behavior is always consistent, we'll enforce precedence of bold over faint, since bold is more commonly used.
- if (enabled.HasFlag (TextStyle.Bold) || enabled.HasFlag(TextStyle.Faint))
+ if (enabled.HasFlag (TextStyle.Bold))
+ {
+ sgr.Add (1);
+ }
+
+ if (enabled.HasFlag (TextStyle.Faint))
{
- sgr.Add (enabled.HasFlag (TextStyle.Bold) ? 1 : 2);
+ sgr.Add (2);
}
if (enabled.HasFlag (TextStyle.Italic))
diff --git a/Terminal.Gui/Drawing/TextStyle.cs b/Terminal.Gui/Drawing/TextStyle.cs
index 3ca296620b..5a7fbb806c 100644
--- a/Terminal.Gui/Drawing/TextStyle.cs
+++ b/Terminal.Gui/Drawing/TextStyle.cs
@@ -12,6 +12,12 @@ namespace Terminal.Gui;
/// Multiple styles can be combined using bitwise operations. Use
/// to get or set these styles on an .
///
+///
+/// Note that and may be mutually exclusive depending on
+/// the user's terminal and its settings. For instance, if a terminal displays faint text as a darker color, and
+/// bold text as a lighter color, then both cannot
+/// be shown at the same time, and it will be up to the terminal to decide which to display.
+///
///
[Flags]
public enum TextStyle : byte
@@ -25,13 +31,20 @@ public enum TextStyle : byte
///
/// Bold text.
///
- /// SGR code: 1 (Bold).
+ ///
+ /// SGR code: 1 (Bold). May be mutually exclusive with , see
+ /// remarks.
+ ///
Bold = 0b_0000_0001,
///
/// Faint (dim) text.
///
- /// SGR code: 2 (Faint). Not widely supported on all terminals.
+ ///
+ /// SGR code: 2 (Faint). Not widely supported on all terminals. May be mutually exclusive with
+ /// , see
+ /// remarks.
+ ///
Faint = 0b_0000_0010,
///
From fd6e44d2f627a02325f475126f0c8a58cfbea91f Mon Sep 17 00:00:00 2001
From: Error-String-Expected-Got-Nil
<103805191+Error-String-Expected-Got-Nil@users.noreply.github.com>
Date: Wed, 7 May 2025 09:31:49 -0500
Subject: [PATCH 10/12] Remove unnecessary check
Realized it's actually impossible for no escape codes to be added, as this is only the case when prev and next are the same, which is already accounted for.
---
Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs | 5 -----
1 file changed, 5 deletions(-)
diff --git a/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs b/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs
index 98997b5266..e0b2e2aed8 100644
--- a/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs
+++ b/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs
@@ -1972,11 +1972,6 @@ internal static void CSI_AppendTextStyleChange (StringBuilder output, TextStyle
}
}
- if (sgr.Count == 0)
- {
- return;
- }
-
output.Append ("\x1b[");
output.Append (string.Join (';', sgr));
output.Append ('m');
From ce92023557942460c8369ed51bacdc873eaaab48 Mon Sep 17 00:00:00 2001
From: Error-String-Expected-Got-Nil
<103805191+Error-String-Expected-Got-Nil@users.noreply.github.com>
Date: Thu, 8 May 2025 20:33:31 -0500
Subject: [PATCH 11/12] Remove redundant check
Attributes are records, and thus already use equality-by-value, meaning attr != redrawAttr will already be false when the TextStyle changes.
---
Terminal.Gui/ConsoleDrivers/V2/NetOutput.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Terminal.Gui/ConsoleDrivers/V2/NetOutput.cs b/Terminal.Gui/ConsoleDrivers/V2/NetOutput.cs
index 4579b6efc2..fb93f6405d 100644
--- a/Terminal.Gui/ConsoleDrivers/V2/NetOutput.cs
+++ b/Terminal.Gui/ConsoleDrivers/V2/NetOutput.cs
@@ -120,7 +120,7 @@ public void Write (IOutputBuffer buffer)
Attribute attr = buffer.Contents [row, col].Attribute.Value;
// Performance: Only send the escape sequence if the attribute has changed.
- if (attr != redrawAttr || attr.TextStyle != _redrawTextStyle)
+ if (attr != redrawAttr)
{
redrawAttr = attr;
From 5884f8f3c40df5981cfb772ddbc4d6039f960dd1 Mon Sep 17 00:00:00 2001
From: Error-String-Expected-Got-Nil
<103805191+Error-String-Expected-Got-Nil@users.noreply.github.com>
Date: Fri, 9 May 2025 00:22:28 -0500
Subject: [PATCH 12/12] WindowsOutput support for text style
---
Terminal.Gui/ConsoleDrivers/V2/WindowsOutput.cs | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Terminal.Gui/ConsoleDrivers/V2/WindowsOutput.cs b/Terminal.Gui/ConsoleDrivers/V2/WindowsOutput.cs
index ba111c130f..1a12740136 100644
--- a/Terminal.Gui/ConsoleDrivers/V2/WindowsOutput.cs
+++ b/Terminal.Gui/ConsoleDrivers/V2/WindowsOutput.cs
@@ -58,6 +58,9 @@ private enum DesiredAccess : uint
private readonly nint _screenBuffer;
+ // Last text style used, for updating style with EscSeqUtils.CSI_AppendTextStyleChange().
+ private TextStyle _redrawTextStyle = TextStyle.None;
+
public WindowsOutput ()
{
Logging.Logger.LogInformation ($"Creating {nameof (WindowsOutput)}");
@@ -230,6 +233,8 @@ public bool WriteToConsole (Size size, ExtendedCharInfo [] charInfoBuffer, Coord
prev = attr;
EscSeqUtils.CSI_AppendForegroundColorRGB (stringBuilder, attr.Foreground.R, attr.Foreground.G, attr.Foreground.B);
EscSeqUtils.CSI_AppendBackgroundColorRGB (stringBuilder, attr.Background.R, attr.Background.G, attr.Background.B);
+ EscSeqUtils.CSI_AppendTextStyleChange (stringBuilder, _redrawTextStyle, attr.TextStyle);
+ _redrawTextStyle = attr.TextStyle;
}
if (info.Char != '\x1b')