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}