diff options
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.lua | 314 |
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 |