summaryrefslogtreecommitdiff
path: root/luaotfload-extralibs.lua
diff options
context:
space:
mode:
Diffstat (limited to 'luaotfload-extralibs.lua')
-rw-r--r--luaotfload-extralibs.lua164
1 files changed, 124 insertions, 40 deletions
diff --git a/luaotfload-extralibs.lua b/luaotfload-extralibs.lua
index 618808f..1e0d85a 100644
--- a/luaotfload-extralibs.lua
+++ b/luaotfload-extralibs.lua
@@ -23,6 +23,7 @@ local texattribute = tex.attribute
local new_node = node.new
local copy_node = node.copy
+local otffeatures = fonts.constructors.newfeatures "otf"
-----------------------------------------------------------------------
--- namespace
@@ -38,8 +39,10 @@ local kerns = typesetters.kerns
kerns.mapping = kerns.mapping or { }
kerns.factors = kerns.factors or { }
-local namespace = "kern" --- <= attribute <= plugin.name
-local callback_name = "typesetters.kerncharacters"
+local kern_callback = "typesetters.kerncharacters"
+
+typesetters.kernfont = typesetters.kernfont or { }
+local kernfont = typesetters.kernfont
-----------------------------------------------------------------------
--- node-ini
@@ -207,6 +210,7 @@ if not markdata then
fonthashes.marks = markdata
end
+--- next stems from the multilingual interface
interfaces = interfaces or { }
interfaces.variables = interfaces.variables or { }
interfaces.variables.max = "max"
@@ -281,9 +285,10 @@ commands = commands or { }
--- LOAD
--===================================================================--
---- we should be ready at this moment to insert the library
+--- we should be ready at this moment to insert the libraries
-require "luaotfload-typo-krn"
+require "luaotfload-typo-krn" --- typesetters.kerns
+require "luaotfload-letterspace" --- typesetters.kernfont
--===================================================================--
--- CLEAN
@@ -296,67 +301,146 @@ local mapping = kerns.mapping
local unsetvalue = attributes.unset_value
local process_kerns = plugin_store.kern
-local kerncharacters = function (head)
- return process_kerns("kerns", hidden.a_kerns, head)
-end
+--- kern_callback : normal
+--- · callback: process_kerns
+--- · enabler: enablecharacterkerning
+--- · disabler: disablecharacterkerning
+--- · interface: kerns.set
+
+--- kernfont_callback : fontwise
+--- · callback: kernfont.handler
+--- · enabler: enablefontkerning
+--- · disabler: disablefontkerning
--- callback wrappers
-local add_kern_processor = function (...)
- for i=1, select("#", ...) do
- luatexbase.add_to_callback(
- select(i, ...), kerncharacters, callback_name
- )
+
+--- (node_t -> node_t) -> string -> string list -> bool
+local registered_as = { } --- procname -> callbacks
+local add_processor = function (processor, name, ...)
+ local callbacks = { ... }
+ for i=1, #callbacks do
+ luatexbase.add_to_callback(callbacks[i], processor, name)
end
+ registered_as[name] = callbacks --- for removal
+ return true
end
-local remove_kern_processor = function (...)
- for i=1, select("#", ...) do
- luatexbase.remove_from_callback(
- select(i, ...), kerncharacters, callback_name
- )
+
+--- string -> bool
+local remove_processor = function (name)
+ local callbacks = registered_as[name]
+ if callbacks then
+ for i=1, #callbacks do
+ luatexbase.remove_from_callback(callbacks[i], name)
+ end
+ return true
end
+ return false --> unregistered
end
--- we use the same callbacks as a node processor in Context
-kerns.enablecharacterkerning = function ( )
- add_kern_processor("pre_linebreak_filter", "hpack_filter")
+--- unit -> bool
+local enablecharacterkerning = function ( )
+ return add_processor(function (head)
+ return process_kerns("kerns", hidden.a_kerns, head)
+ end,
+ "typesetters.kerncharacters",
+ "pre_linebreak_filter", "hpack_filter"
+ )
end
-kerns.disablecharacterkerning = function ( )
- remove_kern_processor("pre_linebreak_filter", "hpack_filter")
+--- unit -> bool
+local disablecharacterkerning = function ( )
+ return remove_processor "typesetters.kerncharacters"
end
-local enabled = false --- callback state
+kerns.enablecharacterkerning = enablecharacterkerning
+kerns.disablecharacterkerning = disablecharacterkerning
+
+--- now for the simplistic variant
+--- unit -> bool
+local enablefontkerning = function ( )
+ return add_processor(
+ kernfont.handler,
+ "typesetters.kernfont",
+ "pre_linebreak_filter", "hpack_filter"
+ )
+end
---- we just replace the kern enabler with our modified version
-kerns.set = function (factor)
- if factor ~= v_max then
+--- unit -> bool
+local disablefontkerning = function ( )
+ return remove_processor "typesetters.kernfont"
+end
+
+--- fontwise kerning uses a font property for passing along the
+--- letterspacing factor
+
+local fontkerning_enabled = false --- callback state
+
+--- fontobj -> float -> unit
+local initializefontkerning = function (tfmdata, factor)
+ if factor ~= "max" then
factor = tonumber(factor) or 0
end
- if factor == v_max or factor ~= 0 then
- if not enabled then
- kerns.enablecharacterkerning()
- enabled = true
+ if factor == "max" or factor ~= 0 then
+ local fontproperties = tfmdata.properties
+ if fontproperties then
+ --- hopefully this field stays unused otherwise
+ fontproperties.kerncharacters = factor
end
- local a = factors[factor]
- if not a then
- a = #mapping + 1
- factors[factors], mapping[a] = a, factor
+ if not fontkerning_enabled then
+ fontkerning_enabled = enablefontkerning()
end
- factor = a
- else
- factor = unsetvalue
end
- texattribute[hidden.a_kerns] = factor
- return factor
end
+--- like the font colorization, fontwise kerning is hooked into the
+--- feature mechanism
+
+otffeatures.register {
+ name = "letterspace", --"kerncharacters",
+ description = "letterspace", --"kerncharacters",
+ initializers = {
+ base = initializefontkerning,
+ node = initializefontkerning,
+ }
+}
+
+kerns.set = nil
+
+local characterkerning_enabled = false
+
+kerns.set = function (factor)
+ if factor ~= "max" then
+ factor = tonumber(factor) or 0
+ end
+ if factor == "max" or factor ~= 0 then
+ if not characterkerning_enabled then
+ enablecharacterkerning()
+ characterkerning_enabled = true
+ end
+ local a = factors[factor]
+ if not a then
+ a = #mapping + 1
+ factors[factors], mapping[a] = a, factor
+ end
+ factor = a
+ else
+ factor = unsetvalue
+ end
+ texattribute[hidden.a_kerns] = factor
+ return factor
+end
+
+
-----------------------------------------------------------------------
--- options
-----------------------------------------------------------------------
-kerns.keepligature = false --- supposed to be of type function
-kerns.keeptogether = false --- supposed to be of type function
+kerns .keepligature = false --- supposed to be of type function
+kerns .keeptogether = false --- supposed to be of type function
+kernfont.keepligature = false --- supposed to be of type function
+kernfont.keeptogether = false --- supposed to be of type function
-----------------------------------------------------------------------
--- erase fake Context layer