mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-06 06:09:50 +00:00
Allow editing font features in the Settings UI (#16678)
## Summary of the Pull Request **Targets #16104** Same as #16104, but for font features ## References and Relevant Issues #10000 ## Validation Steps Performed Font features are detected correctly and can be set in the settings UI   ## PR Checklist - [ ] Closes #xxx - [ ] Tests added/passed - [ ] Documentation updated - If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx - [ ] Schema updated (if necessary)
This commit is contained in:
8
.github/actions/spelling/allow/apis.txt
vendored
8
.github/actions/spelling/allow/apis.txt
vendored
@@ -1,3 +1,5 @@
|
||||
aalt
|
||||
abvm
|
||||
ACCEPTFILES
|
||||
ACCESSDENIED
|
||||
acl
|
||||
@@ -36,6 +38,7 @@ delayimp
|
||||
DERR
|
||||
dlldata
|
||||
DNE
|
||||
dnom
|
||||
DONTADDTORECENT
|
||||
DWMSBT
|
||||
DWMWA
|
||||
@@ -49,6 +52,7 @@ EXPCMDFLAGS
|
||||
EXPCMDSTATE
|
||||
filetime
|
||||
FILTERSPEC
|
||||
fina
|
||||
FORCEFILESYSTEM
|
||||
FORCEMINIMIZE
|
||||
frac
|
||||
@@ -120,6 +124,7 @@ LSHIFT
|
||||
LTGRAY
|
||||
MAINWINDOW
|
||||
MAXIMIZEBOX
|
||||
medi
|
||||
memchr
|
||||
memicmp
|
||||
MENUCOMMAND
|
||||
@@ -150,6 +155,7 @@ NOTIFYBYPOS
|
||||
NOTIFYICON
|
||||
NOTIFYICONDATA
|
||||
ntprivapi
|
||||
numr
|
||||
oaidl
|
||||
ocidl
|
||||
ODR
|
||||
@@ -175,9 +181,11 @@ REGCLS
|
||||
RETURNCMD
|
||||
rfind
|
||||
RLO
|
||||
rnrn
|
||||
ROOTOWNER
|
||||
roundf
|
||||
RSHIFT
|
||||
rvrn
|
||||
SACL
|
||||
schandle
|
||||
SEH
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "Appearances.h"
|
||||
#include "Appearances.g.cpp"
|
||||
#include "AxisKeyValuePair.g.cpp"
|
||||
#include "FeatureKeyValuePair.g.cpp"
|
||||
#include "EnumEntry.h"
|
||||
|
||||
#include <LibraryResources.h>
|
||||
@@ -19,6 +20,20 @@ using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
|
||||
static constexpr std::array<std::wstring_view, 11> DefaultFeatures{
|
||||
L"rlig",
|
||||
L"locl",
|
||||
L"ccmp",
|
||||
L"calt",
|
||||
L"liga",
|
||||
L"clig",
|
||||
L"rnrn",
|
||||
L"kern",
|
||||
L"mark",
|
||||
L"mkmk",
|
||||
L"dist"
|
||||
};
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
bool Font::HasPowerlineCharacters()
|
||||
@@ -86,7 +101,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
winrt::impl::hstring_builder builder{ length };
|
||||
if (SUCCEEDED(names->GetString(localeIndex, builder.data(), length + 1)))
|
||||
{
|
||||
fontAxesTagsAndNames.insert(std::pair<winrt::hstring, winrt::hstring>(_axisTagToString(axesVector[i].axisTag), builder.to_hstring()));
|
||||
fontAxesTagsAndNames.insert(std::pair<winrt::hstring, winrt::hstring>(_tagToString(axesVector[i].axisTag), builder.to_hstring()));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -100,7 +115,47 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return _fontAxesTagsAndNames;
|
||||
}
|
||||
|
||||
winrt::hstring Font::_axisTagToString(DWRITE_FONT_AXIS_TAG tag)
|
||||
IMap<hstring, hstring> Font::FontFeaturesTagsAndNames()
|
||||
{
|
||||
if (!_fontFeaturesTagsAndNames)
|
||||
{
|
||||
wil::com_ptr<IDWriteFont> font;
|
||||
THROW_IF_FAILED(_family->GetFont(0, font.put()));
|
||||
wil::com_ptr<IDWriteFontFace> fontFace;
|
||||
THROW_IF_FAILED(font->CreateFontFace(fontFace.put()));
|
||||
|
||||
wil::com_ptr<IDWriteFactory2> factory;
|
||||
THROW_IF_FAILED(DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(factory), reinterpret_cast<::IUnknown**>(factory.addressof())));
|
||||
wil::com_ptr<IDWriteTextAnalyzer> textAnalyzer;
|
||||
factory->CreateTextAnalyzer(textAnalyzer.addressof());
|
||||
wil::com_ptr<IDWriteTextAnalyzer2> textAnalyzer2 = textAnalyzer.query<IDWriteTextAnalyzer2>();
|
||||
|
||||
DWRITE_SCRIPT_ANALYSIS scriptAnalysis{};
|
||||
UINT32 tagCount;
|
||||
// we have to call GetTypographicFeatures twice, first to get the actual count then to get the features
|
||||
std::ignore = textAnalyzer2->GetTypographicFeatures(fontFace.get(), scriptAnalysis, L"en-us", 0, &tagCount, nullptr);
|
||||
std::vector<DWRITE_FONT_FEATURE_TAG> tags{ tagCount };
|
||||
textAnalyzer2->GetTypographicFeatures(fontFace.get(), scriptAnalysis, L"en-us", tagCount, &tagCount, tags.data());
|
||||
|
||||
std::unordered_map<winrt::hstring, winrt::hstring> fontFeaturesTagsAndNames;
|
||||
for (auto tag : tags)
|
||||
{
|
||||
const auto tagString = _tagToString(tag);
|
||||
hstring formattedResourceString{ fmt::format(L"Profile_FontFeature_{}", tagString) };
|
||||
hstring localizedName{ tagString };
|
||||
// we have resource strings for common font features, see if one for this feature exists
|
||||
if (HasLibraryResourceWithName(formattedResourceString))
|
||||
{
|
||||
localizedName = GetLibraryResourceString(formattedResourceString);
|
||||
}
|
||||
fontFeaturesTagsAndNames.insert(std::pair<winrt::hstring, winrt::hstring>(tagString, localizedName));
|
||||
}
|
||||
_fontFeaturesTagsAndNames = winrt::single_threaded_map<winrt::hstring, winrt::hstring>(std::move(fontFeaturesTagsAndNames));
|
||||
}
|
||||
return _fontFeaturesTagsAndNames;
|
||||
}
|
||||
|
||||
winrt::hstring Font::_tagToString(DWRITE_FONT_AXIS_TAG tag)
|
||||
{
|
||||
std::wstring result;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
@@ -110,6 +165,16 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return winrt::hstring{ result };
|
||||
}
|
||||
|
||||
hstring Font::_tagToString(DWRITE_FONT_FEATURE_TAG tag)
|
||||
{
|
||||
std::wstring result;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
result.push_back((tag >> (i * 8)) & 0xFF);
|
||||
}
|
||||
return hstring{ result };
|
||||
}
|
||||
|
||||
AxisKeyValuePair::AxisKeyValuePair(winrt::hstring axisKey, float axisValue, const Windows::Foundation::Collections::IMap<winrt::hstring, float>& baseMap, const Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring>& tagToNameMap) :
|
||||
_AxisKey{ axisKey },
|
||||
_AxisValue{ axisValue },
|
||||
@@ -191,6 +256,87 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
}
|
||||
}
|
||||
|
||||
FeatureKeyValuePair::FeatureKeyValuePair(hstring featureKey, uint32_t featureValue, const IMap<hstring, uint32_t>& baseMap, const IMap<hstring, hstring>& tagToNameMap) :
|
||||
_FeatureKey{ featureKey },
|
||||
_FeatureValue{ featureValue },
|
||||
_baseMap{ baseMap },
|
||||
_tagToNameMap{ tagToNameMap }
|
||||
{
|
||||
if (_tagToNameMap.HasKey(_FeatureKey))
|
||||
{
|
||||
int32_t i{ 0 };
|
||||
// this loop assumes that every time we iterate through the map
|
||||
// we get the same ordering
|
||||
for (const auto tagAndName : _tagToNameMap)
|
||||
{
|
||||
if (tagAndName.Key() == _FeatureKey)
|
||||
{
|
||||
_FeatureIndex = i;
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hstring FeatureKeyValuePair::FeatureKey()
|
||||
{
|
||||
return _FeatureKey;
|
||||
}
|
||||
|
||||
uint32_t FeatureKeyValuePair::FeatureValue()
|
||||
{
|
||||
return _FeatureValue;
|
||||
}
|
||||
|
||||
int32_t FeatureKeyValuePair::FeatureIndex()
|
||||
{
|
||||
return _FeatureIndex;
|
||||
}
|
||||
|
||||
void FeatureKeyValuePair::FeatureValue(uint32_t featureValue)
|
||||
{
|
||||
if (featureValue != _FeatureValue)
|
||||
{
|
||||
_baseMap.Remove(_FeatureKey);
|
||||
_FeatureValue = featureValue;
|
||||
_baseMap.Insert(_FeatureKey, _FeatureValue);
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"FeatureValue" });
|
||||
}
|
||||
}
|
||||
|
||||
void FeatureKeyValuePair::FeatureKey(hstring featureKey)
|
||||
{
|
||||
if (featureKey != _FeatureKey)
|
||||
{
|
||||
_baseMap.Remove(_FeatureKey);
|
||||
_FeatureKey = featureKey;
|
||||
_baseMap.Insert(_FeatureKey, _FeatureValue);
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"FeatureKey" });
|
||||
}
|
||||
}
|
||||
|
||||
void FeatureKeyValuePair::FeatureIndex(int32_t featureIndex)
|
||||
{
|
||||
if (featureIndex != _FeatureIndex)
|
||||
{
|
||||
_FeatureIndex = featureIndex;
|
||||
|
||||
int32_t i{ 0 };
|
||||
// same as in the constructor, this assumes that iterating through the map
|
||||
// gives us the same order every time
|
||||
for (const auto tagAndName : _tagToNameMap)
|
||||
{
|
||||
if (i == _FeatureIndex)
|
||||
{
|
||||
FeatureKey(tagAndName.Key());
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AppearanceViewModel::AppearanceViewModel(const Model::AppearanceConfig& appearance) :
|
||||
_appearance{ appearance }
|
||||
{
|
||||
@@ -217,9 +363,15 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
// so when the FontAxes change (say from the reset button), reinitialize the observable vector
|
||||
InitializeFontAxesVector();
|
||||
}
|
||||
else if (viewModelProperty == L"FontFeatures")
|
||||
{
|
||||
// same as the FontAxes one
|
||||
InitializeFontFeaturesVector();
|
||||
}
|
||||
});
|
||||
|
||||
InitializeFontAxesVector();
|
||||
InitializeFontFeaturesVector();
|
||||
|
||||
// Cache the original BG image path. If the user clicks "Use desktop
|
||||
// wallpaper", then un-checks it, this is the string we'll restore to
|
||||
@@ -477,6 +629,150 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return axisKeyValuePair;
|
||||
}
|
||||
|
||||
void AppearanceViewModel::AddNewFeatureKeyValuePair()
|
||||
{
|
||||
const auto fontInfo = _appearance.SourceProfile().FontInfo();
|
||||
auto fontFeaturesMap = fontInfo.FontFeatures();
|
||||
if (!fontFeaturesMap)
|
||||
{
|
||||
fontFeaturesMap = winrt::single_threaded_map<hstring, uint32_t>();
|
||||
fontInfo.FontFeatures(fontFeaturesMap);
|
||||
}
|
||||
|
||||
// find one feature that does not already exist, and add that
|
||||
// if there are no more possible features to add, the button is disabled so there shouldn't be a way to get here
|
||||
const auto possibleFeaturesTagsAndNames = ProfileViewModel::FindFontWithLocalizedName(FontFace()).FontFeaturesTagsAndNames();
|
||||
for (const auto tagAndName : possibleFeaturesTagsAndNames)
|
||||
{
|
||||
const auto featureKey = tagAndName.Key();
|
||||
if (!fontFeaturesMap.HasKey(featureKey))
|
||||
{
|
||||
const auto featureDefaultValue = _IsDefaultFeature(featureKey) ? 1 : 0;
|
||||
fontFeaturesMap.Insert(featureKey, featureDefaultValue);
|
||||
FontFeaturesVector().Append(_CreateFeatureKeyValuePairHelper(featureKey, featureDefaultValue, fontFeaturesMap, possibleFeaturesTagsAndNames));
|
||||
break;
|
||||
}
|
||||
}
|
||||
_NotifyChanges(L"CanFontFeaturesBeAdded");
|
||||
}
|
||||
|
||||
void AppearanceViewModel::DeleteFeatureKeyValuePair(hstring key)
|
||||
{
|
||||
for (uint32_t i = 0; i < _FontFeaturesVector.Size(); i++)
|
||||
{
|
||||
if (_FontFeaturesVector.GetAt(i).FeatureKey() == key)
|
||||
{
|
||||
FontFeaturesVector().RemoveAt(i);
|
||||
_appearance.SourceProfile().FontInfo().FontFeatures().Remove(key);
|
||||
if (_FontFeaturesVector.Size() == 0)
|
||||
{
|
||||
_appearance.SourceProfile().FontInfo().ClearFontFeatures();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
_NotifyChanges(L"CanFontAxesBeAdded");
|
||||
}
|
||||
|
||||
void AppearanceViewModel::InitializeFontFeaturesVector()
|
||||
{
|
||||
if (!_FontFeaturesVector)
|
||||
{
|
||||
_FontFeaturesVector = single_threaded_observable_vector<Editor::FeatureKeyValuePair>();
|
||||
}
|
||||
|
||||
_FontFeaturesVector.Clear();
|
||||
if (const auto fontFeaturesMap = _appearance.SourceProfile().FontInfo().FontFeatures())
|
||||
{
|
||||
const auto fontFeaturesTagToNameMap = ProfileViewModel::FindFontWithLocalizedName(FontFace()).FontFeaturesTagsAndNames();
|
||||
for (const auto feature : fontFeaturesMap)
|
||||
{
|
||||
const auto featureKey = feature.Key();
|
||||
// only show the features that the font supports
|
||||
// any features that the font doesn't support continue to be stored in the json, we just don't show them in the UI
|
||||
if (fontFeaturesTagToNameMap.HasKey(featureKey))
|
||||
{
|
||||
_FontFeaturesVector.Append(_CreateFeatureKeyValuePairHelper(featureKey, feature.Value(), fontFeaturesMap, fontFeaturesTagToNameMap));
|
||||
}
|
||||
}
|
||||
}
|
||||
_NotifyChanges(L"AreFontFeaturesAvailable", L"CanFontFeaturesBeAdded");
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Determines whether the currently selected font has any font features
|
||||
bool AppearanceViewModel::AreFontFeaturesAvailable()
|
||||
{
|
||||
return ProfileViewModel::FindFontWithLocalizedName(FontFace()).FontFeaturesTagsAndNames().Size() > 0;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Determines whether the currently selected font has any font features that have not already been set
|
||||
bool AppearanceViewModel::CanFontFeaturesBeAdded()
|
||||
{
|
||||
if (const auto fontFeaturesTagToNameMap = ProfileViewModel::FindFontWithLocalizedName(FontFace()).FontFeaturesTagsAndNames(); fontFeaturesTagToNameMap.Size() > 0)
|
||||
{
|
||||
if (const auto fontFeaturesMap = _appearance.SourceProfile().FontInfo().FontFeatures())
|
||||
{
|
||||
for (const auto tagAndName : fontFeaturesTagToNameMap)
|
||||
{
|
||||
if (!fontFeaturesMap.HasKey(tagAndName.Key()))
|
||||
{
|
||||
// we found a feature that has not been set
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// all possible features have been set already
|
||||
return false;
|
||||
}
|
||||
// the font supports font features but the profile has none set
|
||||
return true;
|
||||
}
|
||||
// the font does not support any font features
|
||||
return false;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Creates a FeatureKeyValuePair and sets up an event handler for it
|
||||
Editor::FeatureKeyValuePair AppearanceViewModel::_CreateFeatureKeyValuePairHelper(hstring featureKey, uint32_t featureValue, const IMap<hstring, uint32_t>& baseMap, const IMap<hstring, hstring>& tagToNameMap)
|
||||
{
|
||||
const auto featureKeyValuePair = winrt::make<winrt::Microsoft::Terminal::Settings::Editor::implementation::FeatureKeyValuePair>(featureKey, featureValue, baseMap, tagToNameMap);
|
||||
// when either the key or the value changes, send an event for the preview control to catch
|
||||
featureKeyValuePair.PropertyChanged([weakThis = get_weak()](auto& sender, const PropertyChangedEventArgs& args) {
|
||||
if (auto appVM{ weakThis.get() })
|
||||
{
|
||||
appVM->_NotifyChanges(L"FeatureKeyValuePair");
|
||||
const auto settingName{ args.PropertyName() };
|
||||
if (settingName == L"FeatureKey")
|
||||
{
|
||||
const auto senderPair = sender.as<FeatureKeyValuePair>();
|
||||
const auto senderKey = senderPair->FeatureKey();
|
||||
if (appVM->_IsDefaultFeature(senderKey))
|
||||
{
|
||||
senderPair->FeatureValue(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
senderPair->FeatureValue(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return featureKeyValuePair;
|
||||
}
|
||||
|
||||
bool AppearanceViewModel::_IsDefaultFeature(winrt::hstring featureKey)
|
||||
{
|
||||
for (const auto defaultFeature : DefaultFeatures)
|
||||
{
|
||||
if (defaultFeature == featureKey)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DependencyProperty Appearances::_AppearanceProperty{ nullptr };
|
||||
|
||||
Appearances::Appearances() :
|
||||
@@ -546,6 +842,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
_FontAxesNames = winrt::single_threaded_observable_vector<winrt::hstring>();
|
||||
FontAxesNamesCVS().Source(_FontAxesNames);
|
||||
|
||||
_FontFeaturesNames = winrt::single_threaded_observable_vector<hstring>();
|
||||
FontFeaturesNamesCVS().Source(_FontFeaturesNames);
|
||||
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(IntenseTextStyle, IntenseTextStyle, winrt::Microsoft::Terminal::Settings::Model::IntenseStyle, L"Appearance_IntenseTextStyle", L"Content");
|
||||
}
|
||||
|
||||
@@ -613,7 +912,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
_FontAxesNames.Append(tagAndName.Value());
|
||||
}
|
||||
|
||||
// when the font face changes, we have to tell the view model to update the font axes vector
|
||||
_FontFeaturesNames.Clear();
|
||||
const auto featuresTagsAndNames = newFontFace.FontFeaturesTagsAndNames();
|
||||
for (const auto tagAndName : featuresTagsAndNames)
|
||||
{
|
||||
_FontFeaturesNames.Append(tagAndName.Value());
|
||||
}
|
||||
|
||||
// when the font face changes, we have to tell the view model to update the font axes/features vectors
|
||||
// since the new font may not have the same possible axes as the previous one
|
||||
Appearance().InitializeFontAxesVector();
|
||||
if (!Appearance().AreFontAxesAvailable())
|
||||
@@ -627,6 +933,19 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
FontAxesContainer().HelpText(RS_(L"Profile_FontAxesAvailable/Text"));
|
||||
}
|
||||
|
||||
Appearance().InitializeFontFeaturesVector();
|
||||
if (!Appearance().AreFontFeaturesAvailable())
|
||||
{
|
||||
// if the previous font had available font features and the expander was expanded,
|
||||
// at this point the expander would be set to disabled so manually collapse it
|
||||
FontFeaturesContainer().SetExpanded(false);
|
||||
FontFeaturesContainer().HelpText(RS_(L"Profile_FontFeaturesUnavailable/Text"));
|
||||
}
|
||||
else
|
||||
{
|
||||
FontFeaturesContainer().HelpText(RS_(L"Profile_FontFeaturesAvailable/Text"));
|
||||
}
|
||||
}
|
||||
|
||||
void Appearances::_ViewModelChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*args*/)
|
||||
@@ -648,6 +967,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
FontAxesCVS().Source(Appearance().FontAxesVector());
|
||||
Appearance().AreFontAxesAvailable() ? FontAxesContainer().HelpText(RS_(L"Profile_FontAxesAvailable/Text")) : FontAxesContainer().HelpText(RS_(L"Profile_FontAxesUnavailable/Text"));
|
||||
|
||||
FontFeaturesCVS().Source(Appearance().FontFeaturesVector());
|
||||
Appearance().AreFontFeaturesAvailable() ? FontFeaturesContainer().HelpText(RS_(L"Profile_FontFeaturesAvailable/Text")) : FontFeaturesContainer().HelpText(RS_(L"Profile_FontFeaturesUnavailable/Text"));
|
||||
|
||||
_ViewModelChangedRevoker = Appearance().PropertyChanged(winrt::auto_revoke, [=](auto&&, const PropertyChangedEventArgs& args) {
|
||||
const auto settingName{ args.PropertyName() };
|
||||
if (settingName == L"CursorShape")
|
||||
@@ -786,6 +1108,22 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
Appearance().AddNewAxisKeyValuePair();
|
||||
}
|
||||
|
||||
void Appearances::DeleteFeatureKeyValuePair_Click(const IInspectable& sender, const RoutedEventArgs& /*e*/)
|
||||
{
|
||||
if (const auto& button{ sender.try_as<Controls::Button>() })
|
||||
{
|
||||
if (const auto& tag{ button.Tag().try_as<hstring>() })
|
||||
{
|
||||
Appearance().DeleteFeatureKeyValuePair(tag.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Appearances::AddNewFeatureKeyValuePair_Click(const IInspectable& /*sender*/, const RoutedEventArgs& /*e*/)
|
||||
{
|
||||
Appearance().AddNewFeatureKeyValuePair();
|
||||
}
|
||||
|
||||
bool Appearances::IsVintageCursor() const
|
||||
{
|
||||
return Appearance().CursorShape() == Core::CursorStyle::Vintage;
|
||||
|
||||
@@ -18,11 +18,13 @@ Author(s):
|
||||
|
||||
#include "Font.g.h"
|
||||
#include "AxisKeyValuePair.g.h"
|
||||
#include "FeatureKeyValuePair.g.h"
|
||||
#include "Appearances.g.h"
|
||||
#include "AppearanceViewModel.g.h"
|
||||
#include "Utils.h"
|
||||
#include "ViewModelHelpers.h"
|
||||
#include "SettingContainer.h"
|
||||
#include <LibraryResources.h>
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
@@ -39,6 +41,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
hstring ToString() { return _LocalizedName; }
|
||||
bool HasPowerlineCharacters();
|
||||
Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring> FontAxesTagsAndNames();
|
||||
Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring> FontFeaturesTagsAndNames();
|
||||
|
||||
WINRT_PROPERTY(hstring, Name);
|
||||
WINRT_PROPERTY(hstring, LocalizedName);
|
||||
@@ -46,8 +49,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
private:
|
||||
winrt::com_ptr<IDWriteFontFamily> _family;
|
||||
std::optional<bool> _hasPowerlineCharacters;
|
||||
winrt::hstring _axisTagToString(DWRITE_FONT_AXIS_TAG tag);
|
||||
|
||||
winrt::hstring _tagToString(DWRITE_FONT_AXIS_TAG tag);
|
||||
winrt::hstring _tagToString(DWRITE_FONT_FEATURE_TAG tag);
|
||||
|
||||
Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring> _fontAxesTagsAndNames;
|
||||
Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring> _fontFeaturesTagsAndNames;
|
||||
};
|
||||
|
||||
struct AxisKeyValuePair : AxisKeyValuePairT<AxisKeyValuePair>, ViewModelHelper<AxisKeyValuePair>
|
||||
@@ -73,6 +80,29 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring> _tagToNameMap{ nullptr };
|
||||
};
|
||||
|
||||
struct FeatureKeyValuePair : FeatureKeyValuePairT<FeatureKeyValuePair>, ViewModelHelper<FeatureKeyValuePair>
|
||||
{
|
||||
FeatureKeyValuePair(winrt::hstring featureKey, uint32_t featureValue, const Windows::Foundation::Collections::IMap<winrt::hstring, uint32_t>& baseMap, const Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring>& tagToNameMap);
|
||||
|
||||
winrt::hstring FeatureKey();
|
||||
void FeatureKey(winrt::hstring featureKey);
|
||||
|
||||
uint32_t FeatureValue();
|
||||
void FeatureValue(uint32_t featureValue);
|
||||
|
||||
int32_t FeatureIndex();
|
||||
void FeatureIndex(int32_t featureIndex);
|
||||
|
||||
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
|
||||
|
||||
private:
|
||||
winrt::hstring _FeatureKey;
|
||||
uint32_t _FeatureValue;
|
||||
int32_t _FeatureIndex;
|
||||
Windows::Foundation::Collections::IMap<winrt::hstring, uint32_t> _baseMap{ nullptr };
|
||||
Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring> _tagToNameMap{ nullptr };
|
||||
};
|
||||
|
||||
struct AppearanceViewModel : AppearanceViewModelT<AppearanceViewModel>, ViewModelHelper<AppearanceViewModel>
|
||||
{
|
||||
public:
|
||||
@@ -102,6 +132,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
bool AreFontAxesAvailable();
|
||||
bool CanFontAxesBeAdded();
|
||||
|
||||
void AddNewFeatureKeyValuePair();
|
||||
void DeleteFeatureKeyValuePair(winrt::hstring key);
|
||||
void InitializeFontFeaturesVector();
|
||||
bool AreFontFeaturesAvailable();
|
||||
bool CanFontFeaturesBeAdded();
|
||||
|
||||
WINRT_PROPERTY(bool, IsDefault, false);
|
||||
|
||||
// These settings are not defined in AppearanceConfig, so we grab them
|
||||
@@ -113,6 +149,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance.SourceProfile().FontInfo(), FontSize);
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance.SourceProfile().FontInfo(), FontWeight);
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance.SourceProfile().FontInfo(), FontAxes);
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance.SourceProfile().FontInfo(), FontFeatures);
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance.SourceProfile().FontInfo(), EnableBuiltinGlyphs);
|
||||
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance, RetroTerminalEffect);
|
||||
@@ -128,12 +165,16 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance, AdjustIndistinguishableColors);
|
||||
WINRT_OBSERVABLE_PROPERTY(Windows::Foundation::Collections::IObservableVector<Editor::ColorSchemeViewModel>, SchemesList, _propertyChangedHandlers, nullptr);
|
||||
WINRT_OBSERVABLE_PROPERTY(Windows::Foundation::Collections::IObservableVector<Editor::AxisKeyValuePair>, FontAxesVector, _propertyChangedHandlers, nullptr);
|
||||
WINRT_OBSERVABLE_PROPERTY(Windows::Foundation::Collections::IObservableVector<Editor::FeatureKeyValuePair>, FontFeaturesVector, _propertyChangedHandlers, nullptr);
|
||||
|
||||
private:
|
||||
Model::AppearanceConfig _appearance;
|
||||
winrt::hstring _lastBgImagePath;
|
||||
|
||||
Editor::AxisKeyValuePair _CreateAxisKeyValuePairHelper(winrt::hstring axisKey, float axisValue, const Windows::Foundation::Collections::IMap<winrt::hstring, float>& baseMap, const Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring>& tagToNameMap);
|
||||
Editor::FeatureKeyValuePair _CreateFeatureKeyValuePairHelper(winrt::hstring axisKey, uint32_t axisValue, const Windows::Foundation::Collections::IMap<winrt::hstring, uint32_t>& baseMap, const Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring>& tagToNameMap);
|
||||
|
||||
bool _IsDefaultFeature(winrt::hstring featureTag);
|
||||
};
|
||||
|
||||
struct Appearances : AppearancesT<Appearances>
|
||||
@@ -156,6 +197,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
void FontFace_SelectionChanged(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Controls::SelectionChangedEventArgs& e);
|
||||
void DeleteAxisKeyValuePair_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& e);
|
||||
void AddNewAxisKeyValuePair_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& e);
|
||||
void DeleteFeatureKeyValuePair_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& e);
|
||||
void AddNewFeatureKeyValuePair_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& e);
|
||||
|
||||
// manually bind FontWeight
|
||||
Windows::Foundation::IInspectable CurrentFontWeight() const;
|
||||
@@ -184,6 +227,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
Editor::EnumEntry _CustomFontWeight{ nullptr };
|
||||
|
||||
Windows::Foundation::Collections::IObservableVector<winrt::hstring> _FontAxesNames;
|
||||
Windows::Foundation::Collections::IObservableVector<winrt::hstring> _FontFeaturesNames;
|
||||
|
||||
Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker _ViewModelChangedRevoker;
|
||||
static void _ViewModelChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
@@ -195,4 +239,5 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(Appearances);
|
||||
BASIC_FACTORY(AxisKeyValuePair);
|
||||
BASIC_FACTORY(FeatureKeyValuePair);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
String LocalizedName { get; };
|
||||
Boolean HasPowerlineCharacters { get; };
|
||||
Windows.Foundation.Collections.IMap<String, String> FontAxesTagsAndNames { get; };
|
||||
Windows.Foundation.Collections.IMap<String, String> FontFeaturesTagsAndNames { get; };
|
||||
}
|
||||
|
||||
// We have to make this because we cannot bind an IObservableMap to a ListView in XAML (in c++)
|
||||
@@ -35,6 +36,14 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
Int32 AxisIndex;
|
||||
}
|
||||
|
||||
runtimeclass FeatureKeyValuePair : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
{
|
||||
FeatureKeyValuePair(String featureKey, UInt32 featureValue, Windows.Foundation.Collections.IMap<String, UInt32> baseMap, Windows.Foundation.Collections.IMap<String, String> tagToNameMap);
|
||||
String FeatureKey;
|
||||
UInt32 FeatureValue;
|
||||
Int32 FeatureIndex;
|
||||
}
|
||||
|
||||
runtimeclass AppearanceViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
{
|
||||
Boolean IsDefault;
|
||||
@@ -58,6 +67,14 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
Windows.Foundation.Collections.IObservableVector<AxisKeyValuePair> FontAxesVector;
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Windows.Foundation.Collections.IMap<String COMMA Single>, FontAxes);
|
||||
|
||||
void AddNewFeatureKeyValuePair();
|
||||
void DeleteFeatureKeyValuePair(String key);
|
||||
void InitializeFontFeaturesVector();
|
||||
Boolean AreFontFeaturesAvailable { get; };
|
||||
Boolean CanFontFeaturesBeAdded { get; };
|
||||
Windows.Foundation.Collections.IObservableVector<FeatureKeyValuePair> FontFeaturesVector;
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Windows.Foundation.Collections.IMap<String COMMA UInt32>, FontFeatures);
|
||||
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(String, FontFace);
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Single, FontSize);
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Double, LineHeight);
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
</DataTemplate>
|
||||
<CollectionViewSource x:Key="FontAxesCVS"
|
||||
x:Name="FontAxesCVS" />
|
||||
<CollectionViewSource x:Key="FontFeaturesCVS"
|
||||
x:Name="FontFeaturesCVS" />
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
@@ -349,6 +351,67 @@
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
<local:SettingContainer x:Name="FontFeaturesContainer"
|
||||
x:Uid="Profile_FontFeatures"
|
||||
ClearSettingValue="{x:Bind Appearance.ClearFontFeatures}"
|
||||
HasSettingValue="{x:Bind Appearance.HasFontFeatures, Mode=OneWay}"
|
||||
IsEnabled="{x:Bind Appearance.AreFontFeaturesAvailable, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.FontFeaturesOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<StackPanel Spacing="16">
|
||||
<ListView IsItemClickEnabled="False"
|
||||
ItemsSource="{Binding Source={StaticResource FontFeaturesCVS}}"
|
||||
SelectionMode="None">
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style TargetType="ListViewItem">
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="Margin" Value="0" />
|
||||
</Style>
|
||||
</ListView.ItemContainerStyle>
|
||||
<ListView.Resources>
|
||||
<CollectionViewSource x:Key="FontFeaturesNamesCVS"
|
||||
x:Name="FontFeaturesNamesCVS" />
|
||||
</ListView.Resources>
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:DataType="local:FeatureKeyValuePair">
|
||||
<Grid ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ComboBox Grid.Column="0"
|
||||
IsSynchronizedWithCurrentItem="False"
|
||||
ItemsSource="{Binding Source={StaticResource FontFeaturesNamesCVS}}"
|
||||
SelectedIndex="{x:Bind FeatureIndex, Mode=TwoWay}" />
|
||||
<muxc:NumberBox Grid.Column="1"
|
||||
Value="{x:Bind FeatureValue, Mode=TwoWay}" />
|
||||
<Button Grid.Column="2"
|
||||
HorizontalAlignment="Right"
|
||||
Click="DeleteFeatureKeyValuePair_Click"
|
||||
Style="{StaticResource DeleteButtonStyle}"
|
||||
Tag="{x:Bind FeatureKey}">
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
</Button>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
<Button Click="AddNewFeatureKeyValuePair_Click"
|
||||
IsEnabled="{x:Bind Appearance.CanFontFeaturesBeAdded, Mode=OneWay}">
|
||||
<Button.Content>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<FontIcon VerticalAlignment="Bottom"
|
||||
FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="Profile_AddNewFontFeature"
|
||||
Style="{StaticResource IconButtonTextBlockStyle}" />
|
||||
</StackPanel>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Builtin Glyphs -->
|
||||
<local:SettingContainer x:Uid="Profile_EnableBuiltinGlyphs"
|
||||
|
||||
@@ -726,6 +726,10 @@
|
||||
<value>Add new</value>
|
||||
<comment>Button label that adds a new font axis for the current font.</comment>
|
||||
</data>
|
||||
<data name="Profile_AddNewFontFeature.Text" xml:space="preserve">
|
||||
<value>Add new</value>
|
||||
<comment>Button label that adds a new font feature for the current font.</comment>
|
||||
</data>
|
||||
<data name="Profile_BackgroundImageOpacitySlider.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Background image opacity</value>
|
||||
<comment>Name for a control to choose the opacity of the image presented on the background of the app.</comment>
|
||||
@@ -938,6 +942,18 @@
|
||||
<value>The selected font has no variable font axes.</value>
|
||||
<comment>A description provided when the font axes setting is disabled. Presented near "Profile_FontAxes".</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeatures.Header" xml:space="preserve">
|
||||
<value>Font features</value>
|
||||
<comment>Header for a control to allow editing the font features.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeaturesAvailable.Text" xml:space="preserve">
|
||||
<value>Add or remove font features for the given font.</value>
|
||||
<comment>A description for what the "font features" setting does. Presented near "Profile_FontFeatures".</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeaturesUnavailable.Text" xml:space="preserve">
|
||||
<value>The selected font has no font features.</value>
|
||||
<comment>A description provided when the font features setting is disabled. Presented near "Profile_FontFeatures".</comment>
|
||||
</data>
|
||||
<data name="Profile_General.Header" xml:space="preserve">
|
||||
<value>General</value>
|
||||
<comment>Header for a sub-page of profile settings focused on more general scenarios.</comment>
|
||||
@@ -1254,6 +1270,110 @@
|
||||
<value>Thin</value>
|
||||
<comment>This is the formal name for a font weight.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_rlig" xml:space="preserve">
|
||||
<value>Required ligatures</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_locl" xml:space="preserve">
|
||||
<value>Localized forms</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_ccmp" xml:space="preserve">
|
||||
<value>Composition/decomposition</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_calt" xml:space="preserve">
|
||||
<value>Contextual alternates</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_liga" xml:space="preserve">
|
||||
<value>Standard ligatures</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_clig" xml:space="preserve">
|
||||
<value>Contextual ligatures</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_rvrn" xml:space="preserve">
|
||||
<value>Required variation alternates</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_kern" xml:space="preserve">
|
||||
<value>Kerning</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_mark" xml:space="preserve">
|
||||
<value>Mark positioning</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_mkmk" xml:space="preserve">
|
||||
<value>Mark to mark positioning</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_dist" xml:space="preserve">
|
||||
<value>Distance</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_aalt" xml:space="preserve">
|
||||
<value>Access all alternates</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_case" xml:space="preserve">
|
||||
<value>Case sensitive forms</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_dnom" xml:space="preserve">
|
||||
<value>Denominator</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_fina" xml:space="preserve">
|
||||
<value>Terminal forms</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_frac" xml:space="preserve">
|
||||
<value>Fractions</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_init" xml:space="preserve">
|
||||
<value>Initial forms</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_medi" xml:space="preserve">
|
||||
<value>Medial forms</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_numr" xml:space="preserve">
|
||||
<value>Numerator</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_ordn" xml:space="preserve">
|
||||
<value>Ordinals</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_rclt" xml:space="preserve">
|
||||
<value>Required contextual alternates</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_sinf" xml:space="preserve">
|
||||
<value>Scientific inferiors</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_subs" xml:space="preserve">
|
||||
<value>Subscript</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_sups" xml:space="preserve">
|
||||
<value>Superscript</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_zero" xml:space="preserve">
|
||||
<value>Slashed zero</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Profile_FontFeature_abvm" xml:space="preserve">
|
||||
<value>Above-base mark positioning</value>
|
||||
<comment>This is the formal name for a font feature.</comment>
|
||||
</data>
|
||||
<data name="Globals_LaunchSize.Header" xml:space="preserve">
|
||||
<value>Launch size</value>
|
||||
<comment>Header for a group of settings that control the size of the app. Presented near "Globals_InitialCols" and "Globals_InitialRows".</comment>
|
||||
|
||||
@@ -42,6 +42,16 @@ winrt::com_ptr<FontConfig> FontConfig::CopyFontInfo(const FontConfig* source, wi
|
||||
fontInfo->_FontAxes = winrt::single_threaded_map(std::move(fontAxes));
|
||||
}
|
||||
|
||||
if (source->_FontFeatures)
|
||||
{
|
||||
std::map<winrt::hstring, uint32_t> fontFeatures;
|
||||
for (const auto keyValuePair : source->_FontFeatures.value())
|
||||
{
|
||||
fontFeatures.insert(std::pair<winrt::hstring, uint32_t>(keyValuePair.Key(), keyValuePair.Value()));
|
||||
}
|
||||
fontInfo->_FontFeatures = winrt::single_threaded_map(std::move(fontFeatures));
|
||||
}
|
||||
|
||||
return fontInfo;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user