diff options
Diffstat (limited to 'tex/context/base/mkiv/node-bck.lua')
-rw-r--r-- | tex/context/base/mkiv/node-bck.lua | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/tex/context/base/mkiv/node-bck.lua b/tex/context/base/mkiv/node-bck.lua new file mode 100644 index 000000000..a095ac4c4 --- /dev/null +++ b/tex/context/base/mkiv/node-bck.lua @@ -0,0 +1,194 @@ +if not modules then modules = { } end modules ['node-bck'] = { + version = 1.001, + comment = "companion to node-bck.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- beware, this one takes quite some runtime, so we need a status flag +-- maybe some page related state + +local attributes, nodes, node = attributes, nodes, node + +local tasks = nodes.tasks + +local nodecodes = nodes.nodecodes +local listcodes = nodes.listcodes + +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local glyph_code = nodecodes.glyph +local cell_code = listcodes.cell + +local nuts = nodes.nuts +local nodepool = nuts.pool + +local tonode = nuts.tonode +local tonut = nuts.tonut + +local getfield = nuts.getfield +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 setfield = nuts.setfield +local setattr = nuts.setattr +local setlink = nuts.setlink +local setlist = nuts.setlist + +local traverse = nuts.traverse +local traverse_id = nuts.traverse_id + +local new_rule = nodepool.rule +local new_glue = nodepool.glue + +local a_color = attributes.private('color') +local a_transparency = attributes.private('transparency') +local a_colorspace = 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) + 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 + local width = getfield(current,"width") + 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_colorspace) + if mode then + local height = getfield(current,"height") + local depth = getfield(current,"depth") + 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_colorspace,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 + end + end + current = getnext(current) + end + return head, true +end + +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 + -- + if background then + -- current has subtype 5 (cell) + local width = getfield(current,"width") + if width > 0 then + local mode = getattr(found,a_colorspace) + if mode then + local glue = new_glue(-width) + local rule = new_rule(width,getfield(current,"height"),getfield(current,"depth")) + local color = getattr(found,a_color) + local transparency = getattr(found,a_transparency) + setattr(rule,a_colorspace,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 + 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, true +end + +-- nodes.handlers.backgrounds = add_backgrounds +-- nodes.handlers.alignbackgrounds = add_alignbackgrounds + +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 + +-- elsewhere: needs checking + +-- tasks.appendaction("shipouts","normalizers","nodes.handlers.backgrounds") +-- tasks.appendaction("shipouts","normalizers","nodes.handlers.alignbackgrounds") + +interfaces.implement { + name = "enablebackgroundboxes", + onlyonce = true, + actions = nodes.tasks.enableaction, + arguments = { "'shipouts'", "'nodes.handlers.backgrounds'" } +} + +interfaces.implement { + name = "enablebackgroundalign", + onlyonce = true, + actions = nodes.tasks.enableaction, + arguments = { "'shipouts'", "'nodes.handlers.alignbackgrounds'" } +} |