mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-04 02:06:36 +02:00
## Summary of the Pull Request - Introduces `FontIconGlyphClassifier` for classifying emojis and symbols. - Correctly recognizes multi-codepoint glyphs (e.g., 🧙🏼♀️ *woman mage with medium-light skin tone*). - Explicitly disallows multi-glyph icons (they would overflow anyway). - Distinguishes between emojis and regular text characters (letters, numbers, symbols), since emojis are slightly larger and require different padding. - Recognizes Unicode [Variation Selectors](https://en.wikipedia.org/wiki/Variation_Selectors_(Unicode_block)) to enforce specific styles: VS15 (U+FE0E) for text style (monochrome) and VS16 (U+FE0F) for emoji style (color). This lets developers choose which variant to display. By default, characters with both representations render as text/monochrome (e.g., ▶ `\u25B6`): <img width="428" height="39" alt="image" src="https://github.com/user-attachments/assets/c5e6865f-61de-4f45-9f3a-4e15e5e5ceb8" /> - Invalid icons are displayed as a dashed circle so extension developers can spot issues, without being overly distracting if they slip into production. - Updates `IconPathConverter` to use the new classifier for improved icon handling. - Adds `SampleIconPage` to demonstrate various icon usages and classifications. - Adjusts icon alignment in `IconBox` so icons are centered. - Scales negative padding for emojis in `IconBox` with control size, fixing misalignment and clipping (noticeable in tags and the details pane hero image). - Applies negative padding to all font icons. This removes the need for classification in these cases and ensures symbols rendered below the baseline remain visible. Based on [microsoft/terminal#19143](https://github.com/microsoft/terminal/pull/19143): Co-authored-by: Dustin L. Howett <duhowett@microsoft.com> Pictures? Pictures! <img width="1912" height="2394" alt="image" src="https://github.com/user-attachments/assets/05a16309-b658-4f21-8f9d-9a3f20db6ad8" /> Keyboard and flag/country emojis may look a bit off, but that’s how they’re actually rendered: <img width="482" height="95" alt="image" src="https://github.com/user-attachments/assets/dc7d4d0d-3dc8-4df5-9b9f-9e977e7e989f" /> <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] Closes: - #41489 - #41496 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed
63 lines
2.4 KiB
Plaintext
63 lines
2.4 KiB
Plaintext
// Copyright (c) Microsoft Corporation.
|
||
// Licensed under the MIT license.
|
||
|
||
namespace Microsoft.Terminal.UI
|
||
{
|
||
/// <summary>
|
||
/// Categorizes the type of a single grapheme cluster or input text.
|
||
/// Used to determine how the input should be handled or rendered (for example,
|
||
/// whether it should be treated as an emoji, an icon from a symbol font, plain text, etc.).
|
||
/// </summary>
|
||
enum FontIconGlyphKind
|
||
{
|
||
/// <summary>
|
||
/// Input is invalid or contains more than one grapheme cluster and therefore cannot be
|
||
/// treated as a single symbol. Typical for multi-character text like file paths
|
||
/// or composed strings that include separators.
|
||
/// </summary>
|
||
Invalid = -1,
|
||
|
||
/// <summary>
|
||
/// No grapheme present (empty string). Indicates absence of a symbol.
|
||
/// </summary>
|
||
None = 0,
|
||
|
||
/// <summary>
|
||
/// A single emoji grapheme cluster. This may consist of multiple Unicode code
|
||
/// points combined into one visible glyph (e.g., emoji with modifiers or ZWJ sequences).
|
||
/// </summary>
|
||
Emoji = 1,
|
||
|
||
/// <summary>
|
||
/// A single glyph from the Segoe Fluent Icons / MDL2 Assets Private Use Area (PUA),
|
||
/// typically in the Unicode range U+E700–U+F8FF. These are font-based icons (Fluent/MDL2).
|
||
/// </summary>
|
||
FluentSymbol = 2,
|
||
|
||
/// <summary>
|
||
/// A single non-emoji grapheme that is not a Fluent/MDL2 PUA symbol.
|
||
/// Covers ordinary characters, letters, numbers, or other single glyph symbols.
|
||
/// </summary>
|
||
Other = 3,
|
||
};
|
||
|
||
/// <summary>
|
||
/// Static utility class for text and icon analysis
|
||
/// </summary>
|
||
static runtimeclass FontIconGlyphClassifier
|
||
{
|
||
/// <summary>
|
||
/// Determines if text represents a single grapheme cluster (emoji/symbol icon).
|
||
/// Uses ICU for Unicode boundary detection to distinguish icons from file paths.
|
||
/// </summary>
|
||
/// <param name="text">Text to analyze</param>
|
||
/// <returns>True if single grapheme cluster, false for multi-character text or paths</returns>
|
||
static Boolean IsLikelyToBeEmojiOrSymbolIcon(String text);
|
||
|
||
/// <summary>
|
||
/// Classifies the input into a glyph kind suitable for icon or text rendering.
|
||
/// </summary>
|
||
static FontIconGlyphKind Classify(String text);
|
||
};
|
||
}
|