summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/mkiv/typo-krn.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/typo-krn.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/mkiv/typo-krn.lua314
1 files changed, 49 insertions, 265 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-krn.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-krn.lua
index c26004a49df..71d9736a44b 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/typo-krn.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/typo-krn.lua
@@ -21,6 +21,9 @@ local enableaction = nodes.tasks.enableaction
local nuts = nodes.nuts
local nodepool = nuts.pool
+local tonode = nuts.tonode
+local tonut = nuts.tonut
+
-- check what is used
local find_node_tail = nuts.tail
@@ -29,7 +32,6 @@ 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 copy_node = nuts.copy
local getnext = nuts.getnext
local getprev = nuts.getprev
@@ -41,12 +43,10 @@ local getdisc = nuts.getdisc
local getglue = nuts.getglue
local getkern = nuts.getkern
local isglyph = nuts.isglyph
-local setchar = nuts.setchar
local setfield = nuts.setfield
local getattr = nuts.getattr
local takeattr = nuts.takeattr
-local setattr = nuts.setattr
local setlink = nuts.setlink
local setdisc = nuts.setdisc
local setglue = nuts.setglue
@@ -62,7 +62,7 @@ local new_glue = nodepool.glue
local nodecodes = nodes.nodecodes
local kerncodes = nodes.kerncodes
-local gluecodes = nodes.gluecodes
+local skipcodes = nodes.skipcodes
local disccodes = nodes.disccodes
local listcodes = nodes.listcodes
@@ -74,18 +74,17 @@ local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
local math_code = nodecodes.math
-local boxlist_code = listcodes.box
-local unknownlist_code = listcodes.unknown
+local box_list_code = listcodes.box
+local user_list_code = listcodes.unknown
-local discretionarydisc_code = disccodes.discretionary
-local automaticdisc_code = disccodes.automatic
+local discretionary_code = disccodes.discretionary
+local automatic_code = disccodes.automatic
local fontkern_code = kerncodes.fontkern
local userkern_code = kerncodes.userkern
-
-local userskip_code = gluecodes.userskip
-local spaceskip_code = gluecodes.spaceskip
-local xspaceskip_code = gluecodes.xspaceskip
+local userskip_code = skipcodes.userskip
+local spaceskip_code = skipcodes.spaceskip
+local xspaceskip_code = skipcodes.xspaceskip
local fonthashes = fonts.hashes
local chardata = fonthashes.characters
@@ -133,6 +132,9 @@ local factors = kerns.factors
local gluefactor = 4 -- assumes quad = .5 enspace
+kerns.keepligature = false -- just for fun (todo: control setting with key/value)
+kerns.keeptogether = false -- just for fun (todo: control setting with key/value)
+
-- red : kept by dynamic feature
-- green : kept by static feature
-- blue : keep by goodie
@@ -255,7 +257,7 @@ end
local function inject_end(boundary,next,keeptogether,krn,ok)
local tail = find_node_tail(boundary)
- local char, id = isglyph(tail)
+ local char, id = getid(tail)
if id == kern_code then
if getsubtype(tail) == fontkern_code then
local inject = true
@@ -299,7 +301,7 @@ local function process_list(head,keeptogether,krn,font,okay)
local char, id = isglyph(start)
if char then
if not font then
- font = id -- getfont(start)
+ font = getfont(start)
mark = markdata[font]
kern = quaddata[font]*krn
end
@@ -352,223 +354,19 @@ local function closest_bound(b,get)
while b do
if not getattr(b,a_kerns) then
break
+ elseif getid(b) == glyph_code then
+ return b, getfont(b)
else
- local c, f = isglyph(b)
- if c then
- return b, f
- else
- b = get(b)
- end
+ b = get(b)
end
end
end
end
--- function kerns.handler(head)
--- local start = head
--- local lastfont = nil
--- local keepligature = kerns.keepligature
--- local keeptogether = kerns.keeptogether
--- local fillup = false
--- local bound = false
--- local prev = nil
--- local previd = nil
--- local prevchar = nil
--- local prevfont = nil
--- local prevmark = nil
--- while start do
--- -- 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 = takeattr(start,a_kerns)
--- if attr and attr > 0 then
--- local krn = mapping[attr]
--- if krn == v_max then
--- krn = .25
--- fillup = true
--- else
--- fillup = false
--- end
--- if not krn or krn == 0 then
--- bound = false
--- elseif id == glyph_code then
--- if keepligature and keepligature(start) then
--- -- keep 'm
--- else
--- -- 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, font = isglyph(start)
--- local mark = markdata[font]
--- if not bound then
--- -- yet
--- elseif mark[char] then
--- -- skip
--- elseif previd == kern_code then
--- if getsubtype(prev) == fontkern_code then
--- local inject = true
--- if keeptogether then
--- if previd == glyph_code and keeptogether(prev,start) then
--- inject = false
--- end
--- end
--- if inject then
--- -- not yet ok, as injected kerns can be overlays (from node-inj.lua)
--- setkern(prev,getkern(prev) + quaddata[font]*krn,userkern_code)
--- end
--- end
--- elseif previd == glyph_code then
--- if prevfont == font then
--- if keeptogether and keeptogether(prev,start) then
--- -- keep 'm
--- else
--- local data = chardata[font][prevchar]
--- local kerns = data and data.kerns
--- local kern = (kerns and kerns[char] or 0) + quaddata[font]*krn
--- insert_node_before(head,start,kern_injector(fillup,kern))
--- end
--- else
--- insert_node_before(head,start,kern_injector(fillup,quaddata[font]*krn))
--- end
--- end
--- prev = start
--- prevchar = char
--- prevfont = font
--- prevmark = mark
--- previd = id
--- bound = true
--- elseif id == disc_code then
--- local prev, next, pglyph, nglyph -- delayed till needed
--- local subtype = getsubtype(start)
--- -- if subtype == automaticdisc_code then
--- -- -- this is kind of special, as we have already injected the
--- -- -- previous kern
--- -- local prev = getprev(start)
--- -- local pglyph = prev and getid(prev) == glyph_code
--- -- languages.expand(start,pglyph and prev)
--- -- -- we can have a different start now
--- -- elseif subtype ~= discretionarydisc_code then
--- -- prev = getprev(start)
--- -- pglyph = prev and getid(prev) == glyph_code
--- -- languages.expand(start,pglyph and prev)
--- -- end
--- local pre, post, replace = getdisc(start)
--- local indeed = false
--- if pre then
--- local okay = false
--- if not prev then
--- prev = getprev(start)
--- pglyph = prev and getid(prev) == glyph_code
--- end
--- if pglyph then
--- pre, okay = inject_begin(pre,prev,keeptogether,krn,okay)
--- end
--- pre, okay = process_list(pre,keeptogether,krn,false,okay)
--- if okay then
--- indeed = true
--- end
--- end
--- if post then
--- local okay = false
--- if not next then
--- next = getnext(start)
--- nglyph = next and getid(next) == glyph_code
--- end
--- if nglyph then
--- post, okay = inject_end(post,next,keeptogether,krn,okay)
--- end
--- post, okay = process_list(post,keeptogether,krn,false,okay)
--- if okay then
--- indeed = true
--- end
--- end
--- if replace then
--- local okay = false
--- if not prev then
--- prev = getprev(start)
--- pglyph = prev and getid(prev) == glyph_code
--- end
--- if pglyph then
--- replace, okay = inject_begin(replace,prev,keeptogether,krn,okay)
--- end
--- if not next then
--- next = getnext(start)
--- nglyph = next and getid(next) == glyph_code
--- end
--- if nglyph then
--- replace, okay = inject_end(replace,next,keeptogether,krn,okay)
--- end
--- replace, okay = process_list(replace,keeptogether,krn,false,okay)
--- if okay then
--- indeed = true
--- end
--- elseif prevfont then
--- replace = new_kern(quaddata[prevfont]*krn)
--- indeed = true
--- end
--- if indeed then
--- setdisc(start,pre,post,replace)
--- end
--- bound = false
--- elseif id == kern_code then
--- bound = getsubtype(start) == fontkern_code
--- prev = start
--- previd = id
--- elseif id == glue_code then
--- local subtype = getsubtype(start)
--- if subtype == userskip_code or subtype == xspaceskip_code or subtype == spaceskip_code then
--- 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
--- stretch_order = 1
--- -- shrink_order = 1 ?
--- end
--- setglue(start,w,stretch,shrink,stretch_order,shrink_order)
--- end
--- end
--- bound = false
--- elseif id == hlist_code or id == vlist_code then
--- local subtype = getsubtype(start)
--- if subtype == unknownlist_code or subtype == boxlist_code then
--- -- special case
--- local b, f = closest_bound(start,getprev)
--- if b then
--- insert_node_before(head,start,kern_injector(fillup,quaddata[f]*krn))
--- end
--- local b, f = closest_bound(start,getnext)
--- if b then
--- insert_node_after(head,start,kern_injector(fillup,quaddata[f]*krn))
--- end
--- end
--- bound = false
--- elseif id == math_code then
--- start = end_of_math(start)
--- bound = false
--- end
--- if start then
--- start = getnext(start)
--- end
--- elseif id == kern_code then
--- bound = getsubtype(start) == fontkern_code
--- prev = start
--- previd = id
--- start = getnext(start)
--- else
--- bound = false
--- start = getnext(start)
--- end
--- end
--- return head
--- end
-
function kerns.handler(head)
+ local head = tonut(head)
local start = head
+ local done = false
local lastfont = nil
local keepligature = kerns.keepligature
local keeptogether = kerns.keeptogether
@@ -581,10 +379,10 @@ function kerns.handler(head)
local prevmark = nil
while start do
-- fontkerns don't get the attribute but they always sit between glyphs so
- -- are always valid bound .. disc nodes also sometimes don't get them
+ -- are always valid bound .. disc nodes also somtimes don't get them
+ local id = getid(start)
local attr = takeattr(start,a_kerns)
if attr and attr > 0 then
- local char, id = isglyph(start)
local krn = mapping[attr]
if krn == v_max then
krn = .25
@@ -594,34 +392,17 @@ function kerns.handler(head)
end
if not krn or krn == 0 then
bound = false
- elseif char then -- id == glyph_code
- local font = id -- more readable
- local mark = markdata[font]
+ elseif id == glyph_code then
if keepligature and keepligature(start) then
-- keep 'm
else
- -- head, start = use_components(head,start)
- -- beware, these are not kerned so we mighty need a kern only pass
- -- maybe some day .. anyway, one should disable ligaturing
- local data = chardata[font][char]
- if data then
- local unicode = data.unicode -- can be cached
- if type(unicode) == "table" then
- char = unicode[1]
- local s = start
- setchar(s,char)
- for i=2,#unicode do
- local n = copy_node(s)
- if i == 2 then
- setattr(n,a_kerns,attr) -- we took away the attr
- end
- setchar(n,unicode[i])
- insert_node_after(head,s,n)
- s = n
- end
- end
- 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)
+ local mark = markdata[font]
if not bound then
-- yet
elseif mark[char] then
@@ -637,6 +418,7 @@ function kerns.handler(head)
if inject then
-- not yet ok, as injected kerns can be overlays (from node-inj.lua)
setkern(prev,getkern(prev) + quaddata[font]*krn,userkern_code)
+ done = true
end
end
elseif previd == glyph_code then
@@ -644,33 +426,34 @@ function kerns.handler(head)
if keeptogether and keeptogether(prev,start) then
-- keep 'm
else
- -- hm, only basemode ... will go away ...
local data = chardata[font][prevchar]
local kerns = data and data.kerns
local kern = (kerns and kerns[char] or 0) + quaddata[font]*krn
insert_node_before(head,start,kern_injector(fillup,kern))
+ done = true
end
else
insert_node_before(head,start,kern_injector(fillup,quaddata[font]*krn))
+ done = true
end
end
prev = start
prevchar = char
prevfont = font
prevmark = mark
- previd = glyph_code -- id
+ previd = id
bound = true
elseif id == disc_code then
local prev, next, pglyph, nglyph -- delayed till needed
local subtype = getsubtype(start)
- -- if subtype == automaticdisc_code then
+ -- if subtype == automatic_code then
-- -- this is kind of special, as we have already injected the
-- -- previous kern
-- local prev = getprev(start)
-- local pglyph = prev and getid(prev) == glyph_code
-- languages.expand(start,pglyph and prev)
-- -- we can have a different start now
- -- elseif subtype ~= discretionarydisc_code then
+ -- elseif subtype ~= discretionary_code then
-- prev = getprev(start)
-- pglyph = prev and getid(prev) == glyph_code
-- languages.expand(start,pglyph and prev)
@@ -731,6 +514,7 @@ function kerns.handler(head)
end
if indeed then
setdisc(start,pre,post,replace)
+ done = true
end
bound = false
elseif id == kern_code then
@@ -752,20 +536,23 @@ function kerns.handler(head)
-- shrink_order = 1 ?
end
setglue(start,w,stretch,shrink,stretch_order,shrink_order)
+ done = true
end
end
bound = false
elseif id == hlist_code or id == vlist_code then
local subtype = getsubtype(start)
- if subtype == unknownlist_code or subtype == boxlist_code then
+ if subtype == user_list_code or subtype == box_list_code then
-- special case
local b, f = closest_bound(start,getprev)
if b then
insert_node_before(head,start,kern_injector(fillup,quaddata[f]*krn))
+ done = true
end
local b, f = closest_bound(start,getnext)
if b then
insert_node_after(head,start,kern_injector(fillup,quaddata[f]*krn))
+ done = true
end
end
bound = false
@@ -776,20 +563,17 @@ function kerns.handler(head)
if start then
start = getnext(start)
end
+ elseif id == kern_code then
+ bound = getsubtype(start) == fontkern_code
+ prev = start
+ previd = id
+ start = getnext(start)
else
- local id = getid(start)
- if id == kern_code then
- bound = getsubtype(start) == fontkern_code
- prev = start
- previd = id
- start = getnext(start)
- else
- bound = false
- start = getnext(start)
- end
+ bound = false
+ start = getnext(start)
end
end
- return head
+ return tonode(head), done
end
local enabled = false