Refactor TerminalDispatch (graphics) to match AdaptDispatch (#6728)

This is essentially a rewrite of the
`TerminalDispatch::SetGraphicsRendition` method, bringing it into closer
alignment with the `AdaptDispatch` implementation, simplifying the
`ITerminalApi` interface, and making the code easier to extend. It adds
support for a number of attributes which weren't previously implemented.

REFERENCES

* This is a mirror of the `AdaptDispatch` refactoring in PR #5758.
* The closer alignment with `AdaptDispatch` is a small step towards
  solving issue #3849.
* The newly supported attributes should help a little with issues #5461
  (italics) and #6205 (strike-through).

DETAILS

I've literally copied and pasted the `SetGraphicsRendition`
implementation from `AdaptDispatch` into `TerminalDispatch`, with only
few minor changes:

* The `SetTextAttribute` and `GetTextAttribute` calls are slightly
  different in the `TerminalDispatch` version, since they don't return a
  pointless `success` value, and in the case of the getter, the
  `TextAttribute` is returned directly instead of by reference.
  Ultimately I'd like to move the `AdaptDispatch` code towards that way
  of doing things too, but I'd like to deal with that later as part of a
  wider refactoring of the `ConGetSet` interface.
* The `SetIndexedForeground256` and `SetIndexedBackground256` calls
  required the color indices to be remapped in the `AdaptDispatch`
  implementation, because the conhost color table is in a different
  order to the XTerm standard. `TerminalDispatch` doesn't have that
  problem, so doesn't require the mapping.
* The index color constants used in the 16-color `SetIndexedForeground`
  and `SetIndexedBackground` calls are also slightly different for the
  same reason.

VALIDATION

I cherry-picked this code on top of the #6506 and #6698 PRs, since
that's only way to really get the different color formats passed-through
to the terminal. I then ran a bunch of manual tests with various color
coverage scripts that I have, and confirmed that all the different color
formats were being rendered as expected.

Closes #6725
This commit is contained in:
James Holderness 2020-07-01 19:13:42 +01:00 committed by GitHub
parent ddbe370d22
commit 6b43ace690
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 231 additions and 374 deletions

View File

@ -3,6 +3,7 @@
#pragma once
#include "../../terminal/adapter/DispatchTypes.hpp"
#include "../../buffer/out/TextAttribute.hpp"
namespace Microsoft::Terminal::Core
{
@ -18,15 +19,8 @@ namespace Microsoft::Terminal::Core
virtual bool PrintString(std::wstring_view string) noexcept = 0;
virtual bool ExecuteChar(wchar_t wch) noexcept = 0;
virtual bool SetTextToDefaults(bool foreground, bool background) noexcept = 0;
virtual bool SetTextForegroundIndex(BYTE colorIndex) noexcept = 0;
virtual bool SetTextBackgroundIndex(BYTE colorIndex) noexcept = 0;
virtual bool SetTextForegroundIndex256(BYTE colorIndex) noexcept = 0;
virtual bool SetTextBackgroundIndex256(BYTE colorIndex) noexcept = 0;
virtual bool SetTextRgbColor(COLORREF color, bool foreground) noexcept = 0;
virtual bool BoldText(bool boldOn) noexcept = 0;
virtual bool UnderlineText(bool underlineOn) noexcept = 0;
virtual bool ReverseText(bool reversed) noexcept = 0;
virtual TextAttribute GetTextAttributes() const noexcept = 0;
virtual void SetTextAttributes(const TextAttribute& attrs) noexcept = 0;
virtual bool SetCursorPosition(short x, short y) noexcept = 0;
virtual COORD GetCursorPosition() noexcept = 0;

View File

@ -78,15 +78,8 @@ public:
// These methods are defined in TerminalApi.cpp
bool PrintString(std::wstring_view stringView) noexcept override;
bool ExecuteChar(wchar_t wch) noexcept override;
bool SetTextToDefaults(bool foreground, bool background) noexcept override;
bool SetTextForegroundIndex(BYTE colorIndex) noexcept override;
bool SetTextBackgroundIndex(BYTE colorIndex) noexcept override;
bool SetTextForegroundIndex256(BYTE colorIndex) noexcept override;
bool SetTextBackgroundIndex256(BYTE colorIndex) noexcept override;
bool SetTextRgbColor(COLORREF color, bool foreground) noexcept override;
bool BoldText(bool boldOn) noexcept override;
bool UnderlineText(bool underlineOn) noexcept override;
bool ReverseText(bool reversed) noexcept override;
TextAttribute GetTextAttributes() const noexcept override;
void SetTextAttributes(const TextAttribute& attrs) noexcept override;
bool SetCursorPosition(short x, short y) noexcept override;
COORD GetCursorPosition() noexcept override;
bool SetCursorVisibility(const bool visible) noexcept override;

View File

@ -26,83 +26,14 @@ try
}
CATCH_LOG_RETURN_FALSE()
bool Terminal::SetTextToDefaults(bool foreground, bool background) noexcept
TextAttribute Terminal::GetTextAttributes() const noexcept
{
TextAttribute attrs = _buffer->GetCurrentAttributes();
if (foreground)
{
attrs.SetDefaultForeground();
}
if (background)
{
attrs.SetDefaultBackground();
}
_buffer->SetCurrentAttributes(attrs);
return true;
return _buffer->GetCurrentAttributes();
}
bool Terminal::SetTextForegroundIndex(BYTE colorIndex) noexcept
void Terminal::SetTextAttributes(const TextAttribute& attrs) noexcept
{
TextAttribute attrs = _buffer->GetCurrentAttributes();
attrs.SetIndexedForeground(colorIndex);
_buffer->SetCurrentAttributes(attrs);
return true;
}
bool Terminal::SetTextBackgroundIndex(BYTE colorIndex) noexcept
{
TextAttribute attrs = _buffer->GetCurrentAttributes();
attrs.SetIndexedBackground(colorIndex);
_buffer->SetCurrentAttributes(attrs);
return true;
}
bool Terminal::SetTextForegroundIndex256(BYTE colorIndex) noexcept
{
TextAttribute attrs = _buffer->GetCurrentAttributes();
attrs.SetIndexedForeground256(colorIndex);
_buffer->SetCurrentAttributes(attrs);
return true;
}
bool Terminal::SetTextBackgroundIndex256(BYTE colorIndex) noexcept
{
TextAttribute attrs = _buffer->GetCurrentAttributes();
attrs.SetIndexedBackground256(colorIndex);
_buffer->SetCurrentAttributes(attrs);
return true;
}
bool Terminal::SetTextRgbColor(COLORREF color, bool foreground) noexcept
{
TextAttribute attrs = _buffer->GetCurrentAttributes();
attrs.SetColor(color, foreground);
_buffer->SetCurrentAttributes(attrs);
return true;
}
bool Terminal::BoldText(bool boldOn) noexcept
{
TextAttribute attrs = _buffer->GetCurrentAttributes();
attrs.SetBold(boldOn);
_buffer->SetCurrentAttributes(attrs);
return true;
}
bool Terminal::UnderlineText(bool underlineOn) noexcept
{
TextAttribute attrs = _buffer->GetCurrentAttributes();
attrs.SetUnderline(underlineOn);
_buffer->SetCurrentAttributes(attrs);
return true;
}
bool Terminal::ReverseText(bool reversed) noexcept
{
TextAttribute attrs = _buffer->GetCurrentAttributes();
attrs.SetReverseVideo(reversed);
_buffer->SetCurrentAttributes(attrs);
return true;
}
bool Terminal::SetCursorPosition(short x, short y) noexcept

View File

@ -64,11 +64,9 @@ public:
private:
::Microsoft::Terminal::Core::ITerminalApi& _terminalApi;
bool _SetRgbColorsHelper(const std::basic_string_view<::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions> options,
size_t& optionsConsumed) noexcept;
bool _SetBoldColorHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions opt) noexcept;
bool _SetDefaultColorHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions opt) noexcept;
void _SetGraphicsOptionHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions opt) noexcept;
size_t _SetRgbColorsHelper(const std::basic_string_view<::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions> options,
TextAttribute& attr,
const bool isForeground) noexcept;
bool _SetResetPrivateModes(const std::basic_string_view<::Microsoft::Console::VirtualTerminal::DispatchTypes::PrivateModeParams> params, const bool enable) noexcept;
bool _PrivateModeParamsHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::PrivateModeParams param, const bool enable) noexcept;

View File

@ -3,22 +3,23 @@
#include "pch.h"
#include "TerminalDispatch.hpp"
using namespace ::Microsoft::Terminal::Core;
using namespace ::Microsoft::Console::VirtualTerminal;
using namespace Microsoft::Console::VirtualTerminal;
using namespace Microsoft::Console::VirtualTerminal::DispatchTypes;
// clang-format off
const BYTE RED_ATTR = 0x01;
const BYTE GREEN_ATTR = 0x02;
const BYTE BLUE_ATTR = 0x04;
const BYTE BRIGHT_ATTR = 0x08;
const BYTE DARK_BLACK = 0;
const BYTE DARK_RED = RED_ATTR;
const BYTE DARK_GREEN = GREEN_ATTR;
const BYTE DARK_YELLOW = RED_ATTR | GREEN_ATTR;
const BYTE DARK_BLUE = BLUE_ATTR;
const BYTE DARK_MAGENTA = RED_ATTR | BLUE_ATTR;
const BYTE DARK_CYAN = GREEN_ATTR | BLUE_ATTR;
const BYTE DARK_WHITE = RED_ATTR | GREEN_ATTR | BLUE_ATTR;
const BYTE RED_ATTR = 0x01;
const BYTE GREEN_ATTR = 0x02;
const BYTE BLUE_ATTR = 0x04;
const BYTE BRIGHT_ATTR = 0x08;
const BYTE DARK_BLACK = 0;
const BYTE DARK_RED = RED_ATTR;
const BYTE DARK_GREEN = GREEN_ATTR;
const BYTE DARK_YELLOW = RED_ATTR | GREEN_ATTR;
const BYTE DARK_BLUE = BLUE_ATTR;
const BYTE DARK_MAGENTA = RED_ATTR | BLUE_ATTR;
const BYTE DARK_CYAN = GREEN_ATTR | BLUE_ATTR;
const BYTE DARK_WHITE = RED_ATTR | GREEN_ATTR | BLUE_ATTR;
const BYTE BRIGHT_BLACK = BRIGHT_ATTR;
const BYTE BRIGHT_RED = BRIGHT_ATTR | RED_ATTR;
const BYTE BRIGHT_GREEN = BRIGHT_ATTR | GREEN_ATTR;
@ -29,40 +30,6 @@ const BYTE BRIGHT_CYAN = BRIGHT_ATTR | GREEN_ATTR | BLUE_ATTR;
const BYTE BRIGHT_WHITE = BRIGHT_ATTR | RED_ATTR | GREEN_ATTR | BLUE_ATTR;
// clang-format on
// Routine Description:
// Returns true if the GraphicsOption represents an extended color option.
// These are followed by up to 4 more values which compose the entire option.
// Return Value:
// - true if the opt is the indicator for an extended color sequence, false otherwise.
static constexpr bool _isRgbColorOption(const DispatchTypes::GraphicsOptions opt) noexcept
{
return opt == DispatchTypes::GraphicsOptions::ForegroundExtended ||
opt == DispatchTypes::GraphicsOptions::BackgroundExtended;
}
// Routine Description:
// Returns true if the GraphicsOption represents an extended color option.
// These are followed by up to 4 more values which compose the entire option.
// Return Value:
// - true if the opt is the indicator for an extended color sequence, false otherwise.
static constexpr bool _isBoldColorOption(const DispatchTypes::GraphicsOptions opt) noexcept
{
return opt == DispatchTypes::GraphicsOptions::BoldBright ||
opt == DispatchTypes::GraphicsOptions::UnBold;
}
// Function Description:
// - checks if this graphics option should set either the console's FG or BG to
//the default attributes.
// Return Value:
// - true if the opt sets either/or attribute to the defaults, false otherwise.
static constexpr bool _isDefaultColorOption(const DispatchTypes::GraphicsOptions opt) noexcept
{
return opt == DispatchTypes::GraphicsOptions::Off ||
opt == DispatchTypes::GraphicsOptions::ForegroundDefault ||
opt == DispatchTypes::GraphicsOptions::BackgroundDefault;
}
// Routine Description:
// - Helper to parse extended graphics options, which start with 38 (FG) or 48 (BG)
// These options are followed by either a 2 (RGB) or 5 (xterm index)
@ -70,257 +37,231 @@ static constexpr bool _isDefaultColorOption(const DispatchTypes::GraphicsOptions
// Xterm index will use the param that follows to use a color from the preset 256 color xterm color table.
// Arguments:
// - options - An array of options that will be used to generate the RGB color
// - optionsConsumed - Returns the number of options we consumed parsing this option.
// - attr - The attribute that will be updated with the parsed color.
// - isForeground - Whether or not the parsed color is for the foreground.
// Return Value:
// Returns true if we successfully parsed an extended color option from the options array.
// - This corresponds to the following number of options consumed (pcOptionsConsumed):
// 1 - false, not enough options to parse.
// 2 - false, not enough options to parse.
// 3 - true, parsed an xterm index to a color
// 5 - true, parsed an RGB color.
bool TerminalDispatch::_SetRgbColorsHelper(const std::basic_string_view<DispatchTypes::GraphicsOptions> options,
size_t& optionsConsumed) noexcept
// - The number of options consumed, not including the initial 38/48.
size_t TerminalDispatch::_SetRgbColorsHelper(const std::basic_string_view<DispatchTypes::GraphicsOptions> options,
TextAttribute& attr,
const bool isForeground) noexcept
{
COLORREF color = 0;
bool isForeground = false;
bool success = false;
optionsConsumed = 1;
if (options.size() >= 2 && _isRgbColorOption(options.front()))
size_t optionsConsumed = 0;
if (options.size() >= 1)
{
optionsConsumed = 2;
const auto extendedOpt = til::at(options, 0);
const auto typeOpt = til::at(options, 1);
if (extendedOpt == DispatchTypes::GraphicsOptions::ForegroundExtended)
optionsConsumed = 1;
const auto typeOpt = til::at(options, 0);
if (typeOpt == DispatchTypes::GraphicsOptions::RGBColorOrFaint && options.size() >= 4)
{
isForeground = true;
}
else if (extendedOpt == DispatchTypes::GraphicsOptions::BackgroundExtended)
{
isForeground = false;
}
if (typeOpt == DispatchTypes::GraphicsOptions::RGBColorOrFaint && options.size() >= 5)
{
optionsConsumed = 5;
optionsConsumed = 4;
const size_t red = til::at(options, 1);
const size_t green = til::at(options, 2);
const size_t blue = til::at(options, 3);
// ensure that each value fits in a byte
const auto limit = static_cast<DispatchTypes::GraphicsOptions>(255);
const auto red = std::min(options.at(2), limit);
const auto green = std::min(options.at(3), limit);
const auto blue = std::min(options.at(4), limit);
color = RGB(red, green, blue);
success = _terminalApi.SetTextRgbColor(color, isForeground);
}
else if (typeOpt == DispatchTypes::GraphicsOptions::BlinkOrXterm256Index && options.size() >= 3)
{
optionsConsumed = 3;
if (options.at(2) <= 255) // ensure that the provided index is on the table
if (red <= 255 && green <= 255 && blue <= 255)
{
const auto tableIndex = til::at(options, 2);
success = isForeground ?
_terminalApi.SetTextForegroundIndex256(gsl::narrow_cast<BYTE>(tableIndex)) :
_terminalApi.SetTextBackgroundIndex256(gsl::narrow_cast<BYTE>(tableIndex));
const COLORREF rgbColor = RGB(red, green, blue);
attr.SetColor(rgbColor, isForeground);
}
}
else if (typeOpt == DispatchTypes::GraphicsOptions::BlinkOrXterm256Index && options.size() >= 2)
{
optionsConsumed = 2;
const size_t tableIndex = til::at(options, 1);
if (tableIndex <= 255)
{
const auto adjustedIndex = gsl::narrow_cast<BYTE>(tableIndex);
if (isForeground)
{
attr.SetIndexedForeground256(adjustedIndex);
}
else
{
attr.SetIndexedBackground256(adjustedIndex);
}
}
}
}
return success;
}
bool TerminalDispatch::_SetBoldColorHelper(const DispatchTypes::GraphicsOptions option) noexcept
{
const bool bold = (option == DispatchTypes::GraphicsOptions::BoldBright);
return _terminalApi.BoldText(bold);
}
bool TerminalDispatch::_SetDefaultColorHelper(const DispatchTypes::GraphicsOptions option) noexcept
{
const bool fg = option == DispatchTypes::GraphicsOptions::Off || option == DispatchTypes::GraphicsOptions::ForegroundDefault;
const bool bg = option == DispatchTypes::GraphicsOptions::Off || option == DispatchTypes::GraphicsOptions::BackgroundDefault;
bool success = _terminalApi.SetTextToDefaults(fg, bg);
if (success && fg && bg)
{
// If we're resetting both the FG & BG, also reset the meta attributes (underline)
// as well as the boldness
success = _terminalApi.UnderlineText(false) &&
_terminalApi.ReverseText(false) &&
_terminalApi.BoldText(false);
}
return success;
return optionsConsumed;
}
// Routine Description:
// - Helper to apply the actual flags to each text attributes field.
// - Placed as a helper so it can be recursive/re-entrant for some of the convenience flag methods that perform similar/multiple operations in one command.
// - SGR - Modifies the graphical rendering options applied to the next
// characters written into the buffer.
// - Options include colors, invert, underlines, and other "font style"
// type options.
// Arguments:
// - opt - Graphics option sent to us by the parser/requestor.
// - pAttr - Pointer to the font attribute field to adjust
// - options - An array of options that will be applied from 0 to N, in order,
// one at a time by setting or removing flags in the font style properties.
// Return Value:
// - <none>
void TerminalDispatch::_SetGraphicsOptionHelper(const DispatchTypes::GraphicsOptions opt) noexcept
{
switch (opt)
{
case DispatchTypes::GraphicsOptions::Off:
FAIL_FAST_MSG("GraphicsOptions::Off should be handled by _SetDefaultColorHelper");
break;
// MSFT:16398982 - These two are now handled by _SetBoldColorHelper
// case DispatchTypes::GraphicsOptions::BoldBright:
// case DispatchTypes::GraphicsOptions::UnBold:
case DispatchTypes::GraphicsOptions::Negative:
_terminalApi.ReverseText(true);
break;
case DispatchTypes::GraphicsOptions::Underline:
_terminalApi.UnderlineText(true);
break;
case DispatchTypes::GraphicsOptions::Positive:
_terminalApi.ReverseText(false);
break;
case DispatchTypes::GraphicsOptions::NoUnderline:
_terminalApi.UnderlineText(false);
break;
case DispatchTypes::GraphicsOptions::ForegroundBlack:
_terminalApi.SetTextForegroundIndex(DARK_BLACK);
break;
case DispatchTypes::GraphicsOptions::ForegroundBlue:
_terminalApi.SetTextForegroundIndex(DARK_BLUE);
break;
case DispatchTypes::GraphicsOptions::ForegroundGreen:
_terminalApi.SetTextForegroundIndex(DARK_GREEN);
break;
case DispatchTypes::GraphicsOptions::ForegroundCyan:
_terminalApi.SetTextForegroundIndex(DARK_CYAN);
break;
case DispatchTypes::GraphicsOptions::ForegroundRed:
_terminalApi.SetTextForegroundIndex(DARK_RED);
break;
case DispatchTypes::GraphicsOptions::ForegroundMagenta:
_terminalApi.SetTextForegroundIndex(DARK_MAGENTA);
break;
case DispatchTypes::GraphicsOptions::ForegroundYellow:
_terminalApi.SetTextForegroundIndex(DARK_YELLOW);
break;
case DispatchTypes::GraphicsOptions::ForegroundWhite:
_terminalApi.SetTextForegroundIndex(DARK_WHITE);
break;
case DispatchTypes::GraphicsOptions::ForegroundDefault:
FAIL_FAST_MSG("GraphicsOptions::ForegroundDefault should be handled by _SetDefaultColorHelper");
break;
case DispatchTypes::GraphicsOptions::BackgroundBlack:
_terminalApi.SetTextBackgroundIndex(DARK_BLACK);
break;
case DispatchTypes::GraphicsOptions::BackgroundBlue:
_terminalApi.SetTextBackgroundIndex(DARK_BLUE);
break;
case DispatchTypes::GraphicsOptions::BackgroundGreen:
_terminalApi.SetTextBackgroundIndex(DARK_GREEN);
break;
case DispatchTypes::GraphicsOptions::BackgroundCyan:
_terminalApi.SetTextBackgroundIndex(DARK_CYAN);
break;
case DispatchTypes::GraphicsOptions::BackgroundRed:
_terminalApi.SetTextBackgroundIndex(DARK_RED);
break;
case DispatchTypes::GraphicsOptions::BackgroundMagenta:
_terminalApi.SetTextBackgroundIndex(DARK_MAGENTA);
break;
case DispatchTypes::GraphicsOptions::BackgroundYellow:
_terminalApi.SetTextBackgroundIndex(DARK_YELLOW);
break;
case DispatchTypes::GraphicsOptions::BackgroundWhite:
_terminalApi.SetTextBackgroundIndex(DARK_WHITE);
break;
case DispatchTypes::GraphicsOptions::BackgroundDefault:
FAIL_FAST_MSG("GraphicsOptions::BackgroundDefault should be handled by _SetDefaultColorHelper");
break;
case DispatchTypes::GraphicsOptions::BrightForegroundBlack:
_terminalApi.SetTextForegroundIndex(BRIGHT_BLACK);
break;
case DispatchTypes::GraphicsOptions::BrightForegroundBlue:
_terminalApi.SetTextForegroundIndex(BRIGHT_BLUE);
break;
case DispatchTypes::GraphicsOptions::BrightForegroundGreen:
_terminalApi.SetTextForegroundIndex(BRIGHT_GREEN);
break;
case DispatchTypes::GraphicsOptions::BrightForegroundCyan:
_terminalApi.SetTextForegroundIndex(BRIGHT_CYAN);
break;
case DispatchTypes::GraphicsOptions::BrightForegroundRed:
_terminalApi.SetTextForegroundIndex(BRIGHT_RED);
break;
case DispatchTypes::GraphicsOptions::BrightForegroundMagenta:
_terminalApi.SetTextForegroundIndex(BRIGHT_MAGENTA);
break;
case DispatchTypes::GraphicsOptions::BrightForegroundYellow:
_terminalApi.SetTextForegroundIndex(BRIGHT_YELLOW);
break;
case DispatchTypes::GraphicsOptions::BrightForegroundWhite:
_terminalApi.SetTextForegroundIndex(BRIGHT_WHITE);
break;
case DispatchTypes::GraphicsOptions::BrightBackgroundBlack:
_terminalApi.SetTextBackgroundIndex(BRIGHT_BLACK);
break;
case DispatchTypes::GraphicsOptions::BrightBackgroundBlue:
_terminalApi.SetTextBackgroundIndex(BRIGHT_BLUE);
break;
case DispatchTypes::GraphicsOptions::BrightBackgroundGreen:
_terminalApi.SetTextBackgroundIndex(BRIGHT_GREEN);
break;
case DispatchTypes::GraphicsOptions::BrightBackgroundCyan:
_terminalApi.SetTextBackgroundIndex(BRIGHT_CYAN);
break;
case DispatchTypes::GraphicsOptions::BrightBackgroundRed:
_terminalApi.SetTextBackgroundIndex(BRIGHT_RED);
break;
case DispatchTypes::GraphicsOptions::BrightBackgroundMagenta:
_terminalApi.SetTextBackgroundIndex(BRIGHT_MAGENTA);
break;
case DispatchTypes::GraphicsOptions::BrightBackgroundYellow:
_terminalApi.SetTextBackgroundIndex(BRIGHT_YELLOW);
break;
case DispatchTypes::GraphicsOptions::BrightBackgroundWhite:
_terminalApi.SetTextBackgroundIndex(BRIGHT_WHITE);
break;
}
}
// - True if handled successfully. False otherwise.
bool TerminalDispatch::SetGraphicsRendition(const std::basic_string_view<DispatchTypes::GraphicsOptions> options) noexcept
{
bool success = false;
TextAttribute attr = _terminalApi.GetTextAttributes();
// Run through the graphics options and apply them
for (size_t i = 0; i < options.size(); i++)
{
const auto opt = options.at(i);
if (_isDefaultColorOption(opt))
const auto opt = til::at(options, i);
switch (opt)
{
success = _SetDefaultColorHelper(opt);
}
else if (_isBoldColorOption(opt))
{
success = _SetBoldColorHelper(opt);
}
else if (_isRgbColorOption(opt))
{
size_t optionsConsumed = 0;
// _SetRgbColorsHelper will call the appropriate ConApi function
success = _SetRgbColorsHelper(options.substr(i), optionsConsumed);
i += (optionsConsumed - 1); // optionsConsumed includes the opt we're currently on.
}
else
{
_SetGraphicsOptionHelper(opt);
// Make sure we un-bold
if (success && opt == DispatchTypes::GraphicsOptions::Off)
{
success = _SetBoldColorHelper(opt);
}
case Off:
attr.SetDefaultForeground();
attr.SetDefaultBackground();
attr.SetStandardErase();
break;
case ForegroundDefault:
attr.SetDefaultForeground();
break;
case BackgroundDefault:
attr.SetDefaultBackground();
break;
case BoldBright:
attr.SetBold(true);
break;
case UnBold:
attr.SetBold(false);
break;
case Italics:
attr.SetItalics(true);
break;
case NotItalics:
attr.SetItalics(false);
break;
case BlinkOrXterm256Index:
attr.SetBlinking(true);
break;
case Steady:
attr.SetBlinking(false);
break;
case Invisible:
attr.SetInvisible(true);
break;
case Visible:
attr.SetInvisible(false);
break;
case CrossedOut:
attr.SetCrossedOut(true);
break;
case NotCrossedOut:
attr.SetCrossedOut(false);
break;
case Negative:
attr.SetReverseVideo(true);
break;
case Positive:
attr.SetReverseVideo(false);
break;
case Underline:
attr.SetUnderline(true);
break;
case NoUnderline:
attr.SetUnderline(false);
break;
case ForegroundBlack:
attr.SetIndexedForeground(DARK_BLACK);
break;
case ForegroundBlue:
attr.SetIndexedForeground(DARK_BLUE);
break;
case ForegroundGreen:
attr.SetIndexedForeground(DARK_GREEN);
break;
case ForegroundCyan:
attr.SetIndexedForeground(DARK_CYAN);
break;
case ForegroundRed:
attr.SetIndexedForeground(DARK_RED);
break;
case ForegroundMagenta:
attr.SetIndexedForeground(DARK_MAGENTA);
break;
case ForegroundYellow:
attr.SetIndexedForeground(DARK_YELLOW);
break;
case ForegroundWhite:
attr.SetIndexedForeground(DARK_WHITE);
break;
case BackgroundBlack:
attr.SetIndexedBackground(DARK_BLACK);
break;
case BackgroundBlue:
attr.SetIndexedBackground(DARK_BLUE);
break;
case BackgroundGreen:
attr.SetIndexedBackground(DARK_GREEN);
break;
case BackgroundCyan:
attr.SetIndexedBackground(DARK_CYAN);
break;
case BackgroundRed:
attr.SetIndexedBackground(DARK_RED);
break;
case BackgroundMagenta:
attr.SetIndexedBackground(DARK_MAGENTA);
break;
case BackgroundYellow:
attr.SetIndexedBackground(DARK_YELLOW);
break;
case BackgroundWhite:
attr.SetIndexedBackground(DARK_WHITE);
break;
case BrightForegroundBlack:
attr.SetIndexedForeground(BRIGHT_BLACK);
break;
case BrightForegroundBlue:
attr.SetIndexedForeground(BRIGHT_BLUE);
break;
case BrightForegroundGreen:
attr.SetIndexedForeground(BRIGHT_GREEN);
break;
case BrightForegroundCyan:
attr.SetIndexedForeground(BRIGHT_CYAN);
break;
case BrightForegroundRed:
attr.SetIndexedForeground(BRIGHT_RED);
break;
case BrightForegroundMagenta:
attr.SetIndexedForeground(BRIGHT_MAGENTA);
break;
case BrightForegroundYellow:
attr.SetIndexedForeground(BRIGHT_YELLOW);
break;
case BrightForegroundWhite:
attr.SetIndexedForeground(BRIGHT_WHITE);
break;
case BrightBackgroundBlack:
attr.SetIndexedBackground(BRIGHT_BLACK);
break;
case BrightBackgroundBlue:
attr.SetIndexedBackground(BRIGHT_BLUE);
break;
case BrightBackgroundGreen:
attr.SetIndexedBackground(BRIGHT_GREEN);
break;
case BrightBackgroundCyan:
attr.SetIndexedBackground(BRIGHT_CYAN);
break;
case BrightBackgroundRed:
attr.SetIndexedBackground(BRIGHT_RED);
break;
case BrightBackgroundMagenta:
attr.SetIndexedBackground(BRIGHT_MAGENTA);
break;
case BrightBackgroundYellow:
attr.SetIndexedBackground(BRIGHT_YELLOW);
break;
case BrightBackgroundWhite:
attr.SetIndexedBackground(BRIGHT_WHITE);
break;
case ForegroundExtended:
i += _SetRgbColorsHelper(options.substr(i + 1), attr, true);
break;
case BackgroundExtended:
i += _SetRgbColorsHelper(options.substr(i + 1), attr, false);
break;
}
}
return success;
_terminalApi.SetTextAttributes(attr);
return true;
}