Add support for cleartype text antialiasing (#4711)
## Summary of the Pull Request I needed to do something to keep sane so today I day of learned about antialiasing. This PR adds the ability to specify the `"antialiasingMode"` as a setting. * "antialiasingMode": "grayscale": the current behavior, `D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE` * "antialiasingMode": "cleartype": use `D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE` instead ## PR Checklist * [x] Closes #1298 * [x] I work here * [ ] I didn't add tests * [x] Requires documentation to be updated ## Detailed Description of the Pull Request / Additional comments Grayscale: ![image](https://user-images.githubusercontent.com/18356694/75173847-2373f680-56f5-11ea-8896-c1cf04c61d41.png) Cleartype: ![image](https://user-images.githubusercontent.com/18356694/75173854-25d65080-56f5-11ea-9de1-e2d1c343cae5.png) Side-by-side (can you tell which is which?) <!-- grayscale, cleartype --> ![image](https://user-images.githubusercontent.com/18356694/75173864-28d14100-56f5-11ea-8bdd-d47a60fbbe4d.png)
This commit is contained in:
parent
4def49c45e
commit
8a5407c13a
|
@ -29,6 +29,7 @@ Properties listed below are specific to each unique profile.
|
|||
| `guid` | _Required_ | String | | Unique identifier of the profile. Written in registry format: `"{00000000-0000-0000-0000-000000000000}"`. |
|
||||
| `name` | _Required_ | String | | Name of the profile. Displays in the dropdown menu. <br>Additionally, this value will be used as the "title" to pass to the shell on startup. Some shells (like `bash`) may choose to ignore this initial value, while others (`cmd`, `powershell`) may use this value over the lifetime of the application. This "title" behavior can be overridden by using `tabTitle`. |
|
||||
| `acrylicOpacity` | Optional | Number | `0.5` | When `useAcrylic` is set to `true`, it sets the transparency of the window for the profile. Accepts floating point values from 0-1. |
|
||||
| `antialiasingMode` | Optional | String | `"grayscale"` | Controls how text is antialiased in the renderer. Possible values are "grayscale", "cleartype" and "aliased". Note that changing this setting will require starting a new terminal instance. |
|
||||
| `background` | Optional | String | | Sets the background color of the profile. Overrides `background` set in color scheme if `colorscheme` is set. Uses hex color format: `"#rrggbb"`. |
|
||||
| `backgroundImage` | Optional | String | | Sets the file location of the Image to draw over the window background. |
|
||||
| `backgroundImageAlignment` | Optional | String | `center` | Sets how the background image aligns to the boundaries of the window. Possible values: `"center"`, `"left"`, `"top"`, `"right"`, `"bottom"`, `"topLeft"`, `"topRight"`, `"bottomLeft"`, `"bottomRight"` |
|
||||
|
|
|
@ -378,6 +378,16 @@
|
|||
"minimum": 0,
|
||||
"type": "number"
|
||||
},
|
||||
"antialiasingMode": {
|
||||
"default": "grayscale",
|
||||
"description": "Controls how text is antialiased in the renderer. Possible values are \"grayscale\", \"cleartype\" and \"aliased\". Note that changing this setting will require starting a new terminal instance.",
|
||||
"enum": [
|
||||
"grayscale",
|
||||
"cleartype",
|
||||
"aliased"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"background": {
|
||||
"$ref": "#/definitions/Color",
|
||||
"default": "#0c0c0c",
|
||||
|
|
|
@ -49,6 +49,8 @@ static constexpr std::string_view BackgroundImageKey{ "backgroundImage" };
|
|||
static constexpr std::string_view BackgroundImageOpacityKey{ "backgroundImageOpacity" };
|
||||
static constexpr std::string_view BackgroundImageStretchModeKey{ "backgroundImageStretchMode" };
|
||||
static constexpr std::string_view BackgroundImageAlignmentKey{ "backgroundImageAlignment" };
|
||||
static constexpr std::string_view RetroTerminalEffectKey{ "experimental.retroTerminalEffect" };
|
||||
static constexpr std::string_view AntialiasingModeKey{ "antialiasingMode" };
|
||||
|
||||
// Possible values for closeOnExit
|
||||
static constexpr std::string_view CloseOnExitAlways{ "always" };
|
||||
|
@ -83,8 +85,10 @@ static constexpr std::string_view ImageAlignmentTopRight{ "topRight" };
|
|||
static constexpr std::string_view ImageAlignmentBottomLeft{ "bottomLeft" };
|
||||
static constexpr std::string_view ImageAlignmentBottomRight{ "bottomRight" };
|
||||
|
||||
// Terminal effects
|
||||
static constexpr std::string_view RetroTerminalEffectKey{ "experimental.retroTerminalEffect" };
|
||||
// Possible values for TextAntialiasingMode
|
||||
static constexpr std::wstring_view AntialiasingModeGrayscale{ L"grayscale" };
|
||||
static constexpr std::wstring_view AntialiasingModeCleartype{ L"cleartype" };
|
||||
static constexpr std::wstring_view AntialiasingModeAliased{ L"aliased" };
|
||||
|
||||
Profile::Profile() :
|
||||
Profile(std::nullopt)
|
||||
|
@ -124,7 +128,8 @@ Profile::Profile(const std::optional<GUID>& guid) :
|
|||
_backgroundImageOpacity{},
|
||||
_backgroundImageStretchMode{},
|
||||
_backgroundImageAlignment{},
|
||||
_retroTerminalEffect{}
|
||||
_retroTerminalEffect{},
|
||||
_antialiasingMode{ TextAntialiasingMode::Grayscale }
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -257,6 +262,8 @@ TerminalSettings Profile::CreateTerminalSettings(const std::unordered_map<std::w
|
|||
terminalSettings.RetroTerminalEffect(_retroTerminalEffect.value());
|
||||
}
|
||||
|
||||
terminalSettings.AntialiasingMode(_antialiasingMode);
|
||||
|
||||
return terminalSettings;
|
||||
}
|
||||
|
||||
|
@ -377,6 +384,8 @@ Json::Value Profile::ToJson() const
|
|||
root[JsonKey(RetroTerminalEffectKey)] = _retroTerminalEffect.value();
|
||||
}
|
||||
|
||||
root[JsonKey(AntialiasingModeKey)] = SerializeTextAntialiasingMode(_antialiasingMode).data();
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
|
@ -742,6 +751,12 @@ void Profile::LayerJson(const Json::Value& json)
|
|||
JsonUtils::GetOptionalValue(json, BackgroundImageAlignmentKey, _backgroundImageAlignment, &Profile::_ConvertJsonToAlignment);
|
||||
|
||||
JsonUtils::GetOptionalValue(json, RetroTerminalEffectKey, _retroTerminalEffect, Profile::_ConvertJsonToBool);
|
||||
|
||||
if (json.isMember(JsonKey(AntialiasingModeKey)))
|
||||
{
|
||||
auto antialiasingMode{ json[JsonKey(AntialiasingModeKey)] };
|
||||
_antialiasingMode = ParseTextAntialiasingMode(GetWstringFromJson(antialiasingMode));
|
||||
}
|
||||
}
|
||||
|
||||
void Profile::SetFontFace(std::wstring fontFace) noexcept
|
||||
|
@ -1349,3 +1364,49 @@ void Profile::SetRetroTerminalEffect(bool value) noexcept
|
|||
{
|
||||
_retroTerminalEffect = value;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Helper function for converting a user-specified antialiasing mode
|
||||
// corresponding TextAntialiasingMode enum value
|
||||
// Arguments:
|
||||
// - antialiasingMode: The string value from the settings file to parse
|
||||
// Return Value:
|
||||
// - The corresponding enum value which maps to the string provided by the user
|
||||
TextAntialiasingMode Profile::ParseTextAntialiasingMode(const std::wstring& antialiasingMode)
|
||||
{
|
||||
if (antialiasingMode == AntialiasingModeCleartype)
|
||||
{
|
||||
return TextAntialiasingMode::Cleartype;
|
||||
}
|
||||
else if (antialiasingMode == AntialiasingModeAliased)
|
||||
{
|
||||
return TextAntialiasingMode::Aliased;
|
||||
}
|
||||
else if (antialiasingMode == AntialiasingModeGrayscale)
|
||||
{
|
||||
return TextAntialiasingMode::Grayscale;
|
||||
}
|
||||
// default behavior for invalid data
|
||||
return TextAntialiasingMode::Grayscale;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Helper function for converting a TextAntialiasingMode to its corresponding
|
||||
// string value.
|
||||
// Arguments:
|
||||
// - antialiasingMode: The enum value to convert to a string.
|
||||
// Return Value:
|
||||
// - The string value for the given TextAntialiasingMode
|
||||
std::wstring_view Profile::SerializeTextAntialiasingMode(const TextAntialiasingMode antialiasingMode)
|
||||
{
|
||||
switch (antialiasingMode)
|
||||
{
|
||||
case TextAntialiasingMode::Cleartype:
|
||||
return AntialiasingModeCleartype;
|
||||
case TextAntialiasingMode::Aliased:
|
||||
return AntialiasingModeAliased;
|
||||
default:
|
||||
case TextAntialiasingMode::Grayscale:
|
||||
return AntialiasingModeGrayscale;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,6 +123,9 @@ private:
|
|||
static winrt::Microsoft::Terminal::Settings::CursorStyle _ParseCursorShape(const std::wstring& cursorShapeString);
|
||||
static std::wstring_view _SerializeCursorStyle(const winrt::Microsoft::Terminal::Settings::CursorStyle cursorShape);
|
||||
|
||||
static winrt::Microsoft::Terminal::Settings::TextAntialiasingMode ParseTextAntialiasingMode(const std::wstring& antialiasingMode);
|
||||
static std::wstring_view SerializeTextAntialiasingMode(const winrt::Microsoft::Terminal::Settings::TextAntialiasingMode antialiasingMode);
|
||||
|
||||
static GUID _GenerateGuidForProfile(const std::wstring& name, const std::optional<std::wstring>& source) noexcept;
|
||||
|
||||
static bool _ConvertJsonToBool(const Json::Value& json);
|
||||
|
@ -166,6 +169,8 @@ private:
|
|||
|
||||
std::optional<std::wstring> _icon;
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::TextAntialiasingMode _antialiasingMode;
|
||||
|
||||
friend class TerminalAppLocalTests::SettingsTests;
|
||||
friend class TerminalAppLocalTests::ProfileTests;
|
||||
friend class TerminalAppUnitTests::JsonTests;
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
"icon": "ms-appx:///ProfileIcons/{61c54bbd-c2c6-5271-96e7-009a87ff44bf}.png",
|
||||
"padding": "8, 8, 8, 8",
|
||||
"snapOnInput": true,
|
||||
"useAcrylic": false
|
||||
"useAcrylic": false,
|
||||
"antialiasingMode": "grayscale"
|
||||
},
|
||||
{
|
||||
"guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
|
||||
|
@ -48,7 +49,8 @@
|
|||
"icon": "ms-appx:///ProfileIcons/{0caa0dad-35be-5f56-a8ff-afceeeaa6101}.png",
|
||||
"padding": "8, 8, 8, 8",
|
||||
"snapOnInput": true,
|
||||
"useAcrylic": false
|
||||
"useAcrylic": false,
|
||||
"antialiasingMode": "grayscale"
|
||||
}
|
||||
],
|
||||
"schemes":
|
||||
|
|
|
@ -638,6 +638,22 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
// here, the setting will only be used when the Terminal is initialized.
|
||||
dxEngine->SetRetroTerminalEffects(_settings.RetroTerminalEffect());
|
||||
|
||||
// TODO:GH#3927 - hot-reload this one too
|
||||
// Update DxEngine's AntialiasingMode
|
||||
switch (_settings.AntialiasingMode())
|
||||
{
|
||||
case TextAntialiasingMode::Cleartype:
|
||||
dxEngine->SetAntialiasingMode(D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE);
|
||||
break;
|
||||
case TextAntialiasingMode::Aliased:
|
||||
dxEngine->SetAntialiasingMode(D2D1_TEXT_ANTIALIAS_MODE_ALIASED);
|
||||
break;
|
||||
case TextAntialiasingMode::Grayscale:
|
||||
default:
|
||||
dxEngine->SetAntialiasingMode(D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE);
|
||||
break;
|
||||
}
|
||||
|
||||
THROW_IF_FAILED(dxEngine->Enable());
|
||||
_renderEngine = std::move(dxEngine);
|
||||
|
||||
|
|
|
@ -12,6 +12,13 @@ namespace Microsoft.Terminal.Settings
|
|||
Hidden
|
||||
};
|
||||
|
||||
enum TextAntialiasingMode
|
||||
{
|
||||
Grayscale = 0,
|
||||
Cleartype,
|
||||
Aliased
|
||||
};
|
||||
|
||||
// Class Description:
|
||||
// TerminalSettings encapsulates all settings that control the
|
||||
// TermControl's behavior. In these settings there is both the entirety
|
||||
|
@ -41,5 +48,7 @@ namespace Microsoft.Terminal.Settings
|
|||
|
||||
UInt32 SelectionBackground;
|
||||
Boolean RetroTerminalEffect;
|
||||
|
||||
TextAntialiasingMode AntialiasingMode;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -39,7 +39,9 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
|
|||
_backgroundImageHorizontalAlignment{ winrt::Windows::UI::Xaml::HorizontalAlignment::Center },
|
||||
_backgroundImageVerticalAlignment{ winrt::Windows::UI::Xaml::VerticalAlignment::Center },
|
||||
_keyBindings{ nullptr },
|
||||
_scrollbarState{ ScrollbarState::Visible }
|
||||
_scrollbarState{ ScrollbarState::Visible },
|
||||
_antialiasingMode{ TextAntialiasingMode::Grayscale }
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -374,4 +376,14 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
|
|||
_retroTerminalEffect = value;
|
||||
}
|
||||
|
||||
Settings::TextAntialiasingMode TerminalSettings::AntialiasingMode() const noexcept
|
||||
{
|
||||
return _antialiasingMode;
|
||||
}
|
||||
|
||||
void TerminalSettings::AntialiasingMode(const Settings::TextAntialiasingMode& value) noexcept
|
||||
{
|
||||
_antialiasingMode = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -102,6 +102,9 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
|
|||
bool RetroTerminalEffect() noexcept;
|
||||
void RetroTerminalEffect(bool value) noexcept;
|
||||
|
||||
TextAntialiasingMode AntialiasingMode() const noexcept;
|
||||
void AntialiasingMode(winrt::Microsoft::Terminal::Settings::TextAntialiasingMode const& value) noexcept;
|
||||
|
||||
private:
|
||||
uint32_t _defaultForeground;
|
||||
uint32_t _defaultBackground;
|
||||
|
@ -137,6 +140,8 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
|
|||
Settings::ScrollbarState _scrollbarState;
|
||||
|
||||
bool _retroTerminalEffect;
|
||||
|
||||
Settings::TextAntialiasingMode _antialiasingMode;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@ DxEngine::DxEngine() :
|
|||
_glyphCell{ 0 },
|
||||
_haveDeviceResources{ false },
|
||||
_retroTerminalEffects{ false },
|
||||
_antialiasingMode{ D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE },
|
||||
_hwndTarget{ static_cast<HWND>(INVALID_HANDLE_VALUE) },
|
||||
_sizeTarget{ 0 },
|
||||
_dpi{ USER_DEFAULT_SCREEN_DPI },
|
||||
|
@ -504,7 +505,8 @@ HRESULT DxEngine::_SetupTerminalEffects()
|
|||
&props,
|
||||
&_d2dRenderTarget));
|
||||
|
||||
_d2dRenderTarget->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE);
|
||||
_d2dRenderTarget->SetTextAntialiasMode(_antialiasingMode);
|
||||
|
||||
RETURN_IF_FAILED(_d2dRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::DarkRed),
|
||||
&_d2dBrushBackground));
|
||||
|
||||
|
@ -2115,3 +2117,17 @@ void DxEngine::SetSelectionBackground(const COLORREF color) noexcept
|
|||
GetBValue(color) / 255.0f,
|
||||
0.5f);
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Changes the antialiasing mode of the renderer. This must be called before
|
||||
// _PrepareRenderTarget, otherwise the renderer will default to
|
||||
// D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE.
|
||||
// Arguments:
|
||||
// - antialiasingMode: a value from the D2D1_TEXT_ANTIALIAS_MODE enum. See:
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/d2d1/ne-d2d1-d2d1_text_antialias_mode
|
||||
// Return Value:
|
||||
// - N/A
|
||||
void DxEngine::SetAntialiasingMode(const D2D1_TEXT_ANTIALIAS_MODE antialiasingMode) noexcept
|
||||
{
|
||||
_antialiasingMode = antialiasingMode;
|
||||
}
|
||||
|
|
|
@ -104,6 +104,7 @@ namespace Microsoft::Console::Render
|
|||
float GetScaling() const noexcept;
|
||||
|
||||
void SetSelectionBackground(const COLORREF color) noexcept;
|
||||
void SetAntialiasingMode(const D2D1_TEXT_ANTIALIAS_MODE antialiasingMode) noexcept;
|
||||
|
||||
protected:
|
||||
[[nodiscard]] HRESULT _DoUpdateTitle(_In_ const std::wstring& newTitle) noexcept override;
|
||||
|
@ -190,6 +191,8 @@ namespace Microsoft::Console::Render
|
|||
::Microsoft::WRL::ComPtr<ID3D11SamplerState> _samplerState;
|
||||
::Microsoft::WRL::ComPtr<ID3D11Texture2D> _framebufferCapture;
|
||||
|
||||
D2D1_TEXT_ANTIALIAS_MODE _antialiasingMode;
|
||||
|
||||
[[nodiscard]] HRESULT _CreateDeviceResources(const bool createSwapChain) noexcept;
|
||||
HRESULT _SetupTerminalEffects();
|
||||
|
||||
|
|
Loading…
Reference in New Issue