Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Group font options in the json into a single object #10433

Merged
merged 14 commits into from
Jul 1, 2021
63 changes: 57 additions & 6 deletions doc/cascadia/profiles.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,49 @@
},
"type": "object"
},
"FontConfig": {
"properties": {
"face": {
"default": "Cascadia Mono",
"description": "Name of the font face used in the profile.",
"type": "string"
},
"size": {
"default": 12,
"description": "Size of the font in points.",
"minimum": 1,
"type": "integer"
},
"weight": {
"default": "normal",
"description": "Sets the weight (lightness or heaviness of the strokes) for the given font. Possible values:\n -\"thin\"\n -\"extra-light\"\n -\"light\"\n -\"semi-light\"\n -\"normal\" (default)\n -\"medium\"\n -\"semi-bold\"\n -\"bold\"\n -\"extra-bold\"\n -\"black\"\n -\"extra-black\"\n or the corresponding numeric representation of OpenType font weight.",
"oneOf": [
{
"enum": [
"thin",
"extra-light",
"light",
"semi-light",
"normal",
"medium",
"semi-bold",
"bold",
"extra-bold",
"black",
"extra-black"
],
"type": "string"
},
{
"maximum": 990,
"minimum": 100,
"type": "integer"
}
]
}
},
"type": "object"
},
"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 @@ -1242,6 +1285,11 @@
"description": "Sets the appearance of the terminal when it is unfocused.",
"type": ["object", "null"]
},
"font": {
"$ref": "#/definitions/FontConfig",
"description": "Sets the font options of the terminal.",
"type": ["object", "null"]
},
"backgroundImage": {
"description": "Sets the file location of the image to draw over the window background.",
"oneOf": [
Expand Down Expand Up @@ -1358,18 +1406,20 @@
},
"fontFace": {
"default": "Cascadia Mono",
"description": "Name of the font face used in the profile.",
"type": "string"
"description": "[deprecated] Define 'face' within the 'font' object instead.",
"type": "string",
"deprecated": true
},
"fontSize": {
"default": 12,
"description": "Size of the font in points.",
"description": "[deprecated] Define 'size' within the 'font' object instead.",
"minimum": 1,
"type": "integer"
"type": "integer",
"deprecated": true
},
"fontWeight": {
"default": "normal",
"description": "Sets the weight (lightness or heaviness of the strokes) for the given font. Possible values:\n -\"thin\"\n -\"extra-light\"\n -\"light\"\n -\"semi-light\"\n -\"normal\" (default)\n -\"medium\"\n -\"semi-bold\"\n -\"bold\"\n -\"extra-bold\"\n -\"black\"\n -\"extra-black\"\n or the corresponding numeric representation of OpenType font weight.",
"description": "[deprecated] Define 'weight' within the 'font' object instead.",
"oneOf": [
{
"enum": [
Expand All @@ -1392,7 +1442,8 @@
"minimum": 100,
"type": "integer"
}
]
],
"deprecated": true
},
"foreground": {
"$ref": "#/definitions/Color",
Expand Down
46 changes: 41 additions & 5 deletions src/cascadia/LocalTests_SettingsModel/SerializationTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ namespace SettingsModelLocalTests
TEST_METHOD(ColorScheme);
TEST_METHOD(Actions);
TEST_METHOD(CascadiaSettings);
TEST_METHOD(LegacyFontSettings);

TEST_CLASS_SETUP(ClassSetup)
{
Expand Down Expand Up @@ -138,9 +139,11 @@ namespace SettingsModelLocalTests
"tabTitle": "Cool Tab",
"suppressApplicationTitle": false,

"fontFace": "Cascadia Mono",
"fontSize": 12,
"fontWeight": "normal",
"font": {
"face": "Cascadia Mono",
"size": 12,
"weight": "normal"
},
"padding": "8, 8, 8, 8",
"antialiasingMode": "grayscale",

Expand Down Expand Up @@ -402,11 +405,13 @@ namespace SettingsModelLocalTests

"profiles": {
"defaults": {
"fontFace": "Zamora Code"
"font": {
"face": "Zamora Code"
}
},
"list": [
{
"fontFace": "Cascadia Code",
"font": { "face": "Cascadia Code" },
"guid": "{61c54bbd-1111-5271-96e7-009a87ff44bf}",
"name": "HowettShell"
},
Expand Down Expand Up @@ -464,4 +469,35 @@ namespace SettingsModelLocalTests
const auto result{ settings->ToJson() };
VERIFY_ARE_EQUAL(toString(settings->_userSettings), toString(result));
}

void SerializationTests::LegacyFontSettings()
{
const std::string profileString{ R"(
{
"name": "Profile with legacy font settings",

"fontFace": "Cascadia Mono",
"fontSize": 12,
"fontWeight": "normal"
})" };

const std::string expectedOutput{ R"(
{
"name": "Profile with legacy font settings",

"font": {
"face": "Cascadia Mono",
"size": 12,
"weight": "normal"
}
})" };

const auto json{ VerifyParseSucceeded(profileString) };
const auto settings{ implementation::Profile::FromJson(json) };
const auto result{ settings->ToJson() };

const auto jsonOutput{ VerifyParseSucceeded(expectedOutput) };

VERIFY_ARE_EQUAL(toString(jsonOutput), toString(result));
}
}
6 changes: 3 additions & 3 deletions src/cascadia/TerminalSettingsEditor/Profiles.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
OBSERVABLE_PROJECTED_SETTING(_profile, UseAcrylic);
OBSERVABLE_PROJECTED_SETTING(_profile, AcrylicOpacity);
OBSERVABLE_PROJECTED_SETTING(_profile, ScrollState);
OBSERVABLE_PROJECTED_SETTING(_profile, FontFace);
OBSERVABLE_PROJECTED_SETTING(_profile, FontSize);
OBSERVABLE_PROJECTED_SETTING(_profile, FontWeight);
OBSERVABLE_PROJECTED_SETTING(_profile.FontInfo(), FontFace);
OBSERVABLE_PROJECTED_SETTING(_profile.FontInfo(), FontSize);
OBSERVABLE_PROJECTED_SETTING(_profile.FontInfo(), FontWeight);
OBSERVABLE_PROJECTED_SETTING(_profile, Padding);
OBSERVABLE_PROJECTED_SETTING(_profile, Commandline);
OBSERVABLE_PROJECTED_SETTING(_profile, StartingDirectory);
Expand Down
14 changes: 11 additions & 3 deletions src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,13 @@ winrt::Microsoft::Terminal::Settings::Model::Profile CascadiaSettings::Duplicate
duplicated->##settingName(source.##settingName()); \
}

#define DUPLICATE_FONT_SETTING_MACRO(settingName) \
if (source.FontInfo().Has##settingName() || \
(source.FontInfo().##settingName##OverrideSource() != nullptr && source.FontInfo().##settingName##OverrideSource().SourceProfile().Origin() != OriginTag::ProfilesDefaults)) \
{ \
duplicated->FontInfo().##settingName(source.FontInfo().##settingName()); \
}
lhecker marked this conversation as resolved.
Show resolved Hide resolved

#define DUPLICATE_APPEARANCE_SETTING_MACRO(settingName) \
if (source.DefaultAppearance().Has##settingName() || \
(source.DefaultAppearance().##settingName##OverrideSource() != nullptr && source.DefaultAppearance().##settingName##OverrideSource().SourceProfile().Origin() != OriginTag::ProfilesDefaults)) \
Expand All @@ -312,9 +319,6 @@ winrt::Microsoft::Terminal::Settings::Model::Profile CascadiaSettings::Duplicate
DUPLICATE_SETTING_MACRO(UseAcrylic);
DUPLICATE_SETTING_MACRO(AcrylicOpacity);
DUPLICATE_SETTING_MACRO(ScrollState);
DUPLICATE_SETTING_MACRO(FontFace);
DUPLICATE_SETTING_MACRO(FontSize);
DUPLICATE_SETTING_MACRO(FontWeight);
DUPLICATE_SETTING_MACRO(Padding);
DUPLICATE_SETTING_MACRO(Commandline);
DUPLICATE_SETTING_MACRO(StartingDirectory);
Expand All @@ -326,6 +330,10 @@ winrt::Microsoft::Terminal::Settings::Model::Profile CascadiaSettings::Duplicate
DUPLICATE_SETTING_MACRO(AltGrAliasing);
DUPLICATE_SETTING_MACRO(BellStyle);

DUPLICATE_FONT_SETTING_MACRO(FontFace);
DUPLICATE_FONT_SETTING_MACRO(FontSize);
DUPLICATE_FONT_SETTING_MACRO(FontWeight);

DUPLICATE_APPEARANCE_SETTING_MACRO(ColorSchemeName);
DUPLICATE_APPEARANCE_SETTING_MACRO(Foreground);
DUPLICATE_APPEARANCE_SETTING_MACRO(Background);
Expand Down
87 changes: 87 additions & 0 deletions src/cascadia/TerminalSettingsModel/FontConfig.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

#include "pch.h"
#include "FontConfig.h"
#include "FontConfig.g.cpp"
#include "TerminalSettingsSerializationHelpers.h"
#include "JsonUtils.h"

using namespace Microsoft::Terminal::Settings::Model;
using namespace winrt::Microsoft::Terminal::Settings::Model::implementation;

static constexpr std::string_view FontInfoKey{ "font" };
static constexpr std::string_view FontFaceKey{ "face" };
static constexpr std::string_view FontSizeKey{ "size" };
static constexpr std::string_view FontWeightKey{ "weight" };
static constexpr std::string_view LegacyFontFaceKey{ "fontFace" };
static constexpr std::string_view LegacyFontSizeKey{ "fontSize" };
static constexpr std::string_view LegacyFontWeightKey{ "fontWeight" };

winrt::Microsoft::Terminal::Settings::Model::implementation::FontConfig::FontConfig(const winrt::weak_ref<Profile> sourceProfile) :
_sourceProfile(sourceProfile)
PankajBhojwani marked this conversation as resolved.
Show resolved Hide resolved
{
}

winrt::com_ptr<FontConfig> FontConfig::CopyFontInfo(const winrt::com_ptr<FontConfig> source, const winrt::weak_ref<Profile> sourceProfile)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taking those arguments by value will force the reference count to be incremented for the duration of the call. It's probably a good idea to just take source as a pointer or reference as you aren't storing it elsewhere for later.
Especially because the code around winrt::com_ptr::copy_from feels a bit non-obvious / roundabout to me.

Copy link
Contributor Author

@PankajBhojwani PankajBhojwani Jun 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this was intentionally done this way to maintain consistency with Profile::CopySettings and AppearanceConfig::CopyAppearance and I'd like to keep it this way because of that

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm convinced that we'll have to start to clean up such code in the future though.
Isn't it quite seldom that you touch all places simultaneously to clean something up? I don't believe there's (in a rhetoric sense) "any better time to do it than now", as such house-keeping tasks will always be unrelated to any actual task by their nature.

{
auto fontInfo{ winrt::make_self<FontConfig>(sourceProfile) };
PankajBhojwani marked this conversation as resolved.
Show resolved Hide resolved
auto const sourceFontInfo = source.try_as<FontConfig>();
fontInfo->_FontFace = sourceFontInfo->_FontFace;
fontInfo->_FontSize = sourceFontInfo->_FontSize;
fontInfo->_FontWeight = sourceFontInfo->_FontWeight;
PankajBhojwani marked this conversation as resolved.
Show resolved Hide resolved
return fontInfo;
}

Json::Value FontConfig::ToJson() const
{
Json::Value json{ Json::ValueType::objectValue };

JsonUtils::SetValueForKey(json, FontFaceKey, _FontFace);
JsonUtils::SetValueForKey(json, FontSizeKey, _FontSize);
JsonUtils::SetValueForKey(json, FontWeightKey, _FontWeight);

return json;
}

// Method Description:
// - Layer values from the given json object on top of the existing properties
// of this object. For any keys we're expecting to be able to parse in the
// given object, we'll parse them and replace our settings with values from
// the new json object. Properties that _aren't_ in the json object will _not_
// be replaced.
// - Optional values that are set to `null` in the json object
// will be set to nullopt.
// - This is similar to Profile::LayerJson but for FontConfig
// Arguments:
// - json: an object which should be a partial serialization of a FontConfig object.
void FontConfig::LayerJson(const Json::Value& json)
{
// Legacy users may not have a font object defined in their profile,
// so check for that before we decide how to parse this
if (json.isMember(JsonKey(FontInfoKey)))
{
// A font object is defined, use that
const auto fontInfoJson = json[JsonKey(FontInfoKey)];
JsonUtils::GetValueForKey(fontInfoJson, FontFaceKey, _FontFace);
JsonUtils::GetValueForKey(fontInfoJson, FontSizeKey, _FontSize);
JsonUtils::GetValueForKey(fontInfoJson, FontWeightKey, _FontWeight);
}
else
{
// No font object is defined
JsonUtils::GetValueForKey(json, LegacyFontFaceKey, _FontFace);
JsonUtils::GetValueForKey(json, LegacyFontSizeKey, _FontSize);
JsonUtils::GetValueForKey(json, LegacyFontWeightKey, _FontWeight);
}
}

bool FontConfig::HasAnyOptionSet() const
{
return HasFontFace() || HasFontSize() || HasFontWeight();
}

winrt::Microsoft::Terminal::Settings::Model::Profile FontConfig::SourceProfile()
{
return _sourceProfile.get();
}
46 changes: 46 additions & 0 deletions src/cascadia/TerminalSettingsModel/FontConfig.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.

Module Name:
- FontConfig

Abstract:
- The implementation of the FontConfig winrt class. Provides settings related
to the font settings of the terminal, for the terminal control.

Author(s):
- Pankaj Bhojwani - June 2021

--*/

#pragma once

#include "pch.h"
#include "FontConfig.g.h"
#include "JsonUtils.h"
#include "../inc/cppwinrt_utils.h"
#include "IInheritable.h"
#include <DefaultSettings.h>

namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{
struct FontConfig : FontConfigT<FontConfig>, IInheritable<FontConfig>
{
public:
FontConfig(const winrt::weak_ref<Profile> sourceProfile);
static winrt::com_ptr<FontConfig> CopyFontInfo(const winrt::com_ptr<FontConfig> source, const winrt::weak_ref<Profile> sourceProfile);
Json::Value ToJson() const;
void LayerJson(const Json::Value& json);
bool HasAnyOptionSet() const;

Model::Profile SourceProfile();

INHERITABLE_SETTING(Model::FontConfig, hstring, FontFace, DEFAULT_FONT_FACE);
INHERITABLE_SETTING(Model::FontConfig, int32_t, FontSize, DEFAULT_FONT_SIZE);
INHERITABLE_SETTING(Model::FontConfig, Windows::UI::Text::FontWeight, FontWeight, DEFAULT_FONT_WEIGHT);

private:
winrt::weak_ref<Profile> _sourceProfile;
};
}
20 changes: 20 additions & 0 deletions src/cascadia/TerminalSettingsModel/FontConfig.idl
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import "Profile.idl";
#include "IInheritable.idl.h"

#define INHERITABLE_FONT_SETTING(Type, Name) \
_BASE_INHERITABLE_SETTING(Type, Name); \
Microsoft.Terminal.Settings.Model.FontConfig Name##OverrideSource { get; }

namespace Microsoft.Terminal.Settings.Model
{
[default_interface] runtimeclass FontConfig {
Microsoft.Terminal.Settings.Model.Profile SourceProfile { get; };

INHERITABLE_FONT_SETTING(String, FontFace);
INHERITABLE_FONT_SETTING(Int32, FontSize);
INHERITABLE_FONT_SETTING(Windows.UI.Text.FontWeight, FontWeight);
}
}
Loading