Hi,

currently LuaTeX does not insert kerning between hyphens and characters
before discretionary hyphens if the hyphen was inserted automatically.

Take for example (here `a` is used as hyphenation character to simulate
a font where kerning with the hyphen is mmre common than in cmr):

    \showboxdepth=\maxdimen
    \showboxbreadth=\maxdimen
    \tracingonline=1
    \lefthyphenmin1
    \righthyphenmin1
    \hyphenation{V-b}
    \prehyphenchar=`a
    \setbox0=\vbox{Vb}
    \showbox0
    \bye

This results in

[...]
..\tenrm V
..\discretionary (penalty 50)
...< \tenrm a
..\tenrm b
[...]

with no kern between the `V` and the `a`. If the hyphenation point is
inserted manually by using 

    \setbox0=\vbox{V\-b}

instead the problem disappears and we get the expected

[...]
..\tenrm V
..\discretionary (penalty 50)
...< \kern-0.83334 (font)
...< \tenrm a
..\tenrm b
[...]

Additionally the broken version writes the dropped kern node to
vlink(null) breaking any code which relies on vlink(null) being null
(see e.g. my previous mail).

The issue is that `add_kern_before` in luafont.c relies on alink of the
right glyph being valid. Since the right glyph here is the "hyphen" glyph
in a discretionary this depends on what `alink` for the beginning of a
discretionary list is. Currently this is inconsistent. When set through
`set_disc_field` then the `alink` is explicitly set to null to avoid
exposing the temporary "nodes" in discretionaries to Lua code. his
triggers the bug since the kern gets added after null instead of before
the right glyph.

If the discretionary gets inserted through a discretionary_cmd by
append_discretionary in maincontrol.c then the alink gets explicitly set
to these pseudo nodes instead avoiding the issue.

It doesn't make much sense to handle this inconsistently this is likely
and internal nodes are already exposed in other places, so IMO the best 
solution is
to alink to these nodes in set_disc_field too, e.g. with

diff --git a/source/texk/web2c/luatexdir/lang/texlang.c 
b/source/texk/web2c/luatexdir/lang/texlang.c
index a0d067251..3cbbdd3b4 100644
--- a/source/texk/web2c/luatexdir/lang/texlang.c
+++ b/source/texk/web2c/luatexdir/lang/texlang.c
@@ -470,12 +470,7 @@ static halfword compound_word_break(halfword t, int clang)
 void set_disc_field(halfword f, halfword t)
 {
     if (t != null) {
-        /*tex
-            No |couple_nodes(f, t);| as we can better not expose |f| as |prev|
-            pointer.
-        */
-        vlink(f) = t ;
-        alink(t) = null ;
+        couple_nodes(f, t);
         tlink(f) = tail_of_list(t);
     } else {
         vlink(f) = null;
--

Best,
Marcel
>From fb9a4811b7891a002f549ff7bbcd34d19ec58b94 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marcel=20Fabian=20Kr=C3=BCger?= <t...@2krueger.de>
Date: Sun, 27 Nov 2022 14:38:23 +0100
Subject: [PATCH 4/4] Make disc node prev pointers more uniform

---
 source/texk/web2c/luatexdir/lang/texlang.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/source/texk/web2c/luatexdir/lang/texlang.c 
b/source/texk/web2c/luatexdir/lang/texlang.c
index a0d067251..3cbbdd3b4 100644
--- a/source/texk/web2c/luatexdir/lang/texlang.c
+++ b/source/texk/web2c/luatexdir/lang/texlang.c
@@ -470,12 +470,7 @@ static halfword compound_word_break(halfword t, int clang)
 void set_disc_field(halfword f, halfword t)
 {
     if (t != null) {
-        /*tex
-            No |couple_nodes(f, t);| as we can better not expose |f| as |prev|
-            pointer.
-        */
-        vlink(f) = t ;
-        alink(t) = null ;
+        couple_nodes(f, t);
         tlink(f) = tail_of_list(t);
     } else {
         vlink(f) = null;
-- 
2.38.1

_______________________________________________
dev-luatex mailing list
dev-luatex@ntg.nl
https://mailman.ntg.nl/mailman/listinfo/dev-luatex

Reply via email to