diff options
author | Context Git Mirror Bot <phg42.2a@gmail.com> | 2014-05-03 13:55:34 +0200 |
---|---|---|
committer | Context Git Mirror Bot <phg42.2a@gmail.com> | 2014-05-03 13:55:34 +0200 |
commit | 624cbb5da392e9403984dd1cf368c0d408b1c2a8 (patch) | |
tree | 489c049ac849bb5bbce7d32e4df477872c58373d /tex/context/base/typo-krn.lua | |
parent | 088de88944c1f2254250bb448c7371a87ff7ee39 (diff) | |
download | context-624cbb5da392e9403984dd1cf368c0d408b1c2a8.tar.gz |
2014-01-03 00:42:00
Diffstat (limited to 'tex/context/base/typo-krn.lua')
-rw-r--r-- | tex/context/base/typo-krn.lua | 192 |
1 files changed, 88 insertions, 104 deletions
diff --git a/tex/context/base/typo-krn.lua b/tex/context/base/typo-krn.lua index a8ffe557b..56f58bb73 100644 --- a/tex/context/base/typo-krn.lua +++ b/tex/context/base/typo-krn.lua @@ -13,36 +13,21 @@ local utfchar = utf.char local nodes, node, fonts = nodes, node, fonts -local tasks = nodes.tasks -local nuts = nodes.nuts -local nodepool = nuts.pool - -local tonode = nuts.tonode -local tonut = nuts.tonut - -local find_node_tail = nuts.tail -local free_node = nuts.free -local free_nodelist = nuts.flush_list -local copy_node = nuts.copy -local copy_nodelist = nuts.copy_list -local insert_node_before = nuts.insert_before -local insert_node_after = nuts.insert_after -local end_of_math = nuts.end_of_math - -local getfield = nuts.getfield -local setfield = nuts.setfield -local getnext = nuts.getnext -local getprev = nuts.getprev -local getid = nuts.getid -local getattr = nuts.getattr -local setattr = nuts.setattr -local getfont = nuts.getfont -local getsubtype = nuts.getsubtype -local getchar = nuts.getchar +local find_node_tail = node.tail or node.slide +local free_node = node.free +local free_nodelist = node.flush_list +local copy_node = node.copy +local copy_nodelist = node.copy_list +local insert_node_before = node.insert_before +local insert_node_after = node.insert_after +local end_of_math = node.end_of_math local texsetattribute = tex.setattribute local unsetvalue = attributes.unsetvalue +local nodepool = nodes.pool +local tasks = nodes.tasks + local new_gluespec = nodepool.gluespec local new_kern = nodepool.kern local new_glue = nodepool.glue @@ -122,10 +107,10 @@ kerns.keeptogether = false -- just for fun (todo: control setting with key/value -- blue : keep by goodie function kerns.keepligature(n) -- might become default - local f = getfont(n) - local a = getattr(n,0) or 0 + local f = n.font + local a = n[0] or 0 if trace_ligatures then - local c = getchar(n) + local c = n.char 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") @@ -184,9 +169,9 @@ end local function kern_injector(fillup,kern) if fillup then local g = new_glue(kern) - local s = getfield(g,"spec") - setfield(s,"stretch",kern) - setfield(s,"stretch_order",1) + local s = g.spec + s.stretch = kern + s.stretch_order = 1 return g else return new_kern(kern) @@ -196,7 +181,7 @@ end local function spec_injector(fillup,width,stretch,shrink) if fillup then local s = new_gluespec(width,2*stretch,2*shrink) - setfield(s,"stretch_order",1) + s.stretch_order = 1 return s else return new_gluespec(width,stretch,shrink) @@ -212,9 +197,9 @@ local function do_process(head,force) -- todo: glue so that we can fully stretch local fillup = false while start do -- faster to test for attr first - local attr = force or getattr(start,a_kerns) + local attr = force or start[a_kerns] if attr and attr > 0 then - setattr(start,a_kerns,unsetvalue) + start[a_kerns] = unsetvalue local krn = mapping[attr] if krn == v_max then krn = .25 @@ -223,10 +208,10 @@ local function do_process(head,force) -- todo: glue so that we can fully stretch fillup = false end if krn and krn ~= 0 then - local id = getid(start) - if id == glyph_code then -- we could use the subtype ligature - lastfont = getfont(start) - local c = getfield(start,"components") + local id = start.id + if id == glyph_code then + lastfont = start.font + local c = start.components if not c then -- fine elseif keepligature and keepligature(start) then @@ -234,47 +219,47 @@ local function do_process(head,force) -- todo: glue so that we can fully stretch else c = do_process(c,attr) local s = start - local p, n = getprev(s), getnext(s) + local p, n = s.prev, s.next local tail = find_node_tail(c) if p then - setfield(p,"next",c) - setfield(c,"prev",p) + p.next = c + c.prev = p else head = c end if n then - setfield(n,"prev",tail) + n.prev = tail end - setfield(tail,"next",n) + tail.next = n start = c - setfield(s,"components",nil) + s.components = nil -- we now leak nodes ! - -- free_node(s) + -- free_node(s) done = true end - local prev = getprev(start) + local prev = start.prev if not prev then -- skip - elseif markdata[lastfont][getchar(start)] then + elseif markdata[lastfont][start.char] then -- skip else - local pid = getid(prev) + local pid = prev.id if not pid then -- nothing elseif pid == kern_code then - if getsubtype(prev) == kerning_code or getattr(prev,a_fontkern) then - if keeptogether and getid(getprev(prev)) == glyph_code and keeptogether(getprev(prev),start) then -- we could also pass start + if prev.subtype == kerning_code or prev[a_fontkern] then + if keeptogether and prev.prev.id == glyph_code and keeptogether(prev.prev,start) then -- we could also pass start -- keep 'm else -- not yet ok, as injected kerns can be overlays (from node-inj.lua) - setfield(prev,"subtype",userkern_code) - setfield(prev,"kern",getfield(prev,"kern") + quaddata[lastfont]*krn) -- here + prev.subtype = userkern_code + prev.kern = prev.kern + quaddata[lastfont]*krn -- here done = true end end elseif pid == glyph_code then - if getfont(prev) == lastfont then - local prevchar, lastchar = getchar(prev), getchar(start) + if prev.font == lastfont then + local prevchar, lastchar = prev.char, start.char if keeptogether and keeptogether(prev,start) then -- keep 'm else @@ -293,102 +278,102 @@ local function do_process(head,force) -- todo: glue so that we can fully stretch -- a bit too complicated, we can best not copy and just calculate -- but we could have multiple glyphs involved so ... local disc = prev -- disc - local prv, nxt = getprev(disc), getnext(disc) - if getsubtype(disc) == discretionary_code then + local prv, nxt = disc.prev, disc.next + if disc.subtype == discretionary_code then -- maybe we should forget about this variant as there is no glue -- possible - local pre, post, replace = getfield(disc,"pre"), getfield(disc,"post"), getfield(disc,"replace") - if pre and prv then -- must pair with getprev(start) + local pre, post, replace = disc.pre, disc.post, disc.replace + if pre and prv then -- must pair with start.prev + -- this one happens in most cases local before = copy_node(prv) - setfield(pre,"prev",before) - setfield(before,"next",pre) - setfield(before,"prev",nil) + pre.prev = before + before.next = pre + before.prev = nil pre = do_process(before,attr) - pre = getnext(pre) - setfield(pre,"prev",nil) - setfield(disc,"pre",pre) + pre = pre.next + pre.prev = nil + disc.pre = pre free_node(before) end if post and nxt then -- must pair with start local after = copy_node(nxt) local tail = find_node_tail(post) - setfield(tail,"next",after) - setfield(after,"prev",tail) - setfield(after,"next",nil) + tail.next = after + after.prev = tail + after.next = nil post = do_process(post,attr) - setfield(tail,"next",nil) - setfield(disc,"post",post) + tail.next = nil + disc.post = post free_node(after) end if replace and prv and nxt then -- must pair with start and start.prev local before = copy_node(prv) local after = copy_node(nxt) local tail = find_node_tail(replace) - setfield(replace,"prev",before) - setfield(before,"next",replace) - setfield(before,"prev",nil) - setfield(tail,"next",after) - setfield(after,"prev",tail) - setfield(after,"next",nil) + replace.prev = before + before.next = replace + before.prev = nil + tail.next = after + after.prev = tail + after.next = nil replace = do_process(before,attr) - replace = getnext(replace) - setfield(replace,"prev",nil) - setfield(getfield(after,"prev"),"next",nil) - setfield(disc,"replace",replace) + replace = replace.next + replace.prev = nil + after.prev.next = nil + disc.replace = replace free_node(after) free_node(before) - elseif prv and getid(prv) == glyph_code and getfont(prv) == lastfont then - local prevchar, lastchar = getchar(prv), getchar(start) + elseif prv and prv.id == glyph_code and prv.font == lastfont then + local prevchar, lastchar = prv.char, start.char local kerns = chardata[lastfont][prevchar].kerns local kern = kerns and kerns[lastchar] or 0 krn = kern + quaddata[lastfont]*krn -- here - setfield(disc,"replace",kern_injector(false,krn)) -- only kerns permitted, no glue + disc.replace = kern_injector(false,krn) -- only kerns permitted, no glue else krn = quaddata[lastfont]*krn -- here - setfield(disc,"replace",kern_injector(false,krn)) -- only kerns permitted, no glue + disc.replace = kern_injector(false,krn) -- only kerns permitted, no glue end else -- this one happens in most cases: automatic (-), explicit (\-), regular (patterns) - if prv and getid(prv) == glyph_code and getfont(prv) == lastfont then - -- the normal case - local prevchar, lastchar = getchar(prv), getchar(start) + if prv and prv.id == glyph_code and prv.font == lastfont then + local prevchar, lastchar = prv.char, start.char local kerns = chardata[lastfont][prevchar].kerns local kern = kerns and kerns[lastchar] or 0 - krn = kern + quaddata[lastfont]*krn + krn = kern + quaddata[lastfont]*krn -- here else - krn = quaddata[lastfont]*krn + krn = quaddata[lastfont]*krn -- here end insert_node_before(head,start,kern_injector(fillup,krn)) end end end elseif id == glue_code then - local subtype = getsubtype(start) + local subtype = start.subtype if subtype == userskip_code or subtype == xspaceskip_code or subtype == spaceskip_code then - local s = getfield(start,"spec") - local w = getfield(s,"width") + local s = start.spec + local w = s.width if w > 0 then - local width, stretch, shrink = w+gluefactor*w*krn, getfield(s,"stretch"), getfield(s,"shrink") - setfield(start,"spec",spec_injector(fillup,width,stretch*width/w,shrink*width/w)) + local width, stretch, shrink = w+gluefactor*w*krn, s.stretch, s.shrink + start.spec = spec_injector(fillup,width,stretch*width/w,shrink*width/w) done = true end end elseif id == kern_code then - -- if getsubtype(start) == kerning_code then -- handle with glyphs - -- local sk = getfield(start,"kern") + -- if start.subtype == kerning_code then -- handle with glyphs + -- local sk = start.kern -- if sk > 0 then - -- setfield(start,"kern",sk*krn) + -- start.kern = sk*krn -- done = true -- end -- end elseif lastfont and (id == hlist_code or id == vlist_code) then -- todo: lookahead - local p = getprev(start) - if p and getid(p) ~= glue_code then + local p = start.prev + if p and p.id ~= glue_code then insert_node_before(head,start,kern_injector(fillup,quaddata[lastfont]*krn)) done = true end - local n = getnext(start) - if n and getid(n) ~= glue_code then + local n = start.next + if n and n.id ~= glue_code then insert_node_after(head,start,kern_injector(fillup,quaddata[lastfont]*krn)) done = true end @@ -398,7 +383,7 @@ local function do_process(head,force) -- todo: glue so that we can fully stretch end end if start then - start = getnext(start) + start = start.next end end return head, done @@ -429,8 +414,7 @@ function kerns.set(factor) end function kerns.handler(head) - local head, done = do_process(tonut(head)) -- no direct map, because else fourth argument is tail == true - return tonode(head), done + return do_process(head) -- no direct map, because else fourth argument is tail == true end -- interface |