summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/typo-krn.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/typo-krn.lua')
-rw-r--r--tex/context/base/mkiv/typo-krn.lua130
1 files changed, 51 insertions, 79 deletions
diff --git a/tex/context/base/mkiv/typo-krn.lua b/tex/context/base/mkiv/typo-krn.lua
index 7607fc5f5..24a91d6b6 100644
--- a/tex/context/base/mkiv/typo-krn.lua
+++ b/tex/context/base/mkiv/typo-krn.lua
@@ -10,12 +10,12 @@ if not modules then modules = { } end modules ['typo-krn'] = {
-- components: better split on tounicode
local next, type, tonumber = next, type, tonumber
-local utfchar = utf.char
local nodes = nodes
local fonts = fonts
-local tasks = nodes.tasks
+local enableaction = nodes.tasks.enableaction
+
local nuts = nodes.nuts
local nodepool = nuts.pool
@@ -25,27 +25,31 @@ local tonut = nuts.tonut
-- check what is used
local find_node_tail = nuts.tail
-local free_node = nuts.free
+local flush_node = nuts.flush_node
local insert_node_before = nuts.insert_before
local insert_node_after = nuts.insert_after
local end_of_math = nuts.end_of_math
+local use_components = nuts.use_components
local getfield = nuts.getfield
local getnext = nuts.getnext
local getprev = nuts.getprev
-local getboth = nuts.getboth
local getid = nuts.getid
local getfont = nuts.getfont
local getsubtype = nuts.getsubtype
local getchar = nuts.getchar
local getdisc = nuts.getdisc
+local getglue = nuts.getglue
+local getkern = nuts.getkern
local isglyph = nuts.isglyph
local setfield = nuts.setfield
local getattr = nuts.getattr
-local setattr = nuts.setattr
+local takeattr = nuts.takeattr
local setlink = nuts.setlink
-local setsubtype = nuts.setsubtype
+local setdisc = nuts.setdisc
+local setglue = nuts.setglue
+local setkern = nuts.setkern
local texsetattribute = tex.setattribute
local unsetvalue = attributes.unsetvalue
@@ -82,7 +86,6 @@ local spaceskip_code = skipcodes.spaceskip
local xspaceskip_code = skipcodes.xspaceskip
local fonthashes = fonts.hashes
-local fontdata = fonthashes.identifiers
local chardata = fonthashes.characters
local quaddata = fonthashes.quads
local markdata = fonthashes.marks
@@ -104,11 +107,8 @@ typesetters.kerns = typesetters.kerns or { }
local kerns = typesetters.kerns
local report = logs.reporter("kerns")
-local trace_ligatures = false trackers.register("typesetters.kerns.ligatures",function(v) trace_ligatures = v end)
-
--- use_advance is just an experiment: it makes copying glyphs (instead of new_glyph) dangerous
-
-local use_advance = false directives.register("typesetters.kerns.advance", function(v) use_advance = v end)
+local trace_ligatures = false trackers.register("typesetters.kerns.ligatures", function(v) trace_ligatures = v end)
+local trace_ligatures_d = false trackers.register("typesetters.kerns.ligatures.detail",function(v) trace_ligatures_d = v end)
kerns.mapping = kerns.mapping or { }
kerns.factors = kerns.factors or { }
@@ -146,18 +146,24 @@ function kerns.keepligature(n) -- might become default
local c = getchar(n)
local d = fontdescriptions[f][c].name
if a > 0 and contextsetups[a].keepligatures == v_auto then
- report("font %!font:name!, glyph %a, slot %X -> ligature %s, by %s feature %a",f,d,c,"kept","dynamic","keepligatures")
+ if trace_ligatures_d then
+ report("font %!font:name!, glyph %a, slot %X -> ligature %s, by %s feature %a",f,d,c,"kept","dynamic","keepligatures")
+ end
setcolor(n,"darkred")
return true
end
local k = fontfeatures[f].keepligatures
if k == v_auto then
- report("font %!font:name!, glyph %a, slot %X -> ligature %s, by %s feature %a",f,d,c,"kept","static","keepligatures")
+ if trace_ligatures_d then
+ report("font %!font:name!, glyph %a, slot %X -> ligature %s, by %s feature %a",f,d,c,"kept","static","keepligatures")
+ end
setcolor(n,"darkgreen")
return true
end
if not k then
- report("font %!font:name!, glyph %a, slot %X -> ligature %s, by %s feature %a",f,d,c,"split","static","keepligatures")
+ if trace_ligatures_d then
+ report("font %!font:name!, glyph %a, slot %X -> ligature %s, by %s feature %a",f,d,c,"split","static","keepligatures")
+ end
resetcolor(n)
return false
end
@@ -227,8 +233,7 @@ local function inject_begin(boundary,prev,keeptogether,krn,ok) -- prev is a glyp
end
if inject then
-- not yet ok, as injected kerns can be overlays (from node-inj.lua)
- setsubtype(boundary,userkern_code)
- setfield(boundary,"kern",getfield(boundary,"kern") + quaddata[getfont(prev)]*krn)
+ setkern(boundary,getkern(boundary) + quaddata[getfont(prev)]*krn,userkern_code)
return boundary, true
end
end
@@ -264,8 +269,7 @@ local function inject_end(boundary,next,keeptogether,krn,ok)
end
if inject then
-- not yet ok, as injected kerns can be overlays (from node-inj.lua)
- setsubtype(tail,userkern_code)
- setfield(tail,"kern",getfield(tail,"kern") + quaddata[getfont(next)]*krn)
+ setkern(tail,getkern(tail) + quaddata[getfont(next)]*krn,userkern_code)
return boundary, true
end
end
@@ -279,7 +283,7 @@ local function inject_end(boundary,next,keeptogether,krn,ok)
local data = chardata[font][nextchar]
local kerns = data and data.kerns
local kern = (kerns and kerns[char] or 0) + quaddata[font]*krn
- insert_node_after(boundary,tail,new_kern(kern))
+ setlink(tail,new_kern(kern))
return boundary, true
end
end
@@ -315,8 +319,7 @@ local function process_list(head,keeptogether,krn,font,okay)
end
if inject then
-- not yet ok, as injected kerns can be overlays (from node-inj.lua)
- setsubtype(prev,userkern_code)
- setfield(prev,"kern",getfield(prev,"kern") + kern)
+ setkern(prev,getkern(prev) + kern,userkern_code)
okay = true
end
end
@@ -378,9 +381,8 @@ function kerns.handler(head)
-- fontkerns don't get the attribute but they always sit between glyphs so
-- are always valid bound .. disc nodes also somtimes don't get them
local id = getid(start)
- local attr = getattr(start,a_kerns)
+ local attr = takeattr(start,a_kerns)
if attr and attr > 0 then
- setattr(start,a_kerns,0) -- unsetvalue)
local krn = mapping[attr]
if krn == v_max then
krn = .25
@@ -390,31 +392,13 @@ function kerns.handler(head)
end
if not krn or krn == 0 then
bound = false
- elseif id == glyph_code then -- we could use the subtype ligature
- local c = getfield(start,"components")
- if not c then
- -- fine
- elseif keepligature and keepligature(start) then
+ elseif id == glyph_code then
+ if keepligature and keepligature(start) then
-- keep 'm
- c = nil
else
- while c do
- local s = start
- local t = find_node_tail(c)
- local p, n = getboth(s)
- if p then
- setlink(p,c)
- else
- head = c
- end
- if n then
- setlink(t,n)
- end
- start = c
- setfield(s,"components",nil)
- free_node(s)
- c = getfield(start,"components")
- end
+ -- we could use the subtype ligature but that's also a call
+ -- todo: check tounicode and use that information to split
+ head, start = use_components(head,start)
end
local char = getchar(start)
local font = getfont(start)
@@ -433,8 +417,7 @@ function kerns.handler(head)
end
if inject then
-- not yet ok, as injected kerns can be overlays (from node-inj.lua)
- setsubtype(prev,userkern_code)
- setfield(prev,"kern",getfield(prev,"kern") + quaddata[font]*krn)
+ setkern(prev,getkern(prev) + quaddata[font]*krn,userkern_code)
done = true
end
end
@@ -446,11 +429,7 @@ function kerns.handler(head)
local data = chardata[font][prevchar]
local kerns = data and data.kerns
local kern = (kerns and kerns[char] or 0) + quaddata[font]*krn
- if not fillup and use_advance then
- setfield(prev,"xadvance",getfield(prev,"xadvance") + kern)
- else
- insert_node_before(head,start,kern_injector(fillup,kern))
- end
+ insert_node_before(head,start,kern_injector(fillup,kern))
done = true
end
else
@@ -480,12 +459,7 @@ function kerns.handler(head)
languages.expand(start,pglyph and prev)
end
local pre, post, replace = getdisc(start)
- -- we really need to reasign the fields as luatex keeps track of
- -- the tail in a temp preceding head .. kind of messy so we might
- -- want to come up with a better solution some day like a real
- -- pretail etc fields in a disc node
- --
- -- maybe i'll merge the now split functions
+ local indeed = false
if pre then
local okay = false
if not prev then
@@ -497,8 +471,7 @@ function kerns.handler(head)
end
pre, okay = process_list(pre,keeptogether,krn,false,okay)
if okay then
- setfield(start,"pre",pre)
- done = true
+ indeed = true
end
end
if post then
@@ -512,8 +485,7 @@ function kerns.handler(head)
end
post, okay = process_list(post,keeptogether,krn,false,okay)
if okay then
- setfield(start,"post",post)
- done = true
+ indeed = true
end
end
if replace then
@@ -534,11 +506,14 @@ function kerns.handler(head)
end
replace, okay = process_list(replace,keeptogether,krn,false,okay)
if okay then
- setfield(start,"replace",replace)
- done = true
+ indeed = true
end
elseif prevfont then
- setfield(start,"replace",new_kern(quaddata[prevfont]*krn))
+ replace = new_kern(quaddata[prevfont]*krn)
+ indeed = true
+ end
+ if indeed then
+ setdisc(start,pre,post,replace)
done = true
end
bound = false
@@ -549,21 +524,18 @@ function kerns.handler(head)
elseif id == glue_code then
local subtype = getsubtype(start)
if subtype == userskip_code or subtype == xspaceskip_code or subtype == spaceskip_code then
- local w = getfield(start,"width")
- if w > 0 then
- local width = w + gluefactor * w * krn
- local stretch = getfield(start,"stretch") * width / w
- local shrink = getfield(start,"shrink") * width / w
+ local width, stretch, shrink, stretch_order, shrink_order = getglue(start)
+ if width > 0 then
+ local w = width + gluefactor * width * krn
+ stretch = stretch * w / width
+ shrink = shrink * w / width
if fillup then
stretch = 2 * stretch
shrink = 2 * shrink
- setfield(start,"stretch_order",1)
- -- shrink_order ?
+ stretch_order = 1
+ -- shrink_order = 1 ?
end
- setfield(start,"width",width)
- setfield(start,"stretch",stretch)
- setfield(start,"shrink", shrink)
- --
+ setglue(start,w,stretch,shrink,stretch_order,shrink_order)
done = true
end
end
@@ -612,7 +584,7 @@ function kerns.set(factor)
end
if factor == v_max or factor ~= 0 then
if not enabled then
- tasks.enableaction("processors","typesetters.kerns.handler")
+ enableaction("processors","typesetters.kerns.handler")
enabled = true
end
local a = factors[factor]