diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/font-otf.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/font-otf.lua | 214 |
1 files changed, 112 insertions, 102 deletions
diff --git a/Master/texmf-dist/tex/context/base/font-otf.lua b/Master/texmf-dist/tex/context/base/font-otf.lua index e1339aec9a9..b8abd590a3e 100644 --- a/Master/texmf-dist/tex/context/base/font-otf.lua +++ b/Master/texmf-dist/tex/context/base/font-otf.lua @@ -14,8 +14,6 @@ if not modules then modules = { } end modules ['font-otf'] = { -- more checking against low level calls of functions -local utf = unicode.utf8 - local utfbyte = utf.byte local format, gmatch, gsub, find, match, lower, strip = string.format, string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip local type, next, tonumber, tostring = type, next, tonumber, tostring @@ -49,7 +47,7 @@ local otf = fonts.handlers.otf otf.glists = { "gsub", "gpos" } -otf.version = 2.737 -- beware: also sync font-mis.lua +otf.version = 2.741 -- beware: also sync font-mis.lua otf.cache = containers.define("fonts", "otf", otf.version, true) local fontdata = fonts.hashes.identifiers @@ -91,7 +89,7 @@ registerdirective("fonts.otf.loader.forcenotdef", function(v) forcenotdef = local function load_featurefile(raw,featurefile) if featurefile and featurefile ~= "" then if trace_loading then - report_otf("featurefile: %s", featurefile) + report_otf("using featurefile %a", featurefile) end fontloader.apply_featurefile(raw, featurefile) end @@ -101,7 +99,7 @@ local function showfeatureorder(rawdata,filename) local sequences = rawdata.resources.sequences if sequences and #sequences > 0 then if trace_loading then - report_otf("font %s has %s sequences",filename,#sequences) + report_otf("font %a has %s sequences",filename,#sequences) report_otf(" ") end for nos=1,#sequences do @@ -111,7 +109,7 @@ local function showfeatureorder(rawdata,filename) local subtables = sequence.subtables or { "no-subtables" } local features = sequence.features if trace_loading then - report_otf("%3i %-15s %-20s [%s]",nos,name,typ,concat(subtables,",")) + report_otf("%3i %-15s %-20s [% t]",nos,name,typ,subtables) end if features then for feature, scripts in next, features do @@ -122,14 +120,14 @@ local function showfeatureorder(rawdata,filename) for language, _ in next, languages do ttt[#ttt+1] = language end - tt[#tt+1] = format("[%s: %s]",script,concat(ttt," ")) + tt[#tt+1] = formatters["[%s: % t]"](script,ttt) end if trace_loading then - report_otf(" %s: %s",feature,concat(tt," ")) + report_otf(" %s: % t",feature,tt) end else if trace_loading then - report_otf(" %s: %s",feature,tostring(scripts)) + report_otf(" %s: %S",feature,scripts) end end end @@ -139,7 +137,7 @@ local function showfeatureorder(rawdata,filename) report_otf("\n") end elseif trace_loading then - report_otf("font %s has no sequences",filename) + report_otf("font %a has no sequences",filename) end end @@ -254,19 +252,19 @@ local function enhance(name,data,filename,raw) local enhancer = actions[name] if enhancer then if trace_loading then - report_otf("enhance: %s (%s)",name,filename) + report_otf("apply enhancement %a to file %a",name,filename) ioflush() end enhancer(data,filename,raw) - elseif trace_loading then - -- report_otf("enhance: %s is undefined",name) + else + -- no message as we can have private ones end end function enhancers.apply(data,filename,raw) local basename = file.basename(lower(filename)) if trace_loading then - report_otf("start enhancing: %s",filename) + report_otf("%s enhancing file %a","start",filename) end ioflush() -- we want instant messages for e=1,#ordered_enhancers do @@ -291,7 +289,7 @@ function enhancers.apply(data,filename,raw) ioflush() -- we want instant messages end if trace_loading then - report_otf("stop enhancing") + report_otf("%s enhancing file %a","stop",filename) end ioflush() -- we want instant messages end @@ -312,7 +310,7 @@ end function patches.report(fmt,...) if trace_loading then - report_otf("patching: " ..fmt,...) + report_otf("patching: %s",formatters[fmt](...)) end end @@ -321,7 +319,8 @@ function enhancers.register(what,action) -- only already registered can be overl end function otf.load(filename,format,sub,featurefile) - local name = file.basename(file.removesuffix(filename)) + local base = file.basename(file.removesuffix(filename)) + local name = file.removesuffix(base) local attr = lfs.attributes(filename) local size = attr and attr.size or 0 local time = attr and attr.modification or 0 @@ -342,7 +341,7 @@ function otf.load(filename,format,sub,featurefile) for s in gmatch(featurefile,"[^,]+") do local name = resolvers.findfile(file.addsuffix(s,'fea'),'fea') or "" if name == "" then - report_otf("loading: no featurefile '%s'",s) + report_otf("loading error, no featurefile %a",s) else local attr = lfs.attributes(name) featurefiles[#featurefiles+1] = { @@ -359,7 +358,7 @@ function otf.load(filename,format,sub,featurefile) local data = containers.read(otf.cache,hash) local reload = not data or data.size ~= size or data.time ~= time if forceload then - report_otf("loading: forced reload due to hard coded flag") + report_otf("forced reload of %a due to hard coded flag",filename) reload = true end if not reload then @@ -380,11 +379,11 @@ function otf.load(filename,format,sub,featurefile) reload = true end if reload then - report_otf("loading: forced reload due to changed featurefile specification: %s",featurefile or "--") + report_otf("loading: forced reload due to changed featurefile specification %a",featurefile) end end if reload then - report_otf("loading: %s (hash: %s)",filename,hash) + report_otf("loading %a, hash %a",filename,hash) local fontdata, messages if sub then fontdata, messages = fontloader.open(filename,sub) @@ -399,11 +398,11 @@ function otf.load(filename,format,sub,featurefile) report_otf("warning: %s",messages) else for m=1,#messages do - report_otf("warning: %s",tostring(messages[m])) + report_otf("warning: %S",messages[m]) end end else - report_otf("font loaded okay") + report_otf("loading done") end if fontdata then if featurefiles then @@ -455,41 +454,41 @@ function otf.load(filename,format,sub,featurefile) starttiming(data) report_otf("file size: %s", size) enhancers.apply(data,filename,fontdata) + local packtime = { } if packdata then if cleanup > 0 then collectgarbage("collect") ---~ lua.collectgarbage() end + starttiming(packtime) enhance("pack",data,filename,nil) + stoptiming(packtime) end - report_otf("saving in cache: %s",filename) + report_otf("saving %a in cache",filename) data = containers.write(otf.cache, hash, data) if cleanup > 1 then collectgarbage("collect") ---~ lua.collectgarbage() end stoptiming(data) if elapsedtime then -- not in generic - report_otf("preprocessing and caching took %s seconds",elapsedtime(data)) + report_otf("preprocessing and caching time %s, packtime %s", + elapsedtime(data),packdata and elapsedtime(packtime) or 0) end fontloader.close(fontdata) -- free memory if cleanup > 3 then collectgarbage("collect") ---~ lua.collectgarbage() end data = containers.read(otf.cache, hash) -- this frees the old table and load the sparse one if cleanup > 2 then collectgarbage("collect") ---~ lua.collectgarbage() end else data = nil - report_otf("loading failed (file read error)") + report_otf("loading failed due to read error") end end if data then if trace_defining then - report_otf("loading from cache: %s",hash) + report_otf("loading from cache using hash %a",hash) end enhance("unpack",data,filename,nil,false) enhance("add dimensions",data,filename,nil,false) @@ -529,13 +528,14 @@ actions["add dimensions"] = function(data,filename) local defaultwidth = resources.defaultwidth or 0 local defaultheight = resources.defaultheight or 0 local defaultdepth = resources.defaultdepth or 0 + local basename = trace_markwidth and file.basename(filename) if usemetatables then for _, d in next, descriptions do local wd = d.width if not wd then d.width = defaultwidth elseif trace_markwidth and wd ~= 0 and d.class == "mark" then - report_otf("mark with width %s (%s) in %s",wd,d.name or "<noname>",file.basename(filename)) + report_otf("mark %a with width %b found in %a",d.name or "<noname>",wd,basename) -- d.width = -wd end setmetatable(d,mt) @@ -546,7 +546,7 @@ actions["add dimensions"] = function(data,filename) if not wd then d.width = defaultwidth elseif trace_markwidth and wd ~= 0 and d.class == "mark" then - report_otf("mark with width %s (%s) in %s",wd,d.name or "<noname>",file.basename(filename)) + report_otf("mark %a with width %b found in %a",d.name or "<noname>",wd,basename) -- d.width = -wd end -- if forcenotdef and not d.name then @@ -650,7 +650,7 @@ actions["prepare glyphs"] = function(data,filename,raw) unicode = private unicodes[name] = private if trace_private then - report_otf("enhance: glyph %s at index 0x%04X is moved to private unicode slot U+%05X",name,index,private) + report_otf("glyph %a at index %H is moved to private unicode slot %U",name,index,private) end private = private + 1 nofnames = nofnames + 1 @@ -674,7 +674,7 @@ actions["prepare glyphs"] = function(data,filename,raw) descriptions[unicode] = description else - -- report_otf("potential problem: glyph 0x%04X is used but empty",index) + -- report_otf("potential problem: glyph %U is used but empty",index) end end end @@ -682,10 +682,10 @@ actions["prepare glyphs"] = function(data,filename,raw) report_otf("cid font remapped, %s unicode points, %s symbolic names, %s glyphs",nofunicodes, nofnames, nofunicodes+nofnames) end elseif trace_loading then - report_otf("unable to remap cid font, missing cid file for %s",filename) + report_otf("unable to remap cid font, missing cid file for %a",filename) end elseif trace_loading then - report_otf("font %s has no glyphs",filename) + report_otf("font %a has no glyphs",filename) end else @@ -699,7 +699,7 @@ actions["prepare glyphs"] = function(data,filename,raw) unicode = private unicodes[name] = private if trace_private then - report_otf("enhance: glyph %s at index 0x%04X is moved to private unicode slot U+%05X",name,index,private) + report_otf("glyph %a at index %H is moved to private unicode slot %U",name,index,private) end private = private + 1 else @@ -742,7 +742,7 @@ actions["prepare glyphs"] = function(data,filename,raw) end end else - report_otf("potential problem: glyph 0x%04X is used but empty",index) + report_otf("potential problem: glyph %U is used but empty",index) end end @@ -774,22 +774,22 @@ actions["check encoding"] = function(data,filename,raw) if find(encname,"unicode") then -- unicodebmp, unicodefull, ... if trace_loading then - report_otf("checking embedded unicode map '%s'",encname) + report_otf("checking embedded unicode map %a",encname) end for unicode, index in next, unicodetoindex do -- altuni already covers this if unicode <= criterium and not descriptions[unicode] then local parent = indices[index] -- why nil? if parent then - report_otf("weird, unicode U+%05X points to U+%05X with index 0x%04X",unicode,parent,index) + report_otf("weird, unicode %U points to %U with index %H",unicode,parent,index) else - report_otf("weird, unicode U+%05X points to nowhere with index 0x%04X",unicode,index) + report_otf("weird, unicode %U points to nowhere with index %H",unicode,index) end end end elseif properties.cidinfo then - report_otf("warning: no unicode map, used cidmap '%s'",properties.cidinfo.usedname or "?") + report_otf("warning: no unicode map, used cidmap %a",properties.cidinfo.usedname) else - report_otf("warning: non unicode map '%s', only using glyph unicode data",encname or "whatever") + report_otf("warning: non unicode map %a, only using glyph unicode data",encname or "whatever") end if mapdata then @@ -831,7 +831,7 @@ actions["add duplicates"] = function(data,filename,raw) -- todo: lookups etc end if trace_loading then - report_otf("duplicating U+%05X to U+%05X with index 0x%04X (%s kerns)",unicode,u,description.index,n) + report_otf("duplicating %U to %U with index %H (%s kerns)",unicode,u,description.index,n) end end end @@ -1058,7 +1058,10 @@ actions["reorganize subtables"] = function(data,filename,raw) -- local name = gk.name -- - if features then + if not name then + -- in fact an error + report_otf("skipping weird lookup number %s",k) + elseif features then -- scripts, tag, ismac local f = { } for i=1,#features do @@ -1114,7 +1117,7 @@ actions["prepare lookups"] = function(data,filename,raw) end -- The reverse handler does a bit redundant splitting but it's seldom --- seen so we don' tbother too much. We could store the replacement +-- seen so we don't bother too much. We could store the replacement -- in the current list (value instead of true) but it makes other code -- uglier. Maybe some day. @@ -1132,6 +1135,22 @@ local function t_uncover(splitter,cache,covers) return result end +local function s_uncover(splitter,cache,cover) + if cover == "" then + return nil + else + local uncovered = cache[cover] + if not uncovered then + uncovered = lpegmatch(splitter,cover) +-- for i=1,#uncovered do +-- uncovered[i] = { [uncovered[i]] = true } +-- end + cache[cover] = uncovered + end + return { uncovered } + end +end + local function t_hashed(t,cache) if t then local ht = { } @@ -1153,22 +1172,6 @@ local function t_hashed(t,cache) end end -local function s_uncover(splitter,cache,cover) - if cover == "" then - return nil - else - local uncovered = cache[cover] - if not uncovered then - uncovered = lpegmatch(splitter,cover) - for i=1,#uncovered do - uncovered[i] = { [uncovered[i]] = true } - end - cache[cover] = uncovered - end - return uncovered - end -end - local s_hashed = t_hashed local function r_uncover(splitter,cache,cover,replacements) @@ -1193,11 +1196,15 @@ local function r_uncover(splitter,cache,cover,replacements) end end -actions["reorganize lookups"] = function(data,filename,raw) +actions["reorganize lookups"] = function(data,filename,raw) -- we could check for "" and n == 0 -- we prefer the before lookups in a normal order if data.lookups then local splitter = data.helpers.tounicodetable - local cache, h_cache = { }, { } + local t_u_cache = { } + local s_u_cache = t_u_cache -- string keys + local t_h_cache = { } + local s_h_cache = t_h_cache -- table keys (so we could use one cache) + local r_u_cache = { } -- maybe shared for _, lookup in next, data.lookups do local rules = lookup.rules if rules then @@ -1205,15 +1212,15 @@ actions["reorganize lookups"] = function(data,filename,raw) if format == "class" then local before_class = lookup.before_class if before_class then - before_class = t_uncover(splitter,cache,reversed(before_class)) + before_class = t_uncover(splitter,t_u_cache,reversed(before_class)) end local current_class = lookup.current_class if current_class then - current_class = t_uncover(splitter,cache,current_class) + current_class = t_uncover(splitter,t_u_cache,current_class) end local after_class = lookup.after_class if after_class then - after_class = t_uncover(splitter,cache,after_class) + after_class = t_uncover(splitter,t_u_cache,after_class) end for i=1,#rules do local rule = rules[i] @@ -1223,7 +1230,7 @@ actions["reorganize lookups"] = function(data,filename,raw) for i=1,#before do before[i] = before_class[before[i]] or { } end - rule.before = t_hashed(before,h_cache) + rule.before = t_hashed(before,t_h_cache) end local current = class.current local lookups = rule.lookups @@ -1231,17 +1238,17 @@ actions["reorganize lookups"] = function(data,filename,raw) for i=1,#current do current[i] = current_class[current[i]] or { } if lookups and not lookups[i] then - lookups[i] = false -- e.g. we can have two lookups and one replacement + lookups[i] = "" -- (was: false) e.g. we can have two lookups and one replacement end end - rule.current = t_hashed(current,h_cache) + rule.current = t_hashed(current,t_h_cache) end local after = class.after if after then for i=1,#after do after[i] = after_class[after[i]] or { } end - rule.after = t_hashed(after,h_cache) + rule.after = t_hashed(after,t_h_cache) end rule.class = nil end @@ -1256,18 +1263,18 @@ actions["reorganize lookups"] = function(data,filename,raw) if coverage then local before = coverage.before if before then - before = t_uncover(splitter,cache,reversed(before)) - rule.before = t_hashed(before,h_cache) + before = t_uncover(splitter,t_u_cache,reversed(before)) + rule.before = t_hashed(before,t_h_cache) end local current = coverage.current if current then - current = t_uncover(splitter,cache,current) - rule.current = t_hashed(current,h_cache) + current = t_uncover(splitter,t_u_cache,current) + rule.current = t_hashed(current,t_h_cache) end local after = coverage.after if after then - after = t_uncover(splitter,cache,after) - rule.after = t_hashed(after,h_cache) + after = t_uncover(splitter,t_u_cache,after) + rule.after = t_hashed(after,t_h_cache) end rule.coverage = nil end @@ -1279,22 +1286,22 @@ actions["reorganize lookups"] = function(data,filename,raw) if reversecoverage then local before = reversecoverage.before if before then - before = t_uncover(splitter,cache,reversed(before)) - rule.before = t_hashed(before,h_cache) + before = t_uncover(splitter,t_u_cache,reversed(before)) + rule.before = t_hashed(before,t_h_cache) end local current = reversecoverage.current if current then - current = t_uncover(splitter,cache,current) - rule.current = t_hashed(current,h_cache) + current = t_uncover(splitter,t_u_cache,current) + rule.current = t_hashed(current,t_h_cache) end local after = reversecoverage.after if after then - after = t_uncover(splitter,cache,after) - rule.after = t_hashed(after,h_cache) + after = t_uncover(splitter,t_u_cache,after) + rule.after = t_hashed(after,t_h_cache) end local replacements = reversecoverage.replacements if replacements then - rule.replacements = r_uncover(splitter,cache,current,replacements) + rule.replacements = r_uncover(splitter,r_u_cache,current,replacements) end rule.reversecoverage = nil end @@ -1305,19 +1312,19 @@ actions["reorganize lookups"] = function(data,filename,raw) local glyphs = rule.glyphs if glyphs then local fore = glyphs.fore - if fore then - fore = s_uncover(splitter,cache,fore) - rule.before = s_hashed(fore,h_cache) + if fore and fore ~= "" then + fore = s_uncover(splitter,s_u_cache,fore) + rule.before = s_hashed(fore,s_h_cache) end local back = glyphs.back if back then - back = s_uncover(splitter,cache,back) - rule.after = s_hashed(back,h_cache) + back = s_uncover(splitter,s_u_cache,back) + rule.after = s_hashed(back,s_h_cache) end local names = glyphs.names if names then - names = s_uncover(splitter,cache,names) - rule.current = s_hashed(names,h_cache) + names = s_uncover(splitter,s_u_cache,names) + rule.current = s_hashed(names,s_h_cache) end rule.glyphs = nil end @@ -1337,7 +1344,7 @@ local function check_variants(unicode,the_variants,splitter,unicodes) for i=1,#glyphs do local g = glyphs[i] if done[g] then - report_otf("skipping cyclic reference U+%05X in math variant U+%05X",g,unicode) + report_otf("skipping cyclic reference %U in math variant %U",g,unicode) else if n == 0 then n = 1 @@ -1453,7 +1460,7 @@ actions["reorganize glyph kerns"] = function(data,filename,raw) end end elseif trace_loading then - report_otf("problems with unicode %s of kern %s of glyph U+%05X",name,k,unicode) + report_otf("problems with unicode %a of kern %a of glyph %U",name,k,unicode) end end end @@ -1487,6 +1494,9 @@ actions["merge kern classes"] = function(data,filename,raw) if type(lookups) ~= "table" then lookups = { lookups } end + -- if offsets[1] == nil then + -- offsets[1] = "" + -- end -- we can check the max in the loop -- local maxseconds = getn(seconds) for n, s in next, firsts do @@ -1507,9 +1517,9 @@ actions["merge kern classes"] = function(data,filename,raw) if splt then local extrakerns = { } local baseoffset = (fk-1) * maxseconds - -- for sk=2,maxseconds do - -- local sv = seconds[sk] - for sk, sv in next, seconds do + for sk=2,maxseconds do -- will become 1 based in future luatex + local sv = seconds[sk] + -- for sk, sv in next, seconds do local splt = split[sv] if splt then -- redundant test local offset = offsets[baseoffset + sk] @@ -1538,7 +1548,7 @@ actions["merge kern classes"] = function(data,filename,raw) lookupkerns[second_unicode] = kern end elseif trace_loading then - report_otf("no glyph data for U+%05X", first_unicode) + report_otf("no glyph data for %U", first_unicode) end end end @@ -1616,7 +1626,7 @@ actions["reorganize glyph lookups"] = function(data,filename,raw) if not lt then lookuptypes[tag] = lookuptype elseif lt ~= lookuptype then - report_otf("conflicting lookuptypes: %s => %s and %s",tag,lt,lookuptype) + report_otf("conflicting lookuptypes, %a points to %a and %a",tag,lt,lookuptype) end if lookuptype == "ligature" then lookuplist[l] = { lpegmatch(splitter,specification.components) } @@ -1773,7 +1783,7 @@ local function copytotfm(data,cache_id) for i=1,#variants do local un = variants[i] -- if done[un] then - -- -- report_otf("skipping cyclic reference U+%05X in math variant U+%05X",un,unicode) + -- -- report_otf("skipping cyclic reference %U in math variant %U",un,unicode) -- else c.next = un c = characters[un] @@ -1792,7 +1802,7 @@ local function copytotfm(data,cache_id) for i=1,#variants do local un = variants[i] -- if done[un] then - -- -- report_otf("skipping cyclic reference U+%05X in math variant U+%05X",un,unicode) + -- -- report_otf("skipping cyclic reference %U in math variant %U",un,unicode) -- else c.next = un c = characters[un] @@ -1972,7 +1982,7 @@ local function read_from_otf(specification) local allfeatures = tfmdata.shared.features or specification.features.normal constructors.applymanipulators("otf",tfmdata,allfeatures,trace_features,report_otf) constructors.setname(tfmdata,specification) -- only otf? - fonts.loggers.register(tfmdata,file.extname(specification.filename),specification) + fonts.loggers.register(tfmdata,file.suffix(specification.filename),specification) end return tfmdata end |