From b14f992ef5f4e868c9959b174278c86516d60dbc Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Fri, 17 Feb 2017 10:31:56 +0100 Subject: 2017-02-17 10:23:00 --- tex/context/base/mkiv/typo-krn.lua | 111 +++++++++++++------------------------ 1 file changed, 39 insertions(+), 72 deletions(-) (limited to 'tex/context/base/mkiv/typo-krn.lua') diff --git a/tex/context/base/mkiv/typo-krn.lua b/tex/context/base/mkiv/typo-krn.lua index 6a2aed9a2..24a91d6b6 100644 --- a/tex/context/base/mkiv/typo-krn.lua +++ b/tex/context/base/mkiv/typo-krn.lua @@ -14,7 +14,8 @@ local next, type, tonumber = next, type, tonumber local nodes = nodes local fonts = fonts -local tasks = nodes.tasks +local enableaction = nodes.tasks.enableaction + local nuts = nodes.nuts local nodepool = nuts.pool @@ -28,23 +29,27 @@ 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 @@ -105,10 +110,6 @@ local report = logs.reporter("kerns") 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) --- 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) - kerns.mapping = kerns.mapping or { } kerns.factors = kerns.factors or { } local a_kerns = attributes.private("kern") @@ -232,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 @@ -269,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 @@ -284,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 @@ -320,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 @@ -383,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 @@ -395,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) - flush_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) @@ -438,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 @@ -451,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 @@ -485,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 @@ -502,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 @@ -517,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 @@ -539,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 @@ -554,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 @@ -617,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] -- cgit v1.2.3