Skip to content

Commit

Permalink
Implement cell size customizations
Browse files Browse the repository at this point in the history
  • Loading branch information
lhecker committed Oct 19, 2022
1 parent bfd480b commit 3660b47
Show file tree
Hide file tree
Showing 26 changed files with 387 additions and 51 deletions.
20 changes: 20 additions & 0 deletions doc/cascadia/profiles.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,13 @@
},
"type": "object"
},
"CSSLengthPercentage": {
"pattern": "^[+-]?\\d+(?:\\.\\d+)?(?:%|px|pt)?$",
"type": [
"string",
"null"
]
},
"ProfileGuid": {
"default": "{}",
"pattern": "^\\{[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\\}$",
Expand Down Expand Up @@ -2086,6 +2093,19 @@
"null"
]
},
"cellSize": {
"type": "object",
"properties": {
"height": {
"$ref": "#/$defs/CSSLengthPercentage",
"description": "Override the height of the terminal's cells. The override works similar to CSS' line-height. Defaults to the sum of the natural glyph ascend, descend and line-gap of the primary font rounded to the nearest pixel. The default is usually quite close to setting this to 1.2."
},
"width": {
"$ref": "#/$defs/CSSLengthPercentage",
"description": "Override the width of the terminal's cells. The override works similar to CSS' line-height. Defaults to the natural glyph advance width of the primary font rounded to the nearest pixel."
}
}
},
"backgroundImage": {
"description": "Sets the file location of the image to draw over the window background.",
"oneOf": [
Expand Down
4 changes: 4 additions & 0 deletions src/cascadia/TerminalControl/ControlCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation

auto lock = _terminal->LockForWriting();

_cellSizeAdjustmentX = CSSLengthPercentage::FromString(_settings->CellSizeX().c_str());
_cellSizeAdjustmentY = CSSLengthPercentage::FromString(_settings->CellSizeY().c_str());
_runtimeOpacity = std::nullopt;
_runtimeUseAcrylic = std::nullopt;

Expand Down Expand Up @@ -871,6 +873,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_actualFont = { fontFace, 0, fontWeight.Weight, _desiredFont.GetEngineSize(), CP_UTF8, false };
_actualFontFaceName = { fontFace };

_desiredFont.SetCellSizes(_cellSizeAdjustmentX, _cellSizeAdjustmentY);

const auto before = _actualFont.GetSize();
_updateFont();
const auto after = _actualFont.GetSize();
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalControl/ControlCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
FontInfoDesired _desiredFont;
FontInfo _actualFont;
winrt::hstring _actualFontFaceName;
CSSLengthPercentage _cellSizeAdjustmentX;
CSSLengthPercentage _cellSizeAdjustmentY;

// storage location for the leading surrogate of a utf-16 surrogate pair
std::optional<wchar_t> _leadingSurrogate{ std::nullopt };
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalControl/IControlSettings.idl
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ namespace Microsoft.Terminal.Control
String Padding { get; };
Windows.Foundation.Collections.IMap<String, UInt32> FontFeatures { get; };
Windows.Foundation.Collections.IMap<String, Single> FontAxes { get; };
String CellSizeX { get; };
String CellSizeY { get; };

Microsoft.Terminal.Control.IKeyBindings KeyBindings { get; };

Expand Down
104 changes: 100 additions & 4 deletions src/cascadia/TerminalSettingsEditor/Appearances.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,88 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
}
}

double AppearanceViewModel::LineHeight() const noexcept
{
const auto cellSizeY = _appearance.SourceProfile().CellSizeY();
const auto str = cellSizeY.c_str();

auto& errnoRef = errno; // Nonzero cost, pay it once.
errnoRef = 0;

wchar_t* end;
const auto value = std::wcstod(str, &end);

return str == end || errnoRef == ERANGE ? NAN : value;
}

void AppearanceViewModel::LineHeight(const double value)
{
wchar_t buffer[16];
std::wstring_view view;

if (value >= 0.1 && value <= 10.0)
{
auto length = gsl::narrow<size_t>(swprintf_s(&buffer[0], std::size(buffer), L"%.6f", value));
const auto separator = std::wstring_view{ &buffer[0], length }.find(L'.');

if (separator != std::wstring_view::npos)
{
for (; length > separator && buffer[length - 1] == L'0'; --length)
{
}
// winrt::hstring expects a null-terminated string
buffer[length] = L'\0';
}

view = { &buffer[0], length };
}

const auto profile = _appearance.SourceProfile();

if (profile.CellSizeY() != view)
{
if (view.empty())
{
profile.ClearCellSizeY();
}
else
{
profile.CellSizeY(view);
}
_NotifyChanges(L"HasLineHeight", L"LineHeight");
}
}

bool AppearanceViewModel::HasLineHeight()
{
return _appearance.SourceProfile().HasCellSizeY();
}

void AppearanceViewModel::ClearLineHeight()
{
LineHeight({});
}

Model::Profile AppearanceViewModel::LineHeightOverrideSource()
{
return _appearance.SourceProfile().CellSizeYOverrideSource();
}

void AppearanceViewModel::SetFontWeightFromDouble(double fontWeight)
{
FontWeight(Converters::DoubleToFontWeight(fontWeight));
}

void AppearanceViewModel::SetBackgroundImageOpacityFromPercentageValue(double percentageValue)
{
BackgroundImageOpacity(Converters::PercentageValueToPercentage(percentageValue));
}

void AppearanceViewModel::SetBackgroundImagePath(winrt::hstring path)
{
BackgroundImagePath(path);
}

bool AppearanceViewModel::UseDesktopBGImage()
{
return BackgroundImagePath() == L"desktopWallpaper";
Expand Down Expand Up @@ -83,6 +165,16 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
return BackgroundImagePath() != L"";
}

IMapView<hstring, Model::ColorScheme> AppearanceViewModel::Schemes()
{
return _Schemes;
}

void AppearanceViewModel::Schemes(const IMapView<hstring, Model::ColorScheme>& val)
{
_Schemes = val;
}

DependencyProperty Appearances::_AppearanceProperty{ nullptr };

Appearances::Appearances() :
Expand All @@ -96,10 +188,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
// > .NET rounds to 12 significant digits when displaying doubles, so we will [...]
// ...obviously not do that, because this is an UI element for humans. This prevents
// issues when displaying 32-bit floats, because WinUI is unaware about their existence.
SignificantDigitsNumberRounder rounder;
rounder.SignificantDigits(6);
// BODGY: Depends on WinUI internals.
_fontSizeBox().NumberFormatter().as<DecimalFormatter>().NumberRounder(rounder);
IncrementNumberRounder rounder;
rounder.Increment(1e-6);

for (const auto& box : { _fontSizeBox(), _lineHeightBox() })
{
// BODGY: Depends on WinUI internals.
box.NumberFormatter().as<DecimalFormatter>().NumberRounder(rounder);
}
}

INITIALIZE_BINDABLE_ENUM_SETTING(CursorShape, CursorStyle, winrt::Microsoft::Terminal::Core::CursorStyle, L"Profile_CursorShape", L"Content");
Expand Down
25 changes: 11 additions & 14 deletions src/cascadia/TerminalSettingsEditor/Appearances.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,26 +51,22 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
public:
AppearanceViewModel(const Model::AppearanceConfig& appearance);

void SetFontWeightFromDouble(double fontWeight)
{
FontWeight(winrt::Microsoft::Terminal::Settings::Editor::Converters::DoubleToFontWeight(fontWeight));
}
void SetBackgroundImageOpacityFromPercentageValue(double percentageValue)
{
BackgroundImageOpacity(winrt::Microsoft::Terminal::Settings::Editor::Converters::PercentageValueToPercentage(percentageValue));
}
void SetBackgroundImagePath(winrt::hstring path)
{
BackgroundImagePath(path);
}
double LineHeight() const noexcept;
void LineHeight(const double value);
bool HasLineHeight();
void ClearLineHeight();
Model::Profile LineHeightOverrideSource();
void SetFontWeightFromDouble(double fontWeight);
void SetBackgroundImageOpacityFromPercentageValue(double percentageValue);
void SetBackgroundImagePath(winrt::hstring path);

// background image
bool UseDesktopBGImage();
void UseDesktopBGImage(const bool useDesktop);
bool BackgroundImageSettingsVisible();

Windows::Foundation::Collections::IMapView<hstring, Model::ColorScheme> Schemes() { return _Schemes; }
void Schemes(const Windows::Foundation::Collections::IMapView<hstring, Model::ColorScheme>& val) { _Schemes = val; }
Windows::Foundation::Collections::IMapView<hstring, Model::ColorScheme> Schemes();
void Schemes(const Windows::Foundation::Collections::IMapView<hstring, Model::ColorScheme>& val);

WINRT_PROPERTY(bool, IsDefault, false);
WINRT_PROPERTY(IHostedInWindow, WindowRoot, nullptr);
Expand Down Expand Up @@ -99,6 +95,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
Model::AppearanceConfig _appearance;
winrt::hstring _lastBgImagePath;
Windows::Foundation::Collections::IMapView<hstring, Model::ColorScheme> _Schemes;
float _cachedLineHeight = 0;
};

struct Appearances : AppearancesT<Appearances>
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsEditor/Appearances.idl
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ namespace Microsoft.Terminal.Settings.Editor

OBSERVABLE_PROJECTED_APPEARANCE_SETTING(String, FontFace);
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Single, FontSize);
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Double, LineHeight);
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Windows.UI.Text.FontWeight, FontWeight);

OBSERVABLE_PROJECTED_APPEARANCE_SETTING(String, ColorSchemeName);
Expand Down
18 changes: 18 additions & 0 deletions src/cascadia/TerminalSettingsEditor/Appearances.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,24 @@
Value="{x:Bind Appearance.FontSize, Mode=TwoWay}" />
</local:SettingContainer>

<!-- Line Height -->
<local:SettingContainer x:Uid="Profile_LineHeight"
ClearSettingValue="{x:Bind Appearance.ClearLineHeight}"
HasSettingValue="{x:Bind Appearance.HasLineHeight, Mode=OneWay}"
SettingOverrideSource="{x:Bind Appearance.LineHeightOverrideSource, Mode=OneWay}"
Visibility="{x:Bind Appearance.IsDefault, Mode=OneWay}">
<muxc:NumberBox x:Name="_lineHeightBox"
x:Uid="Profile_LineHeightBox"
AcceptsExpression="False"
LargeChange="0.1"
Maximum="10"
Minimum="0.1"
SmallChange="0.1"
SpinButtonPlacementMode="Compact"
Style="{StaticResource NumberBoxSettingStyle}"
Value="{x:Bind Appearance.LineHeight, Mode=TwoWay}" />
</local:SettingContainer>

<!-- Font Weight -->
<local:SettingContainer x:Name="FontWeightContainer"
x:Uid="Profile_FontWeight"
Expand Down
16 changes: 16 additions & 0 deletions src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,22 @@
<value>Size of the font in points.</value>
<comment>A description for what the "font size" setting does. Presented near "Profile_FontSize".</comment>
</data>
<data name="Profile_LineHeight.Header" xml:space="preserve">
<value>Line height</value>
<comment>Header for a control that sets the text line height.</comment>
</data>
<data name="Profile_LineHeightBox.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Line height</value>
<comment>Header for a control that sets the text line height.</comment>
</data>
<data name="Profile_LineHeight.HelpText" xml:space="preserve">
<value>Sets the height of each line in the terminal as a multiple of the font size. The default depends on your font and is usually around 1.2.</value>
<comment>A description for what the "line height" setting does. Presented near "Profile_LineHeight".</comment>
</data>
<data name="Profile_LineHeightBox.PlaceholderText" xml:space="preserve">
<value>1.2</value>
<comment>"1.2" is a decimal number.</comment>
</data>
<data name="Profile_FontWeightComboBox.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Font weight</value>
<comment>Name for a control to select the weight (i.e. bold, thin, etc.) of the text in the app.</comment>
Expand Down
4 changes: 3 additions & 1 deletion src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,9 @@ Model::Profile CascadiaSettings::DuplicateProfile(const Model::Profile& source)
MTSM_PROFILE_SETTINGS(DUPLICATE_PROFILE_SETTINGS)
#undef DUPLICATE_PROFILE_SETTINGS

// These two aren't in MTSM_PROFILE_SETTINGS because they're special
// These aren't in MTSM_PROFILE_SETTINGS because they're special
DUPLICATE_SETTING_MACRO(CellSizeX);
DUPLICATE_SETTING_MACRO(CellSizeY);
DUPLICATE_SETTING_MACRO(TabColor);
DUPLICATE_SETTING_MACRO(Padding);

Expand Down
20 changes: 17 additions & 3 deletions src/cascadia/TerminalSettingsModel/Profile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ static constexpr std::string_view SourceKey{ "source" };
static constexpr std::string_view HiddenKey{ "hidden" };

static constexpr std::string_view FontInfoKey{ "font" };
static constexpr std::string_view CellSizeKey{ "cellSize" };
static constexpr std::string_view CellSizeXKey{ "width" };
static constexpr std::string_view CellSizeYKey{ "height" };
static constexpr std::string_view PaddingKey{ "padding" };
static constexpr std::string_view TabColorKey{ "tabColor" };
static constexpr std::string_view UnfocusedAppearanceKey{ "unfocusedAppearance" };
Expand Down Expand Up @@ -102,6 +105,8 @@ winrt::com_ptr<Profile> Profile::CopySettings() const
profile->_Name = _Name;
profile->_Source = _Source;
profile->_Hidden = _Hidden;
profile->_CellSizeX = _CellSizeX;
profile->_CellSizeY = _CellSizeY;
profile->_TabColor = _TabColor;
profile->_Padding = _Padding;

Expand Down Expand Up @@ -171,10 +176,14 @@ void Profile::LayerJson(const Json::Value& json)
JsonUtils::GetValueForKey(json, HiddenKey, _Hidden);
JsonUtils::GetValueForKey(json, SourceKey, _Source);

if (const auto& cellSizeJSON = json[JsonKey(CellSizeKey)])
{
JsonUtils::GetValueForKey(cellSizeJSON, CellSizeXKey, _CellSizeX);
JsonUtils::GetValueForKey(cellSizeJSON, CellSizeYKey, _CellSizeY);
}
// Padding was never specified as an integer, but it was a common working mistake.
// Allow it to be permissive.
JsonUtils::GetValueForKey(json, PaddingKey, _Padding, JsonUtils::OptionalConverter<hstring, JsonUtils::PermissiveStringConverter<std::wstring>>{});

JsonUtils::GetValueForKey(json, TabColorKey, _TabColor);

#define PROFILE_SETTINGS_LAYER_JSON(type, name, jsonKey, ...) \
Expand Down Expand Up @@ -313,9 +322,14 @@ Json::Value Profile::ToJson() const
JsonUtils::SetValueForKey(json, HiddenKey, writeBasicSettings ? Hidden() : _Hidden);
JsonUtils::SetValueForKey(json, SourceKey, writeBasicSettings ? Source() : _Source);

// PermissiveStringConverter is unnecessary for serialization
if (_CellSizeX || _CellSizeY)
{
Json::Value cellSizeJSON{ Json::ValueType::objectValue };
JsonUtils::SetValueForKey(cellSizeJSON, CellSizeXKey, _CellSizeX);
JsonUtils::SetValueForKey(cellSizeJSON, CellSizeYKey, _CellSizeY);
json[JsonKey(CellSizeKey)] = std::move(cellSizeJSON);
}
JsonUtils::SetValueForKey(json, PaddingKey, _Padding);

JsonUtils::SetValueForKey(json, TabColorKey, _TabColor);

#define PROFILE_SETTINGS_TO_JSON(type, name, jsonKey, ...) \
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalSettingsModel/Profile.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
INHERITABLE_SETTING(Model::Profile, hstring, Source);
INHERITABLE_SETTING(Model::Profile, bool, Hidden, false);
INHERITABLE_SETTING(Model::Profile, guid, Guid, _GenerateGuidForProfile(Name(), Source()));
INHERITABLE_SETTING(Model::Profile, hstring, CellSizeX);
INHERITABLE_SETTING(Model::Profile, hstring, CellSizeY);
INHERITABLE_SETTING(Model::Profile, hstring, Padding, DEFAULT_PADDING);

#define PROFILE_SETTINGS_INITIALIZE(type, name, jsonKey, ...) \
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalSettingsModel/Profile.idl
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ namespace Microsoft.Terminal.Settings.Model
String EvaluatedStartingDirectory { get; };

FontConfig FontInfo { get; };
INHERITABLE_PROFILE_SETTING(String, CellSizeX);
INHERITABLE_PROFILE_SETTING(String, CellSizeY);

IAppearanceConfig DefaultAppearance { get; };
INHERITABLE_PROFILE_SETTING(IAppearanceConfig, UnfocusedAppearance);
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalSettingsModel/TerminalSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
_FontWeight = profile.FontInfo().FontWeight();
_FontFeatures = profile.FontInfo().FontFeatures();
_FontAxes = profile.FontInfo().FontAxes();
_CellSizeX = profile.CellSizeX();
_CellSizeY = profile.CellSizeY();
_Padding = profile.Padding();

_Commandline = profile.Commandline();
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalSettingsModel/TerminalSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
INHERITABLE_SETTING(Model::TerminalSettings, winrt::Windows::UI::Text::FontWeight, FontWeight);
INHERITABLE_SETTING(Model::TerminalSettings, IFontAxesMap, FontAxes);
INHERITABLE_SETTING(Model::TerminalSettings, IFontFeatureMap, FontFeatures);
INHERITABLE_SETTING(Model::TerminalSettings, hstring, CellSizeX);
INHERITABLE_SETTING(Model::TerminalSettings, hstring, CellSizeY);

INHERITABLE_SETTING(Model::TerminalSettings, Model::ColorScheme, AppliedColorScheme);
INHERITABLE_SETTING(Model::TerminalSettings, hstring, BackgroundImage);
Expand Down
Loading

0 comments on commit 3660b47

Please sign in to comment.