From ab2be7b7e82ea1b0103b70b327137a939df6b8fa Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Sun, 10 Aug 2014 14:36:13 +0200 Subject: [conf, main] add support for and preliminary implementation of verbose font definers The definers ``info_patch`` and ``info_generic`` wrap the two existing font definers in a function that emits verbose information about the definitions taking place. --- src/luaotfload-configuration.lua | 9 ++++++++- src/luaotfload-main.lua | 40 +++++++++++++++++++++++++++++++--------- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/luaotfload-configuration.lua b/src/luaotfload-configuration.lua index ec38d90..a375c37 100644 --- a/src/luaotfload-configuration.lua +++ b/src/luaotfload-configuration.lua @@ -432,7 +432,14 @@ local option_spec = { definer = { in_t = string_t, out_t = string_t, - transform = function (d) return d == "generic" and d or "patch" end, + transform = function (d) + if d == "generic" or d == "patch" + or d == "info_generic" or d == "info_patch" + then + return d + end + return "patch" + end, }, log_level = { in_t = number_t, diff --git a/src/luaotfload-main.lua b/src/luaotfload-main.lua index 773a3cf..b5cb1d3 100644 --- a/src/luaotfload-main.lua +++ b/src/luaotfload-main.lua @@ -4,7 +4,7 @@ -- REQUIREMENTS: luatex v.0.79 or later; packages lualibs, luatexbase -- AUTHOR: Élie Roux, Khaled Hosny, Philipp Gesang -- VERSION: same as Luaotfload --- MODIFIED: 2014-07-24 22:08:34+0200 +-- MODIFIED: 2014-08-08 23:14:37+0200 ----------------------------------------------------------------------- -- --- Note: @@ -672,13 +672,13 @@ create_callback("luaotfload.patch_font", "simple", dummy_function) --doc]]-- -local read_font_file = fonts.definers.read -local definers = { - generic = read_font_file, - --- spec -> size -> id -> tmfdata - patch = function (specification, size, id) - local tfmdata = read_font_file (specification, size, id) +local definers = { } --- (string, spec -> size -> id -> tmfdata) hash_t +do + local read = fonts.definers.read + + local patch = function (specification, size, id) + local tfmdata = read (specification, size, id) if type (tfmdata) == "table" and tfmdata.shared then --- We need to test for the “shared” field here --- or else the fontspec capheight callback will @@ -686,8 +686,30 @@ local definers = { call_callback ("luaotfload.patch_font", tfmdata, specification) end return tfmdata - end, -} + end + + local mk_info = function (name) + local definer = name == "patch" and patch or read + return function (specification, size, id) + logreport ("both", 0, "main", "active font definer: %q", name) + logreport ("both", 0, "main", " > defining font no. %d", id) + logreport ("both", 0, "main", " > spec %q", specification) + logreport ("both", 0, "main", " > at size %.2f pt", size / 2^16) + local tfmdata = definer (specification, size, id) + if not tfmdata then + logreport ("both", 0, "main", "font definition failed") + return + end + logreport ("both", 0, "main", "font definition successful") + return tfmdata + end + end + + definers.patch = patch + definers.generic = read + definers.info_patch = mk_info "patch" + definers.info_generic = mk_info "generic" +end reset_callback "define_font" -- cgit v1.2.3 From e8d763adc95f74a036232ccbca36b24a662b1256 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Fri, 5 Sep 2014 23:18:27 +0200 Subject: [auxiliary] robustify font property lookups This adresses an issue with entries in the font table that lack the common font structure (manually parsed fonts??). Subtable lookups are now guarded with nil-checks. Reported by Herbert Voss Signed-off-by: Philipp Gesang --- src/luaotfload-auxiliary.lua | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/luaotfload-auxiliary.lua b/src/luaotfload-auxiliary.lua index 89bf51b..b05d491 100644 --- a/src/luaotfload-auxiliary.lua +++ b/src/luaotfload-auxiliary.lua @@ -417,7 +417,9 @@ least one feature. local provides_script = function (font_id, asked_script) asked_script = stringlower(asked_script) if font_id and font_id > 0 then - local fontdata = identifiers[font_id].shared.rawdata + local tfmdata = identifiers[font_id] if not tfmdata then return false end + local shared = tfmdata.shared if not shared then return false end + local fontdata = shared.rawdata if not fontdata then return false end if fontdata then local fontname = fontdata.metadata.fontname local features = fontdata.resources.features @@ -455,7 +457,9 @@ local provides_language = function (font_id, asked_script, asked_language) asked_script = stringlower(asked_script) asked_language = stringlower(asked_language) if font_id and font_id > 0 then - local fontdata = identifiers[font_id].shared.rawdata + local tfmdata = identifiers[font_id] if not tfmdata then return false end + local shared = tfmdata.shared if not shared then return false end + local fontdata = shared.rawdata if not fontdata then return false end if fontdata then local fontname = fontdata.metadata.fontname local features = fontdata.resources.features @@ -527,7 +531,9 @@ local provides_feature = function (font_id, asked_script, asked_feature = lpegmatch(strip_garbage, asked_feature) if font_id and font_id > 0 then - local fontdata = identifiers[font_id].shared.rawdata + local tfmdata = identifiers[font_id] if not tfmdata then return false end + local shared = tfmdata.shared if not shared then return false end + local fontdata = shared.rawdata if not fontdata then return false end if fontdata then local features = fontdata.resources.features local fontname = fontdata.metadata.fontname -- cgit v1.2.3 From 225a39acb0ee3894b848cd7c8a8e71f216bfd623 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Fri, 5 Sep 2014 23:41:43 +0200 Subject: [auxiliary] eliminate redundant conditions --- src/luaotfload-auxiliary.lua | 100 ++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 53 deletions(-) diff --git a/src/luaotfload-auxiliary.lua b/src/luaotfload-auxiliary.lua index b05d491..7ea747e 100644 --- a/src/luaotfload-auxiliary.lua +++ b/src/luaotfload-auxiliary.lua @@ -420,24 +420,22 @@ local provides_script = function (font_id, asked_script) local tfmdata = identifiers[font_id] if not tfmdata then return false end local shared = tfmdata.shared if not shared then return false end local fontdata = shared.rawdata if not fontdata then return false end - if fontdata then - local fontname = fontdata.metadata.fontname - local features = fontdata.resources.features - for method, featuredata in next, features do - --- where method: "gpos" | "gsub" - for feature, data in next, featuredata do - if data[asked_script] then - report ("log", 1, "aux", - "font no %d (%s) defines feature %s for script %s", - font_id, fontname, feature, asked_script) - return true - end + local fontname = fontdata.metadata.fontname + local features = fontdata.resources.features + for method, featuredata in next, features do + --- where method: "gpos" | "gsub" + for feature, data in next, featuredata do + if data[asked_script] then + report ("log", 1, "aux", + "font no %d (%s) defines feature %s for script %s", + font_id, fontname, feature, asked_script) + return true end end - report ("log", 0, "aux", - "font no %d (%s) defines no feature for script %s", - font_id, fontname, asked_script) end + report ("log", 0, "aux", + "font no %d (%s) defines no feature for script %s", + font_id, fontname, asked_script) end report ("log", 0, "aux", "no font with id %d", font_id) return false @@ -460,28 +458,26 @@ local provides_language = function (font_id, asked_script, asked_language) local tfmdata = identifiers[font_id] if not tfmdata then return false end local shared = tfmdata.shared if not shared then return false end local fontdata = shared.rawdata if not fontdata then return false end - if fontdata then - local fontname = fontdata.metadata.fontname - local features = fontdata.resources.features - for method, featuredata in next, features do - --- where method: "gpos" | "gsub" - for feature, data in next, featuredata do - local scriptdata = data[asked_script] - if scriptdata and scriptdata[asked_language] then - report ("log", 1, "aux", - "font no %d (%s) defines feature %s " - .. "for script %s with language %s", - font_id, fontname, feature, - asked_script, asked_language) - return true - end + local fontname = fontdata.metadata.fontname + local features = fontdata.resources.features + for method, featuredata in next, features do + --- where method: "gpos" | "gsub" + for feature, data in next, featuredata do + local scriptdata = data[asked_script] + if scriptdata and scriptdata[asked_language] then + report ("log", 1, "aux", + "font no %d (%s) defines feature %s " + .. "for script %s with language %s", + font_id, fontname, feature, + asked_script, asked_language) + return true end end - report ("log", 0, "aux", - "font no %d (%s) defines no feature " - .. "for script %s with language %s", - font_id, fontname, asked_script, asked_language) end + report ("log", 0, "aux", + "font no %d (%s) defines no feature " + .. "for script %s with language %s", + font_id, fontname, asked_script, asked_language) end report ("log", 0, "aux", "no font with id %d", font_id) return false @@ -534,28 +530,26 @@ local provides_feature = function (font_id, asked_script, local tfmdata = identifiers[font_id] if not tfmdata then return false end local shared = tfmdata.shared if not shared then return false end local fontdata = shared.rawdata if not fontdata then return false end - if fontdata then - local features = fontdata.resources.features - local fontname = fontdata.metadata.fontname - for method, featuredata in next, features do - --- where method: "gpos" | "gsub" - local feature = featuredata[asked_feature] - if feature then - local scriptdata = feature[asked_script] - if scriptdata and scriptdata[asked_language] then - report ("log", 1, "aux", - "font no %d (%s) defines feature %s " - .. "for script %s with language %s", - font_id, fontname, asked_feature, - asked_script, asked_language) - return true - end + local features = fontdata.resources.features + local fontname = fontdata.metadata.fontname + for method, featuredata in next, features do + --- where method: "gpos" | "gsub" + local feature = featuredata[asked_feature] + if feature then + local scriptdata = feature[asked_script] + if scriptdata and scriptdata[asked_language] then + report ("log", 1, "aux", + "font no %d (%s) defines feature %s " + .. "for script %s with language %s", + font_id, fontname, asked_feature, + asked_script, asked_language) + return true end end - report ("log", 0, "aux", - "font no %d (%s) does not define feature %s for script %s with language %s", - font_id, fontname, asked_feature, asked_script, asked_language) end + report ("log", 0, "aux", + "font no %d (%s) does not define feature %s for script %s with language %s", + font_id, fontname, asked_feature, asked_script, asked_language) end report ("log", 0, "aux", "no font with id %d", font_id) return false -- cgit v1.2.3 From 54a4ff05122bf940f997ed73810afd47b9d7712f Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Sat, 6 Sep 2014 11:14:57 +0200 Subject: [main] add name fields to verbose definer --- src/luaotfload-main.lua | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/luaotfload-main.lua b/src/luaotfload-main.lua index b5cb1d3..93256ee 100644 --- a/src/luaotfload-main.lua +++ b/src/luaotfload-main.lua @@ -691,17 +691,23 @@ do local mk_info = function (name) local definer = name == "patch" and patch or read return function (specification, size, id) - logreport ("both", 0, "main", "active font definer: %q", name) - logreport ("both", 0, "main", " > defining font no. %d", id) + logreport ("both", 0, "main", "defining font no. %d", id) + logreport ("both", 0, "main", " > active font definer: %q", name) logreport ("both", 0, "main", " > spec %q", specification) logreport ("both", 0, "main", " > at size %.2f pt", size / 2^16) - local tfmdata = definer (specification, size, id) - if not tfmdata then - logreport ("both", 0, "main", "font definition failed") + local result = definer (specification, size, id) + if not result then + logreport ("both", 0, "main", " > font definition failed") return + elseif type (result) == "number" then + logreport ("both", 0, "main", " > font definition yielded id %d", result) + return result end - logreport ("both", 0, "main", "font definition successful") - return tfmdata + logreport ("both", 0, "main", " > font definition successful") + logreport ("both", 0, "main", " > name %q", result.name or "") + logreport ("both", 0, "main", " > fontname %q", result.fontname or "") + logreport ("both", 0, "main", " > fullname %q", result.fullname or "") + return result end end -- cgit v1.2.3 From f48e304b01274ba41faf59572b605c0f554a04d9 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Thu, 18 Sep 2014 18:38:18 +0200 Subject: [fontloader] sync with Context as of 2014-09-18 --- src/luaotfload-fontloader.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/luaotfload-fontloader.lua b/src/luaotfload-fontloader.lua index 660524e..d58fa5f 100644 --- a/src/luaotfload-fontloader.lua +++ b/src/luaotfload-fontloader.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 07/29/14 00:30:11 +-- merge date : 09/18/14 11:17:09 do -- begin closure to overcome local limits and interference @@ -2581,11 +2581,11 @@ function string.booleanstring(str) return str=="yes" or str=="on" or str=="t" end end -function string.is_boolean(str,default) +function string.is_boolean(str,default,strict) if type(str)=="string" then - if str=="true" or str=="yes" or str=="on" or str=="t" or str=="1" then + if str=="true" or str=="yes" or str=="on" or str=="t" or (not strict and str=="1") then return true - elseif str=="false" or str=="no" or str=="off" or str=="f" or str=="0" then + elseif str=="false" or str=="no" or str=="off" or str=="f" or (not strict and str=="0") then return false end end @@ -2940,7 +2940,7 @@ local format_f=function(f) n=n+1 return format("format('%%%sf',a%s)",f,n) end -local format_F=function() +local format_F=function(f) n=n+1 if not f or f=="" then return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or format((a%s %% 1 == 0) and '%%i' or '%%.9f',a%s))",n,n,n,n) @@ -3173,7 +3173,6 @@ local builder=Cs { "start", +V("j")+V("J") +V("m")+V("M") +V("z") -+V("*") )+V("*") )*(P(-1)+Carg(1)) )^0, @@ -3217,6 +3216,7 @@ local builder=Cs { "start", ["a"]=(prefix_any*P("a"))/format_a, ["A"]=(prefix_any*P("A"))/format_A, ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest, + ["?"]=Cs(((1-P("%"))^1 )^1)/format_rest, ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension, } local direct=Cs ( -- cgit v1.2.3 From 245fe7f679148f4f268109cc702497126610fbc0 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Fri, 26 Sep 2014 18:45:13 +0200 Subject: [fontloader] sync with Context as of 2014-09-26 --- src/luaotfload-fontloader.lua | 56 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/src/luaotfload-fontloader.lua b/src/luaotfload-fontloader.lua index d58fa5f..4aa03e6 100644 --- a/src/luaotfload-fontloader.lua +++ b/src/luaotfload-fontloader.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 09/18/14 11:17:09 +-- merge date : 09/26/14 11:42:21 do -- begin closure to overcome local limits and interference @@ -6706,7 +6706,7 @@ local report_otf=logs.reporter("fonts","otf loading") local fonts=fonts local otf=fonts.handlers.otf otf.glists={ "gsub","gpos" } -otf.version=2.759 +otf.version=2.760 otf.cache=containers.define("fonts","otf",otf.version,true) local fontdata=fonts.hashes.identifiers local chardata=characters and characters.data @@ -6832,7 +6832,6 @@ local valid_fields=table.tohash { "extrema_bound", "familyname", "fontname", - "fontname", "fontstyle_id", "fontstyle_name", "fullname", @@ -7067,6 +7066,7 @@ function otf.load(filename,sub,featurefile) }, lookuptypes={}, }, + warnings={}, metadata={ }, properties={ @@ -8194,6 +8194,10 @@ actions["check glyphs"]=function(data,filename,raw) description.glyph=nil end end +local valid=(lpeg.R("\x00\x7E")-lpeg.S("(){}[]<>%/ \n\r\f\v"))^0*lpeg.P(-1) +local function valid_ps_name(str) + return str and str~="" and #str<64 and lpegmatch(valid,str) and true or false +end actions["check metadata"]=function(data,filename,raw) local metadata=data.metadata for _,k in next,mainfields do @@ -8211,9 +8215,36 @@ actions["check metadata"]=function(data,filename,raw) end end if metadata.validation_state and table.contains(metadata.validation_state,"bad_ps_fontname") then - local name=file.nameonly(filename) - metadata.fontname="bad-fontname-"..name - metadata.fullname="bad-fullname-"..name + local function valid(what) + local names=raw.names + for i=1,#names do + local list=names[i] + local names=list.names + if names then + local name=names[what] + if name and valid_ps_name(name) then + return name + end + end + end + end + local function check(what) + local oldname=metadata[what] + if valid_ps_name(oldname) then + report_otf("ignoring warning %a because %s %a is proper ASCII","bad_ps_fontname",what,oldname) + else + local newname=valid(what) + if not newname then + newname=formatters["bad-%s-%s"](what,file.nameonly(filename)) + end + local warning=formatters["overloading %s from invalid ASCII name %a to %a"](what,oldname,newname) + data.warnings[#data.warnings+1]=warning + report_otf(warning) + metadata[what]=newname + end + end + check("fontname") + check("fullname") end end actions["cleanup tables"]=function(data,filename,raw) @@ -8334,6 +8365,7 @@ end local function copytotfm(data,cache_id) if data then local metadata=data.metadata + local warnings=data.warnings local resources=data.resources local properties=derivetable(data.properties) local descriptions=derivetable(data.descriptions) @@ -8408,6 +8440,7 @@ local function copytotfm(data,cache_id) local filename=constructors.checkedfilename(resources) local fontname=metadata.fontname local fullname=metadata.fullname or fontname + local psname=fontname or fullname local units=metadata.units_per_em or 1000 if units==0 then units=1000 @@ -8489,8 +8522,16 @@ local function copytotfm(data,cache_id) properties.filename=filename properties.fontname=fontname properties.fullname=fullname - properties.psname=fontname or fullname + properties.psname=psname properties.name=filename or fullname + if warnings and #warnings>0 then + report_otf("warnings for font: %s",filename) + report_otf() + for i=1,#warnings do + report_otf(" %s",warnings[i]) + end + report_otf() + end return { characters=characters, descriptions=descriptions, @@ -8499,6 +8540,7 @@ local function copytotfm(data,cache_id) resources=resources, properties=properties, goodies=goodies, + warnings=warnings, } end end -- cgit v1.2.3