diff options
Diffstat (limited to 'tex/context/base/node-res.lua')
-rw-r--r-- | tex/context/base/node-res.lua | 812 |
1 files changed, 406 insertions, 406 deletions
diff --git a/tex/context/base/node-res.lua b/tex/context/base/node-res.lua index 6ec6895c8..768aac404 100644 --- a/tex/context/base/node-res.lua +++ b/tex/context/base/node-res.lua @@ -1,406 +1,406 @@ -if not modules then modules = { } end modules ['node-res'] = {
- 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"
-}
-
-local gmatch, format = string.gmatch, string.format
-local tonumber, round = tonumber, math.round
-
---[[ldx--
-<p>The next function is not that much needed but in <l n='context'/> we use
-for debugging <l n='luatex'/> node management.</p>
---ldx]]--
-
-local report_nodes = logs.reporter("nodes","housekeeping")
-
-local nodes, node = nodes, node
-
-local copy_node = node.copy
-local free_node = node.free
-local free_list = node.flush_list
-local new_node = node.new
-
-nodes.pool = nodes.pool or { }
-local pool = nodes.pool
-
-local whatsitcodes = nodes.whatsitcodes
-local skipcodes = nodes.skipcodes
-local kerncodes = nodes.kerncodes
-local nodecodes = nodes.nodecodes
-
-local glyph_code = nodecodes.glyph
-
-local allocate = utilities.storage.allocate
-
-local reserved, nofreserved = { }, 0
-
-local function register_node(n)
- nofreserved = nofreserved + 1
- reserved[nofreserved] = n
- return n
-end
-
-pool.register = register_node
-
-function pool.cleanup(nofboxes) -- todo
- if nodes.tracers.steppers then -- to be resolved
- nodes.tracers.steppers.reset() -- todo: make a registration subsystem
- end
- local nl, nr = 0, nofreserved
- for i=1,nofreserved do
- local ri = reserved[i]
- -- if not (ri.id == glue_spec and not ri.is_writable) then
- free_node(reserved[i])
- -- end
- end
- if nofboxes then
- local tb = tex.box
- for i=0,nofboxes do
- local l = tb[i]
- if l then
- free_node(tb[i])
- nl = nl + 1
- end
- end
- end
- reserved = { }
- nofreserved = 0
- return nr, nl, nofboxes -- can be nil
-end
-
-function pool.usage()
- local t = { }
- for n, tag in gmatch(status.node_mem_usage,"(%d+) ([a-z_]+)") do
- t[tag] = n
- end
- return t
-end
-
-local disc = register_node(new_node("disc"))
-local kern = register_node(new_node("kern",kerncodes.userkern))
-local fontkern = register_node(new_node("kern",kerncodes.fontkern))
-local penalty = register_node(new_node("penalty"))
-local glue = register_node(new_node("glue")) -- glue.spec = nil
-local glue_spec = register_node(new_node("glue_spec"))
-local glyph = register_node(new_node("glyph",0))
-local textdir = register_node(new_node("whatsit",whatsitcodes.dir))
-local latelua = register_node(new_node("whatsit",whatsitcodes.latelua))
-local special = register_node(new_node("whatsit",whatsitcodes.special))
-local user_n = register_node(new_node("whatsit",whatsitcodes.userdefined)) user_n.type = 100 -- 44
-local user_l = register_node(new_node("whatsit",whatsitcodes.userdefined)) user_l.type = 110 -- 44
-local user_s = register_node(new_node("whatsit",whatsitcodes.userdefined)) user_s.type = 115 -- 44
-local user_t = register_node(new_node("whatsit",whatsitcodes.userdefined)) user_t.type = 116 -- 44
-local left_margin_kern = register_node(new_node("margin_kern",0))
-local right_margin_kern = register_node(new_node("margin_kern",1))
-local lineskip = register_node(new_node("glue",skipcodes.lineskip))
-local baselineskip = register_node(new_node("glue",skipcodes.baselineskip))
-local leftskip = register_node(new_node("glue",skipcodes.leftskip))
-local rightskip = register_node(new_node("glue",skipcodes.rightskip))
-local temp = register_node(new_node("temp",0))
-local noad = register_node(new_node("noad"))
-
--- the dir field needs to be set otherwise crash:
-
-local rule = register_node(new_node("rule")) rule .dir = "TLT"
-local hlist = register_node(new_node("hlist")) hlist.dir = "TLT"
-local vlist = register_node(new_node("vlist")) vlist.dir = "TLT"
-
-function pool.zeroglue(n)
- local s = n.spec
- return not writable or (
- s.width == 0
- and s.stretch == 0
- and s.shrink == 0
- and s.stretch_order == 0
- and s.shrink_order == 0
- )
-end
-
-function pool.glyph(fnt,chr)
- local n = copy_node(glyph)
- if fnt then n.font = fnt end
- if chr then n.char = chr end
- return n
-end
-
-function pool.penalty(p)
- local n = copy_node(penalty)
- n.penalty = p
- return n
-end
-
-function pool.kern(k)
- local n = copy_node(kern)
- n.kern = k
- return n
-end
-
-function pool.fontkern(k)
- local n = copy_node(fontkern)
- n.kern = k
- return n
-end
-
-function pool.gluespec(width,stretch,shrink,stretch_order,shrink_order)
- local s = copy_node(glue_spec)
- if width then s.width = width end
- if stretch then s.stretch = stretch end
- if shrink then s.shrink = shrink end
- if stretch_order then s.stretch_order = stretch_order end
- if shrink_order then s.shrink_order = shrink_order end
- return s
-end
-
-local function someskip(skip,width,stretch,shrink,stretch_order,shrink_order)
- local n = copy_node(skip)
- if not width then
- -- no spec
- elseif width == false or tonumber(width) then
- local s = copy_node(glue_spec)
- if width then s.width = width end
- if stretch then s.stretch = stretch end
- if shrink then s.shrink = shrink end
- if stretch_order then s.stretch_order = stretch_order end
- if shrink_order then s.shrink_order = shrink_order end
- n.spec = s
- else
- -- shared
- n.spec = copy_node(width)
- end
- return n
-end
-
-function pool.stretch(a,b)
- local n = copy_node(glue)
- local s = copy_node(glue_spec)
- if b then
- s.stretch = a
- s.stretch_order = b
- else
- s.stretch = 1
- s.stretch_order = a or 1
- end
- n.spec = s
- return n
-end
-
-function pool.shrink(a,b)
- local n = copy_node(glue)
- local s = copy_node(glue_spec)
- if b then
- s.shrink = a
- s.shrink_order = b
- else
- s.shrink = 1
- s.shrink_order = a or 1
- end
- n.spec = s
- return n
-end
-
-
-function pool.glue(width,stretch,shrink,stretch_order,shrink_order)
- return someskip(glue,width,stretch,shrink,stretch_order,shrink_order)
-end
-
-function pool.leftskip(width,stretch,shrink,stretch_order,shrink_order)
- return someskip(leftskip,width,stretch,shrink,stretch_order,shrink_order)
-end
-
-function pool.rightskip(width,stretch,shrink,stretch_order,shrink_order)
- return someskip(rightskip,width,stretch,shrink,stretch_order,shrink_order)
-end
-
-function pool.lineskip(width,stretch,shrink,stretch_order,shrink_order)
- return someskip(lineskip,width,stretch,shrink,stretch_order,shrink_order)
-end
-
-function pool.baselineskip(width,stretch,shrink)
- return someskip(baselineskip,width,stretch,shrink)
-end
-
-function pool.disc()
- return copy_node(disc)
-end
-
-function pool.textdir(dir)
- local t = copy_node(textdir)
- t.dir = dir
- return t
-end
-
-function pool.rule(width,height,depth,dir) -- w/h/d == nil will let them adapt
- local n = copy_node(rule)
- if width then n.width = width end
- if height then n.height = height end
- if depth then n.depth = depth end
- if dir then n.dir = dir end
- return n
-end
-
-if node.has_field(latelua,'string') then
- function pool.latelua(code)
- local n = copy_node(latelua)
- n.string = code
- return n
- end
-else
- function pool.latelua(code)
- local n = copy_node(latelua)
- n.data = code
- return n
- end
-end
-
-function pool.leftmarginkern(glyph,width)
- local n = copy_node(left_margin_kern)
- if not glyph then
- report_nodes("invalid pointer to left margin glyph node")
- elseif glyph.id ~= glyph_code then
- report_nodes("invalid node type %a for %s margin glyph node",nodecodes[glyph],"left")
- else
- n.glyph = glyph
- end
- if width then
- n.width = width
- end
- return n
-end
-
-function pool.rightmarginkern(glyph,width)
- local n = copy_node(right_margin_kern)
- if not glyph then
- report_nodes("invalid pointer to right margin glyph node")
- elseif glyph.id ~= glyph_code then
- report_nodes("invalid node type %a for %s margin glyph node",nodecodes[p],"right")
- else
- n.glyph = glyph
- end
- if width then
- n.width = width
- end
- return n
-end
-
-function pool.temp()
- return copy_node(temp)
-end
-
-function pool.noad()
- return copy_node(noad)
-end
-
-function pool.hlist()
- return copy_node(hlist)
-end
-
-function pool.vlist()
- return copy_node(vlist)
-end
-
---[[
-<p>At some point we ran into a problem that the glue specification
-of the zeropoint dimension was overwritten when adapting a glue spec
-node. This is a side effect of glue specs being shared. After a
-couple of hours tracing and debugging Taco and I came to the
-conclusion that it made no sense to complicate the spec allocator
-and settled on a writable flag. This all is a side effect of the
-fact that some glues use reserved memory slots (with the zeropoint
-glue being a noticeable one). So, next we wrap this into a function
-and hide it for the user. And yes, LuaTeX now gives a warning as
-well.</p>
-]]--
-
-function nodes.writable_spec(n) -- not pool
- local spec = n.spec
- if not spec then
- spec = copy_node(glue_spec)
- n.spec = spec
- elseif not spec.writable then
- spec = copy_node(spec)
- n.spec = spec
- end
- return spec
-end
-
--- local num = userids["my id"]
--- local str = userids[num]
-
-local userids = allocate() pool.userids = userids
-local lastid = 0
-
-setmetatable(userids, {
- __index = function(t,k)
- if type(k) == "string" then
- lastid = lastid + 1
- rawset(userids,lastid,k)
- rawset(userids,k,lastid)
- return lastid
- else
- rawset(userids,k,k)
- return k
- end
- end,
- __call = function(t,k)
- return t[k]
- end
-} )
-
-function pool.usernumber(id,num)
- local n = copy_node(user_n)
- if num then
- n.user_id, n.value = id, num
- elseif id then
- n.value = id
- end
- return n
-end
-
-function pool.userlist(id,list)
- local n = copy_node(user_l)
- if list then
- n.user_id, n.value = id, list
- else
- n.value = id
- end
- return n
-end
-
-function pool.userstring(id,str)
- local n = copy_node(user_s)
- if str then
- n.user_id, n.value = id, str
- else
- n.value = id
- end
- return n
-end
-
-function pool.usertokens(id,tokens)
- local n = copy_node(user_t)
- if tokens then
- n.user_id, n.value = id, tokens
- else
- n.value = id
- end
- return n
-end
-
-function pool.special(str)
- local n = copy_node(special)
- n.data = str
- return n
-end
-
-statistics.register("cleaned up reserved nodes", function()
- return format("%s nodes, %s lists of %s", pool.cleanup(tex.count["c_syst_last_allocated_box"]))
-end) -- \topofboxstack
-
-statistics.register("node memory usage", function() -- comes after cleanup !
- return status.node_mem_usage
-end)
-
-lua.registerfinalizer(pool.cleanup, "cleanup reserved nodes")
+if not modules then modules = { } end modules ['node-res'] = { + 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" +} + +local gmatch, format = string.gmatch, string.format +local tonumber, round = tonumber, math.round + +--[[ldx-- +<p>The next function is not that much needed but in <l n='context'/> we use +for debugging <l n='luatex'/> node management.</p> +--ldx]]-- + +local report_nodes = logs.reporter("nodes","housekeeping") + +local nodes, node = nodes, node + +local copy_node = node.copy +local free_node = node.free +local free_list = node.flush_list +local new_node = node.new + +nodes.pool = nodes.pool or { } +local pool = nodes.pool + +local whatsitcodes = nodes.whatsitcodes +local skipcodes = nodes.skipcodes +local kerncodes = nodes.kerncodes +local nodecodes = nodes.nodecodes + +local glyph_code = nodecodes.glyph + +local allocate = utilities.storage.allocate + +local reserved, nofreserved = { }, 0 + +local function register_node(n) + nofreserved = nofreserved + 1 + reserved[nofreserved] = n + return n +end + +pool.register = register_node + +function pool.cleanup(nofboxes) -- todo + if nodes.tracers.steppers then -- to be resolved + nodes.tracers.steppers.reset() -- todo: make a registration subsystem + end + local nl, nr = 0, nofreserved + for i=1,nofreserved do + local ri = reserved[i] + -- if not (ri.id == glue_spec and not ri.is_writable) then + free_node(reserved[i]) + -- end + end + if nofboxes then + local tb = tex.box + for i=0,nofboxes do + local l = tb[i] + if l then + free_node(tb[i]) + nl = nl + 1 + end + end + end + reserved = { } + nofreserved = 0 + return nr, nl, nofboxes -- can be nil +end + +function pool.usage() + local t = { } + for n, tag in gmatch(status.node_mem_usage,"(%d+) ([a-z_]+)") do + t[tag] = n + end + return t +end + +local disc = register_node(new_node("disc")) +local kern = register_node(new_node("kern",kerncodes.userkern)) +local fontkern = register_node(new_node("kern",kerncodes.fontkern)) +local penalty = register_node(new_node("penalty")) +local glue = register_node(new_node("glue")) -- glue.spec = nil +local glue_spec = register_node(new_node("glue_spec")) +local glyph = register_node(new_node("glyph",0)) +local textdir = register_node(new_node("whatsit",whatsitcodes.dir)) +local latelua = register_node(new_node("whatsit",whatsitcodes.latelua)) +local special = register_node(new_node("whatsit",whatsitcodes.special)) +local user_n = register_node(new_node("whatsit",whatsitcodes.userdefined)) user_n.type = 100 -- 44 +local user_l = register_node(new_node("whatsit",whatsitcodes.userdefined)) user_l.type = 110 -- 44 +local user_s = register_node(new_node("whatsit",whatsitcodes.userdefined)) user_s.type = 115 -- 44 +local user_t = register_node(new_node("whatsit",whatsitcodes.userdefined)) user_t.type = 116 -- 44 +local left_margin_kern = register_node(new_node("margin_kern",0)) +local right_margin_kern = register_node(new_node("margin_kern",1)) +local lineskip = register_node(new_node("glue",skipcodes.lineskip)) +local baselineskip = register_node(new_node("glue",skipcodes.baselineskip)) +local leftskip = register_node(new_node("glue",skipcodes.leftskip)) +local rightskip = register_node(new_node("glue",skipcodes.rightskip)) +local temp = register_node(new_node("temp",0)) +local noad = register_node(new_node("noad")) + +-- the dir field needs to be set otherwise crash: + +local rule = register_node(new_node("rule")) rule .dir = "TLT" +local hlist = register_node(new_node("hlist")) hlist.dir = "TLT" +local vlist = register_node(new_node("vlist")) vlist.dir = "TLT" + +function pool.zeroglue(n) + local s = n.spec + return not writable or ( + s.width == 0 + and s.stretch == 0 + and s.shrink == 0 + and s.stretch_order == 0 + and s.shrink_order == 0 + ) +end + +function pool.glyph(fnt,chr) + local n = copy_node(glyph) + if fnt then n.font = fnt end + if chr then n.char = chr end + return n +end + +function pool.penalty(p) + local n = copy_node(penalty) + n.penalty = p + return n +end + +function pool.kern(k) + local n = copy_node(kern) + n.kern = k + return n +end + +function pool.fontkern(k) + local n = copy_node(fontkern) + n.kern = k + return n +end + +function pool.gluespec(width,stretch,shrink,stretch_order,shrink_order) + local s = copy_node(glue_spec) + if width then s.width = width end + if stretch then s.stretch = stretch end + if shrink then s.shrink = shrink end + if stretch_order then s.stretch_order = stretch_order end + if shrink_order then s.shrink_order = shrink_order end + return s +end + +local function someskip(skip,width,stretch,shrink,stretch_order,shrink_order) + local n = copy_node(skip) + if not width then + -- no spec + elseif width == false or tonumber(width) then + local s = copy_node(glue_spec) + if width then s.width = width end + if stretch then s.stretch = stretch end + if shrink then s.shrink = shrink end + if stretch_order then s.stretch_order = stretch_order end + if shrink_order then s.shrink_order = shrink_order end + n.spec = s + else + -- shared + n.spec = copy_node(width) + end + return n +end + +function pool.stretch(a,b) + local n = copy_node(glue) + local s = copy_node(glue_spec) + if b then + s.stretch = a + s.stretch_order = b + else + s.stretch = 1 + s.stretch_order = a or 1 + end + n.spec = s + return n +end + +function pool.shrink(a,b) + local n = copy_node(glue) + local s = copy_node(glue_spec) + if b then + s.shrink = a + s.shrink_order = b + else + s.shrink = 1 + s.shrink_order = a or 1 + end + n.spec = s + return n +end + + +function pool.glue(width,stretch,shrink,stretch_order,shrink_order) + return someskip(glue,width,stretch,shrink,stretch_order,shrink_order) +end + +function pool.leftskip(width,stretch,shrink,stretch_order,shrink_order) + return someskip(leftskip,width,stretch,shrink,stretch_order,shrink_order) +end + +function pool.rightskip(width,stretch,shrink,stretch_order,shrink_order) + return someskip(rightskip,width,stretch,shrink,stretch_order,shrink_order) +end + +function pool.lineskip(width,stretch,shrink,stretch_order,shrink_order) + return someskip(lineskip,width,stretch,shrink,stretch_order,shrink_order) +end + +function pool.baselineskip(width,stretch,shrink) + return someskip(baselineskip,width,stretch,shrink) +end + +function pool.disc() + return copy_node(disc) +end + +function pool.textdir(dir) + local t = copy_node(textdir) + t.dir = dir + return t +end + +function pool.rule(width,height,depth,dir) -- w/h/d == nil will let them adapt + local n = copy_node(rule) + if width then n.width = width end + if height then n.height = height end + if depth then n.depth = depth end + if dir then n.dir = dir end + return n +end + +if node.has_field(latelua,'string') then + function pool.latelua(code) + local n = copy_node(latelua) + n.string = code + return n + end +else + function pool.latelua(code) + local n = copy_node(latelua) + n.data = code + return n + end +end + +function pool.leftmarginkern(glyph,width) + local n = copy_node(left_margin_kern) + if not glyph then + report_nodes("invalid pointer to left margin glyph node") + elseif glyph.id ~= glyph_code then + report_nodes("invalid node type %a for %s margin glyph node",nodecodes[glyph],"left") + else + n.glyph = glyph + end + if width then + n.width = width + end + return n +end + +function pool.rightmarginkern(glyph,width) + local n = copy_node(right_margin_kern) + if not glyph then + report_nodes("invalid pointer to right margin glyph node") + elseif glyph.id ~= glyph_code then + report_nodes("invalid node type %a for %s margin glyph node",nodecodes[p],"right") + else + n.glyph = glyph + end + if width then + n.width = width + end + return n +end + +function pool.temp() + return copy_node(temp) +end + +function pool.noad() + return copy_node(noad) +end + +function pool.hlist() + return copy_node(hlist) +end + +function pool.vlist() + return copy_node(vlist) +end + +--[[ +<p>At some point we ran into a problem that the glue specification +of the zeropoint dimension was overwritten when adapting a glue spec +node. This is a side effect of glue specs being shared. After a +couple of hours tracing and debugging Taco and I came to the +conclusion that it made no sense to complicate the spec allocator +and settled on a writable flag. This all is a side effect of the +fact that some glues use reserved memory slots (with the zeropoint +glue being a noticeable one). So, next we wrap this into a function +and hide it for the user. And yes, LuaTeX now gives a warning as +well.</p> +]]-- + +function nodes.writable_spec(n) -- not pool + local spec = n.spec + if not spec then + spec = copy_node(glue_spec) + n.spec = spec + elseif not spec.writable then + spec = copy_node(spec) + n.spec = spec + end + return spec +end + +-- local num = userids["my id"] +-- local str = userids[num] + +local userids = allocate() pool.userids = userids +local lastid = 0 + +setmetatable(userids, { + __index = function(t,k) + if type(k) == "string" then + lastid = lastid + 1 + rawset(userids,lastid,k) + rawset(userids,k,lastid) + return lastid + else + rawset(userids,k,k) + return k + end + end, + __call = function(t,k) + return t[k] + end +} ) + +function pool.usernumber(id,num) + local n = copy_node(user_n) + if num then + n.user_id, n.value = id, num + elseif id then + n.value = id + end + return n +end + +function pool.userlist(id,list) + local n = copy_node(user_l) + if list then + n.user_id, n.value = id, list + else + n.value = id + end + return n +end + +function pool.userstring(id,str) + local n = copy_node(user_s) + if str then + n.user_id, n.value = id, str + else + n.value = id + end + return n +end + +function pool.usertokens(id,tokens) + local n = copy_node(user_t) + if tokens then + n.user_id, n.value = id, tokens + else + n.value = id + end + return n +end + +function pool.special(str) + local n = copy_node(special) + n.data = str + return n +end + +statistics.register("cleaned up reserved nodes", function() + return format("%s nodes, %s lists of %s", pool.cleanup(tex.count["c_syst_last_allocated_box"])) +end) -- \topofboxstack + +statistics.register("node memory usage", function() -- comes after cleanup ! + return status.node_mem_usage +end) + +lua.registerfinalizer(pool.cleanup, "cleanup reserved nodes") |