alacritty / alacritty

A cross-platform, OpenGL terminal emulator.
https://alacritty.org
Apache License 2.0
55.29k stars 2.98k forks source link

Emoji trouble on macos #5857

Closed EdmundsEcho closed 2 years ago

EdmundsEcho commented 2 years ago

For bug reports, the following information can help speed up the process. Please describe the bug that you have found and what you would expect to happen instead.

System

OS: macOS 12.1 on M1 Alacritty Version 0.10.0 (1)

Logs

I can only report the output from infocmp alacritty:

    Reconstructed via infocmp from file: /Users/edmund/.terminfo/61/alacritty
alacritty|alacritty terminal emulator,
    am, bce, ccc, hs, km, mc5i, mir, msgr, npc, xenl,
    colors#256, cols#80, it#8, lines#24, pairs#32767,
    acsc=``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
    bel=^G, bold=\E[1m, cbt=\E[Z, civis=\E[?25l,
    clear=\E[H\E[2J, cnorm=\E[?12l\E[?25h, cr=^M,
    csr=\E[%i%p1%d;%p2%dr, cub=\E[%p1%dD, cub1=^H,
    cud=\E[%p1%dB, cud1=^J, cuf=\E[%p1%dC, cuf1=\E[C,
    cup=\E[%i%p1%d;%p2%dH, cuu=\E[%p1%dA, cuu1=\E[A,
    cvvis=\E[?12;25h, dch=\E[%p1%dP, dch1=\E[P, dim=\E[2m,
    dl=\E[%p1%dM, dl1=\E[M, dsl=\E]2;\007, ech=\E[%p1%dX,
    ed=\E[J, el=\E[K, el1=\E[1K, flash=\E[?5h$<100/>\E[?5l,
    fsl=^G, home=\E[H, hpa=\E[%i%p1%dG, ht=^I, hts=\EH,
    ich=\E[%p1%d@, il=\E[%p1%dL, il1=\E[L, ind=^J,
    indn=\E[%p1%dS,
    initc=\E]4;%p1%d;rgb\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\\,
    invis=\E[8m, is2=\E[!p\E[?3;4l\E[4l\E>, kDC=\E[3;2~,
    kEND=\E[1;2F, kHOM=\E[1;2H, kIC=\E[2;2~, kLFT=\E[1;2D,
    kNXT=\E[6;2~, kPRV=\E[5;2~, kRIT=\E[1;2C, kb2=\EOE,
    kbs=\177, kcbt=\E[Z, kcub1=\EOD, kcud1=\EOB, kcuf1=\EOC,
    kcuu1=\EOA, kdch1=\E[3~, kend=\EOF, kent=\EOM, kf1=\EOP,
    kf10=\E[21~, kf11=\E[23~, kf12=\E[24~, kf13=\E[1;2P,
    kf14=\E[1;2Q, kf15=\E[1;2R, kf16=\E[1;2S, kf17=\E[15;2~,
    kf18=\E[17;2~, kf19=\E[18;2~, kf2=\EOQ, kf20=\E[19;2~,
    kf21=\E[20;2~, kf22=\E[21;2~, kf23=\E[23;2~,
    kf24=\E[24;2~, kf25=\E[1;5P, kf26=\E[1;5Q, kf27=\E[1;5R,
    kf28=\E[1;5S, kf29=\E[15;5~, kf3=\EOR, kf30=\E[17;5~,
    kf31=\E[18;5~, kf32=\E[19;5~, kf33=\E[20;5~,
    kf34=\E[21;5~, kf35=\E[23;5~, kf36=\E[24;5~,
    kf37=\E[1;6P, kf38=\E[1;6Q, kf39=\E[1;6R, kf4=\EOS,
    kf40=\E[1;6S, kf41=\E[15;6~, kf42=\E[17;6~,
    kf43=\E[18;6~, kf44=\E[19;6~, kf45=\E[20;6~,
    kf46=\E[21;6~, kf47=\E[23;6~, kf48=\E[24;6~,
    kf49=\E[1;3P, kf5=\E[15~, kf50=\E[1;3Q, kf51=\E[1;3R,
    kf52=\E[1;3S, kf53=\E[15;3~, kf54=\E[17;3~,
    kf55=\E[18;3~, kf56=\E[19;3~, kf57=\E[20;3~,
    kf58=\E[21;3~, kf59=\E[23;3~, kf6=\E[17~, kf60=\E[24;3~,
    kf61=\E[1;4P, kf62=\E[1;4Q, kf63=\E[1;4R, kf7=\E[18~,
    kf8=\E[19~, kf9=\E[20~, khome=\EOH, kich1=\E[2~,
    kind=\E[1;2B, kmous=\E[M, knp=\E[6~, kpp=\E[5~,
    kri=\E[1;2A, mc0=\E[i, mc4=\E[4i, mc5=\E[5i, meml=\El,
    memu=\Em, oc=\E]104\007, op=\E[39;49m, rc=\E8,
    rep=%p1%c\E[%p2%{1}%-%db, rev=\E[7m, ri=\EM,
    rin=\E[%p1%dT, ritm=\E[23m, rmacs=\E(B, rmam=\E[?7l,
    rmcup=\E[?1049l\E[23;0;0t, rmir=\E[4l, rmkx=\E[?1l\E>,
    rmm=\E[?1034l, rmso=\E[27m, rmul=\E[24m,
    rs1=\Ec\E]104\007, rs2=\E[!p\E[?3;4l\E[4l\E>, sc=\E7,
    setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
    setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
    setb@, setf@,
    sgr=%?%p9%t\E(0%e\E(B%;\E[0%?%p6%t;1%;%?%p5%t;2%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m,
    sgr0=\E(B\E[m, sitm=\E[3m, smacs=\E(0, smam=\E[?7h,
    smcup=\E[?1049h\E[22;0;0t, smir=\E[4h, smkx=\E[?1h\E=,
    smm=\E[?1034h, smso=\E[7m, smul=\E[4m, tbc=\E[3g,
    tsl=\E]2;, u6=\E[%i%d;%dR, u7=\E[6n,
    u8=\E[?%[;0123456789]c, u9=\E[c, vpa=\E[%i%p1%dd,

A picture of the issue

Screen Shot 2022-02-04 at 9 33 35 AM

my alacritty font configuration

# Font configuration
font:
  normal:
    family: Hasklug Nerd Font
    style: Light

  # Bold font face
  bold:
    family: Hasklug Nerd Font
    style: Regular

  # Italic font face
  italic:
    family: Hasklug Nerd Font
    style: Light Italic

  # Point size
  size: 14.0

  # Offset is the extra space around each character. `offset.y` can be thought
  # of as modifying the line spacing, and `offset.x` as modifying the letter
  # spacing.
  offset:
   x: 0
   y: 5

  # Glyph offset determines the locations of the glyphs within their cells with
  # the default being at the bottom. Increasing `x` moves the glyph to the
  # right, increasing `y` moves the glyph upward.
  glyph_offset:
   x: -1
   y: 0

  # Thin stroke font rendering (macOS only)
  #
  # Thin strokes are suitable for retina displays, but for non-retina screens
  # it is recommended to set `use_thin_strokes` to `false`.
  use_thin_strokes: true

config font does not seem to be a solution

I have tried to set this config file in several different ways to no avail. The need for this configuration seems off though because iTerm2 displays the emoji's as expected using the same Hasklug Nerd Font.

This is a macos issue. I suspect the config font solutions are fixes for linux and other systems.

If anyone has avoided this issue on macos, please share!

Thank you!

EdmundsEcho commented 2 years ago

This is over-kill, but when the latest version of the app did not solve the problem, I thought that I would try to get a better handle of the problem. Perhaps I might succeed at articulating the issue with enough precision such that it is easier to find a solution. This may include identifying a fault in how I understand the problem.

Additional background - related issues

Terminology - ligature vs emoji

Per the following from CS department at University of Virginia, there is an important distinction between ligatures and the "emojis" that are the subject of my issue. They are each a single "glyph", they are each encoded using two UTF8 "code-points", however they are different sizes and require different capabilities to render correctly. More specifically, emojis render like any other standard "glyph" in that they consume a single "screen column". This is not the case for ligatures; they require between one and two "screen columns".

Term Definition Motivation
character Gen­eral term for letters, numbers, punctu­a­tion and other symbols. Describes the symbol e.g., "lower case a"
glyph Visual structure Visual representation of the symbol
ligature A sin­gle glyph that rep­re­sents two or more char­ac­ters Used to improve how the characters look together, side-by-side (e.g., -> )
typeface A collection of glyphs Provide a consistent visual theme for the glyphs; a means to group related collections to represent "normal", "bold", "italic" etc...
font tool for select­ing and posi­tion­ing glyphs from a par­tic­u­lar type­face E.g., ensure a mono-space distribution, select the italic typeface from a given typeface

To clarify the distinction between typeface and font, here is how one might use the terms in a sentence:

John designed a typeface that he intended to be used as a mono-spaced font. However, because the typeface is "sans-serif" (a category of typeface), it also looks good as a variable-width font.

The process UTF8 -> glyph

Given the following process described at "freecodecamp",

utf8-codepoint-to-glyph

To focus the issue: "same but different"

Alacritty displays emojis (a type of glyph) encoded with a single code-point correctly. It fails with those that are encoded using two code-points.

Alacrity does not support ligatures. Ligatures are encoded using 2 code-points to render a single glyph. However, the challenge with ligatures is how to render 2 characters in a single glyph that consumes more than one "column" on the screen. It is different because the emojis that aren't displaying correctly use glyphs that are the same size as those that display correctly.

Ligatures and problematic emojis

Iterating on the problem

Unless the lack of ligature support has to do with having to read-in 2 code-points for a single glyph, the issue here is unrelated to ligatures. When I was learning about ligatures a few years ago, it seems to me the challenge has more to do with the irregular size and thus presents a unique rendering challenge. Furthermore, unlike the ligature feature request, my issue is macOS specific.

Ligature support is a rendering issue. The emoji issue is the inability to map 2 code-points to a single glyph.

chrisduerr commented 2 years ago

Grapheme clusters are not supported, see ligature issue.

EdmundsEcho commented 2 years ago

@chrisduerr -- Thank you for the reply - clearly helpful. Just to confirm, does this mean it is not a macOS-specific issue?

chrisduerr commented 2 years ago

Grapheme clusters are not supported on any platform. The only emoji-related issue that is specific to macOS is that font fallback is less reliable and thus sometimes the incorrect fonts can be loaded.

EdmundsEcho commented 2 years ago

@chrisduerr Got it. So any glyph that is encoded with 2 code-points (a grapheme), isn't supported. Thank you.

For ligatures, if we solved the grapheme part of the problem, would we be able to render the > 1 column glyph?... or does that present another, incremental challenge?

chrisduerr commented 2 years ago

As long as it's just a single grapheme, it will work just fine. It's just grapheme clusters that do not work.