diff options
author | Manuel Pégourié-Gonnard <mpg@elzevir.fr> | 2010-05-29 09:35:02 +0000 |
---|---|---|
committer | Manuel Pégourié-Gonnard <mpg@elzevir.fr> | 2010-05-29 09:35:02 +0000 |
commit | bad9348a29610a5030b0ff1da29174f9fe2dbc98 (patch) | |
tree | 1a27079839d052f5b5760ec698e7d708a779a2c5 /Master/texmf-dist/tex/luatex | |
parent | e62580242146a93f7836af785779cfd1a79e0ce1 (diff) |
luaotfload update (2010/05/28 v1.08a)
git-svn-id: svn://tug.org/texlive/trunk@18578 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/luatex')
16 files changed, 574 insertions, 306 deletions
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.lua index 6e76fa57f8f..7033d24d970 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.lua @@ -7,7 +7,8 @@ -- luaotfload.dtx (with options: `lua') -- This is a generated file. -- --- Copyright (C) 2009 by Elie Roux <elie.roux@telecom-bretagne.eu> +-- Copyright (C) 2009-2010 by by Elie Roux <elie.roux@telecom-bretagne.eu> +-- and Khaled Hosny <khaledhosny@eglug.org> -- -- This work is under the CC0 license. -- @@ -19,8 +20,8 @@ module('luaotfload', package.seeall) luaotfload.module = { name = "luaotfload", - version = 1.07, - date = "2010/05/10", + version = 1.08a, + date = "2010/05/28", description = "ConTeXt font loading system.", author = "Elie Roux & Hans Hagen", copyright = "Elie Roux", @@ -75,11 +76,10 @@ luaotfload.loadmodule('node-ini.lua') function attributes.private(name) - local number = luatexbase.attributes['otfl@'..name] + local attr = 'otfl@' .. name + local number = luatexbase.attributes[attr] if not number then - error('asking for attribute %s, but not declared. ' - ..'Please report to the maintainer of luaotfload.', - name) + number = luatexbase.new_attribute(attr) end return number end @@ -87,6 +87,7 @@ end tex.attribute[0] = 0 + luaotfload.loadmodule('node-res.lua') luaotfload.loadmodule('node-inj.lua') luaotfload.loadmodule('node-fnt.lua') @@ -111,6 +112,9 @@ luaotfload.loadmodule('font-nms.lua') luaotfload.loadmodule('font-clr.lua') +fonts.mode = "node" + + function luaotfload.register_callbacks() luatexbase.add_to_callback('pre_linebreak_filter', nodes.simple_font_handler, diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty index e2ec4bba711..0883e086d8c 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty @@ -7,7 +7,8 @@ %% luaotfload.dtx (with options: `package') %% This is a generated file. %% -%% Copyright (C) 2009 by Elie Roux <elie.roux@telecom-bretagne.eu> +%% Copyright (C) 2009-2010 by by Elie Roux <elie.roux@telecom-bretagne.eu> +%% and Khaled Hosny <khaledhosny@eglug.org> %% %% This work is under the CC0 license. %% @@ -23,7 +24,7 @@ \else \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{luaotfload}% - [2010/05/10 v1.07 ConTeXt font loading system] + [2010/05/28 v1.08a ConTeXt font loading system] \RequirePackage{luatextra} \fi @@ -34,17 +35,6 @@ \catcode64 11 -\newluatexattribute\otfl@state -\newluatexattribute\otfl@markbase -\newluatexattribute\otfl@markdone -\newluatexattribute\otfl@markmark -\newluatexattribute\otfl@cursbase -\newluatexattribute\otfl@curscurs -\newluatexattribute\otfl@cursdone -\newluatexattribute\otfl@kernpair -\newluatexattribute\otfl@color - - \def\otfl@off{ \directlua{luaotfload.unregister_callbacks()} } diff --git a/Master/texmf-dist/tex/luatex/luaotfload/otfl-data-con.lua b/Master/texmf-dist/tex/luatex/luaotfload/otfl-data-con.lua index f06dba5b5e5..fabe0baa1b7 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/otfl-data-con.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/otfl-data-con.lua @@ -74,7 +74,7 @@ end function containers.is_valid(container, name) if name and name ~= "" then local storage = container.storage[name] - return storage and not table.is_empty(storage) and storage.cache_version == container.version + return storage and storage.cache_version == container.version else return false end diff --git a/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-def.lua b/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-def.lua index f64bae5636e..0add703ba48 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-def.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-def.lua @@ -501,14 +501,14 @@ a helper function.</p> function define.check(features,defaults) -- nb adapts features ! local done = false - if table.is_empty(features) then - features, done = table.fastcopy(defaults), true - else + if features and next(features) then for k,v in next, defaults do if features[k] == nil then features[k], done = v, true end end + else + features, done = table.fastcopy(defaults), true end return features, done -- done signals a change end diff --git a/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-dum.lua b/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-dum.lua index 5224ae187e7..2de1ae15d01 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-dum.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-dum.lua @@ -55,11 +55,14 @@ fonts.names.old_to_new = { } local data, loaded = nil, false +local fileformats = { "lua", "tex", "other text files" } + function fonts.names.resolve(name,sub) if not loaded then local basename = fonts.names.basename if basename and basename ~= "" then - for _, format in ipairs { "lua", "tex", "other text files" } do + for i=1,#fileformats do + local format = fileformats[i] local foundname = resolvers.find_file(basename,format) or "" if foundname ~= "" then data = dofile(foundname) @@ -356,3 +359,23 @@ fonts.otf.meanings.normalize = fonts.otf.meanings.normalize or function(t) t.rand = "random" end end + +-- bonus + +function fonts.otf.name_to_slot(name) + local tfmdata = fonts.ids[font.current()] + if tfmdata and tfmdata.shared then + local otfdata = tfmdata.shared.otfdata + local unicode = otfdata.luatex.unicodes[name] + return unicode and (type(unicode) == "number" and unicode or unicode[1]) + end +end + +function fonts.otf.char(n) + if type(n) == "string" then + n = fonts.otf.name_to_slot(n) + end + if type(n) == "number" then + tex.sprint("\\char" .. n) + end +end diff --git a/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-ini.lua b/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-ini.lua index b9988687d68..e4514978175 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-ini.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-ini.lua @@ -70,54 +70,26 @@ fonts.define.specify.synonyms = fonts.define.specify.synonyms or { } -- tracing -fonts.color = fonts.color or { } +if not fonts.color then -local attribute = attributes.private('color') -local mapping = (attributes and attributes.list[attribute]) or { } + fonts.color = { + set = function() end, + reset = function() end, + } -local set_attribute = node.set_attribute -local unset_attribute = node.unset_attribute - -function fonts.color.set(n,c) - local mc = mapping[c] - if not mc then - unset_attribute(n,attribute) - else - set_attribute(n,attribute,mc) - end -end -function fonts.color.reset(n) - unset_attribute(n,attribute) end --- this will change ... - -function fonts.show_char_data(n) - local tfmdata = fonts.ids[font.current()] - if tfmdata then - if type(n) == "string" then - n = utf.byte(n) - end - local chr = tfmdata.characters[n] - if chr then - write_nl(format("%s @ %s => U%04X => %s => ",tfmdata.fullname,tfmdata.size,n,utf.char(n)) .. serialize(chr,false)) - end - end -end +-- format identification -function fonts.show_font_parameters() - local tfmdata = fonts.ids[font.current()] - if tfmdata then - local parameters, mathconstants = tfmdata.parameters, tfmdata.MathConstants - local hasparameters, hasmathconstants = parameters and next(parameters), mathconstants and next(mathconstants) - if hasparameters then - write_nl(format("%s @ %s => parameters => ",tfmdata.fullname,tfmdata.size) .. serialize(parameters,false)) - end - if hasmathconstants then - write_nl(format("%s @ %s => math constants => ",tfmdata.fullname,tfmdata.size) .. serialize(mathconstants,false)) - end - if not hasparameters and not hasmathconstants then - write_nl(format("%s @ %s => no parameters and/or mathconstants",tfmdata.fullname,tfmdata.size)) - end +fonts.formats = { } + +function fonts.fontformat(filename,default) + local extname = file.extname(filename) + local format = fonts.formats[extname] + if format then + return format + else + logs.report("fonts define","unable to detemine font format for '%s'",filename) + return default end end diff --git a/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-map.lua b/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-map.lua index 208ad50a873..299508764a1 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-map.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-map.lua @@ -252,7 +252,7 @@ fonts.map.add_to_unicode = function(data,filename) end end if trace_unimapping then - for index, glyph in table.sortedpairs(data.glyphs) do + for index, glyph in table.sortedhash(data.glyphs) do local toun, name, unic = tounicode[index], glyph.name, glyph.unicode or -1 -- play safe if toun then logs.report("load otf","internal: 0x%05X, name: %s, unicode: 0x%05X, tounicode: %s",index,name,unic,toun) @@ -302,7 +302,7 @@ end -- -- function fonts.map.flush(backend) -- will also erase the accumulated data -- local flushline = fonts.map.line[backend or "pdftex"] or fonts.map.line.pdftex --- for _, e in pairs(fonts.map.data) do +-- for _, e in next, fonts.map.data do -- flushline(e) -- end -- fonts.map.data = { } diff --git a/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-nms.lua b/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-nms.lua index fd31bac0832..e75b6c94b18 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-nms.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-nms.lua @@ -3,15 +3,29 @@ if not modules then modules = { } end modules ['font-nms'] = { comment = "companion to luaotfload.lua", author = "Khaled Hosny and Elie Roux", copyright = "Luaotfload Development Team", - license = "GPL" + license = "GNU GPL v2" } +-- This is a patch for otfl-font-def.lua, that defines a reader for ofm fonts, +-- this is necessary if we set the forced field of the specification to 'ofm' +-- we use it only when using luaotfload, not mkluatexfontdb. +if fonts and fonts.tfm and fonts.tfm.readers then + fonts.tfm.readers.ofm = fonts.tfm.readers.tfm +end + +-- This is a necessary initalization in order not to rebuild an existing font. +-- Maybe 600 should be replaced by \pdfpkresolution +-- or texconfig.pk_dpi (and it should be replaced dynamically), but we don't +-- have access (yet) to the texconfig table, so we let it be 600. Anyway, it +-- does still work fine even if \pdfpkresolution is changed. +kpse.init_prog('', 600, '/') + fonts = fonts or { } fonts.names = fonts.names or { } local names = fonts.names local names_dir = "/luatex/generic/luaotfload/names/" -names.version = 2.007 -- not the same as in context +names.version = 2.009 -- not the same as in context names.data = nil names.path = { basename = "otfl-names.lua", @@ -20,15 +34,30 @@ names.path = { } -local splitpath, expandpath, glob, basename = file.split_path, kpse.expand_path, dir.glob, file.basename -local upper, lower, format, gsub, match = string.upper, string.lower, string.format, string.gsub, string.match -local rpadd = string.rpadd -local utfgsub = unicode.utf8.gsub +local splitpath, expandpath = file.split_path, kpse.expand_path +local glob, basename = dir.glob, file.basename +local upper, lower, format = string.upper, string.lower, string.format +local gsub, match, rpadd = string.gsub, string.match, string.rpadd +local gmatch, sub = string.gmatch, string.sub +local utfgsub = unicode.utf8.gsub +local trace_short = false --tracing adapted to rebuilding of the database inside a document local trace_progress = true --trackers.register("names.progress", function(v) trace_progress = v end) local trace_search = false --trackers.register("names.search", function(v) trace_search = v end) local trace_loading = false --trackers.register("names.loading", function(v) trace_loading = v end) + +-- Basic function from <http://stackoverflow.com/questions/2282444/how-to-check-if-a-table-contains-an-element-in-lua> +function table.contains(table, element) + for _, value in pairs(table) do + if value == element then + return true + end + end + return false +end + + local function sanitize(str) if str then return utfgsub(lower(str), "[^%a%d]", "") @@ -37,54 +66,127 @@ local function sanitize(str) end end +local function fontnames_init() + return { + mappings = { }, + status = { }, + version = names.version, + } +end + function names.load() + -- this sets the output of the database building accordingly. + names.set_log_level(-1) local localpath = names.path.localdir .. names.path.basename local systempath = names.path.systemdir .. names.path.basename local kpsefound = kpse.find_file(names.path.basename) + local foundname local data if kpsefound and file.isreadable(kpsefound) then data = dofile(kpsefound) + foundname = kpsefound elseif file.isreadable(localpath) then data = dofile(localpath) + foundname = localpath elseif file.isreadable(systempath) then data = dofile(systempath) + foundname = systempath end if data then - if trace_loading then - logs.report("load font", "loaded font names database: %s", foundname) - end - return data + logs.report("load font", + "loaded font names database: %s", foundname) + else + logs.report("load font", + "no font names database found, generating new one") + data = names.update() + names.save(data) end + return data end -local loaded = false - local synonyms = { - regular = {normal=true, roman=true, plain=true, book=true, medium=true}, - italic = {regularitalic=true, normalitalic=true, oblique=true, slant=true}, - bolditalic = {boldoblique=true, boldslant=true}, + regular = { + normal = true, + roman = true, + plain = true, + book = true, + medium = true, + }, + italic = { + regularitalic = true, + normalitalic = true, + oblique = true, + slant = true, + }, + bolditalic = { + boldoblique = true, + boldslant = true, + }, } --- a small hack to get the log message "no font names database loaded" only --- once in the log -local log_message_shown = false +local loaded = false +local reloaded = false function names.resolve(specification) - local tfm = resolvers.find_file(specification.name, "ofm") - local name = sanitize(specification.name) - local style = sanitize(specification.style) or "regular" - local size = tonumber(specification.optsize) or specification.size and specification.size / 65536 + local tfm = resolvers.find_file(specification.name, "tfm") + local ext = lower(file.extname(specification.name)) + if tfm then -- is a tfm font, skip names database - return specification.name, false + if ext == 'tfm' then + return specification.name, false + else + return specification.name..'.tfm', false + end + elseif resolvers.find_file(specification.name, "ofm") then + if ext == 'ofm' then + return specification.name, false + else + return specification.name..'.ofm', false + end + end + + local name = sanitize(specification.name) + local style = sanitize(specification.style) or "regular" + + local size + if specification.optsize then + size = tonumber(specification.optsize) + elseif specification.size then + size = specification.size / 65536 end + + if not loaded then - names.data = names.load() - loaded = true + names.data = names.load() + loaded = true end - local data = names.data + + local data = names.data if type(data) == "table" and data.version == names.version then if data.mappings then + -- if the specified name ends like a font file, we first look for + -- it through kpse, and if we don't find it, we look for it in + -- the database. + if table.contains(font_extensions_lc, ext) then + local fname = specification.name + -- for absolute and relative path, kpse will find them, so + -- there shouldn't be any problem + local path = resolvers.find_file(fname, "opentype fonts") + if not path then + path = resolvers.find_file(fname, "truetype fonts") + end + if path then + return path -- or fname ? + else + for _,face in ipairs(data.mappings) do + if basename(face.filename[1]) == fname then + return face.filename[1], face.filename[2] + end + end + end + return specification.name + end local found = { } for _,face in ipairs(data.mappings) do local family = sanitize(face.names.family) @@ -97,13 +199,15 @@ function names.resolve(specification) if #face.size > 0 then optsize = face.size dsnsize = optsize[1] and optsize[1] / 10 - maxsize = optsize[2] and optsize[2] / 10 or dsnsize -- can be nil - minsize = optsize[3] and optsize[3] / 10 or dsnsize -- can be nil + -- can be nil + maxsize = optsize[2] and optsize[2] / 10 or dsnsize + minsize = optsize[3] and optsize[3] / 10 or dsnsize end if name == family then if subfamily == style then if optsize then - if dsnsize == size or (size > minsize and size <= maxsize) then + if dsnsize == size + or (size > minsize and size <= maxsize) then found[1] = face break else @@ -115,7 +219,8 @@ function names.resolve(specification) end elseif synonyms[style] and synonyms[style][subfamily] then if optsize then - if dsnsize == size or (size > minsize and size <= maxsize) then + if dsnsize == size + or (size > minsize and size <= maxsize) then found[1] = face break else @@ -129,9 +234,13 @@ function names.resolve(specification) found[1] = face end else - if name == fullname or name == pfullname or name == fontname or name == psname then + if name == fullname + or name == pfullname + or name == fontname + or name == psname then if optsize then - if dsnsize == size or (size > minsize and size <= maxsize) then + if dsnsize == size + or (size > minsize and size <= maxsize) then found[1] = face break else @@ -172,19 +281,37 @@ function names.resolve(specification) return closest.filename[1], closest.filename[2] end end - -- no font found so far, fallback to filename + -- no font found so far + if not reloaded then + -- try reloading the database + names.data = names.update(names.data) + names.save(names.data) + reloaded = true + return names.resolve(specification) + else + -- else, fallback to filename + return specification.name, false + end + end + else + if not reloaded then + names.data = names.update() + names.save(names.data) + reloaded = true + return names.resolve(specification) + else return specification.name, false end - elseif not log_message_shown then - logs.report("load font", "no font names database loaded") - log_message_shown = true end end -names.resolvespec = names.resolve -- only supported in mkiv +names.resolvespec = names.resolve function names.set_log_level(level) - if level == 2 then + if level == -1 then + trace_progress = false + trace_short = true + elseif level == 2 then trace_progress = false trace_loading = true elseif level >= 3 then @@ -193,7 +320,7 @@ function names.set_log_level(level) trace_search = true end end - + local lastislog = 0 function log(fmt, ...) @@ -203,6 +330,7 @@ end logs = logs or { } logs.report = logs.report or log +logs.info = logs.info or log local log = names.log @@ -229,7 +357,13 @@ end local function font_fullinfo(filename, subfont, texmf) local t = { } local f = fontloader.open(filename, subfont) - local m = f and fontloader.to_table(f) + if not f then + if trace_loading then + logs.report("error: failed to open %s", filename) + end + return nil + end + local m = fontloader.to_table(f) fontloader.close(f) collectgarbage('collect') -- see http://www.microsoft.com/typography/OTSPEC/features_pt.htm#size @@ -244,11 +378,13 @@ local function font_fullinfo(filename, subfont, texmf) for _,v in pairs(m.names) do if v.lang == "English (US)" then t.names = { - -- see http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html - fullname = v.names.compatfull or v.names.fullname, -- 18, 4 - family = v.names.preffamilyname or v.names.family, -- 17, 1 - subfamily = t.fontstyle_name or v.names.prefmodifiers or v.names.subfamily, -- opt. style, 16, 2 - psname = v.names.postscriptname --or t.fontname + -- see + -- http://developer.apple.com/textfonts/ + -- TTRefMan/RM06/Chap6name.html + fullname = v.names.compatfull or v.names.fullname, + family = v.names.preffamilyname or v.names.family, + subfamily= t.fontstyle_name or v.names.prefmodifiers or v.names.subfamily, + psname = v.names.postscriptname } end end @@ -266,49 +402,72 @@ local function font_fullinfo(filename, subfont, texmf) m.design_range_top ~= 0 and m.design_range_top or nil, m.design_range_bottom ~= 0 and m.design_range_bottom or nil, } - return t end -local function load_font(filename, fontnames, status, newfontnames, newstatus, texmf) - local mappings = newfontnames and newfontnames.mappings or { } - local oldmappings = fontnames.mappings or { } +local function load_font(filename, fontnames, newfontnames, texmf) + local newmappings = newfontnames.mappings + local newstatus = newfontnames.status + local mappings = fontnames.mappings + local status = fontnames.status + local basefile = texmf and basename(filename) or filename if filename then local timestamp, db_timestamp - db_timestamp = status[filename] and status[filename].timestamp + db_timestamp = status[basefile] and status[basefile].timestamp timestamp = lfs.attributes(filename, "modification") - newstatus[filename] = { } - newstatus[filename].timestamp = timestamp - newstatus[filename].index = {} - if db_timestamp == timestamp then - for _,v in ipairs(status[filename].index) do - mappings[#mappings+1] = oldmappings[v] - newstatus[filename].index[#newstatus[filename].index+1] = #mappings + + local index_status = newstatus[basefile] or (not texmf and newstatus[basename(filename)]) + if index_status and index_status.timestamp == timestamp then + -- already indexed this run + return + end + + newstatus[basefile] = newstatus[basefile] or { } + newstatus[basefile].timestamp = timestamp + newstatus[basefile].index = newstatus[basefile].index or { } + + if db_timestamp == timestamp and not newstatus[basefile].index[1] then + for _,v in ipairs(status[basefile].index) do + local index = #newstatus[basefile].index + newmappings[#newmappings+1] = mappings[v] + newstatus[basefile].index[index+1] = #newmappings end if trace_loading then - logs.report("font already indexed: %s", filename) + logs.report("font already indexed: %s", basefile) end return end if trace_loading then - logs.report("loading font: %s", filename) + logs.report("loading font: %s", basefile) end local info = fontloader.info(filename) if info then if type(info) == "table" and #info > 1 then for i in ipairs(info) do local fullinfo = font_fullinfo(filename, i-1, texmf) - mappings[#mappings+1] = fullinfo - newstatus[filename].index[#newstatus[filename].index+1] = #mappings + local index = newstatus[basefile].index[i] + if newstatus[basefile].index[i] then + index = newstatus[basefile].index[i] + else + index = #newmappings+1 + end + newmappings[index] = fullinfo + newstatus[basefile].index[i] = index end else local fullinfo = font_fullinfo(filename, false, texmf) - mappings[#mappings+1] = fullinfo - newstatus[filename].index[#newstatus[filename].index+1] = #mappings + local index + if newstatus[basefile].index[1] then + index = newstatus[basefile].index[1] + else + index = #newmappings+1 + end + newmappings[index] = fullinfo + newstatus[basefile].index[1] = index end else if trace_loading then - logs.report("failed to load %s", filename) + logs.report("failed to load %s", basefile) end end end @@ -316,66 +475,108 @@ end local function path_normalize(path) --[[ - path normalization: - - a\b\c -> a/b/c - - a/../b -> b - - /cygdrive/a/b -> a:/b + path normalization: + - a\b\c -> a/b/c + - a/../b -> b + - /cygdrive/a/b -> a:/b + - reading symlinks under non-Win32 + - using kpse.readable_file on Win32 --]] if os.type == "windows" or os.type == "msdos" or os.name == "cygwin" then + path = kpse.readable_file(path) path = path:gsub('\\', '/') path = path:lower() - -- for cygwin cases... path = path:gsub('^/cygdrive/(%a)/', '%1:/') end + if os.type ~= "windows" and os.type ~= "msdos" then + local dest = lfs.readlink(path) + if dest then + if kpse.readable_file(dest) then + path = dest + elseif kpse.readable_file(file.join(file.dirname(path), dest)) then + path = file.join(file.dirname(path), dest) + else + -- broken symlink? + end + end + end path = file.collapse_path(path) return path end fonts.path_normalize = path_normalize -local function scan_dir(dirname, fontnames, status, newfontnames, newstatus, recursive, texmf) +if os.name == "macosx" then + -- While Mac OS X 10.6 has a problem with TTC files, ignore them globally: + font_extensions = { + "otf", "ttf", "dfont", "OTF", "TTF", "DFONT" + } + font_extensions_lc = { "otf", "ttf", "dfont" } +else + font_extensions = { + "otf", "ttf", "ttc", "dfont", "OTF", "TTF", "TTC", "DFONT" + } + font_extensions_lc = { "otf", "ttf", "ttc", "dfont" } +end + +local function scan_dir(dirname, fontnames, newfontnames, texmf) --[[ this function scans a directory and populates the list of fonts with all the fonts it finds. - dirname is the name of the directory to scan - names is the font database to fill - - recursive is whether we scan all directories recursively (always false - in this script) - - texmf is a boolean saying if we are scanning a texmf directory (always - true in this script) + - texmf is a boolean saying if we are scanning a texmf directory --]] local list, found = { }, { } local nbfound = 0 - for _,ext in ipairs { "otf", "ttf", "ttc", "dfont" } do - if recursive then pat = "/**." else pat = "/*." end - if trace_search then - logs.report("scanning '%s' for '%s' fonts", dirname, ext) - end - found = glob(dirname .. pat .. ext) + if trace_search then + logs.report("scanning '%s'", dirname) + end + for _,ext in ipairs(font_extensions) do + found = glob(dirname .. "/**." .. ext) -- note that glob fails silently on broken symlinks, which happens -- sometimes in TeX Live. if trace_search then - logs.report("%s fonts found", #found) + logs.report("%s '%s' fonts found", #found, ext) end nbfound = nbfound + #found table.append(list, found) - if trace_search then - logs.report("scanning '%s' for '%s' fonts", dirname, upper(ext)) - end - found = glob(dirname .. pat .. upper(ext)) - table.append(list, found) - nbfound = nbfound + #found end if trace_search then logs.report("%d fonts found in '%s'", nbfound, dirname) end + list = remove_ignore_fonts(list) -- fixme: general solution required for _,fnt in ipairs(list) do fnt = path_normalize(fnt) - load_font(fnt, fontnames, status, newfontnames, newstatus, texmf) + load_font(fnt, fontnames, newfontnames, texmf) end end -local function scan_texmf_tree(fontnames, status, newfontnames, newstatus) +-- Temporary until a general solution is implemented: +if os.name == "macosx" then + ignore_fonts = { + -- this font kills the indexer: + "/System/Library/Fonts/LastResort.ttf" + } + function remove_ignore_fonts(fonts) + for N,fnt in ipairs(fonts) do + if table.contains(ignore_fonts,fnt) then + if trace_search then + logs.report("ignoring font '%s'", fnt) + end + table.remove(fonts,N) + end + end + return fonts + end +-- This function is only necessary, for now, on Mac OS X. +else + function remove_ignore_fonts(fonts) + return fonts + end +end + +local function scan_texmf_fonts(fontnames, newfontnames) --[[ The function that scans all fonts in the texmf tree, through kpathsea variables OPENTYPEFONTS and TTFONTS of texmf.cnf @@ -386,110 +587,149 @@ local function scan_texmf_tree(fontnames, status, newfontnames, newstatus) else logs.report("scanning TEXMF and OS fonts:") end + elseif trace_short then + if expandpath("$OSFONTDIR"):is_empty() then + logs.info("scanning TEXMF fonts...") + else + logs.info("scanning TEXMF and OS fonts...") + end end - local fontdirs = expandpath("$OPENTYPEFONTS") - fontdirs = fontdirs .. gsub(expandpath("$TTFONTS"), "^\.", "") + local fontdirs = expandpath("$OPENTYPEFONTS"):gsub("^\.", "") + fontdirs = fontdirs .. expandpath("$TTFONTS"):gsub("^\.", "") if not fontdirs:is_empty() then - local explored_dirs = {} fontdirs = splitpath(fontdirs) - -- hack, don't scan current dir - table.remove(fontdirs, 1) count = 0 for _,d in ipairs(fontdirs) do - if not explored_dirs[d] then - count = count + 1 - progress(count, #fontdirs) - scan_dir(d, fontnames, status, newfontnames, newstatus, false, true) - explored_dirs[d] = true - end + count = count + 1 + progress(count, #fontdirs) + scan_dir(d, fontnames, newfontnames, true) end end end -local function read_fcdata(data) - --[[ - this function takes raw data returned by fc-list, parses it, normalizes the - paths and makes a list out of it. - --]] - local list = { } - for line in data:lines() do - line = line:gsub(": ", "") - local ext = lower(match(line,"^.+%.([^/\\]-)$")) - if ext == "otf" or ext == "ttf" or ext == "ttc" or ext == "dfont" then - list[#list+1] = path_normalize(line:gsub(": ", "")) - end - end - return list -end +--[[ + For the OS fonts, there are several options: + - if OSFONTDIR is set (which is the case under windows by default but + not on the other OSs), it scans it at the same time as the texmf tree, + in the scan_texmf_fonts. + - if not: + - under Windows and Mac OSX, we take a look at some hardcoded directories + - under Unix, we read /etc/fonts/fonts.conf and read the directories in it -local function scan_os_fonts(fontnames, status, newfontnames, newstatus) - --[[ - This function scans the OS fonts through fontcache (fc-list), it executes - only if OSFONTDIR is empty (which is the case under most Unix by default). - If OSFONTDIR is non-empty, this means that the system fonts it contains have - already been scanned, and thus we don't scan them again. - --]] - if expandpath("$OSFONTDIR"):is_empty() then - if trace_progress then - logs.report("scanning OS fonts:") - end - if trace_search then - logs.report("executing 'fc-list : file' and parsing its result...") - end - local data = io.popen("fc-list : file", 'r') - local list = read_fcdata(data) - data:close() - if trace_search then - logs.report("%d fonts found", #list) - end - count = 0 - for _,fnt in ipairs(list) do - count = count + 1 - progress(count, #list) - load_font(fnt, fontnames, status, newfontnames, newstatus, false) + This means that if you have fonts in fancy directories, you need to set them + in OSFONTDIR. +]] + +--[[ + This function parses /etc/fonts/fonts.conf and returns all the dir it finds. + The code is minimal, please report any error it may generate. +]] + +local function read_fonts_conf() + local f = io.open("/etc/fonts/fonts.conf") + if not f then + error("Cannot open the file /etc/fonts/fonts.conf") + end + local results = {} + local incomments = false + for line in f:lines() do + -- spaghetti code... hmmm... + if incomments and sub(line, 1, 3) == '-->' then + incomments = false + elseif sub(line, 1, 4) == '<!--' then + incomments = true + else + for dir in gmatch(line, '<dir>([^<]+)</dir>') do + -- now we need to replace ~ by kpse.expand_path('~') + if sub(dir, 1, 1) == '~' then + dir = kpse.expand_path('~') .. sub(dir, 2) + end + results[#results+1] = dir + end end end + f:close() + return results end -local function fontnames_init() - return { - mappings = { }, - version = names.version, - } +local function get_os_dirs() + if os.name == 'macosx' then + return { + kpse.expand_path('~') .. "/Library/Fonts", + "/Library/Fonts", + "/System/Library/Fonts", + "/Network/Library/Fonts", + } + elseif os.type == "windows" or os.type == "msdos" or os.name == "cygwin" then + local windir = os.getenv("WINDIR") + return {windir..'\\Fonts',} + else + return read_fonts_conf() + end end -local function status_init() - return { - version = names.version, - } +local function scan_os_fonts(fontnames, newfontnames) + --[[ + This function scans the OS fonts through + - fontcache for Unix (reads the fonts.conf file and scans the directories) + - a static set of directories for Windows and MacOSX + --]] + if trace_progress then + logs.report("scanning OS fonts:") + elseif trace_short then + logs.info("scanning OS fonts...") + end + if trace_search then + logs.info("searching in static system directories...") + end + count = 0 + local os_dirs = get_os_dirs() + for _,d in ipairs(os_dirs) do + count = count + 1 + progress(count, #os_dirs) + scan_dir(d, fontnames, newfontnames, false) + end end -local function update(fontnames, status, force) +local function update_names(fontnames, force) --[[ The main function, scans everything - fontnames is the final table to return - force is whether we rebuild it from scratch or not - - status is a table containing the current status of the database --]] + if trace_short then + logs.info("Updating the font names database:") + end if force then fontnames = fontnames_init() - status = status_init() else - if not fontnames or not fontnames.version or fontnames.version ~= names.version - or not status or not status.version or status.version ~= names.version then + if not fontnames + or not fontnames.version + or fontnames.version ~= names.version then fontnames = fontnames_init() - status = status_init() if trace_search then - logs.report("no font names database or old one found, generating new one") + logs.report("no font names database or old one found, " + .."generating new one") end end end local newfontnames = fontnames_init() - local newstatus = status_init() - scan_texmf_tree(fontnames, status, newfontnames, newstatus) - scan_os_fonts (fontnames, status, newfontnames, newstatus) - return newfontnames, newstatus + scan_texmf_fonts(fontnames, newfontnames) + if expandpath("$OSFONTDIR"):is_empty() then + scan_os_fonts(fontnames, newfontnames) + end + return newfontnames +end + +local function save_names(fontnames) + local savepath = names.path.localdir + if not lfs.isdir(savepath) then + dir.mkdirs(savepath) + end + io.savedata(savepath .. names.path.basename, + table.serialize(fontnames, true)) end names.scan = scan_dir -names.update = update +names.update = update_names +names.save = save_names diff --git a/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-otc.lua b/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-otc.lua index 64e09f8b117..551696f2cbf 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-otc.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-otc.lua @@ -9,8 +9,6 @@ if not modules then modules = { } end modules ['font-otc'] = { local format, insert = string.format, table.insert local type, next = type, next -local ctxcatcodes = tex.ctxcatcodes - -- we assume that the other otf stuff is loaded already local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end) @@ -217,30 +215,3 @@ fonts.initializers.node.otf.lineheight = fonts.initializers.common.lineheight fonts.initializers.base.otf.compose = fonts.initializers.common.compose fonts.initializers.node.otf.compose = fonts.initializers.common.compose - --- bonus function - -function otf.name_to_slot(name) -- todo: afm en tfm - local tfmdata = fonts.ids[font.current()] - if tfmdata and tfmdata.shared then - local otfdata = tfmdata.shared.otfdata - local unicode = otfdata.luatex.unicodes[name] - if not unicode then - return string.byte("?") -- nil - elseif type(unicode) == "number" then - return unicode - else - return unicode[1] - end - end - return nil -end - -function otf.char(n) -- todo: afm en tfm - if type(n) == "string" then - n = otf.name_to_slot(n) - end - if n then - tex.sprint(ctxcatcodes,format("\\char%s ",n)) - end -end diff --git a/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-otf.lua b/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-otf.lua index 29c56cd0012..d68137c96e6 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-otf.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-otf.lua @@ -80,7 +80,7 @@ otf.features.default = otf.features.default or { } otf.enhancers = otf.enhancers or { } otf.glists = { "gsub", "gpos" } -otf.version = 2.645 -- beware: also sync font-mis.lua +otf.version = 2.650 -- beware: also sync font-mis.lua otf.pack = true -- beware: also sync font-mis.lua otf.syncspace = true otf.notdef = false @@ -576,7 +576,10 @@ end otf.enhancers["merge cid fonts"] = function(data,filename) -- we can also move the names to data.luatex.names which might -- save us some more memory (at the cost of harder tracing) - if data.subfonts and table.is_empty(data.glyphs) then + if data.subfonts then + if data.glyphs and next(data.glyphs) then + logs.report("load otf","replacing existing glyph table due to subfonts") + end local cidinfo = data.cidinfo local verbose = fonts.verbose if cidinfo.registry then @@ -1355,7 +1358,7 @@ end function otf.set_features(tfmdata,features) local processes = { } - if not table.is_empty(features) then + if features and next(features) then local lists = { fonts.triggers, fonts.processors, @@ -1430,14 +1433,14 @@ function otf.otf_to_tfm(specification) --~ print(cache_id) if not tfmdata then local otfdata = otf.load(filename,format,sub,features and features.featurefile) - if not table.is_empty(otfdata) then + if otfdata and next(otfdata) then otfdata.shared = otfdata.shared or { featuredata = { }, anchorhash = { }, initialized = false, } tfmdata = otf.copy_to_tfm(otfdata,cache_id) - if not table.is_empty(tfmdata) then + if tfmdata and next(tfmdata) then tfmdata.unique = tfmdata.unique or { } tfmdata.shared = tfmdata.shared or { } -- combine local shared = tfmdata.shared @@ -1490,6 +1493,11 @@ end -- we cannot share descriptions as virtual fonts might extend them (ok, we could -- use a cache with a hash +fonts.formats.dfont = "truetype" +fonts.formats.ttc = "truetype" +fonts.formats.ttf = "truetype" +fonts.formats.otf = "opentype" + function otf.copy_to_tfm(data,cache_id) -- we can save a copy when we reorder the tma to unicode (nasty due to one->many) if data then local glyphs, pfminfo, metadata = data.glyphs or { }, data.pfminfo or { }, data.metadata or { } @@ -1562,13 +1570,15 @@ function otf.copy_to_tfm(data,cache_id) -- we can save a copy when we reorder th designsize = 100 end local spaceunits = 500 - tfm.units = metadata.units_per_em or 1000 - -- we need a runtime lookup because of running from cdrom or zip, brrr - tfm.filename = resolvers.findbinfile(luatex.filename,"") or luatex.filename - tfm.fullname = metadata.fullname + -- we need a runtime lookup because of running from cdrom or zip, brrr (shouldn't we use the basename then?) + tfm.filename = fonts.tfm.checked_filename(luatex) tfm.fontname = metadata.fontname + tfm.fullname = metadata.fullname or tfm.fontname tfm.psname = tfm.fontname or tfm.fullname + tfm.name = tfm.filename or tfm.fullname or tfm.fontname + tfm.units = metadata.units_per_em or 1000 tfm.encodingbytes = 2 + tfm.format = fonts.fontformat(tfm.filename,"opentype") tfm.cidinfo = data.cidinfo tfm.cidinfo.registry = tfm.cidinfo.registry or "" tfm.type = "real" @@ -1653,6 +1663,7 @@ function tfm.read_from_open_type(specification) local s = specification.size local m = otfdata.metadata.math if m then + -- this will move to a function local f = specification.features if f then local f = f.normal @@ -1681,33 +1692,13 @@ function tfm.read_from_open_type(specification) end end tfmtable = tfm.scale(tfmtable,s,specification.relativeid) - -- here we resolve the name; file can be relocated, so this info is not in the cache - local filename = (otfdata and otfdata.luatex and otfdata.luatex.filename) or specification.filename - if not filename then - -- try to locate anyway and set otfdata.luatex.filename - end - if filename then - tfmtable.encodingbytes = 2 - tfmtable.filename = resolvers.findbinfile(filename,"") or filename - tfmtable.fontname = tfmtable.fontname or otfdata.metadata.fontname - tfmtable.fullname = tfmtable.fullname or otfdata.metadata.fullname or tfmtable.fontname - local order = otfdata and otfdata.metadata.order2 - if order == 0 then - tfmtable.format = 'opentype' - elseif order == 1 then - tfmtable.format = 'truetype' - else - tfmtable.format = specification.format - end - tfmtable.name = tfmtable.filename or tfmtable.fullname or tfmtable.fontname - if tfm.fontname_mode == "specification" then - -- not to be used in context ! - local specname = specification.specification - if specname then - tfmtable.name = specname - if trace_defining then - logs.report("define font","overloaded fontname: '%s'",specname) - end + if tfm.fontname_mode == "specification" then + -- not to be used in context ! + local specname = specification.specification + if specname then + tfmtable.name = specname + if trace_defining then + logs.report("define font","overloaded fontname: '%s'",specname) end end end diff --git a/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-otn.lua b/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-otn.lua index 3aa1927d35f..d4f89adc6ec 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-otn.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-otn.lua @@ -123,6 +123,7 @@ results in different tables.</p> local concat, insert, remove = table.concat, table.insert, table.remove 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 +local lpegmatch = lpeg.match local otf = fonts.otf local tfm = fonts.tfm @@ -166,7 +167,7 @@ local zwj = 0x200D local wildcard = "*" local default = "dflt" -local split_at_space = lpeg.Ct(lpeg.splitat(" ")) -- no trailing or multiple spaces anyway +local split_at_space = lpeg.splitters[" "] or lpeg.Ct(lpeg.splitat(" ")) -- no trailing or multiple spaces anyway local glyph = node.id('glyph') local glue = node.id('glue') @@ -2208,11 +2209,11 @@ otf.features.prepare = { } -- document) local function split(replacement,original,cache,unicodes) - -- we can cache this too, but not the same + -- we can cache this too, but not the same (although unicode is a unique enough hash) local o, t, n = { }, { }, 0 for s in gmatch(original,"[^ ]+") do local us = unicodes[s] - if type(us) == "number" then + if type(us) == "number" then -- tonumber(us) o[#o+1] = us else o[#o+1] = us[1] @@ -2221,7 +2222,7 @@ local function split(replacement,original,cache,unicodes) for s in gmatch(replacement,"[^ ]+") do n = n + 1 local us = unicodes[s] - if type(us) == "number" then + if type(us) == "number" then -- tonumber(us) t[o[n]] = us else t[o[n]] = us[1] @@ -2579,6 +2580,46 @@ function prepare_contextchains(tfmdata) end end end + elseif fmt == "glyphs" then + if lookuptype ~= "chainsub" and lookuptype ~= "chainpos" then + logs.report("otf process","unsupported coverage %s for %s",lookuptype,lookupname) + else + local contexts = contextchain[lookupname] + if not contexts then + contexts = { } + contextchain[lookupname] = contexts + end + local t = { } + for nofrules=1,#rules do + -- nearly the same as coverage so we could as well rename it + local rule = rules[nofrules] + local glyphs = rule.glyphs + if glyphs and glyphs.names then + local fore, back, names, sequence = glyphs.fore, glyphs.back, glyphs.names, { } + if fore and fore ~= "" then + fore = lpegmatch(split_at_space,fore) + uncover(fore,sequence,cache,unicodes) + end + local start = #sequence + 1 + names = lpegmatch(split_at_space,names) + uncover(names,sequence,cache,unicodes) + local stop = #sequence + if back and back ~= "" then + back = lpegmatch(split_at_space,back) + uncover(back,sequence,cache,unicodes) + end + if sequence[1] then + t[#t+1] = { nofrules, lookuptype, sequence, start, stop, rule.lookups } + for unic, _ in next, sequence[start] do + local cu = contexts[unic] + if not cu then + contexts[unic] = t + end + end + end + end + end + end end end end diff --git a/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-ott.lua b/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-ott.lua index d26c55f4b82..2be1bf06c00 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-ott.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-ott.lua @@ -672,13 +672,13 @@ local to_scripts = otf.tables.to_scripts local to_languages = otf.tables.to_languages local to_features = otf.tables.to_features -for k, v in pairs(to_features) do +for k, v in next, to_features do local stripped = gsub(k,"%-"," ") to_features[stripped] = v local stripped = gsub(k,"[^a-zA-Z0-9]","") to_features[stripped] = v end -for k, v in pairs(to_features) do +for k, v in next, to_features do to_features[lower(k)] = v end diff --git a/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-tfm.lua b/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-tfm.lua index 4b217a3c407..31ae2cae1c2 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-tfm.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-tfm.lua @@ -279,7 +279,7 @@ t.colorscheme = tfmtable.colorscheme local characters = tfmtable.characters local nameneeded = not tfmtable.shared.otfdata --hack local changed = tfmtable.changed or { } -- for base mode - local ischanged = not table.is_empty(changed) + local ischanged = changed and next(changed) local indices = tfmtable.indices local luatex = tfmtable.luatex local tounicode = luatex and luatex.tounicode @@ -704,6 +704,31 @@ function tfm.replacements(tfm,value) -- tfm.characters[0x0060] = tfm.characters[0x2018] end +-- checking + +function tfm.checked_filename(metadata,whatever) + local foundfilename = metadata.foundfilename + if not foundfilename then + local askedfilename = metadata.filename or "" + if askedfilename ~= "" then + foundfilename = resolvers.findbinfile(askedfilename,"") or "" + if foundfilename == "" then + logs.report("fonts","source file '%s' is not found",askedfilename) + foundfilename = resolvers.findbinfile(file.basename(askedfilename),"") or "" + if foundfilename ~= "" then + logs.report("fonts","using source file '%s' (cache mismatch)",foundfilename) + end + end + elseif whatever then + logs.report("fonts","no source file for '%s'",whatever) + foundfilename = "" + end + metadata.foundfilename = foundfilename + -- logs.report("fonts","using source file '%s'",foundfilename) + end + return foundfilename +end + -- status info statistics.register("fonts load time", function() diff --git a/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-xtx.lua b/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-xtx.lua index 0fa2d696ab0..10062deed95 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-xtx.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/otfl-font-xtx.lua @@ -90,6 +90,7 @@ otf.tables = otf.tables or { } otf.tables.defaults = { dflt = { + "calt", "ccmp", "locl", "rlig", "liga", "clig", "kern", "mark", "mkmk", }, diff --git a/Master/texmf-dist/tex/luatex/luaotfload/otfl-luat-ovr.lua b/Master/texmf-dist/tex/luatex/luaotfload/otfl-luat-ovr.lua index af5e05b364f..20d2b73dafc 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/otfl-luat-ovr.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/otfl-luat-ovr.lua @@ -3,7 +3,7 @@ if not modules then modules = { } end modules ['luat-ovr'] = { comment = "companion to luatex-*.tex", author = "Khaled Hosny and Elie Roux", copyright = "Luaotfload Development Team", - license = "GPL" + license = "GNU GPL v2" } @@ -24,6 +24,16 @@ function logs.report(category,fmt,...) end end +function logs.info(category,fmt,...) + if fmt then + write_nl(format("%s | %s: %s",name,category,format(fmt,...))) + elseif category then + write_nl(format("%s | %s",name,category)) + else + write_nl(format("%s |",name)) + end +end + function logs.simple(fmt,...) if fmt then write_nl('log', format("%s | %s",name,format(fmt,...))) diff --git a/Master/texmf-dist/tex/luatex/luaotfload/otfl-node-res.lua b/Master/texmf-dist/tex/luatex/luaotfload/otfl-node-res.lua index 2657dfa1e71..a8ea8745a72 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/otfl-node-res.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/otfl-node-res.lua @@ -24,7 +24,7 @@ nodes.whatsits = { } -- table.swapped(node.whatsits()) local reserved = { } local whatsits = nodes.whatsits -for k, v in pairs(node.whatsits()) do +for k, v in next, node.whatsits() do whatsits[k], whatsits[v] = v, k -- two way end |