diff options
author | Hans Hagen <pragma@wxs.nl> | 2018-04-16 00:08:11 +0200 |
---|---|---|
committer | Context Git Mirror Bot <phg42.2a@gmail.com> | 2018-04-16 00:08:11 +0200 |
commit | d5d5a39dc16881d098a99b74cba9020d96be4e11 (patch) | |
tree | 3d32c01797d034acc0107f6abd9c2d66af0b5ba6 /tex/context/base/mkiv/node-bck.lua | |
parent | 25fcad7435f56cdce2658336909f4da6a65589c0 (diff) | |
download | context-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.lua | 258 |
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, } |