+ -- for i=1,2 do
+ -- if bh and getid(bh)==id_whatsit
+ -- and getsubtype(bh)==sid_user and getfield(bh, 'user_id')==DIR then
+ -- c = bh
+ -- dir = (dir==0) and has_attr(bh, attr_dir) or dir
+ -- end
+ -- bh = node_next(bh)
+ -- end
+ stop_time_measure('get_box_dir')
+ return (dir==0 and default or dir), c
+end
+
+do
+ local getbox = tex.getbox
+ local dir_backup
+ function luatexja.direction.unbox_check_dir(is_copy)
+ start_time_measure('box_primitive_hook')
+ local list_dir = get_dir_count()%dir_math_mod
+ local b = getbox(tex_getcount('ltj@tempcnta'))
+ if b and getlist(to_direct(b)) then
+ local box_dir = get_box_dir(to_direct(b), dir_yoko)
+ if box_dir%dir_math_mod ~= list_dir then
+ ltjb.package_error(
+ 'luatexja',
+ "Incompatible direction list can't be unboxed",
+ 'I refuse to unbox a box in differrent direction.')
+ tex.sprint(cat_lp, '\\@gobbletwo')
+ else
+ dir_backup = nil
+ local bd = to_direct(b)
+ local hd = getlist(bd)
+ local nh = hd
+ while hd do
+ if getid(hd)==id_whatsit and getsubtype(hd)==sid_user
+ and getfield(hd, 'user_id')==DIR then
+ local d = hd
+ nh, hd = node_remove(nh, hd)
+ if is_copy and (not dir_backup) then
+ dir_backup = d
+ setfield(dir_backup, 'next', nil)
+ else
+ node_free(d)
+ end
+ else
+ hd = node_next(hd)
+ end
+ end
+ setfield(bd, 'head', nh)
+ end
+ end
+ if luatexja.global_temp and tex.globaldefs~=luatexja.global_temp then
+ tex.globaldefs = luatexja.global_temp
+ end
+ stop_time_measure('box_primitive_hook')
+ end
+ function luatexja.direction.uncopy_restore_whatsit()
+ local b = getbox(tex_getcount('ltj@tempcnta'))
+ if b then
+ local bd = to_direct(b)
+ if dir_backup then
+ setfield(dir_backup, 'next', getlist(bd))
+ setfield(bd, 'head', dir_backup)
+ dir_backup = nil
+ end
+ end
+ end
+end
+
+-- dir_node に包まれている「本来の中身」を取り出し,
+-- dir_node を全部消去
+local function unwrap_dir_node(b, head, box_dir)
+ -- b: dir_node, head: the head of list, box_dir:
+ -- return values are (new head), (next of b), (contents), (dir of contents)
+ local bh = getlist(b)
+ local nh, nb
+ if head then
+ nh = insert_before(head, b, bh)
+ nh, nb = node_remove(nh, b)
+ setfield(b, 'next', nil)
+ node_free(b)
+ end
+ local shift_old, b_dir, wh = nil, get_box_dir(bh, 0)
+ if wh then
+ node.direct.flush_list(getfield(wh, 'value'))
+ setfield(wh, 'value', nil)
+ end
+ return nh, nb, bh, b_dir
+end
+
+-- is_manual: 寸法変更に伴うものか?
+local function create_dir_node(b, b_dir, new_dir, is_manual)
+ local info = dir_node_aux[b_dir%dir_math_mod][new_dir%dir_math_mod]
+ local w = getfield(b, 'width')
+ local h = getfield(b, 'height')
+ local d = getfield(b, 'depth')
+ local db = node_new(getid(b)) -- dir_node
+ set_attr(db, attr_dir,
+ new_dir + (is_manual and dir_node_manual or dir_node_auto))
+ set_attr(db, attr_icflag, PROCESSED)
+ set_attr(b, attr_icflag, PROCESSED)
+ ensure_tex_attr(attr_dir, 0)
+ ensure_tex_attr(attr_icflag, 0)
+ setfield(db, 'dir', getfield(b, 'dir'))
+ setfield(db, 'shift', 0)
+ setfield(db, 'width', info.width(w,h,d))
+ setfield(db, 'height', info.height(w,h,d))
+ setfield(db, 'depth', info.depth(w,h,d))
+ return db
+end
+
+-- 異方向のボックスの処理
+local make_dir_whatsit, process_dir_node
+do
+ make_dir_whatsit = function (head, b, new_dir, origin)
+ new_dir = new_dir%dir_math_mod