summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/mkiv/node-bck.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/node-bck.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/mkiv/node-bck.lua378
1 files changed, 134 insertions, 244 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-bck.lua b/Master/texmf-dist/tex/context/base/mkiv/node-bck.lua
index a19e5e969a7..4ed5abe5e5e 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-bck.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-bck.lua
@@ -9,288 +9,178 @@ if not modules then modules = { } end modules ['node-bck'] = {
-- beware, this one takes quite some runtime, so we need a status flag
-- maybe some page related state
--- todo: done (or just get rid of done altogether) ... saves no purpose
--- any longer
-
local attributes, nodes, node = attributes, nodes, node
-local enableaction = nodes.tasks.enableaction
-
-local nodecodes = nodes.nodecodes
-local listcodes = nodes.listcodes
-
-local hlist_code = nodecodes.hlist
-local vlist_code = nodecodes.vlist
-
-local alignmentlist_code = listcodes.alignment
-local celllist_code = listcodes.cell
-
-local nuts = nodes.nuts
-local nodepool = nuts.pool
-
-local getnext = nuts.getnext
-local getprev = nuts.getprev
-local getid = nuts.getid
-local getlist = nuts.getlist
-local getattr = nuts.getattr
-local getsubtype = nuts.getsubtype
-local getwhd = nuts.getwhd
-local getwidth = nuts.getwidth
-local getprop = nuts.getprop
-
-local setattr = nuts.setattr
-local setlink = nuts.setlink
-local setlist = nuts.setlist
-local setattributelist = nuts.setattributelist
-local setprop = nuts.setprop
+local enableaction = nodes.tasks.enableaction
-local takebox = nuts.takebox
-local findtail = nuts.tail
+local nodecodes = nodes.nodecodes
+local listcodes = nodes.listcodes
-local nextnode = nuts.traversers.node
-local nexthlist = nuts.traversers.hlist
-local nextlist = nuts.traversers.list
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+local cell_code = listcodes.cell
-local flush_node_list = nuts.flush_list
+local nuts = nodes.nuts
+local nodepool = nuts.pool
-local new_rule = nodepool.rule
-local new_kern = nodepool.kern
-local new_hlist = nodepool.hlist
+local tonode = nuts.tonode
+local tonut = nuts.tonut
-local privateattributes = attributes.private
-local unsetvalue = attributes.unsetvalue
+local getnext = nuts.getnext
+local getprev = nuts.getprev
+local getid = nuts.getid
+local getlist = nuts.getlist
+local getattr = nuts.getattr
+local getsubtype = nuts.getsubtype
+local getwhd = nuts.getwhd
-local linefillers = nodes.linefillers
+local setattr = nuts.setattr
+local setlink = nuts.setlink
+local setlist = nuts.setlist
-local a_color = privateattributes("color")
-local a_transparency = privateattributes("transparency")
-local a_colormodel = privateattributes("colormodel")
-local a_background = privateattributes("background")
-local a_alignbackground = privateattributes("alignbackground")
-local a_linefiller = privateattributes("linefiller")
-local a_ruled = privateattributes("ruled")
+local traverse = nuts.traverse
+local traverse_id = nuts.traverse_id
-local trace_alignment = false
-local report_alignment = logs.reporter("backgrounds","alignment")
+local new_rule = nodepool.rule
+local new_glue = nodepool.glue
-trackers.register("backgrounds.alignments",function(v) trace_alignment = v end)
-
--- We can't use listbuilders with where=alignment because at that stage we have
--- unset boxes. Also, post_linebreak is unsuitable for nested processing as we
--- get the same stuff many times (wrapped again and again).
---
--- After many experiments with different callbacks the shipout is still the best
--- place but then we need to store some settings longer or save them with the node.
--- For color only we can get away with it with an extra attribute flagging a row
--- but for more complex stuff we can better do as we do here now.
-
-local overshoot = math.floor(65781/5) -- could be an option per table (just also store it)
-
-local function colored_a(current,list,template,id)
- local width, height, depth = getwhd(current)
- local total = height + depth
- if width > 0 and total > 0 then
- local rule = nil
- --
- local a = getattr(template,a_linefiller)
- if a then
- local d = linefillers.data[a%1000]
- if d then
- rule = linefillers.filler(template,d,width,height,depth)
- end
- end
- --
- if not rule then
- rule = new_rule(width,height,depth)
- end
- setattributelist(rule,template)
- local back = new_kern(-((id == vlist_code and total) or width))
- return setlink(rule,back,list)
- end
-end
+local a_color = attributes.private('color')
+local a_transparency = attributes.private('transparency')
+local a_colormodel = attributes.private('colormodel')
+local a_background = attributes.private('background')
+local a_alignbackground = attributes.private('alignbackground')
-local function colored_b(current,list,template,id,indent)
- local width, height, depth = getwhd(current)
- local total = height + depth
- if width > 0 and total > 0 then
- local fore = (indent ~= 0) and new_kern(indent)
- local rule = nil
- --
- local a = getattr(template,a_linefiller)
- if a then
- local d = linefillers.data[a%1000]
- if d then
- rule = linefillers.filler(template,d,width-indent,height,depth)
+local function add_backgrounds(head) -- rather old code .. to be redone
+ local current = head
+ while current do
+ local id = getid(current)
+ if id == hlist_code or id == vlist_code then
+ local list = getlist(current)
+ if list then
+ local head = add_backgrounds(list)
+ if head then
+ setlist(current,head)
+ list = head
+ end
end
- end
- --
- if not rule then
- rule = new_rule(width-indent,height+overshoot,depth+overshoot)
- setattributelist(rule,template)
- end
- if overshoot == 0 then
- local back = new_kern(-((id == vlist_code and total) or width))
- return setlink(fore,rule,back,list)
- else
- rule = new_hlist(rule)
- return setlink(fore,rule,list)
- end
- end
-end
-
-local templates = { }
-local currentrow = 0
-local enabled = false
-local alignments = false
-
-local function add_alignbackgrounds(head,list)
- for current, id, subtype, list in nextlist, list do
- if list and id == hlist_code and subtype == celllist_code then
- for template in nexthlist, list do
- local background = getattr(template,a_alignbackground)
+ local width, height, depth = getwhd(current)
+ if width > 0 then
+ local background = getattr(current,a_background)
if background then
- local list = colored_a(current,list,template)
- if list then
- setlist(current,list)
+ -- direct to hbox
+ -- colorspace is already set so we can omit that and stick to color
+ local mode = getattr(current,a_colormodel)
+ if mode then
+ local skip = id == hlist_code and width or (height + depth)
+ local glue = new_glue(-skip)
+ local rule = new_rule(width,height,depth)
+ local color = getattr(current,a_color)
+ local transparency = getattr(current,a_transparency)
+ setattr(rule,a_colormodel,mode)
+ if color then
+ setattr(rule,a_color,color)
+ end
+ if transparency then
+ setattr(rule,a_transparency,transparency)
+ end
+-- setlink(rule,glue)
+-- if list then
+-- setlink(glue,list)
+-- end
+-- setlist(current,rule)
+ setlist(current,rule,glue,list)
end
- setattr(template,a_alignbackground,unsetvalue) -- or property
end
- break
end
end
+ current = getnext(current)
end
- local template = getprop(head,"alignmentchecked")
- if template then
- list = colored_b(head,list,template[1],hlist_code,template[2])
- flush_node_list(template)
- templates[currentrow] = false
- return list
- end
+ return head, true
end
-local function add_backgrounds(head,id,list)
- if list then
- for current, id, subtype, list in nextlist, list do
- if list then
- if alignments and subtype == alignmentlist_code then
- local l = add_alignbackgrounds(current,list)
- if l then
- list = l
- setlist(current,list)
+local function add_alignbackgrounds(head)
+ local current = head
+ while current do
+ local id = getid(current)
+ if id == hlist_code then
+ local list = getlist(current)
+ if not list then
+ -- no need to look
+ elseif getsubtype(current) == cell_code then
+ local background = nil
+ local found = nil
+ -- for l in traverse(list) do
+ -- background = getattr(l,a_alignbackground)
+ -- if background then
+ -- found = l
+ -- break
+ -- end
+ -- end
+ -- we know that it's a fake hlist (could be user node)
+ -- but we cannot store tables in user nodes yet
+ for l in traverse_id(hpack_code,list) do
+ background = getattr(l,a_alignbackground)
+ if background then
+ found = l
end
+ break
end
- local l = add_backgrounds(current,id,list)
- if l then
- list = l
- setlist(current,l)
- end
- end
- end
- end
- if id == hlist_code or id == vlist_code then
- local background = getattr(head,a_background)
- if background then
- list = colored_a(head,list,head,id)
- -- not needed
- setattr(head,a_background,unsetvalue) -- or property
- return list
- end
- end
-end
-
-function nodes.handlers.backgrounds(head)
- add_backgrounds(head,getid(head),getlist(head))
- return head
-end
-
-function nodes.handlers.backgroundspage(head,where)
- if head and where == "alignment" then
- for n in nexthlist, head do
- local p = getprop(n,"alignmentchecked")
- if not p and getsubtype(n) == alignmentlist_code then
- currentrow = currentrow + 1
- local template = templates[currentrow]
- if trace_alignment then
- report_alignment("%03i %s %s",currentrow,"page",template and "+" or "-")
- end
- setprop(n,"alignmentchecked",template)
- end
- end
- end
- return head
-end
-
-function nodes.handlers.backgroundsvbox(head,where)
- if head and where == "vbox" then
- local list = getlist(head)
- if list then
- for n in nexthlist, list do
- local p = getprop(n,"alignmentchecked")
- if not p and getsubtype(n) == alignmentlist_code then
- currentrow = currentrow + 1
- local template = templates[currentrow]
- if trace_alignment then
- report_alignment("%03i %s %s",currentrow,"vbox",template and "+" or "-")
+ --
+ if background then
+ -- current has subtype 5 (cell)
+ local width, height, depth = getwhd(current)
+ if width > 0 then
+ local mode = getattr(found,a_colormodel)
+ if mode then
+ local glue = new_glue(-width)
+ local rule = new_rule(width,height,depth)
+ local color = getattr(found,a_color)
+ local transparency = getattr(found,a_transparency)
+ setattr(rule,a_colormodel,mode)
+ if color then
+ setattr(rule,a_color,color)
+ end
+ if transparency then
+ setattr(rule,a_transparency,transparency)
+ end
+ setlink(rule,glue)
+ if list then
+ setlink(glue,list)
+ end
+ setlist(current,rule)
+ end
end
- setprop(n,"alignmentchecked",template)
end
+ else
+ add_alignbackgrounds(list)
+ end
+ elseif id == vlist_code then
+ local list = getlist(current)
+ if list then
+ add_alignbackgrounds(list)
end
end
+ current = getnext(current)
end
- return head
+ return head, true
end
--- interfaces.implement {
--- name = "enablebackgroundboxes",
--- onlyonce = true,
--- actions = enableaction,
--- arguments = { "'shipouts'", "'nodes.handlers.backgrounds'" }
--- }
---
--- doing it in the shipout works as well but this is nicer
+-- nodes.handlers.backgrounds = add_backgrounds
+-- nodes.handlers.alignbackgrounds = add_alignbackgrounds
-local function enable(alignmentstoo)
- if not enabled then
- enabled = true
- enableaction("shipouts","nodes.handlers.backgrounds")
- end
- if not alignments and alignmentstoo then
- alignments = true
- enableaction("vboxbuilders","nodes.handlers.backgroundsvbox")
- enableaction("mvlbuilders", "nodes.handlers.backgroundspage")
- end
-end
+nodes.handlers.backgrounds = function(head) local head, done = add_backgrounds (tonut(head)) return tonode(head), done end
+nodes.handlers.alignbackgrounds = function(head) local head, done = add_alignbackgrounds(tonut(head)) return tonode(head), done end
interfaces.implement {
name = "enablebackgroundboxes",
onlyonce = true,
- actions = enable,
+ actions = enableaction,
+ arguments = { "'shipouts'", "'nodes.handlers.backgrounds'" }
}
interfaces.implement {
name = "enablebackgroundalign",
onlyonce = true,
- actions = function()
- enable(true)
- end,
-}
-
-interfaces.implement {
- name = "setbackgroundrowdata",
- arguments = { "integer", "integer", "dimension" },
- actions = function(row,box,indent)
- row = row -1 -- better here than in tex
- if box == 0 then
- templates[row] = false
- else
- templates[row] = { takebox(box), indent }
- end
- end,
-}
-
-interfaces.implement {
- name = "resetbackgroundrowdata",
- actions = function()
- currentrow = 0
- end,
+ actions = enableaction,
+ arguments = { "'shipouts'", "'nodes.handlers.alignbackgrounds'" }
}