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

Add experimental feature for font list command #4886

Merged
merged 19 commits into from
Oct 28, 2024

Conversation

ryfu-msft
Copy link
Contributor

@ryfu-msft ryfu-msft commented Oct 16, 2024

Related to:

Changes:

  • Adds experimental feature flag for font
  • Adds initial winget font command with list subcommand.
  • Adds functions for retrieving the installed font familes along with face names for each font.
  • Adds basic unit tests to verify that font enumeration works as expected.

winget font list --family-name "Vivaldi" will display all of the face names for the font family Vivalidi. At this point, this must be an exact match, but eventually this will allow partial search queries once the font index is created (separate PR).

This comment has been minimized.

@mdanish-kh
Copy link
Contributor

Found myself juggling more than once between winget font / winget fonts. Would it make sense to add an alias fonts for subcommand font? Though aliases are generally shorter and this one isn't so idk...

@ryfu-msft
Copy link
Contributor Author

ryfu-msft commented Oct 16, 2024

Found myself juggling more than once between winget font / winget fonts. Would it make sense to add an alias fonts for subcommand font? Though aliases are generally shorter and this one isn't so idk...

@denelon

@ryfu-msft ryfu-msft marked this pull request as ready for review October 16, 2024 21:17
@ryfu-msft ryfu-msft requested a review from a team as a code owner October 16, 2024 21:17
Copy link
Member

@JohnMcPMS JohnMcPMS left a comment

Choose a reason for hiding this comment

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

It would be helpful as a reviewer if the PR description contained some examples of usage so that I could give feedback on the visual representation.

I also want to ensure that the ISource implementation containing installed items is well thought through to avoid the need to have specialized COM interfaces. It doesn't even have to be a SQLite index, but if we can align the font data to the existing model we can save a lot of work exposing it.

The fun thing we could do with a custom ISource is to have the search results QI into these DWrite interfaces.

schemas/JSON/settings/settings.schema.0.2.json Outdated Show resolved Hide resolved
src/AppInstallerCLICore/Argument.cpp Outdated Show resolved Hide resolved
UINT32 fileCount = 0;
THROW_IF_FAILED(fontFace->GetFiles(&fileCount, nullptr));

wil::com_ptr<IDWriteFontFile> fontFiles[8];
Copy link
Member

Choose a reason for hiding this comment

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

  1. static_assert that sizeof(wil::com_ptr<IDWriteFontFile>) == sizeof(IDWriteFontFile*); means that it is a no-overhead smart pointer type and that you can use an array-like of them this way (regardless of the actual array-like type)
  2. vector of wil::com_ptr<IDWriteFontFile>
  3. resize to fileCount

src/AppInstallerCommonCore/Fonts.cpp Outdated Show resolved Hide resolved
THROW_IF_FAILED(font->GetFaceNames(faceNames.addressof()));

wchar_t localeNameBuffer[LOCALE_NAME_MAX_LENGTH];
const auto localeName = GetUserDefaultLocaleName(localeNameBuffer, LOCALE_NAME_MAX_LENGTH) ? localeNameBuffer : L"en-US";
Copy link
Member

Choose a reason for hiding this comment

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

We already have some locale functionality for choosing installers and settings around this. Prefer those methods over calling this function.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to calling AppInstaller::Locale::GetUserPreferredLanguages() for the default locale.


UINT32 faceNameIndex;
BOOL faceNameExists;
if (FAILED(faceNames->FindLocaleName(localeName, &faceNameIndex, &faceNameExists)) || !faceNameExists)
Copy link
Member

Choose a reason for hiding this comment

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

It doesn't seem like this chooses a "best" locale to use. We have the option of extracting all of the locale names and sorting them for best fit, much like installer selection. Not saying that we should, but a comment may be warranted.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a comment noting that we may need to have better locale selection

src/AppInstallerCommonCore/Fonts.cpp Outdated Show resolved Hide resolved
src/AppInstallerCommonCore/Fonts.cpp Outdated Show resolved Hide resolved
src/AppInstallerCommonCore/Fonts.cpp Outdated Show resolved Hide resolved
@microsoft-github-policy-service microsoft-github-policy-service bot added the Needs-Author-Feedback Issue needs attention from issue or PR author label Oct 16, 2024
Copy link
Contributor

@Trenly Trenly left a comment

Choose a reason for hiding this comment

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

I'm not sure the way you've implemented the font families allows for Substring matching. It seems that if --family-name is present, you're expecting an exact match, which conflicts with the --exact argument. I presume the behavior should be the same as winget list where it defaults to a Substring match unless the --exact argument is specified.

src/AppInstallerCLICore/Argument.cpp Outdated Show resolved Hide resolved
src/AppInstallerCLICore/Commands/FontCommand.cpp Outdated Show resolved Hide resolved
src/AppInstallerCLICore/Workflows/FontFlow.cpp Outdated Show resolved Hide resolved

void ReportInstalledFontsResult(Execution::Context& context)
{
if (context.Args.Contains(Args::Type::FamilyName))
Copy link
Contributor

Choose a reason for hiding this comment

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

Will there be any provision for searching by Face Name? Not sure if it provides value or not

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup, will come out in a later PR when I implement a searchable font source.

src/AppInstallerCLITests/Fonts.cpp Show resolved Hide resolved
src/AppInstallerCommonCore/Public/winget/Fonts.h Outdated Show resolved Hide resolved

This comment has been minimized.

@microsoft-github-policy-service microsoft-github-policy-service bot added Needs-Attention Issue needs attention from Microsoft and removed Needs-Author-Feedback Issue needs attention from issue or PR author labels Oct 23, 2024
@ryfu-msft
Copy link
Contributor Author

I'm not sure the way you've implemented the font families allows for Substring matching. It seems that if --family-name is present, you're expecting an exact match, which conflicts with the --exact argument. I presume the behavior should be the same as winget list where it defaults to a Substring match unless the --exact argument is specified.

Once I create a fonts source and implement search functionality, I'll make this --exact argument work as expected.

src/AppInstallerCLICore/Commands/RootCommand.cpp Outdated Show resolved Hide resolved
src/AppInstallerCLICore/Workflows/FontFlow.cpp Outdated Show resolved Hide resolved
src/AppInstallerCommonCore/Fonts.cpp Outdated Show resolved Hide resolved
src/AppInstallerCommonCore/Fonts.cpp Outdated Show resolved Hide resolved
src/AppInstallerCommonCore/Fonts.cpp Outdated Show resolved Hide resolved
src/AppInstallerCommonCore/Fonts.cpp Outdated Show resolved Hide resolved
src/AppInstallerCommonCore/Fonts.cpp Outdated Show resolved Hide resolved
src/AppInstallerCommonCore/Fonts.cpp Outdated Show resolved Hide resolved
if (FAILED(localizedStringCollection->FindLocaleName(preferredLocale.c_str(), &index, &exists)) || !exists)
for (const auto& locale : preferredLocales)
{
if (FAILED(localizedStringCollection->FindLocaleName(locale.c_str(), &index, &exists)) || exists)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if (FAILED(localizedStringCollection->FindLocaleName(locale.c_str(), &index, &exists)) || exists)
if (SUCCEEDED_LOG(localizedStringCollection->FindLocaleName(locale.c_str(), &index, &exists)) && exists)

Should we exit the search early if one of the lookups fails? I think we would better off logging and continue trying to find a different one.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to suggested.

@@ -10,6 +10,8 @@ namespace AppInstaller::Fonts
{
namespace
{
std::vector<std::wstring> preferredLocales = AppInstaller::Locale::GetUserPreferredLanguagesUTF16();
Copy link
Member

Choose a reason for hiding this comment

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

A global static is not how we should be reducing the number of calls to GetUserPreferredLanguagesUTF16. Global statics bring along several issues, made even worse when they are not statically initialized.

A better approach would be to have the font enumeration functions actually be methods of a type. The caller then controls the lifetime of anything that the font enumeration caches, like a member field of locales.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Created a struct called FontCatalog that hold all of these font enumeration methods as well as a private member field for the preferred locales.

@ryfu-msft ryfu-msft merged commit d60517e into microsoft:master Oct 28, 2024
9 checks passed
@ryfu-msft ryfu-msft deleted the experimentalFont branch October 28, 2024 21:31
@microsoft-github-policy-service microsoft-github-policy-service bot removed the Needs-Attention Issue needs attention from Microsoft label Oct 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants