From f070e8b5b193c0ce686d2e6448b53338a499aecf Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Wed, 11 Mar 2015 07:46:44 +0100 Subject: [fontloader] sync with Context as of 2015-03-11 --- src/fontloader/misc/fontloader-font-otf.lua | 2 +- src/fontloader/misc/fontloader-font-tfm.lua | 6 +- src/fontloader/misc/fontloader-fonts-cbk.lua | 13 +- src/fontloader/misc/fontloader-fonts-inj.lua | 385 ++++++++++++---------- src/fontloader/misc/fontloader-fonts-otn.lua | 12 +- src/fontloader/runtime/fontloader-basics-gen.lua | 9 +- src/fontloader/runtime/fontloader-fontloader.lua | 402 +++++++++++++---------- 7 files changed, 460 insertions(+), 369 deletions(-) diff --git a/src/fontloader/misc/fontloader-font-otf.lua b/src/fontloader/misc/fontloader-font-otf.lua index 44ad893..c7e83a4 100644 --- a/src/fontloader/misc/fontloader-font-otf.lua +++ b/src/fontloader/misc/fontloader-font-otf.lua @@ -53,7 +53,7 @@ local otf = fonts.handlers.otf otf.glists = { "gsub", "gpos" } -otf.version = 2.802 -- beware: also sync font-mis.lua +otf.version = 2.803 -- beware: also sync font-mis.lua otf.cache = containers.define("fonts", "otf", otf.version, true) local hashes = fonts.hashes diff --git a/src/fontloader/misc/fontloader-font-tfm.lua b/src/fontloader/misc/fontloader-font-tfm.lua index 49df94e..ab03788 100644 --- a/src/fontloader/misc/fontloader-font-tfm.lua +++ b/src/fontloader/misc/fontloader-font-tfm.lua @@ -72,15 +72,15 @@ local function read_from_tfm(specification) properties.filename = specification.filename properties.format = fonts.formats.tfm -- better than nothing parameters.size = size - shared.rawdata = { } - shared.features = features - shared.processes = next(features) and tfm.setfeatures(tfmdata,features) or nil -- tfmdata.properties = properties tfmdata.resources = resources tfmdata.parameters = parameters tfmdata.shared = shared -- + shared.rawdata = { } + shared.features = features + shared.processes = next(features) and tfm.setfeatures(tfmdata,features) or nil parameters.slant = parameters.slant or parameters[1] or 0 parameters.space = parameters.space or parameters[2] or 0 parameters.space_stretch = parameters.space_stretch or parameters[3] or 0 diff --git a/src/fontloader/misc/fontloader-fonts-cbk.lua b/src/fontloader/misc/fontloader-fonts-cbk.lua index 414cafb..ce19c88 100644 --- a/src/fontloader/misc/fontloader-fonts-cbk.lua +++ b/src/fontloader/misc/fontloader-fonts-cbk.lua @@ -116,13 +116,14 @@ function nodes.handlers.nodepass(head) if basepass and #basefonts > 0 then for i=1,#basefonts do local range = basefonts[i] - local start, stop = range[1], range[2] + local start = range[1] + local stop = range[2] if stop then - ligaturing(start,stop) - kerning(start,stop) - else - ligaturing(start) - kerning(start) + start, stop = ligaturing(start,stop) + start, stop = kerning(start,stop) + elseif start then + start = ligaturing(start) + start = kerning(start) end end end diff --git a/src/fontloader/misc/fontloader-fonts-inj.lua b/src/fontloader/misc/fontloader-fonts-inj.lua index 3b93382..cb9ed89 100644 --- a/src/fontloader/misc/fontloader-fonts-inj.lua +++ b/src/fontloader/misc/fontloader-fonts-inj.lua @@ -14,13 +14,12 @@ if not nodes.properties then return end local next, rawget = next, rawget local utfchar = utf.char +local fastcopy = table.fastcopy local trace_injections = false trackers.register("fonts.injections", function(v) trace_injections = v end) local report_injections = logs.reporter("fonts","injections") -report_injections("using experimental injector") - local attributes, nodes, node = attributes, nodes, node fonts = fonts @@ -81,19 +80,42 @@ function injections.resetcounts() keepregisteredcounts = false end +-- We need to make sure that a possible metatable will not kick in +-- unexpectedly. + function injections.reset(n) - local p = rawget(properties,start) - if p and p.injections then - -- todo: decrement counters? tricky as we then need to change the nof* to not increment - -- when we change a property - p.injections = nil -- should we keep the liga index? + local p = rawget(properties,n) + if p and rawget(p,"injections") then + p.injections = nil + end +end + +function injections.copy(target,source) + local sp = rawget(properties,source) + if sp then + local tp = rawget(properties,target) + local si = rawget(sp,"injections") + if si then + si = fastcopy(si) + if tp then + tp.injections = si + else + propertydata[target] = { + injections = si, + } + end + else + if tp then + tp.injections = nil + end + end end end function injections.setligaindex(n,index) local p = rawget(properties,n) if p then - local i = p.injections + local i = rawget(p,"injections") if i then i.ligaindex = index else @@ -113,9 +135,9 @@ end function injections.getligaindex(n,default) local p = rawget(properties,n) if p then - p = p.injections - if p then - return p.ligaindex or default + local i = rawget(p,"injections") + if i then + return i.ligaindex or default end end return default @@ -134,7 +156,7 @@ function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmne -- local p = rawget(properties,start) if p then - local i = p.injections + local i = rawget(p,"injections") if i then i.cursiveanchor = true else @@ -151,7 +173,7 @@ function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmne end local p = rawget(properties,nxt) if p then - local i = p.injections + local i = rawget(p,"injections") if i then i.cursivex = dx i.cursivey = dy @@ -185,14 +207,16 @@ function injections.setpair(current,factor,rlmode,r2lflag,spec,injection) -- r2l end local p = rawget(properties,current) if p then - local i = p.injections + local i = rawget(p,"injections") if i then - if leftkern ~= 0 or rightkern ~= 0 then - i.leftkern = i.leftkern or 0 + leftkern - i.rightkern = i.rightkern or 0 + rightkern + if leftkern ~= 0 then + i.leftkern = (i.leftkern or 0) + leftkern + end + if rightkern ~= 0 then + i.rightkern = (i.rightkern or 0) + rightkern end if yoffset ~= 0 then - i.yoffset = i.yoffset or 0 + yoffset + i.yoffset = (i.yoffset or 0) + yoffset end elseif leftkern ~= 0 or rightkern ~= 0 then p.injections = { @@ -240,9 +264,9 @@ function injections.setkern(current,factor,rlmode,x,injection) injection = "injections" end if p then - local i = p[injection] + local i = rawget(p,injection) if i then - i.leftkern = dx + i.leftkern or 0 + i.leftkern = dx + (i.leftkern or 0) else p[injection] = { leftkern = dx, @@ -270,7 +294,7 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase) -- ba=basean end local p = rawget(properties,start) if p then - local i = p.injections + local i = rawget(p,"injections") if i then i.markx = dx i.marky = dy @@ -313,18 +337,18 @@ local function show(n,what,nested,symbol) if n then local p = rawget(properties,n) if p then - local p = p[what] - if p then - local leftkern = p.leftkern or 0 - local rightkern = p.rightkern or 0 - local yoffset = p.yoffset or 0 - local markx = p.markx or 0 - local marky = p.marky or 0 - local markdir = p.markdir or 0 - local markbase = p.markbase or 0 -- will be markbasenode - local cursivex = p.cursivex or 0 - local cursivey = p.cursivey or 0 - local ligaindex = p.ligaindex or 0 + local i = rawget(p,what) + if i then + local leftkern = i.leftkern or 0 + local rightkern = i.rightkern or 0 + local yoffset = i.yoffset or 0 + local markx = i.markx or 0 + local marky = i.marky or 0 + local markdir = i.markdir or 0 + local markbase = i.markbase or 0 -- will be markbasenode + local cursivex = i.cursivex or 0 + local cursivey = i.cursivey or 0 + local ligaindex = i.ligaindex or 0 local margin = nested and 4 or 2 -- if rightkern ~= 0 or yoffset ~= 0 then @@ -355,9 +379,9 @@ local function showsub(n,what,where) report_injections("end subrun") end -local function trace(head) - report_injections("begin run: %s kerns, %s pairs, %s marks and %s cursives registered", - nofregisteredkerns,nofregisteredpairs,nofregisteredmarks,nofregisteredcursives) +local function trace(head,where) + report_injections("begin run %s: %s kerns, %s pairs, %s marks and %s cursives registered", + where or "",nofregisteredkerns,nofregisteredpairs,nofregisteredmarks,nofregisteredcursives) local n = head while n do local id = getid(n) @@ -414,10 +438,6 @@ local function collect_glyphs_1(head) local nf, tm = nil, nil for n in traverse_id(glyph_code,head) do -- only needed for relevant fonts if getsubtype(n) < 256 then - local pn = rawget(properties,n) - if pn then - pn = pn.injections - end local f = getfont(n) if f ~= nf then nf = f @@ -431,10 +451,14 @@ local function collect_glyphs_1(head) glyphs[nofglyphs] = n end -- yoffsets can influence curs steps - if pn then - local yoffset = pn.yoffset - if yoffset and yoffset ~= 0 then - setfield(n,"yoffset",yoffset) + local p = rawget(properties,n) + if p then + local i = rawget(p,"injections") + if i then + local yoffset = i.yoffset + if yoffset and yoffset ~= 0 then + setfield(n,"yoffset",yoffset) + end end end end @@ -470,18 +494,20 @@ local function inject_marks(marks,nofmarks) local n = marks[i] local pn = rawget(properties,n) if pn then - pn = pn.injections - end - if pn then - -- local markbase = pn.markbase - -- if markbase then - -- local p = markanchors[markbase] + pn = rawget(pn,"injections") + if pn then local p = pn.markbasenode if p then local px = getfield(p,"xoffset") local ox = 0 + local rightkern = nil local pp = rawget(properties,p) - local rightkern = pp and pp.rightkern + if pp then + pp = rawget(pp,"injections") + if pp then + rightkern = pp.rightkern + end + end if rightkern then -- x and w ~= 0 if pn.markdir < 0 then -- kern(w-x) glyph(p) kern(x) mark(n) @@ -490,8 +516,13 @@ local function inject_marks(marks,nofmarks) else -- kern(x) glyph(p) kern(w-x) mark(n) -- ox = px - getfield(p,"width") + pn.markx - pp.leftkern - ox = px - pn.markx - pp.leftkern - -- report_injections("l2r case 1: %p",ox) + local leftkern = pp.leftkern + if leftkern then + ox = px - pn.markx + else + ox = px - pn.markx - leftkern + end +-- report_injections("l2r case 1: %p",ox) end else -- we need to deal with fonts that have marks with width @@ -525,10 +556,10 @@ local function inject_marks(marks,nofmarks) end setfield(n,"yoffset",oy) else - -- normally this can't happen (only when in trace mode which is a special case anyway) + -- normally this can't happen (only when in trace mode which is a special case anyway) -- report_injections("missing mark anchor %i",pn.markbase or 0) end - -- end + end end end end @@ -540,14 +571,14 @@ local function inject_cursives(glyphs,nofglyphs) local n = glyphs[i] local pn = rawget(properties,n) if pn then - pn = pn.injections + pn = rawget(pn,"injections") end if pn then local cursivex = pn.cursivex if cursivex then if cursiveanchor then if cursivex ~= 0 then - pn.leftkern = pn.leftkern or 0 + cursivex + pn.leftkern = (pn.leftkern or 0) + cursivex end if lastanchor then if maxc == 0 then @@ -622,16 +653,16 @@ local function inject_kerns(head,glyphs,nofglyphs) local n = glyphs[i] local pn = rawget(properties,n) if pn then - pn = pn.injections - end - if pn then - local leftkern = pn.leftkern - if leftkern ~= 0 then - insert_node_before(head,n,newkern(leftkern)) -- type 0/2 - end - local rightkern = pn.rightkern - if rightkern and rightkern ~= 0 then - insert_node_after(head,n,newkern(rightkern)) -- type 0/2 + local i = rawget(pn,"injections") + if i then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then + insert_node_before(head,n,newkern(leftkern)) -- type 0/2 + end + local rightkern = i.rightkern + if rightkern and rightkern ~= 0 then + insert_node_after(head,n,newkern(rightkern)) -- type 0/2 + end end end end @@ -640,7 +671,7 @@ end local function inject_everything(head,where) head = tonut(head) if trace_injections then - trace(head) + trace(head,"everything") end local glyphs, nofglyphs, marks, nofmarks if nofregisteredpairs > 0 then @@ -652,7 +683,7 @@ local function inject_everything(head,where) if nofregisteredcursives > 0 then inject_cursives(glyphs,nofglyphs) end - if nofregisteredmarks > 0 then + if nofregisteredmarks > 0 then -- and nofmarks > 0 inject_marks(marks,nofmarks) end inject_kerns(head,glyphs,nofglyphs) @@ -671,7 +702,7 @@ end local function inject_kerns_only(head,where) head = tonut(head) if trace_injections then - trace(head) + trace(head,"kerns") end local n = head local p = nil @@ -684,10 +715,10 @@ local function inject_kerns_only(head,where) if p then local d = getfield(p,"post") if d then - local pn = pn.postinjections - if pn then - local leftkern = pn.leftkern - if leftkern ~= 0 then + local i = rawget(pn,"postinjections") + if i then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then local t = find_tail(d) insert_node_after(d,t,newkern(leftkern)) end @@ -695,28 +726,28 @@ local function inject_kerns_only(head,where) end local d = getfield(p,"replace") if d then - local pn = pn.replaceinjections - if pn then - local leftkern = pn.leftkern - if leftkern ~= 0 then + local i = rawget(pn,"replaceinjections") + if i then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then local t = find_tail(d) insert_node_after(d,t,newkern(leftkern)) end end else - local pn = pn.injections - if pn then - local leftkern = pn.leftkern - if leftkern ~= 0 then + local i = rawget(pn,"injections") + if i then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then setfield(p,"replace",newkern(leftkern)) end end end else - local pn = pn.injections - if pn then - local leftkern = pn.leftkern - if leftkern ~= 0 then + local i = rawget(pn,"injections") + if i then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then head = insert_node_before(head,n,newkern(leftkern)) end end @@ -734,12 +765,12 @@ local function inject_kerns_only(head,where) if getsubtype(n) < 256 then local pn = rawget(properties,n) if pn then - pn = pn.preinjections - end - if pn then - local leftkern = pn.leftkern - if leftkern ~= 0 then - h = insert_node_before(h,n,newkern(leftkern)) + local i = rawget(pn,"preinjections") + if i then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then + h = insert_node_before(h,n,newkern(leftkern)) + end end end else @@ -757,12 +788,12 @@ local function inject_kerns_only(head,where) if getsubtype(n) < 256 then local pn = rawget(properties,n) if pn then - pn = pn.postinjections - end - if pn then - local leftkern = pn.leftkern - if leftkern ~= 0 then - h = insert_node_before(h,n,newkern(leftkern)) + local i = rawget(pn,"postinjections") + if i then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then + h = insert_node_before(h,n,newkern(leftkern)) + end end end else @@ -780,12 +811,12 @@ local function inject_kerns_only(head,where) if getsubtype(n) < 256 then local pn = rawget(properties,n) -- why can it be empty { } if pn then - pn = pn.replaceinjections - end - if pn then - local leftkern = pn.leftkern - if leftkern ~= 0 then - h = insert_node_before(h,n,newkern(leftkern)) + local i = rawget(pn,"replaceinjections") + if i then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then + h = insert_node_before(h,n,newkern(leftkern)) + end end end else @@ -814,7 +845,7 @@ end local function inject_pairs_only(head,where) head = tonut(head) if trace_injections then - trace(head) + trace(head,"pairs") end -- local n = head @@ -828,14 +859,14 @@ local function inject_pairs_only(head,where) if p then local d = getfield(p,"post") if d then - local pn = pn.postinjections - if pn then - local leftkern = pn.leftkern - if leftkern ~= 0 then + local i = rawget(pn,"postinjections") + if i then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then local t = find_tail(d) insert_node_after(d,t,newkern(leftkern)) end - -- local rightkern = pn.rightkern + -- local rightkern = i.rightkern -- if rightkern and rightkern ~= 0 then -- insert_node_after(head,n,newkern(rightkern)) -- n = getnext(n) -- to be checked @@ -844,27 +875,27 @@ local function inject_pairs_only(head,where) end local d = getfield(p,"replace") if d then - local pn = pn.replaceinjections - if pn then - local leftkern = pn.leftkern - if leftkern ~= 0 then + local i = rawget(pn,"replaceinjections") + if i then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then local t = find_tail(d) insert_node_after(d,t,newkern(leftkern)) end - -- local rightkern = pn.rightkern + -- local rightkern = i.rightkern -- if rightkern and rightkern ~= 0 then -- insert_node_after(head,n,newkern(rightkern)) -- n = getnext(n) -- to be checked -- end end else - local pn = pn.injections - if pn then - local leftkern = pn.leftkern - if leftkern ~= 0 then + local i = rawget(pn,"injections") + if i then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then setfield(p,"replace",newkern(leftkern)) end - -- local rightkern = pn.rightkern + -- local rightkern = i.rightkern -- if rightkern and rightkern ~= 0 then -- insert_node_after(head,n,newkern(rightkern)) -- n = getnext(n) -- to be checked @@ -873,17 +904,17 @@ local function inject_pairs_only(head,where) end else -- this is the most common case - local pn = pn.injections - if pn then - local yoffset = pn.yoffset + local i = rawget(pn,"injections") + if i then + local yoffset = i.yoffset if yoffset and yoffset ~= 0 then setfield(n,"yoffset",yoffset) end - local leftkern = pn.leftkern - if leftkern ~= 0 then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then insert_node_before(head,n,newkern(leftkern)) end - local rightkern = pn.rightkern + local rightkern = i.rightkern if rightkern and rightkern ~= 0 then insert_node_after(head,n,newkern(rightkern)) n = getnext(n) -- to be checked @@ -901,23 +932,23 @@ local function inject_pairs_only(head,where) local h = d for n in traverse_id(glyph_code,d) do if getsubtype(n) < 256 then - local pn = rawget(properties,n) - if pn then - pn = pn.preinjections - end - if pn then - local yoffset = pn.yoffset - if yoffset and yoffset ~= 0 then - setfield(n,"yoffset",yoffset) - end - local leftkern = pn.leftkern - if leftkern ~= 0 then - h = insert_node_before(h,n,newkern(leftkern)) - end - local rightkern = pn.rightkern - if rightkern and rightkern ~= 0 then - insert_node_after(head,n,newkern(rightkern)) - n = getnext(n) -- to be checked + local p = rawget(properties,n) + if p then + local i = rawget(p,"preinjections") + if i then + local yoffset = i.yoffset + if yoffset and yoffset ~= 0 then + setfield(n,"yoffset",yoffset) + end + local leftkern = i.leftkern + if leftkern ~= 0 then + h = insert_node_before(h,n,newkern(leftkern)) + end + local rightkern = i.rightkern + if rightkern and rightkern ~= 0 then + insert_node_after(head,n,newkern(rightkern)) + n = getnext(n) -- to be checked + end end end else @@ -933,23 +964,23 @@ local function inject_pairs_only(head,where) local h = d for n in traverse_id(glyph_code,d) do if getsubtype(n) < 256 then - local pn = rawget(properties,n) - if pn then - pn = pn.postinjections - end - if pn then - local yoffset = pn.yoffset - if yoffset and yoffset ~= 0 then - setfield(n,"yoffset",yoffset) - end - local leftkern = pn.leftkern - if leftkern ~= 0 then - h = insert_node_before(h,n,newkern(leftkern)) - end - local rightkern = pn.rightkern - if rightkern and rightkern ~= 0 then - insert_node_after(head,n,newkern(rightkern)) - n = getnext(n) -- to be checked + local p = rawget(properties,n) + if p then + local i = rawget(p,"postinjections") + if i then + local yoffset = i.yoffset + if yoffset and yoffset ~= 0 then + setfield(n,"yoffset",yoffset) + end + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then + h = insert_node_before(h,n,newkern(leftkern)) + end + local rightkern = i.rightkern + if rightkern and rightkern ~= 0 then + insert_node_after(head,n,newkern(rightkern)) + n = getnext(n) -- to be checked + end end end else @@ -965,23 +996,23 @@ local function inject_pairs_only(head,where) local h = d for n in traverse_id(glyph_code,d) do if getsubtype(n) < 256 then - local pn = rawget(properties,n) - if pn then - pn = pn.replaceinjections - end - if pn then - local yoffset = pn.yoffset - if yoffset and yoffset ~= 0 then - setfield(n,"yoffset",yoffset) - end - local leftkern = pn.leftkern - if leftkern ~= 0 then - h = insert_node_before(h,n,newkern(leftkern)) - end - local rightkern = pn.rightkern - if rightkern and rightkern ~= 0 then - insert_node_after(head,n,newkern(rightkern)) - n = getnext(n) -- to be checked + local p = rawget(properties,n) + if p then + local i = rawget(pn,"replaceinjections") + if i then + local yoffset = i.yoffset + if yoffset and yoffset ~= 0 then + setfield(n,"yoffset",yoffset) + end + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then + h = insert_node_before(h,n,newkern(leftkern)) + end + local rightkern = i.rightkern + if rightkern and rightkern ~= 0 then + insert_node_after(head,n,newkern(rightkern)) + n = getnext(n) -- to be checked + end end end else diff --git a/src/fontloader/misc/fontloader-fonts-otn.lua b/src/fontloader/misc/fontloader-fonts-otn.lua index 32dc820..3f53078 100644 --- a/src/fontloader/misc/fontloader-fonts-otn.lua +++ b/src/fontloader/misc/fontloader-fonts-otn.lua @@ -6,6 +6,9 @@ if not modules then modules = { } end modules ['font-otn'] = { license = "see context related readme files", } +-- todo: looks like we have a leak somewhere (probably in ligatures) +-- todo: copy attributes to disc + -- this is a context version which can contain experimental code, but when we -- have serious patches we also need to change the other two font-otn files @@ -243,6 +246,7 @@ local setcursive = injections.setcursive local setkern = injections.setkern local setpair = injections.setpair local resetinjection = injections.reset +local copyinjection = injections.copy local setligaindex = injections.setligaindex local getligaindex = injections.getligaindex @@ -354,13 +358,19 @@ local function copy_glyph(g) -- next and prev are untouched ! if components then setfield(g,"components",nil) local n = copy_node(g) + copyinjection(n,g) -- we need to preserve the lig indices setfield(g,"components",components) return n else - return copy_node(g) + local n = copy_node(g) + copyinjection(n,g) -- we need to preserve the lig indices + return n end end +-- + + -- start is a mark and we need to keep that one local function markstoligature(kind,lookupname,head,start,stop,char) diff --git a/src/fontloader/runtime/fontloader-basics-gen.lua b/src/fontloader/runtime/fontloader-basics-gen.lua index e7cdc7b..c4d6536 100644 --- a/src/fontloader/runtime/fontloader-basics-gen.lua +++ b/src/fontloader/runtime/fontloader-basics-gen.lua @@ -15,8 +15,13 @@ local dummyfunction = function() end local dummyreporter = function(c) - return function(...) - (texio.reporter or texio.write_nl)(c .. " : " .. string.formatters(...)) + return function(f,...) + local r = texio.reporter or texio.write_nl + if f then + r(c .. " : " .. string.formatters(f,...)) + else + r("") + end end end diff --git a/src/fontloader/runtime/fontloader-fontloader.lua b/src/fontloader/runtime/fontloader-fontloader.lua index 6500989..b662152 100644 --- a/src/fontloader/runtime/fontloader-fontloader.lua +++ b/src/fontloader/runtime/fontloader-fontloader.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 12/31/14 16:52:11 +-- merge date : 03/10/15 12:09:17 do -- begin closure to overcome local limits and interference @@ -3374,8 +3374,13 @@ end local dummyfunction=function() end local dummyreporter=function(c) - return function(...) - (texio.reporter or texio.write_nl)(c.." : "..string.formatters(...)) + return function(f,...) + local r=texio.reporter or texio.write_nl + if f then + r(c.." : "..string.formatters(f,...)) + else + r("") + end end end statistics={ @@ -5794,13 +5799,13 @@ local function read_from_tfm(specification) properties.filename=specification.filename properties.format=fonts.formats.tfm parameters.size=size - shared.rawdata={} - shared.features=features - shared.processes=next(features) and tfm.setfeatures(tfmdata,features) or nil tfmdata.properties=properties tfmdata.resources=resources tfmdata.parameters=parameters tfmdata.shared=shared + shared.rawdata={} + shared.features=features + shared.processes=next(features) and tfm.setfeatures(tfmdata,features) or nil parameters.slant=parameters.slant or parameters[1] or 0 parameters.space=parameters.space or parameters[2] or 0 parameters.space_stretch=parameters.space_stretch or parameters[3] or 0 @@ -7057,7 +7062,7 @@ local report_otf=logs.reporter("fonts","otf loading") local fonts=fonts local otf=fonts.handlers.otf otf.glists={ "gsub","gpos" } -otf.version=2.802 +otf.version=2.803 otf.cache=containers.define("fonts","otf",otf.version,true) local hashes=fonts.hashes local definers=fonts.definers @@ -9840,9 +9845,9 @@ if not modules then modules={} end modules ['font-inj']={ if not nodes.properties then return end local next,rawget=next,rawget local utfchar=utf.char +local fastcopy=table.fastcopy local trace_injections=false trackers.register("fonts.injections",function(v) trace_injections=v end) local report_injections=logs.reporter("fonts","injections") -report_injections("using experimental injector") local attributes,nodes,node=attributes,nodes,node fonts=fonts local fontdata=fonts.hashes.identifiers @@ -9889,15 +9894,36 @@ function injections.resetcounts() keepregisteredcounts=false end function injections.reset(n) - local p=rawget(properties,start) - if p and p.injections then - p.injections=nil + local p=rawget(properties,n) + if p and rawget(p,"injections") then + p.injections=nil + end +end +function injections.copy(target,source) + local sp=rawget(properties,source) + if sp then + local tp=rawget(properties,target) + local si=rawget(sp,"injections") + if si then + si=fastcopy(si) + if tp then + tp.injections=si + else + propertydata[target]={ + injections=si, + } + end + else + if tp then + tp.injections=nil + end + end end end function injections.setligaindex(n,index) local p=rawget(properties,n) if p then - local i=p.injections + local i=rawget(p,"injections") if i then i.ligaindex=index else @@ -9916,9 +9942,9 @@ end function injections.getligaindex(n,default) local p=rawget(properties,n) if p then - p=p.injections - if p then - return p.ligaindex or default + local i=rawget(p,"injections") + if i then + return i.ligaindex or default end end return default @@ -9935,7 +9961,7 @@ function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmne end local p=rawget(properties,start) if p then - local i=p.injections + local i=rawget(p,"injections") if i then i.cursiveanchor=true else @@ -9952,7 +9978,7 @@ function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmne end local p=rawget(properties,nxt) if p then - local i=p.injections + local i=rawget(p,"injections") if i then i.cursivex=dx i.cursivey=dy @@ -9985,14 +10011,16 @@ function injections.setpair(current,factor,rlmode,r2lflag,spec,injection) end local p=rawget(properties,current) if p then - local i=p.injections + local i=rawget(p,"injections") if i then - if leftkern~=0 or rightkern~=0 then - i.leftkern=i.leftkern or 0+leftkern - i.rightkern=i.rightkern or 0+rightkern + if leftkern~=0 then + i.leftkern=(i.leftkern or 0)+leftkern + end + if rightkern~=0 then + i.rightkern=(i.rightkern or 0)+rightkern end if yoffset~=0 then - i.yoffset=i.yoffset or 0+yoffset + i.yoffset=(i.yoffset or 0)+yoffset end elseif leftkern~=0 or rightkern~=0 then p.injections={ @@ -10034,9 +10062,9 @@ function injections.setkern(current,factor,rlmode,x,injection) injection="injections" end if p then - local i=p[injection] + local i=rawget(p,injection) if i then - i.leftkern=dx+i.leftkern or 0 + i.leftkern=dx+(i.leftkern or 0) else p[injection]={ leftkern=dx, @@ -10062,7 +10090,7 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase) end local p=rawget(properties,start) if p then - local i=p.injections + local i=rawget(p,"injections") if i then i.markx=dx i.marky=dy @@ -10102,18 +10130,18 @@ local function show(n,what,nested,symbol) if n then local p=rawget(properties,n) if p then - local p=p[what] - if p then - local leftkern=p.leftkern or 0 - local rightkern=p.rightkern or 0 - local yoffset=p.yoffset or 0 - local markx=p.markx or 0 - local marky=p.marky or 0 - local markdir=p.markdir or 0 - local markbase=p.markbase or 0 - local cursivex=p.cursivex or 0 - local cursivey=p.cursivey or 0 - local ligaindex=p.ligaindex or 0 + local i=rawget(p,what) + if i then + local leftkern=i.leftkern or 0 + local rightkern=i.rightkern or 0 + local yoffset=i.yoffset or 0 + local markx=i.markx or 0 + local marky=i.marky or 0 + local markdir=i.markdir or 0 + local markbase=i.markbase or 0 + local cursivex=i.cursivex or 0 + local cursivey=i.cursivey or 0 + local ligaindex=i.ligaindex or 0 local margin=nested and 4 or 2 if rightkern~=0 or yoffset~=0 then report_injections("%w%s pair: lx %p, rx %p, dy %p",margin,symbol,leftkern,rightkern,yoffset) @@ -10141,9 +10169,9 @@ local function showsub(n,what,where) end report_injections("end subrun") end -local function trace(head) - report_injections("begin run: %s kerns, %s pairs, %s marks and %s cursives registered", - nofregisteredkerns,nofregisteredpairs,nofregisteredmarks,nofregisteredcursives) +local function trace(head,where) + report_injections("begin run %s: %s kerns, %s pairs, %s marks and %s cursives registered", + where or "",nofregisteredkerns,nofregisteredpairs,nofregisteredmarks,nofregisteredcursives) local n=head while n do local id=getid(n) @@ -10196,10 +10224,6 @@ local function collect_glyphs_1(head) local nf,tm=nil,nil for n in traverse_id(glyph_code,head) do if getsubtype(n)<256 then - local pn=rawget(properties,n) - if pn then - pn=pn.injections - end local f=getfont(n) if f~=nf then nf=f @@ -10212,10 +10236,14 @@ local function collect_glyphs_1(head) nofglyphs=nofglyphs+1 glyphs[nofglyphs]=n end - if pn then - local yoffset=pn.yoffset - if yoffset and yoffset~=0 then - setfield(n,"yoffset",yoffset) + local p=rawget(properties,n) + if p then + local i=rawget(p,"injections") + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setfield(n,"yoffset",yoffset) + end end end end @@ -10249,20 +10277,30 @@ local function inject_marks(marks,nofmarks) local n=marks[i] local pn=rawget(properties,n) if pn then - pn=pn.injections - end - if pn then + pn=rawget(pn,"injections") + if pn then local p=pn.markbasenode if p then local px=getfield(p,"xoffset") local ox=0 + local rightkern=nil local pp=rawget(properties,p) - local rightkern=pp and pp.rightkern + if pp then + pp=rawget(pp,"injections") + if pp then + rightkern=pp.rightkern + end + end if rightkern then if pn.markdir<0 then ox=px-pn.markx-rightkern else - ox=px-pn.markx-pp.leftkern + local leftkern=pp.leftkern + if leftkern then + ox=px-pn.markx + else + ox=px-pn.markx-leftkern + end end else ox=px-pn.markx @@ -10283,6 +10321,7 @@ local function inject_marks(marks,nofmarks) setfield(n,"yoffset",oy) else end + end end end end @@ -10293,14 +10332,14 @@ local function inject_cursives(glyphs,nofglyphs) local n=glyphs[i] local pn=rawget(properties,n) if pn then - pn=pn.injections + pn=rawget(pn,"injections") end if pn then local cursivex=pn.cursivex if cursivex then if cursiveanchor then if cursivex~=0 then - pn.leftkern=pn.leftkern or 0+cursivex + pn.leftkern=(pn.leftkern or 0)+cursivex end if lastanchor then if maxc==0 then @@ -10364,16 +10403,16 @@ local function inject_kerns(head,glyphs,nofglyphs) local n=glyphs[i] local pn=rawget(properties,n) if pn then - pn=pn.injections - end - if pn then - local leftkern=pn.leftkern - if leftkern~=0 then - insert_node_before(head,n,newkern(leftkern)) - end - local rightkern=pn.rightkern - if rightkern and rightkern~=0 then - insert_node_after(head,n,newkern(rightkern)) + local i=rawget(pn,"injections") + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + insert_node_before(head,n,newkern(leftkern)) + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(head,n,newkern(rightkern)) + end end end end @@ -10381,7 +10420,7 @@ end local function inject_everything(head,where) head=tonut(head) if trace_injections then - trace(head) + trace(head,"everything") end local glyphs,nofglyphs,marks,nofmarks if nofregisteredpairs>0 then @@ -10393,7 +10432,7 @@ local function inject_everything(head,where) if nofregisteredcursives>0 then inject_cursives(glyphs,nofglyphs) end - if nofregisteredmarks>0 then + if nofregisteredmarks>0 then inject_marks(marks,nofmarks) end inject_kerns(head,glyphs,nofglyphs) @@ -10411,7 +10450,7 @@ end local function inject_kerns_only(head,where) head=tonut(head) if trace_injections then - trace(head) + trace(head,"kerns") end local n=head local p=nil @@ -10424,10 +10463,10 @@ local function inject_kerns_only(head,where) if p then local d=getfield(p,"post") if d then - local pn=pn.postinjections - if pn then - local leftkern=pn.leftkern - if leftkern~=0 then + local i=rawget(pn,"postinjections") + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then local t=find_tail(d) insert_node_after(d,t,newkern(leftkern)) end @@ -10435,28 +10474,28 @@ local function inject_kerns_only(head,where) end local d=getfield(p,"replace") if d then - local pn=pn.replaceinjections - if pn then - local leftkern=pn.leftkern - if leftkern~=0 then + local i=rawget(pn,"replaceinjections") + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then local t=find_tail(d) insert_node_after(d,t,newkern(leftkern)) end end else - local pn=pn.injections - if pn then - local leftkern=pn.leftkern - if leftkern~=0 then + local i=rawget(pn,"injections") + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then setfield(p,"replace",newkern(leftkern)) end end end else - local pn=pn.injections - if pn then - local leftkern=pn.leftkern - if leftkern~=0 then + local i=rawget(pn,"injections") + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then head=insert_node_before(head,n,newkern(leftkern)) end end @@ -10474,12 +10513,12 @@ local function inject_kerns_only(head,where) if getsubtype(n)<256 then local pn=rawget(properties,n) if pn then - pn=pn.preinjections - end - if pn then - local leftkern=pn.leftkern - if leftkern~=0 then - h=insert_node_before(h,n,newkern(leftkern)) + local i=rawget(pn,"preinjections") + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + h=insert_node_before(h,n,newkern(leftkern)) + end end end else @@ -10497,12 +10536,12 @@ local function inject_kerns_only(head,where) if getsubtype(n)<256 then local pn=rawget(properties,n) if pn then - pn=pn.postinjections - end - if pn then - local leftkern=pn.leftkern - if leftkern~=0 then - h=insert_node_before(h,n,newkern(leftkern)) + local i=rawget(pn,"postinjections") + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + h=insert_node_before(h,n,newkern(leftkern)) + end end end else @@ -10520,12 +10559,12 @@ local function inject_kerns_only(head,where) if getsubtype(n)<256 then local pn=rawget(properties,n) if pn then - pn=pn.replaceinjections - end - if pn then - local leftkern=pn.leftkern - if leftkern~=0 then - h=insert_node_before(h,n,newkern(leftkern)) + local i=rawget(pn,"replaceinjections") + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + h=insert_node_before(h,n,newkern(leftkern)) + end end end else @@ -10552,7 +10591,7 @@ end local function inject_pairs_only(head,where) head=tonut(head) if trace_injections then - trace(head) + trace(head,"pairs") end local n=head local p=nil @@ -10565,10 +10604,10 @@ local function inject_pairs_only(head,where) if p then local d=getfield(p,"post") if d then - local pn=pn.postinjections - if pn then - local leftkern=pn.leftkern - if leftkern~=0 then + local i=rawget(pn,"postinjections") + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then local t=find_tail(d) insert_node_after(d,t,newkern(leftkern)) end @@ -10576,35 +10615,35 @@ local function inject_pairs_only(head,where) end local d=getfield(p,"replace") if d then - local pn=pn.replaceinjections - if pn then - local leftkern=pn.leftkern - if leftkern~=0 then + local i=rawget(pn,"replaceinjections") + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then local t=find_tail(d) insert_node_after(d,t,newkern(leftkern)) end end else - local pn=pn.injections - if pn then - local leftkern=pn.leftkern - if leftkern~=0 then + local i=rawget(pn,"injections") + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then setfield(p,"replace",newkern(leftkern)) end end end else - local pn=pn.injections - if pn then - local yoffset=pn.yoffset + local i=rawget(pn,"injections") + if i then + local yoffset=i.yoffset if yoffset and yoffset~=0 then setfield(n,"yoffset",yoffset) end - local leftkern=pn.leftkern - if leftkern~=0 then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then insert_node_before(head,n,newkern(leftkern)) end - local rightkern=pn.rightkern + local rightkern=i.rightkern if rightkern and rightkern~=0 then insert_node_after(head,n,newkern(rightkern)) n=getnext(n) @@ -10622,23 +10661,23 @@ local function inject_pairs_only(head,where) local h=d for n in traverse_id(glyph_code,d) do if getsubtype(n)<256 then - local pn=rawget(properties,n) - if pn then - pn=pn.preinjections - end - if pn then - local yoffset=pn.yoffset - if yoffset and yoffset~=0 then - setfield(n,"yoffset",yoffset) - end - local leftkern=pn.leftkern - if leftkern~=0 then - h=insert_node_before(h,n,newkern(leftkern)) - end - local rightkern=pn.rightkern - if rightkern and rightkern~=0 then - insert_node_after(head,n,newkern(rightkern)) - n=getnext(n) + local p=rawget(properties,n) + if p then + local i=rawget(p,"preinjections") + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setfield(n,"yoffset",yoffset) + end + local leftkern=i.leftkern + if leftkern~=0 then + h=insert_node_before(h,n,newkern(leftkern)) + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(head,n,newkern(rightkern)) + n=getnext(n) + end end end else @@ -10654,23 +10693,23 @@ local function inject_pairs_only(head,where) local h=d for n in traverse_id(glyph_code,d) do if getsubtype(n)<256 then - local pn=rawget(properties,n) - if pn then - pn=pn.postinjections - end - if pn then - local yoffset=pn.yoffset - if yoffset and yoffset~=0 then - setfield(n,"yoffset",yoffset) - end - local leftkern=pn.leftkern - if leftkern~=0 then - h=insert_node_before(h,n,newkern(leftkern)) - end - local rightkern=pn.rightkern - if rightkern and rightkern~=0 then - insert_node_after(head,n,newkern(rightkern)) - n=getnext(n) + local p=rawget(properties,n) + if p then + local i=rawget(p,"postinjections") + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setfield(n,"yoffset",yoffset) + end + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + h=insert_node_before(h,n,newkern(leftkern)) + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(head,n,newkern(rightkern)) + n=getnext(n) + end end end else @@ -10686,23 +10725,23 @@ local function inject_pairs_only(head,where) local h=d for n in traverse_id(glyph_code,d) do if getsubtype(n)<256 then - local pn=rawget(properties,n) - if pn then - pn=pn.replaceinjections - end - if pn then - local yoffset=pn.yoffset - if yoffset and yoffset~=0 then - setfield(n,"yoffset",yoffset) - end - local leftkern=pn.leftkern - if leftkern~=0 then - h=insert_node_before(h,n,newkern(leftkern)) - end - local rightkern=pn.rightkern - if rightkern and rightkern~=0 then - insert_node_after(head,n,newkern(rightkern)) - n=getnext(n) + local p=rawget(properties,n) + if p then + local i=rawget(pn,"replaceinjections") + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setfield(n,"yoffset",yoffset) + end + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + h=insert_node_before(h,n,newkern(leftkern)) + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(head,n,newkern(rightkern)) + n=getnext(n) + end end end else @@ -11214,6 +11253,7 @@ local setcursive=injections.setcursive local setkern=injections.setkern local setpair=injections.setpair local resetinjection=injections.reset +local copyinjection=injections.copy local setligaindex=injections.setligaindex local getligaindex=injections.getligaindex local cursonce=true @@ -11296,10 +11336,13 @@ local function copy_glyph(g) if components then setfield(g,"components",nil) local n=copy_node(g) + copyinjection(n,g) setfield(g,"components",components) return n else - return copy_node(g) + local n=copy_node(g) + copyinjection(n,g) + return n end end local function markstoligature(kind,lookupname,head,start,stop,char) @@ -15084,13 +15127,14 @@ function nodes.handlers.nodepass(head) if basepass and #basefonts>0 then for i=1,#basefonts do local range=basefonts[i] - local start,stop=range[1],range[2] + local start=range[1] + local stop=range[2] if stop then - ligaturing(start,stop) - kerning(start,stop) - else - ligaturing(start) - kerning(start) + start,stop=ligaturing(start,stop) + start,stop=kerning(start,stop) + elseif start then + start=ligaturing(start) + start=kerning(start) end end end -- cgit v1.2.3