Commits

Philipp Gesang committed d40c233

adapt to luatexbase style; install fallbacks

  • Participants
  • Parent commits 1136d5d

Comments (0)

Files changed (2)

File letterspace-callback.lua

 local insert_node_after  = node.insert_after
 local end_of_math        = node.end_of_math
 
-local texattribute       = tex.attribute--- deleatur
-local unsetvalue         = attributes.unsetvalue--- deleatur
+----- unsetvalue         = -0x7FFFFFFF --- <= attr-ini
+local unsetvalue         = (luatexbase.luatexversion < 37) and -1
+                        or -2147483647 --- <= attr.lua
 
 local nodepool           = nodes.pool
 local tasks              = nodes.tasks
 local new_glue           = nodepool.glue
 
 local nodecodes          = nodes.nodecodes
-local kerncodes          = nodes.kerncodes
-local skipcodes          = nodes.skipcodes
-
 local glyph_code         = nodecodes.glyph
 local kern_code          = nodecodes.kern
 local disc_code          = nodecodes.disc
 local vlist_code         = nodecodes.vlist
 local math_code          = nodecodes.math
 
+local bothways = function (t) return table.swapped (t, t) end
+
+local kerncodes          = bothways({ -- <= node-ini
+    [0] = "fontkern",
+    [1] = "userkern",
+    [2] = "accentkern",
+})
 local kerning_code       = kerncodes.kerning
 local userkern_code      = kerncodes.userkern
+
+local skipcodes          = bothways({ -- <= node-ini
+    [  0] = "userskip",
+    [  1] = "lineskip",
+    [  2] = "baselineskip",
+    [  3] = "parskip",
+    [  4] = "abovedisplayskip",
+    [  5] = "belowdisplayskip",
+    [  6] = "abovedisplayshortskip",
+    [  7] = "belowdisplayshortskip",
+    [  8] = "leftskip",
+    [  9] = "rightskip",
+    [ 10] = "topskip",
+    [ 11] = "splittopskip",
+    [ 12] = "tabskip",
+    [ 13] = "spaceskip",
+    [ 14] = "xspaceskip",
+    [ 15] = "parfillskip",
+    [ 16] = "thinmuskip",
+    [ 17] = "medmuskip",
+    [ 18] = "thickmuskip",
+    [100] = "leaders",
+    [101] = "cleaders",
+    [102] = "xleaders",
+    [103] = "gleaders",
+})
 local userskip_code      = skipcodes.userskip
 local spaceskip_code     = skipcodes.spaceskip
 local xspaceskip_code    = skipcodes.xspaceskip
 
 local fonthashes         = fonts.hashes
-local fontdata           = fonthashes.identifiers
+
+--- some initialization resembling font-hsh
+local identifiers        = fonthashes.identifiers --- was: fontdata
 local chardata           = fonthashes.characters
 local quaddata           = fonthashes.quads
 local markdata           = fonthashes.marks
+local parameters         = fonthashes.parameters
 
-local v_max              = interfaces.variables.max
+if not parameters then
+    parameters = { }
+    setmetatable(parameters, { __index = function(t, k)
+        if k == true then
+            return parameters[currentfont()]
+        else
+            local parameters = identifiers[k].parameters
+            t[k] = parameters
+            return parameters
+        end
+    end})
+    fonthashes.parameters = parameters
+end
 
+if not chardata then
+    chardata = { }
+    setmetatable(chardata, { __index = function(t, k)
+        if k == true then
+            return chardata[currentfont()]
+        else
+            local characters = identifiers[k].characters
+            t[k] = characters
+            return characters
+        end
+    end})
+    fonthashes.characters = chardata
+end
+
+if not quaddata then
+    quaddata = { }
+    setmetatable(quaddata, { __index = function(t, k)
+        if k == true then
+            return quads[currentfont()]
+        else
+            local parameters = parameters[k]
+            local quad = parameters and parameters.quad or 0
+            t[k] = quad
+            return quad
+        end
+    end})
+    fonthashes.quads = quaddata
+end
+
+if not markdata then
+    markdata = { }
+    setmetatable(markdata, { __index = function(t, k)
+        if k == true then
+            return marks[currentfont()]
+        else
+            local resources = identifiers[k].resources or { }
+            local marks = resources.marks or { }
+            t[k] = marks
+            return marks
+        end
+    end})
+    fonthashes.marks = markdata
+end
+
+local v_max              = "max" -- <= interfaces.variables.max
+
+--- we keep the namespace atm
 typesetters              = typesetters or { }
 local typesetters        = typesetters
 
 
 kerns.mapping            = kerns.mapping or { }
 kerns.factors            = kerns.factors or { }
-local a_kerns            = attributes.private("kern")
-local a_fontkern         = attributes.private('fontkern')
-kerns.attribute          = kerns.attribute
+local mapping            = kerns.mapping
+local factors            = kerns.factors
 
-storage.register("typesetters/kerns/mapping", kerns.mapping, "typesetters.kerns.mapping")
-storage.register("typesetters/kerns/factors", kerns.factors, "typesetters.kerns.factors")
+local a_kerns            = luatexbase.new_attribute"kern"
+local a_fontkern         = luatexbase.new_attribute"fontkern"
 
-local mapping = kerns.mapping
-local factors = kerns.factors
+kerns.attribute          = kerns.attribute --- deleatur?
+
+local texattribute       = tex.attribute
 
 -- one must use liga=no and mode=base and kern=yes
 -- use more helpers
                     local prev = start.prev
                     if not prev then
                         -- skip
-                    elseif markdata[lastfont][start.char] then
+--                  elseif markdata[lastfont][start.char] then
                             -- skip
                     else
                         local pid = prev.id
     return head, done
 end
 
-local enabled = false
+local kerncharacters = function (head)
+    return do_process("kerns", a_kerns, head)
+end
+
+--- callback injection ------------------------------------------------
+
+local callback_name = "typesetters.kerncharacters"
+
+local add_processor = function (...)
+    for i=1, select("#", ...) do
+        luatexbase.add_to_callback(
+            select(i, ...), kerncharacters, callback_name
+        )
+    end
+end
+
+local remove_processor = function (...)
+    for i=1, select("#", ...) do
+        luatexbase.remove_from_callback(
+            select(i, ...), kerncharacters, callback_name
+        )
+    end
+end
+
+--- we use the same callbacks as a node processor in Context
+
+kerns.enablecharacterkerning = function ( )
+    add_processor("pre_linebreak_filter", "hpack_filter")
+end
+
+kerns.disablecharacterkerning = function ( )
+    remove_processor("pre_linebreak_filter", "hpack_filter")
+end
+
+--- interface ---------------------------------------------------------
+
+local enabled = false --- callback state
 
 function kerns.set(factor)
     if factor ~= v_max then
     end
     if factor == v_max or factor ~= 0 then
         if not enabled then
-            tasks.enableaction("processors","typesetters.kerns.handler")
+            kerns.enablecharacterkerning()
             enabled = true
         end
         local a = factors[factor]
     return factor
 end
 
-local function process(namespace,attribute,head)
-    return do_process(namespace,attribute,head)  -- no direct map, because else fourth argument is tail == true
-end
 
-kerns.handler = nodes.installattributehandler {
-    name     = "kern",
-    namespace = kerns,
-    processor = process,
-}
 
--- interface
+--- 1) enable() : injects callback
+--- 2) set()    : toggles kerning
 
-commands.setcharacterkerning = kerns.set
+-- vim:ts=4:sw=4:expandtab

File spielwiese.tex

 \input luaotfload.sty
 \RequireLuaModule{letterspace-callback.lua}
+%directlua{typesetters.kerns.enablecharacterkerning()}
 
 \font\iwona = name:Iwona:mode=node at 42pt
 
-{\iwona foo bar baz}
+{\iwona
+ foo
+ {\directlua{typesetters.kerns.set(0.618)}%
+  bar}
+ baz}
 
 \bye