From d1c8ea4d4e53f7304a768048b1c718a30bd9e7f4 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Fri, 8 Jul 2016 08:19:44 +0200 Subject: [fontloader] sync with Context as of 2016-07-14 --- src/fontloader/misc/fontloader-font-otj.lua | 73 ++++++++--- src/fontloader/misc/fontloader-font-ots.lua | 137 ++++++++++++--------- src/fontloader/misc/fontloader-mplib.lua | 22 ++-- src/fontloader/runtime/fontloader-reference.lua | 155 ++++++++++++++++-------- 4 files changed, 252 insertions(+), 135 deletions(-) (limited to 'src/fontloader') diff --git a/src/fontloader/misc/fontloader-font-otj.lua b/src/fontloader/misc/fontloader-font-otj.lua index d1408fd..46b2ca8 100644 --- a/src/fontloader/misc/fontloader-font-otj.lua +++ b/src/fontloader/misc/fontloader-font-otj.lua @@ -36,7 +36,7 @@ local registertracker = trackers.register local trace_injections = false registertracker("fonts.injections", function(v) trace_injections = v end) local trace_marks = false registertracker("fonts.injections.marks", function(v) trace_marks = v end) local trace_cursive = false registertracker("fonts.injections.cursive", function(v) trace_cursive = v end) -local trace_spaces = false registertracker("otf.spaces", function(v) trace_spaces = v end) +local trace_spaces = false registertracker("fonts.injections.spaces", function(v) trace_spaces = v end) -- use_advance is just an experiment: it makes copying glyphs (instead of new_glyph) dangerous @@ -1092,6 +1092,10 @@ local function inject_everything(head,where) nofmarks = nofmarks + 1 marks[nofmarks] = current else +local yoffset = i.yoffset +if yoffset and yoffset ~= 0 then + setfield(current,"yoffset",yoffset) +end if hascursives then local cursivex = i.cursivex if cursivex then @@ -1144,10 +1148,10 @@ local function inject_everything(head,where) end end -- left|glyph|right - local yoffset = i.yoffset - if yoffset and yoffset ~= 0 then - setfield(current,"yoffset",yoffset) - end +-- local yoffset = i.yoffset +-- if yoffset and yoffset ~= 0 then +-- setfield(current,"yoffset",yoffset) +-- end local leftkern = i.leftkern if leftkern and leftkern ~= 0 then insert_node_before(head,current,newkern(leftkern)) @@ -1422,6 +1426,48 @@ function nodes.injections.setspacekerns(font,sequence) end end +local getthreshold + +if context then + + local threshold = 1 -- todo: add a few methods for context + local parameters = fonts.hashes.parameters + + directives.register("otf.threshold", function(v) threshold = tonumber(v) or 1 end) + + getthreshold = function(font) + local p = parameters[font] + local f = p.factor + local s = p.spacing + local t = threshold * (s and s.width or p.space or 0) - 2 + return t > 0 and t or 0, f + end + +else + + injections.threshold = 0 + + getthreshold = function(font) + local p = fontdata[font].parameters + local f = p.factor + local s = p.spacing + local t = injections.threshold * (s and s.width or p.space or 0) - 2 + return t > 0 and t or 0, f + end + +end + +injections.getthreshold = getthreshold + +function injections.isspace(n,threshold) + if getid(n) == glue_code then + local w = getfield(n,"width") + if threshold and w > threshold then -- was >= + return 32 + end + end +end + local function injectspaces(head) if not triggers then @@ -1438,18 +1484,11 @@ local function injectspaces(head) local rightkern = false local function updatefont(font,trig) - -- local resources = resources[font] - -- local spacekerns = resources.spacekerns - -- if spacekerns then - -- leftkerns = spacekerns.left - -- rightkerns = spacekerns.right - -- end leftkerns = trig.left rightkerns = trig.right - local par = fontdata[font].parameters -- fallback for generic - factor = par.factor - threshold = par.spacing.width - 1 -- get rid of rounding errors lastfont = font + threshold, + factor = getthreshold(font) end for n in traverse_id(glue_code,tonut(head)) do @@ -1469,7 +1508,7 @@ local function injectspaces(head) end end if prevchar then - local font = getfont(next) + local font = getfont(prev) local trig = triggers[font] if trig then if lastfont ~= font then @@ -1482,7 +1521,7 @@ local function injectspaces(head) end if leftkern then local old = getfield(n,"width") - if old >= threshold then + if old > threshold then if rightkern then local new = old + (leftkern + rightkern) * factor if trace_spaces then @@ -1501,7 +1540,7 @@ local function injectspaces(head) leftkern = false elseif rightkern then local old = getfield(n,"width") - if old >= threshold then + if old > threshold then local new = old + rightkern * factor if trace_spaces then report_spaces("[%p -> %p] %C",nextchar,old,new) diff --git a/src/fontloader/misc/fontloader-font-ots.lua b/src/fontloader/misc/fontloader-font-ots.lua index d63d524..0f38508 100644 --- a/src/fontloader/misc/fontloader-font-ots.lua +++ b/src/fontloader/misc/fontloader-font-ots.lua @@ -134,12 +134,8 @@ local trace_discruns = false registertracker("otf.discruns", function(v local trace_compruns = false registertracker("otf.compruns", function(v) trace_compruns = v end) local trace_testruns = false registertracker("otf.testruns", function(v) trace_testruns = v end) -local quit_on_no_replacement = true -- maybe per font -local zwnjruns = true -local optimizekerns = true - -registerdirective("otf.zwnjruns", function(v) zwnjruns = v end) -registerdirective("otf.chain.quitonnoreplacement",function(value) quit_on_no_replacement = value end) +----- zwnjruns = true registerdirective("otf.zwnjruns", function(v) zwnjruns = v end) +local optimizekerns = true local report_direct = logs.reporter("fonts","otf direct") local report_subchain = logs.reporter("fonts","otf subchain") @@ -239,6 +235,7 @@ local cursonce = true local fonthashes = fonts.hashes local fontdata = fonthashes.identifiers +local fontfeatures = fonthashes.features local otffeatures = fonts.constructors.features.otf local registerotffeature = otffeatures.register @@ -269,16 +266,8 @@ local notmatchreplace = { } local handlers = { } --- helper - -local function isspace(n) - if getid(n) == glue_code then - local w = getfield(n,"width") - if w >= threshold then - return 32 - end - end -end +local isspace = injections.isspace +local getthreshold = injections.getthreshold -- we use this for special testing and documentation @@ -605,7 +594,7 @@ end return head, base end -local function multiple_glyphs(head,start,multiple,ignoremarks) +local function multiple_glyphs(head,start,multiple,ignoremarks,what) local nofmultiples = #multiple if nofmultiples > 0 then resetinjection(start) @@ -613,17 +602,29 @@ local function multiple_glyphs(head,start,multiple,ignoremarks) if nofmultiples > 1 then local sn = getnext(start) for k=2,nofmultiples do --- untested: --- --- while ignoremarks and marks[getchar(sn)] then --- local sn = getnext(sn) --- end + -- untested: + -- + -- while ignoremarks and marks[getchar(sn)] then + -- local sn = getnext(sn) + -- end local n = copy_node(start) -- ignore components resetinjection(n) setchar(n,multiple[k]) insert_node_after(head,start,n) start = n end + if what == true then + -- we're ok + elseif what > 1 then + local m = multiple[nofmultiples] + for i=2,what do + local n = copy_node(start) -- ignore components + resetinjection(n) + setchar(n,m) + insert_node_after(head,start,n) + start = n + end + end end return head, start, true else @@ -705,7 +706,7 @@ function handlers.gsub_multiple(head,start,dataset,sequence,multiple) if trace_multiples then logprocess("%s: replacing %s by multiple %s",pref(dataset,sequence),gref(getchar(start)),gref(multiple)) end - return multiple_glyphs(head,start,multiple,sequence.flags[1]) + return multiple_glyphs(head,start,multiple,sequence.flags[1],dataset[1]) end function handlers.gsub_ligature(head,start,dataset,sequence,ligature) @@ -1237,7 +1238,7 @@ function chainprocs.gsub_multiple(head,start,stop,dataset,sequence,currentlookup if trace_multiples then logprocess("%s: replacing %s by multiple characters %s",cref(dataset,sequence),gref(startchar),gref(replacement)) end - return multiple_glyphs(head,start,replacement,sequence.flags[1]) + return multiple_glyphs(head,start,replacement,sequence.flags[1],dataset[1]) end return head, start, false end @@ -1262,7 +1263,7 @@ function chainprocs.gsub_alternate(head,start,stop,dataset,sequence,currentlooku end local kind = dataset[4] local what = dataset[1] - local value = what == true and tfmdata.shared.features[kind] or what + local value = what == true and tfmdata.shared.features[kind] or what -- todo: optimize in ctx local current = start while current do local currentchar = ischar(current) @@ -2295,16 +2296,13 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) end -- maybe only if match prev = getprev(prev) - elseif seq[n][32] then + elseif seq[n][32] and isspace(prev,threshold) then n = n - 1 prev = getprev(prev) else match = false break end - elseif seq[n][32] then -- somewhat special, as zapfino can have many preceding spaces - n = n - 1 - prev = getprev(prev) -- was absent else match = false break @@ -2424,15 +2422,13 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) end -- maybe only if match current = getnext(current) - elseif seq[n][32] then -- brrr + elseif seq[n][32] and isspace(current,threshold) then n = n + 1 + current = getnext(current) else match = false break end - elseif seq[n][32] then - n = n + 1 - current = getnext(current) else match = false break @@ -2545,7 +2541,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) if replacements then head, start, done = reversesub(head,start,last,dataset,sequence,replacements,rlmode) else - done = quit_on_no_replacement -- can be meant to be skipped / quite inconsistent in fonts + done = true if trace_contexts then logprocess("%s: skipping match",cref(dataset,sequence)) end @@ -2728,10 +2724,10 @@ local function kernrun(disc,k_run,font,attr,...) end end -- - if prev and (pre or replace) and not ischar(prev,font) then + if prev and not ischar(prev,font) then -- and (pre or replace) prev = false end - if next and (post or replace) and not ischar(next,font) then + if next and not ischar(next,font) then -- and (post or replace) next = false end -- @@ -3306,13 +3302,13 @@ local function featuresprocessor(head,font,attr) if nesting == 1 then - currentfont = font - tfmdata = fontdata[font] - descriptions = tfmdata.descriptions - characters = tfmdata.characters - marks = tfmdata.resources.marks - factor = tfmdata.parameters.factor - threshold = tfmdata.parameters.spacing.width or 65536*10 + currentfont = font + tfmdata = fontdata[font] + descriptions = tfmdata.descriptions + characters = tfmdata.characters + marks = tfmdata.resources.marks + threshold, + factor = getthreshold(font) elseif currentfont ~= font then @@ -3371,15 +3367,12 @@ local function featuresprocessor(head,font,attr) local nofsteps = sequence.nofsteps if not steps then -- this permits injection, watch the different arguments - local h, d, ok = handler(head,start,dataset,sequence,nil,nil,nil,0,font,attr) + local h, d, ok = handler(head,head,dataset,sequence,nil,nil,nil,0,font,attr) if ok then success = true if h then head = h end - if d then - start = d - end end elseif typ == "gsub_reversecontextchain" then -- this is a limited case, no special treatments like 'init' etc @@ -3596,12 +3589,29 @@ otf.handlers = handlers -- used in devanagari local setspacekerns = nodes.injections.setspacekerns if not setspacekerns then os.exit() end -function otf.handlers.trigger_space_kerns(head,start,dataset,sequence,_,_,_,_,font,attr) - -- if not setspacekerns then - -- setspacekerns = nodes.injections.setspacekerns - -- end - setspacekerns(font,sequence) - return head, start, true +if fontfeatures then + + function otf.handlers.trigger_space_kerns(head,start,dataset,sequence,_,_,_,_,font,attr) + local features = fontfeatures[font] + local enabled = features.spacekern == true and features.kern == true + if enabled then + setspacekerns(font,sequence) + end + return head, start, enabled + end + +else -- generic (no hashes) + + function otf.handlers.trigger_space_kerns(head,start,dataset,sequence,_,_,_,_,font,attr) + local shared = fontdata[font].shared + local features = shared and shared.features + local enabled = features and features.spacekern == true and features.kern == true + if enabled then + setspacekerns(font,sequence) + end + return head, start, enabled + end + end local function hasspacekerns(data) @@ -3636,11 +3646,13 @@ otf.readers.registerextender { end } +-- we merge the lookups but we still honor the language / script + local function spaceinitializer(tfmdata,value) -- attr local resources = tfmdata.resources local spacekerns = resources and resources.spacekerns - if spacekerns == nil then - local properties = tfmdata.properties + local properties = tfmdata.properties + if value and spacekerns == nil then if properties and properties.hasspacekerns then local sequences = resources.sequences local left = { } @@ -3653,7 +3665,20 @@ local function spaceinitializer(tfmdata,value) -- attr if steps then local kern = sequence.features.kern if kern then - feat = feat or kern -- or maybe merge + if feat then + for script, languages in next, kern do + local f = feat[k] + if f then + for l in next, languages do + f[l] = true + end + else + feat[script] = languages + end + end + else + feat = kern + end for i=1,#steps do local step = steps[i] local coverage = step.coverage diff --git a/src/fontloader/misc/fontloader-mplib.lua b/src/fontloader/misc/fontloader-mplib.lua index fd6eb97..976bb59 100644 --- a/src/fontloader/misc/fontloader-mplib.lua +++ b/src/fontloader/misc/fontloader-mplib.lua @@ -352,7 +352,7 @@ else return not (sx==1 and rx==0 and ry==0 and sy==1 and tx==0 and ty==0), t.width end - local function concat(px, py) -- no tx, ty here + local function concatinated(px, py) -- no tx, ty here return (sy*px-ry*py)/divider,(sx*py-rx*px)/divider end @@ -401,29 +401,29 @@ else for i=1,#path do pth = path[i] if not ith then - pdf_literalcode("%f %f m",concat(pth.x_coord,pth.y_coord)) + pdf_literalcode("%f %f m",concatinated(pth.x_coord,pth.y_coord)) elseif curved(ith,pth) then - local a, b = concat(ith.right_x,ith.right_y) - local c, d = concat(pth.left_x,pth.left_y) - pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concat(pth.x_coord, pth.y_coord)) + local a, b = concatinated(ith.right_x,ith.right_y) + local c, d = concatinated(pth.left_x,pth.left_y) + pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concatinated(pth.x_coord, pth.y_coord)) else - pdf_literalcode("%f %f l",concat(pth.x_coord, pth.y_coord)) + pdf_literalcode("%f %f l",concatinated(pth.x_coord, pth.y_coord)) end ith = pth end if not open then local one = path[1] if curved(pth,one) then - local a, b = concat(pth.right_x,pth.right_y) - local c, d = concat(one.left_x,one.left_y) - pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concat(one.x_coord, one.y_coord)) + local a, b = concatinated(pth.right_x,pth.right_y) + local c, d = concatinated(one.left_x,one.left_y) + pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concatinated(one.x_coord, one.y_coord)) else - pdf_literalcode("%f %f l",concat(one.x_coord,one.y_coord)) + pdf_literalcode("%f %f l",concatinated(one.x_coord,one.y_coord)) end elseif #path == 1 then -- special case .. draw point local one = path[1] - pdf_literalcode("%f %f l",concat(one.x_coord,one.y_coord)) + pdf_literalcode("%f %f l",concatinated(one.x_coord,one.y_coord)) end return t end diff --git a/src/fontloader/runtime/fontloader-reference.lua b/src/fontloader/runtime/fontloader-reference.lua index 59e985d..e6738ea 100644 --- a/src/fontloader/runtime/fontloader-reference.lua +++ b/src/fontloader/runtime/fontloader-reference.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date : 07/01/16 16:28:20 +-- merge date : 07/13/16 15:09:54 do -- begin closure to overcome local limits and interference @@ -16267,7 +16267,7 @@ local registertracker=trackers.register local trace_injections=false registertracker("fonts.injections",function(v) trace_injections=v end) local trace_marks=false registertracker("fonts.injections.marks",function(v) trace_marks=v end) local trace_cursive=false registertracker("fonts.injections.cursive",function(v) trace_cursive=v end) -local trace_spaces=false registertracker("otf.spaces",function(v) trace_spaces=v end) +local trace_spaces=false registertracker("fonts.injections.spaces",function(v) trace_spaces=v end) local use_advance=false directives.register("fonts.injections.advance",function(v) use_advance=v end) local report_injections=logs.reporter("fonts","injections") local report_spaces=logs.reporter("fonts","spaces") @@ -17149,6 +17149,10 @@ local function inject_everything(head,where) nofmarks=nofmarks+1 marks[nofmarks]=current else +local yoffset=i.yoffset +if yoffset and yoffset~=0 then + setfield(current,"yoffset",yoffset) +end if hascursives then local cursivex=i.cursivex if cursivex then @@ -17200,10 +17204,6 @@ local function inject_everything(head,where) cursiveanchor=nil end end - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setfield(current,"yoffset",yoffset) - end local leftkern=i.leftkern if leftkern and leftkern~=0 then insert_node_before(head,current,newkern(leftkern)) @@ -17450,6 +17450,37 @@ function nodes.injections.setspacekerns(font,sequence) triggers={ [font]=sequence } end end +local getthreshold +if context then + local threshold=1 + local parameters=fonts.hashes.parameters + directives.register("otf.threshold",function(v) threshold=tonumber(v) or 1 end) + getthreshold=function(font) + local p=parameters[font] + local f=p.factor + local s=p.spacing + local t=threshold*(s and s.width or p.space or 0)-2 + return t>0 and t or 0,f + end +else + injections.threshold=0 + getthreshold=function(font) + local p=fontdata[font].parameters + local f=p.factor + local s=p.spacing + local t=injections.threshold*(s and s.width or p.space or 0)-2 + return t>0 and t or 0,f + end +end +injections.getthreshold=getthreshold +function injections.isspace(n,threshold) + if getid(n)==glue_code then + local w=getfield(n,"width") + if threshold and w>threshold then + return 32 + end + end +end local function injectspaces(head) if not triggers then return head,false @@ -17465,10 +17496,9 @@ local function injectspaces(head) local function updatefont(font,trig) leftkerns=trig.left rightkerns=trig.right - local par=fontdata[font].parameters - factor=par.factor - threshold=par.spacing.width-1 lastfont=font + threshold, + factor=getthreshold(font) end for n in traverse_id(glue_code,tonut(head)) do local prev,next=getboth(n) @@ -17487,7 +17517,7 @@ local function injectspaces(head) end end if prevchar then - local font=getfont(next) + local font=getfont(prev) local trig=triggers[font] if trig then if lastfont~=font then @@ -17500,7 +17530,7 @@ local function injectspaces(head) end if leftkern then local old=getfield(n,"width") - if old>=threshold then + if old>threshold then if rightkern then local new=old+(leftkern+rightkern)*factor if trace_spaces then @@ -17519,7 +17549,7 @@ local function injectspaces(head) leftkern=false elseif rightkern then local old=getfield(n,"width") - if old>=threshold then + if old>threshold then local new=old+rightkern*factor if trace_spaces then report_spaces("[%p -> %p] %C",nextchar,old,new) @@ -17970,11 +18000,7 @@ local trace_kernruns=false registertracker("otf.kernruns",function(v) trace_kern local trace_discruns=false registertracker("otf.discruns",function(v) trace_discruns=v end) local trace_compruns=false registertracker("otf.compruns",function(v) trace_compruns=v end) local trace_testruns=false registertracker("otf.testruns",function(v) trace_testruns=v end) -local quit_on_no_replacement=true -local zwnjruns=true local optimizekerns=true -registerdirective("otf.zwnjruns",function(v) zwnjruns=v end) -registerdirective("otf.chain.quitonnoreplacement",function(value) quit_on_no_replacement=value end) local report_direct=logs.reporter("fonts","otf direct") local report_subchain=logs.reporter("fonts","otf subchain") local report_chain=logs.reporter("fonts","otf chain") @@ -18051,6 +18077,7 @@ local getligaindex=injections.getligaindex local cursonce=true local fonthashes=fonts.hashes local fontdata=fonthashes.identifiers +local fontfeatures=fonthashes.features local otffeatures=fonts.constructors.features.otf local registerotffeature=otffeatures.register local onetimemessage=fonts.loggers.onetimemessage or function() end @@ -18070,14 +18097,8 @@ local notmatchpre={} local notmatchpost={} local notmatchreplace={} local handlers={} -local function isspace(n) - if getid(n)==glue_code then - local w=getfield(n,"width") - if w>=threshold then - return 32 - end - end -end +local isspace=injections.isspace +local getthreshold=injections.getthreshold local checkstep=(nodes and nodes.tracers and nodes.tracers.steppers.check) or function() end local registerstep=(nodes and nodes.tracers and nodes.tracers.steppers.register) or function() end local registermessage=(nodes and nodes.tracers and nodes.tracers.steppers.message) or function() end @@ -18355,7 +18376,7 @@ end end return head,base end -local function multiple_glyphs(head,start,multiple,ignoremarks) +local function multiple_glyphs(head,start,multiple,ignoremarks,what) local nofmultiples=#multiple if nofmultiples>0 then resetinjection(start) @@ -18369,6 +18390,17 @@ local function multiple_glyphs(head,start,multiple,ignoremarks) insert_node_after(head,start,n) start=n end + if what==true then + elseif what>1 then + local m=multiple[nofmultiples] + for i=2,what do + local n=copy_node(start) + resetinjection(n) + setchar(n,m) + insert_node_after(head,start,n) + start=n + end + end end return head,start,true else @@ -18439,7 +18471,7 @@ function handlers.gsub_multiple(head,start,dataset,sequence,multiple) if trace_multiples then logprocess("%s: replacing %s by multiple %s",pref(dataset,sequence),gref(getchar(start)),gref(multiple)) end - return multiple_glyphs(head,start,multiple,sequence.flags[1]) + return multiple_glyphs(head,start,multiple,sequence.flags[1],dataset[1]) end function handlers.gsub_ligature(head,start,dataset,sequence,ligature) local current=getnext(start) @@ -18894,7 +18926,7 @@ function chainprocs.gsub_multiple(head,start,stop,dataset,sequence,currentlookup if trace_multiples then logprocess("%s: replacing %s by multiple characters %s",cref(dataset,sequence),gref(startchar),gref(replacement)) end - return multiple_glyphs(head,start,replacement,sequence.flags[1]) + return multiple_glyphs(head,start,replacement,sequence.flags[1],dataset[1]) end return head,start,false end @@ -18906,7 +18938,7 @@ function chainprocs.gsub_alternate(head,start,stop,dataset,sequence,currentlooku end local kind=dataset[4] local what=dataset[1] - local value=what==true and tfmdata.shared.features[kind] or what + local value=what==true and tfmdata.shared.features[kind] or what local current=start while current do local currentchar=ischar(current) @@ -19847,16 +19879,13 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) end end prev=getprev(prev) - elseif seq[n][32] then + elseif seq[n][32] and isspace(prev,threshold) then n=n-1 prev=getprev(prev) else match=false break end - elseif seq[n][32] then - n=n-1 - prev=getprev(prev) else match=false break @@ -19970,15 +19999,13 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) else end current=getnext(current) - elseif seq[n][32] then + elseif seq[n][32] and isspace(current,threshold) then n=n+1 + current=getnext(current) else match=false break end - elseif seq[n][32] then - n=n+1 - current=getnext(current) else match=false break @@ -20073,7 +20100,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) if replacements then head,start,done=reversesub(head,start,last,dataset,sequence,replacements,rlmode) else - done=quit_on_no_replacement + done=true if trace_contexts then logprocess("%s: skipping match",cref(dataset,sequence)) end @@ -20222,10 +20249,10 @@ local function kernrun(disc,k_run,font,attr,...) break end end - if prev and (pre or replace) and not ischar(prev,font) then + if prev and not ischar(prev,font) then prev=false end - if next and (post or replace) and not ischar(next,font) then + if next and not ischar(next,font) then next=false end if pre then @@ -20651,8 +20678,8 @@ local function featuresprocessor(head,font,attr) descriptions=tfmdata.descriptions characters=tfmdata.characters marks=tfmdata.resources.marks - factor=tfmdata.parameters.factor - threshold=tfmdata.parameters.spacing.width or 65536*10 + threshold, + factor=getthreshold(font) elseif currentfont~=font then report_warning("nested call with a different font, level %s, quitting",nesting) nesting=nesting-1 @@ -20680,15 +20707,12 @@ local function featuresprocessor(head,font,attr) local steps=sequence.steps local nofsteps=sequence.nofsteps if not steps then - local h,d,ok=handler(head,start,dataset,sequence,nil,nil,nil,0,font,attr) + local h,d,ok=handler(head,head,dataset,sequence,nil,nil,nil,0,font,attr) if ok then success=true if h then head=h end - if d then - start=d - end end elseif typ=="gsub_reversecontextchain" then local start=find_node_tail(head) @@ -20873,9 +20897,25 @@ otf.nodemodeinitializer=featuresinitializer otf.featuresprocessor=featuresprocessor otf.handlers=handlers local setspacekerns=nodes.injections.setspacekerns if not setspacekerns then os.exit() end -function otf.handlers.trigger_space_kerns(head,start,dataset,sequence,_,_,_,_,font,attr) - setspacekerns(font,sequence) - return head,start,true +if fontfeatures then + function otf.handlers.trigger_space_kerns(head,start,dataset,sequence,_,_,_,_,font,attr) + local features=fontfeatures[font] + local enabled=features.spacekern==true and features.kern==true + if enabled then + setspacekerns(font,sequence) + end + return head,start,enabled + end +else + function otf.handlers.trigger_space_kerns(head,start,dataset,sequence,_,_,_,_,font,attr) + local shared=fontdata[font].shared + local features=shared and shared.features + local enabled=features and features.spacekern==true and features.kern==true + if enabled then + setspacekerns(font,sequence) + end + return head,start,enabled + end end local function hasspacekerns(data) local sequences=data.resources.sequences @@ -20909,8 +20949,8 @@ otf.readers.registerextender { local function spaceinitializer(tfmdata,value) local resources=tfmdata.resources local spacekerns=resources and resources.spacekerns - if spacekerns==nil then - local properties=tfmdata.properties + local properties=tfmdata.properties + if value and spacekerns==nil then if properties and properties.hasspacekerns then local sequences=resources.sequences local left={} @@ -20923,7 +20963,20 @@ local function spaceinitializer(tfmdata,value) if steps then local kern=sequence.features.kern if kern then - feat=feat or kern + if feat then + for script,languages in next,kern do + local f=feat[k] + if f then + for l in next,languages do + f[l]=true + end + else + feat[script]=languages + end + end + else + feat=kern + end for i=1,#steps do local step=steps[i] local coverage=step.coverage -- cgit v1.2.3