summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/node-bck.lua
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2018-04-16 00:08:11 +0200
committerContext Git Mirror Bot <phg42.2a@gmail.com>2018-04-16 00:08:11 +0200
commitd5d5a39dc16881d098a99b74cba9020d96be4e11 (patch)
tree3d32c01797d034acc0107f6abd9c2d66af0b5ba6 /tex/context/base/mkiv/node-bck.lua
parent25fcad7435f56cdce2658336909f4da6a65589c0 (diff)
downloadcontext-d5d5a39dc16881d098a99b74cba9020d96be4e11.tar.gz
2018-04-15 23:21:00
Diffstat (limited to 'tex/context/base/mkiv/node-bck.lua')
-rw-r--r--tex/context/base/mkiv/node-bck.lua258
1 files changed, 156 insertions, 102 deletions
diff --git a/tex/context/base/mkiv/node-bck.lua b/tex/context/base/mkiv/node-bck.lua
index 4ed5abe5e..054135669 100644
--- a/tex/context/base/mkiv/node-bck.lua
+++ b/tex/context/base/mkiv/node-bck.lua
@@ -9,6 +9,9 @@ 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
@@ -18,6 +21,7 @@ local listcodes = nodes.listcodes
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
+local alignment_code = listcodes.alignment
local cell_code = listcodes.cell
local nuts = nodes.nuts
@@ -33,27 +37,88 @@ local getlist = nuts.getlist
local getattr = nuts.getattr
local getsubtype = nuts.getsubtype
local getwhd = nuts.getwhd
+local getwidth = nuts.getwidth
local setattr = nuts.setattr
local setlink = nuts.setlink
local setlist = nuts.setlist
+local setattributelist = nuts.setattributelist
+
+local takebox = nuts.takebox
+local findtail = nuts.tail
local traverse = nuts.traverse
local traverse_id = nuts.traverse_id
+local flush_node_list = nuts.flush_list
+
local new_rule = nodepool.rule
-local new_glue = nodepool.glue
-
-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 add_backgrounds(head) -- rather old code .. to be redone
- local current = head
- while current do
- local id = getid(current)
+local new_kern = nodepool.kern
+
+local privateattributes = attributes.private
+
+local linefillers = nodes.linefillers
+
+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")
+
+-- actually we can be more clever now: we can store cells and row data
+-- and apply 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
+ local back = new_kern(-((id == vlist_code and total) or width))
+ setattributelist(rule,template)
+ return setlink(rule,back,list)
+ end
+end
+
+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)
+ end
+ end
+ --
+ if not rule then
+ rule = new_rule(width-indent,height,depth)
+ setattributelist(rule,template)
+ end
+ local back = new_kern(-((id == vlist_code and total) or width))
+ return setlink(fore,rule,back,list)
+ end
+end
+
+local function add_backgrounds(head)
+ for current, id in traverse(head) do
if id == hlist_code or id == vlist_code then
local list = getlist(current)
if list then
@@ -63,124 +128,113 @@ local function add_backgrounds(head) -- rather old code .. to be redone
list = head
end
end
- local width, height, depth = getwhd(current)
- if width > 0 then
- local background = getattr(current,a_background)
- if background then
- -- 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
+ local background = getattr(current,a_background)
+ if background then
+ local list = colored_a(current,list,current,id)
+ if list then
+ setlist(current,list)
end
end
end
- current = getnext(current)
end
return head, true
end
+-- We use a fake hlist with proper attributes.
+
+local templates = { }
+local currentrow = 0
+
local function add_alignbackgrounds(head)
- local current = head
- while current do
- local id = getid(current)
- if id == hlist_code then
+ for current in traverse_id(hlist_code,head) do -- what is valign?
+ if getsubtype(current) == alignment_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
- --
- 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)
+ if list then
+ for current in traverse_id(hlist_code,list) do
+ if getsubtype(current) == cell_code then
+ local list = getlist(current)
+ if list then
+ for template in traverse_id(hlist_code,list) do
+ local background = getattr(template,a_alignbackground)
+ if background then
+ local list = colored_a(current,list,template)
+ if list then
+ setlist(current,list)
+ end
+ end
+ break
end
- setlist(current,rule)
end
end
end
- else
- add_alignbackgrounds(list)
end
- elseif id == vlist_code then
- local list = getlist(current)
- if list then
- add_alignbackgrounds(list)
+ currentrow = currentrow + 1
+ local template = templates[currentrow]
+ if template then
+ local list = colored_b(current,list,template[1],hlist_code,template[2])
+ if list then
+ setlist(current,list)
+ end
+ flush_node_list(template)
+ templates[currentrow] = false
end
end
- current = getnext(current)
end
return head, true
end
--- nodes.handlers.backgrounds = add_backgrounds
--- nodes.handlers.alignbackgrounds = add_alignbackgrounds
+function nodes.handlers.backgrounds(head,where)
+ local head, done = add_backgrounds(tonut(head))
+ return tonode(head), done
+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
+function nodes.handlers.alignbackgrounds(head,where)
+ if where == "alignment" and head then
+ local head, done = add_alignbackgrounds(tonut(head))
+ return tonode(head), done
+ else
+ return head, false
+ end
+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
interfaces.implement {
name = "enablebackgroundboxes",
onlyonce = true,
- actions = enableaction,
- arguments = { "'shipouts'", "'nodes.handlers.backgrounds'" }
+ actions = function()
+ enableaction("mvlbuilders", "nodes.handlers.backgrounds")
+ enableaction("vboxbuilders","nodes.handlers.backgrounds")
+ end,
}
interfaces.implement {
name = "enablebackgroundalign",
onlyonce = true,
- actions = enableaction,
- arguments = { "'shipouts'", "'nodes.handlers.alignbackgrounds'" }
+ actions = function()
+ enableaction("mvlbuilders", "nodes.handlers.alignbackgrounds")
+ enableaction("vboxbuilders","nodes.handlers.alignbackgrounds")
+ end,
+}
+
+interfaces.implement {
+ name = "setbackgroundrowdata",
+ arguments = { "integer", "integer", "dimension" },
+ actions = function(row,box,indent)
+ templates[row] = { takebox(box), indent }
+ end,
+}
+
+interfaces.implement {
+ name = "resetbackgroundrowdata",
+ actions = function()
+ currentrow = 0
+ end,
}