From cdb8470a2b74a79863900e7ec3130b72acb7f1ae Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Thu, 27 Aug 2020 20:45:33 +0200 Subject: 2020-08-27 19:27:00 --- tex/context/base/mkii/cont-new.mkii | 2 +- tex/context/base/mkii/context.mkii | 2 +- tex/context/base/mkiv/cont-new.mkiv | 5 +- tex/context/base/mkiv/context.mkiv | 2 +- tex/context/base/mkiv/context.mkxl | 2 +- tex/context/base/mkiv/font-cff.lua | 47 +- tex/context/base/mkiv/font-con.lua | 2 + tex/context/base/mkiv/font-ctx.lua | 9 +- tex/context/base/mkiv/font-def.lua | 2 + tex/context/base/mkiv/node-aux.lmt | 396 ++++++++++++++ tex/context/base/mkiv/node-aux.lua | 9 +- tex/context/base/mkiv/node-ini.lmt | 287 +++++++++++ tex/context/base/mkiv/node-ini.mkiv | 6 +- tex/context/base/mkiv/node-met.lua | 2 +- tex/context/base/mkiv/node-nut.lmt | 572 +++++++++++++++++++++ tex/context/base/mkiv/node-nut.lua | 24 +- tex/context/base/mkiv/node-res.lua | 5 + tex/context/base/mkiv/node-snp.lmt | 4 + tex/context/base/mkiv/status-files.pdf | Bin 28100 -> 28150 bytes tex/context/base/mkiv/status-lua.pdf | Bin 256148 -> 256232 bytes tex/context/base/mkiv/trac-inf.lmt | 26 +- tex/context/base/mkiv/trac-tim.lmt | 1 + tex/generic/context/luatex/luatex-fonts-merged.lua | 54 +- 23 files changed, 1380 insertions(+), 79 deletions(-) create mode 100644 tex/context/base/mkiv/node-aux.lmt create mode 100644 tex/context/base/mkiv/node-ini.lmt create mode 100644 tex/context/base/mkiv/node-nut.lmt (limited to 'tex') diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index 3d592f4ed..20642a907 100644 --- a/tex/context/base/mkii/cont-new.mkii +++ b/tex/context/base/mkii/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2020.08.25 19:56} +\newcontextversion{2020.08.27 19:25} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii index 7c22b1c87..16de426df 100644 --- a/tex/context/base/mkii/context.mkii +++ b/tex/context/base/mkii/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2020.08.25 19:56} +\edef\contextversion{2020.08.27 19:25} %D For those who want to use this: diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index 40c3c3272..fc27b0538 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -13,7 +13,7 @@ % \normalend % uncomment this to get the real base runtime -\newcontextversion{2020.08.25 19:56} +\newcontextversion{2020.08.27 19:25} %D This file is loaded at runtime, thereby providing an excellent place for hacks, %D patches, extensions and new features. There can be local overloads in cont-loc @@ -21,6 +21,9 @@ %D so old that I need to remind myself to check it occasionally, so here is the %D reminder). +% \enabletrackers[pages.timing] +% \enabletrackers[system.usage=summary] + \unprotect \writestatus\m!system{beware: some patches loaded from cont-new.mkiv} diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index 092b16960..5164ea5dd 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -45,7 +45,7 @@ %D {YYYY.MM.DD HH:MM} format. \edef\contextformat {\jobname} -\edef\contextversion{2020.08.25 19:56} +\edef\contextversion{2020.08.27 19:25} %D Kind of special: diff --git a/tex/context/base/mkiv/context.mkxl b/tex/context/base/mkiv/context.mkxl index 5c6ded5c9..e7d0ffdfd 100644 --- a/tex/context/base/mkiv/context.mkxl +++ b/tex/context/base/mkiv/context.mkxl @@ -29,7 +29,7 @@ %D {YYYY.MM.DD HH:MM} format. \edef\contextformat {\jobname} -\edef\contextversion{2020.08.25 19:56} +\edef\contextversion{2020.08.27 19:25} %D Kind of special: diff --git a/tex/context/base/mkiv/font-cff.lua b/tex/context/base/mkiv/font-cff.lua index c2cf0e699..b7d45392d 100644 --- a/tex/context/base/mkiv/font-cff.lua +++ b/tex/context/base/mkiv/font-cff.lua @@ -610,15 +610,15 @@ do + p_unsupported )^1 - parsedictionaries = function(data,dictionaries,what) + parsedictionaries = function(data,dictionaries,version) stack = { } strings = data.strings if trace_charstrings then - report("charstring format %a",what) + report("charstring format %a",version) end for i=1,#dictionaries do top = 0 - result = what == "cff" and { + result = version == "cff" and { monospaced = false, italicangle = 0, underlineposition = -100, @@ -2265,8 +2265,8 @@ do end -local function readglobals(f,data) - local routines = readlengths(f) +local function readglobals(f,data,version) + local routines = readlengths(f,version == "cff2") for i=1,#routines do routines[i] = readbytetable(f,routines[i]) end @@ -2324,14 +2324,14 @@ local function readprivates(f,data) end end -local function readlocals(f,data,dictionary) +local function readlocals(f,data,dictionary,version) local header = data.header local private = dictionary.private if private then local subroutineoffset = private.data.subroutines if subroutineoffset ~= 0 then setposition(f,header.offset+private.offset+subroutineoffset) - local subroutines = readlengths(f) + local subroutines = readlengths(f,version == "cff2") for i=1,#subroutines do subroutines[i] = readbytetable(f,subroutines[i]) end @@ -2348,7 +2348,7 @@ end -- These charstrings are little programs and described in: Technical Note #5177. A truetype -- font has only one dictionary. -local function readcharstrings(f,data,what) +local function readcharstrings(f,data,version) local header = data.header local dictionaries = data.dictionaries local dictionary = dictionaries[1] @@ -2359,7 +2359,7 @@ local function readcharstrings(f,data,what) elseif stringtype == 2 then setposition(f,header.offset+offset) -- could be a metatable .. delayed loading - local charstrings = readlengths(f,what=="cff2") + local charstrings = readlengths(f,version=="cff2") local nofglyphs = #charstrings for i=1,nofglyphs do charstrings[i] = readstring(f,charstrings[i]) @@ -2394,7 +2394,8 @@ readers.parsecharstrings = parsecharstrings -- used in font-onr.lua (type 1) local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams) local dictionaries = data.dictionaries local dictionary = dictionaries[1] - readglobals(f,data) + local cid = not dictionary.private and dictionary.cid + readglobals(f,data,version) readcharstrings(f,data,version) if version == "cff2" then dictionary.charset = nil @@ -2402,9 +2403,27 @@ local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams) readencodings(f,data) readcharsets(f,data,dictionary) end + if cid then + local fdarray = cid.fdarray + if fdarray then + setposition(f,data.header.offset + fdarray) + local dictionaries = readlengths(f,version=="cff2") + local nofdictionaries = #dictionaries + if nofdictionaries > 0 then + for i=1,nofdictionaries do + dictionaries[i] = readstring(f,dictionaries[i]) + end + parsedictionaries(data,dictionaries) + dictionary.private = dictionaries[1].private + if nofdictionaries > 1 then + report("ignoring dictionaries > 1 in cid font") + end + end + end + end readprivates(f,data) parseprivates(data,data.dictionaries) - readlocals(f,data,dictionary) + readlocals(f,data,dictionary,version) startparsing(fontdata,data,streams) parsecharstrings(fontdata,data,glyphs,doshapes,version,streams) stopparsing(fontdata,data) @@ -2416,7 +2435,7 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams) local dictionary = dictionaries[1] local cid = dictionary.cid local cidselect = cid and cid.fdselect - readglobals(f,data) + readglobals(f,data,version) readcharstrings(f,data,version) if version ~= "cff2" then readencodings(f,data) @@ -2462,7 +2481,7 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams) local cidarray = cid.fdarray if cidarray then setposition(f,header.offset+cidarray) - local dictionaries = readlengths(f) + local dictionaries = readlengths(f,version == "cff2") for i=1,#dictionaries do dictionaries[i] = readstring(f,dictionaries[i]) end @@ -2470,7 +2489,7 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams) cid.dictionaries = dictionaries readcidprivates(f,data) for i=1,#dictionaries do - readlocals(f,data,dictionaries[i]) + readlocals(f,data,dictionaries[i],version) end startparsing(fontdata,data,streams) for i=1,#charstrings do diff --git a/tex/context/base/mkiv/font-con.lua b/tex/context/base/mkiv/font-con.lua index 495148341..7162338c6 100644 --- a/tex/context/base/mkiv/font-con.lua +++ b/tex/context/base/mkiv/font-con.lua @@ -451,6 +451,7 @@ function constructors.scale(tfmdata,specification) target.format = properties.format target.cache = constructors.cacheintex and "yes" or "renew" -- + local original = properties.original or tfmdata.original local fontname = properties.fontname or tfmdata.fontname local fullname = properties.fullname or tfmdata.fullname local filename = properties.filename or tfmdata.filename @@ -462,6 +463,7 @@ function constructors.scale(tfmdata,specification) -- local psname, psfixed = fixedpsname(psname,fontname or fullname or file.nameonly(filename)) -- + target.original = original target.fontname = fontname target.fullname = fullname target.filename = filename diff --git a/tex/context/base/mkiv/font-ctx.lua b/tex/context/base/mkiv/font-ctx.lua index e6ed58492..eec967c1c 100644 --- a/tex/context/base/mkiv/font-ctx.lua +++ b/tex/context/base/mkiv/font-ctx.lua @@ -1221,6 +1221,7 @@ do -- else too many locals -- ctx_setemptyfontsize() end specification = definers.makespecification(str,lookup,name,sub,method,detail,size) +-- specification.original = str if trace_defining then report_defining("stop stage one") end @@ -1239,11 +1240,6 @@ do -- else too many locals combinefeatures = v end) - - - - - implement { name = "definefont_two", arguments = { @@ -1269,7 +1265,6 @@ do -- else too many locals fontdesignsize, -- \m_font_designsize scaledfontmode -- \scaledfontmode ) - if trace_defining then report_defining("start stage two: %s, size %s, features %a & %a, mode %a",str,size,classfeatures,fontfeatures,inheritancemode) end @@ -1424,6 +1419,7 @@ do -- else too many locals context(function() busy = false mathematics.finishfallbacks(tfmdata,specification,fallbacks) +tfmdata.original = specification.specification local id = definefont(tfmdata) csnames[id] = specification.cs properties.id = id @@ -1461,6 +1457,7 @@ do -- else too many locals end) return else +tfmdata.original = specification.specification local id = definefont(tfmdata) csnames[id] = specification.cs properties.id = id diff --git a/tex/context/base/mkiv/font-def.lua b/tex/context/base/mkiv/font-def.lua index 09f2e2c32..b752b3258 100644 --- a/tex/context/base/mkiv/font-def.lua +++ b/tex/context/base/mkiv/font-def.lua @@ -489,7 +489,9 @@ function definers.read(specification,size,id) -- id can be optional, name can al end else tfmdata = definers.loadfont(specification) -- can be overloaded +-- put in properties instead if tfmdata then + tfmdata.original = specification.specification if trace_defining then report_defining("loaded and hashed: %s",hash) end diff --git a/tex/context/base/mkiv/node-aux.lmt b/tex/context/base/mkiv/node-aux.lmt new file mode 100644 index 000000000..9e7c02028 --- /dev/null +++ b/tex/context/base/mkiv/node-aux.lmt @@ -0,0 +1,396 @@ +if not modules then modules = { } end modules ['node-aux'] = { + version = 1.001, + comment = "companion to node-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- todo: n1 .. n2 : __concat metatable + +local type, tostring = type, tostring + +local nodes = nodes +local context = context + +local utfvalues = utf.values + +local nodecodes = nodes.nodecodes + +local glyph_code = nodecodes.glyph +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local attributelist_code = nodecodes.attributelist -- temporary +local localpar_code = nodecodes.localpar + +local nuts = nodes.nuts +local tonut = nuts.tonut +local tonode = nuts.tonode +local vianuts = nuts.vianuts + +local getbox = nuts.getbox +local getnext = nuts.getnext +local getid = nuts.getid +local getsubtype = nuts.getsubtype +local getlist = nuts.getlist +local getattr = nuts.getattr +local getboth = nuts.getboth +local getprev = nuts.getprev +local getwidth = nuts.getwidth +local setwidth = nuts.setwidth +local getboxglue = nuts.getboxglue +local setboxglue = nuts.setboxglue + +local setfield = nuts.setfield +local setattr = nuts.setattr +local setlink = nuts.setlink +local setlist = nuts.setlist +local setnext = nuts.setnext +local setprev = nuts.setprev +local setattrlist = nuts.setattrlist + +local traversers = nuts.traversers +local nextnode = traversers.node +local nextglyph = traversers.glyph + +local flush_node = nuts.flush +local flush_list = nuts.flush_list +local hpack_nodes = nuts.hpack +local unset_attribute = nuts.unset_attribute +local first_glyph = nuts.first_glyph +local copy_node = nuts.copy +local find_tail = nuts.tail +local getbox = nuts.getbox +local count = nuts.count +local isglyph = nuts.isglyph + +local nodepool = nuts.pool +local new_glue = nodepool.glue +local new_glyph = nodepool.glyph + +local unsetvalue = attributes.unsetvalue + +local current_font = font.current + +local texsetbox = tex.setbox + +local report_error = logs.reporter("node-aux:error") + +local function takebox(id) + local box = getbox(id) + if box then + local list = getlist(box) + setlist(box,nil) + local copy = copy_node(box) + if list then + setlist(copy,list) + end + texsetbox(id,false) + return copy + end +end + +function nodes.takebox(id) + local b = takebox(id) + if b then + return tonode(b) + end +end + +local splitbox = tex.splitbox +nodes.splitbox = splitbox + +function nuts.splitbox(id,height) + return tonut(splitbox(id,height)) +end + +-- function nodes.takelist(n) +-- -- when we need it +-- end + +function nuts.takelist(n) + local l = getlist(n) + setlist(n) + flush_node(n) + return l +end + +nuts.takebox = takebox +tex.takebox = nodes.takebox -- sometimes more clear + +-- so far + +local function repackhlist(list,...) + local temp, b = hpack_nodes(list,...) + list = getlist(temp) + setlist(temp) + flush_node(temp) + return list, b +end + +nuts.repackhlist = repackhlist + +function nodes.repackhlist(list,...) + local list, b = repackhlist(tonut(list),...) + return tonode(list), b +end + +local function set_attributes(head,attr,value) + for n, id in nextnode, head do + setattr(n,attr,value) + if id == hlist_node or id == vlist_node then + set_attributes(getlist(n),attr,value) + end + end +end + +local function set_unset_attributes(head,attr,value) + for n, id in nextnode, head do + if not getattr(n,attr) then + setattr(n,attr,value) + end + if id == hlist_code or id == vlist_code then + set_unset_attributes(getlist(n),attr,value) + end + end +end + +local function unset_attributes(head,attr) + for n, id in nextnode, head do + setattr(n,attr,unsetvalue) + if id == hlist_code or id == vlist_code then + unset_attributes(getlist(n),attr) + end + end +end + +-- for old times sake + +nuts.setattribute = nuts.setattr nodes.setattribute = nodes.setattr +nuts.getattribute = nuts.getattr nodes.getattribute = nodes.getattr +nuts.unsetattribute = nuts.unset_attribute nodes.unsetattribute = nodes.unset_attribute +nuts.has_attribute = nuts.has_attribute nodes.has_attribute = nodes.has_attribute +nuts.firstglyph = nuts.first_glyph nodes.firstglyph = nodes.first_glyph + +nuts.setattributes = set_attributes nodes.setattributes = vianuts(set_attributes) +nuts.setunsetattributes = set_unset_attributes nodes.setunsetattributes = vianuts(set_unset_attributes) +nuts.unsetattributes = unset_attributes nodes.unsetattributes = vianuts(unset_attributes) + +function nuts.firstcharacter(n,untagged) -- tagged == subtype > 255 + if untagged then + return first_glyph(n) + else + for g in nextglyph ,n do + return g + end + end +end + +local function firstcharinbox(n) + local l = getlist(getbox(n)) + if l then + for g, c in nextglyph, l do + return c + end + end + return 0 +end + +nuts .firstcharinbox = firstcharinbox +nodes.firstcharinbox = firstcharinbox -- hm, ok ? +nodes.firstcharacter = vianuts(firstcharacter) + +interfaces.implement { + name = "buildtextaccent", + arguments = "integer", + actions = function(n) -- Is this crap really used? Or was it an experiment? + local char = firstcharinbox(n) + if char > 0 then + -- context.accent(false,char) + context([[\accent%s\relax]],char) + end + end +} + +-- this depends on fonts, so we have a funny dependency ... will be +-- sorted out .. we could make tonodes a plugin into this + +local function tonodes(str,fnt,attr) -- (str,template_glyph) -- moved from blob-ini + if not str or str == "" then + return + end + local head, tail, space, fnt, template = nil, nil, nil, nil, nil + if not fnt then + fnt = current_font() + elseif type(fnt) ~= "number" and getid(fnt) == glyph_code then -- so it has to be a real node + fnt, template = nil, tonut(fnt) + end + for s in utfvalues(str) do + local n + if s == 32 then + if space then + n = copy_node(space) + elseif fonts then -- depedency + local parameters = fonts.hashes.identifiers[fnt].parameters + space = new_glue(parameters.space,parameters.space_stretch,parameters.space_shrink) + n = space + end + elseif template then + n = copy_node(template) + setvalue(n,"char",s) + else + n = new_glyph(fnt,s) + end + if attr then -- normally false when template + setattrlist(n,attr) + end + if head then + setlink(tail,n) + else + head = n + end + tail = n + end + return head, tail +end + +nuts.tonodes = tonodes + +nodes.tonodes = function(str,fnt,attr) + local head, tail = tonodes(str,fnt,attr) + return tonode(head), tonode(tail) +end + +local function link(list,currentfont,currentattr,head,tail) -- an oldie, might be replaced + for i=1,#list do + local n = list[i] + if n then + local tn = type(n) + if tn == "string" then + if #tn > 0 then + if not currentfont then + currentfont = current_font() + end + local h, t = tonodes(n,currentfont,currentattr) + if not h then + -- skip + elseif not head then + head, tail = h, t + else + setnext(tail,h) + setprev(h,t) + tail = t + end + end + elseif tn == "table" then + if #tn > 0 then + if not currentfont then + currentfont = current_font() + end + head, tail = link(n,currentfont,currentattr,head,tail) + end + elseif not head then + head = n + tail = find_tail(n) + elseif getid(n) == attributelist_code then + -- weird case + report_error("weird node type in list at index %s:",i) + for i=1,#list do + local l = list[i] + report_error("%3i: %s %S",i,getid(l) == attributelist_code and "!" or ">",l) + end + os.exit() + else + setlink(tail,n) + if getnext(n) then + tail = find_tail(n) + else + tail = n + end + end + else + -- permitting nil is convenient + end + end + return head, tail +end + +nuts.link = link + +nodes.link = function(list,currentfont,currentattr,head,tail) + local head, tail = link(list,currentfont,currentattr,tonut(head),tonut(tail)) + return tonode(head), tonode(tail) +end + +local function locate(start,wantedid,wantedsubtype) + for n, id, subtype in nextnode, start do + if id == wantedid then + if not wantedsubtype or subtype == wantedsubtype then + return n + end + elseif id == hlist_code or id == vlist_code then + local found = locate(getlist(n),wantedid,wantedsubtype) + if found then + return found + end + end + end +end + +nuts.locate = locate + +function nodes.locate(start,wantedid,wantedsubtype) + local found = locate(tonut(start),wantedid,wantedsubtype) + return found and tonode(found) +end + +local function rehpack(n,width) + local head = getlist(n) + local size = width or getwidth(n) + local temp = hpack_nodes(head,size,"exactly") + setwidth(n,size) + local set, order, sign = getboxglue(temp) + setboxglue(n,set,order,sign) + setlist(temp) + flush_node(temp) + return n +end + +nuts.rehpack = rehpack + +function nodes.rehpack(n,...) + rehpack(tonut(n),...) +end + +do + + local localparcodes = nodes.localparcodes + local hmodepar_code = localparcodes.vmode_par + local vmodepar_code = localparcodes.hmode_par + + local getnest = tex.getnest + local getsubtype = nuts.getsubtype + + function nuts.setparproperty(action,...) + local tail = tonut(getnest().tail) + while tail do + if getid(tail) == localpar_code then + local s = getsubtype(tail) + if s == hmodepar_code or s == vmodepar_code then + return action(tail,...) + else + -- something is wrong here + end + end + tail = getprev(tail) + end + end + + local getsubtype = nodes.getsubtype + + function nodes.start_of_par(n) + local s = getsubtype(n) + return s == hmodepar_code or s == vmodepar_code + end + +end diff --git a/tex/context/base/mkiv/node-aux.lua b/tex/context/base/mkiv/node-aux.lua index 407ebb09c..aa7dc0292 100644 --- a/tex/context/base/mkiv/node-aux.lua +++ b/tex/context/base/mkiv/node-aux.lua @@ -413,10 +413,7 @@ do end --- Currently only in luametatex ... experimental anyway .. if it doesn't end --- up in luatex I'll move this to a different module. - -do +if not nuts.getnormalizedline then local nextnode = traversers.glue local findfail = nuts.tail @@ -459,9 +456,7 @@ do nuts.find_node = find_node - -- if CONTEXTLMTXMODE then ... end - - nuts.getnormalizedline = direct.getnormalizedline or function(h) + function nuts.getnormalizedline(h) if getid(h) == hlist_code and getsubtype(h) == line_code then local ls, rs = 0, 0 local lh, rh = 0, 0 diff --git a/tex/context/base/mkiv/node-ini.lmt b/tex/context/base/mkiv/node-ini.lmt new file mode 100644 index 000000000..2f0b98e88 --- /dev/null +++ b/tex/context/base/mkiv/node-ini.lmt @@ -0,0 +1,287 @@ +if not modules then modules = { } end modules ['node-ini'] = { + version = 1.001, + comment = "companion to node-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +--[[ldx-- +

Most of the code that had accumulated here is now separated in modules.

+--ldx]]-- + +local next, type, tostring = next, type, tostring +local gsub = string.gsub +local concat, remove = table.concat, table.remove +local sortedhash, sortedkeys, swapped = table.sortedhash, table.sortedkeys, table.swapped + +--[[ldx-- +

Access to nodes is what gives its power. Here we implement a +few helper functions. These functions are rather optimized.

+--ldx]]-- + +nodes = nodes or { } +local nodes = nodes +nodes.handlers = nodes.handlers or { } + +local mark = utilities.storage.mark +local allocate = utilities.storage.allocate +local formatcolumns = utilities.formatters.formatcolumns + +local getsubtypes = node.subtypes +local getvalues = node.values + +tex.magicconstants = { -- we use tex.constants for something else + running = -1073741824, -- null_flag + maxdimen = 1073741823, -- max_dimen + trueinch = 4736286, +} + +local listcodes = mark(getsubtypes("list")) +local rulecodes = mark(getsubtypes("rule")) +local dircodes = mark(getsubtypes("dir")) +local glyphcodes = mark(getsubtypes("glyph")) +local disccodes = mark(getsubtypes("disc")) +local gluecodes = mark(getsubtypes("glue")) +local leadercodes = mark(getsubtypes("leader")) +local fillcodes = mark(getsubtypes("fill")) +local boundarycodes = mark(getsubtypes("boundary")) +local penaltycodes = mark(getsubtypes("penalty")) +local kerncodes = mark(getsubtypes("kern")) +local mathcodes = mark(getsubtypes("math")) +local noadcodes = mark(getsubtypes("noad")) +local radicalcodes = mark(getsubtypes("radical")) +local accentcodes = mark(getsubtypes("accent")) +local fencecodes = mark(getsubtypes("fence")) +----- fractioncodes = mark(getsubtypes("fraction")) +local localparcodes = CONTEXTLMTXMODE > 0 and mark(getsubtypes("localpar")) + +if not localparcodes then + localparcodes = allocate { [0] = "new_graf", "local_box", "hmode_par", "penalty", "math" } +end + +local function simplified(t) + local r = { } + for k, v in next, t do + r[k] = gsub(v,"_","") + end + return r +end + +local nodecodes = simplified(node.types()) +local whatcodes = simplified(node.whatsits and node.whatsits() or { }) + +local dirvalues = mark(getvalues("dir")) +local gluevalues = mark(getvalues("glue")) + +local whatcodes = { + literal = 0x1, [0x1] = "literal", + latelua = 0x2, [0x2] = "latelua", + userdefined = 0x3, [0x3] = "userdefined", + savepos = 0x4, [0x4] = "savepos", + save = 0x5, [0x5] = "save", + restore = 0x6, [0x6] = "restore", + setmatrix = 0x7, [0x7] = "setmatrix", + open = 0x8, [0x8] = "open", + close = 0x9, [0x9] = "close", + write = 0xA, [0xA] = "write", +} + +local usercodes = allocate { + [ 97] = "attribute", -- a + [100] = "number", -- d + [102] = "float", -- f + [108] = "lua", -- l + [110] = "node", -- n + [115] = "string", -- s + [116] = "token" -- t +} + +local noadoptions = allocate { + set = 0x08, + unused_1 = 0x00 + 0x08, + unused_2 = 0x01 + 0x08, + axis = 0x02 + 0x08, + no_axis = 0x04 + 0x08, + exact = 0x10 + 0x08, + left = 0x11 + 0x08, + middle = 0x12 + 0x08, + right = 0x14 + 0x08, +} + +local literalvalues = allocate { + [0] = "origin", + [1] = "page", + [2] = "always", + [3] = "raw", + [4] = "text", + [5] = "font", + [6] = "special", +} + +gluecodes = allocate(swapped(gluecodes,gluecodes)) +dircodes = allocate(swapped(dircodes,dircodes)) +boundarycodes = allocate(swapped(boundarycodes,boundarycodes)) +noadcodes = allocate(swapped(noadcodes,noadcodes)) +radicalcodes = allocate(swapped(radicalcodes,radicalcodes)) +nodecodes = allocate(swapped(nodecodes,nodecodes)) +whatcodes = allocate(swapped(whatcodes,whatcodes)) +listcodes = allocate(swapped(listcodes,listcodes)) +glyphcodes = allocate(swapped(glyphcodes,glyphcodes)) +kerncodes = allocate(swapped(kerncodes,kerncodes)) +penaltycodes = allocate(swapped(penaltycodes,penaltycodes)) +mathcodes = allocate(swapped(mathcodes,mathcodes)) +fillcodes = allocate(swapped(fillcodes,fillcodes)) +disccodes = allocate(swapped(disccodes,disccodes)) +accentcodes = allocate(swapped(accentcodes,accentcodes)) +fencecodes = allocate(swapped(fencecodes,fencecodes)) +localparcodes = allocate(swapped(localparcodes,localparcodes)) +rulecodes = allocate(swapped(rulecodes,rulecodes)) +leadercodes = allocate(swapped(leadercodes,leadercodes)) +usercodes = allocate(swapped(usercodes,usercodes)) +noadoptions = allocate(swapped(noadoptions,noadoptions)) +dirvalues = allocate(swapped(dirvalues,dirvalues)) +gluevalues = allocate(swapped(gluevalues,gluevalues)) +literalvalues = allocate(swapped(literalvalues,literalvalues)) + +nodes.gluecodes = gluecodes +nodes.dircodes = dircodes +nodes.boundarycodes = boundarycodes +nodes.noadcodes = noadcodes +nodes.nodecodes = nodecodes +nodes.whatcodes = whatcodes +nodes.listcodes = listcodes +nodes.glyphcodes = glyphcodes +nodes.kerncodes = kerncodes +nodes.penaltycodes = penaltycodes +nodes.mathcodes = mathcodes +nodes.fillcodes = fillcodes +nodes.disccodes = disccodes +nodes.accentcodes = accentcodes +nodes.radicalcodes = radicalcodes +nodes.fencecodes = fencecodes +nodes.localparcodes = localparcodes +nodes.rulecodes = rulecodes +nodes.leadercodes = leadercodes +nodes.usercodes = usercodes +nodes.noadoptions = noadoptions +nodes.dirvalues = dirvalues +nodes.gluevalues = gluevalues +nodes.literalvalues = literalvalues + +nodes.subtypes = allocate { + [nodecodes.accent] = accentcodes, + [nodecodes.boundary] = boundarycodes, + [nodecodes.dir] = dircodes, + [nodecodes.disc] = disccodes, + [nodecodes.fence] = fencecodes, + [nodecodes.glue] = gluecodes, + [nodecodes.glyph] = glyphcodes, + [nodecodes.hlist] = listcodes, + [nodecodes.kern] = kerncodes, + [nodecodes.localpar] = localparcodes, + [nodecodes.math] = mathcodes, + [nodecodes.noad] = noadcodes, + [nodecodes.penalty] = penaltycodes, + [nodecodes.radical] = radicalcodes, + [nodecodes.rule] = rulecodes, + -- [nodecodes.user] = usercodes, + [nodecodes.vlist] = listcodes, + [nodecodes.whatsit] = whatcodes, +} + +table.setmetatableindex(nodes.subtypes,function(t,k) + local v = { } + t[k] = v + return v +end) + +-- a few more friendly aliases: + +nodes.skipcodes = gluecodes +nodes.directioncodes = dircodes +nodes.whatsitcodes = whatcodes +nodes.discretionarycodes = disccodes +nodes.directionvalues = dirvalues +nodes.skipvalues = gluevalues +nodes.literalvalues = literalvalues + +glyphcodes.glyph = glyphcodes.character + +localparcodes.vmode_par = localparcodes.new_graf + +listcodes.row = listcodes.alignment +listcodes.column = listcodes.alignment + +kerncodes.kerning = kerncodes.fontkern +kerncodes.italiccorrection = kerncodes.italiccorrection or 1 -- new + +literalvalues.direct = literalvalues.always + +nodes.codes = allocate { -- mostly for listing + glue = skipcodes, + boundary = boundarycodes, + noad = noadcodes, + node = nodecodes, + hlist = listcodes, + vlist = listcodes, + glyph = glyphcodes, + kern = kerncodes, + penalty = penaltycodes, + math = mathnodes, + fill = fillcodes, + disc = disccodes, + whatsit = whatcodes, + accent = accentcodes, + fence = fencecodes, + rule = rulecodes, + leader = leadercodes, + user = usercodes, + noadoptions = noadoptions, +} + +nodes.noadoptions = { + set = 0x08, + unused_1 = 0x00 + 0x08, + unused_2 = 0x01 + 0x08, + axis = 0x02 + 0x08, + no_axis = 0x04 + 0x08, + exact = 0x10 + 0x08, + left = 0x11 + 0x08, + middle = 0x12 + 0x08, + right = 0x14 + 0x08, +} + +local report_codes = logs.reporter("nodes","codes") + +function nodes.showcodes() + local t = { } + for name, codes in sortedhash(nodes.codes) do + local sorted = sortedkeys(codes) + for i=1,#sorted do + local s = sorted[i] + if type(s) ~= "number" then + t[#t+1] = { name, s, codes[s] } + end + end + end + formatcolumns(t) + for k=1,#t do + report_codes (t[k]) + end +end + +trackers.register("system.showcodes", nodes.showcodes) + +-- We use the real node code numbers. + +local texchardef = tex.chardef + +for i=0,nodecodes.glyph do + texchardef(nodecodes[i] .. "nodecode",i) +end +for i=0,#gluecodes do + texchardef(gluecodes[i] .. "subtypecode",i) +end + +-- tex.set("internalcodesmode",1) -- obsolete diff --git a/tex/context/base/mkiv/node-ini.mkiv b/tex/context/base/mkiv/node-ini.mkiv index 2ecef4a54..8a3aa65df 100644 --- a/tex/context/base/mkiv/node-ini.mkiv +++ b/tex/context/base/mkiv/node-ini.mkiv @@ -21,12 +21,12 @@ \registerctxluafile{node-cmp}{autosuffix} \fi -\registerctxluafile{node-ini}{} +\registerctxluafile{node-ini}{autosuffix} \registerctxluafile{node-met}{} -\registerctxluafile{node-nut}{} +\registerctxluafile{node-nut}{autosuffix} \registerctxluafile{node-res}{} %registerctxluafile{node-ppt}{} % experimental, not used so probably useless -\registerctxluafile{node-aux}{} +\registerctxluafile{node-aux}{autosuffix} \registerctxluafile{node-gcm}{autosuffix} \registerctxluafile{node-tst}{} \registerctxluafile{node-tra}{} % we might split it off (module) diff --git a/tex/context/base/mkiv/node-met.lua b/tex/context/base/mkiv/node-met.lua index f472d31a9..feaff70eb 100644 --- a/tex/context/base/mkiv/node-met.lua +++ b/tex/context/base/mkiv/node-met.lua @@ -1,4 +1,4 @@ -if not modules then modules = { } end modules ['node-nut'] = { +if not modules then modules = { } end modules ['node-MET'] = { version = 1.001, comment = "companion to node-ini.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", diff --git a/tex/context/base/mkiv/node-nut.lmt b/tex/context/base/mkiv/node-nut.lmt new file mode 100644 index 000000000..004729a3c --- /dev/null +++ b/tex/context/base/mkiv/node-nut.lmt @@ -0,0 +1,572 @@ +if not modules then modules = { } end modules ['node-nut'] = { + version = 1.001, + comment = "companion to node-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- Some comments anbout going nuts can be found in the mkiv file with the +-- suffix "lua", including some timing and musings. We copy the direct table +-- (1) because that's what we did while things evolved and (2) because we +-- also add some more helpers. + +local type, rawget = type, rawget + +local nodes = nodes +local direct = node.direct + +local fastcopy = table.fastcopy + +local nodecodes = nodes.nodecodes +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local glyph_code = nodecodes.glyph + +local tonode = direct.tonode +local tonut = direct.todirect + +local is_node = direct.is_node +local is_nut = direct.is_direct + +local d_remove_node = direct.remove +local d_flush_node = direct.flush_node +local d_getnext = direct.getnext +local d_getprev = direct.getprev +local d_getid = direct.getid +local d_getlist = direct.getlist +local d_find_tail = direct.tail +local d_insert_after = direct.insert_after +local d_insert_before = direct.insert_before +local d_slide = direct.slide +local d_traverse = direct.traverse +local d_setlink = direct.setlink +local d_getboth = direct.getboth + +local nuts = { + check_discretionaries = direct.check_discretionaries, + copy = direct.copy, + copy_list = direct.copy_list, + copy_node = direct.copy, + copy_only = direct.copy_only or direct.copy, + count = direct.count, + current_attr = direct.current_attr, + delete = direct.delete, + dimensions = direct.dimensions, + effective_glue = direct.effective_glue, + end_of_math = direct.end_of_math, + exchange = direct.exchange, + find_attribute = direct.find_attribute, + first_glyph = direct.first_glyph, + flatten_discretionaries = direct.flatten_discretionaries, + flush = d_flush_node, + flush_components = direct.flush_components, + flush_list = direct.flush_list, + flush_node = direct.flush_node, + free = direct.free, + get_synctex_fields = direct.get_synctex_fields, + getattr = direct.get_attribute, + getattributelist = direct.getattributelist, + getattrlist = direct.getattributelist, + getboth = d_getboth, + getbox = direct.getbox, + getboxglue = direct.getglue, + getchar = direct.getchar, + getcomponents = direct.getcomponents, + getdata = direct.getdata, + getdepth = direct.getdepth, + getdir = direct.getdir, + getdirection = direct.getdirection, + getdisc = direct.getdisc, + getdiscretionary = direct.getdisc, + getexpansion = direct.getexpansion, + getfam = direct.getfam, + getfield = direct.getfield, + getfont = direct.getfont, + getglue = direct.getglue, + getglyphdata = direct.getglyphdata, + getheight = direct.getheight, + getid = d_getid, + getkern = direct.getkern, + getlang = direct.getlang, + getlanguage = direct.getlang, + getleader = direct.getleader, + getlist = d_getlist, + getnext = d_getnext, + getnormalizedline = direct.getnormalizedline, + getnucleus = direct.getnucleus, + getoffsets = direct.getoffsets, + getorientation = direct.getorientation, + getpenalty = direct.getpenalty, + getpost = direct.getpost, + getpre = direct.getpre, + getprev = d_getprev, + getreplace = direct.getreplace, + getruledata = direct.getglyphdata, + getscript = direct.setscript, + getshift = direct.getshift, + getstate = direct.getstate, + getsub = direct.getsub, + getsubpre = direct.getsubpre, + getsubtype = direct.getsubtype, + getsup = direct.getsup, + getsuppre = direct.getsuppre, + getsurround = direct.getkern, + gettotal = direct.gettotal, + getvalue = direct.getdata, -- obsolete + getwhd = direct.getwhd, + getwidth = direct.getwidth, + has_attribute = direct.has_attribute, + has_dimensions = direct.has_dimensions, + has_field = direct.has_field, + has_glyph = direct.has_glyph or direct.first_glyph, + hpack = direct.hpack, + hyphenating = direct.hyphenating, + insert_after = d_insert_after, + insert_before = d_insert_before, + is_direct = is_direct, + is_node = is_node, + is_nut = direct.is_direct, + is_zero_glue = direct.is_zero_glue, + ischar = direct.is_char, + isglyph = direct.is_glyph, + kerning = direct.kerning, + last_node = direct.last_node, + length = direct.length, + ligaturing = direct.ligaturing, + migrate = direct.migrate, + mlist_to_hlist = direct.mlist_to_hlist, + new = direct.new, + protect_glyph = direct.protect_glyph, + protect_glyphs = direct.protect_glyphs, + protrusion_skippable = direct.protrusion_skippable, + rangedimensions = direct.rangedimensions, + remove = d_remove_node, + reverse = direct.reverse, + set_attribute = direct.set_attribute, + set_synctex_fields = direct.set_synctex_fields, + setattr = direct.set_attribute, + setattributelist = direct.setattributelist, + setattrlist = direct.setattributelist, + setboth = direct.setboth, + setbox = direct.setbox, + setboxglue = direct.setglue, + setchar = direct.setchar, + setcomponents = direct.setcomponents, + setdata = direct.setdata, + setdepth = direct.setdepth, + setdir = direct.setdir, + setdirection = direct.setdirection, + setdisc = direct.setdisc, + setdiscretionary = direct.setdisc, + setexpansion = direct.setexpansion, + setfam = direct.setfam, + setfield = direct.setfield, + setfont = direct.setfont, + setglue = direct.setglue, + setglyphdata = direct.setglyphdata, + setheight = direct.setheight, + setkern = direct.setkern, + setlang = direct.setlang, + setlanguage = direct.setlang, + setleader = direct.setleader, + setlink = d_setlink, + setlist = direct.setlist, + setnext = direct.setnext, + setnucleus = direct.setnucleus, + setoffsets = direct.setoffsets, + setorientation = direct.setorientation, + setpenalty = direct.setpenalty, + setpost = direct.setpost, + setpre = direct.setpre, + setprev = direct.setprev, + setreplace = direct.setreplace, + setruledata = direct.setglyphdata, + setscript = direct.getscript, + setshift = direct.setshift, + setsplit = direct.setsplit, + setstate = direct.setstate, + setsub = direct.setsub, + setsubpre = direct.setsubpre, + setsubtype = direct.setsubtype, + setsup = direct.setsup, + setsuppre = direct.setsuppre, + setsurround = direct.setkern, + setvalue = direct.setdata, -- obsolete + setwhd = direct.setwhd, + setwidth = direct.setwidth, + slide = d_slide, + start_of_par = direct.start_of_par, + tail = d_find_tail, + takeattr = direct.unset_attribute, -- ? + tonode = tonode, + tonut = tonut, + tostring = direct.tostring, + traverse = d_traverse, + traverse_char = direct.traverse_char, + traverse_glyph = direct.traverse_glyph, + traverse_id = direct.traverse_id, + traverse_list = direct.traverse_list, + unprotect_glyph = direct.unprotect_glyph, + unprotect_glyphs = direct.unprotect_glyphs, + unset_attribute = direct.unset_attribute, + usedlist = direct.usedlist, + uses_font = direct.uses_font, + vpack = direct.vpack, + writable_spec = direct.writable_spec, + write = direct.write, +} + + +nodes.nuts = nuts + +nodes.is_node = is_node +nodes.is_direct = is_nut +nodes.is_nut = is_nut + +nodes.tonode = tonode +nodes.tonut = tonut + +function nuts.delete(head,current) + return d_remove_node(head,current,true) +end + +function nuts.replace(head,current,new) -- no head returned if false + if not new then + head, current, new = false, head, current + end + local prev, next = d_getboth(current) + if prev or next then + d_setlink(prev,new,next) + end + if head then + if head == current then + head = new + end + d_flush_node(current) + return head, new + else + d_flush_node(current) + return new + end +end + +local function countall(stack,flat) + local n = 0 + while stack do + local id = d_getid(stack) + if not flat and id == hlist_code or id == vlist_code then + local list = d_getlist(stack) + if list then + n = n + 1 + countall(list) -- self counts too + else + n = n + 1 + end + else + n = n + 1 + end + stack = d_getnext(stack) + end + return n +end + +nuts.countall = countall + +function nodes.countall(stack,flat) + return countall(tonut(stack),flat) +end + +function nuts.append(head,current,...) + for i=1,select("#",...) do + head, current = d_insert_after(head,current,(select(i,...))) + end + return head, current +end + +function nuts.prepend(head,current,...) + for i=1,select("#",...) do + head, current = d_insert_before(head,current,(select(i,...))) + end + return head, current +end + +function nuts.linked(...) -- slides ! + local head, last + for i=1,select("#",...) do + local next = select(i,...) + if next then + if head then + d_setlink(last,next) + else + head = next + end + last = d_find_tail(next) -- we could skip the last one + end + end + return head +end + +function nuts.concat(list) -- consider tail instead of slide + local head, tail + for i=1,#list do + local li = list[i] + if li then + if head then + d_setlink(tail,li) + else + head = li + end + tail = d_slide(li) + end + end + return head, tail +end + +function nuts.reference(n) + return n or "" +end + +function nuts.vianuts (f) return function(n,...) return tonode(f(tonut (n),...)) end end +function nuts.vianodes(f) return function(n,...) return tonut (f(tonode(n),...)) end end + +nodes.vianuts = nuts.vianuts +nodes.vianodes = nuts.vianodes + +function nodes.insert_list_after(h,c,n) + local t = n_tail(n) + if c then + local cn = n_getnext(c) + if cn then + -- no setboth here yet + n_setfield(t,"next",cn) + n_setfield(cn,"prev",t) + else + n_setfield(t,"next",nil) + end + n_setfield(c,"next",n) + n_setfield(n,"prev",c) + return h, n + end + return n, t +end + +function nuts.insert_list_after(h,c,n) + local t = d_tail(n) + if c then + local cn = d_getnext(c) + if cn then + d_setlink(t,cn) + else + d_setnext(t) + end + d_setlink(c,n) + return h, n + end + return n, t +end + +-- test code only + +-- collectranges and mix + +local report = logs.reporter("sliding") + +local function message(detail,head,current,previous) + report("error: %s, current: %s:%s, previous: %s:%s, list: %s, text: %s", + detail, + nodecodes[d_getid(current)], + current, + nodecodes[d_getid(previous)], + previous, + nodes.idstostring(head), + nodes.listtoutf(head) + ) + utilities.debugger.showtraceback(report) +end + +local function warn() + report() + report("warning: the slide tracer is enabled") + report() + warn = false +end + +local function tracedslide(head) + if head then + if warn then + warn() + end + local next = d_getnext(head) + if next then + local prev = head + for n in d_traverse(next) do + local p = d_getprev(n) + if not p then + message("unset",head,n,prev) + -- break + elseif p ~= prev then + message("wrong",head,n,prev) + -- break + end + prev = n + end + end + return d_slide(head) + end +end + +local function nestedtracedslide(head,level) -- no sliding ! + if head then + if warn then + warn() + end + local id = d_getid(head) + local next = d_getnext(head) + if next then + report("%whead:%s",level or 0,nodecodes[id]) + local prev = head + for n in d_traverse(next) do + local p = d_getprev(n) + if not p then + message("unset",head,n,prev) + -- break + elseif p ~= prev then + message("wrong",head,n,prev) + -- break + end + prev = n + local id = d_getid(n) + if id == hlist_code or id == vlist_code then + nestedtracedslide(d_getlist(n),(level or 0) + 1) + end + end + elseif id == hlist_code or id == vlist_code then + report("%wlist:%s",level or 0,nodecodes[id]) + nestedtracedslide(d_getlist(head),(level or 0) + 1) + end + -- return d_slide(head) + end +end + +local function untracedslide(head) + if head then + if warn then + warn() + end + local next = d_getnext(head) + if next then + local prev = head + for n in d_traverse(next) do + local p = d_getprev(n) + if not p then + return "unset", d_getid(n) + elseif p ~= prev then + return "wrong", d_getid(n) + end + prev = n + end + end + return d_slide(head) + end +end + +nuts.tracedslide = tracedslide +nuts.untracedslide = untracedslide +nuts.nestedtracedslide = nestedtracedslide + +-- this might move + +local propertydata = direct.get_properties_table(true) + +local getattr = nuts.getattr +local setattr = nuts.setattr + +nodes.properties = { + data = propertydata, +} + +-- experimental code with respect to copying attributes has been removed +-- as it doesn't pay of (most attributes are only accessed once anyway) + +function nuts.getprop(n,k) + local p = propertydata[n] + if p then + if k then + return p[k] + else + return p + end + end +end + +function nuts.rawprop(n,k) + local p = rawget(propertydata,n) + if p then + if k then + return p[k] + else + return p + end + end +end + +function nuts.setprop(n,k,v) + local p = propertydata[n] + if p then + p[k] = v + else + propertydata[n] = { [k] = v } + end +end + +function nuts.theprop(n) + local p = propertydata[n] + if not p then + p = { } + propertydata[n] = p + end + return p +end + + +function nuts.isdone(n,k) + local p = propertydata[n] + if not p then + propertydata[n] = { [k] = true } + return false + end + local v = p[k] + if v == nil then + propertydata[n] = { [k] = true } + return false + end + return v +end + +function nuts.copy_properties(source,target,what) + local newprops = propertydata[source] + if not newprops then + -- nothing to copy + return + end + if what then + -- copy one category + newprops = rawget(source,what) + if newprops then + newprops = fastcopy(newprops) + local p = rawget(propertydata,target) + if p then + p[what] = newprops + else + propertydata[target] = { + [what] = newprops, + } + end + end + else + -- copy all properties + newprops = fastcopy(newprops) + propertydata[target] = newprops + end + return newprops -- for checking +end diff --git a/tex/context/base/mkiv/node-nut.lua b/tex/context/base/mkiv/node-nut.lua index 80335e933..68d238b1a 100644 --- a/tex/context/base/mkiv/node-nut.lua +++ b/tex/context/base/mkiv/node-nut.lua @@ -1,4 +1,4 @@ -if not modules then modules = { } end modules ['node-met'] = { +if not modules then modules = { } end modules ['node-nut'] = { version = 1.001, comment = "companion to node-ini.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", @@ -396,7 +396,7 @@ local d_setlink = direct.setlink local d_setboth = direct.setboth local d_getboth = direct.getboth -local remove = CONTEXTLMTXMODE > 0 and d_remove_node or function(head,current,free_too) +local remove = function(head,current,free_too) if current then local h, c = d_remove_node(head,current) if free_too then @@ -812,8 +812,6 @@ nuts.tracedslide = tracedslide nuts.untracedslide = untracedslide nuts.nestedtracedslide = nestedtracedslide --- nuts.slide = tracedslide - -- this might move local propertydata = direct.get_properties_table(true) @@ -877,17 +875,7 @@ local getstate = direct.getstate local setstate = direct.setstate if not setstate or not getstate then - -- setstate = function(n,v) - -- setprop(n,"state",v) - -- end - -- getstate = function(n,v) - -- local s = getprop(n,"state") - -- if v then - -- return s == v - -- else - -- return s - -- end - -- end + setstate = function(n,v) local p = propertydata[n] if p then @@ -896,6 +884,7 @@ if not setstate or not getstate then propertydata[n] = { state = v } end end + getstate = function(n,v) local p = propertydata[n] if p then @@ -919,7 +908,7 @@ local setscript = direct.setscript or function(n,v) end -- elsewhere nuts.setscript = getscript nuts.getscript = setscript -nuts.isdone = function(n,k) +function nuts.isdone(n,k) local p = propertydata[n] if not p then propertydata[n] = { [k] = true } @@ -933,9 +922,6 @@ nuts.isdone = function(n,k) return v end --- nodes.setprop = nodes.setproperty --- nodes.getprop = nodes.getproperty - function nuts.copy_properties(source,target,what) local newprops = propertydata[source] if not newprops then diff --git a/tex/context/base/mkiv/node-res.lua b/tex/context/base/mkiv/node-res.lua index 9b76fed54..c27059003 100644 --- a/tex/context/base/mkiv/node-res.lua +++ b/tex/context/base/mkiv/node-res.lua @@ -584,12 +584,17 @@ local usage = CONTEXTLMTXMODE > 0 and node.inuse or function() return t end +local stock = CONTEXTLMTXMODE > 0 and node.instock or { } + nutpool .cleanup = cleanup nodepool.cleanup = cleanup nutpool .usage = usage nodepool.usage = usage +nutpool .stock = stock +nodepool.stock = stock + -- end statistics.register("cleaned up reserved nodes", function() diff --git a/tex/context/base/mkiv/node-snp.lmt b/tex/context/base/mkiv/node-snp.lmt index d058a142a..8c0237a5c 100644 --- a/tex/context/base/mkiv/node-snp.lmt +++ b/tex/context/base/mkiv/node-snp.lmt @@ -16,6 +16,7 @@ nodes.snapshots = snapshots local status = status local nodeusage = nodes.pool and nodes.pool.usage +local nodestock = nodes.pool and nodes.pool.stock local clock = os.gettimeofday or os.clock -- should go in environment local lasttime = clock() local samples = { } @@ -25,6 +26,7 @@ function snapshots.takesample(comment) local c = clock() samples[#samples+1] = { nodes = nodeusage(), + stock = nodestock(), texcallbacks = status.getcallbackstate(), mpcallbacks = mplib.getcallbackstate(), backendcallbacks = backends.getcallbackstate(), @@ -51,6 +53,8 @@ function snapshots.takesample(comment) read = status.getreadstate(), font = status.getfontstate(), language = status.getlanguagestate(), + mark = status.getmarkstate(), + sparse = status.getsparsestate(), }, } end diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf index 41c6c2f60..56e1600c9 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 5d19ce520..1b46f8863 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/trac-inf.lmt b/tex/context/base/mkiv/trac-inf.lmt index 1729c87e5..80bb3b2f6 100644 --- a/tex/context/base/mkiv/trac-inf.lmt +++ b/tex/context/base/mkiv/trac-inf.lmt @@ -289,20 +289,20 @@ function statistics.showusage(when) local list = { "stringstate", "poolstate", "hashstate", "lookupstate", - "nodestate", "tokenstate", + "nodestate", "extrastate", "tokenstate", "bufferstate", "inputstate", "filestate", "neststate", "parameterstate", "savestate", - "fontstate", "languagestate", + "fontstate", "languagestate", "markstate", "sparsestate", } local fields = { "max", "min", "set", "stp", false, "mem", "all", false, "ini", "ptr", "top" } - local line = rep("-",172) + local line = rep("-",190) do local t = { } for i=1,#list do t[i] = gsub(list[i],"state","") end report("%w%s",2,line) - report("%w%12s%12s%12s%12s%12s%12s%12s%12s%12s%12s%12s%12s%12s%12s",5,unpack(t)) + report("%w%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s",5,unpack(t)) report("%w%s",2,line) end for i=1,#fields do @@ -311,9 +311,9 @@ function statistics.showusage(when) local t = { } for i=1,#list do local n = s[list[i]][f] - t[i] = n < 0 and formatters["%w"](12) or formatters["%12i"](n) + t[i] = n < 0 and formatters["%w"](11) or formatters["%11i"](n) end - report(" %3s%12s%12s%12s%12s%12s%12s%12s%12s%12s%12s%12s%12s%12s%12s",f,unpack(t)) + report(" %3s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s",f,unpack(t)) else report("") end @@ -363,8 +363,18 @@ local enabled = false trackers.register("system.usage", function(v) if v and not registered then logs.private.enablepagetiming() - luatex.registerpageactions(function() if enabled then statistics.showusage("page") end end) - luatex.registerstopactions(function() if enabled then statistics.showusage("finish") end end) + if v ~= "summary" then + luatex.registerpageactions(function() + if enabled then + statistics.showusage("page") + end + end) + end + luatex.registerstopactions(function() + if enabled then + statistics.showusage("finish") + end + end) registered = true end enabled = v diff --git a/tex/context/base/mkiv/trac-tim.lmt b/tex/context/base/mkiv/trac-tim.lmt index ce61c7440..fcba7f132 100644 --- a/tex/context/base/mkiv/trac-tim.lmt +++ b/tex/context/base/mkiv/trac-tim.lmt @@ -123,6 +123,7 @@ local function convert(name) end collect("nodes") + collect("stock") collect("memories") collect("variables") collect("texvariables") diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index aaea6ff2f..ff1b629b8 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 : 2020-08-25 19:56 +-- merge date : 2020-08-27 19:25 do -- begin closure to overcome local limits and interference @@ -9131,12 +9131,14 @@ function constructors.scale(tfmdata,specification) target.cidinfo=properties.cidinfo target.format=properties.format target.cache=constructors.cacheintex and "yes" or "renew" + local original=properties.original or tfmdata.original local fontname=properties.fontname or tfmdata.fontname local fullname=properties.fullname or tfmdata.fullname local filename=properties.filename or tfmdata.filename local psname=properties.psname or tfmdata.psname local name=properties.name or tfmdata.name local psname,psfixed=fixedpsname(psname,fontname or fullname or file.nameonly(filename)) + target.original=original target.fontname=fontname target.fullname=fullname target.filename=filename @@ -13275,15 +13277,15 @@ do local p_dictionary=( p_byte+p_positive+p_negative+p_short+p_long+p_nibbles+p_single+p_double+p_unsupported )^1 - parsedictionaries=function(data,dictionaries,what) + parsedictionaries=function(data,dictionaries,version) stack={} strings=data.strings if trace_charstrings then - report("charstring format %a",what) + report("charstring format %a",version) end for i=1,#dictionaries do top=0 - result=what=="cff" and { + result=version=="cff" and { monospaced=false, italicangle=0, underlineposition=-100, @@ -14658,8 +14660,8 @@ do processshape(tab,index-1) end end -local function readglobals(f,data) - local routines=readlengths(f) +local function readglobals(f,data,version) + local routines=readlengths(f,version=="cff2") for i=1,#routines do routines[i]=readbytetable(f,routines[i]) end @@ -14713,14 +14715,14 @@ local function readprivates(f,data) private.data=readstring(f,private.size) end end -local function readlocals(f,data,dictionary) +local function readlocals(f,data,dictionary,version) local header=data.header local private=dictionary.private if private then local subroutineoffset=private.data.subroutines if subroutineoffset~=0 then setposition(f,header.offset+private.offset+subroutineoffset) - local subroutines=readlengths(f) + local subroutines=readlengths(f,version=="cff2") for i=1,#subroutines do subroutines[i]=readbytetable(f,subroutines[i]) end @@ -14733,7 +14735,7 @@ local function readlocals(f,data,dictionary) dictionary.subroutines={} end end -local function readcharstrings(f,data,what) +local function readcharstrings(f,data,version) local header=data.header local dictionaries=data.dictionaries local dictionary=dictionaries[1] @@ -14742,7 +14744,7 @@ local function readcharstrings(f,data,what) if type(offset)~="number" then elseif stringtype==2 then setposition(f,header.offset+offset) - local charstrings=readlengths(f,what=="cff2") + local charstrings=readlengths(f,version=="cff2") local nofglyphs=#charstrings for i=1,nofglyphs do charstrings[i]=readstring(f,charstrings[i]) @@ -14772,7 +14774,8 @@ readers.parsecharstrings=parsecharstrings local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams) local dictionaries=data.dictionaries local dictionary=dictionaries[1] - readglobals(f,data) + local cid=not dictionary.private and dictionary.cid + readglobals(f,data,version) readcharstrings(f,data,version) if version=="cff2" then dictionary.charset=nil @@ -14780,9 +14783,27 @@ local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams) readencodings(f,data) readcharsets(f,data,dictionary) end + if cid then + local fdarray=cid.fdarray + if fdarray then + setposition(f,data.header.offset+fdarray) + local dictionaries=readlengths(f,version=="cff2") + local nofdictionaries=#dictionaries + if nofdictionaries>0 then + for i=1,nofdictionaries do + dictionaries[i]=readstring(f,dictionaries[i]) + end + parsedictionaries(data,dictionaries) + dictionary.private=dictionaries[1].private + if nofdictionaries>1 then + report("ignoring dictionaries > 1 in cid font") + end + end + end + end readprivates(f,data) parseprivates(data,data.dictionaries) - readlocals(f,data,dictionary) + readlocals(f,data,dictionary,version) startparsing(fontdata,data,streams) parsecharstrings(fontdata,data,glyphs,doshapes,version,streams) stopparsing(fontdata,data) @@ -14793,7 +14814,7 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams) local dictionary=dictionaries[1] local cid=dictionary.cid local cidselect=cid and cid.fdselect - readglobals(f,data) + readglobals(f,data,version) readcharstrings(f,data,version) if version~="cff2" then readencodings(f,data) @@ -14837,7 +14858,7 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams) local cidarray=cid.fdarray if cidarray then setposition(f,header.offset+cidarray) - local dictionaries=readlengths(f) + local dictionaries=readlengths(f,version=="cff2") for i=1,#dictionaries do dictionaries[i]=readstring(f,dictionaries[i]) end @@ -14845,7 +14866,7 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams) cid.dictionaries=dictionaries readcidprivates(f,data) for i=1,#dictionaries do - readlocals(f,data,dictionaries[i]) + readlocals(f,data,dictionaries[i],version) end startparsing(fontdata,data,streams) for i=1,#charstrings do @@ -35924,8 +35945,9 @@ function definers.read(specification,size,id) report_defining("already hashed: %s",hash) end else - tfmdata=definers.loadfont(specification) + tfmdata=definers.loadfont(specification) if tfmdata then + tfmdata.original=specification.specification if trace_defining then report_defining("loaded and hashed: %s",hash) end -- cgit v1.2.3