Repository: microsoft/terminal
File: src/cascadia/TerminalSettingsEditor/ProfileViewModel.cpp (C++)

Code before:
                                                                         DWRITE_FONT_STRETCH::DWRITE_FONT_STRETCH_NORMAL,
                                                                         DWRITE_FONT_STYLE::DWRITE_FONT_STYLE_NORMAL,
                                                                         font.put()));

                        // add the font name to our list of monospace fonts
                        const auto castedFont{ font.try_as<IDWriteFont1>() };
                        if (castedFont && castedFont->IsMonospacedFont())
                        {
                            monospaceFontList.emplace_back(fontEntry);
                        }
                    }
                    CATCH_LOG();

                    // add the font name to our list of all fonts
                    fontList.emplace_back(std::move(fontEntry));
                }
            }
            CATCH_LOG();
        }

        // sort and save the lists
        std::sort(begin(fontList), end(fontList), FontComparator());
        _FontList = single_threaded_observable_vector<Editor::Font>(std::move(fontList));

        std::sort(begin(monospaceFontList), end(monospaceFontList), FontComparator());
        _MonospaceFontList = single_threaded_observable_vector<Editor::Font>(std::move(monospaceFontList));
    }
    CATCH_LOG();

    Editor::Font ProfileViewModel::FindFontWithLocalizedName(const winrt::hstring& name) noexcept
    {
        // look for the current font in our shown list of fonts
        Editor::Font fallbackFont{ nullptr };
        try
        {
            const auto& currentFontList{ CompleteFontList() };
            for (const auto& font : currentFontList)
            {
                if (font.LocalizedName() == name)
                {
                    return font;
                }
                else if (font.LocalizedName() == L"Cascadia Mono")
                {
                    fallbackFont = font;
                }
            }
        }
        CATCH_LOG();

        // we couldn't find the desired font, set to "Cascadia Mono" if we found that since it ships by default

Review comment (bug):
Oh, I forgot to mention that this also fixes a minor bug. The `<` operator on strings is not safe for proper Unicode comparisons. It's based on `wmemcmp` which tests for binary equivalence, so it neither works for case-sensitive nor case-insensitive comparisons in the context of Unicode. For instance, because a composed and decomposed grapheme doesn't compare equal.

Code after:
                        THROW_IF_FAILED(fontFamily->GetFirstMatchingFont(DWRITE_FONT_WEIGHT::DWRITE_FONT_WEIGHT_NORMAL,
                                                                         DWRITE_FONT_STRETCH::DWRITE_FONT_STRETCH_NORMAL,
                                                                         DWRITE_FONT_STYLE::DWRITE_FONT_STYLE_NORMAL,
                                                                         font.put()));

                        // add the font name to our list of monospace fonts
                        const auto castedFont{ font.try_as<IDWriteFont1>() };
                        if (castedFont && castedFont->IsMonospacedFont())
                        {
                            monospaceFontList.emplace_back(fontEntry);
                        }
                    }
                    CATCH_LOG();

                    // add the font name to our list of all fonts
                    fontList.emplace_back(std::move(fontEntry));
                }
            }
            CATCH_LOG();
        }

        const auto comparator = [&](const Editor::Font& lhs, const Editor::Font& rhs) {
            const auto a = lhs.LocalizedName();
            const auto b = rhs.LocalizedName();
            return til::compare_linguistic_insensitive(a, b) < 0;
        };

        // sort and save the lists
        std::sort(begin(fontList), end(fontList), comparator);
        _FontList = single_threaded_observable_vector<Editor::Font>(std::move(fontList));

        std::sort(begin(monospaceFontList), end(monospaceFontList), comparator);
        _MonospaceFontList = single_threaded_observable_vector<Editor::Font>(std::move(monospaceFontList));
    }
    CATCH_LOG();

    Editor::Font ProfileViewModel::FindFontWithLocalizedName(const winrt::hstring& name) noexcept
    {
        // look for the current font in our shown list of fonts
        Editor::Font fallbackFont{ nullptr };
        try
        {
            const auto& currentFontList{ CompleteFontList() };
            for (const auto& font : currentFontList)
            {
                if (font.LocalizedName() == name)
                {
                    return font;
                }
                else if (font.LocalizedName() == L"Cascadia Mono")
                {