[Bug 59544] New: GDI text rendering broken for UTF-16 surrogate pairs (SMP characters)
http://bugs.winehq.org/show_bug.cgi?id=59544 Bug ID: 59544 Summary: GDI text rendering broken for UTF-16 surrogate pairs (SMP characters) Product: Wine Version: 11.5 Hardware: x86-64 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: win32u Assignee: wine-bugs@list.winehq.org Reporter: Robert-Gerigk@online.de Distribution: --- Created attachment 80591 --> http://bugs.winehq.org/attachment.cgi?id=80591 test program GDI text rendering fails for characters above U+FFFF. Surrogate pairs are rendered as two separate .notdef squares instead of a single glyph. BMP characters render correctly with the same font. To reproduce: display any SMP character (e.g. U+1F600) using a font with glyf outlines covering that range (e.g. Noto Emoji). Each emoji shows as two squares instead of one. The root cause is in dlls/win32u/font.c — the character-to-glyph mapping loops process each WCHAR independently without checking for UTF-16 surrogate pairs. There is currently no surrogate handling code in font.c at all. Affected functions: font_GetGlyphIndices(), get_total_extents(), nulldrv_ExtTextOut(). Real-world impact: WPF applications using emoji or other SMP characters in UI elements (e.g. toolbar labels) show broken rendering under Wine. Patch and Test are ready very soon. Attached: reproducer (smp_emoji_test.cs) + screenshots (Wine vs Windows). -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
http://bugs.winehq.org/show_bug.cgi?id=59544 --- Comment #1 from Robert-Gerigk@online.de --- Created attachment 80592 --> http://bugs.winehq.org/attachment.cgi?id=80592 Wine Test Screenshot -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
http://bugs.winehq.org/show_bug.cgi?id=59544 --- Comment #2 from Robert-Gerigk@online.de --- Created attachment 80593 --> http://bugs.winehq.org/attachment.cgi?id=80593 Windows Test Screenshot -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
http://bugs.winehq.org/show_bug.cgi?id=59544 --- Comment #3 from Nikolay Sivov <bunglehead@gmail.com> ---
Affected functions: font_GetGlyphIndices(), get_total_extents(), nulldrv_ExtTextOut().
Why do you think these are related here? -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
http://bugs.winehq.org/show_bug.cgi?id=59544 --- Comment #4 from Robert-Gerigk@online.de --- All three functions process the input WCHAR array character by character without checking for surrogate pairs: 1. font_GetGlyphIndices (line 4027): UINT glyph = str[i]; Each WCHAR is passed directly to get_glyph_index(). For a surrogate pair like U+1F600, str[i]=0xD83D and str[i+1]=0xDE00 are looked up separately. Neither is a valid codepoint, so both return .notdef (glyph index 0). 2. get_total_extents (line 5529): get_glyph_bitmap(hdc, str[i], flags, aa_flags, &metrics, NULL); Used to calculate text bounding boxes. Each surrogate half gets its own metrics (the .notdef width), so the total extent is wrong (two .notdef widths instead of one emoji width). 3. nulldrv_ExtTextOut (line 5720): get_glyph_bitmap(dev->hdc, str[i], flags, GGO_BITMAP, &metrics, &image); The actual bitmap rendering path. Each surrogate half is rendered as a separate .notdef square, producing the visible "two squares per emoji" artifact. They are related because all three need the same fix: detect high surrogates (0xD800-0xDBFF), combine with the following low surrogate to form the full codepoint, then pass that to the glyph lookup. The low surrogate position needs special handling (same glyph index / zero-width advance / skip rendering). My merge request (!10413) addresses all three in a single patch since they share the same pattern. -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
participants (1)
-
WineHQ Bugzilla