diff options
Diffstat (limited to 'tex/context/base/mkiv/font-syn.lua')
| -rw-r--r-- | tex/context/base/mkiv/font-syn.lua | 119 | 
1 files changed, 95 insertions, 24 deletions
diff --git a/tex/context/base/mkiv/font-syn.lua b/tex/context/base/mkiv/font-syn.lua index c4dcf0bcd..52f425db3 100644 --- a/tex/context/base/mkiv/font-syn.lua +++ b/tex/context/base/mkiv/font-syn.lua @@ -14,9 +14,11 @@ if not modules then modules = { } end modules ['font-syn'] = {  -- old ff  loader: 140 sec  -- new lua loader:   5 sec +-- maybe find(...,strictname,1,true) +  local next, tonumber, type, tostring = next, tonumber, type, tostring  local sub, gsub, match, find, lower, upper = string.sub, string.gsub, string.match, string.find, string.lower, string.upper -local concat, sort, fastcopy = table.concat, table.sort, table.fastcopy +local concat, sort, fastcopy, tohash = table.concat, table.sort, table.fastcopy, table.tohash  local serialize, sortedhash = table.serialize, table.sortedhash  local lpegmatch = lpeg.match  local unpack = unpack or table.unpack @@ -35,6 +37,7 @@ local splitname            = file.splitname  local basename             = file.basename  local nameonly             = file.nameonly  local pathpart             = file.pathpart +local suffixonly           = file.suffix  local filejoin             = file.join  local is_qualified_path    = file.is_qualified_path  local exists               = io.exists @@ -393,11 +396,11 @@ filters.ttc = filters.otf  --         local hash = { }  --         local okay = false  --         for line in f:lines() do -- slow but only a few lines at the beginning ---             if find(line,"dict begin") then +--             if find(line,"dict begin",1,true) then  --                 okay = true  --             elseif not okay then  --                 -- go on ---             elseif find(line,"currentdict end") then +--             elseif find(line,"currentdict end",1,true) then  --                 break  --             else  --                 local key, value = lpegmatch(p_entry,line) @@ -423,8 +426,10 @@ filters.list = {  -- to be considered: loop over paths per list entry (so first all otf ttf etc) -names.fontconfigfile    = "fonts.conf" -- a bit weird format, bonus feature -names.osfontdirvariable = "OSFONTDIR"  -- the official way, in minimals etc +names.fontconfigfile       = "fonts.conf"   -- a bit weird format, bonus feature +names.osfontdirvariable    = "OSFONTDIR"    -- the official way, in minimals etc +names.extrafontsvariable   = "EXTRAFONTS"   -- the official way, in minimals etc +names.runtimefontsvariable = "RUNTIMEFONTS" -- the official way, in minimals etc  filters.paths = { }  filters.names = { } @@ -436,7 +441,7 @@ function names.getpaths(trace)              local v = cleanpath(t[i])              v = gsub(v,"/+$","") -- not needed any more              local key = lower(v) -            report_names("%a specifies path %a",where,v) +            report_names("variable %a specifies path %a",where,v)              if not hash[key] then                  r = r + 1                  result[r] = v @@ -448,6 +453,10 @@ function names.getpaths(trace)      if path ~= "" then          collect(resolvers.expandedpathlist(path),path)      end +    local path = names.extrafontsvariable or "" +    if path ~= "" then +        collect(resolvers.expandedpathlist(path),path) +    end      if xml then          local confname = resolvers.expansion("FONTCONFIG_FILE") or ""          if confname == "" then @@ -539,23 +548,6 @@ names.cleanfilename = cleanfilename  --     return result  -- end -local function walk_tree(pathlist,suffix,identify) -    if pathlist then -        for i=1,#pathlist do -            local path = pathlist[i] -            path = cleanpath(path .. "/") -            path = gsub(path,"/+","/") -            local pattern = path .. "**." .. suffix -- ** forces recurse -            report_names("globbing path %a",pattern) -            local t = dir.glob(pattern) -            sort(t,sorter) -            for j=1,#t do -                local completename = t[j] -                identify(completename,basename(completename),suffix,completename) -            end -        end -    end -end  local function check_name(data,result,filename,modification,suffix,subfont)      -- shortcuts @@ -1002,9 +994,11 @@ local function unpackreferences()  end  local function analyzefiles(olddata) +      if not trace_warnings then          report_names("warnings are disabled (tracker 'fonts.warnings')")      end +      local data               = names.data      local done               = { }      local totalnofread       = 0 @@ -1020,6 +1014,26 @@ local function analyzefiles(olddata)      local oldspecifications  = olddata and olddata.specifications or { }      local oldrejected        = olddata and olddata.rejected       or { }      local treatmentdata      = treatments.data or { } -- when used outside context +    ----- walked             = setmetatableindex("number") + +    local function walk_tree(pathlist,suffix,identify) +        if pathlist then +            for i=1,#pathlist do +                local path = pathlist[i] +                path = cleanpath(path .. "/") +                path = gsub(path,"/+","/") +                local pattern = path .. "**." .. suffix -- ** forces recurse +                report_names("globbing path %a",pattern) +                local t = dir.glob(pattern) +                sort(t,sorter) +                for j=1,#t do +                    local completename = t[j] +                    identify(completename,basename(completename),suffix,completename) +                end +             -- walked[path] = walked[path] + #t +            end +        end +    end      local function identify(completename,name,suffix,storedname)          local pathpart, basepart = splitbase(completename) @@ -1123,6 +1137,7 @@ local function analyzefiles(olddata)          end          logs.flush() --  a bit overkill for each font, maybe not needed here      end +      local function traverse(what, method)          local list = filters.list          for n=1,#list do @@ -1141,7 +1156,9 @@ local function analyzefiles(olddata)          end          logs.flush()      end +      -- problem .. this will not take care of duplicates +      local function withtree(suffix)          resolvers.dowithfilesintree(".*%." .. suffix .. "$", function(method,root,path,name)              if method == "file" or method == "tree" then @@ -1158,16 +1175,20 @@ local function analyzefiles(olddata)              report_names("%s entries found, %s %s files checked, %s okay",total,checked,suffix,done)          end)      end +      local function withlsr(suffix) -- all trees          -- we do this only for a stupid names run, not used for context itself,          -- using the vars is too clumsy so we just stick to a full scan instead          local pathlist = resolvers.splitpath(resolvers.showpath("ls-R") or "")          walk_tree(pathlist,suffix,identify)      end +      local function withsystem(suffix) -- OSFONTDIR cum suis          walk_tree(names.getpaths(trace),suffix,identify)      end +      traverse("tree",withtree) -- TEXTREE only +      if not usesystemfonts then          report_names("ignoring system fonts")      elseif texconfig.kpse_init then @@ -1175,9 +1196,15 @@ local function analyzefiles(olddata)      else          traverse("system", withsystem)      end +      data.statistics.readfiles      = totalnofread      data.statistics.skippedfiles   = totalnofskipped      data.statistics.duplicatefiles = totalnofduplicates + + -- for k, v in sortedhash(walked) do + --     report_names("%s : %i",k,v) + -- end +  end  local function addfilenames() @@ -1492,10 +1519,54 @@ end  --     end  -- end +local runtimefiles = { } +local runtimedone  = false + +local function addruntimepath(path) +    names.load() +    local paths    = type(path) == "table" and path or { path } +    local suffixes = tohash(filters.list) +    for i=1,#paths do +        local path = resolveprefix(paths[i]) +        if path ~= "" then +            local list = dir.glob(path.."/*") +            for i=1,#list do +                local fullname = list[i] +                local suffix   = lower(suffixonly(fullname)) +                if suffixes[suffix] then +                    local c = cleanfilename(fullname) +                    runtimefiles[c] = fullname +                    if trace_names then +                        report_names("adding runtime filename %a for %a",c,fullname) +                    end +                end +            end +        end +    end +end + +local function addruntimefiles(variable) +    local paths = variable and resolvers.expandedpathlistfromvariable(variable) +    if paths and #paths > 0 then +        addruntimepath(paths) +    end +end + +names.addruntimepath  = addruntimepath +names.addruntimefiles = addruntimefiles +  function names.getfilename(askedname,suffix) -- last resort, strip funny chars +    if not runtimedone then +        addruntimefiles(names.runtimefontsvariable) +        runtimedone = true +    end +    local cleanname = cleanfilename(askedname,suffix) +    local found     = runtimefiles[cleanname] +    if found then +        return found +    end      names.load()      local files = names.data.files -    local cleanname = cleanfilename(askedname,suffix)      local found = files and files[cleanname] or ""      if found == "" and is_reloaded() then          files = names.data.files  | 
