+ ensure_tex_attr(attr_dir, 0)
+ setfield(ad, 'head', h)
+ end
+ stop_time_measure('box_primitive_hook')
+ end
+end
+
+-- vsplit
+do
+ local split_dir_whatsit
+ local function dir_adjust_vpack(h, gc)
+ start_time_measure('direction_vpack')
+ local hd = to_direct(h)
+ if gc=='split_keep' then
+ -- supply dir_whatsit
+ hd = create_dir_whatsit_vbox(hd, gc)
+ split_dir_whatsit = hd
+ elseif gc=='split_off' then
+ for bh in traverse_id(id_whatsit, hd) do
+ if getsubtype(bh)==sid_user and getfield(bh, 'user_id')==DIR then
+ ltjs.list_dir = has_attr(bh, attr_dir); break
+ end
+ end
+ if split_dir_whatsit then
+ -- adjust direction of 'split_keep'
+ set_attr(split_dir_whatsit, attr_dir, ltjs.list_dir)
+ end
+ split_dir_whatsit=nil
+ elseif gc=='preamble' then
+ split_dir_whatsit=nil
+ else
+ adjust_badness(hd)
+ -- hd = process_dir_node(create_dir_whatsit_vbox(hd, gc), gc)
+ -- done in append_to_vpack callback
+ hd = create_dir_whatsit_vbox(hd, gc)
+ split_dir_whatsit=nil
+ end
+ stop_time_measure('direction_vpack')
+ return to_node(hd)
+ end
+ ltjb.add_to_callback('vpack_filter',
+ dir_adjust_vpack,
+ 'ltj.direction', 10000)
+end
+
+do
+ -- supply direction whatsit to the main vertical list "of the next page"
+ local function dir_adjust_pre_output(h, gc)
+ return to_node(create_dir_whatsit_vbox(to_direct(h), gc))
+ end
+ ltjb.add_to_callback('pre_output_filter',
+ dir_adjust_pre_output,
+ 'ltj.direction', 10000)
+
+ function luatexja.direction.remove_end_whatsit()
+ local h=tex.lists.page_head
+ if h and (not h.next) and
+ h.id==id_whatsit and h.subtype==sid_user and
+ h.user_id == DIR then
+ tex.lists.page_head = nil
+ node.free(h)
+ end
+ end
+end
+
+-- append_to_vlist filter
+do
+ local id_glue = node.id('glue')
+ local getglue = node.direct.getglue or
+ function(g)
+ return getfield(g,'width'), getfield(g,'stretch'), getfield(g,'shrink'),
+ getfield(g,'stretch_order'), getfield(g,'shrink_order')
+ end
+local setglue = luatexja.setglue
+ local function copy_glue (new_glue, old_glue, subtype, new_w)
+ setfield(new_glue, 'subtype', subtype)
+ local w,st,sp,sto,spo = getglue(to_direct(old_glue))
+ setglue(new_glue, new_w or w, st, sp, sto, spo)
+ end
+ local node_write = node.direct.write
+ local function dir_adjust_append_vlist(b, loc, prev, mirrored)
+ local old_b = to_direct(b)
+ local new_b = loc=='box' and
+ make_dir_whatsit(old_b, old_b, get_dir_count(), 'append_vlist') or old_b
+
+ if prev > -65536000 then
+ local d = tex.baselineskip.width - prev
+ - getfield(new_b, mirrored and 'depth' or 'height')
+ local g = node_new(id_glue)
+ if d < tex.lineskiplimit then
+ copy_glue(g, tex.lineskip, 1)
+ else
+ copy_glue(g, tex.baselineskip, 2, d);
+ end
+ node_write(g)
+ end
+ node_write(new_b)
+ tex.prevdepth = getfield(new_b, mirrored and 'height' or 'depth')
+ return nil -- do nothing on tex side
+ end
+ ltjb.add_to_callback('append_to_vlist_filter',
+ dir_adjust_append_vlist,
+ 'ltj.direction', 10000)
+end
+
+-- finalize (executed just before \shipout)
+-- we supply correct pdfsavematrix nodes etc. inside dir_node
+do
+ local finalize_inner
+ local function finalize_dir_node(db,new_dir)
+ local b = getlist(db)
+ finalize_inner(b)
+ local w = getfield(b, 'width')
+ local h = getfield(b, 'height')
+ local d = getfield(b, 'depth')
+ local dn_w = getfield(db, 'width')
+ local dn_h = getfield(db, 'height')
+ local dn_d = getfield(db, 'depth')
+ local db_head, db_tail
+ for _,v in ipairs(dir_node_aux
+ [get_box_dir(b, dir_yoko)%dir_math_mod][new_dir][getid(b)]) do
+ local cmd, arg, nn = v[1], v[2]
+ if cmd=='kern' then
+ nn = node_new(id_kern)
+ setfield(nn, 'kern', arg(w, h, d, dn_w, dn_h, dn_d))
+ elseif cmd=='whatsit' then
+ nn = node_new(id_whatsit, arg)
+ elseif cmd=='rotate' then
+ nn = node_new(id_whatsit, sid_matrix)
+ setfield(nn, 'data', arg)
+ elseif cmd=='box' then
+ nn = b; setfield(b, 'next', nil)
+ setfield(nn, 'shift', arg(w, h, d, dn_w, dn_h, dn_d))
+ end
+ if db_head then
+ insert_after(db_head, db_tail, nn)
+ db_tail = nn
+ else
+ setfield(db, 'head', nn)
+ db_head, db_tail = nn, nn
+ end