+ -- 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