I have prepared a plain example (attached) which can be run with

    mtxrun --script plain --run test.tex

and also segfaults.

On 1/16/19 10:14 PM, Henri Menke wrote:
> Dear list,
> 
> To answer a question on TeX.SX I wanted to compare glyph sidebearings
> using kerns.  However, when trying to insert a kern before the head of
> the last line I first get an error followed by segmentation fault:
> 
> warning  (node filter): error: [\directlua]:12: Attempt to
> node.insert_before() a non-existing node
> 
> Segmentation fault
> 
> The example is attached because it's a bit larger.  I marked the
> offending line with “BOOM”.
> 
> Cheers, Henri
> 

\font\1="[lmsans10-bold.otf]" at 60pt
\def\Huge{\1\baselineskip=72pt\relax}

\def\raggedleft{%
  \parindent=0pt
  \parfillskip=0pt
  \rightskip=0pt
  \leftskip=0pt plus 1fil
  \relax
}

\def\raggedright{%
  \parindent=0pt
  \parfillskip=0pt
  \leftskip=0pt
  \rightskip=0pt plus 1fil
  \relax
}

\newcount\dropsidebearings

\begingroup
\catcode`\^^M=12
\directlua{
local function drop_sidebearing(head, groupcode)
    if tex.count['dropsidebearings'] == 0 then
        return true
    end
    for n in node.traverse_id(node.id'hlist', head) do
        local char = node.has_glyph(n.head)
        if char then
            local f = font.getfont(char.font)
            if f.shared then
                local kern = node.new(node.id'kern')
                kern.kern = f.shared.rawdata.descriptions[char.char].boundingbox[1]*f.size/1000
                node.insert_before(n, char, node.copy(kern)) -- BOOM!
                node.free(kern)
            end
        end
        for ch in node.traverse_id(node.id'glyph', n.head) do
            char = ch
        end
        if char then
            local f = font.getfont(char.font)
            if f.shared then
                local desc = f.shared.rawdata.descriptions[char.char]
                local kern = node.new(node.id'kern')
                kern.kern = - (desc.width-desc.boundingbox[3])*f.size/1000
                node.insert_after(n, char, node.copy(kern))
                node.free(kern)
            end
        end
        local new_list = node.hpack(n.head, n.width, 'exactly')
        new_list.head = nil
        n.glue_order = new_list.glue_order 
        n.glue_set = new_list.glue_set
        n.glue_sign = new_list.glue_sign 
        node.free(new_list)
    end
    return true
end
callback.register('post_linebreak_filter', drop_sidebearing)
}
\endgroup

\def\hairlineiv{% 
  \leavevmode%
  \kern-0.1pt %
  \smash{\vrule height 6\baselineskip depth 5pt width 0.1pt}%
  \kern-0.1pt
}

\def\hairlinevi{% 
  \leavevmode%
  \kern-0.1pt %
  \smash{\vrule depth 6\baselineskip height 2ex width 0.1pt}%
  \kern-0.1pt
}

\def\longtitles{Long titles must be exactly aligned with the vertical green bar.}% the main title

Note the {\bf uneven} gap between the text and the green line.

\vskip3\baselineskip

\vbox{\hsize=5in
    \dropsidebearings=0  %correction OFF    
    \raggedleft\Huge \longtitles\hairlineiv\par
}

\eject

Perfect aligment! Each whole line was right shifted by a different amount.

\vskip3\baselineskip

\vbox{\hsize=5in
  \dropsidebearings=1  %correction ON     
 \raggedleft\Huge \longtitles\hairlineiv
}

\vbox{\hsize=5in
  \dropsidebearings=1  %correction ON     
 \raggedright\Huge \hairlinevi\longtitles
}

\bye

Reply via email to