Subject: bug#73752: 29.4; Ligatures are randomly rendered with extra spaces

From: Eli Zaretskii <[email-masked]>
Date: Sat, 02 Nov 2024 14:07:12 +0200

> From: Visuwesh <[email-masked]>
> Cc: Tim Ruffing <[email-masked]>,  [email-masked],  [email-masked]
> Date: Sat, 02 Nov 2024 16:09:15 +0530
> 
> [சனி நவம்பர் 02, 2024] Eli Zaretskii wrote:
> 
> > In bug#50951, an alternative change in fill_gstring_body was proposed
> > (see https://debbugs.gnu.org/cgi/bugreport.cgi?bug=50951#97), which
> > was eventually installed, but I guess that might not be enough?  Can
> > you and Visuwesh please confirm that we sometimes get an lgstring
> > argument to hbfont_shape whose glyphs already have a non-nil
> > LGLYPH_ADJUSTMENT component, and we leave it unmodified because the
> > condition to use LGLYPH_SET_ADJUSTMENT isn't satisfied?  Like this:
> >
> >   (gdb) break hbfont.c:598 if xoff == 0 && yoff == 0 && wadjust == metrics.width && LGLYPH_ADJUSTMENT(lglyph) != Qnil
> >
> > In my testing, a breakpoint with this condition never breaks.  But
> > that could be because I use a different font (Cascadia Code, instead
> > of JetBrains Mono, which I don't have), or because my version of
> > HarfBuzz is much older than yours, or for some other reason.
> 
> I am not sure if you wanted me to apply the above patch or not.

no patch should be applied, not yet.

> But just loading a file that contains
> 
>     (set-face-attribute 'default nil
>                 :family "Cascadia Code"
>                 :height 110
>                 :weight 'bold)
> 
>     (load "/tmp/ligature.el")
> 
>     (ligature-set-ligatures 'prog-mode '("--" "---" "==" "===" "!=" "!==" "=!="
>                                          "=:=" "=/=" "<=" ">=" "&&" "&&&" "&=" "++" "+++" "***" ";;" "!!"
>                                          "??" "???" "?:" "?." "?=" "<:" ":<" ":>" ">:" "<:<" "<>" "<<<" ">>>"
>                                          "<<" ">>" "||" "-|" "_|_" "|-" "||-" "|=" "||=" "##" "###" "####"
>                                          "#{" "#[" "]#" "#(" "#?" "#_" "#_(" "#:" "#!" "#=" "^=" "<$>" "<$"
>                                          "$>" "<+>" "<+" "+>" "<*>" "<*" "*>" "</" "</>" "/>" "<!--" "<#--"
>                                          "-->" "->" "->>" "<<-" "<-" "<=<" "=<<" "<<=" "<==" "<=>" "<==>"
>                                          "==>" "=>" "=>>" ">=>" ">>=" ">>-" ">-" "-<" "-<<" ">->" "<-<" "<-|"
>                                          "<=|" "|=>" "|->" "<->" "<~~" "<~" "<~>" "~~" "~~>" "~>" "~-" "-~"
>                                          "~@" "[||]" "|]" "[|" "|}" "{|" "[<" ">]" "|>" "<|" "||>" "<||"
>                                          "|||>" "<|||" "<|>" "..." ".." ".=" "..<" ".?" "::" ":::" ":=" "::="
>                                          ":?" ":?>" "//" "///" "/*" "*/" "/=" "//=" "/==" "@_" "__" "???"
>                                          "<:<" ";;;"))
>     (global-ligature-mode t)
> 
> was enough to trigger the breakpoint for me.  This is, of course, before
> I got a chance to even reproduce the misalignment.
> 
> Here's what the gdb buffer looks like:
> 
>     (gdb) source .gdbinit
>     SIGINT is used by the debugger.
>     Are you sure you want to change it? (y or n) [answered Y; input not from terminal]
>     DISPLAY = :0.0
>     TERM = dumb
>     Breakpoint 1 at 0x20b4b7: file emacs.c, line 432.
>     Breakpoint 2 at 0x1cfa8a: file xterm.c, line 27102.
>     (gdb) break hbfont.c:598 if xoff == 0 && yoff == 0 && wadjust == metrics.width && LGLYPH_ADJUSTMENT(lglyph) != Qnil
>     Breakpoint 3 at 0x3c3ad7: file hbfont.c, line 598.
>     (gdb) run -Q
>     Starting program: /home/viz/lib/ports/emacs/src/emacs -Q
>     [Thread debugging using libthread_db enabled]
>     Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
>     [New Thread 0x7ffff1b8f6c0 (LWP 198125)]
>     [New Thread 0x7ffff118f6c0 (LWP 198126)]
>     [New Thread 0x7fffebf8f6c0 (LWP 198127)]
>     [New Thread 0x7fffeb58f6c0 (LWP 198128)]
>     Error in testing condition for breakpoint 3:
>     Attempt to take address of value not located in memory.
> 
>     Thread 1 "emacs" hit Breakpoint 3, hbfont_shape (lgstring=XIL(0x7ffff2a9c745), direction=XIL(0x33c0)) at hbfont.c:598
>     598	      if (xoff || yoff || wadjust != metrics.width)

Good.  Now please do this:

  (gdb) pp lgstring
  (gdb) p wadjust
  (gdb) p metrics.width
  (gdb) bt

And post the results here.