+-- \wd, \ht, \dp の代わり
+do
+ local getbox, setdimen = tex.getbox, tex.setdimen
+ local function get_box_dim_common(key, s, l_dir)
+ local s_dir, wh = get_box_dir(s, dir_yoko)
+ if s_dir ~= l_dir then
+ local not_found = true
+ for x in traverse(getfield(wh, 'value')) do
+ if l_dir == has_attr(x, attr_dir)%dir_node_auto then
+ setdimen('ltj@tempdima', getfield(x, key))
+ not_found = false; break
+ end
+ end
+ if not_found then
+ local w = getfield(s, 'width')
+ local h = getfield(s, 'height')
+ local d = getfield(s, 'depth')
+ setdimen('ltj@tempdima',
+ dir_node_aux[s_dir][l_dir][key](w,h,d))
+ end
+ else
+ setdimen('ltj@tempdima', getfield(s, key))
+ end
+ end
+ local function get_box_dim(key, n)
+ local gt = tex.globaldefs; tex.globaldefs = 0
+ local s = getbox(n)
+ if s then
+ local l_dir = get_dir_count()
+ s = to_direct(s)
+ local b_dir = has_attr(s, attr_dir) or 0
+ if b_dir<dir_node_auto then
+ get_box_dim_common(key, s, l_dir)
+ elseif b_dir%dir_node_auto==l_dir then
+ setdimen('ltj@tempdima', getfield(s, key))
+ else
+ get_box_dim_common(key,
+ node_next(node_next(node_next(getlist(s)))), l_dir)
+ end
+ else
+ setdimen('ltj@tempdima', 0)
+ end
+ tex.globaldefs = gt
+ end
+ luatexja.direction.get_box_dim = get_box_dim
+
+ -- return value: (changed dimen of box itself?)
+ local function set_box_dim_common(key, s, l_dir)
+ local s_dir, wh = get_box_dir(s, dir_yoko)
+ if s_dir ~= l_dir then
+ if not wh then
+ wh = create_dir_whatsit(getlist(s), 'set_box_dim', s_dir)
+ setfield(s, 'head', wh)
+ end
+ local db
+ local dnh = getfield(wh, 'value')
+ for x in traverse(dnh) do
+ if has_attr(x, attr_dir)%dir_node_auto==l_dir then
+ db = x; break
+ end
+ end
+ if not db then
+ db = create_dir_node(s, s_dir, l_dir, true)
+ setfield(db, 'next', dnh)
+ setfield(wh, 'value',to_node(db))
+ end
+ setfield(db, key, tex.getdimen('ltj@tempdima'))
+ return false
+ else
+ setfield(s, key, tex.getdimen('ltj@tempdima'))
+ if wh then
+ -- change dimension of dir_nodes which are created "automatically"
+ local bw, bh, bd
+ = getfield(s,'width'), getfield(s, 'height'), getfield(s, 'depth')
+ for x in traverse(getfield(wh, 'value')) do
+ local x_dir = has_attr(x, attr_dir)
+ if x_dir<dir_node_manual then
+ local info = dir_node_aux[s_dir][x_dir%dir_node_auto]
+ setfield(x, 'width', info.width(bw,bh,bd))
+ setfield(x, 'height', info.height(bw,bh,bd))
+ setfield(x, 'depth', info.depth(bw,bh,bd))
+ end
+ end
+ end
+ return true
+ end
+ end
+ local function set_box_dim(key)
+ local n = tex_getcount('ltj@tempcnta')
+ local s = getbox(n)
+ if s then
+ local l_dir = get_dir_count()
+ s = to_direct(s)
+ local b_dir = has_attr(s, attr_dir) or 0
+ if b_dir<dir_node_auto then
+ set_box_dim_common(key, s, l_dir)
+ elseif b_dir%dir_node_auto == l_dir then
+ setfield(s, key, tex.getdimen('ltj@tempdima'))
+ if b_dir<dir_node_manual then
+ set_attr(s, attr_dir, b_dir%dir_node_auto + dir_node_manual)
+ end
+ else
+ local sid, sl = getid(s), getlist(s)
+ local b = node_next(node_next(node_next(sl)))
+ local info = dir_node_aux[get_box_dir(b)][b_dir%dir_node_auto]
+ local shift_old
+ for _,v in ipairs(info[sid]) do
+ if v[1]=='box' then
+ shift_old = v[2](
+ getfield(b,'width'), getfield(b, 'height'), getfield(b, 'depth'))
+ break
+ end
+ end
+ if set_box_dim_common(key, b, l_dir) then
+ local bw, bh, bd
+ = getfield(b,'width'), getfield(b, 'height'), getfield(b, 'depth')
+ -- re-calculate shift
+ for i,v in ipairs(info[sid]) do
+ if getid(sl)==id_kern then
+ setfield(sl, 'kern', v[2](bw,bh,bd) )
+ elseif getid(sl)==sid then
+ local d = getfield(sl, 'shift')
+ setfield(sl, 'shift',
+ getfield(sl, 'shift') - shift_old + v[2](bw,bh,bd) )
+ end
+ sl = node_next(sl)
+ end
+ -- re-calculate dimension of s, if s is created "automatically"
+ if b_dir<dir_node_manual then
+ setfield(s, 'width', info.width(bw,bh,bd))
+ setfield(s, 'height', info.height(bw,bh,bd))
+ setfield(s, 'depth', info.depth(bw,bh,bd))
+ end
+ end
+ end
+ end
+ end
+ luatexja.direction.set_box_dim = set_box_dim
+end
+
+-- \ifydir, \iftdir, \ifddir
+do
+ local cat_lp = luatexbase.catcodetables['latex-package']
+ local getbox = tex.getbox
+ local function dir_conditional(n, mode)
+ local s = getbox(n)
+ local res = false
+ if s then
+ s = to_direct(s)
+ local b_dir = get_box_dir(s, dir_yoko)
+ if b_dir<dir_node_auto then
+ res = (b_dir==mode)
+ else
+ local b_dir = get_box_dir(
+ node_next(node_next(node_next(getlist(s)))), dir_yoko)
+ res = (b_dir==mode)
+ end
+ end
+ tex.sprint(cat_lp, '\\if' .. tostring(res))
+ end
+ luatexja.direction.dir_conditional = dir_conditional
+end