microsoft / microsoft/microsoft-ui-xaml

TextBlock does not correctly handle keypad emojis

Open
#11,079 0 comments 3 reactions 0 assignees View on GitHub
area-Icon area-TextBlocks bug
Dominant language
C++
Stars
8.4k
Forks
942
Avg merge
2d 7h
Merged PRs (30d)
105

Description

### Describe the bug

The keypad emojis are consists of 3 unicode code points, with a ASCII digit 0-9, a variation selector `U+FE0F` and a enclosing keycap `U+20E3`.

Examples:
https://emojipedia.org/keycap-digit-one
https://emojipedia.org/keycap-digit-two
1️⃣2️⃣

By manual implementation of DirectWrite to scan the code points and fallback to `Segoe UI Emoji`, I am able to render it correctly. But the winui3 `TextBlock` is not handling it correctly.

Here is the screenshot of winui3 (upper is my manual directwrite, lower is winui3 TextBlock) with `notepad` for a comparison. (And you can see the `TabView` in notepad is also rendering wrong)

Image

Append my manual directwrite implementation here
```cpp
com_ptr layout;
check_hresult(m_dwriteFactory->CreateTextLayout(
m_text.c_str(), textLen, m_textFormat.get(),
widthDip, heightDip, layout.put()));

// Keycap emoji (e.g. "9\uFE0F\u20E3") uses ASCII [0-9#*] as its base
// character, which Segoe UI already has — so font fallback never fires.
// Force the whole keycap cluster onto Segoe UI Emoji explicitly.
for (UINT32 i = 0; i + 2 < textLen; ++i)
{
wchar_t c = m_text[i];
bool isKeycapBase = (c >= L'0' && c <= L'9') || c == L'#' || c == L'*';
if (isKeycapBase &&
m_text[i + 1] == 0xFE0F &&
m_text[i + 2] == 0x20E3)
{
DWRITE_TEXT_RANGE range{ i, 3 };
winrt::check_hresult(layout->SetFontFamilyName(L"Segoe UI Emoji", range));
i += 2;
}
}

d2dContext->DrawTextLayout(
{ 0.0f, 0.0f },
layout.get(),
textBrush.get(),
D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT);
```

### Why is this important?

This affect quite a lot of system components that use winui3

### Steps to reproduce the bug

Just try to display the emojis with TextBlock

### Actual behavior

_No response_

### Expected behavior

_No response_

### Screenshots

_No response_

### NuGet package version

1.8.260415005

### Windows version

Windows 11 (24H2): Build 26100

### Additional context

_No response_

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the keypad emoji rendering issue in a WinUI 3 TextBlock on Windows 11 24H2, then compare its behavior with the provided DirectWrite implementation and Segoe UI Emoji fallback. Done means keypad sequences such as 1️⃣ and 2️⃣ render correctly in TextBlock without manual fallback handling.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.