From 5135aef167bec739fe429e1aa987671768b237bc Mon Sep 17 00:00:00 2001 From: Context Git Mirror Bot Date: Sat, 30 Jul 2016 01:22:07 +0200 Subject: 2016-07-30 00:31:00 --- tex/context/base/context-version.pdf | Bin 4257 -> 4253 bytes tex/context/base/mkiv/attr-ini.mkiv | 15 +- tex/context/base/mkiv/bibl-bib.mkiv | 2 +- tex/context/base/mkiv/cont-new.mkiv | 2 +- tex/context/base/mkiv/context-todo.tex | 120 +++- tex/context/base/mkiv/context.mkiv | 2 +- tex/context/base/mkiv/font-con.lua | 358 ++++++++---- tex/context/base/mkiv/font-ctx.lua | 71 +-- tex/context/base/mkiv/font-one.lua | 110 ++-- tex/context/base/mkiv/font-otf.lua | 444 ++++++--------- tex/context/base/mkiv/font-otl.lua | 180 ++---- tex/context/base/mkiv/font-otp.lua | 19 +- tex/context/base/mkiv/font-ots.lua | 158 ++++-- tex/context/base/mkiv/font-tfm.lua | 38 +- tex/context/base/mkiv/grph-inc.lua | 84 ++- tex/context/base/mkiv/grph-inc.mkiv | 31 +- tex/context/base/mkiv/lang-def.mkiv | 6 + tex/context/base/mkiv/luat-usr.lua | 1 + tex/context/base/mkiv/math-stc.mkvi | 10 +- tex/context/base/mkiv/meta-ini.lua | 70 ++- tex/context/base/mkiv/meta-ini.mkiv | 37 +- tex/context/base/mkiv/node-ini.mkiv | 3 +- tex/context/base/mkiv/node-ltp.lua | 119 ++-- tex/context/base/mkiv/node-met.lua | 2 +- tex/context/base/mkiv/node-nut.lua | 3 +- tex/context/base/mkiv/node-res.lua | 2 + tex/context/base/mkiv/node-rul.mkiv | 10 +- tex/context/base/mkiv/node-ser.lua | 118 +--- tex/context/base/mkiv/status-files.pdf | Bin 9210 -> 9238 bytes tex/context/base/mkiv/status-lua.pdf | Bin 368229 -> 368500 bytes tex/context/base/mkiv/strc-mat.mkiv | 8 +- tex/context/base/mkiv/tabl-tbl.mkiv | 9 + tex/context/base/mkiv/toks-tra.mkiv | 11 +- tex/context/fonts/mkiv/type-imp-source.mkiv | 66 +++ tex/context/interface/mkiv/i-context.pdf | Bin 774764 -> 774744 bytes tex/context/interface/mkiv/i-readme.pdf | Bin 60792 -> 60787 bytes tex/context/modules/mkiv/m-punk.mkiv | 7 +- tex/context/modules/mkiv/s-math-characters.lua | 6 + tex/context/modules/mkiv/s-math-characters.mkiv | 4 +- tex/context/modules/mkiv/s-math-extensibles.mkiv | 6 +- tex/context/modules/mkiv/x-asciimath.mkiv | 122 ++-- tex/generic/context/luatex/luatex-fonts-merged.lua | 626 +++++++++++---------- 42 files changed, 1551 insertions(+), 1329 deletions(-) create mode 100644 tex/context/fonts/mkiv/type-imp-source.mkiv (limited to 'tex') diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf index a5e21c0e2..f97738e16 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/mkiv/attr-ini.mkiv b/tex/context/base/mkiv/attr-ini.mkiv index 3f0b7fb27..a2d37118b 100644 --- a/tex/context/base/mkiv/attr-ini.mkiv +++ b/tex/context/base/mkiv/attr-ini.mkiv @@ -38,7 +38,8 @@ \expandafter\newcount\csname\??attributestack\string#1\endcsname \fi} -\newtoks \attributesresetlist +\newtoks \t_attr_list_global +\newtoks \t_attr_list_local \ifdefined \s!global \else \def\s!global {global} \fi % for metatex % or hard check later \ifdefined \s!public \else \def\s!public {public} \fi % for metatex % or hard check later @@ -59,9 +60,12 @@ \expandafter\newconstant \csname\??attributeid#2\endcsname \csname\??attributeid#2\endcsname\scratchcounter % some attributes are always global - \doifnotinset\s!global{#3}{\appendetoks\csname\??attributecount#2\endcsname\attributeunsetvalue\to\attributesresetlist}% + \doifelseinset\s!global{#3}% + {\appendetoks\csname\??attributecount#2\endcsname\attributeunsetvalue\to\t_attr_list_global}% + {\appendetoks\csname\??attributecount#2\endcsname\attributeunsetvalue\to\t_attr_list_local }% % here public means 'visible' so it's not to be confused with 'public' at the lua end - \doifinset \s!public{#3}{\expandafter\let\csname#2\s!attribute\expandafter\endcsname\csname\??attributeid#2\endcsname}% + \doifinset\s!public{#3}% + {\expandafter\let\csname#2\s!attribute\expandafter\endcsname\csname\??attributeid#2\endcsname}% \fi} \unexpanded\def\newattribute#1% @@ -77,7 +81,10 @@ \let\dompattribute\gobbletwoarguments -\unexpanded\def\resetallattributes{\the\attributesresetlist} +\unexpanded\def\resetglobalattributes{\the\t_attr_list_global} +\unexpanded\def\resetlocalattributes {\the\t_attr_list_local } + +\let\resetallattributes\resetlocalattributes %D Rather special. diff --git a/tex/context/base/mkiv/bibl-bib.mkiv b/tex/context/base/mkiv/bibl-bib.mkiv index 80d04099b..f5d911ea7 100644 --- a/tex/context/base/mkiv/bibl-bib.mkiv +++ b/tex/context/base/mkiv/bibl-bib.mkiv @@ -140,7 +140,7 @@ \def\doregisterbibtexfile [#1][#2]{\ctxcommand{registerbibtexfile("#1","#2")}} \def\doregisterbibtexentry [#1][#2]{\ctxcommand{registerbibtexentry("#1","#2")}} -\def\doapplytobibtexsession[#1][#2]{\xmlprocessregistered{bibtex:#1}{#2}{#2}} +\def\doapplytobibtexsession[#1][#2]{\xmlprocess{bibtex:#1}{#2}{#2}} \unexpanded\def\bibtexcommand#1% {\ifcsname\??pb:c:#1\endcsname \else diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index 968c39179..5e4e0bb15 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2016.07.25 21:49} +\newcontextversion{2016.07.30 00:26} %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/mkiv/context-todo.tex b/tex/context/base/mkiv/context-todo.tex index deb912fe8..f455bc925 100644 --- a/tex/context/base/mkiv/context-todo.tex +++ b/tex/context/base/mkiv/context-todo.tex @@ -1,12 +1,99 @@ -% language=uk +\setuplayout + [width=middle, + height=middle, + topspace=2cm, + header=0pt, + footer=1cm] -\usemodule[art-01,abr-01] +\setupbodyfont + [bookman] + +\usemodule + [punk,abr-02] + +\setuphead + [section] + [color=ColorThree, + style=\bfb] + +\setupitemgroup + [itemize] [each] + [packed] [color=ColorThree,symcolor=ColorThree] + +\setupfooter + [color=ColorThree, + style=bold] + +\setupfootertexts + [pagenumber] + +\setupwhitespace + [big] + +\definefont[PunkFont][demo@punk at 20pt] + +% \def\aterm{\sym{?}} +% \def\rterm{\sym{--}} +% \def\dterm{\sym{+}} +% \def\pterm{\sym{!}} +% +% \startitemize[packed] +% \aterm on the agenda (update, extension, rewrite) +% \rterm no longer on the agenda, rejected +% \dterm no longer on the agenda, done +% \pterm work in progress (so keep an eye on the betas) +% \stopitemize + +\definecolor[ColorOne] [c=0.5,m=0.2,y=0.5,k=0.2] +\definecolor[ColorTwo] [c=0.5,m=0.5,y=0.1,k=0.1] +\definecolor[ColorThree][c=0.1,m=1.0,y=1.0,k=0.2] \starttext -\subject {On the agenda} +\startMPpage + StartPage ; + numeric n ; n := 200 ; + numeric o ; o := 25 ; + + pair p[] ; + for i=1 upto n : + p[i] = (o + uniformdeviate (PaperWidth-2*o), o + uniformdeviate (PaperHeight-2*o)) ; + endfor ; + + picture d ; d := image ( for i=1 upto n : draw p[i] ; endfor ) ; + picture l ; l := image ( draw for i=1 upto n : if i > 1 : -- fi p[i] endfor ) ; + picture t ; t := textext("\framed[frame=off,align={middle,lohi},foregroundcolor=ColorThree,foregroundstyle=\PunkFont]{\ConTeXt\endgraf MkIV\endgraf\kern-\strutdepth RoadMap}") ; + + fill Page enlarged 10 withcolor "ColorOne" ; + + draw d withcolor white withpen pencircle scaled o ; + draw d withcolor "ColorTwo" withpen pencircle scaled (o - 5) ; + draw l withcolor white withpen pencircle scaled (o / 5) ; + draw l withcolor "ColorTwo" withpen pencircle scaled (o /10) ; + draw thelabel.ulft(t xsized .5PaperWidth,lrcorner Page shifted - (PaperWidth/20,-PaperWidth/40)) ; + StopPage ; +\stopMPpage -\subsubject{\LUATEX} + +\startsubject[title={Introduction}] + +There is not really a long term roadmap for development. One reason is that there is already +a lot available. When we started with \LUATEX, the \CONTEXT\ code was mostly rewritten, +and that process is more of less finished. Of course there is always work left. + +This file is not a complete overview of our plans but users can at least get an +idea of what we're working on and what is coming. Feel free to submit +suggestions. + +\startlines +Hans Hagen +Hasselt NL +\currentdate +\stoplines + +\stopsubject + +\startsubject[title={On the agenda for \LUATEX}] \startitemize \startitem @@ -34,7 +121,9 @@ \stopitem \stopitemize -\subsubject{\CONTEXT} +\stopsubject + +\startsubject[title={On the agenda for \CONTEXT\ \MKIV}] \startitemize \startitem @@ -68,25 +157,6 @@ \stopitem \stopitemize -\vfill {\em Feel free to suggest additions.} +\stopsubject \stoptext - -% also - -check components and pre|post|replace in math-tag - -% new: - - - ... - - ... - - - - - - - - diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index 84611e104..6b102e801 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -39,7 +39,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2016.07.25 21:49} +\edef\contextversion{2016.07.30 00:26} \edef\contextkind {beta} %D For those who want to use this: diff --git a/tex/context/base/mkiv/font-con.lua b/tex/context/base/mkiv/font-con.lua index 9a6f3f84d..931e4e70e 100644 --- a/tex/context/base/mkiv/font-con.lua +++ b/tex/context/base/mkiv/font-con.lua @@ -12,9 +12,10 @@ local next, tostring, rawget = next, tostring, rawget local format, match, lower, gsub, find = string.format, string.match, string.lower, string.gsub, string.find local sort, insert, concat, sortedkeys, serialize, fastcopy = table.sort, table.insert, table.concat, table.sortedkeys, table.serialize, table.fastcopy local derivetable = table.derive +local ioflush = io.flush -local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) -local trace_scaling = false trackers.register("fonts.scaling" , function(v) trace_scaling = v end) +local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) +local trace_scaling = false trackers.register("fonts.scaling", function(v) trace_scaling = v end) local report_defining = logs.reporter("fonts","defining") @@ -1086,146 +1087,269 @@ setmetatableindex(formats, function(t,k) return rawget(t,file.suffix(l)) end) -local locations = { } +do -local function setindeed(mode,target,group,name,action,position) - local t = target[mode] - if not t then - report_defining("fatal error in setting feature %a, group %a, mode %a",name,group,mode) - os.exit() - elseif position then - -- todo: remove existing - insert(t, position, { name = name, action = action }) - else - for i=1,#t do - local ti = t[i] - if ti.name == name then - ti.action = action - return + local function setindeed(mode,target,group,name,action,position) + local t = target[mode] + if not t then + report_defining("fatal error in setting feature %a, group %a, mode %a",name,group,mode) + os.exit() + elseif position then + -- todo: remove existing + insert(t, position, { name = name, action = action }) + else + for i=1,#t do + local ti = t[i] + if ti.name == name then + ti.action = action + return + end end + insert(t, { name = name, action = action }) end - insert(t, { name = name, action = action }) - end -end - -local function set(group,name,target,source) - target = target[group] - if not target then - report_defining("fatal target error in setting feature %a, group %a",name,group) - os.exit() - end - local source = source[group] - if not source then - report_defining("fatal source error in setting feature %a, group %a",name,group) - os.exit() - end - local node = source.node - local base = source.base - local position = source.position - if node then - setindeed("node",target,group,name,node,position) end - if base then - setindeed("base",target,group,name,base,position) - end -end -local function register(where,specification) - local name = specification.name - if name and name ~= "" then - local default = specification.default - local description = specification.description - local initializers = specification.initializers - local processors = specification.processors - local manipulators = specification.manipulators - local modechecker = specification.modechecker - if default then - where.defaults[name] = default + local function set(group,name,target,source) + target = target[group] + if not target then + report_defining("fatal target error in setting feature %a, group %a",name,group) + os.exit() end - if description and description ~= "" then - where.descriptions[name] = description + local source = source[group] + if not source then + report_defining("fatal source error in setting feature %a, group %a",name,group) + os.exit() end - if initializers then - set('initializers',name,where,specification) + local node = source.node + local base = source.base + local position = source.position + if node then + setindeed("node",target,group,name,node,position) end - if processors then - set('processors', name,where,specification) - end - if manipulators then - set('manipulators',name,where,specification) + if base then + setindeed("base",target,group,name,base,position) end - if modechecker then - where.modechecker = modechecker + end + + local function register(where,specification) + local name = specification.name + if name and name ~= "" then + local default = specification.default + local description = specification.description + local initializers = specification.initializers + local processors = specification.processors + local manipulators = specification.manipulators + local modechecker = specification.modechecker + if default then + where.defaults[name] = default + end + if description and description ~= "" then + where.descriptions[name] = description + end + if initializers then + set('initializers',name,where,specification) + end + if processors then + set('processors', name,where,specification) + end + if manipulators then + set('manipulators',name,where,specification) + end + if modechecker then + where.modechecker = modechecker + end end end -end -constructors.registerfeature = register - -function constructors.getfeatureaction(what,where,mode,name) - what = handlers[what].features - if what then - where = what[where] - if where then - mode = where[mode] - if mode then - for i=1,#mode do - local m = mode[i] - if m.name == name then - return m.action + constructors.registerfeature = register + + function constructors.getfeatureaction(what,where,mode,name) + what = handlers[what].features + if what then + where = what[where] + if where then + mode = where[mode] + if mode then + for i=1,#mode do + local m = mode[i] + if m.name == name then + return m.action + end end end end end end + + local newfeatures = { } + constructors.newfeatures = newfeatures -- downward compatible + constructors.features = newfeatures + + local function setnewfeatures(what) + local handler = handlers[what] + local features = handler.features + if not features then + local tables = handler.tables -- can be preloaded + local statistics = handler.statistics -- can be preloaded + features = allocate { + defaults = { }, + descriptions = tables and tables.features or { }, + used = statistics and statistics.usedfeatures or { }, + initializers = { base = { }, node = { } }, + processors = { base = { }, node = { } }, + manipulators = { base = { }, node = { } }, + } + features.register = function(specification) return register(features,specification) end + handler.features = features -- will also become hidden + end + return features + end + + setmetatable(newfeatures, { + __call = function(t,k) local v = t[k] return v end, + __index = function(t,k) local v = setnewfeatures(k) t[k] = v return v end, + }) + end -local newhandler = { } -constructors.handlers = newhandler -- downward compatible -constructors.newhandler = newhandler +do -local function setnewhandler(what) -- could be a metatable newindex - local handler = handlers[what] - if not handler then - handler = { } - handlers[what] = handler + local newhandler = { } + constructors.handlers = newhandler -- downward compatible + constructors.newhandler = newhandler + + local function setnewhandler(what) -- could be a metatable newindex + local handler = handlers[what] + if not handler then + handler = { } + handlers[what] = handler + end + return handler end - return handler + + setmetatable(newhandler, { + __call = function(t,k) local v = t[k] return v end, + __index = function(t,k) local v = setnewhandler(k) t[k] = v return v end, + }) + end -setmetatable(newhandler, { - __call = function(t,k) local v = t[k] return v end, - __index = function(t,k) local v = setnewhandler(k) t[k] = v return v end, -}) - -local newfeatures = { } -constructors.newfeatures = newfeatures -- downward compatible -constructors.features = newfeatures - -local function setnewfeatures(what) - local handler = handlers[what] - local features = handler.features - if not features then - local tables = handler.tables -- can be preloaded - local statistics = handler.statistics -- can be preloaded - features = allocate { - defaults = { }, - descriptions = tables and tables.features or { }, - used = statistics and statistics.usedfeatures or { }, - initializers = { base = { }, node = { } }, - processors = { base = { }, node = { } }, - manipulators = { base = { }, node = { } }, - } - features.register = function(specification) return register(features,specification) end - handler.features = features -- will also become hidden +do + -- a pitty that we need to be generic as we have nicer mechanisms for this ... + + local newenhancer = { } + constructors.enhancers = newenhancer + constructors.newenhancer = newenhancer + + local function setnewenhancer(format) + + local handler = handlers[format] + local enhancers = handler.enhancers + + if not enhancers then + + local actions = allocate() + local before = allocate() + local after = allocate() + local order = allocate() + local patches = { before = before, after = after } + + local trace = false + local report = logs.reporter("fonts",format .. " enhancing") + + trackers.register(format .. ".loading", function(v) trace = v end) + + local function enhance(name,data,filename,raw) + local enhancer = actions[name] + if enhancer then + if trace then + report("apply enhancement %a to file %a",name,filename) + ioflush() + end + enhancer(data,filename,raw) + else + -- no message as we can have private ones + end + end + + local function apply(data,filename,raw) + local basename = file.basename(lower(filename)) + if trace then + report("%s enhancing file %a","start",filename) + end + ioflush() -- we want instant messages + for e=1,#order do + local enhancer = order[e] + local b = before[enhancer] + if b then + for pattern, action in next, b do + if find(basename,pattern) then + action(data,filename,raw) + end + end + end + enhance(enhancer,data,filename,raw) + local a = after[enhancer] + if a then + for pattern, action in next, a do + if find(basename,pattern) then + action(data,filename,raw) + end + end + end + ioflush() -- we want instant messages + end + if trace then + report("%s enhancing file %a","stop",filename) + end + ioflush() -- we want instant messages + end + + local function register(what,action) + if action then + if actions[what] then + -- overloading, e.g."check extra features" + else + order[#order+1] = what + end + actions[what] = action + else + report("bad enhancer %a",what) + end + end + + -- fonts.constructors.otf.enhancers.patch("before","migrate metadata","cambria",function() end) + + local function patch(what,where,pattern,action) + local pw = patches[what] + if pw then + local ww = pw[where] + if ww then + ww[pattern] = action + else + pw[where] = { [pattern] = action} + end + end + end + + enhancers = { + register = register, + apply = apply, + patch = patch, + patches = { register = patch }, -- for old times sake + } + + handler.enhancers = enhancers + end + return enhancers end - return features -end -setmetatable(newfeatures, { - __call = function(t,k) local v = t[k] return v end, - __index = function(t,k) local v = setnewfeatures(k) t[k] = v return v end, -}) + setmetatable(newenhancer, { + __call = function(t,k) local v = t[k] return v end, + __index = function(t,k) local v = setnewenhancer(k) t[k] = v return v end, + }) + +end --[[ldx--

We need to check for default features. For this we provide diff --git a/tex/context/base/mkiv/font-ctx.lua b/tex/context/base/mkiv/font-ctx.lua index 0342ee0ac..33945083e 100644 --- a/tex/context/base/mkiv/font-ctx.lua +++ b/tex/context/base/mkiv/font-ctx.lua @@ -42,6 +42,7 @@ local report_cummulative = logs.reporter("fonts","cummulative") local report_defining = logs.reporter("fonts","defining") local report_status = logs.reporter("fonts","status") local report_mapfiles = logs.reporter("fonts","mapfiles") +local report_newline = logs.newline local setmetatableindex = table.setmetatableindex @@ -1713,15 +1714,16 @@ function loggers.reportdefinedfonts() properties.fullname or "", properties.sharedwith or "", } - report_status("%s: % t",properties.name,sortedkeys(data)) end formatcolumns(t," ") - report_status() + logs.pushtarget("logfile") + report_newline() report_status("defined fonts:") - report_status() + report_newline() for k=1,tn do report_status(t[k]) end + logs.poptarget() end end @@ -1740,12 +1742,14 @@ function loggers.reportusedfeatures() setup.number = n -- restore it (normally not needed as we're done anyway) end formatcolumns(t," ") - report_status() + logs.pushtarget("logfile") + report_newline() report_status("defined featuresets:") - report_status() + report_newline() for k=1,n do report_status(t[k]) end + logs.poptarget() end end @@ -2522,35 +2526,38 @@ end -- for the font manual -local trace_files = false - -trackers.register("fonts.files",function(v) trace_files = v end) - statistics.register("used fonts",function() - if trace_files then - local files = { } - local list = { } - for id, tfmdata in sortedhash(fontdata) do - local filename = tfmdata.properties.filename - local filedata = files[filename] - if filedata then - filedata.instances = filedata.instances + 1 - else - local rawdata = tfmdata.shared and tfmdata.shared.rawdata - local metadata = rawdata and rawdata.metadata - files[filename] = { - instances = 1, - filename = filename, - version = metadata and metadata.version, - size = rawdata and rawdata.size, - } + if trace_usage then + local filename = file.nameonly(environment.jobname) .. "-fonts-usage.lua" + if next(fontdata) then + local files = { } + local list = { } + for id, tfmdata in sortedhash(fontdata) do + local filename = tfmdata.properties.filename + if filename then + local filedata = files[filename] + if filedata then + filedata.instances = filedata.instances + 1 + else + local rawdata = tfmdata.shared and tfmdata.shared.rawdata + local metadata = rawdata and rawdata.metadata + files[filename] = { + instances = 1, + filename = filename, + version = metadata and metadata.version, + size = rawdata and rawdata.size, + } + end + else + -- what to do + end end + for k, v in sortedhash(files) do + list[#list+1] = v + end + table.save(filename,list) + else + os.remove(filename) end - for k, v in sortedhash(files) do - list[#list+1] = v - end - local filename = file.nameonly(environment.jobname) .. "-usedfonts.lua" - table.save(filename,list) - return format("log saved in '%s'",filename) end end) diff --git a/tex/context/base/mkiv/font-one.lua b/tex/context/base/mkiv/font-one.lua index 8629850de..d9b9c65df 100644 --- a/tex/context/base/mkiv/font-one.lua +++ b/tex/context/base/mkiv/font-one.lua @@ -29,42 +29,45 @@ local bxor, rshift = bit32.bxor, bit32.rshift local P, S, R, Cmt, C, Ct, Cs, Carg = lpeg.P, lpeg.S, lpeg.R, lpeg.Cmt, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Carg local lpegmatch, patterns = lpeg.match, lpeg.patterns -local trace_features = false trackers.register("afm.features", function(v) trace_features = v end) -local trace_indexing = false trackers.register("afm.indexing", function(v) trace_indexing = v end) -local trace_loading = false trackers.register("afm.loading", function(v) trace_loading = v end) -local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) +local trace_features = false trackers.register("afm.features", function(v) trace_features = v end) +local trace_indexing = false trackers.register("afm.indexing", function(v) trace_indexing = v end) +local trace_loading = false trackers.register("afm.loading", function(v) trace_loading = v end) +local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) -local report_afm = logs.reporter("fonts","afm loading") +local report_afm = logs.reporter("fonts","afm loading") -local setmetatableindex = table.setmetatableindex -local derivetable = table.derive +local setmetatableindex = table.setmetatableindex +local derivetable = table.derive -local findbinfile = resolvers.findbinfile +local findbinfile = resolvers.findbinfile -local definers = fonts.definers -local readers = fonts.readers -local constructors = fonts.constructors +local definers = fonts.definers +local readers = fonts.readers +local constructors = fonts.constructors -local afm = constructors.handlers.afm -local pfb = constructors.handlers.pfb -local otf = fonts.handlers.otf +local afm = constructors.handlers.afm +local pfb = constructors.handlers.pfb +local otf = fonts.handlers.otf -local otfreaders = otf.readers -local otfenhancers = otf.enhancers +local otfreaders = otf.readers +local otfenhancers = otf.enhancers -local afmfeatures = constructors.features.afm -local registerafmfeature = afmfeatures.register +local afmfeatures = constructors.features.afm +local registerafmfeature = afmfeatures.register -afm.version = 1.512 -- incrementing this number one up will force a re-cache -afm.cache = containers.define("fonts", "afm", afm.version, true) -afm.autoprefixed = true -- this will become false some day (catches texnansi-blabla.*) +local afmenhancers = constructors.enhancers.afm +local registerafmenhancer = afmenhancers.register -afm.helpdata = { } -- set later on so no local for this -afm.syncspace = true -- when true, nicer stretch values +afm.version = 1.512 -- incrementing this number one up will force a re-cache +afm.cache = containers.define("fonts", "one", afm.version, true) +afm.autoprefixed = true -- this will become false some day (catches texnansi-blabla.*) -local overloads = fonts.mappings.overloads +afm.helpdata = { } -- set later on so no local for this +afm.syncspace = true -- when true, nicer stretch values -local applyruntimefixes = fonts.treatments and fonts.treatments.applyfixes +local overloads = fonts.mappings.overloads + +local applyruntimefixes = fonts.treatments and fonts.treatments.applyfixes --[[ldx--

We cache files. Caching is taken care of in the loader. We cheat a bit by adding @@ -76,36 +79,6 @@ fashion and later we transform it to sequences. Then we apply some methods also used in opentype fonts (like tlig).

--ldx]]-- -local enhancers = { - -- It's cleaner to implement them after we've seen what we are - -- dealing with. -} - -local steps = { - "unify names", - "add ligatures", - "add extra kerns", - "normalize features", - "check extra features", - "fix names", -- what a hack ... --- "add tounicode data", -} - -local function applyenhancers(data,filename) - for i=1,#steps do - local step = steps[i] - local enhancer = enhancers[step] - if enhancer then - if trace_loading then - report_afm("applying enhancer %a",step) - end - enhancer(data,filename) - else - report_afm("invalid enhancer %a",step) - end - end -end - function afm.load(filename) filename = resolvers.findfile(filename,'afm') or "" if filename ~= "" and not fonts.names.ignoredfile(filename) then @@ -129,7 +102,7 @@ function afm.load(filename) report_afm("reading %a",filename) data = afm.readers.loadfont(filename,pfbname) if data then - applyenhancers(data,filename) + afmenhancers.apply(data,filename) -- otfreaders.addunicodetable(data) -- only when not done yet fonts.mappings.addtounicode(data,filename) -- otfreaders.extend(data) @@ -162,7 +135,7 @@ end local uparser = fonts.mappings.makenameparser() -- each time -enhancers["unify names"] = function(data, filename) +local function enhance_unify_names(data, filename) local unicodevector = fonts.encodings.agl.unicodes -- loaded runtime in context local unicodes = { } local names = { } @@ -218,7 +191,7 @@ end local everywhere = { ["*"] = { ["*"] = true } } -- or: { ["*"] = { "*" } } local noflags = { false, false, false, false } -enhancers["normalize features"] = function(data) +local function enhance_normalize_features(data) local ligatures = setmetatableindex("table") local kerns = setmetatableindex("table") local extrakerns = setmetatableindex("table") @@ -319,9 +292,7 @@ enhancers["normalize features"] = function(data) data.resources.sequences = sequences end -enhancers["check extra features"] = otf.enhancers.enhance - -enhancers["fix names"] = function(data) +local function enhance_fix_names(data) for k, v in next, data.descriptions do local n = v.name local r = overloads[n] @@ -368,14 +339,10 @@ local addthem = function(rawdata,ligatures) end end -enhancers["add ligatures"] = function(rawdata) +local function enhance_add_ligatures(rawdata) addthem(rawdata,afm.helpdata.ligatures) end --- enhancers["add tex ligatures"] = function(rawdata) --- addthem(rawdata,afm.helpdata.texligatures) --- end - --[[ldx--

We keep the extra kerns in separate kerning tables so that we can use them selectively.

@@ -388,7 +355,7 @@ them selectively.

-- we don't use the character database. (Ok, we can have a context specific -- variant). -enhancers["add extra kerns"] = function(rawdata) -- using shcodes is not robust here +local function enhance_add_extra_kerns(rawdata) -- using shcodes is not robust here local descriptions = rawdata.descriptions local resources = rawdata.resources local unicodes = resources.unicodes @@ -851,3 +818,12 @@ function readers.pfb(specification,method) -- only called when forced swap("specification") return readers.afm(specification,method) end + +-- now we register them + +registerafmenhancer("unify names", enhance_unify_names) +registerafmenhancer("add ligatures", enhance_add_ligatures) +registerafmenhancer("add extra kerns", enhance_add_extra_kerns) +registerafmenhancer("normalize features", enhance_normalize_features) +registerafmenhancer("check extra features", otfenhancers.enhance) +registerafmenhancer("fix names", enhance_fix_names) diff --git a/tex/context/base/mkiv/font-otf.lua b/tex/context/base/mkiv/font-otf.lua index dbfc0b583..09e810857 100644 --- a/tex/context/base/mkiv/font-otf.lua +++ b/tex/context/base/mkiv/font-otf.lua @@ -29,81 +29,79 @@ local fastcopy, tohash, derivetable, copy = table.fastcopy, table.tohash, table. local formatters = string.formatters local P, R, S, C, Ct, lpegmatch = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Ct, lpeg.match -local setmetatableindex = table.setmetatableindex -local allocate = utilities.storage.allocate -local registertracker = trackers.register -local registerdirective = directives.register -local starttiming = statistics.starttiming -local stoptiming = statistics.stoptiming -local elapsedtime = statistics.elapsedtime -local findbinfile = resolvers.findbinfile - -local trace_private = false registertracker("otf.private", function(v) trace_private = v end) -local trace_subfonts = false registertracker("otf.subfonts", function(v) trace_subfonts = v end) -local trace_loading = false registertracker("otf.loading", function(v) trace_loading = v end) -local trace_features = false registertracker("otf.features", function(v) trace_features = v end) -local trace_dynamics = false registertracker("otf.dynamics", function(v) trace_dynamics = v end) -local trace_sequences = false registertracker("otf.sequences", function(v) trace_sequences = v end) -local trace_markwidth = false registertracker("otf.markwidth", function(v) trace_markwidth = v end) -local trace_defining = false registertracker("fonts.defining", function(v) trace_defining = v end) - -local compact_lookups = true registertracker("otf.compactlookups", function(v) compact_lookups = v end) -local purge_names = true registertracker("otf.purgenames", function(v) purge_names = v end) - -local report_otf = logs.reporter("fonts","otf loading") - -local fonts = fonts -local otf = fonts.handlers.otf - -otf.glists = { "gsub", "gpos" } - -otf.version = 2.826 -- beware: also sync font-mis.lua and in mtx-fonts -otf.cache = containers.define("fonts", "otf", otf.version, true) - -local hashes = fonts.hashes -local definers = fonts.definers -local readers = fonts.readers -local constructors = fonts.constructors - -local fontdata = hashes and hashes.identifiers -local chardata = characters and characters.data -- not used - -local otffeatures = constructors.features.otf -local registerotffeature = otffeatures.register - -local enhancers = allocate() -otf.enhancers = enhancers -local patches = { } -enhancers.patches = patches - -local forceload = false -local cleanup = 0 -- mk: 0=885M 1=765M 2=735M (regular run 730M) -local packdata = true -local syncspace = true -local forcenotdef = false -local includesubfonts = false -local overloadkerns = false -- experiment - -local applyruntimefixes = fonts.treatments and fonts.treatments.applyfixes - -local wildcard = "*" -local default = "dflt" - -local fontloader = fontloader -local open_font = fontloader.open -local close_font = fontloader.close -local font_fields = fontloader.fields -local apply_featurefile = fontloader.apply_featurefile - -local mainfields = nil -local glyphfields = nil -- not used yet - -local formats = fonts.formats - -formats.otf = "opentype" -formats.ttf = "truetype" -formats.ttc = "truetype" -formats.dfont = "truetype" +local setmetatableindex = table.setmetatableindex +local allocate = utilities.storage.allocate +local registertracker = trackers.register +local registerdirective = directives.register +local starttiming = statistics.starttiming +local stoptiming = statistics.stoptiming +local elapsedtime = statistics.elapsedtime +local findbinfile = resolvers.findbinfile + +local trace_private = false registertracker("otf.private", function(v) trace_private = v end) +local trace_subfonts = false registertracker("otf.subfonts", function(v) trace_subfonts = v end) +local trace_loading = false registertracker("otf.loading", function(v) trace_loading = v end) +local trace_features = false registertracker("otf.features", function(v) trace_features = v end) +local trace_dynamics = false registertracker("otf.dynamics", function(v) trace_dynamics = v end) +local trace_sequences = false registertracker("otf.sequences", function(v) trace_sequences = v end) +local trace_markwidth = false registertracker("otf.markwidth", function(v) trace_markwidth = v end) +local trace_defining = false registertracker("fonts.defining", function(v) trace_defining = v end) + +local compact_lookups = true registertracker("otf.compactlookups", function(v) compact_lookups = v end) +local purge_names = true registertracker("otf.purgenames", function(v) purge_names = v end) + +local report_otf = logs.reporter("fonts","otf loading") + +local fonts = fonts +local otf = fonts.handlers.otf + +otf.glists = { "gsub", "gpos" } + +otf.version = 2.826 -- beware: also sync font-mis.lua and in mtx-fonts +otf.cache = containers.define("fonts", "otf", otf.version, true) + +local hashes = fonts.hashes +local definers = fonts.definers +local readers = fonts.readers +local constructors = fonts.constructors + +local fontdata = hashes and hashes.identifiers +local chardata = characters and characters.data -- not used + +local otffeatures = constructors.features.otf +local registerotffeature = otffeatures.register + +local otfenhancers = constructors.enhancers.otf +local registerotfenhancer = otfenhancers.register + +local forceload = false +local cleanup = 0 -- mk: 0=885M 1=765M 2=735M (regular run 730M) +local packdata = true +local syncspace = true +local forcenotdef = false +local includesubfonts = false +local overloadkerns = false -- experiment + +local applyruntimefixes = fonts.treatments and fonts.treatments.applyfixes + +local wildcard = "*" +local default = "dflt" + +local fontloader = fontloader +local open_font = fontloader.open +local close_font = fontloader.close +local font_fields = fontloader.fields +local apply_featurefile = fontloader.apply_featurefile + +local mainfields = nil +local glyphfields = nil -- not used yet + +local formats = fonts.formats + +formats.otf = "opentype" +formats.ttf = "truetype" +formats.ttc = "truetype" +formats.dfont = "truetype" registerdirective("fonts.otf.loader.cleanup", function(v) cleanup = tonumber(v) or (v and 1) or 0 end) registerdirective("fonts.otf.loader.force", function(v) forceload = v end) @@ -262,129 +260,52 @@ local valid_fields = table.tohash { -- "truetype", -- maybe as check } -local ordered_enhancers = { - "prepare tables", - - "prepare glyphs", - "prepare lookups", - - "analyze glyphs", - "analyze math", - - -- "prepare tounicode", - - "reorganize lookups", - "reorganize mark classes", - "reorganize anchor classes", - - "reorganize glyph kerns", - "reorganize glyph lookups", - "reorganize glyph anchors", - - "merge kern classes", - - "reorganize features", - "reorganize subtables", - - "check glyphs", - "check metadata", - - "prepare tounicode", - - "check encoding", -- moved - "add duplicates", - - "expand lookups", -- a temp hack awaiting the lua loader - - "check extra features", -- after metadata and duplicates - - "cleanup tables", - - "compact lookups", - "purge names", -} - ---[[ldx-- -

Here we go.

---ldx]]-- - -local actions = allocate() -local before = allocate() -local after = allocate() - -patches.before = before -patches.after = after - -local function enhance(name,data,filename,raw) - local enhancer = actions[name] - if enhancer then - if trace_loading then - report_otf("apply enhancement %a to file %a",name,filename) - ioflush() - end - enhancer(data,filename,raw) - else - -- no message as we can have private ones - end -end - -function enhancers.apply(data,filename,raw) - local basename = file.basename(lower(filename)) - if trace_loading then - report_otf("%s enhancing file %a","start",filename) - end - ioflush() -- we want instant messages - for e=1,#ordered_enhancers do - local enhancer = ordered_enhancers[e] - local b = before[enhancer] - if b then - for pattern, action in next, b do - if find(basename,pattern) then - action(data,filename,raw) - end +local function adddimensions(data,filename) + -- todo: forget about the width if it's the defaultwidth (saves mem) + -- we could also build the marks hash here (instead of storing it) + if data then + local descriptions = data.descriptions + local resources = data.resources + local defaultwidth = resources.defaultwidth or 0 + local defaultheight = resources.defaultheight or 0 + local defaultdepth = resources.defaultdepth or 0 + local basename = trace_markwidth and file.basename(filename) + for _, d in next, descriptions do + local bb, wd = d.boundingbox, d.width + if not wd then + -- or bb? + d.width = defaultwidth + elseif trace_markwidth and wd ~= 0 and d.class == "mark" then + report_otf("mark %a with width %b found in %a",d.name or "",wd,basename) + -- d.width = -wd end - end - enhance(enhancer,data,filename,raw) - local a = after[enhancer] - if a then - for pattern, action in next, a do - if find(basename,pattern) then - action(data,filename,raw) - end + if bb then + local ht = bb[4] + local dp = -bb[2] + -- if alldimensions then + -- if ht ~= 0 then + -- d.height = ht + -- end + -- if dp ~= 0 then + -- d.depth = dp + -- end + -- else + if ht == 0 or ht < 0 then + -- not set + else + d.height = ht + end + if dp == 0 or dp < 0 then + -- not set + else + d.depth = dp + end + -- end end end - ioflush() -- we want instant messages - end - if trace_loading then - report_otf("%s enhancing file %a","stop",filename) - end - ioflush() -- we want instant messages -end - --- patches.register("before","migrate metadata","cambria",function() end) - -function patches.register(what,where,pattern,action) - local pw = patches[what] - if pw then - local ww = pw[where] - if ww then - ww[pattern] = action - else - pw[where] = { [pattern] = action} - end - end -end - -function patches.report(fmt,...) - if trace_loading then - report_otf("patching: %s",formatters[fmt](...)) end end -function enhancers.register(what,action) -- only already registered can be overloaded - actions[what] = action -end - function otf.load(filename,sub,featurefile) -- second argument (format) is gone ! local base = file.basename(file.removesuffix(filename)) local name = file.removesuffix(base) @@ -524,14 +445,14 @@ function otf.load(filename,sub,featurefile) -- second argument (format) is gone }, } report_otf("file size: %s", size) - enhancers.apply(data,filename,fontdata) + otfenhancers.apply(data,filename,fontdata) local packtime = { } if packdata then if cleanup > 0 then collectgarbage("collect") end starttiming(packtime) - enhance("pack",data,filename,nil) + otf.packdata(data,filename,nil) -- implemented elsewhere stoptiming(packtime) end report_otf("saving %a in cache",filename) @@ -562,7 +483,7 @@ function otf.load(filename,sub,featurefile) -- second argument (format) is gone if trace_defining then report_otf("loading from cache using hash %a",hash) end - enhance("unpack",data,filename,nil,false) + otf.unpackdata(data,filename,nil,false) -- implemented elsewhere -- local resources = data.resources local lookuptags = resources.lookuptags @@ -599,7 +520,7 @@ function otf.load(filename,sub,featurefile) -- second argument (format) is gone if applyruntimefixes then applyruntimefixes(filename,data) end - enhance("add dimensions",data,filename,nil,false) + adddimensions(data,filename,nil,false) if trace_sequences then showfeatureorder(data,filename) end @@ -623,56 +544,10 @@ local mt = { end } -actions["prepare tables"] = function(data,filename,raw) +local function enhance_prepare_tables(data,filename,raw) data.properties.hasitalics = false end -actions["add dimensions"] = function(data,filename) - -- todo: forget about the width if it's the defaultwidth (saves mem) - -- we could also build the marks hash here (instead of storing it) - if data then - local descriptions = data.descriptions - local resources = data.resources - local defaultwidth = resources.defaultwidth or 0 - local defaultheight = resources.defaultheight or 0 - local defaultdepth = resources.defaultdepth or 0 - local basename = trace_markwidth and file.basename(filename) - for _, d in next, descriptions do - local bb, wd = d.boundingbox, d.width - if not wd then - -- or bb? - d.width = defaultwidth - elseif trace_markwidth and wd ~= 0 and d.class == "mark" then - report_otf("mark %a with width %b found in %a",d.name or "",wd,basename) - -- d.width = -wd - end - if bb then - local ht = bb[4] - local dp = -bb[2] - -- if alldimensions then - -- if ht ~= 0 then - -- d.height = ht - -- end - -- if dp ~= 0 then - -- d.depth = dp - -- end - -- else - if ht == 0 or ht < 0 then - -- not set - else - d.height = ht - end - if dp == 0 or dp < 0 then - -- not set - else - d.depth = dp - end - -- end - end - end - end -end - local function somecopy(old) -- fast one if old then local new = { } @@ -707,7 +582,7 @@ end -- not setting hasitalics and class (when nil) during table construction can save some mem -actions["prepare glyphs"] = function(data,filename,raw) +local function enhance_prepare_glyphs(data,filename,raw) local rawglyphs = raw.glyphs local rawsubfonts = raw.subfonts local rawcidinfo = raw.cidinfo @@ -985,7 +860,7 @@ end -- -- PsuedoEncodeUnencoded(EncMap *map,struct ttfinfo *info) -actions["check encoding"] = function(data,filename,raw) +local function enhance_check_encoding(data,filename,raw) local descriptions = data.descriptions local resources = data.resources local properties = data.properties @@ -1064,7 +939,7 @@ end -- do an indirect lookup uni_to_uni . but then we need that in -- all lookups -actions["add duplicates"] = function(data,filename,raw) +local function enhance_add_duplicates(data,filename,raw) local descriptions = data.descriptions local resources = data.resources local properties = data.properties @@ -1117,7 +992,7 @@ end -- class : nil base mark ligature component (maybe we don't need it in description) -- boundingbox: split into ht/dp takes more memory (larger tables and less sharing) -actions["analyze glyphs"] = function(data,filename,raw) -- maybe integrate this in the previous +local function enhance_analyze_glyphs(data,filename,raw) -- maybe integrate this in the previous local descriptions = data.descriptions local resources = data.resources local metadata = data.metadata @@ -1176,7 +1051,7 @@ actions["analyze glyphs"] = function(data,filename,raw) -- maybe integrate this end end -actions["reorganize mark classes"] = function(data,filename,raw) +local function enhance_reorganize_mark_classes(data,filename,raw) local mark_classes = raw.mark_classes if mark_classes then local resources = data.resources @@ -1193,7 +1068,7 @@ actions["reorganize mark classes"] = function(data,filename,raw) end end -actions["reorganize features"] = function(data,filename,raw) -- combine with other +local function enhance_reorganize_features(data,filename,raw) -- combine with other local features = { } data.resources.features = features for k=1,#otf.glists do @@ -1231,7 +1106,7 @@ actions["reorganize features"] = function(data,filename,raw) -- combine with oth end end -actions["reorganize anchor classes"] = function(data,filename,raw) +local function enhance_reorganize_anchor_classes(data,filename,raw) local resources = data.resources local anchor_to_lookup = { } local lookup_to_anchor = { } @@ -1400,7 +1275,7 @@ end -- end -- end -actions["prepare tounicode"] = function(data,filename,raw) +local function enhance_prepare_tounicode(data,filename,raw) fonts.mappings.addtounicode(data,filename) end @@ -1428,7 +1303,7 @@ local g_directions = { -- return true -- end -actions["reorganize subtables"] = function(data,filename,raw) +local function enhance_reorganize_subtables(data,filename,raw) local resources = data.resources local sequences = { } local lookups = { } @@ -1522,7 +1397,7 @@ actions["reorganize subtables"] = function(data,filename,raw) end end -actions["prepare lookups"] = function(data,filename,raw) +local function enhance_prepare_lookups(data,filename,raw) local lookups = raw.lookups if lookups then data.lookups = lookups @@ -1632,7 +1507,7 @@ local function r_uncover(splitter,cache,cover,replacements) end end -actions["reorganize lookups"] = function(data,filename,raw) -- we could check for "" and n == 0 +local function enhance_reorganize_lookups(data,filename,raw) -- we could check for "" and n == 0 -- we prefer the before lookups in a normal order if data.lookups then local helpers = data.helpers @@ -1798,7 +1673,7 @@ actions["reorganize lookups"] = function(data,filename,raw) -- we could check fo end end -actions["expand lookups"] = function(data,filename,raw) -- we could check for "" and n == 0 +local function enhance_expand_lookups(data,filename,raw) -- we could check for "" and n == 0 if data.lookups then local cache = data.helpers.matchcache if cache then @@ -1889,7 +1764,7 @@ local function check_variants(unicode,the_variants,splitter,unicodes) return variants, parts, italic end -actions["analyze math"] = function(data,filename,raw) +local function enhance_analyze_math(data,filename,raw) if raw.math then data.metadata.math = raw.math local unicodes = data.resources.unicodes @@ -1933,7 +1808,7 @@ actions["analyze math"] = function(data,filename,raw) end end -actions["reorganize glyph kerns"] = function(data,filename,raw) +local function enhance_reorganize_glyph_kerns(data,filename,raw) local descriptions = data.descriptions local resources = data.resources local unicodes = resources.unicodes @@ -1976,7 +1851,7 @@ actions["reorganize glyph kerns"] = function(data,filename,raw) end end -actions["merge kern classes"] = function(data,filename,raw) +local function enhance_merge_kern_classes(data,filename,raw) local gposlist = raw.gpos if gposlist then local descriptions = data.descriptions @@ -2098,7 +1973,7 @@ actions["merge kern classes"] = function(data,filename,raw) end end -actions["check glyphs"] = function(data,filename,raw) +local function enhance_check_glyphs(data,filename,raw) for unicode, description in next, data.descriptions do description.glyph = nil end @@ -2112,7 +1987,7 @@ 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 function enhance_check_metadata(data,filename,raw) local metadata = data.metadata for _, k in next, mainfields do if valid_fields[k] then @@ -2201,7 +2076,7 @@ actions["check metadata"] = function(data,filename,raw) end end -actions["cleanup tables"] = function(data,filename,raw) +local function enhance_cleanup_tables(data,filename,raw) local duplicates = data.resources.duplicates if duplicates then for k, v in next, duplicates do @@ -2228,7 +2103,7 @@ end -- mlookups only with pairs and ligatures -actions["reorganize glyph lookups"] = function(data,filename,raw) +local function enhance_reorganize_glyph_lookups(data,filename,raw) local resources = data.resources local unicodes = resources.unicodes local descriptions = data.descriptions @@ -2314,7 +2189,7 @@ end local zero = { 0, 0 } -actions["reorganize glyph anchors"] = function(data,filename,raw) +local function enhance_reorganize_glyph_anchors(data,filename,raw) local descriptions = data.descriptions for unicode, description in next, descriptions do local anchors = description.glyph.anchors @@ -2365,7 +2240,7 @@ local bogusname = (P("uni") + P("u")) * R("AF","09")^4 + (P("index") + P("glyph") + S("Ii") * P("dentity") * P(".")^0) * R("09")^1 local uselessname = (1-bogusname)^0 * bogusname -actions["purge names"] = function(data,filename,raw) -- not used yet +local function enhance_purge_names(data,filename,raw) -- not used yet if purge_names then local n = 0 for u, d in next, data.descriptions do @@ -2381,7 +2256,7 @@ actions["purge names"] = function(data,filename,raw) -- not used yet end end -actions["compact lookups"] = function(data,filename,raw) +local function enhance_compact_lookups(data,filename,raw) if not compact_lookups then report_otf("not compacting") return @@ -3053,3 +2928,42 @@ function otf.getkern(tfmdata,left,right,kind) end return 0 end + + +registerotfenhancer("prepare tables", enhance_prepare_tables) + +registerotfenhancer("prepare glyphs", enhance_prepare_glyphs) +registerotfenhancer("prepare lookups", enhance_prepare_lookups) + +registerotfenhancer("analyze glyphs", enhance_analyze_glyphs) +registerotfenhancer("analyze math", enhance_analyze_math) + +registerotfenhancer("reorganize lookups", enhance_reorganize_lookups) +registerotfenhancer("reorganize mark classes", enhance_reorganize_mark_classes) +registerotfenhancer("reorganize anchor classes", enhance_reorganize_anchor_classes) + +registerotfenhancer("reorganize glyph kerns", enhance_reorganize_glyph_kerns) +registerotfenhancer("reorganize glyph lookups", enhance_reorganize_glyph_lookups) +registerotfenhancer("reorganize glyph anchors", enhance_reorganize_glyph_anchors) + +registerotfenhancer("merge kern classes", enhance_merge_kern_classes) + +registerotfenhancer("reorganize features", enhance_reorganize_features) +registerotfenhancer("reorganize subtables", enhance_reorganize_subtables) + +registerotfenhancer("check glyphs", enhance_check_glyphs) +registerotfenhancer("check metadata", enhance_check_metadata) + +registerotfenhancer("prepare tounicode", enhance_prepare_tounicode) + +registerotfenhancer("check encoding", enhance_check_encoding) +registerotfenhancer("add duplicates", enhance_add_duplicates) + +registerotfenhancer("expand lookups", enhance_expand_lookups) + +registerotfenhancer("check extra features", function() end) --placeholder, will be overloaded + +registerotfenhancer("cleanup tables", enhance_cleanup_tables) + +registerotfenhancer("compact lookups", enhance_compact_lookups) +registerotfenhancer("purge names", enhance_purge_names) diff --git a/tex/context/base/mkiv/font-otl.lua b/tex/context/base/mkiv/font-otl.lua index bdce80db2..94f6a45c6 100644 --- a/tex/context/base/mkiv/font-otl.lua +++ b/tex/context/base/mkiv/font-otl.lua @@ -26,70 +26,67 @@ if not modules then modules = { } end modules ['font-otl'] = { local gmatch, find, match, lower, strip = string.gmatch, string.find, string.match, string.lower, string.strip local type, next, tonumber, tostring, unpack = type, next, tonumber, tostring, unpack local abs = math.abs -local ioflush = io.flush local derivetable = table.derive local formatters = string.formatters -local setmetatableindex = table.setmetatableindex -local allocate = utilities.storage.allocate -local registertracker = trackers.register -local registerdirective = directives.register -local starttiming = statistics.starttiming -local stoptiming = statistics.stoptiming -local elapsedtime = statistics.elapsedtime -local findbinfile = resolvers.findbinfile +local setmetatableindex = table.setmetatableindex +local allocate = utilities.storage.allocate +local registertracker = trackers.register +local registerdirective = directives.register +local starttiming = statistics.starttiming +local stoptiming = statistics.stoptiming +local elapsedtime = statistics.elapsedtime +local findbinfile = resolvers.findbinfile ------ trace_private = false registertracker("otf.private", function(v) trace_private = v end) ------ trace_subfonts = false registertracker("otf.subfonts", function(v) trace_subfonts = v end) -local trace_loading = false registertracker("otf.loading", function(v) trace_loading = v end) -local trace_features = false registertracker("otf.features", function(v) trace_features = v end) ------ trace_dynamics = false registertracker("otf.dynamics", function(v) trace_dynamics = v end) ------ trace_sequences = false registertracker("otf.sequences", function(v) trace_sequences = v end) ------ trace_markwidth = false registertracker("otf.markwidth", function(v) trace_markwidth = v end) -local trace_defining = false registertracker("fonts.defining", function(v) trace_defining = v end) +----- trace_private = false registertracker("otf.private", function(v) trace_private = v end) +----- trace_subfonts = false registertracker("otf.subfonts", function(v) trace_subfonts = v end) +local trace_loading = false registertracker("otf.loading", function(v) trace_loading = v end) +local trace_features = false registertracker("otf.features", function(v) trace_features = v end) +----- trace_dynamics = false registertracker("otf.dynamics", function(v) trace_dynamics = v end) +----- trace_sequences = false registertracker("otf.sequences", function(v) trace_sequences = v end) +----- trace_markwidth = false registertracker("otf.markwidth", function(v) trace_markwidth = v end) +local trace_defining = false registertracker("fonts.defining", function(v) trace_defining = v end) -local report_otf = logs.reporter("fonts","otf loading") +local report_otf = logs.reporter("fonts","otf loading") -local fonts = fonts -local otf = fonts.handlers.otf +local fonts = fonts +local otf = fonts.handlers.otf -otf.version = 3.025 -- beware: also sync font-mis.lua and in mtx-fonts -otf.cache = containers.define("fonts", "otl", otf.version, true) -otf.svgcache = containers.define("fonts", "svg", otf.version, true) -otf.pdfcache = containers.define("fonts", "pdf", otf.version, true) +otf.version = 3.025 -- beware: also sync font-mis.lua and in mtx-fonts +otf.cache = containers.define("fonts", "otl", otf.version, true) +otf.svgcache = containers.define("fonts", "svg", otf.version, true) +otf.pdfcache = containers.define("fonts", "pdf", otf.version, true) -otf.svgenabled = false +otf.svgenabled = false -local otfreaders = otf.readers +local otfreaders = otf.readers -local hashes = fonts.hashes -local definers = fonts.definers -local readers = fonts.readers -local constructors = fonts.constructors +local hashes = fonts.hashes +local definers = fonts.definers +local readers = fonts.readers +local constructors = fonts.constructors -local otffeatures = constructors.features.otf -local registerotffeature = otffeatures.register +local otffeatures = constructors.features.otf +local registerotffeature = otffeatures.register -local enhancers = allocate() -otf.enhancers = enhancers -local patches = { } -enhancers.patches = patches +local otfenhancers = constructors.enhancers.otf +local registerotfenhancer = otfenhancers.register -local forceload = false -local cleanup = 0 -- mk: 0=885M 1=765M 2=735M (regular run 730M) -local syncspace = true -local forcenotdef = false +local forceload = false +local cleanup = 0 -- mk: 0=885M 1=765M 2=735M (regular run 730M) +local syncspace = true +local forcenotdef = false -local applyruntimefixes = fonts.treatments and fonts.treatments.applyfixes +local applyruntimefixes = fonts.treatments and fonts.treatments.applyfixes -local wildcard = "*" -local default = "dflt" +local wildcard = "*" +local default = "dflt" -local formats = fonts.formats +local formats = fonts.formats -formats.otf = "opentype" -formats.ttf = "truetype" -formats.ttc = "truetype" +formats.otf = "opentype" +formats.ttf = "truetype" +formats.ttc = "truetype" registerdirective("fonts.otf.loader.cleanup", function(v) cleanup = tonumber(v) or (v and 1) or 0 end) registerdirective("fonts.otf.loader.force", function(v) forceload = v end) @@ -105,92 +102,9 @@ registerdirective("fonts.otf.loader.forcenotdef", function(v) forcenotdef = -- end -- end --- Enhancers are used to apply fixes and extensions to fonts. For instance, we use them --- to implement tlig and trep features. They are not neccessarily bound to opentype --- fonts but can also apply to type one fonts, given that they obey the structure of an --- opentype font. They are not to be confused with format specific features but maybe --- some are so generic that they might eventually move to this mechanism. +-- otfenhancers.patch("before","migrate metadata","cambria",function() end) -local ordered_enhancers = { - "check extra features", -} - -local actions = allocate() -local before = allocate() -local after = allocate() - -patches.before = before -patches.after = after - -local function enhance(name,data,filename,raw) - local enhancer = actions[name] - if enhancer then - if trace_loading then - report_otf("apply enhancement %a to file %a",name,filename) - ioflush() - end - enhancer(data,filename,raw) - else - -- no message as we can have private ones - end -end - -function enhancers.apply(data,filename,raw) - local basename = file.basename(lower(filename)) - if trace_loading then - report_otf("%s enhancing file %a","start",filename) - end - ioflush() -- we want instant messages - for e=1,#ordered_enhancers do - local enhancer = ordered_enhancers[e] - local b = before[enhancer] - if b then - for pattern, action in next, b do - if find(basename,pattern) then - action(data,filename,raw) - end - end - end - enhance(enhancer,data,filename,raw) - local a = after[enhancer] - if a then - for pattern, action in next, a do - if find(basename,pattern) then - action(data,filename,raw) - end - end - end - ioflush() -- we want instant messages - end - if trace_loading then - report_otf("%s enhancing file %a","stop",filename) - end - ioflush() -- we want instant messages -end - --- patches.register("before","migrate metadata","cambria",function() end) - -function patches.register(what,where,pattern,action) - local pw = patches[what] - if pw then - local ww = pw[where] - if ww then - ww[pattern] = action - else - pw[where] = { [pattern] = action} - end - end -end - -function patches.report(fmt,...) - if trace_loading then - report_otf("patching: %s",formatters[fmt](...)) - end -end - -function enhancers.register(what,action) -- only already registered can be overloaded - actions[what] = action -end +registerotfenhancer("check extra features", function() end) -- placeholder function otf.load(filename,sub,featurefile) -- second argument (format) is gone ! -- @@ -329,7 +243,7 @@ function otf.load(filename,sub,featurefile) -- second argument (format) is gone otfreaders.expand(data) -- inline tables otfreaders.addunicodetable(data) -- only when not done yet -- - enhancers.apply(data,filename,data) + otfenhancers.apply(data,filename,data) -- -- constructors.addcoreunicodes(data.resources.unicodes) -- still needed ? -- diff --git a/tex/context/base/mkiv/font-otp.lua b/tex/context/base/mkiv/font-otp.lua index 91bd05b32..c52e574b9 100644 --- a/tex/context/base/mkiv/font-otp.lua +++ b/tex/context/base/mkiv/font-otp.lua @@ -30,9 +30,6 @@ fonts.handlers = handlers local otf = handlers.otf or { } handlers.otf = otf -local enhancers = otf.enhancers or { } -otf.enhancers = enhancers - local glists = otf.glists or { "gsub", "gpos" } otf.glists = glists @@ -146,7 +143,7 @@ end -- and repack in such cases (never needed anyway) .. a tricky aspect is that -- we then need to sort more thanks to random hashing -local function packdata(data) +function otf.packdata(data) if data then -- stripdata(data) @@ -536,7 +533,7 @@ local unpacked_mt = { end } -local function unpackdata(data) +function otf.unpackdata(data) if data then local tables = data.tables @@ -895,15 +892,3 @@ local function unpackdata(data) end end end - -if otf.enhancers.register then - - otf.enhancers.register( "pack", packdata) - otf.enhancers.register("unpack",unpackdata) - --- todo: directive - -end - -otf.enhancers.unpack = unpackdata -- used elsewhere -otf.enhancers.pack = packdata -- used elsewhere diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua index 10f0518a8..d37115603 100644 --- a/tex/context/base/mkiv/font-ots.lua +++ b/tex/context/base/mkiv/font-ots.lua @@ -275,6 +275,13 @@ local checkstep = (nodes and nodes.tracers and nodes.tracers.steppers.chec local registerstep = (nodes and nodes.tracers and nodes.tracers.steppers.register) or function() end local registermessage = (nodes and nodes.tracers and nodes.tracers.steppers.message) or function() end +local function checkdisccontent(d) + local pre, post, replace = getdisc(d) + if pre then for n in traverse_id(glue_code,pre) do print("pre",nodes.idstostring(pre)) break end end + if post then for n in traverse_id(glue_code,post) do print("pos",nodes.idstostring(post)) break end end + if replace then for n in traverse_id(glue_code,replace) do print("rep",nodes.idstostring(replace)) break end end +end + local function logprocess(...) if trace_steps then registermessage(...) @@ -351,7 +358,7 @@ end local function copy_glyph(g) -- next and prev are untouched ! local components = getfield(g,"components") if components then - setfield(g,"components",nil) + setfield(g,"components") local n = copy_node(g) copyinjection(n,g) -- we need to preserve the lig indices setfield(g,"components",components) @@ -364,11 +371,18 @@ local function copy_glyph(g) -- next and prev are untouched ! end local function flattendisk(head,disc) - local _, _, replace, _, _, replacetail = getdisc(disc,true) - setfield(disc,"replace",nil) + local pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true) + local prev, next = getboth(disc) + local ishead = head == disc + setdisc(disc) flush_node(disc) - if head == disc then - local next = getnext(disc) + if pre then + flush_node_list(pre) + end + if post then + flush_node_list(post) + end + if ishead then if replace then if next then setlink(replacetail,next) @@ -380,7 +394,6 @@ local function flattendisk(head,disc) return -- maybe warning end else - local prev, next = getboth(disc) if replace then if next then setlink(replacetail,next) @@ -419,8 +432,8 @@ local function markstoligature(head,start,stop,char) else local prev = getprev(start) local next = getnext(stop) - setprev(start,nil) - setnext(stop,nil) + setprev(start) + setnext(stop) local base = copy_glyph(start) if head == start then head = base @@ -482,8 +495,8 @@ local function toligature(head,start,stop,char,dataset,sequence,markflag,discfou local prev = getprev(start) local next = getnext(stop) local comp = start - setprev(start,nil) - setnext(stop,nil) + setprev(start) + setnext(stop) local base = copy_glyph(start) if start == head then head = base @@ -553,38 +566,37 @@ local function toligature(head,start,stop,char,dataset,sequence,markflag,discfou -- anyway local pre, post, replace, pretail, posttail, replacetail = getdisc(discfound,true) if not replace then -- todo: signal simple hyphen - local prev = getprev(base) --- local copied = copy_node_list(comp) -local current = comp -local previous = nil -local copied = nil -while current do - if getid(current) == glyph_code then - local n = copy_node(current) - if copied then - setlink(previous,n) - else - copied = n - end - previous = n - end - current = getnext(current) -end - setprev(discnext,nil) -- also blocks funny assignments - setnext(discprev,nil) -- also blocks funny assignments + local prev = getprev(base) + local current = comp + local previous = nil + local copied = nil + while current do + if getid(current) == glyph_code then + local n = copy_node(current) + if copied then + setlink(previous,n) + else + copied = n + end + previous = n + end + current = getnext(current) + end + setprev(discnext) -- also blocks funny assignments + setnext(discprev) -- also blocks funny assignments if pre then setlink(discprev,pre) end pre = comp if post then setlink(posttail,discnext) - setprev(post,nil) + setprev(post) else post = discnext end setlink(prev,discfound) setlink(discfound,next) - setboth(base,nil,nil) + setboth(base) setfield(base,"components",copied) setdisc(discfound,pre,post,base,discretionary_code) base = prev -- restart @@ -1751,6 +1763,42 @@ end -- order to handle that we need more complex code which also slows down even more. The main -- loop variant could deal with that: test, collapse, backtrack. +local new_kern = nuts.pool.kern + +local function checked(head) + local current = head + while current do + if getid(current) == glue_code then + local kern = new_kern(getfield(current,"width")) + if head == current then + local next = getnext(current) + if next then + setlink(kern,next) + end + flush_node(current) + head = kern + current = next + else + local prev, next = getboth(current) + setlink(prev,kern) + setlink(kern,next) + flush_node(current) + current = next + end + else + current = getnext(current) + end + end + return head +end + +local function setdiscchecked(d,pre,post,replace) + if pre then pre = checked(pre) end + if post then post = checked(post) end + if replace then replace = checked(replace) end + setdisc(d,pre,post,replace) +end + local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,ck,chainproc) if not start then @@ -1773,8 +1821,10 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c local current = start local last = start local prev = getprev(start) + local hasglue = false -- fishy: so we can overflow and then go on in the sweep? + -- todo : id can also be glue_code as we checked spaces local i = f while i <= l do @@ -1783,6 +1833,11 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c i = i + 1 last = current current = getnext(current) + elseif id == glue_code then + i = i + 1 + last = current + current = getnext(current) + hasglue = true elseif id == disc_code then if keepdisc then keepdisc = false @@ -1835,8 +1890,8 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c tail = find_node_tail(head) end setnext(sweepnode,current) - setprev(head,nil) - setnext(tail,nil) + setprev(head) + setnext(tail) appenddisc(sweepnode,head) end end @@ -1849,6 +1904,10 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c if id == glyph_code then i = i + 1 current = getnext(current) + elseif id == glue_code then + i = i + 1 + current = getnext(current) + hasglue = true elseif id == disc_code then if keepdisc then keepdisc = false @@ -1891,6 +1950,9 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c local id = getid(current) if id == glyph_code then i = i - 1 + elseif id == glue_code then + i = i - 1 + hasglue = true elseif id == disc_code then if keepdisc then keepdisc = false @@ -1939,8 +2001,8 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c if cprev then setnext(cprev,lookaheaddisc) end - setprev(cf,nil) - setnext(cl,nil) + setprev(cf) + setnext(cl) if startishead then head = lookaheaddisc end @@ -1967,7 +2029,11 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c local tail = find_node_tail(new) setlink(tail,replace) end - setdisc(lookaheaddisc,cf,post,new) + if hasglue then + setdiscchecked(lookaheaddisc,cf,post,new) + else + setdisc(lookaheaddisc,cf,post,new) + end start = getprev(lookaheaddisc) sweephead[cf] = getnext(clast) sweephead[new] = getnext(last) @@ -1993,8 +2059,8 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c setprev(cnext,backtrackdisc) end setnext(backtrackdisc,cnext) - setprev(cf,nil) - setnext(cl,nil) + setprev(cf) + setnext(cl) local pre, post, replace, pretail, posttail, replacetail = getdisc(backtrackdisc,true) local new = copy_node_list(cf) local cnew = find_node_tail(new) @@ -2021,7 +2087,11 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c else replace = new end - setdisc(backtrackdisc,pre,post,replace) + if hasglue then + setdiscchecked(backtrackdisc,pre,post,replace) + else + setdisc(backtrackdisc,pre,post,replace) + end start = getprev(backtrackdisc) sweephead[post] = getnext(clast) sweephead[replace] = getnext(last) @@ -2744,7 +2814,7 @@ local function kernrun(disc,k_run,font,attr,...) done = true end setprev(pre,nest) --- setprev(pre,nil) +-- setprev(pre) setnext(prev,disc) end end @@ -2758,7 +2828,7 @@ local function kernrun(disc,k_run,font,attr,...) if k_run(posttail,"postinjections",next,font,attr,...) then done = true end - setnext(posttail,nil) + setnext(posttail) setprev(next,disc) end end @@ -2774,7 +2844,7 @@ local function kernrun(disc,k_run,font,attr,...) done = true end setprev(replace,nest) --- setprev(replace,nil) +-- setprev(replace) setnext(prev,disc) end if next then @@ -2782,7 +2852,7 @@ local function kernrun(disc,k_run,font,attr,...) if k_run(replacetail,"replaceinjections",next,font,attr,...) then done = true end - setnext(replacetail,nil) + setnext(replacetail) setprev(next,disc) end elseif prev and next then @@ -2862,7 +2932,7 @@ local function testrun(disc,t_run,c_run,...) local ok, overflow = t_run(replace,next,...) if ok and overflow then -- so, we can have crossed the boundary - setfield(disc,"replace",nil) + setfield(disc,"replace") setlink(prev,replace) -- setlink(replacetail,next) setboth(disc) diff --git a/tex/context/base/mkiv/font-tfm.lua b/tex/context/base/mkiv/font-tfm.lua index d9b052388..6584190ce 100644 --- a/tex/context/base/mkiv/font-tfm.lua +++ b/tex/context/base/mkiv/font-tfm.lua @@ -31,10 +31,14 @@ tfm.maxnestingdepth = 5 tfm.maxnestingsize = 65536*1024 local otf = fonts.handlers.otf +local otfenhancers = otf.enhancers local tfmfeatures = constructors.features.tfm local registertfmfeature = tfmfeatures.register +local tfmenhancers = constructors.enhancers.tfm +local registertfmenhancer = tfmenhancers.register + constructors.resolvevirtualtoo = false -- wil be set in font-ctx.lua fonts.formats.tfm = "type1" -- we need to have at least a value here @@ -73,32 +77,7 @@ function tfm.setfeatures(tfmdata,features) end end -local depth = { } -- table.setmetatableindex("number") -local enhancers = { } - -local steps = { - "normalize features", - "check extra features" -} - --- otf.enhancers.register("check extra features",enhance) - -enhancers["check extra features"] = otf.enhancers.enhance - -local function applyenhancers(data,filename) - for i=1,#steps do - local step = steps[i] - local enhancer = enhancers[step] - if enhancer then - if trace_loading then - report_tfm("applying enhancer %a",step) - end - enhancer(data,filename) - else - report_tfm("invalid enhancer %a",step) - end - end -end +local depth = { } -- table.setmetatableindex("number") -- Normally we just load the tfm data and go on. However there was some demand for -- loading good old tfm /pfb files where afm files were lacking and even enc files @@ -214,7 +193,7 @@ local function read_from_tfm(specification) -- -- We make a pseudo opentype font, e.g. kerns and ligatures etc: -- - applyenhancers(tfmdata,filename) + tfmenhancers.apply(tfmdata,filename) -- -- Now user stuff can kick in. -- @@ -616,7 +595,7 @@ do local everywhere = { ["*"] = { ["*"] = true } } -- or: { ["*"] = { "*" } } local noflags = { false, false, false, false } - enhancers["normalize features"] = function(data) + local function enhance_normalize_features(data) local ligatures = setmetatableindex("table") local kerns = setmetatableindex("table") local characters = data.characters @@ -702,6 +681,9 @@ do data.shared.resources = data.shared.resources or resources end + registertfmenhancer("normalize features", enhance_normalize_features) + registertfmenhancer("check extra features", otfenhancers.enhance) + end -- As with type one (afm) loading, we just use the opentype ones: diff --git a/tex/context/base/mkiv/grph-inc.lua b/tex/context/base/mkiv/grph-inc.lua index 5fd0c07d8..aa4d56805 100644 --- a/tex/context/base/mkiv/grph-inc.lua +++ b/tex/context/base/mkiv/grph-inc.lua @@ -48,6 +48,7 @@ local todimen = string.todimen local collapsepath = file.collapsepath local formatters = string.formatters local expandfilename = dir.expandname +local formatcolumns = utilities.formatters.formatcolumns local P, R, S, Cc, C, Cs, Ct, lpegmatch = lpeg.P, lpeg.R, lpeg.S, lpeg.Cc, lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.match @@ -84,12 +85,15 @@ local trace_bases = false trackers.register ("graphics.bases", func local trace_programs = false trackers.register ("graphics.programs", function(v) trace_programs = v end) local trace_conversion = false trackers.register ("graphics.conversion", function(v) trace_conversion = v end) local trace_inclusion = false trackers.register ("graphics.inclusion", function(v) trace_inclusion = v end) +local trace_usage = false trackers.register ("graphics.usage", function(v) trace_usage = v end) local extra_check = false directives.register("graphics.extracheck", function(v) extra_check = v end) local report_inclusion = logs.reporter("graphics","inclusion") local report_figures = logs.reporter("system","graphics") local report_figure = logs.reporter("used graphic") +local report_status = logs.reporter("graphics","status") +local report_newline = logs.newline local f_hash_part = formatters["%s->%s->%s->%s"] local f_hash_full = formatters["%s->%s->%s->%s->%s->%s->%s->%s"] @@ -301,39 +305,31 @@ function figures.badname(name) end end -local trace_names = false - -trackers.register("graphics.lognames", function(v) - if v and not trace_names then - luatex.registerstopactions(function() - if figures.nofprocessed > 0 then - local report_newline = logs.newline - logs.pushtarget("logfile") - report_newline() - report_figures("start names") - for _, data in table.sortedhash(figures_found) do - report_newline() - report_figure("asked : %s",data.askedname) - if data.found then - report_figure("format : %s",data.format) - report_figure("found : %s",data.foundname) - report_figure("used : %s",data.fullname) - if data.badname then - report_figure("comment : %s","bad name") - elseif data.comment then - report_figure("comment : %s",data.comment) - end - else - report_figure("comment : %s","not found") - end +luatex.registerstopactions(function() + if trace_usage and figures.nofprocessed > 0 then + logs.pushtarget("logfile") + report_newline() + report_figures("start names") + for _, data in table.sortedhash(figures_found) do + report_newline() + report_figure("asked : %s",data.askedname) + if data.found then + report_figure("format : %s",data.format) + report_figure("found : %s",data.foundname) + report_figure("used : %s",data.fullname) + if data.badname then + report_figure("comment : %s","bad name") + elseif data.comment then + report_figure("comment : %s",data.comment) end - report_newline() - report_figures("stop names") - report_newline() - logs.poptarget() + else + report_figure("comment : %s","not found") end - end) - trace_names = true + end + report_newline() + report_figures("stop names") + report_newline() + logs.poptarget() end end) @@ -1182,18 +1178,18 @@ function figures.check(data) return (checkers[data.status.format] or checkers.generic)(data) end -local trace_usage = false local used_images = { } -trackers.register("graphics.usage", function(v) - if v and not trace_usage then - luatex.registerstopactions(function() +statistics.register("used graphics",function() + if trace_usage then + local filename = file.nameonly(environment.jobname) .. "-figures-usage.lua" + if next(figures_found) then local found = { } - for _, t in table.sortedhash(figures_found) do - found[#found+1] = t - for k, v in next, t do + for _, data in table.sortedhash(figures_found) do + found[#found+1] = data + for k, v in next, data do if v == false or v == "" then - t[k] = nil + data[k] = nil end end end @@ -1208,18 +1204,20 @@ trackers.register("graphics.usage", function(v) end for _, t in next, u do for k, v in next, t do - if v == false or v == "" then + if v == false or v == "" or k == "private" then t[k] = nil end end end end - table.save(file.nameonly(environment.jobname) .. "-figures-usage.lua",{ + table.save(filename,{ found = found, used = used_images, } ) - end) - trace_usage = true + return format("log saved in '%s'",filename) + else + os.remove(filename) + end end end) diff --git a/tex/context/base/mkiv/grph-inc.mkiv b/tex/context/base/mkiv/grph-inc.mkiv index 94682b65f..5600ac868 100644 --- a/tex/context/base/mkiv/grph-inc.mkiv +++ b/tex/context/base/mkiv/grph-inc.mkiv @@ -866,12 +866,41 @@ [\jobname.buffer] [\c!object=\v!no] -% Another one: +% Another two: \defineexternalfigure [\v!inline] [\c!height=\lineheight] +\defineexternalfigure + [\v!combination] + [\c!width=\dimexpr(\textwidth-\numexpr\combinationparameter\c!nx-\plusone\relax\dimexpr\combinationparameter\c!distance\relax)/\combinationparameter\c!nx\relax] + +% \startcombination[nx=2,ny=1] +% {\externalfigure[dummy][combination]} {} +% {\externalfigure[dummy][combination]} {} +% \stopcombination + +% \startcombination[nx=2,ny=2] +% {\externalfigure[dummy][combination]} {} +% {\externalfigure[dummy][combination]} {} +% {\externalfigure[dummy][combination]} {} +% {\externalfigure[dummy][combination]} {} +% \stopcombination + +% \startcombination[nx=3,ny=1] +% {\externalfigure[dummy][combination]} {} +% {\externalfigure[dummy][combination]} {} +% {\externalfigure[dummy][combination]} {} +% \stopcombination + +% \startcombination[nx=4,ny=1] +% {\externalfigure[dummy][combination]} {} +% {\externalfigure[dummy][combination]} {} +% {\externalfigure[dummy][combination]} {} +% {\externalfigure[dummy][combination]} {} +% \stopcombination + \unexpanded\def\inlinefigure[#1]{\dontleavehmode\sbox{\externalfigure[#1][\v!inline]}} \protect \endinput diff --git a/tex/context/base/mkiv/lang-def.mkiv b/tex/context/base/mkiv/lang-def.mkiv index 5e40a33b0..85f4e4e3f 100644 --- a/tex/context/base/mkiv/lang-def.mkiv +++ b/tex/context/base/mkiv/lang-def.mkiv @@ -450,6 +450,8 @@ % Celtic: Breton, Welsh, Irish, Manx, Scottish Gaelic +% CJK: Chinese, Japanese, Korean + \installlanguage [\s!cn] [\c!leftsentence=——, @@ -487,6 +489,10 @@ % \c!date={서기,\space,\v!year,\labeltext{\v!year},\space,\v!month,\labeltext{\v!month},\space,\v!day,\labeltext{\v!day}}] \c!date={\v!year,\labeltext{\v!year},\space,\v!month,\labeltext{\v!month},\space,\v!day,\labeltext{\v!day}}] +\installlanguage [\s!chinese] [\s!cn] +\installlanguage [\s!japanese] [\s!ja] +\installlanguage [\s!korean] [\s!kr] + % Greek \installlanguage diff --git a/tex/context/base/mkiv/luat-usr.lua b/tex/context/base/mkiv/luat-usr.lua index 071e3bf5b..e7406782b 100644 --- a/tex/context/base/mkiv/luat-usr.lua +++ b/tex/context/base/mkiv/luat-usr.lua @@ -148,6 +148,7 @@ local function registername(name,message) documentdata = documentdata, -- always there fast context = context, + -- tostring = tostring, tonumber = tonumber, -- standard lua modules diff --git a/tex/context/base/mkiv/math-stc.mkvi b/tex/context/base/mkiv/math-stc.mkvi index 96e1738db..208e756f6 100644 --- a/tex/context/base/mkiv/math-stc.mkvi +++ b/tex/context/base/mkiv/math-stc.mkvi @@ -471,10 +471,14 @@ {\math_stackers_triplet\zerocount\currentmathstackers\scratchcounter{#toptext}{#bottomtext}% \endgroup} -%D A few direct accessors: +%D A few direct accessors (in the meantime we redefined \mathextensible so we renamed the +%D following): -\unexpanded\def\mathextensible{\begingroup\dosingleempty\math_stackers_handle_math} -\unexpanded\def\textextensible{\begingroup\dosingleempty\math_stackers_handle_text} +\unexpanded\def\directmathextensible{\begingroup\dosingleempty\math_stackers_handle_math} +\unexpanded\def\directtextextensible{\begingroup\dosingleempty\math_stackers_handle_text} + +\let\mathstacker\directmathextensible +\let\textstacker\directtextextensible \unexpanded\def\math_stackers_handle_math[#category]% {\math_stackers_handle_extensible{\iffirstargument#category\else\v!mathematics\fi}} % will be defined later on diff --git a/tex/context/base/mkiv/meta-ini.lua b/tex/context/base/mkiv/meta-ini.lua index 8f7131263..d3865c433 100644 --- a/tex/context/base/mkiv/meta-ini.lua +++ b/tex/context/base/mkiv/meta-ini.lua @@ -75,45 +75,53 @@ local dimenorname = + (C(lpegpatterns.float) + Cc(1)) * lpegpatterns.space^0 * P("\\") * C(lpegpatterns.letter^1) / function(f,s) local t = textype(s) if t == "dimen" then - context("\\the\\dimexpr %s\\%s",f,s) + context("\\the\\dimexpr %s\\%s\\relax",f,s) elseif t == "count" then context("\\the\\numexpr \\%s * %s\\relax",s,f) -- \scratchcounter is not permitted end end -local splitter = lpeg.splitat(":",true) - -function commands.prepareMPvariable(v) -- slow but ok - if v == "" then - MPcolor("black") - else - local typ, var = lpegmatch(splitter,v) - if not var then - -- parse - if colorhash[v] then - MPcolor(v) - elseif tonumber(v) then - context(v) - elseif not lpegmatch(dimenorname,v) then - context("\\number %s",v) -- 0.4 ... - end - elseif typ == "d" then -- to be documented - -- dimension - context("\\the\\dimexpr %s",var) - elseif typ == "n" then -- to be documented - -- number - context("\\the\\numexpr %s",var) - elseif typ == "s" then -- to be documented - -- string - context(var) - elseif typ == "c" then -- to be documented - -- color - MPcolor(var) +local splitter = lpeg.splitat("::",true) + +interfaces.implement { + name = "prepareMPvariable", + arguments = "string", + actions = function(v) + if v == "" then + -- MPcolor("black") + context("black") else - context(var) + local typ, var = lpegmatch(splitter,v) + if not var then + -- parse + if colorhash[v] then + -- MPcolor(v) + context("%q",var) + elseif tonumber(v) then + context(v) + elseif not lpegmatch(dimenorname,v) then + context("\\number %s",v) -- 0.4 ... + end + elseif typ == "d" then -- to be documented + -- dimension + context("\\the\\dimexpr %s\\relax",var) + elseif typ == "n" then -- to be documented + -- number + context("\\the\\numexpr %s\\relax",var) + elseif typ == "s" then -- to be documented + -- string + -- context(var) + context("%q",var) + elseif typ == "c" then -- to be documented + -- color + -- MPcolor(var) + context("%q",var) + else + context(var) + end end end -end +} -- function metapost.formatnumber(f,n) -- just lua format -- f = gsub(f,"@(%d)","%%.%1") diff --git a/tex/context/base/mkiv/meta-ini.mkiv b/tex/context/base/mkiv/meta-ini.mkiv index c9b15c822..b07574573 100644 --- a/tex/context/base/mkiv/meta-ini.mkiv +++ b/tex/context/base/mkiv/meta-ini.mkiv @@ -521,10 +521,7 @@ \installcorenamespace{graphicvariable} -\def \meta_prepare_variable_default {\MPcolor{black}} % just to be sure we use a color but ... -\edef\meta_unknown_variable_template {\??graphicvariable:\s!unknown} - -\letvalue{\??graphicvariable:\s!unknown}\empty +\def\meta_prepare_variable_default{\MPcolor{black}} % just to be sure we use a color but ... \unexpanded\def\setupMPvariables {\dodoubleempty\meta_setup_variables} @@ -564,9 +561,9 @@ {\edef\m_meta_current_variable_template {\??graphicvariable\currentmpvariableclass:#1}% \edef\m_meta_current_variable - {\csname\ifcsname\m_meta_current_variable_template\endcsname - \m_meta_current_variable_template\else\meta_unknown_variable_template - \fi\endcsname}% + {\ifcsname\m_meta_current_variable_template\endcsname + \lastnamedcs + \fi}% \ifx\m_meta_current_variable\empty \expandafter\meta_prepare_variable_nop \else @@ -580,15 +577,11 @@ {\edef\m_meta_current_variable_template {\??graphicvariable\currentmpvariableclass:#1}% \edef\m_meta_current_variable - {\csname - \ifcsname\m_meta_current_variable_template\endcsname - \m_meta_current_variable_template - \else\ifcsname\??graphicvariable\currentMPgraphicname:#1\endcsname - \??graphicvariable\currentMPgraphicname:#1% - \else - \meta_unknown_variable_template - \fi\fi - \endcsname}% + {\ifcsname\m_meta_current_variable_template\endcsname + \lastnamedcs + \else\ifcsname\??graphicvariable\currentMPgraphicname:#1\endcsname + \lastnamedcs + \fi\fi}% \ifx\m_meta_current_variable\empty \expandafter\meta_prepare_variable_nop \else @@ -619,6 +612,10 @@ \endgroup\meta_prepare_variable_dimension \fi}} +% \def\meta_prepare_variable_yes +% {\expandafter\edef\csname\m_meta_current_variable_template\endcsname +% {\clf_prepareMPvariable {\m_meta_current_variable}}} + \let\MPvar \MPvariable \let\setMPvariables\setupMPvariables @@ -708,16 +705,18 @@ {\setunreferencedobject{MP}} \def\meta_handle_unique_graphic#1#2#3% when there are too many, we can store data at the lua end, although, - {\begingroup % when there are that many they're probably not that unique anyway + {\begingroup % when there are that many they're probably not that unique anyway \edef\currentmpvariableclass{#1}% \extendMPoverlaystamp{#2}% incl prepare - \ifcsname\??mpgraphic\overlaystamp:#1\endcsname\else + \ifcsname\??mpgraphic\overlaystamp:#1\endcsname + \lastnamedcs + \else \meta_enable_include % redundant \global\advance\c_meta_object_counter\plusone \meta_use_box{\number\c_meta_object_counter}\hpack{\meta_process_graphic{#3}}% was vbox, graphic must end up as hbox \setxvalue{\??mpgraphic\overlaystamp:#1}{\meta_reuse_box{\number\c_meta_object_counter}{\the\MPllx}{\the\MPlly}{\the\MPurx}{\the\MPury}}% + \csname\??mpgraphic\overlaystamp:#1\endcsname\empty \fi - \csname\??mpgraphic\overlaystamp:#1\endcsname\empty \endgroup} \unexpanded\def\startuniqueMPgraphic diff --git a/tex/context/base/mkiv/node-ini.mkiv b/tex/context/base/mkiv/node-ini.mkiv index d04e647de..eb4b3a706 100644 --- a/tex/context/base/mkiv/node-ini.mkiv +++ b/tex/context/base/mkiv/node-ini.mkiv @@ -34,8 +34,7 @@ \registerctxluafile{node-ext}{1.001} \registerctxluafile{node-acc}{1.001} % experimental %registerctxluafile{node-prp}{1.001} % makes no sense (yet) - -\doifelsefile{node-ppt.lua}{\registerctxluafile{node-ppt}{1.001}}{} +\registerctxluafile{node-ppt}{1.001} \newcount\c_node_tracers_show_box % box number diff --git a/tex/context/base/mkiv/node-ltp.lua b/tex/context/base/mkiv/node-ltp.lua index 0803c949d..de1954386 100644 --- a/tex/context/base/mkiv/node-ltp.lua +++ b/tex/context/base/mkiv/node-ltp.lua @@ -135,7 +135,7 @@ if not modules then modules = { } end modules ['node-par'] = { local utfchar = utf.char local write, write_nl = texio.write, texio.write_nl -local sub, format = string.sub, string.format +local sub, formatters = string.sub, string.formatters local round, floor = math.round, math.floor local insert, remove = table.insert, table.remove @@ -205,6 +205,7 @@ local getchar = nuts.getchar local getdisc = nuts.getdisc local getattr = nuts.getattr local getdisc = nuts.getdisc +local getglue = nuts.getglue local isglyph = nuts.isglyph @@ -216,10 +217,10 @@ local setnext = nuts.setnext local setprev = nuts.setprev local setdisc = nuts.setdisc local setsubtype = nuts.setsubtype +local setglue = nuts.setglue local slide_node_list = nuts.slide -- get rid of this, probably ok > 78.2 local find_tail = nuts.tail -local new_node = nuts.new local copy_node = nuts.copy local flush_node = nuts.flush local flush_node_list = nuts.flush_list @@ -228,6 +229,7 @@ local xpack_nodes = nuts.hpack local replace_node = nuts.replace local insert_node_after = nuts.insert_after local insert_node_before = nuts.insert_before +local is_zero_glue = nuts.is_zero_glue local setnodecolor = nodes.tracers.colors.set @@ -315,6 +317,7 @@ local new_lineskip = nodepool.lineskip local new_baselineskip = nodepool.baselineskip local new_temp = nodepool.temp local new_rule = nodepool.rule +local new_hlist = nodepool.hlist local is_rotated = nodes.is_rotated local is_parallel = nodes.textdir_is_parallel @@ -339,7 +342,7 @@ local function new_dir_stack(dir) -- also use elsewhere end -- The next function checks a dir node and returns the new dir state. By --- using s static table we are quite efficient. This function is used +-- using a static table we are quite efficient. This function is used -- in the parbuilder. local function checked_line_dir(stack,current) @@ -838,28 +841,36 @@ end local function append_to_vlist(par, b) local prev_depth = par.prev_depth + local head_field = par.head_field + local tail_field = head_field and slide_node_list(head_field) -- todo: find_tail + local is_hlist = getid(b) == hlist_code -- if prev_depth > par.ignored_dimen then if prev_depth > ignore_depth then - if getid(b) == hlist_code then - local d = getfield(par.baseline_skip,"width") - prev_depth - getfield(b,"height") -- deficiency of space between baselines - local s = d < par.line_skip_limit and new_lineskip(par.lineskip) or new_baselineskip(d) - local head_field = par.head_field + if is_hlist then + local width, stretch, shrink, stretch_order, shrink_order = getglue(par.baseline_skip) + local delta = width - prev_depth - getfield(b,"height") -- deficiency of space between baselines + local skip = nil + if delta < par.line_skip_limit then + width, stretch, shrink, stretch_order, shrink_order = getglue(par.lineskip) + skip = new_lineskip(width, stretch, shrink, stretch_order, shrink_order) + else + skip = new_baselineskip(delta, stretch, shrink, stretch_order, shrink_order) + end if head_field then - local n = slide_node_list(head_field) -- todo: find_tail - setlink(n,s) + setlink(tail_field,skip) else - par.head_field = s + par.head_field = skip + head_field = skip end + tail_field = skip end end - local head_field = par.head_field if head_field then - local n = slide_node_list(head_field) -- todo: find_tail - setlink(n,b) + setlink(tail_field,b) else par.head_field = b end - if getid(b) == hlist_code then + if is_hlist then local pd = getfield(b,"depth") par.prev_depth = pd texnest[texnest.ptr].prevdepth = pd @@ -883,7 +894,7 @@ local hztolerance = 2500 local hzwarned = false local function used_skip(s) - return s and (getfield(s,"width") ~= 0 or getfield(s,"stretch") ~= 0 or getfield(s,"shrink") ~= 0) and s or nil + return s and not is_zero_glue(s) and s end local function initialize_line_break(head,display) @@ -1144,9 +1155,9 @@ local function initialize_line_break(head,display) end if last_line_fit > 0 then - local spec = par.final_par_glue.spec - local stretch = spec.stretch - local stretch_order = spec.stretch_order + local final_par_glue = par.final_par_glue + local stretch = getfield(final_par_glue,"stretch") + local stretch_order = getfield(final_par_glue,"stretch_order") if stretch > 0 and stretch_order > 0 and background.fi == 0 and background.fil == 0 and background.fill == 0 and background.filll == 0 then par.do_last_line_fit = true local si = stretch_orders[stretch_order] @@ -1222,7 +1233,7 @@ local function post_line_break(par) lastnode = replace_node(lastnode,new_rightskip(rightskip)) glue_break = true lineend = lastnode - lastnode = getprev(r) + lastnode = getprev(lastnode) elseif id == disc_code then local prevlast = getprev(lastnode) local nextlast = getnext(lastnode) @@ -1432,12 +1443,13 @@ local function post_line_break(par) local next = nil while true do next = getnext(current) - if next == current_break.cur_break or getid(next) == glyph_code then + if next == current_break.cur_break then break end - local id = getid(next) - local subtype = getsubtype(next) - if id == localpar_code then + local id = getid(next) + if id == glyph_code then + break + elseif id == localpar_code then -- nothing elseif id < math_code then -- messy criterium @@ -1446,9 +1458,12 @@ local function post_line_break(par) -- keep the math node setfield(next,"surround",0) break - elseif id == kern_code and (subtype ~= userkern_code and subtype ~= italickern_code and not getattr(next,a_fontkern)) then - -- fontkerns and accent kerns as well as otf injections - break + elseif id == kern_code then + local subtype = getsubtype(next) + if subtype ~= userkern_code and subtype ~= italickern_code and not getattr(next,a_fontkern) then + -- fontkerns and accent kerns as well as otf injections + break + end end current = next end @@ -1920,8 +1935,8 @@ local function try_break(pi, break_type, par, first_p, current, checked_expansio local id = getid(l) if id == glyph_code then -- ok ? - elseif id == disc_code and l.post then - l = l.post -- TODO: first char could be a disc + elseif id == disc_code and getfield(l,"post") then + l = getfield(l,"post") -- TODO: first char could be a disc else l = find_protchar_left(l) end @@ -2470,10 +2485,10 @@ function diagnostics.stop() end function diagnostics.current_pass(par,what) - write_nl("log",format("@%s",what)) + write_nl("log",formatters["@%s"](what)) end -local verbose = false -- true +local verbose = false -- true local function short_display(target,a,font_in_short_display) while a do @@ -2494,7 +2509,7 @@ local function short_display(target,a,font_in_short_display) font_in_short_display = short_display(target,pre,font_in_short_display) font_in_short_display = short_display(target,post,font_in_short_display) elseif verbose then - write(target,format("[%s]",nodecodes[id])) + write(target,formatters["[%s]"](nodecodes[id])) elseif id == rule_code then write(target,"|") elseif id == glue_code then @@ -2529,20 +2544,20 @@ function diagnostics.break_node(par, q, fit_class, break_type, current) -- %d ? local s = number.toscaled(q.active_short) local g = number.toscaled(q.active_glue) if current then - write_nl("log",format("@@%d: line %d.%d%s t=%s s=%s g=%s", + write_nl("log",formatters["@@%d: line %d.%d%s t=%s s=%s g=%s"]( passive.serial or 0,q.line_number-1,fit_class,typ_ind,q.total_demerits,s,g)) else - write_nl("log",format("@@%d: line %d.%d%s t=%s s=%s a=%s", + write_nl("log",formatters["@@%d: line %d.%d%s t=%s s=%s a=%s"]( passive.serial or 0,q.line_number-1,fit_class,typ_ind,q.total_demerits,s,g)) end else - write_nl("log",format("@@%d: line %d.%d%s t=%s", + write_nl("log",formatters["@@%d: line %d.%d%s t=%s"]( passive.serial or 0,q.line_number-1,fit_class,typ_ind,q.total_demerits)) end if not passive.prev_break then write("log"," -> @0") else - write("log",format(" -> @%d", passive.prev_break.serial or 0)) + write("log",formatters[" -> @%d"](passive.prev_break.serial or 0)) end end @@ -2585,19 +2600,19 @@ function diagnostics.feasible_break(par, current, r, b, pi, d, artificial_demeri via = r.break_node.serial or 0 end if b <= infinite_badness then - badness = tonumber(d) -- format("%d", b) + badness = tonumber(d) end if not artificial_demerits then - demerits = tonumber(d) -- format("%d", d) + demerits = tonumber(d) end - write("log",format(" via @%d b=%s p=%s d=%s", via, badness, pi, demerits)) + write("log",formatters[" via @%d b=%s p=%s d=%s"](via,badness,pi,demerits)) end -- reporting -- statistics.register("alternative parbuilders", function() if nofpars > 0 then - return format("%s paragraphs, %s lines (%s protruded, %s adjusted)", nofpars, noflines, nofprotrudedlines, nofadjustedlines) + return formatters["%s paragraphs, %s lines (%s protruded, %s adjusted)"](nofpars,noflines,nofprotrudedlines,nofadjustedlines) end end) @@ -2677,7 +2692,7 @@ end -- local font_expand_ratio = 0 -- local delta = width - natural -- --- local hlist = new_node("hlist") +-- local hlist = new_hlist() -- -- setlist(hlist,head) -- setfield(hlist,"dir",direction or tex.textdir) @@ -2793,7 +2808,7 @@ local function hpack(head,width,method,direction,firstline,line) -- fast version -- we can pass the adjust_width and adjust_height so that we don't need to recalculate them but -- with the glue mess it's less trivial as we lack detail .. challenge - local hlist = new_node("hlist") + local hlist = new_hlist() setfield(hlist,"dir",direction) @@ -3126,7 +3141,7 @@ local function hpack(head,width,method,direction,firstline,line) -- fast version local overfullrule = tex.overfullrule if fuzz > hfuzz and overfullrule > 0 then -- weird, is always called and no rules shows up - setfield(slide_node_list(list),"next",new_rule(overfullrule,nil,nil,hlist.dir)) -- todo: find_tail + setfield(slide_node_list(list),"next",new_rule(overfullrule,nil,nil,getfield(hlist,"dir"))) -- todo: find_tail end diagnostics.overfull_hbox(hlist,line,-delta) end @@ -3145,35 +3160,37 @@ local function common_message(hlist,line,str) write_nl("") if status.output_active then -- unset write(str," has occurred while \\output is active") + else + write(str) end local fileline = status.linenumber if line > 0 then - write(str," in paragraph at lines ",fileline,"--",fileline+line-1) + write(formatters[" in paragraph at lines %s--%s"](fileline,"--",fileline+line-1)) elseif line < 0 then - write(str," in alignment at lines ",fileline,"--",fileline-line-1) + write(formatters[" in alignment at lines "](fileline,"--",fileline-line-1)) else - write(str," detected at line ",fileline) + write(formatters[" detected at line %s"](fileline)) end write_nl("") - diagnostics.short_display(hlist.list,false) + diagnostics.short_display(getlist(hlist),false) write_nl("") -- diagnostics.start() - -- show_box(hlist.list) + -- show_box(getlist(hlist)) -- diagnostics.stop() end function diagnostics.overfull_hbox(hlist,line,d) - common_message(hlist,line,format("Overfull \\hbox (%spt too wide)",number.toscaled(d))) + common_message(hlist,line,formatters["Overfull \\hbox (%spt too wide)"](number.toscaled(d))) end function diagnostics.bad_hbox(hlist,line,b) - common_message(hlist,line,format("Tight \\hbox (badness %i)",b)) + common_message(hlist,line,formatters["Tight \\hbox (badness %i)"](b)) end function diagnostics.underfull_hbox(hlist,line,b) - common_message(hlist,line,format("Underfull \\hbox (badness %i)",b)) + common_message(hlist,line,formatters["Underfull \\hbox (badness %i)"](b)) end function diagnostics.loose_hbox(hlist,line,b) - common_message(hlist,line,format("Loose \\hbox (badness %i)",b)) + common_message(hlist,line,formatters["Loose \\hbox (badness %i)"](b)) end diff --git a/tex/context/base/mkiv/node-met.lua b/tex/context/base/mkiv/node-met.lua index 2402a9fd5..1dee3a9f5 100644 --- a/tex/context/base/mkiv/node-met.lua +++ b/tex/context/base/mkiv/node-met.lua @@ -625,7 +625,7 @@ local messyhack = table.tohash { -- temporary solution } table.setmetatableindex(keys,function(t,k) - local v = getfields(k) + v = (k == "attributelist" or k == nodecodes.attributelist) and { } or getfields(k) if messyhack[k] then for i=1,#v do if v[i] == "subtype" then diff --git a/tex/context/base/mkiv/node-nut.lua b/tex/context/base/mkiv/node-nut.lua index 3bd63bd58..c2c74308d 100644 --- a/tex/context/base/mkiv/node-nut.lua +++ b/tex/context/base/mkiv/node-nut.lua @@ -265,6 +265,7 @@ local d_slide = direct.slide local d_traverse = direct.traverse local d_setlink = direct.setlink local d_setboth = direct.setboth +local d_getboth = direct.getboth local function remove(head,current,free_too) local t = current @@ -297,7 +298,7 @@ function nuts.replace(head,current,new) -- no head returned if false d_setlink(new,next) end if prev then - d_setlink(new,prev) + d_setlink(prev,new) end if head then if head == current then diff --git a/tex/context/base/mkiv/node-res.lua b/tex/context/base/mkiv/node-res.lua index e4cba8ef1..68eb92d2b 100644 --- a/tex/context/base/mkiv/node-res.lua +++ b/tex/context/base/mkiv/node-res.lua @@ -251,6 +251,7 @@ function nutpool.italickern(k) end function nutpool.gluespec(width,stretch,shrink,stretch_order,shrink_order) + -- maybe setglue local s = copy_nut(glue_spec) if width and width ~= 0 then setfield(s,"width",width) @@ -271,6 +272,7 @@ function nutpool.gluespec(width,stretch,shrink,stretch_order,shrink_order) end local function someskip(skip,width,stretch,shrink,stretch_order,shrink_order) + -- maybe setglue local n = copy_nut(skip) if width and width ~= 0 then setfield(n,"width",width) diff --git a/tex/context/base/mkiv/node-rul.mkiv b/tex/context/base/mkiv/node-rul.mkiv index 8eef40a18..0be4a0f4b 100644 --- a/tex/context/base/mkiv/node-rul.mkiv +++ b/tex/context/base/mkiv/node-rul.mkiv @@ -97,13 +97,13 @@ \appendtoks \ifcsname\??barindex\currentbar\endcsname - \lastnamedcs + \lastnamedcs\zerocount \else \expandafter\newcount\csname\??barindex\currentbar\endcsname \fi -% \normalexpanded{\t_node_rules_checklist{\node_rules_redefine{\currentbar}\the\t_node_rules_checklist}}% - \normalexpanded{\t_node_rules_checklist{\the\t_node_rules_checklist\node_rules_redefine{\currentbar}}}% -% \etoksapp\t_node_rules_checklist{\node_rules_redefine{\currentbar}}% + % \normalexpanded{\t_node_rules_checklist{\node_rules_redefine{\currentbar}\the\t_node_rules_checklist}}% + \normalexpanded{\t_node_rules_checklist{\the\t_node_rules_checklist\relax\node_rules_redefine{\currentbar}}}% + % \etoksapp\t_node_rules_checklist{\node_rules_redefine{\currentbar}}% \node_rules_define \setuevalue\currentbar{\node_rules_direct{\currentbar}}% \to \everydefinebar @@ -341,7 +341,7 @@ \else \expandafter\newcount\csname\??shiftindex\currentshift\endcsname \fi - \normalexpanded{\t_node_shifts_checklist{\node_shifts_redefine{\currentshift}\the\t_node_shifts_checklist}}% + \normalexpanded{\t_node_shifts_checklist{\the\t_node_shifts_checklist\node_shifts_redefine{\currentshift}}}% order ? \node_shifts_define \setuevalue\currentshift{\node_shifts_direct{\currentshift}}% \to \everydefineshift diff --git a/tex/context/base/mkiv/node-ser.lua b/tex/context/base/mkiv/node-ser.lua index 2ad1242c5..b00268828 100644 --- a/tex/context/base/mkiv/node-ser.lua +++ b/tex/context/base/mkiv/node-ser.lua @@ -10,7 +10,7 @@ if not modules then modules = { } end modules ['node-ser'] = { -- of luatex; this is pretty old code that needs an overhaul local type = type -local concat, tohash, sortedkeys, printtable = table.concat, table.tohash, table.sortedkeys, table.print +local concat, tohash, sortedkeys, printtable, serialize = table.concat, table.tohash, table.sortedkeys, table.print, table.serialize local formatters, format, rep = string.formatters, string.format, string.rep local allocate = utilities.storage.allocate @@ -38,14 +38,16 @@ local f_char = formatters["%U"] ----- f_char = utilities.strings.chkuni -- formatters["%!chkuni!"] +-- this needs checking with the latest state of affairs: + local expand = allocate ( tohash { -- text: "list", -- list_ptr & ins_ptr & adjust_ptr "pre", -- "post", -- + "replace", -- nobreak "top_skip", -- "attr", -- - "replace", -- nobreak "components", -- lig_ptr "box_left", -- "box_right", -- @@ -85,15 +87,15 @@ local ignore = allocate ( tohash { local dimension = allocate ( tohash { "width", "height", "depth", "shift", "stretch", "shrink", - "xoffset", "yoffset", + "xoffset", "yoffset", "xadvance", "surround", "kern", "box_left_width", "box_right_width" } ) --- flat: don't use next, but indexes --- verbose: also add type --- can be sped up +-- flat : don't use next, but indexes +-- verbose : also add type +-- todo : speed up nodes.dimensionfields = dimension nodes.listablefields = expand @@ -111,7 +113,7 @@ local function astable(n,sparse) -- not yet ok, might get obsolete anyway if ignore[v] or v == "id" then -- skip elseif expand[v] then -- or: type(n[v]) ~= "string" or type(n[v]) ~= "number" or type(n[v]) ~= "table" - t[v] = "pointer to list" + t[v] = "" elseif sparse then if (type(d) == "number" and d ~= 0) or (type(d) == "string" and d ~= "") then t[v] = d @@ -133,7 +135,7 @@ setinspector("node",function(v) if is_node(v) then printtable(astable(v),tostrin local function totable(n,flat,verbose,noattributes) -- nicest: n,true,true,true local function to_table(n,flat,verbose,noattributes) -- no need to pass - local f = getfields(n) + local f = getfields(n) local tt = { } for k=1,#f do local v = f[k] @@ -143,6 +145,8 @@ local function totable(n,flat,verbose,noattributes) -- nicest: n,true,true,true -- skip elseif noattributes and v == "attr" then -- skip + elseif v == "prev" then + tt[v] = "" elseif expand[v] then if type(nv) == "number" or type(nv) == "string" then tt[v] = nv @@ -213,102 +217,16 @@ local function key(k) return ((type(k) == "number") and "["..k.."]") or k end --- not ok yet; this will become a module - --- todo: adapt to nodecodes etc .. use formatters - -local function serialize(root,name,handle,depth,m,noattributes) - handle = handle or print - if depth then - depth = depth .. " " - handle(format("%s%s={",depth,key(name))) - else - depth = "" - local tname = type(name) - if tname == "string" then - if name == "return" then - handle("return {") - else - handle(name .. "={") - end - elseif tname == "number" then - handle("[" .. name .. "]={") - else - handle("t={") - end - end - if root then - local fld - if root.id then - fld = getfields(root) -- we can cache these (todo) - else - fld = sortedkeys(root) - end - if type(root) == 'table' and root['type'] then -- userdata or table - handle(format("%s type=%q,",depth,root['type'])) - end - for f=1,#fld do - local k = fld[f] - if k == "ref_count" then - -- skip - elseif noattributes and k == "attr" then - -- skip - elseif k == "id" then - local v = root[k] - handle(format("%s id=%s,",depth,nodecodes[v] or noadcodes[v] or v)) - elseif k then - local v = root[k] - local t = type(v) - if t == "number" then - if v == 0 then - -- skip - else - handle(format("%s %s=%s,",depth,key(k),v)) - end - elseif t == "string" then - if v == "" then - -- skip - else - handle(format("%s %s=%q,",depth,key(k),v)) - end - elseif t == "boolean" then - handle(format("%s %s=%q,",depth,key(k),tostring(v))) - elseif v then -- userdata or table - serialize(v,k,handle,depth,m+1,noattributes) - end - end - end - if root['next'] then -- userdata or table - serialize(root['next'],'next',handle,depth,m+1,noattributes) - end - end - if m and m > 0 then - handle(format("%s},",depth)) - else - handle(format("%s}",depth)) - end -end - -function nodes.serialize(root,name,noattributes) - local t, n = { }, 0 - local function flush(s) - n = n + 1 - t[n] = s - end - serialize(tonode(root),name,flush,nil,0,noattributes) - return concat(t,"\n") +function nodes.serialize(root,flat,verbose,noattributes,name) + return serialize(totable(tonode(root),flat,verbose,noattributes),name) end -function nodes.serializebox(n,flat,verbose,name) - return nodes.serialize(nodes.totable(tex.box[n],flat,verbose),name) +function nodes.serializebox(n,flat,verbose,noattributes,name) + return serialize(totable(tex.box[n],flat,verbose,noattributes),name) end -function nodes.visualizebox(...) -- to be checked .. will move to module anyway - context.starttyping() - context.pushcatcodes("verbatim") - context(nodes.serializebox(...)) - context.stoptyping() - context.popcatcodes() +function nodes.visualizebox(n,flat,verbose,noattributes,name) + context.tocontext(totable(tex.box[n],flat,verbose,noattributes),name) end function nodes.list(head,n) -- name might change to nodes.type -- to be checked .. will move to module anyway diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf index 75daa0532..88085d831 100644 Binary files a/tex/context/base/mkiv/status-files.pdf and b/tex/context/base/mkiv/status-files.pdf differ diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf index 0bc38badd..a5db281ed 100644 Binary files a/tex/context/base/mkiv/status-lua.pdf and b/tex/context/base/mkiv/status-lua.pdf differ diff --git a/tex/context/base/mkiv/strc-mat.mkiv b/tex/context/base/mkiv/strc-mat.mkiv index 54bf7d225..d4f1c3d91 100644 --- a/tex/context/base/mkiv/strc-mat.mkiv +++ b/tex/context/base/mkiv/strc-mat.mkiv @@ -978,10 +978,14 @@ {\hbox to \displaywidth \bgroup \hsize\displaywidth \hss - \Ustartmath} + %\Ustartmath + \dostarttagged\t!formulacontent\empty + \csname\e!start\formulaparameter\c!alternative\v!formula\endcsname} \unexpanded\def\strc_formulas_nested_formula_stop - {\Ustopmath + {\csname\e!stop\formulaparameter\c!alternative\v!formula\endcsname + \dostoptagged + %\Ustopmath \hss \egroup \hss} diff --git a/tex/context/base/mkiv/tabl-tbl.mkiv b/tex/context/base/mkiv/tabl-tbl.mkiv index 426e83d1d..9e3f00ccc 100644 --- a/tex/context/base/mkiv/tabl-tbl.mkiv +++ b/tex/context/base/mkiv/tabl-tbl.mkiv @@ -2098,6 +2098,14 @@ \let\v_tabl_tabulate_align\!!zerocount +\def\tabl_tabulate_check_side_float % new per 29-07-2016 + {\ifdefined\page_sides_check_floats_indeed + \page_sides_check_floats_indeed + \ifdim\hangindent>\zeropoint + \advance\d_tabl_tabulate_indent\hangindent + \fi + \fi} + \def\tabl_tabulate_set_local_hsize {\setlocalhsize \hsize\localhsize} @@ -2185,6 +2193,7 @@ \ifinsidefloat \d_tabl_tabulate_indent\zeropoint \else + \tabl_tabulate_check_side_float \tabl_tabulate_set_local_hsize \fi \dontcomplain diff --git a/tex/context/base/mkiv/toks-tra.mkiv b/tex/context/base/mkiv/toks-tra.mkiv index a3e27eaf8..6186402a7 100644 --- a/tex/context/base/mkiv/toks-tra.mkiv +++ b/tex/context/base/mkiv/toks-tra.mkiv @@ -22,10 +22,13 @@ \unexpanded\def\starttokens [#1]{\ctxcommand{collecttokens("#1","stoptokens")}} \let\stoptokens \relax - \def\flushtokens [#1]{\ctxcommand{flushtokens("#1")}} - \def\showtokens [#1]{\ctxcommand{showtokens("#1")}} - \def\testtokens [#1]{\ctxcommand{testtokens("#1")}} - \def\registertoken #1{\ctxcommand{registertoken("#1")}} +\unexpanded\def\flushtokens [#1]{\ctxcommand{flushtokens("#1")}} +\unexpanded\def\showtokens [#1]{\ctxcommand{showtokens("#1")}} +\unexpanded\def\testtokens [#1]{\ctxcommand{testtokens("#1")}} +\unexpanded\def\registertoken #1{\ctxcommand{registertoken("#1")}} +\let\toks_show\showtokens % we also support the primitive + +\unexpanded\def\showtokens{\doifelsenextoptional\toks_show\normalshowtokens} \protect \endinput diff --git a/tex/context/fonts/mkiv/type-imp-source.mkiv b/tex/context/fonts/mkiv/type-imp-source.mkiv new file mode 100644 index 000000000..b20c6383c --- /dev/null +++ b/tex/context/fonts/mkiv/type-imp-source.mkiv @@ -0,0 +1,66 @@ +%D \module +%D [ file=type-imp-source, +%D version=2010.06.21, +%D title=\CONTEXT\ Typescript Macros, +%D subtitle=Adobe Source Fonts (https://fonts.google.com/), +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\starttypescriptcollection[source] + + \definefontfeature[source-serif-slanted][slant=0.2] + + \starttypescript [\s!serif] [source] [\s!name] + \setups[\s!font:\s!fallback:\s!serif] + \definefontsynonym [\s!Serif] [\s!file:SourceSerifPro-Regular.ttf] [\s!features=\s!default] + \definefontsynonym [\s!SerifBold] [\s!file:SourceSerifPro-Bold.ttf] [\s!features=\s!default] + % \definefontsynonym [\s!SerifBold] [\s!file:SourceSerifPro-Semibold.ttf] [\s!features=\s!default] + \definefontsynonym [\s!SerifItalic] [\s!file:SourceSerifPro-Regular.ttf] [\s!features={\s!default,source-serif-slanted}] + \definefontsynonym [\s!SerifBoldItalic] [\s!file:SourceSerifPro-Bold.ttf] [\s!features={\s!default,source-serif-slanted}] + \stoptypescript + + \starttypescript [\s!sans] [source] [\s!name] + \setups[\s!font:\s!fallback:\s!sans] + % \definefontsynonym [\s!Sans] [\s!file:SourceSansPro-ExtraLight.ttf] [\s!features=\s!default] + % \definefontsynonym [\s!Sans] [\s!file:SourceSansPro-Light.ttf] [\s!features=\s!default] + \definefontsynonym [\s!Sans] [\s!file:SourceSansPro-Regular.ttf] [\s!features=\s!default] + % \definefontsynonym [\s!SansBold] [\s!file:SourceSansPro-Semibold.ttf] [\s!features=\s!default] + \definefontsynonym [\s!SansBold] [\s!file:SourceSansPro-Bold.ttf] [\s!features=\s!default] + % \definefontsynonym [\s!SansBold] [\s!file:SourceSansPro-Black.ttf] [\s!features=\s!default] + % \definefontsynonym [\s!SansItalic] [\s!file:SourceSansPro-ExtraLightItalic.ttf] [\s!features=\s!default] + % \definefontsynonym [\s!SansItalic] [\s!file:SourceSansPro-LightItalic.ttf] [\s!features=\s!default] + \definefontsynonym [\s!SansItalic] [\s!file:SourceSansPro-Italic.ttf] [\s!features=\s!default] + % \definefontsynonym [\s!SansBoldItalic] [\s!file:SourceSansPro-SemiboldItalic.ttf] [\s!features=\s!default] + \definefontsynonym [\s!SansBoldItalic] [\s!file:SourceSansPro-BoldItalic.ttf] [\s!features=\s!default] + % \definefontsynonym [\s!SansBoldItalic] [\s!file:SourceSansPro-BlackItalic.ttf] [\s!features=\s!default] + \stoptypescript + + \starttypescript [\s!mono] [source] [\s!name] + \setups[\s!font:\s!fallback:\s!mono] + % \definefontsynonym [\s!Mono] [\s!file:SourceCodePro-ExtraLight.ttf] [\s!features=\s!none] + % \definefontsynonym [\s!Mono] [\s!file:SourceCodePro-Light.ttf] [\s!features=\s!none] + \definefontsynonym [\s!Mono] [\s!file:SourceCodePro-Regular.ttf] [\s!features=\s!none] + % \definefontsynonym [\s!MonoBold] [\s!file:SourceCodePro-Medium.ttf] [\s!features=\s!none] + % \definefontsynonym [\s!MonoBold] [\s!file:SourceCodePro-Semibold.ttf] [\s!features=\s!none] + \definefontsynonym [\s!MonoBold] [\s!file:SourceCodePro-Bold.ttf] [\s!features=\s!none] + % \definefontsynonym [\s!MonoBold] [\s!file:SourceCodePro-Black.ttf] [\s!features=\s!none] + \stoptypescript + + \starttypescript [\s!math][source][\s!name] + % \loadfontgoodies[texgyre] + \definefontsynonym[\s!MathRoman][file:texgyredejavu-math][\s!features=\s!math\mathsizesuffix,\s!goodies=dejavu-math] + \stoptypescript + + \starttypescript[source] + \definetypeface [source] [\s!rm] [\s!serif] [source] [\s!default] + \definetypeface [source] [\s!ss] [\s!sans] [source] [\s!default] + \definetypeface [source] [\s!tt] [\s!mono] [source] [\s!default] + \definetypeface [source] [\s!mm] [\s!math] [source] [\s!default] % [\s!rscale=1.2] + \stoptypescript + +\stoptypescriptcollection diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf index f91ddb031..73add297a 100644 Binary files a/tex/context/interface/mkiv/i-context.pdf and b/tex/context/interface/mkiv/i-context.pdf differ diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf index 9679f4b7c..a3c7158cb 100644 Binary files a/tex/context/interface/mkiv/i-readme.pdf and b/tex/context/interface/mkiv/i-readme.pdf differ diff --git a/tex/context/modules/mkiv/m-punk.mkiv b/tex/context/modules/mkiv/m-punk.mkiv index 331e90d2e..f7e17da83 100644 --- a/tex/context/modules/mkiv/m-punk.mkiv +++ b/tex/context/modules/mkiv/m-punk.mkiv @@ -11,11 +11,6 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\ifx\luaversion\undefined \endinput \fi - -% At some point the font generation code will move into the -% ConTeXt MkIV kernel. - \startluacode local concat = table.concat local chardata = characters.data @@ -242,7 +237,7 @@ end) \definetypeface [punk] [rm] [serif] [punk] [default] \stoptypescript -\endinput +\continueifinputfile{m-punk.mkiv} \usetypescript[punk] diff --git a/tex/context/modules/mkiv/s-math-characters.lua b/tex/context/modules/mkiv/s-math-characters.lua index 8ff3a8660..757e843da 100644 --- a/tex/context/modules/mkiv/s-math-characters.lua +++ b/tex/context/modules/mkiv/s-math-characters.lua @@ -53,8 +53,14 @@ function moduledata.math.characters.showlist(specification) local sorted = { } if type(list) == "string" then sorted = utilities.parsers.settings_to_array(list) + for i=1,#sorted do + sorted[i] = tonumber(sorted[i]) + end elseif type(list) == "table" then sorted = list + for i=1,#sorted do + sorted[i] = tonumber(sorted[i]) + end elseif fillinthegaps then sorted = table.keys(characters) for k, v in next, gaps do diff --git a/tex/context/modules/mkiv/s-math-characters.mkiv b/tex/context/modules/mkiv/s-math-characters.mkiv index 3b273cb6c..a35429538 100644 --- a/tex/context/modules/mkiv/s-math-characters.mkiv +++ b/tex/context/modules/mkiv/s-math-characters.mkiv @@ -56,8 +56,8 @@ \directsetup{s-math-characters:reset} - \unexpanded\def\showmathcharactersstartentry {\blank\begingroup\raggedright} - \unexpanded\def\showmathcharactersstopentry {\endgroup\blank} + \unexpanded\def\showmathcharactersstartentry {\blank\startpacked\raggedright} + \unexpanded\def\showmathcharactersstopentry {\stoppacked\blank} \def\showmathcharactersentryhexdectit##1##2##3% {##1:\space{\char##2}\space\ruledhbox{\char##2}\space##3\par diff --git a/tex/context/modules/mkiv/s-math-extensibles.mkiv b/tex/context/modules/mkiv/s-math-extensibles.mkiv index f9ff8547a..cc6fd1b00 100644 --- a/tex/context/modules/mkiv/s-math-extensibles.mkiv +++ b/tex/context/modules/mkiv/s-math-extensibles.mkiv @@ -48,9 +48,9 @@ \def\modulemathextensiblesalternativea#1#2#3% {\NC U+#1 \NC \filledhboxm{\math{\char"#1}} - \NC \hbox{\math{\mathextensible[demo]{"#1}{top}{bottom}}} - \NC \hbox{\math{\mathextensible[demo]{"#1}{}{bottom}}} - \NC \hbox{\math{\mathextensible[demo]{"#1}{top}{}}} + \NC \hbox{\math{\mathstacker[demo]{"#1}{top}{bottom}}} + \NC \hbox{\math{\mathstacker[demo]{"#1}{}{bottom}}} + \NC \hbox{\math{\mathstacker[demo]{"#1}{top}{}}} \NC \nohyphens \veryraggedright #2 \NC\NR} diff --git a/tex/context/modules/mkiv/x-asciimath.mkiv b/tex/context/modules/mkiv/x-asciimath.mkiv index d3a629c81..5c96d4f8a 100644 --- a/tex/context/modules/mkiv/x-asciimath.mkiv +++ b/tex/context/modules/mkiv/x-asciimath.mkiv @@ -299,7 +299,7 @@ %D This will become an extra. -\showframe +\starttext \setups[asciimath:layout] @@ -312,10 +312,12 @@ % % \ShowAsciiMathSave[e:/temporary/asciimath/asciimath.lua] % \stoptext -\starttext -\unexpanded\def\MyAsciiMath#1{\startformula\asciimath{#1}\stopformula} -\startlines -\MyAsciiMath{x^2 / 10 // z_12^34 / 20} +\subject{Some tests} + +% \unexpanded\def\MyAsciiMath#1{\startformula\asciimath{#1}\stopformula} +% +% \startlines +% \MyAsciiMath{x^2 / 10 // z_12^34 / 20} % \MyAsciiMath{{:{:x^2:} / 10:} // {:{:z_12^34 :} / 20:}} % \MyAsciiMath{x^2+y_1+z_12^34} % \MyAsciiMath{sin^-1(x)} @@ -399,38 +401,82 @@ % \MyAsciiMath{x^ (-1 1/2) =1/x^ (1 1/2)=1/ (x^1*x^ (1/2)) =1/ (xsqrt(x))} % \MyAsciiMath{x^2(10 -x)>2 x^2} % \MyAsciiMath{x^4>x} -\stoplines - -\setupasciimath[splitmethod=3,symbol={{,}}] - -\startlines -\asciimath{sqrt 1} -\asciimath{sqrt 1.2} -\asciimath{sqrt 1.2} -\asciimath{1} -\asciimath{12} -\asciimath{123} -\asciimath{1234} -\asciimath{12345} -\asciimath{123456} -\asciimath{1234567} -\asciimath{12345678} -\asciimath{123456789} -\asciimath{1.1} -\asciimath{12.12} -\asciimath{1234.123} -\asciimath{1234.1234} -\asciimath{12345.1234} -\asciimath{1234.12345} -\asciimath{12345.12345} -\asciimath{123456.123456} -\asciimath{1234567.1234567} -\asciimath{12345678.12345678} -\asciimath{123456789.123456789} -\asciimath{0.1234} -\asciimath{1234.0} -\asciimath{1234.00} -\asciimath{0.123456789} -\stoplines +% \stoplines + +% \setupasciimath[splitmethod=3,symbol={{,}}] +% +% \startlines +% \asciimath{sqrt 1} +% \asciimath{sqrt 1.2} +% \asciimath{sqrt 1.2} +% \asciimath{1} +% \asciimath{12} +% \asciimath{123} +% \asciimath{1234} +% \asciimath{12345} +% \asciimath{123456} +% \asciimath{1234567} +% \asciimath{12345678} +% \asciimath{123456789} +% \asciimath{1.1} +% \asciimath{12.12} +% \asciimath{1234.123} +% \asciimath{1234.1234} +% \asciimath{12345.1234} +% \asciimath{1234.12345} +% \asciimath{12345.12345} +% \asciimath{123456.123456} +% \asciimath{1234567.1234567} +% \asciimath{12345678.12345678} +% \asciimath{123456789.123456789} +% \asciimath{0.1234} +% \asciimath{1234.0} +% \asciimath{1234.00} +% \asciimath{0.123456789} +% \stoplines + +% \definemixedcolumns[asciimath][n=3,balance=yes] +% +% \startluacode +% local asciimath = moduledata.asciimath +% local variables = { "w", "x", "y", "z", "p", "q", "r" } +% local constants = { "a", "b", "c" } +% local functions = { "g", "h", "i" } +% local iterators = { "i", "j", "k" } +% local vectors = { "A", "B", "C", "D", "E", "P", "Q", "R" } +% local reserved = { } +% local reserved = { +% -- "vdots","ddots","oint", +% "grad", "prod", "prop", "sube", "supe", "sum", +% "vvv", "nnn", "uuu", "sub", "sup", +% "iff", "int", "del", +% "sinh", "cosh", "tanh", "sin", "cos", "tan", "csc", "sec", "cot", +% "atan", "asin", "acos", "arctan", "arcsin", "arccos", +% "log", "ln", "det", "lim", "mod", "gcd", -- "lcm", +% "min", "max", +% "xx", "in", "ox", "vv", "nn", "uu", "oo", "bb", +% "not", "and", "or", "if", +% "AA", "EE", "TT", +% "sqrt", "root", "frac", "stackrel", +% "hat", "overbar", "underline", "vec", +% "dx", "dy", "dz", +% } +% for c=1,#constants do +% for r=1,#reserved do +% context.startmixedcolumns { "asciimath" } +% for v1=1,#variables do +% for v2=1,#variables do +% local str = constants[c] .. variables[v1] .. reserved[r] .. variables[v2] +% context.type(str) +% context.quad() +% commands.asciimath(str) +% context.par() +% end +% end +% context.stopmixedcolumns() +% context.blank() +% end +% end +% \stopluacode \stoptext diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 13c45aa2a..4cefe9a5e 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 : c:/data/develop/context/sources/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date : 07/25/16 21:49:08 +-- merge date : 07/30/16 00:26:47 do -- begin closure to overcome local limits and interference @@ -5722,6 +5722,7 @@ local next,tostring,rawget=next,tostring,rawget local format,match,lower,gsub,find=string.format,string.match,string.lower,string.gsub,string.find local sort,insert,concat,sortedkeys,serialize,fastcopy=table.sort,table.insert,table.concat,table.sortedkeys,table.serialize,table.fastcopy local derivetable=table.derive +local ioflush=io.flush local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) local trace_scaling=false trackers.register("fonts.scaling",function(v) trace_scaling=v end) local report_defining=logs.reporter("fonts","defining") @@ -6547,134 +6548,233 @@ setmetatableindex(formats,function(t,k) end return rawget(t,file.suffix(l)) end) -local locations={} -local function setindeed(mode,target,group,name,action,position) - local t=target[mode] - if not t then - report_defining("fatal error in setting feature %a, group %a, mode %a",name,group,mode) - os.exit() - elseif position then - insert(t,position,{ name=name,action=action }) - else - for i=1,#t do - local ti=t[i] - if ti.name==name then - ti.action=action - return +do + local function setindeed(mode,target,group,name,action,position) + local t=target[mode] + if not t then + report_defining("fatal error in setting feature %a, group %a, mode %a",name,group,mode) + os.exit() + elseif position then + insert(t,position,{ name=name,action=action }) + else + for i=1,#t do + local ti=t[i] + if ti.name==name then + ti.action=action + return + end end + insert(t,{ name=name,action=action }) end - insert(t,{ name=name,action=action }) end -end -local function set(group,name,target,source) - target=target[group] - if not target then - report_defining("fatal target error in setting feature %a, group %a",name,group) - os.exit() - end - local source=source[group] - if not source then - report_defining("fatal source error in setting feature %a, group %a",name,group) - os.exit() - end - local node=source.node - local base=source.base - local position=source.position - if node then - setindeed("node",target,group,name,node,position) - end - if base then - setindeed("base",target,group,name,base,position) - end -end -local function register(where,specification) - local name=specification.name - if name and name~="" then - local default=specification.default - local description=specification.description - local initializers=specification.initializers - local processors=specification.processors - local manipulators=specification.manipulators - local modechecker=specification.modechecker - if default then - where.defaults[name]=default + local function set(group,name,target,source) + target=target[group] + if not target then + report_defining("fatal target error in setting feature %a, group %a",name,group) + os.exit() end - if description and description~="" then - where.descriptions[name]=description + local source=source[group] + if not source then + report_defining("fatal source error in setting feature %a, group %a",name,group) + os.exit() end - if initializers then - set('initializers',name,where,specification) + local node=source.node + local base=source.base + local position=source.position + if node then + setindeed("node",target,group,name,node,position) end - if processors then - set('processors',name,where,specification) - end - if manipulators then - set('manipulators',name,where,specification) + if base then + setindeed("base",target,group,name,base,position) end - if modechecker then - where.modechecker=modechecker + end + local function register(where,specification) + local name=specification.name + if name and name~="" then + local default=specification.default + local description=specification.description + local initializers=specification.initializers + local processors=specification.processors + local manipulators=specification.manipulators + local modechecker=specification.modechecker + if default then + where.defaults[name]=default + end + if description and description~="" then + where.descriptions[name]=description + end + if initializers then + set('initializers',name,where,specification) + end + if processors then + set('processors',name,where,specification) + end + if manipulators then + set('manipulators',name,where,specification) + end + if modechecker then + where.modechecker=modechecker + end end end -end -constructors.registerfeature=register -function constructors.getfeatureaction(what,where,mode,name) - what=handlers[what].features - if what then - where=what[where] - if where then - mode=where[mode] - if mode then - for i=1,#mode do - local m=mode[i] - if m.name==name then - return m.action + constructors.registerfeature=register + function constructors.getfeatureaction(what,where,mode,name) + what=handlers[what].features + if what then + where=what[where] + if where then + mode=where[mode] + if mode then + for i=1,#mode do + local m=mode[i] + if m.name==name then + return m.action + end end end end end end -end -local newhandler={} -constructors.handlers=newhandler -constructors.newhandler=newhandler -local function setnewhandler(what) - local handler=handlers[what] - if not handler then - handler={} - handlers[what]=handler + local newfeatures={} + constructors.newfeatures=newfeatures + constructors.features=newfeatures + local function setnewfeatures(what) + local handler=handlers[what] + local features=handler.features + if not features then + local tables=handler.tables + local statistics=handler.statistics + features=allocate { + defaults={}, + descriptions=tables and tables.features or {}, + used=statistics and statistics.usedfeatures or {}, + initializers={ base={},node={} }, + processors={ base={},node={} }, + manipulators={ base={},node={} }, + } + features.register=function(specification) return register(features,specification) end + handler.features=features + end + return features end - return handler + setmetatable(newfeatures,{ + __call=function(t,k) local v=t[k] return v end, + __index=function(t,k) local v=setnewfeatures(k) t[k]=v return v end, + }) end -setmetatable(newhandler,{ - __call=function(t,k) local v=t[k] return v end, - __index=function(t,k) local v=setnewhandler(k) t[k]=v return v end, -}) -local newfeatures={} -constructors.newfeatures=newfeatures -constructors.features=newfeatures -local function setnewfeatures(what) - local handler=handlers[what] - local features=handler.features - if not features then - local tables=handler.tables - local statistics=handler.statistics - features=allocate { - defaults={}, - descriptions=tables and tables.features or {}, - used=statistics and statistics.usedfeatures or {}, - initializers={ base={},node={} }, - processors={ base={},node={} }, - manipulators={ base={},node={} }, - } - features.register=function(specification) return register(features,specification) end - handler.features=features +do + local newhandler={} + constructors.handlers=newhandler + constructors.newhandler=newhandler + local function setnewhandler(what) + local handler=handlers[what] + if not handler then + handler={} + handlers[what]=handler + end + return handler + end + setmetatable(newhandler,{ + __call=function(t,k) local v=t[k] return v end, + __index=function(t,k) local v=setnewhandler(k) t[k]=v return v end, + }) +end +do + local newenhancer={} + constructors.enhancers=newenhancer + constructors.newenhancer=newenhancer + local function setnewenhancer(format) + local handler=handlers[format] + local enhancers=handler.enhancers + if not enhancers then + local actions=allocate() + local before=allocate() + local after=allocate() + local order=allocate() + local patches={ before=before,after=after } + local trace=false + local report=logs.reporter("fonts",format.." enhancing") + trackers.register(format..".loading",function(v) trace=v end) + local function enhance(name,data,filename,raw) + local enhancer=actions[name] + if enhancer then + if trace then + report("apply enhancement %a to file %a",name,filename) + ioflush() + end + enhancer(data,filename,raw) + else + end + end + local function apply(data,filename,raw) + local basename=file.basename(lower(filename)) + if trace then + report("%s enhancing file %a","start",filename) + end + ioflush() + for e=1,#order do + local enhancer=order[e] + local b=before[enhancer] + if b then + for pattern,action in next,b do + if find(basename,pattern) then + action(data,filename,raw) + end + end + end + enhance(enhancer,data,filename,raw) + local a=after[enhancer] + if a then + for pattern,action in next,a do + if find(basename,pattern) then + action(data,filename,raw) + end + end + end + ioflush() + end + if trace then + report("%s enhancing file %a","stop",filename) + end + ioflush() + end + local function register(what,action) + if action then + if actions[what] then + else + order[#order+1]=what + end + actions[what]=action + else + report("bad enhancer %a",what) + end + end + local function patch(what,where,pattern,action) + local pw=patches[what] + if pw then + local ww=pw[where] + if ww then + ww[pattern]=action + else + pw[where]={ [pattern]=action} + end + end + end + enhancers={ + register=register, + apply=apply, + patch=patch, + patches={ register=patch }, + } + handler.enhancers=enhancers + end + return enhancers end - return features + setmetatable(newenhancer,{ + __call=function(t,k) local v=t[k] return v end, + __index=function(t,k) local v=setnewenhancer(k) t[k]=v return v end, + }) end -setmetatable(newfeatures,{ - __call=function(t,k) local v=t[k] return v end, - __index=function(t,k) local v=setnewfeatures(k) t[k]=v return v end, -}) function constructors.checkedfeatures(what,features) local defaults=handlers[what].features.defaults if features and next(features) then @@ -15228,7 +15328,6 @@ if not modules then modules={} end modules ['font-otl']={ local gmatch,find,match,lower,strip=string.gmatch,string.find,string.match,string.lower,string.strip local type,next,tonumber,tostring,unpack=type,next,tonumber,tostring,unpack local abs=math.abs -local ioflush=io.flush local derivetable=table.derive local formatters=string.formatters local setmetatableindex=table.setmetatableindex @@ -15257,10 +15356,8 @@ local readers=fonts.readers local constructors=fonts.constructors local otffeatures=constructors.features.otf local registerotffeature=otffeatures.register -local enhancers=allocate() -otf.enhancers=enhancers -local patches={} -enhancers.patches=patches +local otfenhancers=constructors.enhancers.otf +local registerotfenhancer=otfenhancers.register local forceload=false local cleanup=0 local syncspace=true @@ -15276,76 +15373,7 @@ registerdirective("fonts.otf.loader.cleanup",function(v) cleanup=tonumber(v) or registerdirective("fonts.otf.loader.force",function(v) forceload=v end) registerdirective("fonts.otf.loader.syncspace",function(v) syncspace=v end) registerdirective("fonts.otf.loader.forcenotdef",function(v) forcenotdef=v end) -local ordered_enhancers={ - "check extra features", -} -local actions=allocate() -local before=allocate() -local after=allocate() -patches.before=before -patches.after=after -local function enhance(name,data,filename,raw) - local enhancer=actions[name] - if enhancer then - if trace_loading then - report_otf("apply enhancement %a to file %a",name,filename) - ioflush() - end - enhancer(data,filename,raw) - else - end -end -function enhancers.apply(data,filename,raw) - local basename=file.basename(lower(filename)) - if trace_loading then - report_otf("%s enhancing file %a","start",filename) - end - ioflush() - for e=1,#ordered_enhancers do - local enhancer=ordered_enhancers[e] - local b=before[enhancer] - if b then - for pattern,action in next,b do - if find(basename,pattern) then - action(data,filename,raw) - end - end - end - enhance(enhancer,data,filename,raw) - local a=after[enhancer] - if a then - for pattern,action in next,a do - if find(basename,pattern) then - action(data,filename,raw) - end - end - end - ioflush() - end - if trace_loading then - report_otf("%s enhancing file %a","stop",filename) - end - ioflush() -end -function patches.register(what,where,pattern,action) - local pw=patches[what] - if pw then - local ww=pw[where] - if ww then - ww[pattern]=action - else - pw[where]={ [pattern]=action} - end - end -end -function patches.report(fmt,...) - if trace_loading then - report_otf("patching: %s",formatters[fmt](...)) - end -end -function enhancers.register(what,action) - actions[what]=action -end +registerotfenhancer("check extra features",function() end) function otf.load(filename,sub,featurefile) local featurefile=nil local base=file.basename(file.removesuffix(filename)) @@ -15445,7 +15473,7 @@ function otf.load(filename,sub,featurefile) otfreaders.unpack(data) otfreaders.expand(data) otfreaders.addunicodetable(data) - enhancers.apply(data,filename,data) + otfenhancers.apply(data,filename,data) if applyruntimefixes then applyruntimefixes(filename,data) end @@ -18165,6 +18193,12 @@ local getthreshold=injections.getthreshold local checkstep=(nodes and nodes.tracers and nodes.tracers.steppers.check) or function() end local registerstep=(nodes and nodes.tracers and nodes.tracers.steppers.register) or function() end local registermessage=(nodes and nodes.tracers and nodes.tracers.steppers.message) or function() end +local function checkdisccontent(d) + local pre,post,replace=getdisc(d) + if pre then for n in traverse_id(glue_code,pre) do print("pre",nodes.idstostring(pre)) break end end + if post then for n in traverse_id(glue_code,post) do print("pos",nodes.idstostring(post)) break end end + if replace then for n in traverse_id(glue_code,replace) do print("rep",nodes.idstostring(replace)) break end end +end local function logprocess(...) if trace_steps then registermessage(...) @@ -18225,7 +18259,7 @@ end local function copy_glyph(g) local components=getfield(g,"components") if components then - setfield(g,"components",nil) + setfield(g,"components") local n=copy_node(g) copyinjection(n,g) setfield(g,"components",components) @@ -18237,11 +18271,18 @@ local function copy_glyph(g) end end local function flattendisk(head,disc) - local _,_,replace,_,_,replacetail=getdisc(disc,true) - setfield(disc,"replace",nil) + local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) + local prev,next=getboth(disc) + local ishead=head==disc + setdisc(disc) flush_node(disc) - if head==disc then - local next=getnext(disc) + if pre then + flush_node_list(pre) + end + if post then + flush_node_list(post) + end + if ishead then if replace then if next then setlink(replacetail,next) @@ -18253,7 +18294,6 @@ local function flattendisk(head,disc) return end else - local prev,next=getboth(disc) if replace then if next then setlink(replacetail,next) @@ -18288,8 +18328,8 @@ local function markstoligature(head,start,stop,char) else local prev=getprev(start) local next=getnext(stop) - setprev(start,nil) - setnext(stop,nil) + setprev(start) + setnext(stop) local base=copy_glyph(start) if head==start then head=base @@ -18336,8 +18376,8 @@ local function toligature(head,start,stop,char,dataset,sequence,markflag,discfou local prev=getprev(start) local next=getnext(stop) local comp=start - setprev(start,nil) - setnext(stop,nil) + setprev(start) + setnext(stop) local base=copy_glyph(start) if start==head then head=base @@ -18401,36 +18441,36 @@ local function toligature(head,start,stop,char,dataset,sequence,markflag,discfou local pre,post,replace,pretail,posttail,replacetail=getdisc(discfound,true) if not replace then local prev=getprev(base) -local current=comp -local previous=nil -local copied=nil -while current do - if getid(current)==glyph_code then - local n=copy_node(current) - if copied then - setlink(previous,n) - else - copied=n - end - previous=n - end - current=getnext(current) -end - setprev(discnext,nil) - setnext(discprev,nil) + local current=comp + local previous=nil + local copied=nil + while current do + if getid(current)==glyph_code then + local n=copy_node(current) + if copied then + setlink(previous,n) + else + copied=n + end + previous=n + end + current=getnext(current) + end + setprev(discnext) + setnext(discprev) if pre then setlink(discprev,pre) end pre=comp if post then setlink(posttail,discnext) - setprev(post,nil) + setprev(post) else post=discnext end setlink(prev,discfound) setlink(discfound,next) - setboth(base,nil,nil) + setboth(base) setfield(base,"components",copied) setdisc(discfound,pre,post,base,discretionary_code) base=prev @@ -19434,6 +19474,39 @@ end local function show_skip(dataset,sequence,char,ck,class) logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a",cref(dataset,sequence),gref(char),class,ck[1],ck[8] or ck[2]) end +local new_kern=nuts.pool.kern +local function checked(head) + local current=head + while current do + if getid(current)==glue_code then + local kern=new_kern(getfield(current,"width")) + if head==current then + local next=getnext(current) + if next then + setlink(kern,next) + end + flush_node(current) + head=kern + current=next + else + local prev,next=getboth(current) + setlink(prev,kern) + setlink(kern,next) + flush_node(current) + current=next + end + else + current=getnext(current) + end + end + return head +end +local function setdiscchecked(d,pre,post,replace) + if pre then pre=checked(pre) end + if post then post=checked(post) end + if replace then replace=checked(replace) end + setdisc(d,pre,post,replace) +end local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,ck,chainproc) if not start then return head,start,false @@ -19454,6 +19527,7 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c local current=start local last=start local prev=getprev(start) + local hasglue=false local i=f while i<=l do local id=getid(current) @@ -19461,6 +19535,11 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c i=i+1 last=current current=getnext(current) + elseif id==glue_code then + i=i+1 + last=current + current=getnext(current) + hasglue=true elseif id==disc_code then if keepdisc then keepdisc=false @@ -19510,8 +19589,8 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c tail=find_node_tail(head) end setnext(sweepnode,current) - setprev(head,nil) - setnext(tail,nil) + setprev(head) + setnext(tail) appenddisc(sweepnode,head) end end @@ -19523,6 +19602,10 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c if id==glyph_code then i=i+1 current=getnext(current) + elseif id==glue_code then + i=i+1 + current=getnext(current) + hasglue=true elseif id==disc_code then if keepdisc then keepdisc=false @@ -19564,6 +19647,9 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c local id=getid(current) if id==glyph_code then i=i-1 + elseif id==glue_code then + i=i-1 + hasglue=true elseif id==disc_code then if keepdisc then keepdisc=false @@ -19608,8 +19694,8 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c if cprev then setnext(cprev,lookaheaddisc) end - setprev(cf,nil) - setnext(cl,nil) + setprev(cf) + setnext(cl) if startishead then head=lookaheaddisc end @@ -19636,7 +19722,11 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c local tail=find_node_tail(new) setlink(tail,replace) end - setdisc(lookaheaddisc,cf,post,new) + if hasglue then + setdiscchecked(lookaheaddisc,cf,post,new) + else + setdisc(lookaheaddisc,cf,post,new) + end start=getprev(lookaheaddisc) sweephead[cf]=getnext(clast) sweephead[new]=getnext(last) @@ -19659,8 +19749,8 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c setprev(cnext,backtrackdisc) end setnext(backtrackdisc,cnext) - setprev(cf,nil) - setnext(cl,nil) + setprev(cf) + setnext(cl) local pre,post,replace,pretail,posttail,replacetail=getdisc(backtrackdisc,true) local new=copy_node_list(cf) local cnew=find_node_tail(new) @@ -19687,7 +19777,11 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c else replace=new end - setdisc(backtrackdisc,pre,post,replace) + if hasglue then + setdiscchecked(backtrackdisc,pre,post,replace) + else + setdisc(backtrackdisc,pre,post,replace) + end start=getprev(backtrackdisc) sweephead[post]=getnext(clast) sweephead[replace]=getnext(last) @@ -20341,7 +20435,7 @@ local function kernrun(disc,k_run,font,attr,...) if k_run(posttail,"postinjections",next,font,attr,...) then done=true end - setnext(posttail,nil) + setnext(posttail) setprev(next,disc) end end @@ -20363,7 +20457,7 @@ local function kernrun(disc,k_run,font,attr,...) if k_run(replacetail,"replaceinjections",next,font,attr,...) then done=true end - setnext(replacetail,nil) + setnext(replacetail) setprev(next,disc) end elseif prev and next then @@ -20430,7 +20524,7 @@ local function testrun(disc,t_run,c_run,...) setlink(replacetail,next) local ok,overflow=t_run(replace,next,...) if ok and overflow then - setfield(disc,"replace",nil) + setfield(disc,"replace") setlink(prev,replace) setboth(disc) flush_node_list(disc) @@ -23653,37 +23747,15 @@ local otfreaders=otf.readers local otfenhancers=otf.enhancers local afmfeatures=constructors.features.afm local registerafmfeature=afmfeatures.register +local afmenhancers=constructors.enhancers.afm +local registerafmenhancer=afmenhancers.register afm.version=1.512 -afm.cache=containers.define("fonts","afm",afm.version,true) +afm.cache=containers.define("fonts","one",afm.version,true) afm.autoprefixed=true afm.helpdata={} afm.syncspace=true local overloads=fonts.mappings.overloads local applyruntimefixes=fonts.treatments and fonts.treatments.applyfixes -local enhancers={ -} -local steps={ - "unify names", - "add ligatures", - "add extra kerns", - "normalize features", - "check extra features", - "fix names", -} -local function applyenhancers(data,filename) - for i=1,#steps do - local step=steps[i] - local enhancer=enhancers[step] - if enhancer then - if trace_loading then - report_afm("applying enhancer %a",step) - end - enhancer(data,filename) - else - report_afm("invalid enhancer %a",step) - end - end -end function afm.load(filename) filename=resolvers.findfile(filename,'afm') or "" if filename~="" and not fonts.names.ignoredfile(filename) then @@ -23706,7 +23778,7 @@ function afm.load(filename) report_afm("reading %a",filename) data=afm.readers.loadfont(filename,pfbname) if data then - applyenhancers(data,filename) + afmenhancers.apply(data,filename) fonts.mappings.addtounicode(data,filename) otfreaders.pack(data) data.size=size @@ -23731,7 +23803,7 @@ function afm.load(filename) end end local uparser=fonts.mappings.makenameparser() -enhancers["unify names"]=function(data,filename) +local function enhance_unify_names(data,filename) local unicodevector=fonts.encodings.agl.unicodes local unicodes={} local names={} @@ -23783,7 +23855,7 @@ enhancers["unify names"]=function(data,filename) end local everywhere={ ["*"]={ ["*"]=true } } local noflags={ false,false,false,false } -enhancers["normalize features"]=function(data) +local function enhance_normalize_features(data) local ligatures=setmetatableindex("table") local kerns=setmetatableindex("table") local extrakerns=setmetatableindex("table") @@ -23881,8 +23953,7 @@ enhancers["normalize features"]=function(data) data.resources.features=features data.resources.sequences=sequences end -enhancers["check extra features"]=otf.enhancers.enhance -enhancers["fix names"]=function(data) +local function enhance_fix_names(data) for k,v in next,data.descriptions do local n=v.name local r=overloads[n] @@ -23921,10 +23992,10 @@ local addthem=function(rawdata,ligatures) end end end -enhancers["add ligatures"]=function(rawdata) +local function enhance_add_ligatures(rawdata) addthem(rawdata,afm.helpdata.ligatures) end -enhancers["add extra kerns"]=function(rawdata) +local function enhance_add_extra_kerns(rawdata) local descriptions=rawdata.descriptions local resources=rawdata.resources local unicodes=resources.unicodes @@ -24332,6 +24403,12 @@ function readers.pfb(specification,method) swap("specification") return readers.afm(specification,method) end +registerafmenhancer("unify names",enhance_unify_names) +registerafmenhancer("add ligatures",enhance_add_ligatures) +registerafmenhancer("add extra kerns",enhance_add_extra_kerns) +registerafmenhancer("normalize features",enhance_normalize_features) +registerafmenhancer("check extra features",otfenhancers.enhance) +registerafmenhancer("fix names",enhance_fix_names) end -- closure @@ -24532,8 +24609,11 @@ tfm.version=1.000 tfm.maxnestingdepth=5 tfm.maxnestingsize=65536*1024 local otf=fonts.handlers.otf +local otfenhancers=otf.enhancers local tfmfeatures=constructors.features.tfm local registertfmfeature=tfmfeatures.register +local tfmenhancers=constructors.enhancers.tfm +local registertfmenhancer=tfmenhancers.register constructors.resolvevirtualtoo=false fonts.formats.tfm="type1" fonts.formats.ofm="type1" @@ -24545,27 +24625,7 @@ function tfm.setfeatures(tfmdata,features) return {} end end -local depth={} -local enhancers={} -local steps={ - "normalize features", - "check extra features" -} -enhancers["check extra features"]=otf.enhancers.enhance -local function applyenhancers(data,filename) - for i=1,#steps do - local step=steps[i] - local enhancer=enhancers[step] - if enhancer then - if trace_loading then - report_tfm("applying enhancer %a",step) - end - enhancer(data,filename) - else - report_tfm("invalid enhancer %a",step) - end - end -end +local depth={} local function read_from_tfm(specification) local filename=specification.filename local size=specification.size @@ -24620,7 +24680,7 @@ local function read_from_tfm(specification) tfmdata.descriptions=tfmdata.characters end otf.readers.addunicodetable(tfmdata) - applyenhancers(tfmdata,filename) + tfmenhancers.apply(tfmdata,filename) constructors.applymanipulators("tfm",tfmdata,features,trace_features,report_tfm) otf.readers.unifymissing(tfmdata) fonts.mappings.addtounicode(tfmdata,filename) @@ -24921,7 +24981,7 @@ end do local everywhere={ ["*"]={ ["*"]=true } } local noflags={ false,false,false,false } - enhancers["normalize features"]=function(data) + local function enhance_normalize_features(data) local ligatures=setmetatableindex("table") local kerns=setmetatableindex("table") local characters=data.characters @@ -25003,6 +25063,8 @@ do data.resources.sequences=sequences data.shared.resources=data.shared.resources or resources end + registertfmenhancer("normalize features",enhance_normalize_features) + registertfmenhancer("check extra features",otfenhancers.enhance) end registertfmfeature { name="mode", -- cgit v1.2.3