flag = 0; break
end
end
- if flag==1 then -- move dir_whatsit w
- return 1,w -- TODO
+ if flag==1 then -- dir_whatsit already exists
+ return 1,w
else
return flag
end
end
end
+ function luatexja.direction.set_list_direction_hook(v)
+ local lv = tex_nest.ptr -- must be >= 1
+ if not v then
+ v = get_dir_count()
+ if abs(tex_nest[lv-1].mode) == ltjs.mmode and v == dir_tate then
+ v = dir_utod
+ end
+ elseif v=='adj' then
+ v = get_adjust_dir_count()
+ end
+ local h = to_direct(tex_nest[lv].head)
+ local w = node_new(id_whatsit, sid_user)
+ setfield(w, 'next', nil)
+ setfield(w, 'user_id', DIR)
+ setfield(w, 'type', 110)
+ set_attr(w, attr_dir, v)
+ insert_after(h, h, w)
+ tex_nest[lv].tail = to_node(node_tail(w))
+ tex_set_attr('global', attr_icflag, 0)
+ tex_set_attr('global', attr_dir, 0)
+ end
+
local function set_list_direction(v, name)
local lv = tex_nest.ptr
if not v then
for line in traverse_id(id_hlist, hd) do
local nh = getlist(line)
setfield(line, 'head', create_dir_whatsit(nh, gc, new_dir) )
- set_attr(line, attr_dir, new_dir)
+ --set_attr(line, attr_dir, new_dir)
end
tex_set_attr('global', attr_dir, 0)
return h
local bh = getfield(b,'head')
-- b は insert node となりうるので getlist() は使えない
local c
- for i=1,2 do
- if bh and getid(bh)==id_whatsit
- and getsubtype(bh)==sid_user and getfield(bh, 'user_id')==DIR then
+ for bh in traverse_id(id_whatsit, bh) do
+ if getsubtype(bh)==sid_user and getfield(bh, 'user_id')==DIR then
c = bh
- dir = (dir==0) and has_attr(bh, attr_dir) or dir
+ dir = (dir==0) and has_attr(bh, attr_dir) or dir
end
- bh = node_next(bh)
end
+ -- 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 function check_dir(reg_num)
+ 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 then
local box_dir = get_box_dir(to_direct(b), dir_yoko)
if box_dir%dir_math_mod ~= list_dir then
- -- print('NEST', tex_nest.ptr, tex_getcount('ltj@tempcnta'))
- -- luatexja.ext_show_node_list(
- -- (tex_nest.ptr==0) and tex.lists.page_head or tex_nest[tex_nest.ptr].head,
- -- 'LIST' .. tostring(list_dir) .. '> ', print)
- -- luatexja.ext_show_node_list(b, 'BOX' .. tostring(box_dir) .. '> ', print)
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
end
stop_time_measure('box_primitive_hook')
end
- luatexja.direction.check_dir = check_dir
+ 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 に包まれている「本来の中身」を取り出し,
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)
- luatexja.ext_show_node(to_node(b), '>> ', print)
local bh = getlist(b)
local nh, nb
if head then
end
end
Dnode.flush_list(getfield(dn, 'value'))
+ setfield(dn, 'value', nil)
db = db or create_dir_node(b, box_dir, new_dir, false)
local w = getfield(b, 'width')
local h = getfield(b, 'height')
if box_dir%dir_math_mod ~= list_dir then
setbox(
'ltj@afbox',
- to_node(
- copy_list(make_dir_whatsit(sd, sd, list_dir, 'box_move'))
- -- without copy_list, we get a segfault
- )
+ to_node(copy_list(make_dir_whatsit(sd, sd, list_dir, 'box_move')))
+ -- copy_list しないとリストの整合性が崩れる……?
)
end
end
do
local function glyph_from_packed(h)
local b = getlist(h)
- return (getid(b)==id_kern)
- and node_next(node_next(node_next(node_next(b)))) or b
+ return (getid(b)==id_kern or (getid(b)==id_whatsit and getsubtype(b)==sid_save) )
+ and node_next(node_next(node_next(b))) or b
end
luatexja.direction.glyph_from_packed = glyph_from_packed
end
--- adjust and insertion
-local id_adjust = node.id('adjust')
-function luatexja.direction.check_adjust_direction()
- start_time_measure('box_primitive_hook')
- local list_dir = get_adjust_dir_count()
- local a = tex_nest[tex_nest.ptr].tail
- local ad = to_direct(a)
- if a and getid(ad)==id_adjust then
- local adj_dir = get_box_dir(ad)
- if list_dir~=adj_dir then
- ltjb.package_error(
- 'luatexja',
- 'Direction Incompatible',
- "\\vadjust's argument and outer vlist must have same direction.")
- Dnode.last_node()
+-- adjust
+do
+ local id_adjust = node.id('adjust')
+ function luatexja.direction.check_adjust_direction()
+ start_time_measure('box_primitive_hook')
+ local list_dir = get_adjust_dir_count()
+ local a = tex_nest[tex_nest.ptr].tail
+ local ad = to_direct(a)
+ if a and getid(ad)==id_adjust then
+ local adj_dir = get_box_dir(ad)
+ if list_dir~=adj_dir then
+ ltjb.package_error(
+ 'luatexja',
+ 'Direction Incompatible',
+ "\\vadjust's argument and outer vlist must have same direction.")
+ Dnode.last_node()
+ end
+ end
+ stop_time_measure('box_primitive_hook')
+ end
+end
+
+-- insert
+do
+ local id_ins = node.id('ins')
+ local id_rule = node.id('rule')
+ function luatexja.direction.populate_insertion_dir_whatsit()
+ start_time_measure('box_primitive_hook')
+ local list_dir = get_dir_count()
+ local a = tex_nest[tex_nest.ptr].tail
+ local ad = to_direct(a)
+ if a and getid(ad)==id_ins then
+ local h = getfield(ad, 'head')
+ if getid(h)==id_whatsit and
+ getsubtype(h)==sid_user and getfield(h, 'user_id')==DIR then
+ local n = h; h = node_remove(h,h)
+ node_free(n)
+ end
+ for box_rule in traverse(h) do
+ if getid(box_rule)<id_rule then
+ local w = node_new(id_whatsit, sid_user)
+ setfield(w, 'next', nil)
+ setfield(w, 'user_id', DIR)
+ setfield(w, 'type', 110)
+ set_attr(w, attr_dir, list_dir)
+ h = insert_before(h, box_rule, w)
+ end
+ end
+ tex_set_attr('global', attr_dir, 0)
+ setfield(ad, 'head', h)
end
+ stop_time_measure('box_primitive_hook')
end
- stop_time_measure('box_primitive_hook')
end
-- vsplit
hd = create_dir_whatsit_vbox(hd, gc)
split_dir_whatsit = hd
elseif gc=='split_off' then
- local bh=hd
- for i=1,2 do
- if bh and getid(bh)==id_whatsit
- and getsubtype(bh)==sid_user and getfield(bh, 'user_id')==DIR 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
- bh = node_next(bh)
end
+ -- local bh=hd
+ -- for i=1,2 do
+ -- if bh and getid(bh)==id_whatsit
+ -- and getsubtype(bh)==sid_user and getfield(bh, 'user_id')==DIR then
+ -- ltjs.list_dir = has_attr(bh, attr_dir); break
+ -- end
+ -- bh = node_next(bh)
+ -- end
if split_dir_whatsit then
-- adjust direction of 'split_keep'
set_attr(split_dir_whatsit, attr_dir, ltjs.list_dir)
setfield(db, 'head', db_head)
end
end
+
+ local shipout_temp = node_new(id_hlist)
+ set_attr(shipout_temp, attr_dir, dir_yoko)
+ tex_set_attr('global', attr_dir, 0)
+
finalize_inner = function (box)
for n in traverse(getlist(box)) do
local nid = getid(n)
else
finalize_inner(n)
end
- end
+ end
end
end
local getbox = tex.getbox
+ local setbox, copy = Dnode.setbox, Dnode.copy
function luatexja.direction.finalize()
- finalize_inner(to_direct(tex.getbox("AtBeginShipoutBox")))
+ local a = to_direct(tex.getbox("AtBeginShipoutBox"))
+ local a_dir = get_box_dir(a, dir_yoko)
+ if a_dir~=dir_yoko then
+ local b = create_dir_node(a, a_dir, dir_yoko, false)
+ setfield(b, 'head', a); a = b
+ end
+ setfield(shipout_temp, 'head', a)
+ finalize_inner(shipout_temp)
+ setbox('global', "AtBeginShipoutBox", copy(getlist(shipout_temp)))
+ setfield(shipout_temp, 'head',nil)
end
end