[luatex] Kerning: when does it not work?

Paul Isambert zappathustra at free.fr
Sat Apr 30 11:43:02 CEST 2011

Le 29/04/2011 11:52, Heilmann, Till A. a écrit :
> On 28/04/2011 07:27 PM, Paul Isambert wrote:
>> Two remarks (unfortunately you haven't had many answers...):
>> - Contrary to what might be implied (or simply misunderstood by me) 
>> in your last remark, penalties (and by the way \special's and 
>> whatever is between two glyphs) affect all font kerns, not only those 
>> you set by yourself in a feature file;
>> - There exists a solution: add the kerns by yourself; this means 
>> browsing a list of nodes, and for each pair of contiguous nodes, 
>> insert a kern if required in the font, where /contiguous/ means next 
>> to each other or separated by such things as penalties, specials, etc.
> Thank you, Paul, for your remarks and your advice. I am afraid, 
> though, that what you propose is beyond my capability as a (somewhat 
> experienced) user since it seems to require a good knowledge of LuaTeX 
> and at least some programming.
> I can work with the popular (La)TeX packages, not least because of the 
> good documentation provided and the friendly support from the 
> community. But actual programming is another thing. (I tried to read 
> the LuaTeX beta 0.66.0 manual but had to admit defeat).
> It looks like I have to do without customized kerning in LuaTeX and 
> for my future book projects must consider (horror, horror) switching 
> to a commercial DTP solution like InDesign.

Ah, this cannot be allowed; Taco has turned your problem into a feature 
request; in the meanwhile, here's some experimental code that add kerns 
between glyphs even though they are separated by penalties:

local GLYF = node.id("glyph")
local PNTY = node.id("penalty")
local KERN = node.id("kern")

local function add_kerns (head)
   for glyph in node.traverse_id(GLYF, head) do
     local next = glyph.next
     while next and next.id == PNTY do
       next = next.next
     if next and next.id == GLYF then
       if glyph.font == next.font then
         local kerns = font.getfont(glyph.font).characters[glyph.char].kerns
         if kerns and kerns[next.char] then
           local kern = node.new(KERN, 1)
           kern.kern = kerns[next.char]
           node.insert_after(head, glyph, kern)

luatexbase.add_to_callback("kerning", add_kerns, "add_kerns")

Some remarks:
- I use luatexbase.add_to_callback because I suppose you're using 
luatexbase (even if you might not know that), and thus callback.register 
(the original function) isn't available.
- I add kerns with subtype 1, equivalent to \kern, although what you 
really want is /font/ kerns (subtype 0); the difference is that font 
kerns may vary in width if you use font expansion, while normal kerns 
don't. However, if I inserted font kerns, they might disappear by the 
same process of font expansion and never reappear precisely because TeX 
hasn't inserted them by itself (at least that's what happened last 
summer and I suppose that hasn't changed, since it's normal behavior).
- Also, kerns won't be properly added in case of discretionaries. All in 
all, Taco's implementation will be better, of course, because it won't 
face this issue and the previous one.
- The code hasn't been put to any stringent test.
- Hope you haven't switched to InDesign yet.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://tug.org/pipermail/luatex/attachments/20110430/8c86f9d1/attachment.html>

More information about the luatex mailing list