microsoft / microsoft/microsoft-ui-xaml
TextBlock does not correctly handle keypad emojis
- 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)
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
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