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

From: Eli Zaretskii <[email-masked]>
Date: Tue, 29 Oct 2024 19:45:15 +0200

> From: Visuwesh <[email-masked]>
> Cc: [email-masked],  [email-masked],  [email-masked]
> Date: Tue, 29 Oct 2024 22:16:01 +0530
> 
> [செவ்வாய் அக்டோபர் 29, 2024] Eli Zaretskii wrote:
> 
> >> From: Visuwesh <[email-masked]>
> >> Cc: [email-masked],  [email-masked],  [email-masked]
> >> Date: Tue, 29 Oct 2024 19:24:26 +0530
> >> 
> >> I seem to have run into the issue.  The attached images
> >> "cascadia-code-bold-15-good" and "-bad.png" are the desired and
> >> misaligned composite text of "-->" rendered in Cascadia Code bold 15
> >> font.  The same text is composed fine with Cascadia Code bold 17.
> >
> > I'm not sure this is the same issue we are talking about, but here are
> > the instructions anyway:
> >
> >  . Move the cursor to where this ligature is displayed
> >  . Use "C-x =" to display the buffer position of the ligature
> >  . Attaching GDB to Emacs, then type these commands:
> >
> >     (gdb) source /path/to/emacs/src/.gdbinit
> >     (gdb) thread 1
> >     (gdb) break set_cursor_from_row
> >     (gdb) continue
> >
> > The breakpoint in set_cursor_from_row will break soon enough.  The
> > first time it breaks, just type "continue".  Second time it breaks,
> > type:
> >
> >     (gdb) pgrow
> >
> > This will show you the entire screen line (a.k.a. "glyph row") where
> > the cursor is displayed, which is also the screen line of the
> > ligature.  Here's how a similar line with ligatures looks here:
> >
> >   (gdb) pgrow
> >   TEXT: 80 glyphs
> >     0    0: CHAR[ ] pos=857 blev=0,btyp=L w=9 a+d=17+4 MB
> >     1    9: CHAR[ ] pos=858 blev=0,btyp=L w=9 a+d=17+4 MB
> >     2   18: CHAR[ ] pos=859 blev=0,btyp=L w=9 a+d=17+4 MB
> >     3   27: CHAR[ ] pos=860 blev=0,btyp=L w=9 a+d=17+4 MB
> >     4   36: CHAR[ ] pos=861 blev=0,btyp=L w=9 a+d=17+4 MB
> >     5   45: CHAR[ ] pos=862 blev=0,btyp=L w=9 a+d=17+4 MB
> >     6   54: CHAR[ ] pos=863 blev=0,btyp=L w=9 a+d=17+4 MB
> >     7   63: CHAR[ ] pos=864 blev=0,btyp=L w=9 a+d=17+4 MB
> >     8   72: CHAR[ ] pos=865 blev=0,btyp=L w=9 a+d=17+4 MB
> >     9   81: CHAR[ ] pos=866 blev=0,btyp=L w=9 a+d=17+4 MB
> >    10   90: CHAR[ ] pos=867 blev=0,btyp=L w=9 a+d=17+4 MB
> >    11   99: CHAR[ ] pos=868 blev=0,btyp=L w=9 a+d=17+4 MB
> >    12  108: CHAR[ ] pos=869 blev=0,btyp=L w=9 a+d=17+4 MB
> >    13  117: CHAR[ ] pos=870 blev=0,btyp=L w=9 a+d=17+4 MB
> >    14  126: CHAR[ ] pos=871 blev=0,btyp=L w=9 a+d=17+4 MB
> >    15  135: CHAR[ ] pos=872 blev=0,btyp=L w=9 a+d=17+4 MB
> >    16  144: CHAR[ ] pos=873 blev=0,btyp=L w=9 a+d=17+4 MB
> >    17  153: CHAR[ ] pos=874 blev=0,btyp=L w=9 a+d=17+4 MB
> >    18  162: CHAR[ ] pos=875 blev=0,btyp=L w=9 a+d=17+4 MB
> >    19  171: CHAR[ ] pos=876 blev=0,btyp=L w=9 a+d=17+4 MB
> >    20  180: CHAR[ ] pos=877 blev=0,btyp=L w=9 a+d=17+4 MB
> >    21  189: CHAR[ ] pos=878 blev=0,btyp=L w=9 a+d=17+4 MB
> >    22  198: CHAR[ ] pos=879 blev=0,btyp=L w=9 a+d=17+4 MB
> >    23  207: CHAR[ ] pos=880 blev=0,btyp=L w=9 a+d=17+4 MB
> >    24  216: CHAR[ ] pos=881 blev=0,btyp=L w=9 a+d=17+4 MB
> >    25  225: CHAR[ ] pos=882 blev=0,btyp=L w=9 a+d=17+4 MB
> >    26  234: CHAR[ ] pos=883 blev=0,btyp=L w=9 a+d=17+4 MB
> >    27  243: CHAR[ ] pos=884 blev=0,btyp=L w=9 a+d=17+4 MB
> >    28  252: CHAR[ ] pos=885 blev=0,btyp=L w=9 a+d=17+4 MB
> >    29  261: CHAR[ ] pos=886 blev=0,btyp=L w=9 a+d=17+4 MB
> >    30  270: CHAR["] pos=887 blev=0,btyp=L w=9 a+d=17+4 face=23 MB
> >    31  279: COMP[69 (0..0)] pos=888 w=9 a+d=17+4 face=24 MB
> >    32  288: COMP[69 (1..1)] pos=889 w=9 a+d=17+4 face=24 MB
> >    33  297: COMP[69 (2..2)] pos=890 w=9 a+d=17+4 face=24 MB
> >    34  306: CHAR["] pos=891 blev=0,btyp=L w=9 a+d=17+4 face=23 MB
> >    35  315: CHAR[ ] pos=892 blev=0,btyp=L w=9 a+d=17+4 MB
> >    36  324: CHAR["] pos=893 blev=0,btyp=L w=9 a+d=17+4 face=23 MB
> >    37  333: COMP[70 (0..0)] pos=894 w=9 a+d=17+4 face=24 MB
> >    38  342: COMP[70 (1..1)] pos=895 w=9 a+d=17+4 face=24 MB
> >    39  351: CHAR["] pos=896 blev=0,btyp=L w=9 a+d=17+4 face=23 MB
> >    40  360: CHAR[ ] pos=897 blev=0,btyp=L w=9 a+d=17+4 MB
> >    41  369: CHAR["] pos=898 blev=0,btyp=L w=9 a+d=17+4 face=23 MB
> >    42  378: COMP[71 (0..0)] pos=899 w=9 a+d=17+4 face=24 MB
> >    43  387: COMP[71 (1..1)] pos=900 w=9 a+d=17+4 face=24 MB
> >    44  396: COMP[71 (2..2)] pos=901 w=9 a+d=17+4 face=24 MB
> >    45  405: CHAR["] pos=902 blev=0,btyp=L w=9 a+d=17+4 face=23 MB
> >    46  414: CHAR[ ] pos=903 blev=0,btyp=L w=9 a+d=17+4 MB
> >    47  423: CHAR["] pos=904 blev=0,btyp=L w=9 a+d=17+4 face=23 MB
> >    48  432: COMP[72 (0..0)] pos=905 w=9 a+d=17+4 face=24 MB
> >    49  441: COMP[72 (1..1)] pos=906 w=9 a+d=17+4 face=24 MB
> >    50  450: COMP[72 (2..2)] pos=907 w=9 a+d=17+4 face=24 MB
> >    51  459: CHAR["] pos=908 blev=0,btyp=L w=9 a+d=17+4 face=23 MB
> >    52  468: CHAR[ ] pos=909 blev=0,btyp=L w=9 a+d=17+4 MB
> >    53  477: CHAR["] pos=910 blev=0,btyp=L w=9 a+d=17+4 face=23 MB
> >    54  486: COMP[73 (0..0)] pos=911 w=9 a+d=17+4 face=24 MB
> >    55  495: COMP[73 (1..1)] pos=912 w=9 a+d=17+4 face=24 MB
> >    56  504: CHAR["] pos=913 blev=0,btyp=L w=9 a+d=17+4 face=23 MB
> >    57  513: CHAR[ ] pos=914 blev=0,btyp=L w=9 a+d=17+4 MB
> >    58  522: CHAR["] pos=915 blev=0,btyp=L w=9 a+d=17+4 face=23 MB
> >    59  531: COMP[74 (0..0)] pos=916 w=9 a+d=17+4 face=24 MB
> >    60  540: COMP[74 (1..1)] pos=917 w=9 a+d=17+4 face=24 MB
> >    61  549: COMP[74 (2..2)] pos=918 w=9 a+d=17+4 face=24 MB
> >    62  558: CHAR["] pos=919 blev=0,btyp=L w=9 a+d=17+4 face=23 MB
> >    63  567: CHAR[ ] pos=920 blev=0,btyp=L w=9 a+d=17+4 MB
> >    64  576: CHAR["] pos=921 blev=0,btyp=L w=9 a+d=17+4 face=23 MB
> >    65  585: COMP[75 (0..0)] pos=922 w=9 a+d=17+4 face=24 MB
> >    66  594: COMP[75 (1..1)] pos=923 w=9 a+d=17+4 face=24 MB
> >    67  603: COMP[75 (2..2)] pos=924 w=9 a+d=17+4 face=24 MB
> >    68  612: CHAR["] pos=925 blev=0,btyp=L w=9 a+d=17+4 face=23 MB
> >    69  621: CHAR[ ] pos=926 blev=0,btyp=L w=9 a+d=17+4 MB
> >    70  630: CHAR["] pos=927 blev=0,btyp=L w=9 a+d=17+4 face=23 MB
> >    71  639: COMP[76 (0..0)] pos=928 w=9 a+d=17+4 face=24 MB
> >    72  648: COMP[76 (1..1)] pos=929 w=9 a+d=17+4 face=24 MB
> >    73  657: COMP[76 (2..2)] pos=930 w=9 a+d=17+4 face=24 MB
> >    74  666: CHAR["] pos=931 blev=0,btyp=L w=9 a+d=17+4 face=23 MB
> >    75  675: CHAR[ ] pos=932 blev=0,btyp=L w=9 a+d=17+4 MB
> >    76  684: CHAR["] pos=933 blev=0,btyp=L w=9 a+d=17+4 face=23 MB
> >    77  693: COMP[77 (0..0)] pos=934 w=9 a+d=17+4 face=24 MB
> >    78  702: COMP[77 (1..1)] pos=935 w=9 a+d=17+4 face=24 MB
> >    79  711: COMP[77 (2..2)] pos=936 w=9 a+d=17+4 face=24 MB
> >
> > Each line here describes a glyph on display.  Where it says "CHAR[X]",
> > that's a character glyph of character X.  Where it says
> > "COMP[n (i..j)]", that's a composition whose cached ID is n, and i and
> > j are the characters in the composed sequence represented by this
> > glyph.
> >
> > The "pos=NNNN" part is the buffer position from where each glyph came.
> >
> > Find the cache ID of the composition which shows the problematic
> > ligature by its buffer position which you displayed at the beginning.
> > Let's assume that the ID of that composition is 69 (from the glyph
> > row shown above).  Then type:
> >
> >    (gdb) pp composition_gstring_from_id(69)
> >
> > This will show the composition cached at slot 116.  The structure of
> > the composition is described in the doc string of
> > composition-get-gstring.  Here's what I get here for the ligature
> > cached at slot 69:
> >
> >     (gdb) pp composition_gstring_from_id(69)
> >     [[#<font-object "-outline-Cascadia Code-regular-normal-normal-mono-16-*-*-*-c-*-iso8859-1"> 45 45 62] 69 [0 0 45 1970 9 1 10 17 4 nil] [1 1 45 1969 9 0 10 17 4 nil] [2 2 62 2728 9 0 9 17 4 nil]]
> >
> > It clearly shows the font used to display the 3 glyphs of this
> > ligature and the data of the 3 glyphs themselves.
> >
> > The idea is then to compare what you get from the "bad" display with
> > what you get for the same ligature in a fresh Emacs session, where the
> > display should be good.
> >
> > Let me know if you need more help or more detailed instructions or
> > have questions.
> >
> > Thanks.
> 
> Thank you very much for the clear instructions.  I was testing this in a
> fresh Emacs session.  And
> 
>     (gdb) pp composition_gstring_from_id(ID)
> 
> seems to show nothing?
> 
>     (gdb) c
>     Continuing.
> 
>     Thread 1 "emacs" hit Breakpoint 3, set_cursor_from_row (w=0x55b8c994f338, row=0x55b8c9e20410, matrix=0x55b8c9960480, delta=0, delta_bytes=0, dy=0, dvpos=0) at xdisp.c:18217
>     18217	  struct glyph *glyph = row->glyphs[TEXT_AREA];
>     (gdb) pgrow
>     TEXT: 4 glyphs
>       0    0: COMP[16 (0..0)] pos=5 w=9 a+d=14+4 face=28 MB
>       1    9: COMP[16 (1..1)] pos=6 w=9 a+d=14+4 face=28 MB
>       2   18: COMP[16 (2..2)] pos=7 w=9 a+d=14+4 face=28 MB
>       3   27: CHAR[ ] pos=0 blev=0,btyp=B w=9 a+d=14+4 MB
>     (gdb) pp composition_gstring_from_id(16)
>     (gdb) p composition_gstring_from_id(16)
>     $1 = XIL(0x55b8cada607d)
> 
> Am I missing something?

Maybe your Emacs is not built with enough debug info?

What does this produce:

  (gdb) p composition_gstring_from_id(16)
  $1 = XIL(0x55b8cada607d)
  (gdb) xpr

If this doesn't work, either, you will have to decypher
XIL(0x55b8cada607d) "by hand", using xvector etc...  I can give you
instructions for that as well.