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
\documentclass[12pt]{article}    
\RequirePackage{xcolor}
\RequirePackage{luacode}

\newcount\dropsidebearings

\begin{luacode*}
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
luatexbase.add_to_callback('post_linebreak_filter', drop_sidebearing, 'Drop sidebearings after linebreaking')
\end{luacode*}


\newcommand{\hairlineiv}[1][green]{% 
  \leavevmode%
  \kern-0.1pt %
  \smash{\color{#1}\vrule height 6\baselineskip depth 5pt width 0.1pt}%
  \kern-0.1pt
}

\newcommand{\hairlinevi}[1][green]{% 
  \leavevmode%
  \kern-0.1pt %
  \smash{\color{#1}\vrule depth 6\baselineskip height 2ex width 0.1pt}%
  \kern-0.1pt
}
\begin{document}  
\pagestyle{empty}  

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

Note the {\bfseries uneven} gap between the text and the green line.
\vspace{3\baselineskip}

\begin{minipage}{5in}
    \dropsidebearings=0  %correction OFF    
    \raggedleft\sffamily\fontsize{60}{72}\selectfont\bfseries \longtitles\hairlineiv
\end{minipage}

\newpage

Perfect aligment! Each whole line was right shifted by a different amount.
\vspace{3\baselineskip}

\begin{minipage}{5in}
  \dropsidebearings=1  %correction ON     
 \raggedleft\sffamily\fontsize{60}{72}\selectfont\bfseries \longtitles\hairlineiv
\end{minipage}

\begin{minipage}{5in}
  \dropsidebearings=1  %correction ON     
 \raggedright\sffamily\fontsize{60}{72}\selectfont\bfseries \hairlinevi\longtitles
\end{minipage}

\end{document}

Reply via email to