Okay, here's what I think is a breakthrough: > > There are a few calls to lglyph-set-adjustment in composite.el, > > which > > could be responsible for this.  So if the breakpoint inside > > composition_gstring_adjust_zero_width never breaks in your > > sessions, > > either, the next step is to put a watchpoint on the cached > > composition > > created by font-shape-gstring and wait for some code to modify the > > adjustment part. > Neither the critical line in composition_gstring_adjust_zero_width nor the calls to lglyph-set-adjustment in composite.el are triggered. But this hack in hbfont_shape means I can't reproduce the bug anymore using Yixuan's init file: diff --git a/src/hbfont.c b/src/hbfont.c index 37ed4132492..6fae513069a 100644 --- a/src/hbfont.c +++ b/src/hbfont.c @@ -592,11 +592,12 @@ hbfont_shape (Lisp_Object lgstring, Lisp_Object direction) LGLYPH_SET_ASCENT (lglyph, metrics.ascent); LGLYPH_SET_DESCENT (lglyph, metrics.descent); xoff = lround (pos[i].x_offset * position_unit); yoff = - lround (pos[i].y_offset * position_unit); - wadjust = lround (pos[i].x_advance * position_unit); + /* wadjust = lround (pos[i].x_advance * position_unit); */ + wadjust = metrics.width; if (xoff || yoff || wadjust != metrics.width) LGLYPH_SET_ADJUSTMENT (lglyph, CALLN (Fvector, make_fixnum (xoff), make_fixnum (yoff), make_fixnum (wadjust))); Without this patch, what I see with his init file matches his screenshots in the initial bug report (with the same ligatures affected, as far as I can see), namely a single additional "space" at the end of the ligature. Let me note again that this is different from I typically see when I use emacs daily, namely a space after (almost?) every character which is part of the ligature. We may or may not be chasing multiple bugs here. Anyway, I tried adding a printf inside the critical "if" in hbfont.c. This is what I see when the bug triggers: xoff: 0, yoff: 0, wadjust: 18, metrics.width: 9, pos[i].x_advance * position_unit: 18.000000 xoff: 0, yoff: 0, wadjust: 18, metrics.width: 9, pos[i].x_advance * position_unit: 18.000000 xoff: 0, yoff: 0, wadjust: 18, metrics.width: 9, pos[i].x_advance * position_unit: 18.000000 xoff: 0, yoff: 0, wadjust: 18, metrics.width: 9, pos[i].x_advance * position_unit: 18.000000 xoff: 0, yoff: 0, wadjust: 18, metrics.width: 9, pos[i].x_advance * position_unit: 18.000000 xoff: 0, yoff: 0, wadjust: 18, metrics.width: 9, pos[i].x_advance * position_unit: 18.000000 xoff: 0, yoff: 0, wadjust: 18, metrics.width: 9, pos[i].x_advance * position_unit: 18.000000 So this is not a rounding error at least. ;) Much more interesting: I can reproduce this only when "enough" (or I guess, the right) ligatures are visible in the buffer. With Yixuan's init file, when I not only load but also visit this init file -- just for testing the rendering, because it contains relevant ligatures -- then I can trigger the bug. But I can't trigger it with a reduced version (that notably doesn't contain arrow ligatures)! Eli, perhaps this is precise enough already so that you can reproduce it? See the attached archive: Use it as init-dir. It contains the init script (but I removed the automatic repeat). Visit bad.el. Press C=# to initialize the font randomization, and then keep pressing C-RET until you hopefully hit the bug. And I can't reproduce the bug with good.el that has fewer ligatures. So it seems that harfbuzz gives different results for some composition depending on the "context", i.e., the other characters (and ligatures?) that appear in the buffer passed to harfbuzz. Is this a bug in harfbuzz? If you still can't reproduce, what's a good way to pretty print the lgstring passed to hbfont_shape? (I'd prefer changing the code, that's a bit easier than gdb, at least for me.)