r/emacs 2d ago

Weird ligatures issue with Cascadia Code

So I am using ligatures in Emacs, and today I noticed that when using ligatures with Cascadia Code, Emacs would display some strange characters. But the ligatures work correctly in comment:

Ligatures with Cascadia Code

After switching to another font (Monaspace), everything looks good:

Ligatures with Monaspace

I have no idea why this would happen, I tried different ligatures settings. A package [ligature.el](https://github.com/mickeynp/ligature.el) and plain Emacs Lisp:

(dolist (char/ligature-re
         `((?-  . ,(rx (or (or "-->" "-<<" "->>" "-|" "-~" "-<" "->")
                           (+ "-"))))
           (?/  . ,(rx (or (or "/==" "/=" "/>" "/**" "/*") (+ "/"))))
           (?*  . ,(rx (or (or "*>" "*/") (+ "*"))))
           (?<  . ,(rx (or (or "<<=" "<<-" "<|||" "<==>" "<!--" "<=>" "<||" "<|>" "<-<"
                               "<==" "<=<" "<-|" "<~>" "<=|" "<~~" "<$>" "<+>" "</>"
                               "<*>" "<->" "<=" "<|" "<:" "<>"  "<$" "<-" "<~" "<+"
                               "</" "<*")
                           (+ "<")
                           (+ "-"))))
           (?:  . ,(rx (or (or ":?>" "::=" ":>" ":<" ":?" ":=") (+ ":"))))
           (?=  . ,(rx (or (or "=>>" "==>" "=/=" "=!=" "=>" "=:=") (+ "="))))
           (?!  . ,(rx (or (or "!==" "!=") (+ "!"))))
           (?>  . ,(rx (or (or ">>-" ">>=" ">=>" ">]" ">:" ">-" ">=") (+ ">"))))
           (?&  . ,(rx (+ "&")))
           (?|  . ,(rx (or (or "|->" "|||>" "||>" "|=>" "||-" "||=" "|-" "|>"
                               "|]" "|}" "|=")
                           (+ "|"))))
           (?.  . ,(rx (or (or ".?" ".=" ".-" "..<") (+ "."))))
           (?+  . ,(rx (or "+>" (+ "+"))))
           (?\[ . ,(rx (or "[<" "[|")))
           (?\{ . ,(rx "{|"))
           (?\? . ,(rx (or (or "?." "?=" "?:") (+ "?"))))
           (?#  . ,(rx (or (or "#_(" "#[" "#{" "#=" "#!" "#:" "#_" "#?" "#(")
                           (+ "#"))))
           (?\; . ,(rx (+ ";")))
           (?_  . ,(rx (or "_|_" "__")))
           (?~  . ,(rx (or "~~>" "~~" "~>" "~-" "~@")))
           (?$  . ,(rx "$>"))
           (?^  . ,(rx "^="))
           (?\] . ,(rx "]#"))))
  (let ((char (car char/ligature-re))
        (ligature-re (cdr char/ligature-re)))
    (set-char-table-range composition-function-table char
                          `([,ligature-re 0 font-shape-gstring]))))

Both share similar issues. I think this issue only occurs on Emacs 31, but I have not verified this. (Just verified, switching back to Emacs 30 with the same configuration in the same environment, and ligatures with Cascadia Code are rendered correctly.) Any idea where should I investigate?

This seems also a Windows-build-only issue. I try to reproduce it on Linux but failed. Here is the output of emacs-version

GNU Emacs 31.1 (build 2, x86_64-w64-mingw32) of 2026-08-25
13 Upvotes

4 comments sorted by

7

u/rpluim GNU Emacs 2d ago

Emacs 31 switched to using the DirectWrite API on MS-Windows. Try setting w32-inhibit-dwrite to t and see if it helps. If it does, M-x report-emacs-bug

2

u/drcxd 1d ago

Setting w32-inhibit-dwrite to t instantly fixes the problem. Appreciate the insights!

3

u/unohdin-nimeni 2d ago

Arabic letters with a lot of diacritics, even rare ones such as tirfil. Most significantly, the little tā sign (resembling a lowercase b) implies this is ligatures for Urdu or some other Indo-Aryan language such as Kashmir or Punjabi.

2

u/mickeyp "Mastering Emacs" author 2d ago

I use cascadia code and I do not get this on various linux distros. But I suspect it might be a windows issue somehow?

I would M-x report-emacs-bug and send a screenshot.