From 239fc2639fd42f6ad1c44bb256ae2f98ed164b45 Mon Sep 17 00:00:00 2001 From: Marius Date: Sat, 16 Mar 2013 03:00:15 +0200 Subject: beta 2013.03.16 01:51 --- tex/context/base/cont-new.mkii | 2 +- tex/context/base/cont-new.mkiv | 2 +- tex/context/base/context-version.pdf | Bin 4137 -> 4133 bytes tex/context/base/context-version.png | Bin 40388 -> 40062 bytes tex/context/base/context.mkii | 2 +- tex/context/base/context.mkiv | 2 +- tex/context/base/data-res.lua | 8 +- tex/context/base/font-ctx.lua | 68 ++-- tex/context/base/font-fea.mkvi | 86 ++-- tex/context/base/font-otd.lua | 44 +- tex/context/base/font-otn.lua | 4 +- tex/context/base/font-syn.lua | 441 +++++++++++---------- tex/context/base/status-files.pdf | Bin 24800 -> 24747 bytes tex/context/base/status-lua.pdf | Bin 210821 -> 210817 bytes tex/generic/context/luatex/luatex-fonts-merged.lua | 6 +- 15 files changed, 357 insertions(+), 308 deletions(-) (limited to 'tex') diff --git a/tex/context/base/cont-new.mkii b/tex/context/base/cont-new.mkii index 80abb9ff6..24f5b6125 100644 --- a/tex/context/base/cont-new.mkii +++ b/tex/context/base/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2013.03.15 19:22} +\newcontextversion{2013.03.16 01:51} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv index 26eb00a9e..40af8292c 100644 --- a/tex/context/base/cont-new.mkiv +++ b/tex/context/base/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2013.03.15 19:22} +\newcontextversion{2013.03.16 01:51} %D This file is loaded at runtime, thereby providing an excellent place for %D hacks, patches, extensions and new features. diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf index d34e7e92a..b6cf0ade4 100644 Binary files a/tex/context/base/context-version.pdf and b/tex/context/base/context-version.pdf differ diff --git a/tex/context/base/context-version.png b/tex/context/base/context-version.png index 828e90b95..773e1bda4 100644 Binary files a/tex/context/base/context-version.png and b/tex/context/base/context-version.png differ diff --git a/tex/context/base/context.mkii b/tex/context/base/context.mkii index fab2ab6fd..e66203c0c 100644 --- a/tex/context/base/context.mkii +++ b/tex/context/base/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2013.03.15 19:22} +\edef\contextversion{2013.03.16 01:51} %D For those who want to use this: diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index 30a89aa46..b489389a2 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -25,7 +25,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2013.03.15 19:22} +\edef\contextversion{2013.03.16 01:51} %D For those who want to use this: diff --git a/tex/context/base/data-res.lua b/tex/context/base/data-res.lua index 0e87aeb78..f0b7a96cb 100644 --- a/tex/context/base/data-res.lua +++ b/tex/context/base/data-res.lua @@ -1653,13 +1653,11 @@ function resolvers.dowithfilesintree(pattern,handle,before,after) -- will move, local files = instance.files[blobpath] local total, checked, done = 0, 0, 0 if files then - for k,v in next, files do + for k, v in table.sortedhash(files) do -- next, files do, beware: this is not the resolve order total = total + 1 if find(k,"^remap:") then - k = files[k] - v = k -- files[k] -- chained - end - if find(k,pattern) then + -- forget about these + elseif find(k,pattern) then if type(v) == "string" then checked = checked + 1 if handle(blobtype,blobpath,v,k) then diff --git a/tex/context/base/font-ctx.lua b/tex/context/base/font-ctx.lua index 2e5b9b6cd..51924e70c 100644 --- a/tex/context/base/font-ctx.lua +++ b/tex/context/base/font-ctx.lua @@ -603,7 +603,7 @@ local function contextnumber(name) -- will be replaced end end -local function mergecontext(currentnumber,extraname,option) -- number string number +local function mergecontext(currentnumber,extraname,option) -- number string number (used in scrp-ini local extra = setups[extraname] if extra then local current = setups[numbers[currentnumber]] @@ -712,7 +712,7 @@ local function registercontextfeature(mergedname,extraname,how) local number = #numbers + 1 mergedfeatures.number = number numbers[number] = mergedname - merged[number] = option + merged[number] = how == "=" and 1 or 2 -- 1=replace, 2=combine setups[mergedname] = mergedfeatures return number -- contextnumber(mergedname) else @@ -749,27 +749,27 @@ end local withcache = { } -- concat might be less efficient than nested tables -local function withset(name,what) - local zero = texattribute[0] - local hash = zero .. "+" .. name .. "*" .. what - local done = withcache[hash] - if not done then - done = mergecontext(zero,name,what) - withcache[hash] = done - end - texattribute[0] = done -end - -local function withfnt(name,what,font) - local font = font or currentfont() - local hash = font .. "*" .. name .. "*" .. what - local done = withcache[hash] - if not done then - done = registercontext(font,name,what) - withcache[hash] = done - end - texattribute[0] = done -end +-- local function withset(name,what) +-- local zero = texattribute[0] +-- local hash = zero .. "+" .. name .. "*" .. what +-- local done = withcache[hash] +-- if not done then +-- done = mergecontext(zero,name,what) +-- withcache[hash] = done +-- end +-- texattribute[0] = done +-- end +-- +-- local function withfnt(name,what,font) +-- local font = font or currentfont() +-- local hash = font .. "*" .. name .. "*" .. what +-- local done = withcache[hash] +-- if not done then +-- done = registercontext(font,name,what) +-- withcache[hash] = done +-- end +-- texattribute[0] = done +-- end function specifiers.showcontext(name) return setups[name] or setups[numbers[name]] or setups[numbers[tonumber(name)]] or { } @@ -1469,15 +1469,10 @@ function commands.resetfontfeature() texattribute[0] = 0 end -function commands.addfs(tag) withset(tag, 1) end -function commands.subfs(tag) withset(tag,-1) end -function commands.addff(tag) withfnt(tag, 2) end -function commands.subff(tag) withfnt(tag,-2) end - --- function commands.addfontfeaturetoset (tag) withset(tag, 1) end --- function commands.subtractfontfeaturefromset (tag) withset(tag,-1) end --- function commands.addfontfeaturetofont (tag) withfnt(tag, 2) end --- function commands.subtractfontfeaturefromfont(tag) withfnt(tag,-2) end +-- function commands.addfs(tag) withset(tag, 1) end +-- function commands.subfs(tag) withset(tag,-1) end +-- function commands.addff(tag) withfnt(tag, 2) end -- on top of font features +-- function commands.subff(tag) withfnt(tag,-2) end -- on top of font features function commands.cleanfontname (name) context(names.cleanname(name)) end @@ -1690,6 +1685,12 @@ commands.definefontfeature = presetcontext local cache = { } +local hows = { + ["+"] = "add", + ["-"] = "subtract", + ["="] = "replace", +} + function commands.feature(how,parent,name,font) if not how then if trace_features and texattribute[0] ~= 0 then @@ -1717,8 +1718,7 @@ function commands.feature(how,parent,name,font) done = registercontextfeature(hash,full,how) cache[hash] = done if trace_features then - report_cummulative("font %!font:name!, %s %a : %!font:features!", - fontdata[font or true],how == "+" and "add" or how == "-" and "subtract" or "replace",full,setups[numbers[done]]) + report_cummulative("font %!font:name!, %s %a : %!font:features!",fontdata[font or true],hows[how],full,setups[numbers[done]]) end end texattribute[0] = done diff --git a/tex/context/base/font-fea.mkvi b/tex/context/base/font-fea.mkvi index d23e15ccc..71067d3ea 100644 --- a/tex/context/base/font-fea.mkvi +++ b/tex/context/base/font-fea.mkvi @@ -133,39 +133,6 @@ \attribute\zerocount\zerocount % first in list, so fast match -\let\currentfeature\empty - -% ! ! ! very experimental, some test code for idris advanced features ! ! ! -% -% \startbuffer -% \definefontfeature[smallcaps][smallcaps][script=latn] -% \definefontfeature[oldstyle] [oldstyle] [script=latn] -% -% \definedfont[name:cambria at 15pt] -% -% Hello there {\setff{smallcaps}capped 123 \setff{oldstyle}123!} \blank -% Hello there {\addff{smallcaps}capped 123 \addff{oldstyle}123!} \blank -% Hello there {\addff{smallcaps}capped \subff{smallcaps}normal} \blank -% \stopbuffer -% -% \typebuffer \getbuffer - -\unexpanded\def\featureattribute#feature{\ctxcommand{featureattribute("#feature")}} -\unexpanded\def\setfontfeature #feature{\ctxcommand{setfontfeature("#feature")}\edef\currentfeature{#feature}} -%unexpanded\def\resetfontfeature {\ctxcommand{resetfontfeature()}\let\currentfeature\empty} % initial value -\unexpanded\def\resetfontfeature {\attribute\zerocount\zerocount \let\currentfeature\empty} % initial value - -\unexpanded\def\addfontfeaturetoset #feature{\ctxcommand{addfs("#feature")}} % merge -\unexpanded\def\subtractfontfeaturefromset #feature{\ctxcommand{subfs("#feature")}} % merge -\unexpanded\def\addfontfeaturetofont #feature{\ctxcommand{addff("#feature")}} % overload -\unexpanded\def\subtractfontfeaturefromfont#feature{\ctxcommand{subff("#feature")}} % overload - -\let\setff\setfontfeature -\let\addfs\addfontfeaturetoset -\let\subfs\subtractfontfeaturefromset -\let\addff\addfontfeaturetofont -\let\subff\subtractfontfeaturefromfont - % beware: these are global features on top of existing font features \let\currentfeature \s!current @@ -181,20 +148,20 @@ \unexpanded\def\replacefeature {\doifnextoptionalelse\font_feature_replace_yes \font_feature_replace_nop } \unexpanded\def\feature {\doifnextoptionalelse\font_feature_yes \font_feature_nop } -\unexpanded\def\font_feature_add_yes [#1]{\edef\m_font_feature_asked{#1}\font_feature_add} -\unexpanded\def\font_feature_add_nop #1{\edef\m_font_feature_asked{#1}\font_feature_add} +\unexpanded\def\font_feature_add_yes [#feature]{\edef\m_font_feature_asked{#feature}\font_feature_add} +\unexpanded\def\font_feature_add_nop #feature{\edef\m_font_feature_asked{#feature}\font_feature_add} -\unexpanded\def\font_feature_subtract_yes[#1]{\edef\m_font_feature_asked{#1}\font_feature_subtract} -\unexpanded\def\font_feature_subtract_nop #1{\edef\m_font_feature_asked{#1}\font_feature_subtract} +\unexpanded\def\font_feature_subtract_yes[#feature]{\edef\m_font_feature_asked{#feature}\font_feature_subtract} +\unexpanded\def\font_feature_subtract_nop #feature{\edef\m_font_feature_asked{#feature}\font_feature_subtract} -\unexpanded\def\font_feature_replace_yes [#1]{\edef\m_font_feature_asked{#1}\font_feature_replace} -\unexpanded\def\font_feature_replace_nop #1{\edef\m_font_feature_asked{#1}\font_feature_replace} +\unexpanded\def\font_feature_replace_yes [#feature]{\edef\m_font_feature_asked{#feature}\font_feature_replace} +\unexpanded\def\font_feature_replace_nop #feature{\edef\m_font_feature_asked{#feature}\font_feature_replace} \let\doaddfeature \font_feature_add_nop % low level faster ones \let\dosubtractfeature\font_feature_subtract_nop % low level faster ones \let\doreplacefeature \font_feature_replace_nop % low level faster ones -\def\font_feature_add +\unexpanded\def\font_feature_add {\ifnum\c_font_feature_state=\plusone \ifx\m_font_feature_asked\currentfeature\else \font_feature_add_indeed @@ -203,7 +170,7 @@ \font_feature_add_indeed \fi} -\def\font_feature_add_indeed +\unexpanded\def\font_feature_add_indeed {\ctxcommand{feature("+","\m_font_feature_list","\m_font_feature_asked")}% \edef\m_font_feature_list{\m_font_feature_list+\m_font_feature_asked}% also + at the lua end \c_font_feature_state\plusone @@ -218,7 +185,7 @@ \font_feature_subtract_indeed \fi} -\def\font_feature_subtract_indeed +\unexpanded\def\font_feature_subtract_indeed {\ctxcommand{feature("-","\m_font_feature_list","\m_font_feature_asked")}% \edef\m_font_feature_list{\m_font_feature_list-\m_font_feature_asked}% also - at the lua end \c_font_feature_state\minusone @@ -233,7 +200,7 @@ \font_feature_replace_indeed \fi} -\def\font_feature_replace_indeed +\unexpanded\def\font_feature_replace_indeed {\ctxcommand{feature("=","\m_font_feature_list","\m_font_feature_asked")}% \edef\m_font_feature_list{\m_font_feature_list=\m_font_feature_asked}% also = at the lua end \c_font_feature_state\zerocount @@ -244,7 +211,7 @@ \font_feature_reset_indeed \fi} -\def\font_feature_reset_indeed +\unexpanded\def\font_feature_reset_indeed {\let\m_font_feature_asked\empty \let\currentfeature \s!current \let\m_font_feature_list \s!current @@ -255,14 +222,14 @@ \font_feature_revive_indeed \fi} -\def\font_feature_revive_indeed +\unexpanded\def\font_feature_revive_indeed {\ctxcommand{feature(true,"\m_font_feature_list")}} \installcorenamespace{featureyes} \installcorenamespace{featurenop} -\unexpanded\def\font_feature_yes[#1]{\csname\??featureyes\ifcsname\??featureyes#1\endcsname#1\else\s!unknown\fi\endcsname} -\unexpanded\def\font_feature_nop #1{\csname\??featurenop\ifcsname\??featurenop#1\endcsname#1\else\s!unknown\fi\endcsname} +\unexpanded\def\font_feature_yes[#method]{\csname\??featureyes\ifcsname\??featureyes#1\endcsname#1\else\s!unknown\fi\endcsname} +\unexpanded\def\font_feature_nop #method{\csname\??featurenop\ifcsname\??featurenop#1\endcsname#1\else\s!unknown\fi\endcsname} \letvalue{\??featureyes+}\addfeature \letvalue{\??featurenop+}\addfeature @@ -294,6 +261,31 @@ \letvalue{\??featureyes\s!unknown}\empty \letvalue{\??featurenop\s!unknown}\empty +% just for old times sake: + +\unexpanded\def\featureattribute#feature% + {\ctxcommand{featureattribute("#feature")}} + +\unexpanded\def\setfontfeature #feature% + {\edef\currentfeature{#feature}% + \let\m_font_feature_list\currentfeature + \ctxcommand{setfontfeature("\currentfeature")}} + +\let\resetfontfeature\resetfeature + +% these are obsolete (don't use them any longer) + +\let\addfontfeaturetoset \font_feature_add_nop +\let\subtractfontfeaturefromset \font_feature_subtract_nop +\let\addfontfeaturetofont \font_feature_add_nop +\let\subtractfontfeaturefromfont\font_feature_subtract_nop + +\let\setff\setfontfeature +\let\addfs\addfontfeaturetoset +\let\subfs\subtractfontfeaturefromset +\let\addff\addfontfeaturetofont +\let\subff\subtractfontfeaturefromfont + %D \macros %D {os} %D diff --git a/tex/context/base/font-otd.lua b/tex/context/base/font-otd.lua index 9ff16ffd5..d2562d08a 100644 --- a/tex/context/base/font-otd.lua +++ b/tex/context/base/font-otd.lua @@ -126,9 +126,13 @@ local function initialize(sequence,script,language,s_enabled,a_enabled,font,attr local features = sequence.features if features then for kind, scripts in next, features do - local s_e = s_enabled and s_enabled[kind] -- the value - local a_e = a_enabled and a_enabled[kind] -- the value - local e_e = s_e or a_e -- todo: when one of them is true and the other is a value + local e_e + local a_e = a_enabled and a_enabled[kind] -- the value (location) + if a_e ~= nil then + e_e = a_e + else + e_e = s_enabled and s_enabled[kind] -- the value (font) + end if e_e then local languages = scripts[script] or scripts[wildcard] if languages then @@ -148,14 +152,19 @@ local function initialize(sequence,script,language,s_enabled,a_enabled,font,attr end if valid then local attribute = autofeatures[kind] or false - if a_e and dynamic < 0 then - valid = false - end + -- if a_e and dynamic < 0 then + -- valid = false + -- end + -- if trace_applied then + -- local typ, action = match(sequence.type,"(.*)_(.*)") -- brrr + -- report_process( + -- "%s font: %03i, dynamic: %03i, kind: %s, script: %-4s, language: %-4s (%-4s), type: %s, action: %s, name: %s", + -- (valid and "+") or "-",font,attr or 0,kind,script,language,what,typ,action,sequence.name) + -- end if trace_applied then - local typ, action = match(sequence.type,"(.*)_(.*)") -- brrr report_process( - "%s font: %03i, dynamic: %03i, kind: %s, script: %-4s, language: %-4s (%-4s), type: %s, action: %s, name: %s", - (valid and "+") or "-",font,attr or 0,kind,script,language,what,typ,action,sequence.name) + "%s font %s, dynamic %s (%s), kind %a, script %a, language %a (%s), value %a, action %s, name %a", + font,attr or 0,dynamic,kind,script,language,what,valid,sequence.name) end return { valid, attribute, sequence.chain or 0, kind, sequence } end @@ -181,15 +190,22 @@ function otf.dataset(tfmdata,font,attr) -- attr only when explicit (as in specia local script, language, s_enabled, a_enabled, dynamic if attr and attr ~= 0 then + dynamic = contextmerged[attr] or 0 local features = contextsetups[contextnumbers[attr]] -- could be a direct list -- local features = contextresolved[attr] language = features.language or "dflt" script = features.script or "dflt" - a_enabled = features - dynamic = contextmerged[attr] or 0 - if dynamic == 2 or dynamic == -2 then - -- font based - s_enabled = tfmdata.shared.features + a_enabled = features -- location based + -- if dynamic == 1 or dynamic == -2 then + -- s_enabled = tfmdata.shared.features -- font based + -- end + if dynamic == 2 then -- or dynamic == -2 then + -- merge + s_enabled = tfmdata.shared.features -- font based + -- elseif dynamic == 1 then -- or dynamic == -1 then + -- -- replace + -- else + -- -- error end else local properties = tfmdata.properties diff --git a/tex/context/base/font-otn.lua b/tex/context/base/font-otn.lua index 72216f9db..3b0e44e17 100644 --- a/tex/context/base/font-otn.lua +++ b/tex/context/base/font-otn.lua @@ -575,10 +575,10 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) if lig then if trace_ligatures then local stopchar = stop.char - head, start = markstoligature(kind,lookupname,start,stop,lig) + head, start = markstoligature(kind,lookupname,head,start,stop,lig) logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char)) else - head, start = markstoligature(kind,lookupname,start,stop,lig) + head, start = markstoligature(kind,lookupname,head,start,stop,lig) end return head, start, true else diff --git a/tex/context/base/font-syn.lua b/tex/context/base/font-syn.lua index ad8cd2b1d..81e27afd6 100644 --- a/tex/context/base/font-syn.lua +++ b/tex/context/base/font-syn.lua @@ -8,7 +8,7 @@ if not modules then modules = { } end modules ['font-syn'] = { -- todo: subs in lookups requests -local next, tonumber = next, tonumber +local next, tonumber, type, tostring = next, tonumber, type, tostring local sub, gsub, lower, match, find, lower, upper = string.sub, string.gsub, string.lower, string.match, string.find, string.lower, string.upper local find, gmatch = string.find, string.gmatch local concat, sort, format = table.concat, table.sort, string.format @@ -17,8 +17,21 @@ local lpegmatch = lpeg.match local unpack = unpack or table.unpack local formatters = string.formatters -local allocate = utilities.storage.allocate -local sparse = utilities.storage.sparse +local allocate = utilities.storage.allocate +local sparse = utilities.storage.sparse + +local removesuffix = file.removesuffix +local splitbase = file.splitbase +local splitname = file.splitname +local basename = file.basename +local nameonly = file.nameonly +local pathpart = file.pathpart +local filejoin = file.join +local is_qualified_path = file.is_qualified_path + +local findfile = resolvers.findfile +local cleanpath = resolvers.cleanpath +local resolveresolved = resolvers.resolve local trace_names = false trackers.register("fonts.names", function(v) trace_names = v end) local trace_warnings = false trackers.register("fonts.warnings", function(v) trace_warnings = v end) @@ -151,17 +164,17 @@ names.knownstyles = { } names.knownwidths = { - "book", - "condensed", - "expanded", - "normal", - "thin", + "book", + "condensed", + "expanded", + "normal", + "thin", } names.knownvariants = { - "normal", - "oldstyle", - "smallcaps", + "normal", + "oldstyle", + "smallcaps", } local any = P(1) @@ -218,7 +231,7 @@ filters.ttf = fontloader.info filters.ttc = fontloader.info filters.dfont = fontloader.info -function fontloader.fullinfo(...) +function fontloader.fullinfo(...) -- check with taco what we get / could get local ff = fontloader.open(...) if ff then local d = ff and fontloader.to_table(ff) @@ -235,9 +248,9 @@ filters.otf = fontloader.fullinfo function filters.afm(name) -- we could parse the afm file as well, and then report an error but -- it's not worth the trouble - local pfbname = resolvers.findfile(file.removesuffix(name)..".pfb","pfb") or "" + local pfbname = findfile(removesuffix(name)..".pfb","pfb") or "" if pfbname == "" then - pfbname = resolvers.findfile(file.removesuffix(file.basename(name))..".pfb","pfb") or "" + pfbname = findfile(nameonly(name)..".pfb","pfb") or "" end if pfbname ~= "" then local f = io.open(name) @@ -271,7 +284,7 @@ for combination with the weight of a font.

filters.list = { "otf", "ttf", "ttc", "dfont", "afm", ---~ "ttc", "otf", "ttf", "dfont", "afm", + -- "ttc", "otf", "ttf", "dfont", "afm", } names.fontconfigfile = "fonts.conf" -- a bit weird format, bonus feature @@ -283,8 +296,8 @@ filters.names = { } function names.getpaths(trace) local hash, result, r = { }, { }, 0 local function collect(t,where) - for i=1, #t do - local v = resolvers.cleanpath(t[i]) + for i=1,#t do + local v = cleanpath(t[i]) v = gsub(v,"/+$","") -- not needed any more local key = lower(v) report_names("%a specifies path %a",where,v) @@ -306,10 +319,10 @@ function names.getpaths(trace) end if confname ~= "" then -- first look in the tex tree - local name = resolvers.findfile(confname,"fontconfig files") or "" + local name = findfile(confname,"fontconfig files") or "" if name == "" then -- after all, fontconfig is a unix thing - name = file.join("/etc",confname) + name = filejoin("/etc",confname) if not lfs.isfile(name) then name = "" -- force quit end @@ -321,10 +334,10 @@ function names.getpaths(trace) local xmldata = xml.load(name) -- begin of untested mess xml.include(xmldata,"include","",true,function(incname) - if not file.is_qualified_path(incname) then - local path = file.dirname(name) -- main name + if not is_qualified_path(incname) then + local path = pathpart(name) -- main name if path ~= "" then - incname = file.join(path,incname) + incname = filejoin(path,incname) end end if lfs.isfile(incname) then @@ -356,7 +369,7 @@ local function cleanname(name) end local function cleanfilename(fullname,defaultsuffix) - local path, name, suffix = file.splitname(fullname) + local path, name, suffix = splitname(fullname) name = gsub(lower(name),"[^%a%d]","") if suffix and suffix ~= "" then return name .. ".".. suffix @@ -386,7 +399,7 @@ local function walk_tree(pathlist,suffix,identify) if pathlist then for i=1,#pathlist do local path = pathlist[i] - path = resolvers.cleanpath(path .. "/") + path = cleanpath(path .. "/") path = gsub(path,"/+","/") local pattern = path .. "**." .. suffix -- ** forces recurse report_names("globbing path %a",pattern) @@ -394,25 +407,24 @@ local function walk_tree(pathlist,suffix,identify) sort(t,sorter) for j=1,#t do local completename = t[j] - identify(completename,file.basename(completename),suffix,completename) + identify(completename,basename(completename),suffix,completename) end end end end -local function check_name(data,result,filename,suffix,subfont) +local function check_name(data,result,filename,modification,suffix,subfont) -- shortcuts local specifications = data.specifications - local families = data.families -- prepare local names = check_names(result) -- fetch - local familyname = (names and names.preffamilyname) or result.familyname - local fullname = (names and names.fullname) or result.fullname + local familyname = names and names.preffamilyname or result.familyname + local fullname = names and names.fullname or result.fullname local fontname = result.fontname - local subfamily = (names and names.subfamily) - local modifiers = (names and names.prefmodifiers) - local weight = (names and names.weight) or result.weight + local subfamily = names and names.subfamily + local modifiers = names and names.prefmodifiers + local weight = names and names.weight or result.weight local italicangle = tonumber(result.italicangle) local subfont = subfont or nil local rawname = fullname or fontname or familyname @@ -423,7 +435,7 @@ local function check_name(data,result,filename,suffix,subfont) subfamily = subfamily and cleanname(subfamily) modifiers = modifiers and cleanname(modifiers) weight = weight and cleanname(weight) - italicangle = (italicangle == 0) and nil + italicangle = italicangle == 0 and nil -- analyze local a_name, a_weight, a_style, a_width, a_variant = analyzespec(fullname or fontname or familyname) -- check @@ -445,34 +457,38 @@ local function check_name(data,result,filename,suffix,subfont) if not familyname then familyname = a_name end - fontname = fontname or fullname or familyname or file.basename(filename) + fontname = fontname or fullname or familyname or basename(filename) fullname = fullname or fontname familyname = familyname or fontname specifications[#specifications + 1] = { - filename = filename, -- unresolved - format = lower(suffix), - subfont = subfont, - rawname = rawname, - familyname = familyname, - fullname = fullname, - fontname = fontname, - subfamily = subfamily, - modifiers = modifiers, - weight = weight, - style = style, - width = width, - variant = variant, - minsize = result.design_range_bottom or 0, - maxsize = result.design_range_top or 0, - designsize = result.design_size or 0, + filename = filename, -- unresolved + format = lower(suffix), + subfont = subfont, + rawname = rawname, + familyname = familyname, + fullname = fullname, + fontname = fontname, + subfamily = subfamily, + modifiers = modifiers, + weight = weight, + style = style, + width = width, + variant = variant, + minsize = result.design_range_bottom or 0, + maxsize = result.design_range_top or 0, + designsize = result.design_size or 0, + modification = modification or 0, } end local function cleanupkeywords() - local data = names.data + local data = names.data local specifications = names.data.specifications if specifications then - local weights, styles, widths, variants = { }, { }, { }, { } + local weights = { } + local styles = { } + local widths = { } + local variants = { } for i=1,#specifications do local s = specifications[i] -- fix (sofar styles are taken from the name, and widths from the specification) @@ -504,29 +520,40 @@ local function cleanupkeywords() end local function collectstatistics() - local data = names.data + local data = names.data local specifications = data.specifications if specifications then - local weights, styles, widths, variants = { }, { }, { }, { } + local weights = { } + local styles = { } + local widths = { } + local variants = { } for i=1,#specifications do - local s = specifications[i] - local weight, style, width, variant = s.weight, s.style, s.width, s.variant + local s = specifications[i] + local weight = s.weight + local style = s.style + local width = s.width + local variant = s.variant if weight then weights [weight ] = (weights [weight ] or 0) + 1 end if style then styles [style ] = (styles [style ] or 0) + 1 end if width then widths [width ] = (widths [width ] or 0) + 1 end if variant then variants[variant] = (variants[variant] or 0) + 1 end end - local stats = data.statistics - stats.weights, stats.styles, stats.widths, stats.variants, stats.fonts = weights, styles, widths, variants, #specifications + local stats = data.statistics + stats.weights = weights + stats.styles = styles + stats.widths = widths + stats.variants = variants + stats.fonts = #specifications end end local function collecthashes() - local data = names.data + local data = names.data local mappings = data.mappings local fallbacks = data.fallbacks local specifications = data.specifications - local nofmappings, noffallbacks = 0, 0 + local nofmappings = 0 + local noffallbacks = 0 if specifications then -- maybe multiple passes for index=1,#specifications do @@ -560,12 +587,12 @@ local function collecthashes() end local function collectfamilies() - local data = names.data + local data = names.data local specifications = data.specifications - local families = data.families + local families = data.families for index=1,#specifications do local familyname = specifications[index].familyname - local family = families[familyname] + local family = families[familyname] if not family then families[familyname] = { index } else @@ -575,9 +602,10 @@ local function collectfamilies() end local function checkduplicate(where) -- fails on "Romantik" but that's a border case anyway - local data = names.data - local mapping = data[where] - local specifications, loaded = data.specifications, { } + local data = names.data + local mapping = data[where] + local specifications = data.specifications + local loaded = { } if specifications and mapping then for _, m in next, mapping do for k, v in next, m do @@ -626,13 +654,19 @@ local sorter = function(a,b) end local function sorthashes() - local data, list = names.data, filters.list - local mappings, fallbacks, sorted_mappings, sorted_fallbacks = data.mappings, data.fallbacks, { }, { } - data.sorted_mappings, data.sorted_fallbacks = sorted_mappings, sorted_fallbacks + local data = names.data + local list = filters.list + local mappings = data.mappings + local fallbacks = data.fallbacks + local sorted_mappings = { } + local sorted_fallbacks = { } + data.sorted_mappings = sorted_mappings + data.sorted_fallbacks = sorted_fallbacks for i=1,#list do local l = list[i] - sorted_mappings[l], sorted_fallbacks[l] = table.keys(mappings[l]), table.keys(fallbacks[l]) - sort(sorted_mappings[l],sorter) + sorted_mappings [l] = table.keys(mappings[l]) + sorted_fallbacks[l] = table.keys(fallbacks[l]) + sort(sorted_mappings [l],sorter) sort(sorted_fallbacks[l],sorter) end data.sorted_families = table.keys(data.families) @@ -640,7 +674,7 @@ local function sorthashes() end local function unpackreferences() - local data = names.data + local data = names.data local specifications = data.specifications if specifications then for k, v in next, data.families do @@ -667,14 +701,26 @@ local function unpackreferences() end end -local function analyzefiles() - local data = names.data - local done, totalnofread, totalnofskipped, totalnofduplicates, nofread, nofskipped, nofduplicates = { }, 0, 0, 0, 0, 0, 0 - local skip_paths, skip_names = filters.paths, filters.names ---~ local trace_warnings = true +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 + local totalnofskipped = 0 + local totalnofduplicates = 0 + local nofread = 0 + local nofskipped = 0 + local nofduplicates = 0 + local skip_paths = filters.paths + local skip_names = filters.names + local specifications = data.specifications + local oldindices = olddata and olddata.indices or { } + local oldspecifications = olddata and olddata.specifications or { } + local oldrejected = olddata and olddata.rejected or { } local function identify(completename,name,suffix,storedname) - local basename = file.basename(completename) - local basepath = file.dirname(completename) + local pathpart, basepart = splitbase(completename) nofread = nofread + 1 if done[name] then -- already done (avoid otf afm clash) @@ -689,8 +735,8 @@ local function analyzefiles() report_names("%s font %a does not really exist",suffix,completename) end nofskipped = nofskipped + 1 - elseif not file.is_qualified_path(completename) and resolvers.findfile(completename,suffix) == "" then - -- not locateble by backend anyway + elseif not is_qualified_path(completename) and findfile(completename,suffix) == "" then + -- not locatable by backend anyway if trace_names then report_names("%s font %a cannot be found by backend",suffix,completename) end @@ -698,7 +744,7 @@ local function analyzefiles() else if #skip_paths > 0 then for i=1,#skip_paths do - if find(basepath,skip_paths[i]) then + if find(pathpart,skip_paths[i]) then if trace_names then report_names("rejecting path of %s font %a",suffix,completename) end @@ -709,7 +755,7 @@ local function analyzefiles() end if #skip_names > 0 then for i=1,#skip_paths do - if find(basename,skip_names[i]) then + if find(basepart,skip_names[i]) then done[name] = true if trace_names then report_names("rejecting name of %s font %a",suffix,completename) @@ -722,27 +768,48 @@ local function analyzefiles() if trace_names then report_names("identifying %s font %a",suffix,completename) end - local result, message = filters[lower(suffix)](completename) - if result then - if result[1] then - for r=1,#result do - local ok = check_name(data,result[r],storedname,suffix,r-1) -- subfonts start at zero + local result = nil + local modification = lfs.attributes(completename,"modification") + if olddata and modification and modification > 0 then + local oldindex = oldindices[storedname] -- index into specifications + if oldindex then + local oldspecification = oldspecifications[oldindex] + if oldspecification and oldspecification.filename == storedname then -- double check for out of sync + local oldmodification = oldspecification.modification + if oldmodification == modification then + result = oldspecification + specifications[#specifications + 1] = result + else + end + else + end + elseif oldrejected[storedname] == modification then + result = false + end + end + if result == nil then + local result, message = filters[lower(suffix)](completename) + if result then + if result[1] then + for r=1,#result do + local ok = check_name(data,result[r],storedname,modification,suffix,r-1) -- subfonts start at zero + -- if not ok then + -- nofskipped = nofskipped + 1 + -- end + end + else + local ok = check_name(data,result,storedname,modification,suffix) -- if not ok then -- nofskipped = nofskipped + 1 -- end end - else - local ok = check_name(data,result,storedname,suffix) - -- if not ok then - -- nofskipped = nofskipped + 1 - -- end - end - if trace_warnings and message and message ~= "" then - report_names("warning when identifying %s font %a, %s",suffix,completename,message) + if trace_warnings and message and message ~= "" then + report_names("warning when identifying %s font %a, %s",suffix,completename,message) + end + elseif trace_warnings then + nofskipped = nofskipped + 1 + report_names("error when identifying %s font %a, %s",suffix,completename,message or "unknown") end - elseif trace_warnings then - nofskipped = nofskipped + 1 - report_names("error when identifying %s font %a, %s",suffix,completename,message or "unknown") end done[name] = true end @@ -766,62 +833,74 @@ local function analyzefiles() end logs.flush() end - if not trace_warnings then - report_names("warnings are disabled (tracker 'fonts.warnings')") - end - traverse("tree", function(suffix) -- TEXTREE only + -- 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 local completename = root .."/" .. path .. "/" .. name - completename = resolvers.resolve(completename) -- no shortcut + completename = resolveresolved(completename) -- no shortcut identify(completename,name,suffix,name) return true end end, function(blobtype,blobpath,pattern) - blobpath = resolvers.resolve(blobpath) -- no shortcut + blobpath = resolveresolved(blobpath) -- no shortcut report_names("scanning path %a for %s files",blobpath,suffix) end, function(blobtype,blobpath,pattern,total,checked,done) - blobpath = resolvers.resolve(blobpath) -- no shortcut + blobpath = resolveresolved(blobpath) -- no shortcut report_names("%s entries found, %s %s files checked, %s okay",total,checked,suffix,done) end) - end) - if texconfig.kpse_init then + 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 to clumsy so we just stick to a full scan instead - traverse("lsr", function(suffix) -- all trees - local pathlist = resolvers.splitpath(resolvers.showpath("ls-R") or "") - walk_tree(pathlist,suffix,identify) - end) + -- 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 texconfig.kpse_init then + traverse("lsr", withlsr) else - traverse("system", function(suffix) -- OSFONTDIR cum suis - walk_tree(names.getpaths(trace),suffix,identify) - end) + traverse("system", withsystem) end - data.statistics.readfiles, data.statistics.skippedfiles, data.statistics.duplicatefiles = totalnofread, totalnofskipped, totalnofduplicates + data.statistics.readfiles = totalnofread + data.statistics.skippedfiles = totalnofskipped + data.statistics.duplicatefiles = totalnofduplicates end local function addfilenames() - local data = names.data + local data = names.data local specifications = data.specifications - local files = { } + local indices = { } + local files = { } for i=1,#specifications do local fullname = specifications[i].filename files[cleanfilename(fullname)] = fullname + indices[fullname] = i end - data.files = files + data.files = files + data.indices = indices end local function rejectclashes() -- just to be sure, so no explicit afm will be found then - local specifications, used, okay, o = names.data.specifications, { }, { }, 0 + local specifications = names.data.specifications + local used = { } + local okay = { } + local rejected = { } -- only keep modification + local o = 0 for i=1,#specifications do local s = specifications[i] local f = s.fontname if f then - local fnd, fnm = used[f], s.filename + local fnd = used[f] + local fnm = s.filename if fnd then if trace_warnings then report_names("fontname %a clashes, %a rejected in favor of %a",f,fnm,fnd) end + rejected[f] = s.modification else used[f] = fnm o = o + 1 @@ -837,27 +916,34 @@ local function rejectclashes() -- just to be sure, so no explicit afm will be fo report_names("%s files rejected due to clashes",d) end names.data.specifications = okay + names.data.rejected = rejected end local function resetdata() - local mappings, fallbacks = { }, { } + local mappings = { } + local fallbacks = { } for _, k in next, filters.list do - mappings[k], fallbacks[k] = { }, { } + mappings [k] = { } + fallbacks[k] = { } end names.data = { - version = names.version, - mappings = mappings, - fallbacks = fallbacks, + version = names.version, + mappings = mappings, + fallbacks = fallbacks, specifications = { }, - families = { }, - statistics = { }, - datastate = resolvers.datastate(), + families = { }, + statistics = { }, + names = { }, + indices = { }, + rejected = { }, + datastate = resolvers.datastate(), } end -function names.identify() +function names.identify(force) + local starttime = os.gettimeofday() -- use elapser resetdata() - analyzefiles() + analyzefiles(not force and names.readdata(names.basename)) rejectclashes() collectfamilies() collectstatistics() @@ -866,6 +952,7 @@ function names.identify() checkduplicates() addfilenames() -- sorthashes() -- will be resorted when saved + report_names("total scan time %0.3f seconds",os.gettimeofday()-starttime) end function names.is_permitted(name) @@ -878,11 +965,11 @@ function names.readdata(name) return containers.read(names.cache,name) end -function names.load(reload,verbose) +function names.load(reload,force) if not names.loaded then if reload then if names.is_permitted(names.basename) then - names.identify(verbose) + names.identify(force) names.writedata(names.basename,names.data) else report_names("unable to access database cache") @@ -929,9 +1016,11 @@ function names.list(pattern,reload,all) -- here? local t = { } local data = names.data if data then - local list = filters.list - local mappings, sorted_mappings = data.mappings, data.sorted_mappings - local fallbacks, sorted_fallbacks = data.fallbacks, data.sorted_fallbacks + local list = filters.list + local mappings = data.mappings + local sorted_mappings = data.sorted_mappings + local fallbacks = data.fallbacks + local sorted_fallbacks = data.sorted_fallbacks for i=1,#list do local format = list[i] list_them(mappings[format],sorted_mappings[format],pattern,t,all) @@ -993,10 +1082,12 @@ end -- we could cache a lookup .. maybe some day ... (only when auto loaded!) local function foundname(name,sub) -- sub is not used currently - local data = names.data - local mappings, sorted_mappings = data.mappings, data.sorted_mappings - local fallbacks, sorted_fallbacks = data.fallbacks, data.sorted_fallbacks - local list = filters.list + local data = names.data + local mappings = data.mappings + local sorted_mappings = data.sorted_mappings + local fallbacks = data.fallbacks + local sorted_fallbacks = data.sorted_fallbacks + local list = filters.list -- dilemma: we lookup in the order otf ttf ttc ... afm but now an otf fallback -- can come after an afm match ... well, one should provide nice names anyway -- and having two lists is not an option @@ -1287,8 +1378,9 @@ end local function collect(stage,found,done,name,weight,style,width,variant,all) local data = names.data - local families, sorted = data.families, data.sorted_families - strictname = "^".. name -- to be checked + local families = data.families + local sorted = data.sorted_families + local strictname = "^".. name -- to be checked local family = families[name] if trace_names then report_names("resolving name %a, weight %a, style %a, width %a, variant %a",name,weight,style,width,variant) @@ -1439,7 +1531,6 @@ function names.collectfiles(askedname,reload) -- no all askedname = cleanname(askedname) -- or cleanname names.load(reload) local list = { } - local basename = file.basename local specifications = names.data.specifications for i=1,#specifications do local s = specifications[i] @@ -1451,71 +1542,23 @@ function names.collectfiles(askedname,reload) -- no all end end ---~ --[[ldx-- ---~

Fallbacks, not permanent but a transition thing.

---~ --ldx]]-- ---~ ---~ names.new_to_old = allocate { ---~ ["lmroman10-capsregular"] = "lmromancaps10-oblique", ---~ ["lmroman10-capsoblique"] = "lmromancaps10-regular", ---~ ["lmroman10-demi"] = "lmromandemi10-oblique", ---~ ["lmroman10-demioblique"] = "lmromandemi10-regular", ---~ ["lmroman8-oblique"] = "lmromanslant8-regular", ---~ ["lmroman9-oblique"] = "lmromanslant9-regular", ---~ ["lmroman10-oblique"] = "lmromanslant10-regular", ---~ ["lmroman12-oblique"] = "lmromanslant12-regular", ---~ ["lmroman17-oblique"] = "lmromanslant17-regular", ---~ ["lmroman10-boldoblique"] = "lmromanslant10-bold", ---~ ["lmroman10-dunhill"] = "lmromandunh10-oblique", ---~ ["lmroman10-dunhilloblique"] = "lmromandunh10-regular", ---~ ["lmroman10-unslanted"] = "lmromanunsl10-regular", ---~ ["lmsans10-demicondensed"] = "lmsansdemicond10-regular", ---~ ["lmsans10-demicondensedoblique"] = "lmsansdemicond10-oblique", ---~ ["lmsansquotation8-bold"] = "lmsansquot8-bold", ---~ ["lmsansquotation8-boldoblique"] = "lmsansquot8-boldoblique", ---~ ["lmsansquotation8-oblique"] = "lmsansquot8-oblique", ---~ ["lmsansquotation8-regular"] = "lmsansquot8-regular", ---~ ["lmtypewriter8-regular"] = "lmmono8-regular", ---~ ["lmtypewriter9-regular"] = "lmmono9-regular", ---~ ["lmtypewriter10-regular"] = "lmmono10-regular", ---~ ["lmtypewriter12-regular"] = "lmmono12-regular", ---~ ["lmtypewriter10-italic"] = "lmmono10-italic", ---~ ["lmtypewriter10-oblique"] = "lmmonoslant10-regular", ---~ ["lmtypewriter10-capsoblique"] = "lmmonocaps10-oblique", ---~ ["lmtypewriter10-capsregular"] = "lmmonocaps10-regular", ---~ ["lmtypewriter10-light"] = "lmmonolt10-regular", ---~ ["lmtypewriter10-lightoblique"] = "lmmonolt10-oblique", ---~ ["lmtypewriter10-lightcondensed"] = "lmmonoltcond10-regular", ---~ ["lmtypewriter10-lightcondensedoblique"] = "lmmonoltcond10-oblique", ---~ ["lmtypewriter10-dark"] = "lmmonolt10-bold", ---~ ["lmtypewriter10-darkoblique"] = "lmmonolt10-boldoblique", ---~ ["lmtypewritervarwd10-regular"] = "lmmonoproplt10-regular", ---~ ["lmtypewritervarwd10-oblique"] = "lmmonoproplt10-oblique", ---~ ["lmtypewritervarwd10-light"] = "lmmonoprop10-regular", ---~ ["lmtypewritervarwd10-lightoblique"] = "lmmonoprop10-oblique", ---~ ["lmtypewritervarwd10-dark"] = "lmmonoproplt10-bold", ---~ ["lmtypewritervarwd10-darkoblique"] = "lmmonoproplt10-boldoblique", ---~ } ---~ ---~ names.old_to_new = allocate(table.swapped(names.new_to_old)) - ---~ todo: ---~ ---~ blacklisted = { ---~ ["cmr10.ttf"] = "completely messed up", ---~ } +-- todo: +-- +-- blacklisted = { +-- ["cmr10.ttf"] = "completely messed up", +-- } function names.exists(name) local found = false local list = filters.list for k=1,#list do local v = list[k] - found = (resolvers.findfile(name,v) or "") ~= "" + found = (findfile(name,v) or "") ~= "" if found then return found end end - return ((resolvers.findfile(name,"tfm") or "") ~= "") or ((names.resolve(name) or "") ~= "") + return (findfile(name,"tfm") or "") ~= "" or (names.resolve(name) or "") ~= "" end local lastlookups, lastpattern = { }, "" diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf index 91c1fcf64..a964404da 100644 Binary files a/tex/context/base/status-files.pdf and b/tex/context/base/status-files.pdf differ diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf index 877cdb237..39ea14a55 100644 Binary files a/tex/context/base/status-lua.pdf and b/tex/context/base/status-lua.pdf differ diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 4aac7d36b..bfc5d6232 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 03/15/13 19:22:42 +-- merge date : 03/16/13 01:51:00 do -- begin closure to overcome local limits and interference @@ -8628,10 +8628,10 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) if lig then if trace_ligatures then local stopchar=stop.char - head,start=markstoligature(kind,lookupname,start,stop,lig) + head,start=markstoligature(kind,lookupname,head,start,stop,lig) logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char)) else - head,start=markstoligature(kind,lookupname,start,stop,lig) + head,start=markstoligature(kind,lookupname,head,start,stop,lig) end return head,start,true else -- cgit v1.2.3