The ❤ heart emoji can overlap with other characters #22490

Closed
opened 2026-01-31 08:14:58 +00:00 by claunia · 4 comments
Owner

Originally created by @ClaireCJS on GitHub (Nov 4, 2024).

Windows Terminal version

1.21.2911.0

Windows build number

10.0.19045.5011

Other Software

I'm just echoing characters to the console from my command line (TCC)

Steps to reproduce

In TCC:

    echo %@char[10084] %@repEAT[%@CHAR[10084],4]^ECHO 1234567890

In CMD:

    echo ❤ ❤❤❤❤

(but it is possible it is not encoded correctly here in the comment, as it is not rendered red. Grab the ones from the subject line instead, those appear rendered correctly. Maybe it makes no difference.)

Expected Behavior

I was expecting
Image

Actual Behavior

What?!?!?! A ligature of hearts????

Is this intentional?

Is there a list of all the emoji ligatures? [I lost the ligature list and can't find it]

Do you accept user-contributed artwork of new emoji-combination-ligatures, if they are up to visual quality standards?

Image

Originally created by @ClaireCJS on GitHub (Nov 4, 2024). ### Windows Terminal version 1.21.2911.0 ### Windows build number 10.0.19045.5011 ### Other Software I'm just echoing characters to the console from my command line (TCC) ### Steps to reproduce In TCC: ``` echo %@char[10084] %@repEAT[%@CHAR[10084],4]^ECHO 1234567890 ``` In CMD: ``` echo ❤ ❤❤❤❤ ``` (but it is possible it is not encoded correctly here in the comment, as it is not rendered red. Grab the ones from the subject line instead, those appear rendered correctly. Maybe it makes no difference.) ### Expected Behavior I was expecting ![Image](https://github.com/user-attachments/assets/941413d5-cf69-4afb-bcf8-e95daa18b560) ### Actual Behavior What?!?!?! A ligature of hearts???? Is this intentional? Is there a list of all the emoji ligatures? [I lost the ligature list and can't find it] Do you accept user-contributed artwork of new emoji-combination-ligatures, if they are up to visual quality standards? ![Image](https://github.com/user-attachments/assets/be459cb5-4bfb-43be-8868-bffea398f364)
claunia added the Needs-TriageIssue-Bug labels 2026-01-31 08:14:58 +00:00
Author
Owner

@ClaireCJS commented on GitHub (Nov 4, 2024):

Possible duplicate of #18145 if this is the reason you can also do this:
Image

@ClaireCJS commented on GitHub (Nov 4, 2024): Possible duplicate of #18145 if this is the reason you can also do this: ![Image](https://github.com/user-attachments/assets/6d30aa82-934f-47bb-92af-5f1385874a0c)
Author
Owner

@lhecker commented on GitHub (Nov 4, 2024):

There are 2 reasons this happens

  1. The ❤ emoji is this codepoint: https://codepoints.net/U+2764
    As you can see there "It has no designated width in East Asian texts". Traditionally, this means that the terminal interprets it as a narrow character and so it only gets allocated 1 cell.
  2. There are so called "unqalified" and "fully qualified" emojis. The difference between the two is that unqualified ones can either be black & white or colored, and it's up to the text renderer to decide that. "fully qualified" emojis are those where the emoji codepoint is followed by either U+FE0E (= black & white) or U+FE0F (= colored), which tells the text renderer what to pick.

You're using U+2764 ❤ in its "unqualified" version. This means it gets 1 cell and it's up to the text renderer to decide how it should look like. Our text rasterizer (DirectWrite) uses color in that case. This way you end up with a colored emoji that gets only 1 cell and thus ends up overlapping surrounding glyphs/characters.

The solution is for you to use ❤️ (U+2764 U+FE0F) instead of ❤ (U+2764) and to use Windows Terminal 1.22 or later which has support for grapheme clusters (= can detect such pairs of U+FE0F).

Let me know if you have any other questions!

@lhecker commented on GitHub (Nov 4, 2024): There are 2 reasons this happens 1. The ❤ emoji is this codepoint: https://codepoints.net/U+2764 As you can see there "It has no designated width in East Asian texts". Traditionally, this means that the terminal interprets it as a narrow character and so it only gets allocated 1 cell. 2. There are so called "unqalified" and "fully qualified" emojis. The difference between the two is that unqualified ones can either be black & white or colored, and it's up to the text renderer to decide that. "fully qualified" emojis are those where the emoji codepoint is followed by either U+FE0E (= black & white) or U+FE0F (= colored), which tells the text renderer what to pick. You're using U+2764 ❤ in its "unqualified" version. This means it gets 1 cell and it's up to the text renderer to decide how it should look like. Our text rasterizer (DirectWrite) uses color in that case. This way you end up with a colored emoji that gets only 1 cell and thus ends up overlapping surrounding glyphs/characters. The solution is for you to use ❤️ (U+2764 U+FE0F) instead of ❤ (U+2764) and to use Windows Terminal 1.22 or later which has support for grapheme clusters (= can detect such pairs of U+FE0F). Let me know if you have any other questions!
Author
Owner

@DHowett commented on GitHub (Nov 4, 2024):

FWIW, if it seems weird that they can overlap... this is the "social standard" way that other terminal emulators have chosen to render them as well. Apple's Terminal.app does the same.

The ability to trivially overlap glyphs is a prerequisite for proper rendering of Arabic, Devanagari, Sinhala and others. :)

@DHowett commented on GitHub (Nov 4, 2024): FWIW, if it seems weird that they can overlap... this is the "social standard" way that other terminal emulators have chosen to render them as well. Apple's `Terminal.app` does the same. The ability to trivially overlap glyphs is a prerequisite for proper rendering of Arabic, Devanagari, Sinhala and others. :)
Author
Owner

@nanaya commented on GitHub (Jan 28, 2025):

hello, I'm trying to get a project with similar problem fixed but I have problem getting the "fully qualified" emoji; it just shows blank:

am I doing it wrong? I tried entering using windows emoji picker but it also returns the "unqualified" version. How can I get the fully qualified heart? (or in my specific case, checkmark)

edit: nvm, it works in 1.23.10271.0. I previously tested it on 1.23.10151.0

edit 2: looks like it sometimes still doesn't render it correctly...?

@nanaya commented on GitHub (Jan 28, 2025): hello, I'm trying to get a project with [similar problem](https://s.kohaku.love/2025/01/WindowsTerminal_2025-01-27_16-06-49.png) fixed but I have problem getting the "fully qualified" emoji; it just shows blank: ![](https://s.kohaku.love/2025/01/WindowsTerminal_2025-01-28_15-58-00.png) am I doing it wrong? I tried entering using windows emoji picker but it also returns the "unqualified" version. How can I get the fully qualified heart? (or in my specific case, [checkmark](https://github.com/nextcloud/updater/blob/e73aa39fff1d3a9ebaf40746a9de093392a5f743/lib/UpdateCommand.php#L430)) edit: nvm, it works in 1.23.10271.0. I previously tested it on 1.23.10151.0 edit 2: looks like it sometimes still doesn't render it correctly...?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#22490